/ bm_rbr_data_msg.cpp
bm_rbr_data_msg.cpp
  1  #include "bm_rbr_data_msg.h"
  2  #include <math.h>
  3  
  4  namespace BmRbrDataMsg {
  5  
  6  CborError encode(Data &d, uint8_t *cbor_buffer, size_t size,
  7                   size_t *encoded_len) {
  8    CborError err;
  9    CborEncoder encoder, map_encoder;
 10    cbor_encoder_init(&encoder, cbor_buffer, size, 0);
 11  
 12    do {
 13      // Set the unused field to NaN
 14      switch (d.sensor_type) {
 15      case TEMPERATURE: {
 16        d.pressure_deci_bar = NAN;
 17        break;
 18      }
 19      case PRESSURE: {
 20        d.temperature_deg_c = NAN;
 21        break;
 22      }
 23      case PRESSURE_AND_TEMPERATURE: {
 24        break;
 25      }
 26      default: {
 27        d.temperature_deg_c = NAN;
 28        d.pressure_deci_bar = NAN;
 29        break;
 30      }
 31      }
 32  
 33      err = cbor_encoder_create_map(&encoder, &map_encoder, NUM_FIELDS);
 34      if (err != CborNoError) {
 35        printf("cbor_encoder_create_map failed: %d\n", err);
 36        if (err != CborErrorOutOfMemory) {
 37          break;
 38        }
 39      }
 40  
 41      // sensor_header_msg
 42      err = SensorHeaderMsg::encode(map_encoder, d.header);
 43      if (err != CborNoError) {
 44        printf("SensorHeaderMsg::encode failed: %d\n", err);
 45        if (err != CborErrorOutOfMemory) {
 46          break;
 47        }
 48      }
 49  
 50      // sensor_type
 51      err = cbor_encode_text_stringz(&map_encoder, "sensor_type");
 52      if (err != CborNoError) {
 53        printf("cbor_encode_text_stringz failed for sensor_type key: %d\n", err);
 54        if (err != CborErrorOutOfMemory) {
 55          break;
 56        }
 57      }
 58      err = cbor_encode_uint(&map_encoder, d.sensor_type);
 59      if (err != CborNoError) {
 60        printf("cbor_encode_double failed for sensor_type value: %d\n", err);
 61        if (err != CborErrorOutOfMemory) {
 62          break;
 63        }
 64      }
 65  
 66      // temperature_deg_c
 67      err = cbor_encode_text_stringz(&map_encoder, "temperature_deg_c");
 68      if (err != CborNoError) {
 69        printf("cbor_encode_text_stringz failed for temperature_deg_c key: %d\n",
 70               err);
 71        if (err != CborErrorOutOfMemory) {
 72          break;
 73        }
 74      }
 75      err = cbor_encode_double(&map_encoder, d.temperature_deg_c);
 76      if (err != CborNoError) {
 77        printf("cbor_encode_double failed for temperature_deg_c value: %d\n",
 78               err);
 79        if (err != CborErrorOutOfMemory) {
 80          break;
 81        }
 82      }
 83  
 84      // pressure_deci_bar
 85      err = cbor_encode_text_stringz(&map_encoder, "pressure_deci_bar");
 86      if (err != CborNoError) {
 87        printf("cbor_encode_text_stringz failed for pressure_deci_bar key: %d\n",
 88               err);
 89        if (err != CborErrorOutOfMemory) {
 90          break;
 91        }
 92      }
 93      err = cbor_encode_double(&map_encoder, d.pressure_deci_bar);
 94      if (err != CborNoError) {
 95        printf("cbor_encode_double failed for pressure_deci_bar value: %d\n",
 96               err);
 97        if (err != CborErrorOutOfMemory) {
 98          break;
 99        }
100      }
101  
102      err = cbor_encoder_close_container(&encoder, &map_encoder);
103      if (err == CborNoError) {
104        *encoded_len = cbor_encoder_get_buffer_size(&encoder, cbor_buffer);
105      } else {
106        printf("cbor_encoder_close_container failed: %d\n", err);
107  
108        if (err != CborErrorOutOfMemory) {
109          break;
110        }
111        size_t extra_bytes_needed = cbor_encoder_get_extra_bytes_needed(&encoder);
112        printf("extra_bytes_needed: %zu\n", extra_bytes_needed);
113      }
114    } while (0);
115  
116    return err;
117  }
118  
119  CborError decode(Data &d, const uint8_t *cbor_buffer, size_t size) {
120    CborParser parser;
121    CborValue map;
122    CborError err = cbor_parser_init(cbor_buffer, size, 0, &parser, &map);
123  
124    do {
125      if (err != CborNoError) {
126        break;
127      }
128      err = cbor_value_validate_basic(&map);
129      if (err != CborNoError) {
130        break;
131      }
132      if (!cbor_value_is_map(&map)) {
133        err = CborErrorIllegalType;
134        break;
135      }
136  
137      size_t num_fields;
138      err = cbor_value_get_map_length(&map, &num_fields);
139      if (err != CborNoError) {
140        break;
141      }
142      if (num_fields != NUM_FIELDS) {
143        err = CborErrorUnknownLength;
144        printf("expected %zu fields but got %zu\n", NUM_FIELDS, num_fields);
145        break;
146      }
147  
148      CborValue value;
149      err = cbor_value_enter_container(&map, &value);
150      if (err != CborNoError) {
151        break;
152      }
153  
154      // header
155      err = SensorHeaderMsg::decode(value, d.header);
156      if (err != CborNoError) {
157        break;
158      }
159  
160      // sensor_type
161      if (!cbor_value_is_text_string(&value)) {
162        err = CborErrorIllegalType;
163        printf("expected string key but got something else\n");
164        break;
165      }
166      err = cbor_value_advance(&value);
167      if (err != CborNoError) {
168        break;
169      }
170      uint64_t sensor_type;
171      err = cbor_value_get_uint64(&value, &sensor_type);
172      if (err != CborNoError) {
173        break;
174      }
175      d.sensor_type = static_cast<SensorType_t>(sensor_type);
176      err = cbor_value_advance(&value);
177      if (err != CborNoError) {
178        break;
179      }
180  
181      // temperature_deg_c
182      if (!cbor_value_is_text_string(&value)) {
183        err = CborErrorIllegalType;
184        printf("expected string key but got something else\n");
185        break;
186      }
187      err = cbor_value_advance(&value);
188      if (err != CborNoError) {
189        break;
190      }
191      err = cbor_value_get_double(&value, &d.temperature_deg_c);
192      if (err != CborNoError) {
193        break;
194      }
195      err = cbor_value_advance(&value);
196      if (err != CborNoError) {
197        break;
198      }
199  
200      // pressure_deci_bar
201      if (!cbor_value_is_text_string(&value)) {
202        err = CborErrorIllegalType;
203        printf("expected string key but got something else\n");
204        break;
205      }
206      err = cbor_value_advance(&value);
207      if (err != CborNoError) {
208        break;
209      }
210      err = cbor_value_get_double(&value, &d.pressure_deci_bar);
211      if (err != CborNoError) {
212        break;
213      }
214      err = cbor_value_advance(&value);
215      if (err != CborNoError) {
216        break;
217      }
218  
219      if (err == CborNoError) {
220        err = cbor_value_leave_container(&map, &value);
221        if (err != CborNoError) {
222          break;
223        }
224        if (!cbor_value_at_end(&map)) {
225          err = CborErrorGarbageAtEnd;
226          break;
227        }
228      }
229    } while (0);
230  
231    return err;
232  }
233  
234  } // namespace BmRbrDataMsg