• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_UTIL_PIGWEED_RPC_SERVER_H_
18 #define CHRE_UTIL_PIGWEED_RPC_SERVER_H_
19 
20 #include "chre/util/dynamic_vector.h"
21 #include "chre/util/macros.h"
22 #include "chre/util/non_copyable.h"
23 #include "chre/util/pigweed/chre_channel_output.h"
24 #include "chre/util/pigweed/permission.h"
25 #include "pw_rpc/server.h"
26 #include "pw_rpc/service.h"
27 #include "pw_span/span.h"
28 
29 namespace chre {
30 
31 /**
32  * RPC Server wrapping a Pigweed RPC server.
33  *
34  * This helper class handles Pigweed RPC calls on the server side.
35  *
36  * The services must be registered from the `nanoappStart` function using
37  * the `registerService` method.
38  *
39  * The `handleEvent` method must be called at the beginning of the
40  * `nanoappHandleEvent` function to respond to RPC calls from the clients.
41  */
42 class RpcServer : public NonCopyable {
43  public:
44   struct Service {
45     /** A Pigweed service. */
46     pw::rpc::Service &service;
47     /**
48      * The ID of the service, it must be generated according to RFC 4122, UUID
49      * version 4 (random). This ID must be unique within a given nanoapp.
50      */
51     uint64_t id;
52 
53     /**
54      * The version of the service. It should be in sync with the version on the
55      * client side.
56      */
57     uint32_t version;
58   };
59 
RpcServer()60   RpcServer() : mHostOutput(mPermission), mNanoappOutput(mPermission) {}
61   ~RpcServer();
62 
63   /**
64    * Registers services to the server and to CHRE.
65    *
66    * This method must be called from `nanoappStart`.
67    *
68    * Although nanoapps are recommended to only call this API once with all
69    * services it intends to publish, if it is called multiple times, each
70    * call will append to the list of published services.
71    *
72    * @param numServices The number of services to register.
73    * @param services Service definitions.
74    * @return whether the registration was successful.
75    */
76   bool registerServices(size_t numServices, Service *services);
77 
78   /**
79    * Sets the permission for the next message to a client.
80    *
81    * While the permission are only actually used for messages to host clients,
82    * the value passed here only applies to the next message whether the client
83    * is a host client or a nanoapp.
84    *
85    * This method must be called:
86    * - from the body of a service implementation method in the case of unary
87    *   RPCs,
88    * - right before invoking ServerReader.Finish for client streaming and
89    *   bidirectional streaming RPCs,
90    * - right before invoking ServerWriter.Write and ServerWriter.Finish for
91    *   server streaming and bidirectional streaming RPCs.
92    *
93    * @params permission Bitmasked CHRE_MESSAGE_PERMISSION_.
94    *
95    * @see chreSendMessageWithPermissions
96    */
97   void setPermissionForNextMessage(uint32_t permission);
98 
99   /**
100    * Handles events related to RPC services.
101    *
102    * Handles the following events:
103    * - CHRE_EVENT_MESSAGE_FROM_HOST: respond to host RPC requests,
104    * - PW_RPC_CHRE_NAPP_REQUEST_EVENT_TYPE: respond to nanoapp RPC requests,
105    * - CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION: close the channel when the host
106    *   terminates,
107    * - CHRE_EVENT_NANOAPP_STOPPED: close the channel when a nanoapp
108    *   terminates.
109    *
110    * @param senderInstanceId The Instance ID for the source of this event.
111    * @param eventType The event type.
112    * @param eventData The associated data, if any, for this specific type of
113    *                  event.
114    * @return whether any event was handled successfully.
115    */
116   bool handleEvent(uint32_t senderInstanceId, uint16_t eventType,
117                    const void *eventData);
118 
119  private:
120   /**
121    * Handles messages from host clients.
122    *
123    * This method must be called when nanoapps receive a
124    * CHRE_EVENT_MESSAGE_FROM_HOST event.
125    *
126    * @param eventData  The associated data, if any.
127    * @return whether the RPC was handled successfully.
128    */
129   bool handleMessageFromHost(const void *eventData);
130 
131   /**
132    * Handles messages from nanoapp clients.
133    *
134    * This method must be called when nanoapps receive a
135    * PW_RPC_CHRE_NAPP_REQUEST_EVENT_TYPE event.
136    *
137    * @param eventData  The associated data, if any.
138    * @return whether the RPC was handled successfully.
139    */
140   bool handleMessageFromNanoapp(uint32_t senderInstanceId,
141                                 const void *eventData);
142 
143   /**
144    * Closes the Pigweed channel when a host client disconnects.
145    *
146    * @param notification The notification from the host client
147    */
148   void handleHostClientNotification(const void *eventData);
149 
150   /**
151    * Closes the Pigweed channel when a nanoapp client disconnects.
152    *
153    * @param notification The eventData associated to a
154    *    CHRE_EVENT_NANOAPP_STOPPED event.
155    */
156   void handleNanoappStopped(const void *eventData);
157 
158   /**
159    * Closes a Pigweed channel.
160    *
161    * @param id The channel ID.
162    * @return either an ok or not found status if the channel was not opened.
163    */
164   pw::Status closeChannel(uint32_t id);
165 
166   // Permission for the next message sent by mServer.
167   RpcPermission mPermission;
168 
169   pw::rpc::Server mServer;
170 
171   ChreServerHostChannelOutput mHostOutput;
172   ChreServerNanoappChannelOutput mNanoappOutput;
173 
174   // Host endpoints for the connected clients.
175   DynamicVector<uint16_t> mConnectedHosts;
176 };
177 
178 }  // namespace chre
179 
180 #endif  // CHRE_UTIL_PIGWEED_RPC_SERVER_H_