1 /*
2  * Copyright (C) 2016 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 #include <stdarg.h>
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include <cpu.h>
24 #include <cpu/cpuMath.h>
25 #include <heap.h>
26 #include <sensors.h>
27 #include <sensors_priv.h>
28 #include <seos.h>
29 #include <seos_priv.h>
30 #include <syscall.h>
31 #include <timer.h>
32 #include <util.h>
33 #include <printf.h>
34 #include <nanohubCommand.h>
35 
36 #include <chre.h>
37 #include <chreApi.h>
38 
39 #define MINIMUM_INTERVAL_DEFAULT_HZ SENSOR_HZ(1.0f)
40 
41 /*
42  * This is to ensure that message size and some extra headers will stay representable with 1 byte
43  * Code relies on that in many places.
44  */
45 C_STATIC_ASSERT(max_chre_msg_size, CHRE_MESSAGE_TO_HOST_MAX_SIZE <= 240);
46 
47 /*
48  * Many syscalls rely on the property that uintptr_t can hold uint32_t without data loss
49  * This is enforced by static assertion in chreApi.h
50  * None of the methods returning uint32_t are cast to uintptr_t
51  * This is done in order to let compiler warn us if our assumption is not safe for some reason
52  */
53 
osChreGetAppId(void)54 static inline uint64_t osChreGetAppId(void)
55 {
56     struct Task *task = osGetCurrentTask();
57     const struct AppHdr *app = task ? task->app : NULL;
58 
59     return app ? app->hdr.appId : 0;
60 }
61 
osChreApiGetAppId(uintptr_t * retValP,va_list args)62 static void osChreApiGetAppId(uintptr_t *retValP, va_list args)
63 {
64     uint64_t *appId = va_arg(args, uint64_t *);
65     if (appId)
66         *appId = osChreGetAppId();
67 }
68 
osChreApiGetInstanceId(uintptr_t * retValP,va_list args)69 static void osChreApiGetInstanceId(uintptr_t *retValP, va_list args)
70 {
71     *retValP = osGetCurrentTid();
72 }
73 
osChreApiLogLogv(uintptr_t * retValP,va_list args)74 static void osChreApiLogLogv(uintptr_t *retValP, va_list args)
75 {
76     va_list innerArgs;
77     enum chreLogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */);
78     const static char levels[] = "EWIDV";
79     char clevel = (level > CHRE_LOG_DEBUG || (int) level < 0) ? 'V' : levels[level];
80     const char *str = va_arg(args, const char*);
81     uintptr_t inner = va_arg(args, uintptr_t);
82 
83     va_copy(innerArgs, INTEGER_TO_VA_LIST(inner));
84     osLogv(clevel, PRINTF_FLAG_CHRE, str, innerArgs);
85     va_end(innerArgs);
86 }
87 
osChreApiLogLogvOld(uintptr_t * retValP,va_list args)88 static void osChreApiLogLogvOld(uintptr_t *retValP, va_list args)
89 {
90     va_list innerArgs;
91     enum chreLogLevel level = va_arg(args, int /* enums promoted to ints in va_args in C */);
92     const static char levels[] = "EWIDV";
93     char clevel = (level > CHRE_LOG_DEBUG || (int) level < 0) ? 'V' : levels[level];
94     const char *str = va_arg(args, const char*);
95     uintptr_t inner = va_arg(args, uintptr_t);
96 
97     va_copy(innerArgs, INTEGER_TO_VA_LIST(inner));
98     osLogv(clevel, PRINTF_FLAG_CHRE | PRINTF_FLAG_SHORT_DOUBLE, str, innerArgs);
99     va_end(innerArgs);
100 }
101 
osChreApiGetTime(uintptr_t * retValP,va_list args)102 static void osChreApiGetTime(uintptr_t *retValP, va_list args)
103 {
104     uint64_t *timeNanos = va_arg(args, uint64_t *);
105     if (timeNanos)
106         *timeNanos = sensorGetTime();
107 }
108 
osChreApiGetHostTimeOffset(uintptr_t * retValP,va_list args)109 static void osChreApiGetHostTimeOffset(uintptr_t *retValP, va_list args)
110 {
111     uint64_t *timeNanos = va_arg(args, uint64_t *);
112     if (timeNanos)
113         *timeNanos = hostGetTimeDelta();
114 }
115 
osChreTimerSet(uint64_t duration,const void * cookie,bool oneShot)116 static inline uint32_t osChreTimerSet(uint64_t duration, const void* cookie, bool oneShot)
117 {
118     uint32_t timId = timTimerSetNew(duration, cookie, oneShot);
119 
120     return timId == 0 ? CHRE_TIMER_INVALID : timId;
121 }
122 
osChreApiTimerSet(uintptr_t * retValP,va_list args)123 static void osChreApiTimerSet(uintptr_t *retValP, va_list args)
124 {
125     uint32_t length_lo = va_arg(args, uint32_t);
126     uint32_t length_hi = va_arg(args, uint32_t);
127     void *cookie = va_arg(args, void *);
128     bool oneshot = va_arg(args, int);
129     uint64_t length = (((uint64_t)length_hi) << 32) | length_lo;
130 
131     *retValP = osChreTimerSet(length, cookie, oneshot);
132 }
133 
osChreApiTimerCancel(uintptr_t * retValP,va_list args)134 static void osChreApiTimerCancel(uintptr_t *retValP, va_list args)
135 {
136     uint32_t timerId = va_arg(args, uint32_t);
137     *retValP = timTimerCancelEx(timerId, true);
138 }
139 
osChreAbort(uint32_t abortCode)140 static inline void osChreAbort(uint32_t abortCode)
141 {
142     struct Task *task = osGetCurrentTask();
143     if (task) {
144         if (task->app) {
145             osLog(LOG_ERROR, "APP ID=0x%" PRIX64 " TID=0x%" PRIX16 " aborted [code 0x%" PRIX32 "]",
146                   task->app->hdr.appId, task->tid, abortCode);
147         } else {
148             osLog(LOG_ERROR, "APP ID=NULL TID=0x%" PRIX16 " aborted [code 0x%" PRIX32 "]",
149                   task->tid, abortCode);
150         }
151         osTaskAbort(task);
152     } else {
153         osLog(LOG_ERROR, "osChreAbort called with no current task [code 0x%" PRIX32 "]",
154               abortCode);
155     }
156 }
157 
osChreApiAbort(uintptr_t * retValP,va_list args)158 static void osChreApiAbort(uintptr_t *retValP, va_list args)
159 {
160     uint32_t code = va_arg(args, uint32_t);
161     osChreAbort(code);
162 }
163 
osChreApiHeapAlloc(uintptr_t * retValP,va_list args)164 static void osChreApiHeapAlloc(uintptr_t *retValP, va_list args)
165 {
166     uint32_t size = va_arg(args, uint32_t);
167     *retValP = (uintptr_t)heapAlloc(size);
168 }
169 
osChreApiHeapFree(uintptr_t * retValP,va_list args)170 static void osChreApiHeapFree(uintptr_t *retValP, va_list args)
171 {
172     void *ptr = va_arg(args, void *);
173     heapFree(ptr);
174 }
175 
176 /*
177  * we have no way to verify if this is a CHRE event; just trust the caller to do the right thing
178  */
osChreFreeEvent(uint32_t tid,chreEventCompleteFunction * cbFreeEvt,uint32_t evtType,void * evtData)179 void osChreFreeEvent(uint32_t tid, chreEventCompleteFunction *cbFreeEvt, uint32_t evtType, void * evtData)
180 {
181     struct Task *chreTask = osTaskFindByTid(tid);
182     struct Task *preempted = osSetCurrentTask(chreTask);
183     if (chreTask && osTaskIsChre(chreTask))
184         osTaskInvokeEventFreeCallback(chreTask, cbFreeEvt, evtType, evtData);
185     osSetCurrentTask(preempted);
186 }
187 
osChreSendEvent(uint16_t evtType,void * evtData,chreEventCompleteFunction * evtFreeCallback,uint32_t toTid)188 static bool osChreSendEvent(uint16_t evtType, void *evtData,
189                             chreEventCompleteFunction *evtFreeCallback,
190                             uint32_t toTid)
191 {
192     /*
193      * this primitive may only be used for USER CHRE events;
194      * system events come from the OS itself through different path,
195      * and are interpreted by the CHRE app compatibility library.
196      * therefore, we have to enforce the evtType >= CHRE_EVENT_FIRST_USER_VALUE.
197      */
198     if (evtType < CHRE_EVENT_FIRST_USER_VALUE) {
199         osChreFreeEvent(osGetCurrentTid(), evtFreeCallback, evtType, evtData);
200         return false;
201     }
202     return osEnqueuePrivateEvtNew(evtType, evtData, evtFreeCallback, toTid);
203 }
204 
osChreSendMessageToHost(void * message,uint32_t messageSize,uint32_t messageType,uint16_t hostEndpoint,chreMessageFreeFunction * freeCallback)205 static bool osChreSendMessageToHost(void *message, uint32_t messageSize,
206                            uint32_t messageType, uint16_t hostEndpoint,
207                            chreMessageFreeFunction *freeCallback)
208 {
209     bool result = false;
210     struct HostHubChrePacket *hostMsg = NULL;
211 
212     if (messageSize > CHRE_MESSAGE_TO_HOST_MAX_SIZE || (messageSize && !message))
213         goto out;
214 
215     hostMsg = heapAlloc(sizeof(*hostMsg) + messageSize);
216     if (!hostMsg)
217         goto out;
218 
219     if (messageSize)
220         memcpy(hostMsg+1, message, messageSize);
221 
222     hostMsg->appId = osChreGetAppId();
223     hostMsg->messageSize = messageSize;
224     hostMsg->messageType = messageType;
225     hostMsg->hostEndpoint = hostEndpoint;
226     result = osEnqueueEvtOrFree(EVT_APP_TO_HOST_CHRE, hostMsg, heapFree);
227 
228 out:
229     if (freeCallback)
230         osTaskInvokeMessageFreeCallback(osGetCurrentTask(), freeCallback, message, messageSize);
231     return result;
232 }
233 
osChreApiSendMessageToHost(uintptr_t * retValP,va_list args)234 static void osChreApiSendMessageToHost(uintptr_t *retValP, va_list args)
235 {
236     void *message = va_arg(args, void *);
237     uint32_t messageSize = va_arg(args, uint32_t);
238     uint32_t messageType = va_arg(args, uint32_t);
239     chreMessageFreeFunction *freeCallback = va_arg(args, chreMessageFreeFunction *);
240 
241     *retValP = osChreSendMessageToHost(message, messageSize, messageType, CHRE_HOST_ENDPOINT_BROADCAST, freeCallback);
242 }
243 
osChreSensorFindDefault(uint8_t sensorType,uint32_t * pHandle)244 static bool osChreSensorFindDefault(uint8_t sensorType, uint32_t *pHandle)
245 {
246     if (!pHandle)
247         return false;
248 
249     const struct SensorInfo *info = sensorFind(sensorType, 0, pHandle);
250 
251     return info != NULL;
252 }
253 
osChreApiSensorFindDefault(uintptr_t * retValP,va_list args)254 static void osChreApiSensorFindDefault(uintptr_t *retValP, va_list args)
255 {
256     uint8_t sensorType = va_arg(args, uint32_t);
257     uint32_t *pHandle = va_arg(args, uint32_t *);
258     *retValP = osChreSensorFindDefault(sensorType, pHandle);
259 }
260 
osChreSensorGetInfoOld(uint32_t sensorHandle,struct chreSensorInfo * info)261 static bool osChreSensorGetInfoOld(uint32_t sensorHandle, struct chreSensorInfo *info)
262 {
263     struct Sensor *s = sensorFindByHandle(sensorHandle);
264     if (!s || !info)
265         return false;
266     const struct SensorInfo *si = s->si;
267     info->sensorName = si->sensorName;
268     info->sensorType = si->sensorType;
269     info->unusedFlags = 0;
270 
271     if (si->sensorType == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT
272         || si->sensorType == CHRE_SENSOR_TYPE_STATIONARY_DETECT)
273         info->isOneShot = true;
274     else
275         info->isOneShot = false;
276     info->isOnChange = s->hasOnchange;
277 
278     return true;
279 }
280 
osChreSensorGetInfo(uint32_t sensorHandle,struct chreSensorInfo * info)281 static bool osChreSensorGetInfo(uint32_t sensorHandle, struct chreSensorInfo *info)
282 {
283     struct Sensor *s = sensorFindByHandle(sensorHandle);
284     uint32_t max = 0;
285     int i;
286     if (!s || !info)
287         return false;
288     const struct SensorInfo *si = s->si;
289     info->sensorName = si->sensorName;
290     info->sensorType = si->sensorType;
291     info->unusedFlags = 0;
292 
293     if (si->sensorType == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT
294         || si->sensorType == CHRE_SENSOR_TYPE_STATIONARY_DETECT)
295         info->isOneShot = true;
296     else
297         info->isOneShot = false;
298     info->isOnChange = s->hasOnchange;
299     info->minInterval = CHRE_SENSOR_INTERVAL_DEFAULT;
300     if (si->supportedRates) {
301         for (i=0; si->supportedRates[i] != 0; i++) {
302             if (si->supportedRates[i] > max
303                 && si->supportedRates[i] != SENSOR_RATE_ONDEMAND
304                 && si->supportedRates[i] != SENSOR_RATE_ONCHANGE
305                 && si->supportedRates[i] != SENSOR_RATE_ONESHOT) {
306                 max = si->supportedRates[i];
307             }
308         }
309         if (max)
310             info->minInterval = (UINT32_C(1024000000) / max) * UINT64_C(1000);
311     }
312 
313     return true;
314 }
315 
osChreApiSensorGetInfoOld(uintptr_t * retValP,va_list args)316 static void osChreApiSensorGetInfoOld(uintptr_t *retValP, va_list args)
317 {
318     uint32_t sensorHandle = va_arg(args, uint32_t);
319     struct chreSensorInfo *info = va_arg(args, struct chreSensorInfo *);
320     *retValP = osChreSensorGetInfoOld(sensorHandle, info);
321 }
322 
osChreApiSensorGetInfo(uintptr_t * retValP,va_list args)323 static void osChreApiSensorGetInfo(uintptr_t *retValP, va_list args)
324 {
325     uint32_t sensorHandle = va_arg(args, uint32_t);
326     struct chreSensorInfo *info = va_arg(args, struct chreSensorInfo *);
327     *retValP = osChreSensorGetInfo(sensorHandle, info);
328 }
329 
osChreSensorGetSamplingStatus(uint32_t sensorHandle,struct chreSensorSamplingStatus * status)330 static bool osChreSensorGetSamplingStatus(uint32_t sensorHandle,
331                                  struct chreSensorSamplingStatus *status)
332 {
333     struct Sensor *s = sensorFindByHandle(sensorHandle);
334     uint32_t rate;
335     uint64_t latency;
336 
337     if (!s || !status)
338         return false;
339 
340     rate = sensorGetHwRate(sensorHandle);
341     latency = sensorGetHwLatency(sensorHandle);
342 
343     if (rate == SENSOR_RATE_OFF) {
344         status->enabled = 0;
345         status->interval = 0;
346         status->latency = 0;
347     } else {
348         status->enabled = true;
349         if (rate == SENSOR_RATE_ONDEMAND
350             || rate == SENSOR_RATE_ONCHANGE
351             || rate == SENSOR_RATE_ONESHOT)
352             status->interval = CHRE_SENSOR_INTERVAL_DEFAULT;
353         else
354             status->interval = (UINT32_C(1024000000) / rate) * UINT64_C(1000);
355 
356         if (latency == SENSOR_LATENCY_NODATA)
357             status->latency = CHRE_SENSOR_INTERVAL_DEFAULT;
358         else
359             status->latency = latency;
360     }
361 
362     return true;
363 }
364 
osChreApiSensorGetStatus(uintptr_t * retValP,va_list args)365 static void osChreApiSensorGetStatus(uintptr_t *retValP, va_list args)
366 {
367     uint32_t sensorHandle = va_arg(args, uint32_t);
368     struct chreSensorSamplingStatus *status = va_arg(args, struct chreSensorSamplingStatus *);
369     *retValP = osChreSensorGetSamplingStatus(sensorHandle, status);
370 }
371 
osChreSensorConfigure(uint32_t sensorHandle,enum chreSensorConfigureMode mode,uint64_t interval,uint64_t latency)372 static bool osChreSensorConfigure(uint32_t sensorHandle,
373                          enum chreSensorConfigureMode mode,
374                          uint64_t interval, uint64_t latency)
375 {
376     uint32_t rate, interval_us;
377     bool ret;
378     struct Sensor *s = sensorFindByHandle(sensorHandle);
379     int i;
380     if (!s)
381         return false;
382 
383     if (mode & CHRE_SENSOR_CONFIGURE_RAW_POWER_ON) {
384         if (interval == CHRE_SENSOR_INTERVAL_DEFAULT) {
385             // use first rate in supported rates list > minimum (if avaliable)
386             const struct SensorInfo *si = s->si;
387             if (!si)
388                 return false;
389 
390             if (!si->supportedRates || si->supportedRates[0] == 0)
391                 rate = SENSOR_RATE_ONCHANGE;
392             else {
393                 for (i = 0; si->supportedRates[i] != 0; i++) {
394                     rate = si->supportedRates[i];
395                     if (rate >= MINIMUM_INTERVAL_DEFAULT_HZ)
396                         break;
397                 }
398             }
399         } else {
400             interval_us = U64_DIV_BY_CONST_U16(interval, 1000);
401             rate = UINT32_C(1024000000) / interval_us;
402         }
403         if (!rate) // 0 is a reserved value. minimum is 1
404             rate = 1;
405         if (latency == CHRE_SENSOR_LATENCY_DEFAULT)
406             latency = 0ULL;
407         if (sensorGetReqRate(sensorHandle) == SENSOR_RATE_OFF) {
408             if ((ret = sensorRequest(0, sensorHandle, rate, latency))) {
409                 if (!(ret = osEventsSubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType))))
410                     sensorRelease(0, sensorHandle);
411             }
412         } else {
413             ret = sensorRequestRateChange(0, sensorHandle, rate, latency);
414         }
415     } else if (mode & (CHRE_SENSOR_CONFIGURE_RAW_REPORT_CONTINUOUS|CHRE_SENSOR_CONFIGURE_RAW_REPORT_ONE_SHOT)) {
416         if (sensorGetReqRate(sensorHandle) == SENSOR_RATE_OFF)
417             ret = osEventsSubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType));
418         else
419             ret = true;
420     } else {
421         if (sensorGetReqRate(sensorHandle) != SENSOR_RATE_OFF) {
422             if ((ret = sensorRelease(0, sensorHandle)))
423                 ret = osEventsUnsubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType));
424         } else {
425             ret = osEventsUnsubscribe(2, sensorGetMyEventType(s->si->sensorType), sensorGetMyCfgEventType(s->si->sensorType));
426         }
427     }
428 
429     return ret;
430 }
431 
osChreApiSensorConfig(uintptr_t * retValP,va_list args)432 static void osChreApiSensorConfig(uintptr_t *retValP, va_list args)
433 {
434     uint32_t sensorHandle = va_arg(args, uint32_t);
435     enum chreSensorConfigureMode mode = va_arg(args, int);
436     uint64_t interval = va_arg(args, uint32_t);
437     uint32_t interval_hi = va_arg(args, uint32_t);
438     uint64_t latency = va_arg(args, uint32_t);
439     uint32_t latency_hi = va_arg(args, uint32_t);
440 
441     interval |= ((uint64_t)interval_hi) << 32;
442     latency  |= ((uint64_t)latency_hi) << 32;
443 
444     *retValP = osChreSensorConfigure(sensorHandle, mode, interval, latency);
445 }
446 
osChreGetApiVersion(void)447 static uint32_t osChreGetApiVersion(void)
448 {
449     return CHRE_API_VERSION;
450 }
451 
osChreApiChreApiVersion(uintptr_t * retValP,va_list args)452 static void osChreApiChreApiVersion(uintptr_t *retValP, va_list args)
453 {
454     *retValP = osChreGetApiVersion();
455 }
456 
osChreGetVersion(void)457 static uint32_t osChreGetVersion(void)
458 {
459     return CHRE_API_VERSION | NANOHUB_OS_PATCH_LEVEL;
460 }
461 
osChreApiChreOsVersion(uintptr_t * retValP,va_list args)462 static void osChreApiChreOsVersion(uintptr_t *retValP, va_list args)
463 {
464     *retValP = (uintptr_t)osChreGetVersion();
465 }
466 
osChreGetPlatformId(void)467 static uint64_t osChreGetPlatformId(void)
468 {
469     return HW_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
470 }
471 
osChreApiPlatformId(uintptr_t * retValP,va_list args)472 static void osChreApiPlatformId(uintptr_t *retValP, va_list args)
473 {
474     uint64_t *pHwId = va_arg(args, uint64_t*);
475     if (pHwId)
476         *pHwId = osChreGetPlatformId();
477 }
478 
osChreEventSendEvent(uintptr_t * retValP,va_list args)479 static void osChreEventSendEvent(uintptr_t *retValP, va_list args)
480 {
481     uint16_t evtType = va_arg(args, uint32_t); // stored as 32-bit
482     void *evtData = va_arg(args, void *);
483     chreEventCompleteFunction *freeCallback = va_arg(args, chreEventCompleteFunction *);
484     uint32_t toTid = va_arg(args, uint32_t);
485     *retValP = osChreSendEvent(evtType, evtData, freeCallback, toTid);
486 }
487 
osChreEventSendMessageToHost(uintptr_t * retValP,va_list args)488 static void osChreEventSendMessageToHost(uintptr_t *retValP, va_list args)
489 {
490     void *message = va_arg(args, void *);
491     uint32_t messageSize = va_arg(args, size_t);
492     uint32_t messageType = va_arg(args, uint32_t);
493     uint16_t hostEndpoint = va_arg(args, uint32_t);
494     chreMessageFreeFunction *freeCallback = va_arg(args, chreMessageFreeFunction *);
495 
496     *retValP = osChreSendMessageToHost(message, messageSize, messageType, hostEndpoint, freeCallback);
497 }
498 
chreInfoByTid(uint32_t tid,struct chreNanoappInfo * info)499 static bool chreInfoByTid(uint32_t tid, struct chreNanoappInfo *info)
500 {
501     struct Task *task = osTaskFindByTid(tid);
502     if (task) {
503         info->appId = task->app->hdr.appId;
504         info->version = task->app->hdr.appVer;
505         info->instanceId = tid;
506         return true;
507     } else {
508         return false;
509     }
510 }
511 
osChreEventInfoByAppId(uintptr_t * retValP,va_list args)512 static void osChreEventInfoByAppId(uintptr_t *retValP, va_list args)
513 {
514     uint32_t app_lo = va_arg(args, uint32_t);
515     uint32_t app_hi = va_arg(args, uint32_t);
516     struct chreNanoappInfo *info = va_arg(args, struct chreNanoappInfo *);
517     uint64_t appId = (((uint64_t)app_hi) << 32) | app_lo;
518     uint32_t tid;
519 
520     if (osTidById(&appId, &tid))
521         *retValP = chreInfoByTid(tid, info);
522     else
523         *retValP = false;
524 }
525 
osChreEeventInfoByInstId(uintptr_t * retValP,va_list args)526 static void osChreEeventInfoByInstId(uintptr_t *retValP, va_list args)
527 {
528     uint32_t tid = va_arg(args, uint32_t);
529     struct chreNanoappInfo *info = va_arg(args, struct chreNanoappInfo *);
530 
531     *retValP = chreInfoByTid(tid, info);
532 }
533 
osChreEventCfgInfo(uintptr_t * retValP,va_list args)534 static void osChreEventCfgInfo(uintptr_t *retValP, va_list args)
535 {
536     bool enable = va_arg(args, int);
537     if (enable)
538         osEventsSubscribe(2, EVT_APP_STARTED, EVT_APP_STOPPED);
539     else
540         osEventsUnsubscribe(2, EVT_APP_STARTED, EVT_APP_STOPPED);
541 }
542 
osChreEventHostSleep(uintptr_t * retValP,va_list args)543 static void osChreEventHostSleep(uintptr_t *retValP, va_list args)
544 {
545     // bool enable = va_arg(args, int();
546 }
547 
osChreEventIsHostAwake(uintptr_t * retValP,va_list args)548 static void osChreEventIsHostAwake(uintptr_t *retValP, va_list args)
549 {
550     *retValP = true;
551 }
552 
osChreDrvGnssGetCap(uintptr_t * retValP,va_list args)553 static void osChreDrvGnssGetCap(uintptr_t *retValP, va_list args)
554 {
555     *retValP = CHRE_GNSS_CAPABILITIES_NONE;
556 }
557 
osChreDrvGnssLocStartAsync(uintptr_t * retValP,va_list args)558 static void osChreDrvGnssLocStartAsync(uintptr_t *retValP, va_list args)
559 {
560     // uint32_t minIntervalMs = va_args(args, uint32_t);
561     // uint32_t minTimeToNextFixMs = va_args(args, uint32_t);
562     // const void *cookie = va_args(args, void *);
563     *retValP = false;
564 }
565 
osChreDrvGnssLocStopAsync(uintptr_t * retValP,va_list args)566 static void osChreDrvGnssLocStopAsync(uintptr_t *retValP, va_list args)
567 {
568     // const void *cookie = va_args(args, void *);
569     *retValP = false;
570 }
571 
osChreDrvGnssMeasStartAsync(uintptr_t * retValP,va_list args)572 static void osChreDrvGnssMeasStartAsync(uintptr_t *retValP, va_list args)
573 {
574     // uint32_t minIntervalMs = va_args(args, uint32_t);
575     // const void *cookie = va_args(args, void *);
576     *retValP = false;
577 }
578 
osChreDrvGnssMeasStopAsync(uintptr_t * retValP,va_list args)579 static void osChreDrvGnssMeasStopAsync(uintptr_t *retValP, va_list args)
580 {
581     // const void *cookie = va_args(args, void *);
582     *retValP = false;
583 }
584 
osChreDrvGnssConfLocMon(uintptr_t * retValP,va_list args)585 static void osChreDrvGnssConfLocMon(uintptr_t *retValP, va_list args)
586 {
587     // bool enable = va_args(args, bool);
588     *retValP = false;
589 }
590 
osChreDrvWifiGetCap(uintptr_t * retValP,va_list args)591 static void osChreDrvWifiGetCap(uintptr_t *retValP, va_list args)
592 {
593     *retValP = CHRE_WIFI_CAPABILITIES_NONE;
594 }
595 
osChreDrvWifiConfScanMonAsync(uintptr_t * retValP,va_list args)596 static void osChreDrvWifiConfScanMonAsync(uintptr_t *retValP, va_list args)
597 {
598     // bool enable = va_args(args, int);
599     // const void *cookie = va_args(args, void *);
600     *retValP = false;
601 }
602 
osChreDrvWifiReqScanAsync(uintptr_t * retValP,va_list args)603 static void osChreDrvWifiReqScanAsync(uintptr_t *retValP, va_list args)
604 {
605     // const struct chreWifiScanParams *params = va_args(args, struct chreWifiScanParams *);
606     // const void *cookie = va_args(args, void *);
607     *retValP = false;
608 }
609 
osChreDrvWwanGetCap(uintptr_t * retValP,va_list args)610 static void osChreDrvWwanGetCap(uintptr_t *retValP, va_list args)
611 {
612     *retValP = CHRE_WWAN_CAPABILITIES_NONE;
613 }
614 
osChreDrvWwanGetCallInfoAsync(uintptr_t * retValP,va_list args)615 static void osChreDrvWwanGetCallInfoAsync(uintptr_t *retValP, va_list args)
616 {
617     // const void *cookie = va_args(args, void *);
618     *retValP = false;
619 }
620 
osChreDrvAudioGetSrc(uintptr_t * retValP,va_list args)621 static void osChreDrvAudioGetSrc(uintptr_t *retValP, va_list args)
622 {
623     // uint32_t handle = va_args(args, uint32_t);
624     // struct chreAudioSource *audioSource = va_args(args, struct chreAudioSource *);
625     *retValP = false;
626 }
627 
osChreDrvAudioConfSrc(uintptr_t * retValP,va_list args)628 static void osChreDrvAudioConfSrc(uintptr_t *retValP, va_list args)
629 {
630     // uint32_t handle = va_args(args, uint32_t);
631     // bool enable = va_args(args, int);
632     // uint32_t duration_lo = va_arg(args, uint32_t);
633     // uint32_t duration_hi = va_arg(args, uint32_t);
634     // uint64_t bufferDuration = (((uint64_t)dur_hi) << 32) | dur_lo;
635     // uint32_t interval_lo = va_args(args, uint32_t);
636     // uint32_t interval_hi = va_args(args, uint32_t);
637     // uint64_t deliveryInterval = (((uint64_t)del_hi) << 32) | del_lo;
638     *retValP = false;
639 }
640 
osChreDrvAudioGetStatus(uintptr_t * retValP,va_list args)641 static void osChreDrvAudioGetStatus(uintptr_t *retValP, va_list args)
642 {
643     // uint32_t handle = va_args(args, uint32_t);
644     // struct chreAudioSourceStatus *status = va_args(args, struct chreAudioSourceStatus *);
645     *retValP = false;
646 }
647 
648 static const struct SyscallTable chreMainApiTable = {
649     .numEntries = SYSCALL_CHRE_MAIN_API_LAST,
650     .entry = {
651         [SYSCALL_CHRE_MAIN_API_LOG_OLD]                 = { .func = osChreApiLogLogvOld },
652         [SYSCALL_CHRE_MAIN_API_LOG]                     = { .func = osChreApiLogLogv },
653         [SYSCALL_CHRE_MAIN_API_GET_APP_ID]              = { .func = osChreApiGetAppId },
654         [SYSCALL_CHRE_MAIN_API_GET_INST_ID]             = { .func = osChreApiGetInstanceId },
655         [SYSCALL_CHRE_MAIN_API_GET_TIME]                = { .func = osChreApiGetTime },
656         [SYSCALL_CHRE_MAIN_API_GET_HOST_TIME_OFFSET]    = { .func = osChreApiGetHostTimeOffset },
657         [SYSCALL_CHRE_MAIN_API_TIMER_SET]               = { .func = osChreApiTimerSet },
658         [SYSCALL_CHRE_MAIN_API_TIMER_CANCEL]            = { .func = osChreApiTimerCancel },
659         [SYSCALL_CHRE_MAIN_API_ABORT]                   = { .func = osChreApiAbort },
660         [SYSCALL_CHRE_MAIN_API_HEAP_ALLOC]              = { .func = osChreApiHeapAlloc },
661         [SYSCALL_CHRE_MAIN_API_HEAP_FREE]               = { .func = osChreApiHeapFree },
662         [SYSCALL_CHRE_MAIN_API_SEND_EVENT]              = { .func = osChreEventSendEvent },
663         [SYSCALL_CHRE_MAIN_API_SEND_MSG]                = { .func = osChreApiSendMessageToHost },
664         [SYSCALL_CHRE_MAIN_API_SENSOR_FIND_DEFAULT]     = { .func = osChreApiSensorFindDefault },
665         [SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO_OLD]     = { .func = osChreApiSensorGetInfoOld },
666         [SYSCALL_CHRE_MAIN_API_SENSOR_GET_INFO]         = { .func = osChreApiSensorGetInfo },
667         [SYSCALL_CHRE_MAIN_API_SENSOR_GET_STATUS]       = { .func = osChreApiSensorGetStatus },
668         [SYSCALL_CHRE_MAIN_API_SENSOR_CONFIG]           = { .func = osChreApiSensorConfig },
669         [SYSCALL_CHRE_MAIN_API_GET_OS_API_VERSION]      = { .func = osChreApiChreApiVersion },
670         [SYSCALL_CHRE_MAIN_API_GET_OS_VERSION]          = { .func = osChreApiChreOsVersion },
671         [SYSCALL_CHRE_MAIN_API_GET_PLATFORM_ID]         = { .func = osChreApiPlatformId },
672     },
673 };
674 
675 static const struct SyscallTable chreMainEventTable = {
676     .numEntries = SYSCALL_CHRE_MAIN_EVENT_LAST,
677     .entry = {
678         [SYSCALL_CHRE_MAIN_EVENT_SEND_EVENT]           = { .func = osChreEventSendEvent },
679         [SYSCALL_CHRE_MAIN_EVENT_SEND_MSG]             = { .func = osChreEventSendMessageToHost },
680         [SYSCALL_CHRE_MAIN_EVENT_INFO_BY_APP_ID]       = { .func = osChreEventInfoByAppId },
681         [SYSCALL_CHRE_MAIN_EVENT_INFO_BY_INST_ID]      = { .func = osChreEeventInfoByInstId },
682         [SYSCALL_CHRE_MAIN_EVENT_CFG_INFO]             = { .func = osChreEventCfgInfo },
683         [SYSCALL_CHRE_MAIN_EVENT_HOST_SLEEP]           = { .func = osChreEventHostSleep },
684         [SYSCALL_CHRE_MAIN_EVENT_IS_HOST_AWAKE]        = { .func = osChreEventIsHostAwake },
685     },
686 };
687 
688 static const struct SyscallTable chreMainTable = {
689     .numEntries = SYSCALL_CHRE_MAIN_LAST,
690     .entry = {
691         [SYSCALL_CHRE_MAIN_API]     = { .subtable = (struct SyscallTable*)&chreMainApiTable,     },
692         [SYSCALL_CHRE_MAIN_EVENT]   = { .subtable = (struct SyscallTable*)&chreMainEventTable,   },
693     },
694 };
695 
696 static const struct SyscallTable chreDrvGnssTable = {
697     .numEntries = SYSCALL_CHRE_DRV_GNSS_LAST,
698     .entry = {
699         [SYSCALL_CHRE_DRV_GNSS_GET_CAP]                 = { .func = osChreDrvGnssGetCap },
700         [SYSCALL_CHRE_DRV_GNSS_LOC_START_ASYNC]         = { .func = osChreDrvGnssLocStartAsync },
701         [SYSCALL_CHRE_DRV_GNSS_LOC_STOP_ASYNC]          = { .func = osChreDrvGnssLocStopAsync },
702         [SYSCALL_CHRE_DRV_GNSS_MEAS_START_ASYNC]        = { .func = osChreDrvGnssMeasStartAsync },
703         [SYSCALL_CHRE_DRV_GNSS_MEAS_STOP_ASYNC]         = { .func = osChreDrvGnssMeasStopAsync },
704         [SYSCALL_CHRE_DRV_GNSS_CONF_PASV_LOC_LIS]       = { .func = osChreDrvGnssConfLocMon },
705     },
706 };
707 
708 static const struct SyscallTable chreDrvWifiTable = {
709     .numEntries = SYSCALL_CHRE_DRV_WIFI_LAST,
710     .entry = {
711         [SYSCALL_CHRE_DRV_WIFI_GET_CAP]                 = { .func = osChreDrvWifiGetCap },
712         [SYSCALL_CHRE_DRV_WIFI_CONF_SCAN_MON_ASYNC]     = { .func = osChreDrvWifiConfScanMonAsync },
713         [SYSCALL_CHRE_DRV_WIFI_REQ_SCAN_ASYNC]          = { .func = osChreDrvWifiReqScanAsync },
714     },
715 };
716 
717 static const struct SyscallTable chreDrvWwanTable = {
718     .numEntries = SYSCALL_CHRE_DRV_WWAN_LAST,
719     .entry = {
720         [SYSCALL_CHRE_DRV_WWAN_GET_CAP]                 = { .func = osChreDrvWwanGetCap },
721         [SYSCALL_CHRE_DRV_WWAN_GET_CELL_INFO_ASYNC]     = { .func = osChreDrvWwanGetCallInfoAsync },
722     },
723 };
724 
725 static const struct SyscallTable chreDrvAudioTable = {
726     .numEntries = SYSCALL_CHRE_DRV_AUDIO_LAST,
727     .entry = {
728         [SYSCALL_CHRE_DRV_AUDIO_GET_SRC]                = { .func = osChreDrvAudioGetSrc },
729         [SYSCALL_CHRE_DRV_AUDIO_CONF_SRC]               = { .func = osChreDrvAudioConfSrc },
730         [SYSCALL_CHRE_DRV_AUDIO_GET_STATUS]             = { .func = osChreDrvAudioGetStatus },
731     },
732 };
733 
734 static const struct SyscallTable chreDriversTable = {
735     .numEntries = SYSCALL_CHRE_DRV_LAST,
736     .entry = {
737         [SYSCALL_CHRE_DRV_GNSS]     = { .subtable = (struct SyscallTable*)&chreDrvGnssTable,     },
738         [SYSCALL_CHRE_DRV_WIFI]     = { .subtable = (struct SyscallTable*)&chreDrvWifiTable,     },
739         [SYSCALL_CHRE_DRV_WWAN]     = { .subtable = (struct SyscallTable*)&chreDrvWwanTable,     },
740         [SYSCALL_CHRE_DRV_AUDIO]    = { .subtable = (struct SyscallTable*)&chreDrvAudioTable     },
741     },
742 };
743 
744 static const struct SyscallTable chreTable = {
745     .numEntries = SYSCALL_CHRE_LAST,
746     .entry = {
747         [SYSCALL_CHRE_MAIN]    = { .subtable = (struct SyscallTable*)&chreMainTable,    },
748         [SYSCALL_CHRE_DRIVERS] = { .subtable = (struct SyscallTable*)&chreDriversTable, },
749     },
750 };
751 
osChreApiExport()752 void osChreApiExport()
753 {
754     if (!syscallAddTable(SYSCALL_NO(SYSCALL_DOMAIN_CHRE,0,0,0), 1, (struct SyscallTable*)&chreTable))
755             osLog(LOG_ERROR, "Failed to export CHRE OS API");
756 }
757