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
chreappStart(uint32_t tid)35 static bool chreappStart(uint32_t tid)
36 {
37 __crt_init();
38 return nanoappStart();
39 }
40
chreappEnd(void)41 static void chreappEnd(void)
42 {
43 nanoappEnd();
44 __crt_exit();
45 }
46
initDataHeader(struct chreSensorDataHeader * header,uint64_t timestamp,uint32_t sensorHandle)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
processTripleAxisData(const struct TripleAxisDataEvent * src,uint32_t sensorHandle,uint8_t sensorType)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
processSingleAxisData(const struct SingleAxisDataEvent * src,uint32_t sensorHandle,uint8_t sensorType)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
processEmbeddedData(const void * src,uint32_t sensorHandle,uint8_t sensorType)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
chreappProcessSensorData(uint16_t evt,const void * eventData)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
chreappProcessConfigEvt(uint16_t evt,const void * eventData)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
chreappHandle(uint32_t eventTypeAndTid,const void * eventData)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 NanohubMsgChreHdrV10 *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