1 /* 2 * Copyright (C) 2017 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_CORE_HOST_COMMS_MANAGER_H_ 18 #define CHRE_CORE_HOST_COMMS_MANAGER_H_ 19 20 #include <cstddef> 21 #include <cstdint> 22 23 #include "chre/core/event_loop.h" 24 #include "chre/platform/atomic.h" 25 #include "chre/platform/host_link.h" 26 #include "chre/util/buffer.h" 27 #include "chre/util/non_copyable.h" 28 #include "chre/util/synchronized_memory_pool.h" 29 #include "chre/util/time.h" 30 #include "chre/util/transaction_manager.h" 31 #include "chre_api/chre/event.h" 32 33 namespace chre { 34 35 //! Only valid for messages from host to CHRE - indicates that the sender of the 36 //! message is not specified. 37 constexpr uint16_t kHostEndpointUnspecified = CHRE_HOST_ENDPOINT_UNSPECIFIED; 38 39 //! Only valid for messages from CHRE to host - delivers the message to all 40 //! registered clients of the Context Hub HAL, which is the default behavior. 41 constexpr uint16_t kHostEndpointBroadcast = CHRE_HOST_ENDPOINT_BROADCAST; 42 43 /** 44 * Data associated with a message either to or from the host. 45 */ 46 struct HostMessage : public NonCopyable { 47 // This union must be first, as this structure is aliased with 48 // chreMessageFromHostData 49 union { 50 // Fields use when the message was received from the host 51 struct chreMessageFromHostData fromHostData; 52 53 // Fields used when the messsage is directed to the host 54 struct { 55 //! Application-specific message ID 56 uint32_t messageType; 57 58 //! List of Android permissions declared by the nanoapp. This must be a 59 //! superset of messagePermissions. 60 uint32_t appPermissions; 61 62 //! List of Android permissions that cover the contents of the message. 63 //! These permissions are used to record and attribute access to 64 //! permissions-controlled resources. 65 //! Note that these permissions must always be a subset of uint32_t 66 //! permissions. Otherwise, the message will be dropped. 67 uint32_t messagePermissions; 68 69 //! Message free callback supplied by the nanoapp. Must only be invoked 70 //! from the EventLoop where the nanoapp runs. 71 chreMessageFreeFunction *nanoappFreeFunction; 72 73 //! Identifier for the host-side entity that should receive this message, 74 //! or that which sent it 75 uint16_t hostEndpoint; 76 77 //! true if this message results in the host transitioning from suspend 78 //! to awake. 79 bool wokeHost; 80 } toHostData; 81 }; 82 83 //! Whether the message is reliable. 84 //! Reliable messages are acknowledge by sending with a status containing 85 //! the transaction ID. 86 bool isReliable; 87 88 //! Source/destination nanoapp ID 89 uint64_t appId; 90 91 //! Used to report reliable message status back to the sender. 92 uint32_t messageSequenceNumber; 93 94 //! Application-defined message data 95 Buffer<uint8_t> message; 96 }; 97 98 typedef HostMessage MessageFromHost; 99 typedef HostMessage MessageToHost; 100 101 /** 102 * Common code for managing bi-directional communications between the host and 103 * nanoapps. Inherits from the platform-specific HostLink class to accomplish 104 * this, and also to provide an access point (lookup via the EventLoopManager 105 * Singleton) to the platform-specific HostLinkBase functionality for use by 106 * platform-specific code. 107 */ 108 class HostCommsManager : public HostLink { 109 public: 110 HostCommsManager(); 111 112 /** 113 * Completes a reliable message transaction. 114 * 115 * The callback registered when starting the transaction is called with the 116 * errorCode. 117 * 118 * @param transactionId ID of the transaction to complete. 119 * @param errorCode Error code to pass to the callback. 120 * @return Whether the transaction was completed successfully. 121 */ 122 bool completeTransaction(uint32_t transactionId, uint8_t errorCode); 123 124 /** 125 * Flush (or purge) any messages sent by the given app ID that are currently 126 * pending delivery to the host. At the point that this function is called, it 127 * is guaranteed that no new messages will be generated from this nanoapp. 128 * 129 * This function also flushes any outstanding reliable message transactions 130 * for the associated nanoapp. 131 * 132 * This function must impose strict ordering constraints, such that after it 133 * returns, it is guaranteed that HostCommsManager::onMessageToHostComplete 134 * will not be invoked for the app with the given ID. 135 */ 136 void flushNanoappMessagesAndTransactions(uint64_t appId); 137 138 /** 139 * Invoked by the HostLink platform layer when it is done with a message to 140 * the host: either it successfully sent it, or encountered an error. 141 * 142 * This function is thread-safe. 143 * 144 * @param message A message pointer previously given to HostLink::sendMessage 145 */ 146 void onMessageToHostComplete(const MessageToHost *msgToHost); 147 148 /* 149 * Resets mIsNanoappBlamedForWakeup to false so that 150 * nanoapp->blameHostWakeup() can be called again on next wakeup for one of 151 * the nanoapps. 152 */ 153 void resetBlameForNanoappHostWakeup(); 154 155 /** 156 * This function is used by sendMessageToNanoappFromHost() for sending 157 * deferred messages. Messages are deferred when the destination nanoapp is 158 * not yet loaded. 159 * 160 * By the time this function is called through deferCallback, nanoapp load 161 * requests in the queue will have been processed and therefore all nanoapps 162 * are expected to be ready. 163 * 164 * @param craftedMessage Deferred message from host to be delivered to the 165 * destination nanoapp 166 */ 167 void sendDeferredMessageToNanoappFromHost(MessageFromHost *craftedMessage); 168 169 /** 170 * Formulates a MessageToHost using the supplied message contents and 171 * passes it to HostLink for transmission to the host. 172 * 173 * @param nanoapp The sender of this message. 174 * @param messageData Pointer to message payload. Can be null if 175 * messageSize is 0. This buffer must remain valid until freeCallback is 176 * invoked. 177 * @param messageSize Size of the message to send, in bytes 178 * @param messageType Application-defined identifier for the message 179 * @param hostEndpoint Identifier for the entity on the host that should 180 * receive this message 181 * @param messagePermissions List of Android permissions that cover the 182 * contents of the message. These permissions are used to record 183 * and attribute access to permissions-controlled resources. 184 * @param freeCallback Optional callback to invoke when the messageData is 185 * no longer needed. The provided callback is only invoked when the return 186 * value is CHRE_ERROR_NONE. 187 * @param isReliable Whether the message is reliable. The receiver 188 * acknowledges the delivery of a reliable message by sending a 189 * status back to the sender. 190 * @param cookie The cookie to use when reporting the async status to the 191 * nanoapp via the CHRE_EVENT_RELIABLE_MSG_ASYNC_STATUS event. Only 192 * used when isReliable is true. 193 * @return true if the message was accepted into the outbound message 194 * queue. If this function returns false, it does *not* invoke 195 * freeCallback. If it returns true, freeCallback will be invoked (if 196 * non-null) on either success or failure. 197 * 198 * @see chreSendMessageToHost 199 */ 200 bool sendMessageToHostFromNanoapp(Nanoapp *nanoapp, void *messageData, 201 size_t messageSize, uint32_t messageType, 202 uint16_t hostEndpoint, 203 uint32_t messagePermissions, 204 chreMessageFreeFunction *freeCallback, 205 bool isReliable, const void *cookie); 206 207 /** 208 * Makes a copy of the supplied message data and posts it to the queue for 209 * later delivery to the addressed nanoapp. 210 * 211 * This function is safe to call from any thread. 212 * 213 * @param appId Identifier for the destination nanoapp 214 * @param messageType Application-defined message identifier 215 * @param hostEndpoint Identifier for the entity on the host that sent this 216 * message 217 * @param messageData Buffer containing application-specific message data; can 218 * be null if messageSize is 0 219 * @param messageSize Size of messageData, in bytes 220 * @param isReliable Whether the message is reliable 221 * @param messageSequenceNumber The message sequence number for reliable 222 * messages 223 */ 224 void sendMessageToNanoappFromHost(uint64_t appId, uint32_t messageType, 225 uint16_t hostEndpoint, 226 const void *messageData, size_t messageSize, 227 bool isReliable, 228 uint32_t messageSequenceNumber); 229 230 private: 231 //! The data passed to the transaction manager for use with reliable messages. 232 struct MessageTransactionData { 233 uint32_t *messageSequenceNumberPtr; 234 uint32_t messageSequenceNumber; 235 uint16_t nanoappInstanceId; 236 const void *cookie; 237 }; 238 239 //! The maximum number of retries for a reliable message. 240 static constexpr uint16_t kReliableMessageNumRetries = 3; 241 242 //! The retry wait time for reliable messages. 243 static constexpr Milliseconds kReliableMessageRetryWaitTime = 244 Milliseconds(250); 245 246 //! The timeout to receive an acknowledgment for a reliable message. 247 static constexpr Seconds kReliableMessageTimeout = Seconds(1); 248 249 //! The maximum number of messages we can have outstanding at any given time. 250 static constexpr size_t kMaxOutstandingMessages = 32; 251 252 /** 253 * Allocates and populates the event structure used to notify a nanoapp of an 254 * incoming message from the host. 255 * 256 * Used to implement sendMessageToNanoappFromHost() - see that 257 * function for parameter documentation. 258 * 259 * All parameters must be sanitized before invoking this function. 260 * 261 * @see sendMessageToNanoappFromHost 262 */ 263 MessageFromHost *craftNanoappMessageFromHost( 264 uint64_t appId, uint16_t hostEndpoint, uint32_t messageType, 265 const void *messageData, uint32_t messageSize, bool isReliable, 266 uint32_t messageSequenceNumber); 267 268 //! @see TransactionManager::DeferCallback 269 static bool deferCallback( 270 TransactionManager<MessageTransactionData, 271 kMaxOutstandingMessages>::DeferCallbackFunction func, 272 void *data, void *extraData, Nanoseconds delay, uint32_t *outTimerHandle); 273 274 /** 275 * Posts a crafted event, craftedMessage, to a nanoapp for processing, and 276 * deallocates it afterwards. 277 * 278 * Used to implement sendMessageToNanoappFromHost() and 279 * sendDeferredMessageToNanoappFromHost(). They allocate and populated the 280 * event using craftNanoappMessageFromHost(). 281 * 282 * @param craftedMessage Message from host to be delivered to the destination 283 * nanoapp 284 * 285 * @return true if the message was delivered to the event queue (i.e. 286 * destination app ID exists in the system) 287 */ 288 bool deliverNanoappMessageFromHost(MessageFromHost *craftedMessage); 289 290 /** 291 * Sends a message to the host from a nanoapp. This method also 292 * appropriately blames the nanoapp for sending a message or 293 * waking up the host. This function assumes both parameters 294 * are non-nullptr. 295 * 296 * @param nanoapp The sender of this message. 297 * @param msgToHost The message to send. 298 * 299 * @return Whether the message was successfully sent. 300 */ 301 bool doSendMessageToHostFromNanoapp(Nanoapp *nanoapp, 302 MessageToHost *msgToHost); 303 304 /** 305 * Find the message associated with the message sequence number if it exists. 306 * Returns nullptr other wise. 307 * 308 * @param messageSequenceNumber The message sequence number. 309 * @return The message or nullptr if not found. 310 */ 311 HostMessage *findMessageByMessageSequenceNumber( 312 uint32_t messageSequenceNumber); 313 314 /** 315 * Flushes all the pending reliable message transactions for a nanoapp. 316 * 317 * The completion callback is not called. However, 318 * onMessageToHostCompleteInternal is called for every message removed. 319 * 320 * @param nanoappInstanceId The nanoapp instance ID which 321 * transactions will be flushed. 322 * @return The number of flushed transactions. 323 */ 324 size_t flushNanoappTransactions(uint16_t nanoappInstanceId); 325 326 /** 327 * Releases memory associated with a message to the host, including invoking 328 * the Nanoapp's free callback (if given). Must be called from within the 329 * context of the EventLoop that contains the sending Nanoapp. 330 * 331 * @param msgToHost The message to free 332 */ 333 void freeMessageToHost(MessageToHost *msgToHost); 334 335 /** 336 * Event free callback used to release memory allocated to deliver a message 337 * to a nanoapp from the host. 338 * 339 * @param type Event type 340 * @param data Event data 341 */ 342 static void freeMessageFromHostCallback(uint16_t type, void *data); 343 344 /** 345 * Callback used to send a reliable message. 346 * 347 * @param data The message transaction data. 348 * @return Whether the message was sent successfully. 349 */ 350 static bool sendMessageWithTransactionData(MessageTransactionData &data); 351 352 /** 353 * Called when a reliable message transaction status is reported by the host. 354 * 355 * The status is delivered to the nanoapp that sent the message by posting a 356 * CHRE_EVENT_RELIABLE_MSG_ASYNC_STATUS event. 357 * 358 * @param data The message transaction data. 359 * @param errorCode The errorCode reported by the host from enum chreError. 360 * @return Whether the event was posted successfully. 361 * 362 */ 363 static bool onMessageDeliveryStatus(const MessageTransactionData &data, 364 uint8_t errorCode); 365 366 /** 367 * Invoked by onMessageToHostComplete for a non-reliable message 368 * or the TransactionManager for a reliable message when either 369 * are done with a message to the host. 370 * 371 * This function is thread-safe. 372 * 373 * @param message A message pointer previously given to HostLink::sendMessage 374 */ 375 void onMessageToHostCompleteInternal(const MessageToHost *msgToHost); 376 377 //! Ensures that we do not blame more than once per host wakeup. This is 378 //! checked before calling host blame to make sure it is set once. The power 379 //! control managers then reset back to false on host suspend. 380 AtomicBool mIsNanoappBlamedForWakeup{false}; 381 382 //! Memory pool used to allocate message metadata (but not the contents of the 383 //! messages themselves). Must be synchronized as the same HostCommsManager 384 //! handles communications for all EventLoops, and also to support freeing 385 //! messages directly in onMessageToHostComplete. 386 SynchronizedMemoryPool<HostMessage, kMaxOutstandingMessages> mMessagePool; 387 388 #ifdef CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED 389 //! The transaction manager for reliable messages. 390 TransactionManager<MessageTransactionData, kMaxOutstandingMessages> 391 mTransactionManager; 392 #endif // CHRE_RELIABLE_MESSAGE_SUPPORT_ENABLED 393 }; 394 395 } // namespace chre 396 397 #endif // CHRE_CORE_HOST_COMMS_MANAGER_H_ 398