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