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 #ifndef SENSOREVENT_H_
18 #define SENSOREVENT_H_
19 
20 #include "contexthub.h"
21 #include "nanomessage.h"
22 
23 namespace android {
24 
25 // Copied from sensors.h in nanohub firmware/inc
26 struct SensorFirstSample
27 {
28     uint8_t numSamples;
29     uint8_t numFlushes;
30     uint8_t biasCurrent : 1;
31     uint8_t biasPresent : 1;
32     uint8_t biasSample : 6;
33     uint8_t interrupt;
34 };
35 
36 struct SingleAxisDataPoint {
37     union {
38         uint32_t deltaTime; //delta since last sample, for 0th sample this is firstSample
39         struct SensorFirstSample firstSample;
40     };
41     union {
42         float fdata;
43         int32_t idata;
44     };
45 } __attribute__((packed));
46 
47 struct CompressedTripleAxisDataPoint {
48     uint32_t deltaTime;
49     int16_t ix;
50     int16_t iy;
51     int16_t iz;
52 } __attribute__((packed));
53 
54 struct TripleAxisDataPoint {
55     union {
56         uint32_t deltaTime; //delta since last sample, for 0th sample this is firstSample
57         struct SensorFirstSample firstSample;
58     };
59     union {
60         float x;
61         int32_t ix;
62     };
63     union {
64         float y;
65         int32_t iy;
66     };
67     union {
68         float z;
69         int32_t iz;
70     };
71 } __attribute__((packed));
72 
73 /*
74  * Common timestamped sensor event structure is SensorEventHeader followed by
75  * a variable length array of sensor samples, each starting with
76  * SensorSampleHeader.
77  */
78 struct SensorEventHeader : public Event {
79     uint64_t reference_time;
80 } __attribute__((packed));
81 
82 struct SensorSampleHeader {
83     union {
84         struct SensorFirstSample first_sample_header;
85         uint32_t delta_time;
86     };
87 } __attribute__((packed));
88 
89 class SensorEvent : public ReadEventResponse {
90   public:
91     /*
92      * Returns a pointer to a ReadEventResponse that will be constructed from
93      * one of the sensor event types and populated from byte stream. If
94      * this function is called, it's assumed that the event type is within the
95      * range [EVT_NO_FIRST_SENSOR_EVENT, EVT_NO_SENSOR_CONFIG_EVENT)
96      */
97     static std::unique_ptr<SensorEvent> FromBytes(
98         const std::vector<uint8_t>& buffer);
99 
100     SensorType GetSensorType() const;
101     std::string GetSensorName() const;
102 
103     /*
104      * Subclasses should override this function to return the number of samples
105      * contained in the event.
106      */
107     virtual uint8_t GetNumSamples() const = 0;
108 
109   protected:
110     virtual bool SizeIsValid() const = 0;
111 };
112 
113 class TimestampedSensorEvent : public SensorEvent {
114   public:
115     uint8_t GetNumSamples() const override;
116     uint64_t GetReferenceTime() const;
117     uint64_t GetSampleTime(uint8_t index) const;
118     std::string GetSampleTimeStr(uint8_t index) const;
119     const SensorSampleHeader *GetSampleAtIndex(uint8_t index) const;
120 
121     std::string ToString() const override;
122 
123     virtual std::string StringForSample(uint8_t index) const = 0;
124 
125   protected:
126     bool SizeIsValid() const override;
127     std::string StringForAllSamples() const;
128 
129     /*
130      * Subclasses must implement this to be the size of each data point,
131      * including struct SensorSampleHeader.
132      */
133     virtual uint8_t GetSampleDataSize() const = 0;
134 };
135 
136 class SingleAxisSensorEvent : public TimestampedSensorEvent {
137   public:
138     virtual std::string StringForSample(uint8_t index) const override;
139 
140   protected:
141     uint8_t GetSampleDataSize() const override;
142 };
143 
144 // Same as SingleAxisSensorEvent, but data is interpreted as an integer instead
145 // of float
146 class SingleAxisIntSensorEvent : public SingleAxisSensorEvent {
147   public:
148     std::string StringForSample(uint8_t index) const override;
149 };
150 
151 class TripleAxisSensorEvent : public TimestampedSensorEvent {
152   public:
153     std::string StringForSample(uint8_t index) const override;
154 
155   protected:
156     uint8_t GetSampleDataSize() const override;
157 };
158 
159 class CompressedTripleAxisSensorEvent : public TimestampedSensorEvent {
160   public:
161     std::string StringForSample(uint8_t index) const override;
162 
163   protected:
164     uint8_t GetSampleDataSize() const override;
165 };
166 
167 }  // namespace android
168 
169 #endif // SENSOREVENT_H_
170