xref: /aosp_15_r20/external/pigweed/pw_rpc/nanopb/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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