BayEOS-Arduino  1.8.0_0.0.4
BayEOS.cpp
1 #include "BayEOS.h"
2 
3 void BayEOS::startFrame(uint8_t type) {
4  _next = 0;
5  addToPayload(type);
6 }
7 
8 void BayEOS::startDataFrame(uint8_t subtype, uint8_t checksum) {
9  _next = 0;
10  if (checksum)
11  addToPayload((uint8_t) BayEOS_ChecksumFrame);
12  addToPayload((uint8_t) BayEOS_DataFrame);
13  addToPayload(subtype);
14 }
15 
16 void BayEOS::startOriginFrame(const String &o, uint8_t routed) {
17  if(routed) startFrame((uint8_t) BayEOS_RoutedOriginFrame);
18  else startFrame((uint8_t) BayEOS_OriginFrame);
19  addToPayload((uint8_t) o.length());
20  addToPayload(o);
21 }
22 
23 void BayEOS::startDataFrameWithOrigin(uint8_t subtype, const String &o,
24  uint8_t checksum, uint8_t routed) {
25  _next = 0;
26  if (checksum)
27  addToPayload((uint8_t) BayEOS_ChecksumFrame);
28  if(routed) addToPayload((uint8_t) BayEOS_RoutedOriginFrame);
29  else addToPayload((uint8_t) BayEOS_OriginFrame);
30  addToPayload((uint8_t) o.length());
31  addToPayload(o);
32  addToPayload((uint8_t) BayEOS_DataFrame);
33  addToPayload(subtype);
34 }
35 
36 uint8_t BayEOS::addChannelValue(double v, uint8_t channel_number) {
37  return addChannelValue((float) v, channel_number);
38 }
39 uint8_t BayEOS::addChannelValue(long v, uint8_t channel_number) {
40  return addChannelValue((float) v, channel_number);
41 }
42 uint8_t BayEOS::addChannelValue(unsigned long v, uint8_t channel_number) {
43  return addChannelValue((float) v, channel_number);
44 }
45 uint8_t BayEOS::addChannelValue(int v, uint8_t channel_number) {
46  return addChannelValue((float) v, channel_number);
47 }
48 uint8_t BayEOS::addChannelValue(unsigned int v, uint8_t channel_number) {
49  return addChannelValue((float) v, channel_number);
50 }
51 uint8_t BayEOS::addChannelValue(uint8_t v, uint8_t channel_number) {
52  return addChannelValue((float) v, channel_number);
53 }
54 uint8_t BayEOS::addChannelValue(int8_t v, uint8_t channel_number) {
55  return addChannelValue((float) v, channel_number);
56 }
57 uint8_t BayEOS::addChannelValue(float v, uint8_t channel_number) {
58  uint8_t res = 0;
59  uint8_t offset = 0;
60  if (_payload[0] == BayEOS_ChecksumFrame) {
61  offset = 1;
62  }
63  if (_payload[offset] == BayEOS_OriginFrame || _payload[offset] == BayEOS_RoutedOriginFrame) {
64  offset += _payload[offset + 1] + 2;
65  }
66  if (_payload[offset] != BayEOS_DataFrame)
67  return 2;
68  if ((_payload[offset + 1] & BayEOS_OFFSETTYP_MASK) == BayEOS_ChannelLabel)
69  return 3;
70  if (((_payload[offset + 1] & BayEOS_OFFSETTYP_MASK) == BayEOS_ChannelNumber))
71  addToPayload(channel_number); //channel number
72  else if ((((_payload[offset + 1] & BayEOS_OFFSETTYP_MASK) == 0x0)
73  & (_next == (2 + offset)))) {
74  if (channel_number)
75  channel_number--;
76  addToPayload(channel_number); //offset - only once
77  }
78  switch (_payload[offset + 1] & 0x0f) {
79  case 1:
80  res = addToPayload((float) v);
81  break;
82  case 2:
83  res = addToPayload((long) v);
84  break;
85  case 3:
86  res = addToPayload((int) v);
87  break;
88  case 4:
89  res = addToPayload((uint8_t) v);
90  break;
91  }
92  if (res)
93  return 0;
94  else
95  return 1;
96 }
97 
98 uint8_t BayEOS::addChannelValue(double v, const char* channel_label) {
99  return addChannelValue((float) v, channel_label);
100 }
101 uint8_t BayEOS::addChannelValue(long v, const char* channel_label) {
102  return addChannelValue((float) v, channel_label);
103 }
104 uint8_t BayEOS::addChannelValue(unsigned long v, const char* channel_label) {
105  return addChannelValue((float) v, channel_label);
106 }
107 uint8_t BayEOS::addChannelValue(int v, const char* channel_label) {
108  return addChannelValue((float) v, channel_label);
109 }
110 uint8_t BayEOS::addChannelValue(unsigned int v, const char* channel_label) {
111  return addChannelValue((float) v, channel_label);
112 }
113 uint8_t BayEOS::addChannelValue(uint8_t v, const char* channel_label) {
114  return addChannelValue((float) v, channel_label);
115 }
116 uint8_t BayEOS::addChannelValue(int8_t v, const char* channel_label) {
117  return addChannelValue((float) v, channel_label);
118 }
119 uint8_t BayEOS::addChannelValue(float v, const char* channel_label) {
120  uint8_t res = 0;
121  uint8_t offset = 0;
122  if (_payload[0] == BayEOS_ChecksumFrame) {
123  offset = 1;
124  }
125  if (_payload[offset] == BayEOS_OriginFrame || _payload[offset] == BayEOS_RoutedOriginFrame) {
126  offset += _payload[offset + 1] + 2;
127  }
128  if (_payload[offset] != BayEOS_DataFrame)
129  return 2;
130  if ((_payload[offset + 1] & BayEOS_OFFSETTYP_MASK) != BayEOS_ChannelLabel)
131  return 3;
132  addToPayload((uint8_t) strlen(channel_label));
133  addToPayload(channel_label);
134  switch (_payload[offset + 1] & 0x0f) {
135  case 1:
136  res = addToPayload((float) v);
137  break;
138  case 2:
139  res = addToPayload((long) v);
140  break;
141  case 3:
142  res = addToPayload((int) v);
143  break;
144  case 4:
145  res = addToPayload((uint8_t) v);
146  break;
147  }
148  if (res)
149  return 0;
150  else
151  return 1;
152 }
153 
154 uint8_t BayEOS::addChecksum() {
155  uint16_t checksum = 0;
156  for (uint8_t i = 0; i < _next; i++) {
157  checksum += _payload[i];
158  }
159  return addToPayload((uint16_t)(0xffff - checksum & 0xffff));
160 }
161 uint8_t BayEOS::validateChecksum() {
162  uint8_t offset = 0;
163  uint8_t has_checksum = 0;
164  uint16_t checksum = 0;
165  while (!has_checksum) {
166  switch (_payload[offset]) {
167  case BayEOS_RoutedFrame:
168  offset += 5;
169  break;
170  case BayEOS_RoutedFrameRSSI:
171  offset += 6;
172  break;
173  case BayEOS_DelayedFrame:
174  offset += 5;
175  break;
176  case BayEOS_TimestampFrame:
177  offset += 5;
178  break;
179  case BayEOS_OriginFrame:
180  case BayEOS_RoutedOriginFrame:
181  offset += 2+_payload[offset+1];
182  break;
183  case BayEOS_ChecksumFrame:
184  has_checksum = 1;
185  break;
186  default:
187  return 2;
188  }
189  }
190  while (offset < getPacketLength() - 2) {
191  checksum += _payload[offset];
192  offset++;
193  }
194  checksum += *(uint16_t*) (_payload+offset);
195  if(checksum == 0xffff) return 0;
196  return 1;
197 }
198 
199 void BayEOS::startRoutedFrame(uint16_t sourceMyID, uint16_t sourcePANID,
200  uint8_t rssi) {
201  if (rssi)
202  startFrame((uint8_t) BayEOS_RoutedFrameRSSI);
203  else
204  startFrame((uint8_t) BayEOS_RoutedFrame);
205  addToPayload(sourceMyID);
206  addToPayload(sourcePANID);
207  if (rssi)
208  addToPayload(rssi);
209 }
210 
211 void BayEOS::startDelayedFrame(unsigned long delay) {
212  startFrame((uint8_t) BayEOS_DelayedFrame);
213  addToPayload(delay);
214 }
215 
216 void BayEOS::startTimestampFrame(unsigned long timestamp) {
217  startFrame((uint8_t) BayEOS_TimestampFrame);
218  addToPayload(timestamp);
219 }
220 
221 void BayEOS::startCommand(uint8_t cmd_api) {
222  startFrame((uint8_t) BayEOS_Command);
223  addToPayload(cmd_api);
224 }
225 
226 void BayEOS::startCommandResponse(uint8_t cmd_api) {
227  startFrame((uint8_t) BayEOS_CommandResponse);
228  addToPayload(cmd_api);
229 }
230 
231 uint8_t BayEOS::addToPayload(const void* p, uint8_t length) {
232  uint8_t* b = (uint8_t *) p;
233  for (int i = 0; i < length; i++) {
234  _success = addToPayload(b[i]);
235  }
236  return _success;
237 }
238 
239 uint8_t BayEOS::addToPayload(const uint8_t* c) {
240  while (*c) {
241  _success = addToPayload(*c);
242  c++;
243  }
244  return _success;
245 }
246 uint8_t BayEOS::addToPayload(const String &s) {
247  for (uint8_t i = 0; i < s.length(); i++) {
248  _success = addToPayload((uint8_t) s[i]);
249  }
250  return _success;
251 }
252 
253 uint8_t BayEOS::addToPayload(int w) {
254  return addToPayload(&w, 2);
255 }
256 
257 uint8_t BayEOS::addToPayload(uint16_t w) {
258  return addToPayload(&w, 2);
259 }
260 
261 uint8_t BayEOS::addToPayload(float f) {
262  return addToPayload(&f, 4);
263 }
264 
265 uint8_t BayEOS::addToPayload(unsigned long l) {
266  return addToPayload(&l, 4);
267 }
268 
269 uint8_t BayEOS::addToPayload(long l) {
270  return addToPayload(&l, 4);
271 }
272 
273 uint8_t BayEOS::sendError(const String &s) {
274  startFrame((uint8_t) BayEOS_ErrorMessage);
275  addToPayload(s);
276  return sendPayload();
277 }
278 
279 uint8_t BayEOS::sendMessage(const String &s) {
280  startFrame((uint8_t) BayEOS_Message);
281  addToPayload(s);
282  return sendPayload();
283 }
284 
285 uint8_t BayEOS::writeToBuffer(void) {
286  if ((getPayloadLength() - getPacketLength()) < 5)
287  return 0;
288 // Serial.println("writeToBuffer");
289 // Serial.println(_buffer->getTime());
290  return _buffer->addPacket(_payload, _next);
291 }
292 
293 uint8_t BayEOS::readBinaryFromBuffer(unsigned long pos) {
294  startFrame(BayEOS_BinaryFrame);
295  addToPayload(pos);
296  _next += _buffer->readBinary(pos, getPayloadLength() - 5, &_payload[_next]);
297  return _next - 5;
298 }
299 uint8_t BayEOS::readBinaryFromBuffer(unsigned long pos, unsigned long stop,
300  unsigned long vpos) {
301  startFrame(BayEOS_BinaryFrame);
302  addToPayload(vpos);
303  _next += _buffer->readBinary(pos, stop, getPayloadLength() - 5,
304  &_payload[_next]);
305  return _next - 5;
306 }
307 
308 uint8_t BayEOS::readFromBuffer(void) {
309  while (_buffer->available()) {
310  _buffer->initNextPacket();
311  if (!_buffer->packetLength()) {
312  _buffer->next(); //skip empty packet
313  continue;
314  }
315  if (_buffer->rtc()) {
316  if (_buffer->_absoluteTime)
317  startTimestampFrame(_buffer->packetMillis());
318  else
320  (_buffer->getTime() - _buffer->packetMillis()) * 1000);
321  } else
322  startDelayedFrame(millis() - _buffer->packetMillis());
323 
324  if (getPayloadBytesLeft() < _buffer->packetLength()) {
325  _buffer->next(); //skip packet - now way to send this...
326  continue;
327  }
328  _buffer->readPacket(&_payload[_next]);
329  _next += _buffer->packetLength();
330  return _buffer->packetLength();
331  }
332  return 0;
333 }
334 
335 uint8_t BayEOS::sendOrBuffer(void) {
336  //Try to send when no failure or _skip_counter has reached next try...
337  if (_failure_counter < 2
338  || _skip_counter
339  >= (uint16_t)(
340  (uint16_t) _failure_counter
341  * (uint16_t) _failure_counter) /* 2->4 skip, 3->9 skip ...*/
342  || _skip_counter >= _max_skip) {
343  _skip_counter = 0;
344  if (!sendPayload()) {
345  //success -> reset _failure_counter to 0
346  _failure_counter = 0;
347  return 0;
348  } else {
349  //no success
350  if (_failure_counter != 255)
351  _failure_counter++;
352  }
353  } else
354  _skip_counter++;
355  if (writeToBuffer())
356  return 0;
357  return 1;
358 }
359 
360 uint8_t BayEOS::sendFromBuffer(void) {
361  if (readFromBuffer()) {
362  if (_failure_counter < 2
363  || /* not too much failures */
364  _skip_counter
365  >= (uint16_t)(
366  (uint16_t) _failure_counter
367  * (uint16_t) _failure_counter) || /* 2->4 skip, 3->9 skip ...*/
368  _skip_counter >= _max_skip) {
369  _skip_counter = 0;
370  if (!sendPayload()) {
371  //success -> reset _failure_counter to 0
372  _failure_counter = 0;
373  _buffer->next();
374  return 0;
375  } else {
376  //no success
377  if (_failure_counter != 255)
378  _failure_counter++;
379  return 1;
380  }
381  } else
382  _skip_counter++;
383  }
384  return 0;
385 }
386 
387 uint8_t BayEOS::getPayloadBytesLeft(void) const{
388  return (BayEOS_MAX_PAYLOAD-_next);
389 }
390 
391 uint8_t BayEOS::getPayloadLength(void) const{
392  return BayEOS_MAX_PAYLOAD;
393 }
394 
395 uint8_t BayEOS::getPacketLength(void) const{
396  return _next;
397 }
398 
399 const uint8_t* BayEOS::getPayload(void) const{
400  return _payload;
401 }
402 
403 uint8_t BayEOS::getPayload(uint8_t index) const{
404  return _payload[index];
405 }
406 
407 
virtual uint8_t sendPayload(void)=0
const uint8_t * getPayload(void) const
Definition: BayEOS.cpp:399
int readPacket(uint8_t *dest)
uint8_t sendError(const String &s)
Definition: BayEOS.cpp:273
uint8_t writeToBuffer(void)
Definition: BayEOS.cpp:285
void startCommand(uint8_t cmd_api)
Definition: BayEOS.cpp:221
uint8_t sendFromBuffer(void)
Definition: BayEOS.cpp:360
void startDataFrame(uint8_t subtype=BayEOS_Float32le, uint8_t checksum=0)
Definition: BayEOS.cpp:8
uint8_t getPayloadBytesLeft(void) const
Definition: BayEOS.cpp:387
void startRoutedFrame(uint16_t sourceMyID, uint16_t sourcePANID, uint8_t rssi=0)
Definition: BayEOS.cpp:199
uint8_t addToPayload(uint8_t b)
Definition: BayEOS.h:418
uint8_t getPacketLength(void) const
Definition: BayEOS.cpp:395
uint8_t sendOrBuffer(void)
Definition: BayEOS.cpp:335
uint8_t rtc(void)
void startDataFrameWithOrigin(uint8_t subtype, const String &o, uint8_t checksum=0, uint8_t routed=0)
Definition: BayEOS.cpp:23
void startFrame(uint8_t type)
Definition: BayEOS.cpp:3
void startDelayedFrame(unsigned long delay)
Definition: BayEOS.cpp:211
unsigned long packetMillis(void)
void next(void)
void startTimestampFrame(unsigned long timestamp)
Definition: BayEOS.cpp:216
uint8_t readBinary(unsigned long pos, uint8_t length, uint8_t *dest)
unsigned long available(void)
uint8_t readBinaryFromBuffer(unsigned long pos)
Definition: BayEOS.cpp:293
uint8_t packetLength(void)
void startCommandResponse(uint8_t cmd_api)
Definition: BayEOS.cpp:226
uint8_t addChannelValue(float v, uint8_t channel_number=0)
Definition: BayEOS.cpp:57
uint8_t addPacket(const uint8_t *payload, uint8_t length)
uint8_t sendMessage(const String &s)
Definition: BayEOS.cpp:279
uint8_t readFromBuffer(void)
Definition: BayEOS.cpp:308
uint8_t initNextPacket(void)
void startOriginFrame(const String &o, uint8_t routed=0)
Definition: BayEOS.cpp:16
uint8_t getPayloadLength(void) const
Definition: BayEOS.cpp:391