1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_rpc_nanopb: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker------ 4*61c4878aSAndroid Build Coastguard Workernanopb 5*61c4878aSAndroid Build Coastguard Worker------ 6*61c4878aSAndroid Build Coastguard Worker``pw_rpc`` can generate services which encode/decode RPC requests and responses 7*61c4878aSAndroid Build Coastguard Workeras nanopb message structs. 8*61c4878aSAndroid Build Coastguard Worker 9*61c4878aSAndroid Build Coastguard WorkerUsage 10*61c4878aSAndroid Build Coastguard Worker===== 11*61c4878aSAndroid Build Coastguard WorkerTo enable nanopb code generation, the build argument 12*61c4878aSAndroid Build Coastguard Worker``dir_pw_third_party_nanopb`` must be set to point to a local nanopb 13*61c4878aSAndroid Build Coastguard Workerinstallation. Nanopb 0.4 is recommended, but Nanopb 0.3 is also supported. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard WorkerDefine a ``pw_proto_library`` containing the .proto file defining your service 16*61c4878aSAndroid Build Coastguard Worker(and optionally other related protos), then depend on the ``nanopb_rpc`` 17*61c4878aSAndroid Build Coastguard Workerversion of that library in the code implementing the service. 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard Worker.. code-block:: 20*61c4878aSAndroid Build Coastguard Worker 21*61c4878aSAndroid Build Coastguard Worker # chat/BUILD.gn 22*61c4878aSAndroid Build Coastguard Worker 23*61c4878aSAndroid Build Coastguard Worker import("$dir_pw_build/target_types.gni") 24*61c4878aSAndroid Build Coastguard Worker import("$dir_pw_protobuf_compiler/proto.gni") 25*61c4878aSAndroid Build Coastguard Worker 26*61c4878aSAndroid Build Coastguard Worker pw_proto_library("chat_protos") { 27*61c4878aSAndroid Build Coastguard Worker sources = [ "chat_protos/chat_service.proto" ] 28*61c4878aSAndroid Build Coastguard Worker } 29*61c4878aSAndroid Build Coastguard Worker 30*61c4878aSAndroid Build Coastguard Worker # Library that implements the Chat service. 31*61c4878aSAndroid Build Coastguard Worker pw_source_set("chat_service") { 32*61c4878aSAndroid Build Coastguard Worker sources = [ 33*61c4878aSAndroid Build Coastguard Worker "chat_service.cc", 34*61c4878aSAndroid Build Coastguard Worker "chat_service.h", 35*61c4878aSAndroid Build Coastguard Worker ] 36*61c4878aSAndroid Build Coastguard Worker public_deps = [ ":chat_protos.nanopb_rpc" ] 37*61c4878aSAndroid Build Coastguard Worker } 38*61c4878aSAndroid Build Coastguard Worker 39*61c4878aSAndroid Build Coastguard WorkerA C++ header file is generated for each input .proto file, with the ``.proto`` 40*61c4878aSAndroid Build Coastguard Workerextension replaced by ``.rpc.pb.h``. For example, given the input file 41*61c4878aSAndroid Build Coastguard Worker``chat_protos/chat_service.proto``, the generated header file will be placed 42*61c4878aSAndroid Build Coastguard Workerat the include path ``"chat_protos/chat_service.rpc.pb.h"``. 43*61c4878aSAndroid Build Coastguard Worker 44*61c4878aSAndroid Build Coastguard WorkerGenerated code API 45*61c4878aSAndroid Build Coastguard Worker================== 46*61c4878aSAndroid Build Coastguard WorkerAll examples in this document use the following RPC service definition. 47*61c4878aSAndroid Build Coastguard Worker 48*61c4878aSAndroid Build Coastguard Worker.. code-block:: protobuf 49*61c4878aSAndroid Build Coastguard Worker 50*61c4878aSAndroid Build Coastguard Worker // chat/chat_protos/chat_service.proto 51*61c4878aSAndroid Build Coastguard Worker 52*61c4878aSAndroid Build Coastguard Worker syntax = "proto3"; 53*61c4878aSAndroid Build Coastguard Worker 54*61c4878aSAndroid Build Coastguard Worker service Chat { 55*61c4878aSAndroid Build Coastguard Worker // Returns information about a chatroom. 56*61c4878aSAndroid Build Coastguard Worker rpc GetRoomInformation(RoomInfoRequest) returns (RoomInfoResponse) {} 57*61c4878aSAndroid Build Coastguard Worker 58*61c4878aSAndroid Build Coastguard Worker // Lists all of the users in a chatroom. The response is streamed as there 59*61c4878aSAndroid Build Coastguard Worker // may be a large amount of users. 60*61c4878aSAndroid Build Coastguard Worker rpc ListUsersInRoom(ListUsersRequest) returns (stream ListUsersResponse) {} 61*61c4878aSAndroid Build Coastguard Worker 62*61c4878aSAndroid Build Coastguard Worker // Uploads a file, in chunks, to a chatroom. 63*61c4878aSAndroid Build Coastguard Worker rpc UploadFile(stream UploadFileRequest) returns (UploadFileResponse) {} 64*61c4878aSAndroid Build Coastguard Worker 65*61c4878aSAndroid Build Coastguard Worker // Sends messages to a chatroom while receiving messages from other users. 66*61c4878aSAndroid Build Coastguard Worker rpc Chat(stream ChatMessage) returns (stream ChatMessage) {} 67*61c4878aSAndroid Build Coastguard Worker } 68*61c4878aSAndroid Build Coastguard Worker 69*61c4878aSAndroid Build Coastguard WorkerServer-side 70*61c4878aSAndroid Build Coastguard Worker----------- 71*61c4878aSAndroid Build Coastguard WorkerA C++ class is generated for each service in the .proto file. The class is 72*61c4878aSAndroid Build Coastguard Workerlocated within a special ``pw_rpc::nanopb`` sub-namespace of the file's package. 73*61c4878aSAndroid Build Coastguard Worker 74*61c4878aSAndroid Build Coastguard WorkerThe generated class is a base class which must be derived to implement the 75*61c4878aSAndroid Build Coastguard Workerservice's methods. The base class is templated on the derived class. 76*61c4878aSAndroid Build Coastguard Worker 77*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 78*61c4878aSAndroid Build Coastguard Worker 79*61c4878aSAndroid Build Coastguard Worker #include "chat_protos/chat_service.rpc.pb.h" 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard Worker class ChatService final : public pw_rpc::nanopb::Chat::Service<ChatService> { 82*61c4878aSAndroid Build Coastguard Worker public: 83*61c4878aSAndroid Build Coastguard Worker // Implementations of the service's RPC methods; see below. 84*61c4878aSAndroid Build Coastguard Worker }; 85*61c4878aSAndroid Build Coastguard Worker 86*61c4878aSAndroid Build Coastguard WorkerUnary RPC 87*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^ 88*61c4878aSAndroid Build Coastguard WorkerA unary RPC is implemented as a function which takes in the RPC's request struct 89*61c4878aSAndroid Build Coastguard Workerand populates a response struct to send back, with a status indicating whether 90*61c4878aSAndroid Build Coastguard Workerthe request succeeded. 91*61c4878aSAndroid Build Coastguard Worker 92*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 93*61c4878aSAndroid Build Coastguard Worker 94*61c4878aSAndroid Build Coastguard Worker pw::Status GetRoomInformation(pw::rpc:: 95*61c4878aSAndroid Build Coastguard Worker const RoomInfoRequest& request, 96*61c4878aSAndroid Build Coastguard Worker RoomInfoResponse& response); 97*61c4878aSAndroid Build Coastguard Worker 98*61c4878aSAndroid Build Coastguard WorkerServer streaming RPC 99*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^ 100*61c4878aSAndroid Build Coastguard WorkerA server streaming RPC receives the client's request message alongside a 101*61c4878aSAndroid Build Coastguard Worker``ServerWriter``, used to stream back responses. 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 104*61c4878aSAndroid Build Coastguard Worker 105*61c4878aSAndroid Build Coastguard Worker void ListUsersInRoom(pw::rpc:: 106*61c4878aSAndroid Build Coastguard Worker const ListUsersRequest& request, 107*61c4878aSAndroid Build Coastguard Worker pw::rpc::ServerWriter<ListUsersResponse>& writer); 108*61c4878aSAndroid Build Coastguard Worker 109*61c4878aSAndroid Build Coastguard WorkerThe ``ServerWriter`` object is movable, and remains active until it is manually 110*61c4878aSAndroid Build Coastguard Workerclosed or goes out of scope. The writer has a simple API to return responses: 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: Status ServerWriter::Write(const T& response) 113*61c4878aSAndroid Build Coastguard Worker 114*61c4878aSAndroid Build Coastguard Worker Writes a single response message to the stream. The returned status indicates 115*61c4878aSAndroid Build Coastguard Worker whether the write was successful. 116*61c4878aSAndroid Build Coastguard Worker 117*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: void ServerWriter::Finish(Status status = OkStatus()) 118*61c4878aSAndroid Build Coastguard Worker 119*61c4878aSAndroid Build Coastguard Worker Closes the stream and sends back the RPC's overall status to the client. 120*61c4878aSAndroid Build Coastguard Worker 121*61c4878aSAndroid Build Coastguard Worker.. cpp:function:: Status ServerWriter::TryFinish(Status status = OkStatus()) 122*61c4878aSAndroid Build Coastguard Worker 123*61c4878aSAndroid Build Coastguard Worker Closes the stream and sends back the RPC's overall status to the client only 124*61c4878aSAndroid Build Coastguard Worker if the final packet is successfully sent. 125*61c4878aSAndroid Build Coastguard Worker 126*61c4878aSAndroid Build Coastguard WorkerOnce a ``ServerWriter`` has been closed, all future ``Write`` calls will fail. 127*61c4878aSAndroid Build Coastguard Worker 128*61c4878aSAndroid Build Coastguard Worker.. attention:: 129*61c4878aSAndroid Build Coastguard Worker 130*61c4878aSAndroid Build Coastguard Worker Make sure to use ``std::move`` when passing the ``ServerWriter`` around to 131*61c4878aSAndroid Build Coastguard Worker avoid accidentally closing it and ending the RPC. 132*61c4878aSAndroid Build Coastguard Worker 133*61c4878aSAndroid Build Coastguard WorkerClient streaming RPC 134*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^ 135*61c4878aSAndroid Build Coastguard Worker.. attention:: Supported, but the documentation is still under construction. 136*61c4878aSAndroid Build Coastguard Worker 137*61c4878aSAndroid Build Coastguard WorkerBidirectional streaming RPC 138*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^ 139*61c4878aSAndroid Build Coastguard Worker.. attention:: Supported, but the documentation is still under construction. 140*61c4878aSAndroid Build Coastguard Worker 141*61c4878aSAndroid Build Coastguard WorkerClient-side 142*61c4878aSAndroid Build Coastguard Worker----------- 143*61c4878aSAndroid Build Coastguard WorkerA corresponding client class is generated for every service defined in the proto 144*61c4878aSAndroid Build Coastguard Workerfile. To allow multiple types of clients to exist, it is placed under the 145*61c4878aSAndroid Build Coastguard Worker``pw_rpc::nanopb`` namespace. The ``Client`` class is nested under 146*61c4878aSAndroid Build Coastguard Worker``pw_rpc::nanopb::ServiceName``. For example, the ``Chat`` service would create 147*61c4878aSAndroid Build Coastguard Worker``pw_rpc::nanopb::Chat::Client``. 148*61c4878aSAndroid Build Coastguard Worker 149*61c4878aSAndroid Build Coastguard WorkerService clients are instantiated with a reference to the RPC client through 150*61c4878aSAndroid Build Coastguard Workerwhich they will send requests, and the channel ID they will use. 151*61c4878aSAndroid Build Coastguard Worker 152*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 153*61c4878aSAndroid Build Coastguard Worker 154*61c4878aSAndroid Build Coastguard Worker // Nested under pw_rpc::nanopb::ServiceName. 155*61c4878aSAndroid Build Coastguard Worker class Client { 156*61c4878aSAndroid Build Coastguard Worker public: 157*61c4878aSAndroid Build Coastguard Worker Client(::pw::rpc::Client& client, uint32_t channel_id); 158*61c4878aSAndroid Build Coastguard Worker 159*61c4878aSAndroid Build Coastguard Worker pw::rpc::NanopbUnaryReceiver<RoomInfoResponse> GetRoomInformation( 160*61c4878aSAndroid Build Coastguard Worker const RoomInfoRequest& request, 161*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(Status, const RoomInfoResponse&)> on_response, 162*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(Status)> on_rpc_error = nullptr); 163*61c4878aSAndroid Build Coastguard Worker 164*61c4878aSAndroid Build Coastguard Worker // ...and more (see below). 165*61c4878aSAndroid Build Coastguard Worker }; 166*61c4878aSAndroid Build Coastguard Worker 167*61c4878aSAndroid Build Coastguard WorkerRPCs can also be invoked individually as free functions: 168*61c4878aSAndroid Build Coastguard Worker 169*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 170*61c4878aSAndroid Build Coastguard Worker 171*61c4878aSAndroid Build Coastguard Worker pw::rpc::NanopbUnaryReceiver<RoomInfoResponse> call = pw_rpc::nanopb::Chat::GetRoomInformation( 172*61c4878aSAndroid Build Coastguard Worker client, channel_id, request, on_response, on_rpc_error); 173*61c4878aSAndroid Build Coastguard Worker 174*61c4878aSAndroid Build Coastguard WorkerThe client class has member functions for each method defined within the 175*61c4878aSAndroid Build Coastguard Workerservice's protobuf descriptor. The arguments to these methods vary depending on 176*61c4878aSAndroid Build Coastguard Workerthe type of RPC. Each method returns a client call object which stores the 177*61c4878aSAndroid Build Coastguard Workercontext of the ongoing RPC call. For more information on call objects, refer to 178*61c4878aSAndroid Build Coastguard Workerthe :ref:`core RPC docs <module-pw_rpc-making-calls>`. 179*61c4878aSAndroid Build Coastguard Worker 180*61c4878aSAndroid Build Coastguard Worker.. admonition:: Callback invocation 181*61c4878aSAndroid Build Coastguard Worker 182*61c4878aSAndroid Build Coastguard Worker RPC callbacks are invoked synchronously from ``Client::ProcessPacket``. 183*61c4878aSAndroid Build Coastguard Worker 184*61c4878aSAndroid Build Coastguard WorkerMethod APIs 185*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^ 186*61c4878aSAndroid Build Coastguard WorkerThe arguments provided when invoking a method depend on its type. 187*61c4878aSAndroid Build Coastguard Worker 188*61c4878aSAndroid Build Coastguard WorkerUnary RPC 189*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~ 190*61c4878aSAndroid Build Coastguard WorkerA unary RPC call takes the request struct and a callback to invoke when a 191*61c4878aSAndroid Build Coastguard Workerresponse is received. The callback receives the RPC's status and response 192*61c4878aSAndroid Build Coastguard Workerstruct. 193*61c4878aSAndroid Build Coastguard Worker 194*61c4878aSAndroid Build Coastguard WorkerAn optional second callback can be provided to handle internal errors. 195*61c4878aSAndroid Build Coastguard Worker 196*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 197*61c4878aSAndroid Build Coastguard Worker 198*61c4878aSAndroid Build Coastguard Worker pw::rpc::NanopbUnaryReceiver<RoomInfoResponse> GetRoomInformation( 199*61c4878aSAndroid Build Coastguard Worker const RoomInfoRequest& request, 200*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(const RoomInfoResponse&, Status)> on_response, 201*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(Status)> on_rpc_error = nullptr); 202*61c4878aSAndroid Build Coastguard Worker 203*61c4878aSAndroid Build Coastguard WorkerServer streaming RPC 204*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~ 205*61c4878aSAndroid Build Coastguard WorkerA server streaming RPC call takes the initial request struct and two callbacks. 206*61c4878aSAndroid Build Coastguard WorkerThe first is invoked on every stream response received, and the second is 207*61c4878aSAndroid Build Coastguard Workerinvoked once the stream is complete with its overall status. 208*61c4878aSAndroid Build Coastguard Worker 209*61c4878aSAndroid Build Coastguard WorkerAn optional third callback can be provided to handle internal errors. 210*61c4878aSAndroid Build Coastguard Worker 211*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 212*61c4878aSAndroid Build Coastguard Worker 213*61c4878aSAndroid Build Coastguard Worker pw::rpc::NanopbClientReader<ListUsersResponse> ListUsersInRoom( 214*61c4878aSAndroid Build Coastguard Worker const ListUsersRequest& request, 215*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(const ListUsersResponse&)> on_response, 216*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(Status)> on_stream_end, 217*61c4878aSAndroid Build Coastguard Worker ::pw::Function<void(Status)> on_rpc_error = nullptr); 218*61c4878aSAndroid Build Coastguard Worker 219*61c4878aSAndroid Build Coastguard WorkerClient streaming RPC 220*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~ 221*61c4878aSAndroid Build Coastguard Worker.. attention:: Supported, but the documentation is still under construction. 222*61c4878aSAndroid Build Coastguard Worker 223*61c4878aSAndroid Build Coastguard WorkerBidirectional streaming RPC 224*61c4878aSAndroid Build Coastguard Worker~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225*61c4878aSAndroid Build Coastguard Worker.. attention:: Supported, but the documentation is still under construction. 226*61c4878aSAndroid Build Coastguard Worker 227*61c4878aSAndroid Build Coastguard WorkerExample usage 228*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^ 229*61c4878aSAndroid Build Coastguard WorkerThe following example demonstrates how to call an RPC method using a nanopb 230*61c4878aSAndroid Build Coastguard Workerservice client and receive the response. 231*61c4878aSAndroid Build Coastguard Worker 232*61c4878aSAndroid Build Coastguard Worker.. code-block:: c++ 233*61c4878aSAndroid Build Coastguard Worker 234*61c4878aSAndroid Build Coastguard Worker #include "chat_protos/chat_service.rpc.pb.h" 235*61c4878aSAndroid Build Coastguard Worker 236*61c4878aSAndroid Build Coastguard Worker namespace { 237*61c4878aSAndroid Build Coastguard Worker 238*61c4878aSAndroid Build Coastguard Worker using ChatClient = pw_rpc::nanopb::Chat::Client; 239*61c4878aSAndroid Build Coastguard Worker 240*61c4878aSAndroid Build Coastguard Worker MyChannelOutput output; 241*61c4878aSAndroid Build Coastguard Worker pw::rpc::Channel channels[] = {pw::rpc::Channel::Create<1>(&output)}; 242*61c4878aSAndroid Build Coastguard Worker pw::rpc::Client client(channels); 243*61c4878aSAndroid Build Coastguard Worker 244*61c4878aSAndroid Build Coastguard Worker // Callback function for GetRoomInformation. 245*61c4878aSAndroid Build Coastguard Worker void LogRoomInformation(const RoomInfoResponse& response, Status status); 246*61c4878aSAndroid Build Coastguard Worker 247*61c4878aSAndroid Build Coastguard Worker } // namespace 248*61c4878aSAndroid Build Coastguard Worker 249*61c4878aSAndroid Build Coastguard Worker void InvokeSomeRpcs() { 250*61c4878aSAndroid Build Coastguard Worker // Instantiate a service client to call Chat service methods on channel 1. 251*61c4878aSAndroid Build Coastguard Worker ChatClient chat_client(client, 1); 252*61c4878aSAndroid Build Coastguard Worker 253*61c4878aSAndroid Build Coastguard Worker // The RPC will remain active as long as `call` is alive. 254*61c4878aSAndroid Build Coastguard Worker auto call = chat_client.GetRoomInformation( 255*61c4878aSAndroid Build Coastguard Worker {.room = "pigweed"}, LogRoomInformation); 256*61c4878aSAndroid Build Coastguard Worker if (!call.active()) { 257*61c4878aSAndroid Build Coastguard Worker // The invocation may fail. This could occur due to an invalid channel ID, 258*61c4878aSAndroid Build Coastguard Worker // for example. The failure status is forwarded to the to call's 259*61c4878aSAndroid Build Coastguard Worker // on_rpc_error callback. 260*61c4878aSAndroid Build Coastguard Worker return; 261*61c4878aSAndroid Build Coastguard Worker } 262*61c4878aSAndroid Build Coastguard Worker 263*61c4878aSAndroid Build Coastguard Worker // For simplicity, block until the call completes. An actual implementation 264*61c4878aSAndroid Build Coastguard Worker // would likely std::move the call somewhere to keep it active while doing 265*61c4878aSAndroid Build Coastguard Worker // other work. 266*61c4878aSAndroid Build Coastguard Worker while (call.active()) { 267*61c4878aSAndroid Build Coastguard Worker Wait(); 268*61c4878aSAndroid Build Coastguard Worker } 269*61c4878aSAndroid Build Coastguard Worker 270*61c4878aSAndroid Build Coastguard Worker // Do other stuff now that we have the room information. 271*61c4878aSAndroid Build Coastguard Worker } 272*61c4878aSAndroid Build Coastguard Worker 273*61c4878aSAndroid Build Coastguard WorkerZephyr 274*61c4878aSAndroid Build Coastguard Worker====== 275*61c4878aSAndroid Build Coastguard WorkerTo enable ``pw_rpc.nanopb.*`` for Zephyr add ``CONFIG_PIGWEED_RPC_NANOPB=y`` to 276*61c4878aSAndroid Build Coastguard Workerthe project's configuration. This will enable the Kconfig menu for the 277*61c4878aSAndroid Build Coastguard Workerfollowing: 278*61c4878aSAndroid Build Coastguard Worker 279*61c4878aSAndroid Build Coastguard Worker* ``pw_rpc.nanopb.method`` which can be enabled via 280*61c4878aSAndroid Build Coastguard Worker ``CONFIG_PIGWEED_RPC_NANOPB_METHOD=y``. 281*61c4878aSAndroid Build Coastguard Worker* ``pw_rpc.nanopb.method_union`` which can be enabled via 282*61c4878aSAndroid Build Coastguard Worker ``CONFIG_PIGWEED_RPC_NANOPB_METHOD_UNION=y``. 283*61c4878aSAndroid Build Coastguard Worker* ``pw_rpc.nanopb.client`` which can be enabled via 284*61c4878aSAndroid Build Coastguard Worker ``CONFIG_PIGWEED_RPC_NANOPB_CLIENT=y``. 285*61c4878aSAndroid Build Coastguard Worker* ``pw_rpc.nanopb.common`` which can be enabled via 286*61c4878aSAndroid Build Coastguard Worker ``CONFIG_PIGWEED_RPC_NANOPB_COMMON=y``. 287*61c4878aSAndroid Build Coastguard Worker* ``pw_rpc.nanopb.echo_service`` which can be enabled via 288*61c4878aSAndroid Build Coastguard Worker ``CONFIG_PIGWEED_RPC_NANOPB_ECHO_SERVICE=y``. 289