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