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 22 #include "chre/core/event_loop.h" 23 #include "chre/platform/atomic.h" 24 #include "chre/platform/host_link.h" 25 #include "chre/util/buffer.h" 26 #include "chre/util/non_copyable.h" 27 #include "chre/util/synchronized_memory_pool.h" 28 #include "chre_api/chre/event.h" 29 30 namespace chre { 31 32 //! Only valid for messages from host to CHRE - indicates that the sender of the 33 //! message is not specified. 34 constexpr uint16_t kHostEndpointUnspecified = CHRE_HOST_ENDPOINT_UNSPECIFIED; 35 36 //! Only valid for messages from CHRE to host - delivers the message to all 37 //! registered clients of the Context Hub HAL, which is the default behavior. 38 constexpr uint16_t kHostEndpointBroadcast = CHRE_HOST_ENDPOINT_BROADCAST; 39 40 /** 41 * Data associated with a message either to or from the host. 42 */ 43 struct HostMessage : public NonCopyable { 44 // This union must be first, as this structure is aliased with 45 // chreMessageFromHostData 46 union { 47 // Fields use when the message was received from the host 48 struct chreMessageFromHostData fromHostData; 49 50 // Fields used when the messsage is directed to the host 51 struct { 52 //! Application-specific message ID 53 uint32_t messageType; 54 55 //! List of Android permissions declared by the nanoapp. This must be a 56 //! superset of messagePermissions. 57 uint32_t appPermissions; 58 59 //! List of Android permissions that cover the contents of the message. 60 //! These permissions are used to record and attribute access to 61 //! permissions-controlled resources. 62 //! Note that these permissions must always be a subset of uint32_t 63 //! permissions. Otherwise, the message will be dropped. 64 uint32_t messagePermissions; 65 66 //! Message free callback supplied by the nanoapp. Must only be invoked 67 //! from the EventLoop where the nanoapp runs. 68 chreMessageFreeFunction *nanoappFreeFunction; 69 70 //! Identifier for the host-side entity that should receive this message, 71 //! or that which sent it 72 uint16_t hostEndpoint; 73 } toHostData; 74 }; 75 76 //! Source/destination nanoapp ID 77 uint64_t appId; 78 79 //! Application-defined message data 80 Buffer<uint8_t> message; 81 }; 82 83 typedef HostMessage MessageFromHost; 84 typedef HostMessage MessageToHost; 85 86 /** 87 * Common code for managing bi-directional communications between the host and 88 * nanoapps. Inherits from the platform-specific HostLink class to accomplish 89 * this, and also to provide an access point (lookup via the EventLoopManager 90 * Singleton) to the platform-specific HostLinkBase functionality for use by 91 * platform-specific code. 92 */ 93 class HostCommsManager : public HostLink { 94 public: HostCommsManager()95 HostCommsManager() : mIsNanoappBlamedForWakeup(false) {} 96 97 /** 98 * Formulates a MessageToHost using the supplied message contents and passes 99 * it to HostLink for transmission to the host. 100 * 101 * @param nanoapp The sender of this message 102 * @param messageData Pointer to message payload. Can be null if messageSize 103 * is 0. This buffer must remain valid until freeCallback is invoked. 104 * @param messageSize Size of the message to send, in bytes 105 * @param messageType Application-defined identifier for the message 106 * @param hostEndpoint Identifier for the entity on the host that should 107 * receive this message 108 * @param freeCallback Optional callback to invoke when the messageData is no 109 * longer needed (the message has been sent or an error occurred) 110 * @param messagePermissions List of Android permissions that cover the 111 * contents of the message. These permissions are used to record and 112 * attribute access to permissions-controlled resources. 113 * 114 * @return true if the message was accepted into the outbound message queue. 115 * If this function returns false, it does *not* invoke freeCallback. 116 * If it returns true, freeCallback will be invoked (if non-null) on 117 * either success or failure. 118 * 119 * @see chreSendMessageToHost 120 */ 121 bool sendMessageToHostFromNanoapp(Nanoapp *nanoapp, void *messageData, 122 size_t messageSize, uint32_t messageType, 123 uint16_t hostEndpoint, 124 uint32_t messagePermissions, 125 chreMessageFreeFunction *freeCallback); 126 127 /** 128 * Makes a copy of the supplied message data and posts it to the queue for 129 * later delivery to the addressed nanoapp. 130 * 131 * This function is safe to call from any thread. 132 * 133 * @param appId Identifier for the destination nanoapp 134 * @param messageType Application-defined message identifier 135 * @param hostEndpoint Identifier for the entity on the host that sent this 136 * message 137 * @param messageData Buffer containing application-specific message data; can 138 * be null if messageSize is 0 139 * @param messageSize Size of messageData, in bytes 140 */ 141 void sendMessageToNanoappFromHost(uint64_t appId, uint32_t messageType, 142 uint16_t hostEndpoint, 143 const void *messageData, 144 size_t messageSize); 145 146 /** 147 * This function is used by sendMessageToNanoappFromHost() for sending 148 * deferred messages. Messages are deferred when the destination nanoapp is 149 * not yet loaded. 150 * 151 * By the time this function is called through deferCallback, nanoapp load 152 * requests in the queue will have been processed and therefore all nanoapps 153 * are expected to be ready. 154 * 155 * @param craftedMessage Deferred message from host to be delivered to the 156 * destination nanoapp 157 */ 158 void sendDeferredMessageToNanoappFromHost(MessageFromHost *craftedMessage); 159 160 /* 161 * Resets mIsNanoappBlamedForWakeup to false so that 162 * nanoapp->blameHostWakeup() can be called again on next wakeup for one of 163 * the nanoapps. 164 */ 165 void resetBlameForNanoappHostWakeup(); 166 167 /** 168 * Invoked by the HostLink platform layer when it is done with a message to 169 * the host: either it successfully sent it, or encountered an error. 170 * 171 * This function is thread-safe. 172 * 173 * @param message A message pointer previously given to HostLink::sendMessage 174 */ 175 void onMessageToHostComplete(const MessageToHost *msgToHost); 176 177 private: 178 //! The maximum number of messages we can have outstanding at any given time 179 static constexpr size_t kMaxOutstandingMessages = 32; 180 181 //! Ensures that we do not blame more than once per host wakeup. This is 182 //! checked before calling host blame to make sure it is set once. The power 183 //! control managers then reset back to false on host suspend. 184 AtomicBool mIsNanoappBlamedForWakeup; 185 186 //! Memory pool used to allocate message metadata (but not the contents of the 187 //! messages themselves). Must be synchronized as the same HostCommsManager 188 //! handles communications for all EventLoops, and also to support freeing 189 //! messages directly in onMessageToHostComplete. 190 SynchronizedMemoryPool<HostMessage, kMaxOutstandingMessages> mMessagePool; 191 192 /** 193 * Allocates and populates the event structure used to notify a nanoapp of an 194 * incoming message from the host. 195 * 196 * Used to implement sendMessageToNanoappFromHost() - see that 197 * function for parameter documentation. 198 * 199 * All parameters must be sanitized before invoking this function. 200 * 201 * @see sendMessageToNanoappFromHost 202 */ 203 MessageFromHost *craftNanoappMessageFromHost(uint64_t appId, 204 uint16_t hostEndpoint, 205 uint32_t messageType, 206 const void *messageData, 207 uint32_t messageSize); 208 209 /** 210 * Posts a crafted event, craftedMessage, to a nanoapp for processing, and 211 * deallocates it afterwards. 212 * 213 * Used to implement sendMessageToNanoappFromHost() and 214 * sendDeferredMessageToNanoappFromHost(). They allocate and populated the 215 * event using craftNanoappMessageFromHost(). 216 * 217 * @param craftedMessage Message from host to be delivered to the destination 218 * nanoapp 219 * 220 * @return true if the message was delivered to the event queue (i.e. 221 * destination app ID exists in the system) 222 */ 223 bool deliverNanoappMessageFromHost(MessageFromHost *craftedMessage); 224 225 /** 226 * Releases memory associated with a message to the host, including invoking 227 * the Nanoapp's free callback (if given). Must be called from within the 228 * context of the EventLoop that contains the sending Nanoapp. 229 * 230 * @param msgToHost The message to free 231 */ 232 void freeMessageToHost(MessageToHost *msgToHost); 233 234 /** 235 * Event free callback used to release memory allocated to deliver a message 236 * to a nanoapp from the host. 237 * 238 * @param type Event type 239 * @param data Event data 240 */ 241 static void freeMessageFromHostCallback(uint16_t type, void *data); 242 }; 243 244 } // namespace chre 245 246 #endif // CHRE_CORE_HOST_COMMS_MANAGER_H_ 247