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/settings.h"
23 #include "chre/platform/shared/generated/host_messages_generated.h"
24 #include "chre/platform/shared/host_protocol_common.h"
25 #include "chre/util/dynamic_vector.h"
26 #include "chre/util/flatbuffers/helpers.h"
27 #include "flatbuffers/flatbuffers.h"
28 
29 namespace chre {
30 
31 typedef flatbuffers::Offset<fbs::NanoappListEntry> NanoappListEntryOffset;
32 
33 /**
34  * Checks that a string encapsulated as a byte vector is null-terminated, and
35  * if it is, returns a pointer to the vector's data. Otherwise returns null.
36  *
37  * This is similar to getStringFromByteVector in host_protocol_host.h. Ensure
38  * that method's implementation is kept in sync with this.
39  *
40  * @param vec Target vector, can be null
41  *
42  * @return Pointer to the vector's data, or null
43  */
44 const char *getStringFromByteVector(const flatbuffers::Vector<int8_t> *vec);
45 
46 /**
47  * These methods are called from decodeMessageFromHost() and must be implemented
48  * by the code that calls it to handle parsed messages.
49  */
50 class HostMessageHandlers {
51  public:
52   static void handleNanoappMessage(uint64_t appId, uint32_t messageType,
53                                    uint16_t hostEndpoint,
54                                    const void *messageData,
55                                    size_t messageDataLen);
56 
57   static void handleHubInfoRequest(uint16_t hostClientId);
58 
59   static void handleNanoappListRequest(uint16_t hostClientId);
60 
61   static void handleLoadNanoappRequest(
62       uint16_t hostClientId, uint32_t transactionId, uint64_t appId,
63       uint32_t appVersion, uint32_t appFlags, uint32_t targetApiVersion,
64       const void *buffer, size_t bufferLen, const char *appFileName,
65       uint32_t fragmentId, size_t appBinaryLen, bool respondBeforeStart);
66 
67   static void handleUnloadNanoappRequest(uint16_t hostClientId,
68                                          uint32_t transactionId, uint64_t appId,
69                                          bool allowSystemNanoappUnload);
70 
71   static void handleTimeSyncMessage(int64_t offset);
72 
73   static void handleDebugDumpRequest(uint16_t hostClientId);
74 
75   static void handleSettingChangeMessage(fbs::Setting setting,
76                                          fbs::SettingState state);
77 
78   static void handleSelfTestRequest(uint16_t hostClientId);
79 };
80 
81 /**
82  * A set of helper methods that simplify the encode/decode of FlatBuffers
83  * messages used in communications with the host from CHRE.
84  */
85 class HostProtocolChre : public HostProtocolCommon {
86  public:
87   /**
88    * Verifies and decodes a FlatBuffers-encoded CHRE message.
89    *
90    * @param message Buffer containing message
91    * @param messageLen Size of the message, in bytes
92    * @param handlers Contains callbacks to process a decoded message
93    *
94    * @return bool true if the message was successfully decoded, false if it was
95    *         corrupted/invalid/unrecognized
96    */
97   static bool decodeMessageFromHost(const void *message, size_t messageLen);
98 
99   /**
100    * Refer to the context hub HAL definition for a details of these parameters.
101    *
102    * @param builder A newly constructed ChreFlatBufferBuilder that will be used
103    * to encode the message
104    */
105   static void encodeHubInfoResponse(
106       ChreFlatBufferBuilder &builder, const char *name, const char *vendor,
107       const char *toolchain, uint32_t legacyPlatformVersion,
108       uint32_t legacyToolchainVersion, float peakMips, float stoppedPower,
109       float sleepPower, float peakPower, uint32_t maxMessageLen,
110       uint64_t platformId, uint32_t version, uint16_t hostClientId);
111 
112   /**
113    * Supports construction of a NanoappListResponse by adding a single
114    * NanoappListEntry to the response. The offset for the newly added entry is
115    * maintained in the given vector until finishNanoappListResponse() is called.
116    * Example usage:
117    *
118    *   ChreFlatBufferBuilder builder;
119    *   DynamicVector<NanoappListEntryOffset> vector;
120    *   for (auto app : appList) {
121    *     HostProtocolChre::addNanoppListEntry(builder, vector, ...);
122    *   }
123    *   HostProtocolChre::finishNanoappListResponse(builder, vector);
124    *
125    * @param builder A ChreFlatBufferBuilder to use for encoding the message
126    * @param offsetVector A vector to track the offset to the newly added
127    *        NanoappListEntry, which be passed to finishNanoappListResponse()
128    *        once all entries are added
129    */
130   static void addNanoappListEntry(
131       ChreFlatBufferBuilder &builder,
132       DynamicVector<NanoappListEntryOffset> &offsetVector, uint64_t appId,
133       uint32_t appVersion, bool enabled, bool isSystemNanoapp,
134       uint32_t appPermissions);
135 
136   /**
137    * Finishes encoding a NanoappListResponse message after all NanoappListEntry
138    * elements have already been added to the builder.
139    *
140    * @param builder The ChreFlatBufferBuilder used with addNanoappListEntry()
141    * @param offsetVector The vector used with addNanoappListEntry()
142    * @param hostClientId
143    *
144    * @see addNanoappListEntry()
145    */
146   static void finishNanoappListResponse(
147       ChreFlatBufferBuilder &builder,
148       DynamicVector<NanoappListEntryOffset> &offsetVector,
149       uint16_t hostClientId);
150 
151   /**
152    * Encodes a response to the host communicating the result of dynamically
153    * loading a nanoapp.
154    */
155   static void encodeLoadNanoappResponse(ChreFlatBufferBuilder &builder,
156                                         uint16_t hostClientId,
157                                         uint32_t transactionId, bool success,
158                                         uint32_t fragmentId);
159 
160   /**
161    * Encodes a response to the host communicating the result of dynamically
162    * unloading a nanoapp.
163    */
164   static void encodeUnloadNanoappResponse(ChreFlatBufferBuilder &builder,
165                                           uint16_t hostClientId,
166                                           uint32_t transactionId, bool success);
167 
168   /**
169    * Encodes a buffer of log messages to the host.
170    */
171   static void encodeLogMessages(ChreFlatBufferBuilder &builder,
172                                 const uint8_t *logBuffer, size_t bufferSize);
173 
174   /**
175    * Encodes a buffer of V2 log messages to the host.
176    */
177   static void encodeLogMessagesV2(ChreFlatBufferBuilder &builder,
178                                   const uint8_t *logBuffer, size_t bufferSize,
179                                   uint32_t numLogsDropped);
180 
181   /**
182    * Encodes a string into a DebugDumpData message.
183    *
184    * @param debugStr Null-terminated ASCII string containing debug information
185    * @param debugStrSize Size of the debugStr buffer, including null termination
186    */
187   static void encodeDebugDumpData(ChreFlatBufferBuilder &builder,
188                                   uint16_t hostClientId, const char *debugStr,
189                                   size_t debugStrSize);
190 
191   /**
192    * Encodes the final response to a debug dump request.
193    */
194   static void encodeDebugDumpResponse(ChreFlatBufferBuilder &builder,
195                                       uint16_t hostClientId, bool success,
196                                       uint32_t dataCount);
197 
198   /**
199    * Encodes a message requesting time sync from host.
200    */
201   static void encodeTimeSyncRequest(ChreFlatBufferBuilder &builder);
202 
203   /**
204    * Encodes a message notifying the host that audio has been requested by a
205    * nanoapp, so the low-power microphone needs to be powered on.
206    */
207   static void encodeLowPowerMicAccessRequest(ChreFlatBufferBuilder &builder);
208 
209   /**
210    * Encodes a message notifying the host that no nanoapps are requesting audio
211    * anymore, so the low-power microphone may be powered off.
212    */
213   static void encodeLowPowerMicAccessRelease(ChreFlatBufferBuilder &builder);
214 
215   /**
216    * @param state The fbs::Setting value.
217    * @param chreSetting If success, stores the corresponding
218    * chre::Setting value.
219    *
220    * @return true if state was a valid fbs::Setting value.
221    */
222   static bool getSettingFromFbs(fbs::Setting setting, Setting *chreSetting);
223 
224   /**
225    * @param state The fbs::SettingState value.
226    * @param chreSettingState If success, stores the corresponding
227    * chre::SettingState value.
228    *
229    * @return true if state was a valid fbs::SettingState value.
230    */
231   static bool getSettingStateFromFbs(fbs::SettingState state,
232                                      SettingState *chreSettingState);
233 
234   /**
235    * Encodes a message notifying the result of a self test.
236    */
237   static void encodeSelfTestResponse(ChreFlatBufferBuilder &builder,
238                                      uint16_t hostClientId, bool success);
239 };
240 
241 }  // namespace chre
242 
243 #endif  // CHRE_PLATFORM_SHARED_HOST_PROTOCOL_CHRE_H_
244