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 62 /** 63 * Registers services to the server and to CHRE. 64 * 65 * This method must be called from `nanoappStart`. 66 * 67 * Although nanoapps are recommended to only call this API once with all 68 * services it intends to publish, if it is called multiple times, each 69 * call will append to the list of published services. 70 * 71 * @param numServices The number of services to register. 72 * @param services Service definitions. 73 * @return whether the registration was successful. 74 */ 75 bool registerServices(size_t numServices, Service *services); 76 77 /** 78 * Sets the permission for the next message to a client. 79 * 80 * While the permission are only actually used for messages to host clients, 81 * the value passed here only applies to the next message whether the client 82 * is a host client or a nanoapp. 83 * 84 * This method must be called: 85 * - from the body of a service implementation method in the case of unary 86 * RPCs, 87 * - right before invoking ServerReader.Finish for client streaming and 88 * bidirectional streaming RPCs, 89 * - right before invoking ServerWriter.Write and ServerWriter.Finish for 90 * server streaming and bidirectional streaming RPCs. 91 * 92 * @params permission Bitmasked CHRE_MESSAGE_PERMISSION_. 93 * 94 * @see chreSendMessageWithPermissions 95 */ 96 void setPermissionForNextMessage(uint32_t permission); 97 98 /** 99 * Handles events related to RPC services. 100 * 101 * Handles the following events: 102 * - CHRE_EVENT_MESSAGE_FROM_HOST: respond to host RPC requests, 103 * - CHRE_EVENT_RPC_REQUEST: respond to nanoapp RPC requests, 104 * - CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION: close the channel when the host 105 * terminates, 106 * - CHRE_EVENT_NANOAPP_STOPPED: close the channel when a nanoapp 107 * terminates. 108 * 109 * @param senderInstanceId The Instance ID for the source of this event. 110 * @param eventType The event type. 111 * @param eventData The associated data, if any, for this specific type of 112 * event. 113 * @return whether any event was handled successfully. 114 */ 115 bool handleEvent(uint32_t senderInstanceId, uint16_t eventType, 116 const void *eventData); 117 118 /** 119 * Close all connections to the server. 120 * 121 * Must be called from the nanoapp end. 122 */ 123 void close(); 124 125 private: 126 /** 127 * Handles messages from host clients. 128 * 129 * This method must be called when nanoapps receive a 130 * CHRE_EVENT_MESSAGE_FROM_HOST event. 131 * 132 * @param eventData The associated data, if any. 133 * @return whether the RPC was handled successfully. 134 */ 135 bool handleMessageFromHost(const void *eventData); 136 137 /** 138 * Handles messages from nanoapp clients. 139 * 140 * This method must be called when nanoapps receive a CHRE_EVENT_RPC_REQUEST 141 * event. 142 * 143 * @param eventData The associated data, if any. 144 * @return whether the RPC was handled successfully. 145 */ 146 bool handleMessageFromNanoapp(uint32_t senderInstanceId, 147 const void *eventData); 148 149 /** 150 * Closes the Pigweed channel when a host client disconnects. 151 * 152 * @param notification The notification from the host client 153 */ 154 void handleHostClientNotification(const void *eventData); 155 156 /** 157 * Closes the Pigweed channel when a nanoapp client disconnects. 158 * 159 * @param notification The eventData associated to a 160 * CHRE_EVENT_NANOAPP_STOPPED event. 161 */ 162 void handleNanoappStopped(const void *eventData); 163 164 /** 165 * Closes a Pigweed channel. 166 * 167 * @param id The channel ID. 168 * @return either an ok or not found status if the channel was not opened. 169 */ 170 pw::Status closeChannel(uint32_t id); 171 172 // Permission for the next message sent by mServer. 173 RpcPermission mPermission; 174 175 pw::rpc::Server mServer; 176 177 ChreServerHostChannelOutput mHostOutput; 178 ChreServerNanoappChannelOutput mNanoappOutput; 179 180 // Host endpoints for the connected clients. 181 DynamicVector<uint16_t> mConnectedHosts; 182 }; 183 184 } // namespace chre 185 186 #endif // CHRE_UTIL_PIGWEED_RPC_SERVER_H_