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/ble_l2cap_coc_socket_data.h" 24 #include "chre/core/nanoapp.h" 25 #include "chre/core/settings.h" 26 #include "chre/platform/shared/fbs/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/util/system/message_common.h" 31 #include "chre/util/system/system_callback_type.h" 32 #include "chre_api/chre/event.h" 33 #include "flatbuffers/flatbuffers.h" 34 35 #include "pw_allocator/unique_ptr.h" 36 37 namespace chre { 38 39 typedef flatbuffers::Offset<fbs::NanoappListEntry> NanoappListEntryOffset; 40 41 /** 42 * Checks that a string encapsulated as a byte vector is null-terminated, and 43 * if it is, returns a pointer to the vector's data. Otherwise returns null. 44 * 45 * This is similar to getStringFromByteVector in host_protocol_host.h. Ensure 46 * that method's implementation is kept in sync with this. 47 * 48 * @param vec Target vector, can be null 49 * 50 * @return Pointer to the vector's data, or null 51 */ 52 const char *getStringFromByteVector(const flatbuffers::Vector<int8_t> *vec); 53 54 /** 55 * These methods are called from decodeMessageFromHost() and must be implemented 56 * by the code that calls it to handle parsed messages. 57 */ 58 class HostMessageHandlers { 59 public: 60 struct LoadNanoappCallbackData { 61 uint64_t appId; 62 uint32_t transactionId; 63 uint16_t hostClientId; 64 UniquePtr<Nanoapp> nanoapp; 65 uint32_t fragmentId; 66 bool sendFragmentResponse; 67 }; 68 69 static void handleNanoappMessage(uint64_t appId, uint32_t messageType, 70 uint16_t hostEndpoint, 71 const void *messageData, 72 size_t messageDataLen, bool isReliable, 73 uint32_t messageSequenceNumber); 74 75 static void handleMessageDeliveryStatus(uint32_t messageSequenceNumber, 76 uint8_t errorCode); 77 78 static void handleHubInfoRequest(uint16_t hostClientId); 79 80 static void handleNanoappListRequest(uint16_t hostClientId); 81 82 static void handlePulseRequest(); 83 84 static void handleDebugConfiguration( 85 const fbs::DebugConfiguration *debugConfiguration); 86 87 static void handleLoadNanoappRequest( 88 uint16_t hostClientId, uint32_t transactionId, uint64_t appId, 89 uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion, 90 const void *buffer, size_t bufferLen, const char *appFileName, 91 uint32_t fragmentId, size_t appBinaryLen, bool respondBeforeStart); 92 93 static void handleUnloadNanoappRequest(uint16_t hostClientId, 94 uint32_t transactionId, uint64_t appId, 95 bool allowSystemNanoappUnload); 96 97 static void handleTimeSyncMessage(int64_t offset); 98 99 static void handleDebugDumpRequest(uint16_t hostClientId); 100 101 static void handleSettingChangeMessage(fbs::Setting setting, 102 fbs::SettingState state); 103 104 static void handleSelfTestRequest(uint16_t hostClientId); 105 106 static void handleNanConfigurationUpdate(bool enabled); 107 108 static void handleBtSocketOpen(uint64_t hubId, 109 const BleL2capCocSocketData &socketData, 110 const char *name, uint32_t psm); 111 112 static void handleBtSocketCapabilitiesRequest(); 113 114 private: 115 static void sendFragmentResponse(uint16_t hostClientId, 116 uint32_t transactionId, uint32_t fragmentId, 117 bool success); 118 119 static void finishLoadingNanoappCallback( 120 SystemCallbackType type, UniquePtr<LoadNanoappCallbackData> &&cbData); 121 122 /** 123 * Helper function that loads a nanoapp into the system 124 * from a buffer sent over in 1 or more fragments. 125 * 126 * @param hostClientId the ID of client that originated this transaction 127 * @param transactionId the ID of the transaction 128 * @param appId the ID of the app to load 129 * @param appVersion the version of the app to load 130 * @param appFlags The flags provided by the app being loaded 131 * @param targetApiVersion the API version this nanoapp is targeted for 132 * @param buffer the nanoapp binary data. May be only part of the nanoapp's 133 * binary if it's being sent over multiple fragments 134 * @param bufferLen the size of buffer in bytes 135 * @param fragmentId the identifier indicating which fragment is being loaded 136 * @param appBinaryLen the full size of the nanoapp binary to be loaded 137 * 138 * @return void 139 */ 140 static void loadNanoappData(uint16_t hostClientId, uint32_t transactionId, 141 uint64_t appId, uint32_t appVersion, 142 uint32_t appFlags, uint32_t targetApiVersion, 143 const void *buffer, size_t bufferLen, 144 uint32_t fragmentId, size_t appBinaryLen, 145 bool respondBeforeStart); 146 }; 147 148 /** 149 * A set of helper methods that simplify the encode/decode of FlatBuffers 150 * messages used in communications with the host from CHRE. 151 */ 152 class HostProtocolChre : public HostProtocolCommon { 153 public: 154 /** 155 * Verifies and decodes a FlatBuffers-encoded CHRE message. 156 * 157 * @param message Buffer containing message 158 * @param messageLen Size of the message, in bytes 159 * @param handlers Contains callbacks to process a decoded message 160 * 161 * @return bool true if the message was successfully decoded, false if it was 162 * corrupted/invalid/unrecognized 163 */ 164 static bool decodeMessageFromHost(const void *message, size_t messageLen); 165 166 /** 167 * Refer to the context hub HAL definition for a details of these 168 * parameters. 169 * 170 * @param builder A newly constructed ChreFlatBufferBuilder that will be 171 * used to encode the message 172 */ 173 static void encodeHubInfoResponse( 174 ChreFlatBufferBuilder &builder, const char *name, const char *vendor, 175 const char *toolchain, uint32_t legacyPlatformVersion, 176 uint32_t legacyToolchainVersion, float peakMips, float stoppedPower, 177 float sleepPower, float peakPower, uint32_t maxMessageLen, 178 uint64_t platformId, uint32_t version, uint16_t hostClientId, 179 bool supportsReliableMessages); 180 181 /** 182 * Supports construction of a NanoappListResponse by adding a single 183 * NanoappListEntry to the response. The offset for the newly added entry is 184 * maintained in the given vector until finishNanoappListResponse() is called. 185 * Example usage: 186 * 187 * ChreFlatBufferBuilder builder; 188 * DynamicVector<NanoappListEntryOffset> vector; 189 * for (auto app : appList) { 190 * HostProtocolChre::addNanoppListEntry(builder, vector, ...); 191 * } 192 * HostProtocolChre::finishNanoappListResponse(builder, vector); 193 * 194 * @param builder A ChreFlatBufferBuilder to use for encoding the message 195 * @param offsetVector A vector to track the offset to the newly added 196 * NanoappListEntry, which be passed to finishNanoappListResponse() 197 * once all entries are added 198 */ 199 static void addNanoappListEntry( 200 ChreFlatBufferBuilder &builder, 201 DynamicVector<NanoappListEntryOffset> &offsetVector, uint64_t appId, 202 uint32_t appVersion, bool enabled, bool isSystemNanoapp, 203 uint32_t appPermissions, 204 const DynamicVector<struct chreNanoappRpcService> &rpcServices); 205 206 /** 207 * Finishes encoding a NanoappListResponse message after all NanoappListEntry 208 * elements have already been added to the builder. 209 * 210 * @param builder The ChreFlatBufferBuilder used with addNanoappListEntry() 211 * @param offsetVector The vector used with addNanoappListEntry() 212 * @param hostClientId 213 * 214 * @see addNanoappListEntry() 215 */ 216 static void finishNanoappListResponse( 217 ChreFlatBufferBuilder &builder, 218 DynamicVector<NanoappListEntryOffset> &offsetVector, 219 uint16_t hostClientId); 220 221 /** 222 * Encodes a response to the host indicating CHRE is up running. 223 */ 224 static void encodePulseResponse(ChreFlatBufferBuilder &builder); 225 226 /** 227 * Encodes a response to the host communicating the result of dynamically 228 * loading a nanoapp. 229 */ 230 static void encodeLoadNanoappResponse(ChreFlatBufferBuilder &builder, 231 uint16_t hostClientId, 232 uint32_t transactionId, bool success, 233 uint32_t fragmentId); 234 235 /** 236 * Encodes a response to the host communicating the result of dynamically 237 * unloading a nanoapp. 238 */ 239 static void encodeUnloadNanoappResponse(ChreFlatBufferBuilder &builder, 240 uint16_t hostClientId, 241 uint32_t transactionId, bool success); 242 243 /** 244 * Encodes a nanoapp's instance ID and app ID to the host. 245 */ 246 static void encodeNanoappTokenDatabaseInfo(ChreFlatBufferBuilder &builder, 247 uint16_t instanceId, 248 uint64_t appId, 249 uint32_t tokenDatabaseOffset, 250 size_t tokenDatabaseSize); 251 252 /** 253 * Encodes a buffer of log messages to the host. 254 */ 255 static void encodeLogMessages(ChreFlatBufferBuilder &builder, 256 const uint8_t *logBuffer, size_t bufferSize); 257 258 /** 259 * Encodes a buffer of V2 log messages to the host. 260 */ 261 static void encodeLogMessagesV2(ChreFlatBufferBuilder &builder, 262 const uint8_t *logBuffer, size_t bufferSize, 263 uint32_t numLogsDropped); 264 265 /** 266 * Encodes a string into a DebugDumpData message. 267 * 268 * @param debugStr Null-terminated ASCII string containing debug information 269 * @param debugStrSize Size of the debugStr buffer, including null termination 270 */ 271 static void encodeDebugDumpData(ChreFlatBufferBuilder &builder, 272 uint16_t hostClientId, const char *debugStr, 273 size_t debugStrSize); 274 275 /** 276 * Encodes the final response to a debug dump request. 277 */ 278 static void encodeDebugDumpResponse(ChreFlatBufferBuilder &builder, 279 uint16_t hostClientId, bool success, 280 uint32_t dataCount); 281 282 /** 283 * Encodes a message requesting time sync from host. 284 */ 285 static void encodeTimeSyncRequest(ChreFlatBufferBuilder &builder); 286 287 /** 288 * Encodes a message notifying the host that audio has been requested by a 289 * nanoapp, so the low-power microphone needs to be powered on. 290 */ 291 static void encodeLowPowerMicAccessRequest(ChreFlatBufferBuilder &builder); 292 293 /** 294 * Encodes a message notifying the host that no nanoapps are requesting audio 295 * anymore, so the low-power microphone may be powered off. 296 */ 297 static void encodeLowPowerMicAccessRelease(ChreFlatBufferBuilder &builder); 298 299 /** 300 * @param state The fbs::Setting value. 301 * @param chreSetting If success, stores the corresponding 302 * chre::Setting value. 303 * 304 * @return true if state was a valid fbs::Setting value. 305 */ 306 static bool getSettingFromFbs(fbs::Setting setting, Setting *chreSetting); 307 308 /** 309 * @param state The fbs::SettingState value. 310 * @param chreSettingEnabled If success, stores the value indicating whether 311 * the setting is enabled or not. 312 * 313 * @return true if state was a valid fbs::SettingState value. 314 */ 315 static bool getSettingEnabledFromFbs(fbs::SettingState state, 316 bool *chreSettingEnabled); 317 318 /** 319 * Encodes a message notifying the result of a self test. 320 */ 321 static void encodeSelfTestResponse(ChreFlatBufferBuilder &builder, 322 uint16_t hostClientId, bool success); 323 324 /** 325 * Encodes a metric message using custon-defined protocol 326 */ 327 static void encodeMetricLog(ChreFlatBufferBuilder &builder, uint32_t metricId, 328 const uint8_t *encodedMsg, size_t metricSize); 329 330 /** 331 * Encodes a NAN configuration request. 332 * 333 * @param builder An instance of the CHRE Flatbuffer builder. 334 * @param enable Boolean to indicate the enable/disable operation being 335 * requested. 336 */ 337 static void encodeNanConfigurationRequest(ChreFlatBufferBuilder &builder, 338 bool enable); 339 340 /** 341 * Encodes a BT socket open response. 342 * 343 * @param builder An instance of the CHRE Flatbuffer builder. 344 * @param hostClientId Host client identifier. 345 * @param success Whether the socket open request was successful. 346 * @param reason Failure reason if success is false. 347 * @param socketId BT socket identifier. 348 */ 349 static void encodeBtSocketOpenResponse(ChreFlatBufferBuilder &builder, 350 uint16_t hostClientId, 351 uint64_t socketId, bool success, 352 const char *reason); 353 354 /** 355 * Encodes a BT socket close request. 356 * 357 * @param builder An instance of the CHRE Flatbuffer builder. 358 * @param hostClientId Host client identifier. 359 * @param reason Reason socket is being closed. 360 * @param socketId BT socket identifier. 361 */ 362 static void encodeBtSocketClose(ChreFlatBufferBuilder &builder, 363 uint16_t hostClientId, uint64_t socketId, 364 const char *reason); 365 366 /** 367 * Encodes a BT socket capabilities response. 368 * 369 * @param builder An instance of the CHRE Flatbuffer builder. 370 * @param leCocNumberOfSupportedSockets Number of LE CoC sockets supported. 371 * @param leCocMtu Max local MTU of LE CoC sockets. 372 * @param rfcommNumberOfSupportedSockets Number of RFCOMM sockets supported. 373 * @param rfcommMaxFrameSize Max frame size of RFCOMM sockets. 374 */ 375 static void encodeBtSocketGetCapabilitiesResponse( 376 ChreFlatBufferBuilder &builder, uint32_t leCocNumberOfSupportedSockets, 377 uint32_t leCocMtu, uint32_t rfcommNumberOfSupportedSockets, 378 uint32_t rfcommMaxFrameSize); 379 380 /** 381 * Encodes the response acking a GetMessageHubsAndEndpointsRequest. 382 * 383 * @param builder Builder which assembles and stores the message. 384 */ 385 static void encodeGetMessageHubsAndEndpointsResponse( 386 ChreFlatBufferBuilder &builder); 387 388 /** 389 * Encodes a new embedded hub notification. 390 * 391 * @param builder Builder which assembles and stores the message. 392 * @param hub Details of the new hub. 393 */ 394 static void encodeRegisterMessageHub(ChreFlatBufferBuilder &builder, 395 const message::MessageHubInfo &hub); 396 397 /** 398 * Encodes an embedded hub removal notification. 399 * 400 * @param builder Builder which assembles and stores the message. 401 * @param id Id of the unregistered hub. 402 */ 403 static void encodeUnregisterMessageHub(ChreFlatBufferBuilder &builder, 404 message::MessageHubId id); 405 406 /** 407 * Encodes a new embedded endpoint notification. 408 * 409 * @param builder Builder which assembles and stores the message. 410 * @param hub Id of the hub hosting the new endpoint. 411 * @param endpoint Details of the new endpoint. 412 */ 413 static void encodeRegisterEndpoint(ChreFlatBufferBuilder &builder, 414 message::MessageHubId hub, 415 const message::EndpointInfo &endpoint); 416 417 /** 418 * Encodes a notification to add a service hosted by a new embedded endpoint. 419 * 420 * @param builder Builder which assembles and stores the message. 421 * @param hub Id of the hub hosting the new endpoint. 422 * @param endpoint Id of the new endpoint. 423 * @param service The service being added. 424 */ 425 static void encodeAddServiceToEndpoint(ChreFlatBufferBuilder &builder, 426 message::MessageHubId hub, 427 message::EndpointId endpoint, 428 const message::ServiceInfo &service); 429 430 /** 431 * Encodes an embedded endpoint ready notification. 432 * 433 * @param builder Builder which assembles and stores the message. 434 * @param hub Id of the hub hosting the new endpoint. 435 * @param endpoint Id of the new endpoint. 436 */ 437 static void encodeEndpointReady(ChreFlatBufferBuilder &builder, 438 message::MessageHubId hub, 439 message::EndpointId endpoint); 440 441 /** 442 * Encodes an embedded endpoint removal notification. 443 * 444 * @param builder Builder which assembles and stores the message. 445 * @param hub Id of the hub hosting the removed endpoint. 446 * @param endpoint Id of the removed endpoint. 447 */ 448 static void encodeUnregisterEndpoint(ChreFlatBufferBuilder &builder, 449 message::MessageHubId hub, 450 message::EndpointId endpoint); 451 452 /** 453 * Encodes a request to open a new session with host endpoint. 454 * 455 * @param builder Builder which assembles and stores the message. 456 * @param session Details of the new session. 457 */ 458 static void encodeOpenEndpointSessionRequest(ChreFlatBufferBuilder &builder, 459 const message::Session &session); 460 461 /** 462 * Encodes a notification that a session has been opened. 463 * 464 * @param builder Builder which assembles and stores the message. 465 * @param hub Id of the destination host hub. 466 * @param session Id of the session that was opened. 467 */ 468 static void encodeEndpointSessionOpened(ChreFlatBufferBuilder &builder, 469 message::MessageHubId hub, 470 message::SessionId session); 471 472 /** 473 * Encodes a notification that a session has been closed. 474 * 475 * @param builder Builder which assembles and stores the message. 476 * @param hub Id of the destination host hub. 477 * @param session Id of the session that was closed. 478 * @param reason Reason the session was closed (or rejected). 479 */ 480 static void encodeEndpointSessionClosed(ChreFlatBufferBuilder &builder, 481 message::MessageHubId hub, 482 message::SessionId session, 483 message::Reason reason); 484 485 /** 486 * Encodes a message sent within an endpoint session. 487 * 488 * @param builder Builder which assembles and stores the message. 489 * @param hub Id of the destination host hub. 490 * @param session Id of the session. 491 * @param data The message data. 492 * @param type The type of the message. 493 * @param permissions The permissions required to receive the message. 494 */ 495 static void encodeEndpointSessionMessage(ChreFlatBufferBuilder &builder, 496 message::MessageHubId hub, 497 message::SessionId session, 498 pw::UniquePtr<std::byte[]> &&data, 499 uint32_t type, uint32_t permissions); 500 }; 501 502 } // namespace chre 503 504 #endif // CHRE_PLATFORM_SHARED_HOST_PROTOCOL_CHRE_H_ 505