Home | History | Annotate | Download | only in common
      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 <eventnums.h>
     18 #include <seos.h>
     19 #include <timer.h>
     20 #include <toolchain.h>
     21 #include <crt_priv.h>
     22 #include <string.h>
     23 
     24 #include <chre.h>
     25 #include <sensors.h>
     26 #include <syscallDo.h>
     27 #include <hostIntf.h>
     28 
     29 #define SENSOR_TYPE(x)      ((x) & 0xFF)
     30 
     31 /*
     32  * Common CHRE App support code
     33  */
     34 
     35 static bool chreappStart(uint32_t tid)
     36 {
     37     __crt_init();
     38     return nanoappStart();
     39 }
     40 
     41 static void chreappEnd(void)
     42 {
     43     nanoappEnd();
     44     __crt_exit();
     45 }
     46 
     47 static void initDataHeader(struct chreSensorDataHeader *header, uint64_t timestamp, uint32_t sensorHandle) {
     48     header->baseTimestamp = timestamp;
     49     header->sensorHandle = sensorHandle;
     50     header->readingCount = 1;
     51     header->reserved[0] = header->reserved[1] = 0;
     52 }
     53 
     54 static void processTripleAxisData(const struct TripleAxisDataEvent *src, uint32_t sensorHandle, uint8_t sensorType)
     55 {
     56     int i;
     57     struct chreSensorThreeAxisData three;
     58 
     59     initDataHeader(&three.header, src->referenceTime, sensorHandle);
     60     three.readings[0].timestampDelta = 0;
     61 
     62     for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
     63         if (i > 0)
     64             three.header.baseTimestamp += src->samples[i].deltaTime;
     65         three.readings[0].x = src->samples[i].x;
     66         three.readings[0].y = src->samples[i].y;
     67         three.readings[0].z = src->samples[i].z;
     68 
     69         nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &three);
     70     }
     71 }
     72 
     73 static void processSingleAxisData(const struct SingleAxisDataEvent *src, uint32_t sensorHandle, uint8_t sensorType)
     74 {
     75     int i;
     76 
     77     switch (sensorType) {
     78     case CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT:
     79     case CHRE_SENSOR_TYPE_STATIONARY_DETECT: {
     80         struct chreSensorOccurrenceData occ;
     81 
     82         initDataHeader(&occ.header, src->referenceTime, sensorHandle);
     83         occ.readings[0].timestampDelta = 0;
     84 
     85         for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
     86             if (i > 0)
     87                 occ.header.baseTimestamp += src->samples[i].deltaTime;
     88 
     89             nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &occ);
     90         }
     91         break;
     92     }
     93     case CHRE_SENSOR_TYPE_LIGHT:
     94     case CHRE_SENSOR_TYPE_PRESSURE: {
     95         struct chreSensorFloatData flt;
     96 
     97         initDataHeader(&flt.header, src->referenceTime, sensorHandle);
     98         flt.readings[0].timestampDelta = 0;
     99 
    100         for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
    101             if (i > 0)
    102                 flt.header.baseTimestamp += src->samples[i].deltaTime;
    103             flt.readings[0].value = src->samples[i].fdata;
    104 
    105             nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &flt);
    106         }
    107         break;
    108     }
    109     case CHRE_SENSOR_TYPE_PROXIMITY: {
    110         struct chreSensorByteData byte;
    111 
    112         initDataHeader(&byte.header, src->referenceTime, sensorHandle);
    113         byte.readings[0].timestampDelta = 0;
    114 
    115         for (i=0; i<src->samples[0].firstSample.numSamples; i++) {
    116             if (i > 0)
    117                 byte.header.baseTimestamp += src->samples[i].deltaTime;
    118             byte.readings[0].isNear = src->samples[i].fdata == 0.0f;
    119             byte.readings[0].invalid = false;
    120             byte.readings[0].padding0 = 0;
    121 
    122             nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &byte);
    123         }
    124         break;
    125     }
    126     }
    127 }
    128 
    129 static void processEmbeddedData(const void *src, uint32_t sensorHandle, uint8_t sensorType)
    130 {
    131     union EmbeddedDataPoint data = (union EmbeddedDataPoint)((void *)src);
    132 
    133     switch (sensorType) {
    134     case CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT:
    135     case CHRE_SENSOR_TYPE_STATIONARY_DETECT: {
    136         struct chreSensorOccurrenceData occ;
    137 
    138         initDataHeader(&occ.header, eOsSensorGetTime(), sensorHandle);
    139         occ.readings[0].timestampDelta = 0;
    140 
    141         nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &occ);
    142         break;
    143     }
    144     case CHRE_SENSOR_TYPE_LIGHT:
    145     case CHRE_SENSOR_TYPE_PRESSURE: {
    146         struct chreSensorFloatData flt;
    147 
    148         initDataHeader(&flt.header, eOsSensorGetTime(), sensorHandle);
    149         flt.readings[0].timestampDelta = 0;
    150         flt.readings[0].value = data.fdata;
    151 
    152         nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &flt);
    153         break;
    154     }
    155     case CHRE_SENSOR_TYPE_PROXIMITY: {
    156         struct chreSensorByteData byte;
    157 
    158         initDataHeader(&byte.header, eOsSensorGetTime(), sensorHandle);
    159         byte.readings[0].timestampDelta = 0;
    160         byte.readings[0].isNear = data.fdata == 0.0f;
    161         byte.readings[0].invalid = false;
    162         byte.readings[0].padding0 = 0;
    163 
    164         nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_DATA_EVENT_BASE | sensorType, &byte);
    165         break;
    166     }
    167     }
    168 }
    169 
    170 static void chreappProcessSensorData(uint16_t evt, const void *eventData)
    171 {
    172     const struct SensorInfo *si;
    173     uint32_t sensorHandle;
    174 
    175     if (eventData == SENSOR_DATA_EVENT_FLUSH)
    176         return;
    177 
    178     si = eOsSensorFind(SENSOR_TYPE(evt), 0, &sensorHandle);
    179     if (si && eOsSensorGetReqRate(sensorHandle)) {
    180         switch (si->numAxis) {
    181         case NUM_AXIS_EMBEDDED:
    182             processEmbeddedData(eventData, sensorHandle, SENSOR_TYPE(evt));
    183             break;
    184         case NUM_AXIS_ONE:
    185             processSingleAxisData(eventData, sensorHandle, SENSOR_TYPE(evt));
    186             break;
    187         case NUM_AXIS_THREE:
    188             processTripleAxisData(eventData, sensorHandle, SENSOR_TYPE(evt));
    189             break;
    190         }
    191 
    192         if (SENSOR_TYPE(evt) == CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT
    193             || SENSOR_TYPE(evt) == CHRE_SENSOR_TYPE_STATIONARY_DETECT) {
    194             // one-shot, disable after receiving sample
    195             chreSensorConfigure(sensorHandle, CHRE_SENSOR_CONFIGURE_MODE_DONE, CHRE_SENSOR_INTERVAL_DEFAULT, CHRE_SENSOR_LATENCY_DEFAULT);
    196         }
    197     }
    198 }
    199 
    200 static void chreappProcessConfigEvt(uint16_t evt, const void *eventData)
    201 {
    202     const struct SensorRateChangeEvent *msg = eventData;
    203     struct chreSensorSamplingStatusEvent change;
    204 
    205     change.sensorHandle = msg->sensorHandle;
    206     if (!msg->newRate) {
    207         change.status.enabled = 0;
    208         change.status.interval = 0;
    209         change.status.latency = 0;
    210     } else {
    211         change.status.enabled = true;
    212         if (msg->newRate == SENSOR_RATE_ONDEMAND
    213             || msg->newRate == SENSOR_RATE_ONCHANGE
    214             || msg->newRate == SENSOR_RATE_ONESHOT)
    215             change.status.interval = CHRE_SENSOR_INTERVAL_DEFAULT;
    216         else
    217             change.status.interval = (UINT32_C(1024000000) / msg->newRate) * UINT64_C(1000);
    218 
    219         if (msg->newLatency == SENSOR_LATENCY_NODATA)
    220             change.status.latency = CHRE_SENSOR_INTERVAL_DEFAULT;
    221         else
    222             change.status.latency = msg->newLatency;
    223     }
    224 
    225     nanoappHandleEvent(CHRE_INSTANCE_ID, CHRE_EVENT_SENSOR_SAMPLING_CHANGE, &change);
    226 }
    227 
    228 static void chreappHandle(uint32_t eventTypeAndTid, const void *eventData)
    229 {
    230     uint16_t evt = eventTypeAndTid;
    231     uint16_t srcTid = eventTypeAndTid >> 16;
    232     const void *data = eventData;
    233 
    234     union EventLocalData {
    235     struct chreMessageFromHostData msg;
    236     } u;
    237 
    238     switch(evt) {
    239     case EVT_APP_TIMER:
    240         evt = CHRE_EVENT_TIMER;
    241         data = ((struct TimerEvent *)eventData)->data;
    242         break;
    243     case EVT_APP_FROM_HOST:
    244         srcTid = CHRE_INSTANCE_ID;
    245         evt = CHRE_EVENT_MESSAGE_FROM_HOST;
    246         data = &u.msg;
    247         u.msg.message = (uint8_t*)eventData + 1;
    248         u.msg.reservedMessageType = 0;
    249         u.msg.messageSize = *(uint8_t*)eventData;
    250         break;
    251     case EVT_APP_FROM_HOST_CHRE:
    252     {
    253         const struct NanohubMsgChreHdr *hdr = eventData;
    254         srcTid = CHRE_INSTANCE_ID;
    255         evt = CHRE_EVENT_MESSAGE_FROM_HOST;
    256         data = &u.msg;
    257         u.msg.message = hdr + 1;
    258         u.msg.reservedMessageType = hdr->appEvent;
    259         u.msg.messageSize = hdr->size;
    260         break;
    261     }
    262     case EVT_APP_SENSOR_SELF_TEST:
    263     case EVT_APP_SENSOR_MARSHALL:
    264     case EVT_APP_SENSOR_SEND_ONE_DIR_EVT:
    265     case EVT_APP_SENSOR_CFG_DATA:
    266     case EVT_APP_SENSOR_CALIBRATE:
    267     case EVT_APP_SENSOR_TRIGGER:
    268     case EVT_APP_SENSOR_FLUSH:
    269     case EVT_APP_SENSOR_SET_RATE:
    270     case EVT_APP_SENSOR_FW_UPLD:
    271     case EVT_APP_SENSOR_POWER:
    272         // sensor events; pass through
    273         break;
    274     default:
    275         // ignore any other system events; OS may send them to any app
    276         if (evt < EVT_NO_FIRST_USER_EVENT)
    277             return;
    278         else if (evt > EVT_NO_FIRST_SENSOR_EVENT && evt < EVT_NO_SENSOR_CONFIG_EVENT) {
    279             return chreappProcessSensorData(evt, data);
    280         } else if (evt > EVT_NO_SENSOR_CONFIG_EVENT && evt < EVT_APP_START) {
    281             return chreappProcessConfigEvt(evt, data);
    282         }
    283     }
    284     nanoappHandleEvent(srcTid, evt, data);
    285 }
    286 
    287 // Collect entry points
    288 const struct AppFuncs SET_EXTERNAL_APP_ATTRIBUTES(used, section (".app_init"),visibility("default")) _mAppFuncs = {
    289     .init   = chreappStart,
    290     .end    = chreappEnd,
    291     .handle = chreappHandle,
    292 };
    293 
    294 // declare version for compatibility with current runtime
    295 const uint32_t SET_EXTERNAL_APP_VERSION(used, section (".app_version"), visibility("default")) _mAppVer = 0;
    296