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/dynamic_vector.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 DynamicVector<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 * Formulates a MessageToHost using the supplied message contents and passes 86 * it to HostLink for transmission to the host. 87 * 88 * @param messageData Pointer to message payload. Can be null if messageSize 89 * is 0. This buffer must remain valid until freeCallback is invoked. 90 * @param messageSize Size of the message to send, in bytes 91 * @param messageType Application-defined identifier for the message 92 * @param hostEndpoint Identifier for the entity on the host that should 93 * receive this message 94 * @param freeCallback Optional callback to invoke when the messageData is no 95 * longer needed (the message has been sent or an error occurred) 96 * 97 * @return true if the message was accepted into the outbound message queue 98 * 99 * @see chreSendMessageToHost 100 */ 101 bool sendMessageToHostFromCurrentNanoapp( 102 void *messageData, size_t messageSize, uint32_t messageType, 103 uint16_t hostEndpoint, chreMessageFreeFunction *freeCallback); 104 105 /** 106 * Makes a copy of the supplied message data and posts it to the queue for 107 * later delivery to the addressed nanoapp. 108 * 109 * This function is safe to call from any thread. 110 * 111 * @param appId Identifier for the destination nanoapp 112 * @param messageType Application-defined message identifier 113 * @param hostEndpoint Identifier for the entity on the host that sent this 114 * message 115 * @param messageData Buffer containing application-specific message data; can 116 * be null if messageSize is 0 117 * @param messageSize Size of messageData, in bytes 118 */ 119 void sendMessageToNanoappFromHost( 120 uint64_t appId, uint32_t messageType, uint16_t hostEndpoint, 121 const void *messageData, size_t messageSize); 122 123 /** 124 * Invoked by the HostLink platform layer when it is done with a message to 125 * the host: either it successfully sent it, or encountered an error. 126 * 127 * This function is thread-safe. 128 * 129 * @param message A message pointer previously given to HostLink::sendMessage 130 */ 131 void onMessageToHostComplete(const MessageToHost *msgToHost); 132 133 private: 134 //! The maximum number of messages we can have outstanding at any given time 135 static constexpr size_t kMaxOutstandingMessages = 32; 136 137 //! Memory pool used to allocate message metadata (but not the contents of the 138 //! messages themselves). Must be synchronized as the same HostCommsManager 139 //! handles communications for all EventLoops, and also to support freeing 140 //! messages directly in onMessageToHostComplete. 141 SynchronizedMemoryPool<HostMessage, kMaxOutstandingMessages> mMessagePool; 142 143 //! The platform-specific link to the host that we manage 144 HostLink mHostLink; 145 146 /** 147 * Allocates and populates the event structure used to notify a nanoapp of an 148 * incoming message from the host, and posts an event to the nanoapp for 149 * processing. Used to implement sendMessageToNanoappFromHost() - see that 150 * function for parameter documentation. 151 * 152 * All parameters must be sanitized before invoking this function. 153 * 154 * @param targetEventLoop EventLoop containing the target app 155 * @param targetInstanceId Instance ID of the destination nanoapp 156 * 157 * @see sendMessageToNanoappFromHost 158 */ 159 void deliverNanoappMessageFromHost( 160 uint64_t appId, uint16_t hostEndpoint, uint32_t messageType, 161 const void *messageData, uint32_t messageSize, EventLoop *targetEventLoop, 162 uint32_t targetInstanceId); 163 164 /** 165 * Releases memory associated with a message to the host, including invoking 166 * the Nanoapp's free callback (if given). Must be called from within the 167 * context of the EventLoop that contains the sending Nanoapp. 168 * 169 * @param msgToHost The message to free 170 */ 171 void freeMessageToHost(MessageToHost *msgToHost); 172 173 /** 174 * Event free callback used to release memory allocated to deliver a message 175 * to a nanoapp from the host. 176 * 177 * @param type Event type 178 * @param data Event data 179 */ 180 static void freeMessageFromHostCallback(uint16_t type, void *data); 181 }; 182 183 } // namespace chre 184 185 #endif // CHRE_CORE_HOST_COMMS_MANAGER_H_ 186