• 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 #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