Home | History | Annotate | Download | only in core
      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 
     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 
     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 
     69 static void osChreApiGetInstanceId(uintptr_t *retValP, va_list args)
     70 {
     71     *retValP = osGetCurrentTid();
     72 }
     73 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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  */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    447 static uint32_t osChreGetApiVersion(void)
    448 {
    449     return CHRE_API_VERSION;
    450 }
    451 
    452 static void osChreApiChreApiVersion(uintptr_t *retValP, va_list args)
    453 {
    454     *retValP = osChreGetApiVersion();
    455 }
    456 
    457 static uint32_t osChreGetVersion(void)
    458 {
    459     return CHRE_API_VERSION | NANOHUB_OS_PATCH_LEVEL;
    460 }
    461 
    462 static void osChreApiChreOsVersion(uintptr_t *retValP, va_list args)
    463 {
    464     *retValP = (uintptr_t)osChreGetVersion();
    465 }
    466 
    467 static uint64_t osChreGetPlatformId(void)
    468 {
    469     return HW_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
    470 }
    471 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    543 static void osChreEventHostSleep(uintptr_t *retValP, va_list args)
    544 {
    545     // bool enable = va_arg(args, int();
    546 }
    547 
    548 static void osChreEventIsHostAwake(uintptr_t *retValP, va_list args)
    549 {
    550     *retValP = true;
    551 }
    552 
    553 static void osChreDrvGnssGetCap(uintptr_t *retValP, va_list args)
    554 {
    555     *retValP = CHRE_GNSS_CAPABILITIES_NONE;
    556 }
    557 
    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 
    566 static void osChreDrvGnssLocStopAsync(uintptr_t *retValP, va_list args)
    567 {
    568     // const void *cookie = va_args(args, void *);
    569     *retValP = false;
    570 }
    571 
    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 
    579 static void osChreDrvGnssMeasStopAsync(uintptr_t *retValP, va_list args)
    580 {
    581     // const void *cookie = va_args(args, void *);
    582     *retValP = false;
    583 }
    584 
    585 static void osChreDrvGnssConfLocMon(uintptr_t *retValP, va_list args)
    586 {
    587     // bool enable = va_args(args, bool);
    588     *retValP = false;
    589 }
    590 
    591 static void osChreDrvWifiGetCap(uintptr_t *retValP, va_list args)
    592 {
    593     *retValP = CHRE_WIFI_CAPABILITIES_NONE;
    594 }
    595 
    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 
    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 
    610 static void osChreDrvWwanGetCap(uintptr_t *retValP, va_list args)
    611 {
    612     *retValP = CHRE_WWAN_CAPABILITIES_NONE;
    613 }
    614 
    615 static void osChreDrvWwanGetCallInfoAsync(uintptr_t *retValP, va_list args)
    616 {
    617     // const void *cookie = va_args(args, void *);
    618     *retValP = false;
    619 }
    620 
    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 
    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 
    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 
    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