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_api/chre/event.h" 23 #include "chre/core/event_loop.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 29 namespace chre { 30 31 //! Only valid for messages from host to CHRE - indicates that the sender of the 32 //! message is not specified. 33 constexpr uint16_t kHostEndpointUnspecified = CHRE_HOST_ENDPOINT_UNSPECIFIED; 34 35 //! Only valid for messages from CHRE to host - delivers the message to all 36 //! registered clients of the Context Hub HAL, which is the default behavior. 37 constexpr uint16_t kHostEndpointBroadcast = CHRE_HOST_ENDPOINT_BROADCAST; 38 39 /** 40 * Data associated with a message either to or from the host. 41 */ 42 struct HostMessage : public NonCopyable { 43 // This union must be first, as this structure is aliased with 44 // chreMessageFromHostData 45 union { 46 // Fields use when the message was received from the host 47 struct chreMessageFromHostData fromHostData; 48 49 // Fields used when the messsage is directed to the host 50 struct { 51 //! Application-specific message ID 52 uint32_t messageType; 53 54 //! Padding used to align this structure with chreMessageFromHostData 55 uint32_t reserved; 56 57 //! Message free callback supplied by the nanoapp. Must only be invoked from 58 //! the EventLoop where the nanoapp runs. 59 chreMessageFreeFunction *nanoappFreeFunction; 60 61 //! Identifier for the host-side entity that should receive this message, or 62 //! that which sent it 63 uint16_t hostEndpoint; 64 } toHostData; 65 }; 66 67 //! Source/destination nanoapp ID 68 uint64_t appId; 69 70 //! Application-defined message data 71 Buffer<uint8_t> message; 72 }; 73 74 typedef HostMessage MessageFromHost; 75 typedef HostMessage MessageToHost; 76 77 /** 78 * Manages bi-directional communications with the host. There must only be one 79 * instance of this class per CHRE instance, as the HostLink is not multiplexed 80 * per-EventLoop. 81 */ 82 class HostCommsManager : public NonCopyable { 83 public: 84 /** 85 * @see HostLink::flushMessagesSentByNanoapp 86 */ 87 void flushMessagesSentByNanoapp(uint64_t appId); 88 89 /** 90 * Formulates a MessageToHost using the supplied message contents and passes 91 * it to HostLink for transmission to the host. 92 * 93 * @param nanoapp The sender of this message 94 * @param messageData Pointer to message payload. Can be null if messageSize 95 * is 0. This buffer must remain valid until freeCallback is invoked. 96 * @param messageSize Size of the message to send, in bytes 97 * @param messageType Application-defined identifier for the message 98 * @param hostEndpoint Identifier for the entity on the host that should 99 * receive this message 100 * @param freeCallback Optional callback to invoke when the messageData is no 101 * longer needed (the message has been sent or an error occurred) 102 * 103 * @return true if the message was accepted into the outbound message queue. 104 * If this function returns false, it does *not* invoke freeCallback. 105 * If it returns true, freeCallback will be invoked (if non-null) on 106 * either success or failure. 107 * 108 * @see chreSendMessageToHost 109 */ 110 bool sendMessageToHostFromNanoapp( 111 Nanoapp *nanoapp, void *messageData, size_t messageSize, 112 uint32_t messageType, uint16_t hostEndpoint, 113 chreMessageFreeFunction *freeCallback); 114 115 /** 116 * Makes a copy of the supplied message data and posts it to the queue for 117 * later delivery to the addressed nanoapp. 118 * 119 * This function is safe to call from any thread. 120 * 121 * @param appId Identifier for the destination nanoapp 122 * @param messageType Application-defined message identifier 123 * @param hostEndpoint Identifier for the entity on the host that sent this 124 * message 125 * @param messageData Buffer containing application-specific message data; can 126 * be null if messageSize is 0 127 * @param messageSize Size of messageData, in bytes 128 */ 129 void sendMessageToNanoappFromHost( 130 uint64_t appId, uint32_t messageType, uint16_t hostEndpoint, 131 const void *messageData, size_t messageSize); 132 133 /** 134 * Invoked by the HostLink platform layer when it is done with a message to 135 * the host: either it successfully sent it, or encountered an error. 136 * 137 * This function is thread-safe. 138 * 139 * @param message A message pointer previously given to HostLink::sendMessage 140 */ 141 void onMessageToHostComplete(const MessageToHost *msgToHost); 142 143 private: 144 //! The maximum number of messages we can have outstanding at any given time 145 static constexpr size_t kMaxOutstandingMessages = 32; 146 147 //! Memory pool used to allocate message metadata (but not the contents of the 148 //! messages themselves). Must be synchronized as the same HostCommsManager 149 //! handles communications for all EventLoops, and also to support freeing 150 //! messages directly in onMessageToHostComplete. 151 SynchronizedMemoryPool<HostMessage, kMaxOutstandingMessages> mMessagePool; 152 153 //! The platform-specific link to the host that we manage 154 HostLink mHostLink; 155 156 /** 157 * Allocates and populates the event structure used to notify a nanoapp of an 158 * incoming message from the host, and posts an event to the nanoapp for 159 * processing. Used to implement sendMessageToNanoappFromHost() - see that 160 * function for parameter documentation. 161 * 162 * All parameters must be sanitized before invoking this function. 163 * 164 * @param targetInstanceId Instance ID of the destination nanoapp 165 * 166 * @see sendMessageToNanoappFromHost 167 */ 168 void deliverNanoappMessageFromHost( 169 uint64_t appId, uint16_t hostEndpoint, uint32_t messageType, 170 const void *messageData, uint32_t messageSize, uint32_t targetInstanceId); 171 172 /** 173 * Releases memory associated with a message to the host, including invoking 174 * the Nanoapp's free callback (if given). Must be called from within the 175 * context of the EventLoop that contains the sending Nanoapp. 176 * 177 * @param msgToHost The message to free 178 */ 179 void freeMessageToHost(MessageToHost *msgToHost); 180 181 /** 182 * Event free callback used to release memory allocated to deliver a message 183 * to a nanoapp from the host. 184 * 185 * @param type Event type 186 * @param data Event data 187 */ 188 static void freeMessageFromHostCallback(uint16_t type, void *data); 189 }; 190 191 } // namespace chre 192 193 #endif // CHRE_CORE_HOST_COMMS_MANAGER_H_ 194