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