ENTS-tock
Environmental NeTworked Sensor firmware on Tock OS
Loading...
Searching...
No Matches
sensor.c
Go to the documentation of this file.
1#include "sensor.h"
2
3#include <nanopb/pb_decode.h>
4#include <nanopb/pb_encode.h>
5#include <stdio.h>
6
15bool MetadataEqual(Metadata* left, Metadata* right);
16
26unsigned int Format(RepeatedSensorMeasurements* meas);
27
36SensorStatus Parse(RepeatedSensorMeasurements* meas);
37
38void PrintMetadata(const Metadata* meta);
39
41 const SensorMeasurement meas[],
42 size_t count,
43 RepeatedSensorMeasurements* out);
44
45bool MetadataEqual(Metadata* left, Metadata* right) {
46 if (left->ts != right->ts) {
47 return false;
48 }
49 if (left->logger_id != right->logger_id) {
50 return false;
51 }
52 if (left->cell_id != right->cell_id) {
53 return false;
54 }
55
56 return true;
57}
58
59unsigned int Format(RepeatedSensorMeasurements* meas) {
60 unsigned int most_count = 1;
61
62 // find the most repeated metadata
63 for (int first = 0; first < meas->measurements_count; first++) {
64 unsigned int current_count = 1;
65 for (int second = 0; second < meas->measurements_count; second++) {
66 // skip over yourself
67 if (first == second) {
68 continue;
69 }
70
71 // check for duplicates
72 Metadata* first_meta = &meas->measurements[first].meta;
73 Metadata* second_meta = &meas->measurements[second].meta;
74 if (MetadataEqual(first_meta, second_meta)) {
75 current_count++;
76 }
77 }
78
79 // update if there are more duplicates
80 if (current_count > most_count) {
81 most_count = current_count;
82 meas->meta = meas->measurements[first].meta;
83 }
84 }
85
86 // return early if there is no duplicates
87 if (most_count < 2) {
88 return 1;
89 }
90
91 // enable top level metadata and delete duplicates
92 meas->has_meta = true;
93 for (int i = 0; i < meas->measurements_count; i++) {
94 Metadata* current_meta = &meas->measurements[i].meta;
95 if (MetadataEqual(&meas->meta, current_meta)) {
96 meas->measurements[i].has_meta = false;
97 }
98 }
99
100 return most_count;
101}
102
103SensorStatus Parse(RepeatedSensorMeasurements* meas) {
104 // if no top level metadata, check each measurements has metadata
105 if (!meas->has_meta) {
106 for (size_t i = 0; i < meas->measurements_count; i++) {
107 if (!meas->measurements[i].has_meta) {
108 return SENSOR_ERROR;
109 }
110 }
111 } else {
112 // add top level metadata to measurements missing it
113 for (size_t i = 0; i < meas->measurements_count; i++) {
114 if (!meas->measurements[i].has_meta) {
115 meas->measurements[i].meta = meas->meta;
116 meas->measurements[i].has_meta = true;
117 }
118 }
119 }
120
121 return SENSOR_OK;
122}
123
125 const SensorMeasurement meas[],
126 size_t count,
127 RepeatedSensorMeasurements* out) {
128 // keep meta for future optimization
129 (void)meta;
130
131 // check count doesn't exceed max count
132 size_t max_count = sizeof(out->measurements) / sizeof(out->measurements[0]);
133 if (count > max_count) {
135 }
136
137 // cannot reset a pointer directly, just hoping this works
138 //*out = RepeatedSensorMeasurements_init_zero;
139
140 // copy measurements
141 out->measurements_count = count;
142 for (size_t i = 0; i < count; i++) {
143 out->measurements[i] = meas[i];
144 }
145
146 Format(out);
147
148 return SENSOR_OK;
149}
150
151SensorStatus EncodeSensorMeasurement(const SensorMeasurement* meas,
152 uint8_t* buffer, size_t* size) {
153 // create output stream
154 pb_ostream_t ostream = pb_ostream_from_buffer(buffer, 256);
155 // encode message and check rc
156 bool status = pb_encode(&ostream, SensorMeasurement_fields, meas);
157 if (!status) {
158 return SENSOR_ERROR;
159 }
160
161 // return number of bytes written
162 *size = ostream.bytes_written;
163 return SENSOR_OK;
164}
165
167 const SensorMeasurement meas[],
168 size_t count, uint8_t* buffer,
169 size_t size, size_t* length) {
170 RepeatedSensorMeasurements rep_meas = RepeatedSensorMeasurements_init_zero;
171
172 // format into repeated structure
173 SensorStatus sensor_status =
174 FormatRepeatedSensorMeasurements(meta, meas, count, &rep_meas);
175 if (sensor_status != SENSOR_OK) {
176 return sensor_status;
177 }
178
179 // encode
180 pb_ostream_t ostream = pb_ostream_from_buffer(buffer, size);
181 bool status =
182 pb_encode(&ostream, RepeatedSensorMeasurements_fields, &rep_meas);
183 if (!status) {
184 return SENSOR_ERROR;
185 }
186
187 *length = ostream.bytes_written;
188 return SENSOR_OK;
189}
190
192 const SensorMeasurement meas[],
193 size_t count, size_t* size) {
194 RepeatedSensorMeasurements rep_meas = RepeatedSensorMeasurements_init_zero;
195
196 // format into repeated structure
197 SensorStatus sensor_status =
198 FormatRepeatedSensorMeasurements(meta, meas, count, &rep_meas);
199 if (sensor_status != SENSOR_OK) {
200 return sensor_status;
201 }
202
203 // get size
204 bool status =
205 pb_get_encoded_size(size, RepeatedSensorMeasurements_fields, &rep_meas);
206 if (!status) {
207 return SENSOR_ERROR;
208 }
209
210 return SENSOR_OK;
211}
212
213SensorStatus EncodeUint32Measurement(Metadata meta, uint32_t value,
214 SensorType type, uint8_t* buffer,
215 size_t* size) {
216 SensorMeasurement meas = SensorMeasurement_init_zero;
217
218 // has_meta is handled in EncodeMeasuremnet function
219 meas.meta = meta;
220 meas.has_meta = true;
221
222 meas.type = type;
223 meas.which_value = SensorMeasurement_unsigned_int_tag;
224 meas.value.unsigned_int = value;
225
226 return EncodeSensorMeasurement(&meas, buffer, size);
227}
228
229SensorStatus EncodeInt32Measurement(Metadata meta, int32_t value,
230 SensorType type, uint8_t* buffer,
231 size_t* size) {
232 SensorMeasurement meas = SensorMeasurement_init_zero;
233
234 meas.meta = meta;
235 meas.has_meta = true;
236
237 meas.type = type;
238 meas.which_value = SensorMeasurement_signed_int_tag;
239 meas.value.signed_int = value;
240
241 return EncodeSensorMeasurement(&meas, buffer, size);
242}
243
244SensorStatus EncodeDoubleMeasurement(Metadata meta, double value,
245 SensorType type, uint8_t* buffer,
246 size_t* size) {
247 SensorMeasurement meas = SensorMeasurement_init_zero;
248
249 meas.meta = meta;
250 meas.has_meta = true;
251
252 meas.type = type;
253 meas.which_value = SensorMeasurement_decimal_tag;
254 meas.value.decimal = value;
255
256 return EncodeSensorMeasurement(&meas, buffer, size);
257}
258
259SensorStatus DecodeSensorMeasurement(const uint8_t* data, const size_t len,
260 SensorMeasurement* meas) {
261 pb_istream_t istream = pb_istream_from_buffer(data, len);
262 bool status = pb_decode(&istream, SensorMeasurement_fields, meas);
263 if (!status) {
264 return SENSOR_ERROR;
265 }
266
267 return SENSOR_OK;
268}
269
271 const uint8_t* data, const size_t len,
272 RepeatedSensorMeasurements* measurements) {
273 pb_istream_t istream = pb_istream_from_buffer(data, len);
274 bool status =
275 pb_decode(&istream, RepeatedSensorMeasurements_fields, measurements);
276 if (!status) {
277 return SENSOR_ERROR;
278 }
279
280 return Parse(measurements);
281}
282
284 const RepeatedSensorResponses responses, uint8_t* buffer, size_t* size) {
285 pb_ostream_t ostream = pb_ostream_from_buffer(buffer, *size);
286 bool status = pb_encode(&ostream, RepeatedSensorResponses_fields, &responses);
287 if (!status) {
288 return SENSOR_ERROR;
289 }
290
291 *size = ostream.bytes_written;
292 return SENSOR_OK;
293}
294
295SensorStatus DecodeRepeatedSensorReponses(const uint8_t* data, const size_t len,
296 RepeatedSensorResponses* resp) {
297 pb_istream_t istream = pb_istream_from_buffer(data, len);
298 bool status = pb_decode(&istream, RepeatedSensorResponses_fields, resp);
299 if (!status) {
300 return SENSOR_ERROR;
301 }
302
303 return SENSOR_OK;
304}
305
306SensorStatus CheckSensorResponse(const SensorResponse* resp) {
307 // Handle an overall error for repeated sensor measurement
308 if (resp->idx == 0) {
309 switch (resp->error) {
310 case SensorError_OK:
311 return SENSOR_OK;
312 default:
313 return SENSOR_REUPLOAD;
314 }
315 // Otherwise handle on individual measurement
316 } else {
317 switch (resp->error) {
318 case SensorError_OK:
319 return SENSOR_OK;
320 case SensorError_LOGGER:
321 case SensorError_CELL:
322 case SensorError_UNSUPPORTED:
323 return SENSOR_FORMAT;
324 default:
325 return SENSOR_REUPLOAD;
326 }
327 }
328
329 return SENSOR_OK;
330}
331
332void PrintMetadata(const Metadata* meta) {
333 printf(" cell_id : %ld\n", meta->cell_id);
334 printf(" logger_id: %ld\n", meta->logger_id);
335 printf(" ts : %ld\n", meta->ts);
336}
337
338void PrintSensorMeasurement(const SensorMeasurement* m) {
339 printf(" idx: %ld\n", m->idx);
340 printf(" has_meta: %s\n", m->has_meta ? "true" : "false");
341
342 if (m->has_meta) {
343 printf(" Metadata:\n");
344 PrintMetadata(&m->meta);
345 }
346
347 printf(" type: %d\n", m->type);
348
349 printf(" value: ");
350 switch (m->which_value) {
351 case SensorMeasurement_unsigned_int_tag:
352 printf("%lu (unsigned)\n", m->value.unsigned_int);
353 break;
354
355 case SensorMeasurement_signed_int_tag:
356 printf("%ld (signed)\n", m->value.signed_int);
357 break;
358
359 case SensorMeasurement_decimal_tag:
360 printf("%f (decimal)\n", m->value.decimal);
361 break;
362
363 default:
364 printf("<unset>\n");
365 break;
366 }
367}
368
369void PrintRepeatedSensorMeasurements(const RepeatedSensorMeasurements* msg) {
370 printf("RepeatedSensorMeasurements\n");
371 printf(" has_meta: %s\n", msg->has_meta ? "true" : "false");
372
373 if (msg->has_meta) {
374 printf(" Metadata:\n");
375 PrintMetadata(&msg->meta);
376 }
377
378 printf(" type: %d\n", msg->type);
379 printf(" measurements_count: %u\n", (unsigned)msg->measurements_count);
380
381 for (pb_size_t i = 0; i < msg->measurements_count; i++) {
382 printf(" Measurement[%u]\n", (unsigned)i);
383 PrintSensorMeasurement(&msg->measurements[i]);
384 }
385}
const char data[]
uint8_t buffer[32]
uint8_t i
SensorStatus DecodeSensorMeasurement(const uint8_t *data, const size_t len, SensorMeasurement *meas)
Decodes a sensor measurement from a buffer.
Definition sensor.c:259
void PrintRepeatedSensorMeasurements(const RepeatedSensorMeasurements *msg)
Definition sensor.c:369
SensorStatus EncodeSensorMeasurement(const SensorMeasurement *meas, uint8_t *buffer, size_t *size)
Encodes a single sensor measurement into a buffer.
Definition sensor.c:151
SensorStatus RepeatedSensorMeasurementsSize(Metadata meta, const SensorMeasurement meas[], size_t count, size_t *size)
Gets the size of multiple repeated sensor measurements when encoded.
Definition sensor.c:191
SensorStatus EncodeInt32Measurement(Metadata meta, int32_t value, SensorType type, uint8_t *buffer, size_t *size)
Encodes an int64_t sensor measurement into a buffer.
Definition sensor.c:229
SensorStatus CheckSensorResponse(const SensorResponse *resp)
Checks a single sensor response for errors.
Definition sensor.c:306
SensorStatus EncodeRepeatedSensorMeasurements(Metadata meta, const SensorMeasurement meas[], size_t count, uint8_t *buffer, size_t size, size_t *length)
Encodes multiple sensor measurements into a buffer.
Definition sensor.c:166
SensorStatus EncodeDoubleMeasurement(Metadata meta, double value, SensorType type, uint8_t *buffer, size_t *size)
Encodes a double sensor measurement into a buffer.
Definition sensor.c:244
SensorStatus DecodeRepeatedSensorReponses(const uint8_t *data, const size_t len, RepeatedSensorResponses *resp)
Decodes multiple sensor responses from a buffer.
Definition sensor.c:295
SensorStatus EncodeRepeatedSensorResponses(const RepeatedSensorResponses responses, uint8_t *buffer, size_t *size)
Encodes multiple sensor responses into a buffer.
Definition sensor.c:283
enum _SensorStatus SensorStatus
SensorStatus DecodeRepeatedSensorMeasurements(const uint8_t *data, const size_t len, RepeatedSensorMeasurements *measurements)
Decodes multiple sensor measurements from a buffer.
Definition sensor.c:270
SensorStatus EncodeUint32Measurement(Metadata meta, uint32_t value, SensorType type, uint8_t *buffer, size_t *size)
Encodes a uint64_t sensor measurement into a buffer.
Definition sensor.c:213
void PrintSensorMeasurement(const SensorMeasurement *m)
Definition sensor.c:338
@ SENSOR_FORMAT
Definition sensor.h:47
@ SENSOR_ERROR
Definition sensor.h:42
@ SENSOR_REUPLOAD
Definition sensor.h:45
@ SENSOR_OK
Definition sensor.h:41
@ SENSOR_OUT_OF_BOUNDS
Definition sensor.h:43
SensorStatus FormatRepeatedSensorMeasurements(Metadata meta, const SensorMeasurement meas[], size_t count, RepeatedSensorMeasurements *out)
Definition sensor.c:124
SensorStatus Parse(RepeatedSensorMeasurements *meas)
Parses repeated sensor measurements to add metadata back to individual measurements.
Definition sensor.c:103
void PrintMetadata(const Metadata *meta)
Definition sensor.c:332
unsigned int Format(RepeatedSensorMeasurements *meas)
Optimizes repeated sensor measurements for size.
Definition sensor.c:59
bool MetadataEqual(Metadata *left, Metadata *right)
Compares two Metadata structures for equality.
Definition sensor.c:45
Library for sensor measurement encoding/decoding.