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