• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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