1// Copyright (C) 2017 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15namespace chre.fbs;
16
17/// Represents a message sent to/from a nanoapp from/to a client on the host
18table NanoappMessage {
19  app_id:ulong = 0;
20  message_type:uint = 0;
21
22  /// Identifies the host-side endpoint on the host that sent or should receive
23  /// this message. The default value is a special value defined in the HAL and
24  /// elsewhere that indicates that the endpoint is unspecified.
25  host_endpoint:ushort = 0xfffe;
26
27  /// Vector containing arbitrary application-specific message data
28  message:[ubyte] (required);
29
30  /// List of Android permissions that cover the contents of a message from a
31  /// nanoapp to the host.
32  /// These permissions are used to record and attribute access to
33  /// permissions-controlled resources.
34  message_permissions:uint;
35
36  /// List of Android permissions declared by the nanoapp / granted to the host.
37  /// For messages from a nanoaapp to the host, this must be a superset of
38  /// message_permissions.
39  permissions:uint;
40}
41
42table HubInfoRequest {}
43table HubInfoResponse {
44  /// The name of the hub. Nominally a UTF-8 string, but note that we're not
45  /// using the built-in "string" data type from FlatBuffers here, because the
46  /// generated C++ uses std::string which is not well-supported in CHRE. This
47  /// applies for vendor and toolchain as well.
48  name:[byte];
49  vendor:[byte];
50  toolchain:[byte];
51
52  /// Legacy platform version reported in the HAL; semantics not strictly
53  /// defined
54  platform_version:uint;
55
56  /// Toolchain version reported in the HAL; semantics not strictly defined
57  toolchain_version:uint;
58
59  peak_mips:float;
60  stopped_power:float;
61  sleep_power:float;
62  peak_power:float;
63
64  /// Maximum size message that can be sent to a nanoapp
65  max_msg_len:uint;
66
67  /// @see chreGetPlatformId()
68  platform_id:ulong;
69
70  /// @see chreGetVersion()
71  chre_platform_version:uint;
72
73  // TODO: list of connected sensors
74}
75
76table NanoappListRequest {}
77
78table NanoappListEntry {
79  app_id:ulong;
80  version:uint;
81  enabled:bool = true;
82
83  /// Whether the nanoapp is a pre-loaded "system" nanoapp, i.e. one that should
84  /// not show up in the list of nanoapps in the context hub HAL. System
85  /// nanoapps are typically used to leverage CHRE for some device functionality
86  /// and do not interact via the context hub HAL.
87  is_system:bool = false;
88
89  /// Nanoapp permissions, if supported. Nanoapp permissions are required on
90  /// CHRE API v1.5+, and are defined in chre/util/system/napp_permissions.h
91  permissions:uint;
92
93  // TODO: memory usage
94}
95
96table NanoappListResponse {
97  nanoapps:[NanoappListEntry] (required);
98}
99
100/// Represents a request for loading a nanoapp.
101/// The nanaopp can either be requested to be loaded via a file or via a buffer.
102/// For loading via a file, the following steps will be taken:
103/// 1. The loader sends a LoadNanoappRequest message to CHRE. app_binary must
104///    be set for legacy purposes, but should be empty. Additionally,
105///    fragment_id and total_app_size are unused in this request. The loading
106///    that happens as part of this request is serialized, but asynchronous
107///    meaning that load requests will be processed in the order they are sent
108///    but multiple requests can be outstanding at any given time.
109/// 2. CHRE stores the filename and waits until its event loop is able to
110///    process the request.
111/// 3. Once ready, the nanoapp will be loaded from the file specified in the
112///    original request and will send a callback indicating the
113///    completion/failure of the request.
114/// For loading via a buffer, loading may optionally be fragmented into multiple
115/// sequential requests, which will follow the following steps:
116/// 1. The loader sends a LoadNanoappRequest message to CHRE. If the request
117///    is fragmented, then the fields fragment_id and total_app_size must
118///    be defined. Once the first fragment is sent to CHRE, all subsequent
119///    fragments must be delivered before a new LoadNanoappRequest can be
120///    issued. If a new request is received while a current request has
121///    outstanding fragments, the current request will be overridden with the
122///    new one.
123/// 2. CHRE preallocates the required amount of memory, and loads app_binary,
124///    appending to already loaded fragments as appropriate.
125/// 3. If the request is fragmented, then the requestor must sequentially send
126///    multiple LoadNanoappRequest with incremental nanoapp binary fragments.
127///    CHRE will respond with LoadNanoappResponse for each request. For
128///    requests starting from the second fragment, all fields except
129///    fragment_id and app_binary should be ignored by CHRE.
130///
131///    Once the LoadNanoappRepsonse for the last fragment is received
132///    by the HAL, the HAL client will receive a callback indicating the
133///    completion/failure of a load request.
134///
135/// If any request fragment is lost, then the entire load request will be
136/// considered to have failed. If the request times out (e.g. the requestor
137/// process crashes), then the load request will be cancelled at CHRE and fail.
138table LoadNanoappRequest {
139  transaction_id:uint;
140
141  app_id:ulong;
142  app_version:uint;
143  target_api_version:uint;
144
145  app_binary:[ubyte] (required);
146
147  /// Fields that are relevant for fragmented loading
148  /// The framgent count starts at 1 and should end at the total number of
149  /// fragments. For clients that do not support fragmented loading, the
150  /// default behavior should be to assume one fragment.
151  fragment_id:uint = 0;
152  total_app_size:uint;
153
154  /// Null-terminated ASCII string containing the file name that contains the
155  /// app binary to be loaded.
156  app_binary_file_name:[byte];
157
158  /// The nanoapp flag values from the nanoapp header defined in
159  /// build/build_template.mk. Refer to that file for more details.
160  app_flags:uint;
161
162  /// If true and fragmented loading is requested, the LoadNanoappResponse
163  /// for the last fragment will be sent after the fragment was confirmed
164  /// to be placed in memory and no additional response will be sent after
165  /// the nanoapp is linked and started in the framework.
166  respond_before_start:bool;
167}
168
169table LoadNanoappResponse {
170  transaction_id:uint;
171
172  /// Denotes whether a load request succeeded or failed.
173  /// If any fragment of a load request fails, the entire load request for
174  /// the same transaction will fail.
175  success:bool;
176
177  /// The fragment count of the load reponse is for.
178  fragment_id:uint = 0;
179
180  // TODO: detailed error code?
181}
182
183table UnloadNanoappRequest {
184  transaction_id:uint;
185
186  app_id:ulong;
187
188  /// Set to true to allow this request to unload nanoapps identified as "system
189  /// nanoapps", i.e. ones with is_system set to true in NanoappListResponse.
190  allow_system_nanoapp_unload:bool;
191}
192
193table UnloadNanoappResponse {
194  transaction_id:uint;
195  success:bool;
196}
197
198/// Represents log messages from CHRE.
199table LogMessage {
200  /// A buffer containing formatted log data. A flat array is used here to avoid
201  /// overhead in serializing and deserializing. The format is as follows:
202  ///
203  /// uint8_t                 - log level (1 = error, 2 = warning,
204  ///                                      3 = info, 4 = debug)
205  /// uint64_t, little-endian - timestamp in nanoseconds
206  /// char[]                  - message to log
207  /// char, \0                - null-terminator
208  ///
209  /// This pattern repeats until the end of the buffer for multiple log
210  /// messages. The last byte will always be a null-terminator. There are no
211  /// padding bytes between these fields. Treat this like a packed struct and be
212  /// cautious with unaligned access when reading/writing this buffer.
213  buffer:[byte];
214}
215
216/// Represents a message sent to CHRE to indicate AP timestamp for time sync
217table TimeSyncMessage {
218  /// Offset between AP and CHRE timestamp
219  offset:long;
220}
221
222/// A request to gather and return debugging information. Only one debug dump
223/// session can be active at a time. Upon accepting a request, zero or more
224/// DebugDumpData messages are generated, followed by a DebugDumpResponse
225/// indicating the completion of the operation.
226table DebugDumpRequest {}
227
228table DebugDumpData {
229  /// Null-terminated ASCII string containing debugging information
230  debug_str:[byte];
231}
232
233table DebugDumpResponse {
234  /// true if the request was accepted and a dump was performed, false if it was
235  /// rejected or failed to complete for some reason
236  success:bool;
237
238  /// The number of DebugDumpData messages sent in this session
239  data_count:uint;
240}
241
242/// A request from CHRE for host to initiate a time sync message
243/// (system feature, platform-specific - not all platforms necessarily use this)
244table TimeSyncRequest {}
245
246/// Request from CHRE to enable direct access to data from the low-power
247/// microphone. On some systems, coordination via the AP (e.g. with
248/// SoundTrigger HAL) is needed to ensure this capability is powered up when
249/// CHRE needs it. The host does not send a response.
250table LowPowerMicAccessRequest {}
251
252/// Notification from CHRE that it no longer needs direct access to low-power
253/// microphone data.
254table LowPowerMicAccessRelease {}
255
256/// An enum describing the setting type.
257enum Setting : byte {
258  LOCATION = 0,
259  WIFI_AVAILABLE,
260  AIRPLANE_MODE,
261  MICROPHONE,
262}
263
264/// An enum describing the state of a setting.
265enum SettingState : byte {
266  DISABLED = 0,
267  ENABLED,
268}
269
270/// Notification from the host that a system setting has changed
271table SettingChangeMessage {
272  /// The setting that has changed
273  setting:Setting = LOCATION;
274
275  /// The new setting value
276  state:SettingState = DISABLED;
277}
278
279/// Represents V2 log messages from CHRE.
280table LogMessageV2 {
281  /// A buffer containing formatted log data. A flat array is used here to avoid
282  /// overhead in serializing and deserializing. The format is as follows:
283  ///
284  /// uint8_t                 - LogBuffer log level (1 = error, 2 = warn,
285  ///                                                3 = info,  4 = debug,
286  ///                                                5 = verbose)
287  /// uint32_t, little-endian - timestamp in milliseconds
288  /// char[]                  - message to log
289  /// char, \0                - null-terminator
290  ///
291  /// This pattern repeats until the end of the buffer for multiple log
292  /// messages. The last byte will always be a null-terminator. There are no
293  /// padding bytes between these fields. Treat this like a packed struct and be
294  /// cautious with unaligned access when reading/writing this buffer.
295  buffer:[byte];
296
297  /// The number of logs dropped since CHRE started
298  num_logs_dropped:uint;
299}
300
301// A request to perform basic internal self-test in CHRE. The test to be performed
302// is platform-dependent, and can be used to check if the system is functioning
303// properly. This message should be used for debugging/testing.
304table SelfTestRequest {}
305table SelfTestResponse {
306  // True if the self-test succeeded.
307  success:bool;
308}
309
310/// A union that joins together all possible messages. Note that in FlatBuffers,
311/// unions have an implicit type
312union ChreMessage {
313  NanoappMessage,
314
315  HubInfoRequest,
316  HubInfoResponse,
317
318  NanoappListRequest,
319  NanoappListResponse,
320
321  LoadNanoappRequest,
322  LoadNanoappResponse,
323
324  UnloadNanoappRequest,
325  UnloadNanoappResponse,
326
327  LogMessage,
328
329  TimeSyncMessage,
330
331  DebugDumpRequest,
332  DebugDumpData,
333  DebugDumpResponse,
334
335  TimeSyncRequest,
336
337  LowPowerMicAccessRequest,
338  LowPowerMicAccessRelease,
339
340  SettingChangeMessage,
341
342  LogMessageV2,
343
344  SelfTestRequest,
345  SelfTestResponse,
346}
347
348struct HostAddress {
349  client_id:ushort;
350}
351
352/// The top-level container that encapsulates all possible messages. Note that
353/// per FlatBuffers requirements, we can't use a union as the top-level
354/// structure (root type), so we must wrap it in a table.
355table MessageContainer {
356  message:ChreMessage (required);
357
358  /// The originating or destination client ID on the host side, used to direct
359  /// responses only to the client that sent the request. Although initially
360  /// populated by the requesting client, this is enforced to be the correct
361  /// value by the entity guarding access to CHRE.
362  /// This is wrapped in a struct to ensure that it is always included when
363  /// encoding the message, so it can be mutated by the host daemon.
364  host_addr:HostAddress (required);
365}
366
367root_type MessageContainer;
368