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_