1 /* 2 * Copyright (C) 2017 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 struct chreNanoappInfo info; 237 } u; 238 239 switch(evt) { 240 case EVT_APP_TIMER: 241 evt = CHRE_EVENT_TIMER; 242 data = ((struct TimerEvent *)eventData)->data; 243 break; 244 case EVT_APP_FROM_HOST: 245 srcTid = CHRE_INSTANCE_ID; 246 evt = CHRE_EVENT_MESSAGE_FROM_HOST; 247 data = &u.msg; 248 u.msg.message = (uint8_t*)eventData + 1; 249 u.msg.messageType = 0; 250 u.msg.messageSize = *(uint8_t*)eventData; 251 u.msg.hostEndpoint = CHRE_HOST_ENDPOINT_UNSPECIFIED; 252 break; 253 case EVT_APP_FROM_HOST_CHRE: 254 { 255 if (chreGetApiVersion() == CHRE_API_VERSION_1_0) { 256 const struct NanohubMsgChreHdrV10 *hdr = eventData; 257 srcTid = CHRE_INSTANCE_ID; 258 evt = CHRE_EVENT_MESSAGE_FROM_HOST; 259 data = &u.msg; 260 u.msg.message = hdr + 1; 261 u.msg.messageType = hdr->appEvent; 262 u.msg.messageSize = hdr->size; 263 u.msg.hostEndpoint = CHRE_HOST_ENDPOINT_UNSPECIFIED; 264 } else { 265 const struct NanohubMsgChreHdr *hdr = eventData; 266 srcTid = CHRE_INSTANCE_ID; 267 evt = CHRE_EVENT_MESSAGE_FROM_HOST; 268 data = &u.msg; 269 u.msg.message = hdr + 1; 270 u.msg.messageType = hdr->appEvent; 271 u.msg.messageSize = hdr->size; 272 u.msg.hostEndpoint = hdr->endpoint; 273 } 274 break; 275 } 276 case EVT_APP_STARTED: 277 case EVT_APP_STOPPED: 278 { 279 const struct AppEventStartStop *msg = eventData; 280 srcTid = CHRE_INSTANCE_ID; 281 if (evt == EVT_APP_STARTED) 282 evt = CHRE_EVENT_NANOAPP_STARTED; 283 else 284 evt = CHRE_EVENT_NANOAPP_STOPPED; 285 data = &u.info; 286 u.info.appId = msg->appId; 287 u.info.version = msg->version; 288 u.info.instanceId = msg->tid; 289 break; 290 } 291 case EVT_APP_SENSOR_SELF_TEST: 292 case EVT_APP_SENSOR_MARSHALL: 293 case EVT_APP_SENSOR_SEND_ONE_DIR_EVT: 294 case EVT_APP_SENSOR_CFG_DATA: 295 case EVT_APP_SENSOR_CALIBRATE: 296 case EVT_APP_SENSOR_TRIGGER: 297 case EVT_APP_SENSOR_FLUSH: 298 case EVT_APP_SENSOR_SET_RATE: 299 case EVT_APP_SENSOR_FW_UPLD: 300 case EVT_APP_SENSOR_POWER: 301 // sensor events; pass through 302 break; 303 default: 304 // ignore any other system events; OS may send them to any app 305 if (evt < EVT_NO_FIRST_USER_EVENT) 306 return; 307 else if (evt > EVT_NO_FIRST_SENSOR_EVENT && evt < EVT_NO_SENSOR_CONFIG_EVENT) { 308 return chreappProcessSensorData(evt, data); 309 } else if (evt > EVT_NO_SENSOR_CONFIG_EVENT && evt < EVT_APP_START) { 310 return chreappProcessConfigEvt(evt, data); 311 } 312 } 313 nanoappHandleEvent(srcTid, evt, data); 314 } 315 316 // Collect entry points 317 const struct AppFuncs SET_EXTERNAL_APP_ATTRIBUTES(used, section (".app_init"),visibility("default")) _mAppFuncs = { 318 .init = chreappStart, 319 .end = chreappEnd, 320 .handle = chreappHandle, 321 }; 322 323 // declare version for compatibility with current runtime 324 const uint32_t SET_EXTERNAL_APP_VERSION(used, section (".app_version"), visibility("default")) _mAppVer = 0; 325