/ bm_rbr_pressure_difference_signal_msg.cpp
bm_rbr_pressure_difference_signal_msg.cpp
  1  #include "bm_rbr_pressure_difference_signal_msg.h"
  2  #include <math.h>
  3  
  4  namespace BmRbrPressureDifferenceSignalMsg {
  5  
  6  /*!
  7   * \brief Encode the BmRbrPressureDifferenceSignalMsg::Data structure into a
  8   * CBOR buffer.
  9   *
 10   * \param[in] d The BmRbrPressureDifferenceSignalMsg::Data structure to encode.
 11   * \param[out] cbor_buffer The buffer to encode the data into.
 12   * \param[in] size The size of the buffer.
 13   * \param[out] encoded_len The length of the encoded data.
 14   *
 15   * \return CborError
 16   */
 17  CborError encode(Data &d, uint8_t *cbor_buffer, size_t size,
 18                   size_t *encoded_len) {
 19    CborError err;
 20    CborEncoder encoder, map_encoder, array_encoder;
 21    cbor_encoder_init(&encoder, cbor_buffer, size, 0);
 22  
 23    do {
 24      if (!cbor_buffer) {
 25        err = CborErrorOutOfMemory;
 26        break;
 27      }
 28  
 29      if (!d.difference_signal) {
 30        err = CborErrorOutOfMemory;
 31        break;
 32      }
 33  
 34      if (!d.num_samples) {
 35        err = CborErrorImproperValue;
 36        break;
 37      }
 38  
 39      err = cbor_encoder_create_map(&encoder, &map_encoder, NUM_FIELDS);
 40      if (err != CborNoError) {
 41        printf("cbor_encoder_create_map failed: %d\n", err);
 42        if (err != CborErrorOutOfMemory) {
 43          break;
 44        }
 45      }
 46  
 47      // sensor_header_msg
 48      err = SensorHeaderMsg::encode(map_encoder, d.header);
 49      if (err != CborNoError) {
 50        printf("SensorHeaderMsg::encode failed: %d\n", err);
 51        if (err != CborErrorOutOfMemory) {
 52          break;
 53        }
 54      }
 55      
 56      // sequence_num
 57      err = cbor_encode_text_stringz(&map_encoder, "sequence_num");
 58      if (err != CborNoError) {
 59        printf("cbor_encode_text_stringz failed for sequence_num key: %d\n", err);
 60        if (err != CborErrorOutOfMemory) {
 61          break;
 62        }
 63      }
 64      err = cbor_encode_uint(&map_encoder, d.sequence_num);
 65      if (err != CborNoError) {
 66        printf("cbor_encode_uint failed for sequence_num value: %d\n", err);
 67        if (err != CborErrorOutOfMemory) {
 68          break;
 69        }
 70      }
 71    
 72      // total_samples
 73      err = cbor_encode_text_stringz(&map_encoder, "total_samples");
 74      if (err != CborNoError) {
 75        printf("cbor_encode_text_stringz failed for total_samples key: %d\n", err);
 76        if (err != CborErrorOutOfMemory) {
 77          break;
 78        }
 79      }
 80      err = cbor_encode_uint(&map_encoder, d.total_samples);
 81      if (err != CborNoError) {
 82        printf("cbor_encode_uint failed for total_samples value: %d\n", err);
 83        if (err != CborErrorOutOfMemory) {
 84          break;
 85        }
 86      }
 87  
 88      // num_samples
 89      err = cbor_encode_text_stringz(&map_encoder, "num_samples");
 90      if (err != CborNoError) {
 91        printf("cbor_encode_text_stringz failed for num_samples key: %d\n", err);
 92        if (err != CborErrorOutOfMemory) {
 93          break;
 94        }
 95      }
 96      err = cbor_encode_uint(&map_encoder, d.num_samples);
 97      if (err != CborNoError) {
 98        printf("cbor_encode_uint failed for num_samples value: %d\n", err);
 99        if (err != CborErrorOutOfMemory) {
100          break;
101        }
102      }
103  
104      // residual_0
105      err = cbor_encode_text_stringz(&map_encoder, "residual_0");
106      if (err != CborNoError) {
107        printf("cbor_encode_text_stringz failed for residual_0 key: %d\n", err);
108        if (err != CborErrorOutOfMemory) {
109          break;
110        }
111      }
112      err = cbor_encode_double(&map_encoder, d.residual_0);
113      if (err != CborNoError) {
114        printf("cbor_encode_double failed for residual_0 value: %d\n", err);
115        if (err != CborErrorOutOfMemory) {
116          break;
117        }
118      }
119  
120      // residual_1
121      err = cbor_encode_text_stringz(&map_encoder, "residual_1");
122      if (err != CborNoError) {
123        printf("cbor_encode_text_stringz failed for residual_1 key: %d\n", err);
124        if (err != CborErrorOutOfMemory) {
125          break;
126        }
127      }
128      err = cbor_encode_double(&map_encoder, d.residual_1);
129      if (err != CborNoError) {
130        printf("cbor_encode_double failed for residual_1 value: %d\n", err);
131        if (err != CborErrorOutOfMemory) {
132          break;
133        }
134      }
135  
136      // difference_signal
137      err = cbor_encode_text_stringz(&map_encoder, "difference_signal");
138      if (err != CborNoError) {
139        printf("cbor_encode_text_stringz failed for difference_signal key: %d\n",
140               err);
141        if (err != CborErrorOutOfMemory) {
142          break;
143        }
144      }
145      err =
146          cbor_encoder_create_array(&map_encoder, &array_encoder, d.num_samples);
147      if (err != CborNoError) {
148        printf(
149            "cbor_encoder_create_array failed for difference_signal value: %d\n",
150            err);
151        if (err != CborErrorOutOfMemory) {
152          break;
153        }
154      }
155  
156      for (size_t i = 0; i < d.num_samples; i++) {
157        err = cbor_encode_double(&array_encoder, d.difference_signal[i]);
158        if (err != CborNoError) {
159          printf("cbor_encode_double failed for difference_signal value: %d\n",
160                 err);
161          if (err != CborErrorOutOfMemory) {
162            break;
163          }
164        }
165      }
166  
167      if (err != CborNoError && err != CborErrorOutOfMemory) {
168        break;
169      }
170  
171      err = cbor_encoder_close_container(&map_encoder, &array_encoder);
172      if (err != CborNoError) {
173        printf("cbor_encoder_close_container failed: %d\n", err);
174        if (err != CborErrorOutOfMemory) {
175          break;
176        }
177      }
178  
179      err = cbor_encoder_close_container(&encoder, &map_encoder);
180      if (err == CborNoError) {
181        *encoded_len = cbor_encoder_get_buffer_size(&encoder, cbor_buffer);
182      } else {
183        printf("cbor_encoder_close_container failed: %d\n", err);
184  
185        if (err != CborErrorOutOfMemory) {
186          break;
187        }
188        size_t extra_bytes_needed = cbor_encoder_get_extra_bytes_needed(&encoder);
189        printf("extra_bytes_needed: %zu\n", extra_bytes_needed);
190      }
191    } while (0);
192  
193    return err;
194  }
195  
196  /*!
197   * \brief Decode a CBOR buffer into the BmRbrPressureDifferenceSignalMsg::Data
198   * structure.
199   *
200   * \param[in/out] d The BmRbrPressureDifferenceSignalMsg::Data structure to
201   * decode into. d.num_samples must be set to the maximum number of samples that
202   * can be put into the buffer d.difference_signal must be a valid pointer to an
203   * array of doubles of size d.num_samples
204   * \param[in] cbor_buffer The buffer to
205   * decode.
206   * \param[in] size The size of the buffer.
207   *
208   * \return CborError
209   */
210  CborError decode(Data &d, const uint8_t *cbor_buffer, size_t size) {
211    CborParser parser;
212    CborValue map;
213    CborError err = CborNoError;
214    do {
215      if (!cbor_buffer) {
216        err = CborErrorOutOfMemory;
217        break;
218      }
219      if (!d.difference_signal) {
220        err = CborErrorOutOfMemory;
221        break;
222      }
223      if (err != CborNoError) {
224        break;
225      }
226      err = cbor_parser_init(cbor_buffer, size, 0, &parser, &map);
227      if (err != CborNoError) {
228        break;
229      }
230  
231      err = cbor_value_validate_basic(&map);
232      if (err != CborNoError) {
233        break;
234      }
235      if (!cbor_value_is_map(&map)) {
236        err = CborErrorIllegalType;
237        break;
238      }
239  
240      size_t num_fields;
241      err = cbor_value_get_map_length(&map, &num_fields);
242      if (err != CborNoError) {
243        break;
244      }
245      if (num_fields != NUM_FIELDS) {
246        err = CborErrorUnknownLength;
247        printf("expected %zu fields but got %zu\n", NUM_FIELDS, num_fields);
248        break;
249      }
250  
251      CborValue value;
252      err = cbor_value_enter_container(&map, &value);
253      if (err != CborNoError) {
254        break;
255      }
256  
257      // header
258      err = SensorHeaderMsg::decode(value, d.header);
259      if (err != CborNoError) {
260        break;
261      }
262  
263      // sequence_num
264      if (!cbor_value_is_text_string(&value)) {
265        err = CborErrorIllegalType;
266        printf("expected string key but got something else\n");
267        break;
268      }
269      err = cbor_value_advance(&value);
270      if (err != CborNoError) {
271        break;
272      }
273      uint64_t sequence_num;
274      err = cbor_value_get_uint64(&value, &sequence_num);
275      if (err != CborNoError) {
276        break;
277      }
278      d.sequence_num = sequence_num;
279      err = cbor_value_advance(&value);
280      if (err != CborNoError) {
281        break;
282      }
283  
284      // total_samples
285      if (!cbor_value_is_text_string(&value)) {
286        err = CborErrorIllegalType;
287        printf("expected string key but got something else\n");
288        break;
289      }
290      err = cbor_value_advance(&value);
291      if (err != CborNoError) {
292        break;
293      }
294      uint64_t total_samples;
295      err = cbor_value_get_uint64(&value, &total_samples);
296      if (err != CborNoError) {
297        break;
298      }
299      d.total_samples = total_samples;
300      err = cbor_value_advance(&value);
301      if (err != CborNoError) {
302        break;
303      }
304  
305      // num_samples
306      if (!cbor_value_is_text_string(&value)) {
307        err = CborErrorIllegalType;
308        printf("expected string key but got something else\n");
309        break;
310      }
311      err = cbor_value_advance(&value);
312      if (err != CborNoError) {
313        break;
314      }
315      uint64_t num_samples;
316      err = cbor_value_get_uint64(&value, &num_samples);
317      if (err != CborNoError) {
318        break;
319      }
320      if (d.num_samples < num_samples) {
321        err = CborErrorOutOfMemory;
322        break;
323      }
324      d.num_samples = num_samples;
325      err = cbor_value_advance(&value);
326      if (err != CborNoError) {
327        break;
328      }
329  
330      // residual_0
331      if (!cbor_value_is_text_string(&value)) {
332        err = CborErrorIllegalType;
333        printf("expected string key but got something else\n");
334        break;
335      }
336      err = cbor_value_advance(&value);
337      if (err != CborNoError) {
338        break;
339      }
340      err = cbor_value_get_double(&value, &d.residual_0);
341      if (err != CborNoError) {
342        break;
343      }
344      err = cbor_value_advance(&value);
345      if (err != CborNoError) {
346        break;
347      }
348  
349      // residual_1
350      if (!cbor_value_is_text_string(&value)) {
351        err = CborErrorIllegalType;
352        printf("expected string key but got something else\n");
353        break;
354      }
355      err = cbor_value_advance(&value);
356      if (err != CborNoError) {
357        break;
358      }
359      err = cbor_value_get_double(&value, &d.residual_1);
360      if (err != CborNoError) {
361        break;
362      }
363      err = cbor_value_advance(&value);
364      if (err != CborNoError) {
365        break;
366      }
367  
368      // difference_signal
369      if (!cbor_value_is_text_string(&value)) {
370        err = CborErrorIllegalType;
371        printf("expected string key but got something else\n");
372        break;
373      }
374      err = cbor_value_advance(&value);
375      if (err != CborNoError) {
376        break;
377      }
378      if (!cbor_value_is_array(&value)) {
379        err = CborErrorIllegalType;
380        printf("expected array key but got something else\n");
381        break;
382      }
383      size_t array_num_samples;
384      err = cbor_value_get_array_length(&value, &array_num_samples);
385      if (err != CborNoError) {
386        break;
387      }
388      if (array_num_samples != d.num_samples) {
389        err = CborErrorUnknownLength;
390        printf("expected %zu samples but got %zu\n", d.num_samples,
391               array_num_samples);
392        break;
393      }
394  
395      CborValue array_elem;
396      if (cbor_value_enter_container(&value, &array_elem) != CborNoError) {
397        printf("Failed to enter the array\n");
398        break;
399      }
400      for (size_t i = 0; i < d.num_samples; i++) {
401        double sample;
402        err = cbor_value_get_double(&array_elem, &sample);
403        if (err != CborNoError) {
404          break;
405        }
406        d.difference_signal[i] = sample;
407        if (cbor_value_advance(&array_elem) != CborNoError) {
408          printf("Failed to advance the array\n");
409          break;
410        }
411      }
412  
413      if (err != CborNoError) {
414        break;
415      }
416  
417      err = cbor_value_leave_container(&value, &array_elem);
418      if (err != CborNoError) {
419        break;
420      }
421  
422      if (cbor_value_at_end(&value)) {
423        err = CborNoError;
424      } else {
425        err = CborErrorGarbageAtEnd;
426      }
427  
428      if (err == CborNoError) {
429        err = cbor_value_leave_container(&map, &value);
430        if (err != CborNoError) {
431          break;
432        }
433        if (!cbor_value_at_end(&map)) {
434          err = CborErrorGarbageAtEnd;
435          break;
436        }
437      }
438    } while (0);
439  
440    return err;
441  }
442  
443  } // namespace BmRbrPressureDifferenceSignalMsg