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_PLATFORM_SHARED_HOST_PROTOCOL_CHRE_H_ 18 #define CHRE_PLATFORM_SHARED_HOST_PROTOCOL_CHRE_H_ 19 20 #include <stdint.h> 21 22 #include "chre/core/event_loop_common.h" 23 #include "chre/core/nanoapp.h" 24 #include "chre/core/settings.h" 25 #include "chre/platform/shared/generated/host_messages_generated.h" 26 #include "chre/platform/shared/host_protocol_common.h" 27 #include "chre/util/dynamic_vector.h" 28 #include "chre/util/flatbuffers/helpers.h" 29 #include "chre_api/chre/event.h" 30 #include "flatbuffers/flatbuffers.h" 31 32 namespace chre { 33 34 typedef flatbuffers::Offset<fbs::NanoappListEntry> NanoappListEntryOffset; 35 36 /** 37 * Checks that a string encapsulated as a byte vector is null-terminated, and 38 * if it is, returns a pointer to the vector's data. Otherwise returns null. 39 * 40 * This is similar to getStringFromByteVector in host_protocol_host.h. Ensure 41 * that method's implementation is kept in sync with this. 42 * 43 * @param vec Target vector, can be null 44 * 45 * @return Pointer to the vector's data, or null 46 */ 47 const char *getStringFromByteVector(const flatbuffers::Vector<int8_t> *vec); 48 49 /** 50 * These methods are called from decodeMessageFromHost() and must be implemented 51 * by the code that calls it to handle parsed messages. 52 */ 53 class HostMessageHandlers { 54 public: 55 struct LoadNanoappCallbackData { 56 uint64_t appId; 57 uint32_t transactionId; 58 uint16_t hostClientId; 59 UniquePtr<Nanoapp> nanoapp; 60 uint32_t fragmentId; 61 bool sendFragmentResponse; 62 }; 63 64 static void handleNanoappMessage(uint64_t appId, uint32_t messageType, 65 uint16_t hostEndpoint, 66 const void *messageData, 67 size_t messageDataLen, bool isReliable, 68 uint32_t messageSequenceNumber); 69 70 static void handleMessageDeliveryStatus(uint32_t messageSequenceNumber, 71 uint8_t errorCode); 72 73 static void handleHubInfoRequest(uint16_t hostClientId); 74 75 static void handleNanoappListRequest(uint16_t hostClientId); 76 77 static void handlePulseRequest(); 78 79 static void handleDebugConfiguration( 80 const fbs::DebugConfiguration *debugConfiguration); 81 82 static void handleLoadNanoappRequest( 83 uint16_t hostClientId, uint32_t transactionId, uint64_t appId, 84 uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion, 85 const void *buffer, size_t bufferLen, const char *appFileName, 86 uint32_t fragmentId, size_t appBinaryLen, bool respondBeforeStart); 87 88 static void handleUnloadNanoappRequest(uint16_t hostClientId, 89 uint32_t transactionId, uint64_t appId, 90 bool allowSystemNanoappUnload); 91 92 static void handleTimeSyncMessage(int64_t offset); 93 94 static void handleDebugDumpRequest(uint16_t hostClientId); 95 96 static void handleSettingChangeMessage(fbs::Setting setting, 97 fbs::SettingState state); 98 99 static void handleSelfTestRequest(uint16_t hostClientId); 100 101 static void handleNanConfigurationUpdate(bool enabled); 102 103 private: 104 static void sendFragmentResponse(uint16_t hostClientId, 105 uint32_t transactionId, uint32_t fragmentId, 106 bool success); 107 108 static void finishLoadingNanoappCallback( 109 SystemCallbackType type, UniquePtr<LoadNanoappCallbackData> &&cbData); 110 111 /** 112 * Helper function that loads a nanoapp into the system 113 * from a buffer sent over in 1 or more fragments. 114 * 115 * @param hostClientId the ID of client that originated this transaction 116 * @param transactionId the ID of the transaction 117 * @param appId the ID of the app to load 118 * @param appVersion the version of the app to load 119 * @param appFlags The flags provided by the app being loaded 120 * @param targetApiVersion the API version this nanoapp is targeted for 121 * @param buffer the nanoapp binary data. May be only part of the nanoapp's 122 * binary if it's being sent over multiple fragments 123 * @param bufferLen the size of buffer in bytes 124 * @param fragmentId the identifier indicating which fragment is being loaded 125 * @param appBinaryLen the full size of the nanoapp binary to be loaded 126 * 127 * @return void 128 */ 129 static void loadNanoappData(uint16_t hostClientId, uint32_t transactionId, 130 uint64_t appId, uint32_t appVersion, 131 uint32_t appFlags, uint32_t targetApiVersion, 132 const void *buffer, size_t bufferLen, 133 uint32_t fragmentId, size_t appBinaryLen, 134 bool respondBeforeStart); 135 }; 136 137 /** 138 * A set of helper methods that simplify the encode/decode of FlatBuffers 139 * messages used in communications with the host from CHRE. 140 */ 141 class HostProtocolChre : public HostProtocolCommon { 142 public: 143 /** 144 * Verifies and decodes a FlatBuffers-encoded CHRE message. 145 * 146 * @param message Buffer containing message 147 * @param messageLen Size of the message, in bytes 148 * @param handlers Contains callbacks to process a decoded message 149 * 150 * @return bool true if the message was successfully decoded, false if it was 151 * corrupted/invalid/unrecognized 152 */ 153 static bool decodeMessageFromHost(const void *message, size_t messageLen); 154 155 /** 156 * Refer to the context hub HAL definition for a details of these parameters. 157 * 158 * @param builder A newly constructed ChreFlatBufferBuilder that will be used 159 * to encode the message 160 */ 161 static void encodeHubInfoResponse( 162 ChreFlatBufferBuilder &builder, const char *name, const char *vendor, 163 const char *toolchain, uint32_t legacyPlatformVersion, 164 uint32_t legacyToolchainVersion, float peakMips, float stoppedPower, 165 float sleepPower, float peakPower, uint32_t maxMessageLen, 166 uint64_t platformId, uint32_t version, uint16_t hostClientId, 167 bool supportsReliableMessages); 168 169 /** 170 * Supports construction of a NanoappListResponse by adding a single 171 * NanoappListEntry to the response. The offset for the newly added entry is 172 * maintained in the given vector until finishNanoappListResponse() is called. 173 * Example usage: 174 * 175 * ChreFlatBufferBuilder builder; 176 * DynamicVector<NanoappListEntryOffset> vector; 177 * for (auto app : appList) { 178 * HostProtocolChre::addNanoppListEntry(builder, vector, ...); 179 * } 180 * HostProtocolChre::finishNanoappListResponse(builder, vector); 181 * 182 * @param builder A ChreFlatBufferBuilder to use for encoding the message 183 * @param offsetVector A vector to track the offset to the newly added 184 * NanoappListEntry, which be passed to finishNanoappListResponse() 185 * once all entries are added 186 */ 187 static void addNanoappListEntry( 188 ChreFlatBufferBuilder &builder, 189 DynamicVector<NanoappListEntryOffset> &offsetVector, uint64_t appId, 190 uint32_t appVersion, bool enabled, bool isSystemNanoapp, 191 uint32_t appPermissions, 192 const DynamicVector<struct chreNanoappRpcService> &rpcServices); 193 194 /** 195 * Finishes encoding a NanoappListResponse message after all NanoappListEntry 196 * elements have already been added to the builder. 197 * 198 * @param builder The ChreFlatBufferBuilder used with addNanoappListEntry() 199 * @param offsetVector The vector used with addNanoappListEntry() 200 * @param hostClientId 201 * 202 * @see addNanoappListEntry() 203 */ 204 static void finishNanoappListResponse( 205 ChreFlatBufferBuilder &builder, 206 DynamicVector<NanoappListEntryOffset> &offsetVector, 207 uint16_t hostClientId); 208 209 /** 210 * Encodes a response to the host indicating CHRE is up running. 211 */ 212 static void encodePulseResponse(ChreFlatBufferBuilder &builder); 213 214 /** 215 * Encodes a response to the host communicating the result of dynamically 216 * loading a nanoapp. 217 */ 218 static void encodeLoadNanoappResponse(ChreFlatBufferBuilder &builder, 219 uint16_t hostClientId, 220 uint32_t transactionId, bool success, 221 uint32_t fragmentId); 222 223 /** 224 * Encodes a response to the host communicating the result of dynamically 225 * unloading a nanoapp. 226 */ 227 static void encodeUnloadNanoappResponse(ChreFlatBufferBuilder &builder, 228 uint16_t hostClientId, 229 uint32_t transactionId, bool success); 230 231 /** 232 * Encodes a nanoapp's instance ID and app ID to the host. 233 */ 234 static void encodeNanoappTokenDatabaseInfo(ChreFlatBufferBuilder &builder, 235 uint16_t instanceId, 236 uint64_t appId, 237 uint32_t tokenDatabaseOffset, 238 size_t tokenDatabaseSize); 239 240 /** 241 * Encodes a buffer of log messages to the host. 242 */ 243 static void encodeLogMessages(ChreFlatBufferBuilder &builder, 244 const uint8_t *logBuffer, size_t bufferSize); 245 246 /** 247 * Encodes a buffer of V2 log messages to the host. 248 */ 249 static void encodeLogMessagesV2(ChreFlatBufferBuilder &builder, 250 const uint8_t *logBuffer, size_t bufferSize, 251 uint32_t numLogsDropped); 252 253 /** 254 * Encodes a string into a DebugDumpData message. 255 * 256 * @param debugStr Null-terminated ASCII string containing debug information 257 * @param debugStrSize Size of the debugStr buffer, including null termination 258 */ 259 static void encodeDebugDumpData(ChreFlatBufferBuilder &builder, 260 uint16_t hostClientId, const char *debugStr, 261 size_t debugStrSize); 262 263 /** 264 * Encodes the final response to a debug dump request. 265 */ 266 static void encodeDebugDumpResponse(ChreFlatBufferBuilder &builder, 267 uint16_t hostClientId, bool success, 268 uint32_t dataCount); 269 270 /** 271 * Encodes a message requesting time sync from host. 272 */ 273 static void encodeTimeSyncRequest(ChreFlatBufferBuilder &builder); 274 275 /** 276 * Encodes a message notifying the host that audio has been requested by a 277 * nanoapp, so the low-power microphone needs to be powered on. 278 */ 279 static void encodeLowPowerMicAccessRequest(ChreFlatBufferBuilder &builder); 280 281 /** 282 * Encodes a message notifying the host that no nanoapps are requesting audio 283 * anymore, so the low-power microphone may be powered off. 284 */ 285 static void encodeLowPowerMicAccessRelease(ChreFlatBufferBuilder &builder); 286 287 /** 288 * @param state The fbs::Setting value. 289 * @param chreSetting If success, stores the corresponding 290 * chre::Setting value. 291 * 292 * @return true if state was a valid fbs::Setting value. 293 */ 294 static bool getSettingFromFbs(fbs::Setting setting, Setting *chreSetting); 295 296 /** 297 * @param state The fbs::SettingState value. 298 * @param chreSettingEnabled If success, stores the value indicating whether 299 * the setting is enabled or not. 300 * 301 * @return true if state was a valid fbs::SettingState value. 302 */ 303 static bool getSettingEnabledFromFbs(fbs::SettingState state, 304 bool *chreSettingEnabled); 305 306 /** 307 * Encodes a message notifying the result of a self test. 308 */ 309 static void encodeSelfTestResponse(ChreFlatBufferBuilder &builder, 310 uint16_t hostClientId, bool success); 311 312 /** 313 * Encodes a metric message using custon-defined protocol 314 */ 315 static void encodeMetricLog(ChreFlatBufferBuilder &builder, uint32_t metricId, 316 const uint8_t *encodedMsg, size_t metricSize); 317 318 /** 319 * Encodes a NAN configuration request. 320 * 321 * @param builder An instance of the CHRE Flatbuffer builder. 322 * @param enable Boolean to indicate the enable/disable operation being 323 * requested. 324 */ 325 static void encodeNanConfigurationRequest(ChreFlatBufferBuilder &builder, 326 bool enable); 327 }; 328 329 } // namespace chre 330 331 #endif // CHRE_PLATFORM_SHARED_HOST_PROTOCOL_CHRE_H_ 332