RSeries astromech firmware
ReelTwoSMQ.h
Go to the documentation of this file.
1 #ifndef REELTWOSMQ_H
2 #define REELTWOSMQ_H
3 #define USE_SMQ
4 
5 #ifdef ReelTwo_h
6 #error ReelTwoSMQ.h must be included before ReelTwo.h
7 #endif
8 
9 #include "ReelTwo.h"
10 
11 #ifdef USE_SMQDEBUG
12 #define SMQ_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
13 #define SMQ_DEBUG_PRINT(s) DEBUG_PRINT(s)
14 #define SMQ_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
15 #define SMQ_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
16 #define SMQ_DEBUG_FLUSH(s) DEBUG_FLUSH()
17 #else
18 #define SMQ_DEBUG_PRINTLN(s)
19 #define SMQ_DEBUG_PRINT(s)
20 #define SMQ_DEBUG_PRINTLN_HEX(s)
21 #define SMQ_DEBUG_PRINT_HEX(s)
22 #define SMQ_DEBUG_FLUSH(s)
23 #endif
24 
25 #define REELTWO_READY() \
26 { \
27  if (!sSMQREADY) \
28  { \
29  _REELTWO_READY_; \
30  SMQ_SERIAL.begin(DEFAULT_BAUD_RATE); \
31  sSMQ = &SMQ_SERIAL; \
32  SMQ_DEBUG_PRINTLN("Waiting for agent"); \
33  SMQ::ready(); \
34  } \
35 }
36 
37 static Stream *sSMQ;
38 static bool sSMQREADY;
39 
40 typedef uint16_t msg_id;
41 //typedef uint32_t smq_id;
42 typedef uint16_t smq_id;
43 
54 class SMQ
55 {
56 public:
57  static void ready()
58  {
59  while (!sSMQ->available())
60  ;
61  for (;;)
62  {
63  int val = read_int8();
64  if (val == 'A')
65  {
66  sSMQREADY = true;
67  break;
68  }
69  DEBUG_PRINTLN((char)val);
70  }
71  Message::sendSubscriberList();
72  }
73 
74  static void process()
75  {
76  while (sSMQ->available())
77  {
78  int op = sSMQ->read();
79  if (op == 'D')
80  {
81  char ack = 'R';
82  sSMQ->write(&ack, sizeof(ack));
83  sSMQ->flush();
84  DEBUG_PRINTLN("Subscriber::process");
85  Message::process();
86  break;
87  }
88  else if (op == 'A')
89  {
90  /* acknowledge */
91  sSMQREADY = true;
92  }
93  else if (op != -1)
94  {
95  //Serial.print("<== ");
96  //Serial.println(op, HEX);
97  }
98  else
99  {
100  //Serial.print(".");
101  break;
102  }
103  }
104  }
105 
106  static void send_string(const char* str)
107  {
108  uint8_t delim = 0x00;
109  send_raw_bytes(&delim, sizeof(delim));
110 
111  size_t len = strlen(str);
112  send_data(&len, sizeof(len));
113  send_data(str, len);
114  }
115 
116  static void send_string(PROGMEMString str)
117  {
118  uint8_t delim = 0x00;
119  send_raw_bytes(&delim, sizeof(delim));
120 
121  size_t len = strlen_P((const char*)str);
122  send_data(&len, sizeof(len));
123  send_data(str, len);
124  }
125 
126  static void send_string_id(const msg_id id)
127  {
128  uint8_t delim = 0x01;
129  send_raw_bytes(&delim, sizeof(delim));
130  send_raw_bytes(&id, sizeof(id));
131  }
132 
133  static void send_string_hash(const char* str)
134  {
135  uint8_t delim = 0x01;
136  send_raw_bytes(&delim, sizeof(delim));
137 
138  uint16_t crc = 0xFFFF;
139  size_t len = strlen(str);
140  const uint8_t* b = (uint8_t*)str;
141  const uint8_t* buf_end = (uint8_t*)str + len;
142  while (b < buf_end)
143  {
144  crc = update_crc(crc, *b++);
145  }
146  crc = ~crc;
147  send_raw_bytes(&crc, sizeof(crc));
148  }
149 
150  static bool send_ready()
151  {
152  return sSMQREADY;
153  }
154 
155  static bool sendTopic(const smq_id id)
156  {
157  send_start(id);
158  return true;
159  }
160 
161  static bool sendTopic(PROGMEMString str)
162  {
163  send_start(str);
164  return true;
165  }
166 
167  static bool sendTopic(const char* str)
168  {
169  send_start(str);
170  return true;
171  }
172 
173  static void send_start(const smq_id id)
174  {
175  sSMQREADY = false;
176  send_string_id(id);
177  }
178 
179  static void send_start(PROGMEMString str)
180  {
181  sSMQREADY = false;
182  send_string(str);
183  }
184 
185  static void send_start(const char* str)
186  {
187  sSMQREADY = false;
188  send_string(str);
189  }
190 
191  static void send_start_hash(const char* str)
192  {
193  send_string_hash(str);
194  }
195 
196  static void send_string(const msg_id id, const char* val)
197  {
198  send_string_id(id);
199  send_string(val);
200  }
201 
202  static void send_string(PROGMEMString key, const char* val)
203  {
204  send_string(key);
205  send_string(val);
206  }
207 
209  {
210  send_string(key);
211  send_string(val);
212  }
213 
214  static void send_string(const char* key, const char* val)
215  {
216  send_string(key);
217  send_string(val);
218  }
219 
220  static void send_int8(const msg_id id, int8_t val)
221  {
222  uint8_t delim = 0x02;
223  send_string_id(id);
224  send_raw_bytes(&delim, sizeof(delim));
225  send_data(&val, sizeof(val));
226  }
227 
228  static void send_int8(PROGMEMString key, int8_t val)
229  {
230  uint8_t delim = 0x02;
231  send_string(key);
232  send_raw_bytes(&delim, sizeof(delim));
233  send_data(&val, sizeof(val));
234  }
235 
236  static void send_int8(const char* key, int8_t val)
237  {
238  uint8_t delim = 0x02;
239  send_string(key);
240  send_raw_bytes(&delim, sizeof(delim));
241  send_data(&val, sizeof(val));
242  }
243 
244  static void send_int16(const msg_id id, int16_t val)
245  {
246  uint8_t delim = 0x03;
247  send_string_id(id);
248  send_raw_bytes(&delim, sizeof(delim));
249  send_data(&val, sizeof(val));
250  }
251 
252  static void send_int16(PROGMEMString key, int16_t val)
253  {
254  uint8_t delim = 0x03;
255  send_string(key);
256  send_raw_bytes(&delim, sizeof(delim));
257  send_data(&val, sizeof(val));
258  }
259 
260  static void send_int16(const char* key, int16_t val)
261  {
262  uint8_t delim = 0x03;
263  send_string(key);
264  send_raw_bytes(&delim, sizeof(delim));
265  send_data(&val, sizeof(val));
266  }
267 
268  static void send_int32(const msg_id id, int32_t val)
269  {
270  uint8_t delim = 0x04;
271  send_string_id(id);
272  send_raw_bytes(&delim, sizeof(delim));
273  send_data(&val, sizeof(val));
274  }
275 
276  static void send_int32(const char* key, int32_t val)
277  {
278  uint8_t delim = 0x04;
279  send_string(key);
280  send_raw_bytes(&delim, sizeof(delim));
281  send_data(&val, sizeof(val));
282  }
283 
284  static void send_int32(PROGMEMString key, int32_t val)
285  {
286  uint8_t delim = 0x04;
287  send_string(key);
288  send_raw_bytes(&delim, sizeof(delim));
289  send_data(&val, sizeof(val));
290  }
291 
292  static void send_uint8(const msg_id id, uint8_t val)
293  {
294  uint8_t delim = 0x05;
295  send_string_id(id);
296  send_raw_bytes(&delim, sizeof(delim));
297  send_data(&val, sizeof(val));
298  }
299 
300  static void send_uint8(PROGMEMString key, uint8_t val)
301  {
302  uint8_t delim = 0x05;
303  send_string(key);
304  send_raw_bytes(&delim, sizeof(delim));
305  send_data(&val, sizeof(val));
306  }
307 
308  static void send_uint8(const char* key, uint8_t val)
309  {
310  uint8_t delim = 0x05;
311  send_string(key);
312  send_raw_bytes(&delim, sizeof(delim));
313  send_data(&val, sizeof(val));
314  }
315 
316  static void send_uint16(const msg_id id, uint16_t val)
317  {
318  uint8_t delim = 0x06;
319  send_string_id(id);
320  send_raw_bytes(&delim, sizeof(delim));
321  send_data(&val, sizeof(val));
322  }
323 
324  static void send_uint16(PROGMEMString key, uint16_t val)
325  {
326  uint8_t delim = 0x06;
327  send_string(key);
328  send_raw_bytes(&delim, sizeof(delim));
329  send_data(&val, sizeof(val));
330  }
331 
332  static void send_uint16(const char* key, uint16_t val)
333  {
334  uint8_t delim = 0x06;
335  send_string(key);
336  send_raw_bytes(&delim, sizeof(delim));
337  send_data(&val, sizeof(val));
338  }
339 
340  static void send_uint32(const msg_id id, uint32_t val)
341  {
342  uint8_t delim = 0x07;
343  send_string_id(id);
344  send_raw_bytes(&delim, sizeof(delim));
345  send_data(&val, sizeof(val));
346  }
347 
348  static void send_uint32(PROGMEMString key, uint32_t val)
349  {
350  uint8_t delim = 0x07;
351  send_string(key);
352  send_raw_bytes(&delim, sizeof(delim));
353  send_data(&val, sizeof(val));
354  }
355 
356  static void send_uint32(const char* key, uint32_t val)
357  {
358  uint8_t delim = 0x07;
359  send_string(key);
360  send_raw_bytes(&delim, sizeof(delim));
361  send_data(&val, sizeof(val));
362  }
363 
364  static void send_float(const msg_id id, float val)
365  {
366  uint8_t delim = 0x08;
367  send_string_id(id);
368  send_raw_bytes(&delim, sizeof(delim));
369  send_data(&val, sizeof(val));
370  }
371 
372  static void send_float(PROGMEMString key, float val)
373  {
374  uint8_t delim = 0x08;
375  send_string(key);
376  send_raw_bytes(&delim, sizeof(delim));
377  send_data(&val, sizeof(val));
378  }
379 
380  static void send_float(const char* key, float val)
381  {
382  uint8_t delim = 0x08;
383  send_string(key);
384  send_raw_bytes(&delim, sizeof(delim));
385  send_data(&val, sizeof(val));
386  }
387 
388  static void send_double(const msg_id id, double val)
389  {
390  uint8_t delim = 0x09;
391  send_string_id(id);
392  send_raw_bytes(&delim, sizeof(delim));
393  send_data(&val, sizeof(val));
394  }
395 
396  static void send_double(PROGMEMString key, double val)
397  {
398  uint8_t delim = 0x09;
399  send_string(key);
400  send_raw_bytes(&delim, sizeof(delim));
401  send_data(&val, sizeof(val));
402  }
403 
404  static void send_double(const char* key, double val)
405  {
406  uint8_t delim = 0x09;
407  send_string(key);
408  send_raw_bytes(&delim, sizeof(delim));
409  send_data(&val, sizeof(val));
410  }
411 
412  static void send_boolean(const msg_id id, bool val)
413  {
414  uint8_t delim = (val) ? 0x0A : 0x0B;
415  send_string_id(id);
416  send_raw_bytes(&delim, sizeof(delim));
417  }
418 
419  static void send_boolean(PROGMEMString key, bool val)
420  {
421  uint8_t delim = (val) ? 0x0A : 0x0B;
422  send_string(key);
423  send_raw_bytes(&delim, sizeof(delim));
424  }
425 
426  static void send_boolean(const char* key, bool val)
427  {
428  uint8_t delim = (val) ? 0x0A : 0x0B;
429  send_string(key);
430  send_raw_bytes(&delim, sizeof(delim));
431  }
432 
433  static void send_null(const msg_id id)
434  {
435  uint8_t delim = 0x0C;
436  send_string_id(id);
437  send_raw_bytes(&delim, sizeof(delim));
438  }
439 
440  static void send_null(PROGMEMString key)
441  {
442  uint8_t delim = 0x0C;
443  send_string(key);
444  send_raw_bytes(&delim, sizeof(delim));
445  }
446 
447  static void send_null(const char* key)
448  {
449  uint8_t delim = 0x0C;
450  send_string(key);
451  send_raw_bytes(&delim, sizeof(delim));
452  }
453 
454  // static void send_buffer(const void* buf, size_t len)
455  // {
456  // uint8_t delim = 0x0D;
457  // send_string(key);
458  // send_raw_bytes(&delim, sizeof(delim));
459  // send_data(&len, sizeof(len));
460  // send_data(buf, len);
461  // }
462 
463  static void send_end()
464  {
465  uint8_t delim = 0xFF;
466  send_raw_bytes(&delim, sizeof(delim));
467  }
468 
469  class Message;
470  typedef void (*MessageHandler)(Message& msg);
471 
558  class Message
560  {
561  public:
562  Message(smq_id topic, MessageHandler handler) :
563  fTopic(topic),
564  fHandler(handler)
565  {
566  fNext = *tail();
567  *tail() = this;
568  }
569 
570  long get_integer(const msg_id keyID)
571  {
572  if (find_key(keyID))
573  {
574  return get_integer_worker();
575  }
576  fMType = -1;
577  return 0;
578  }
579 
580  long get_integer(const char* key)
581  {
582  if (key == NULL || find_key(key))
583  {
584  return get_integer_worker();
585  }
586  fMType = -1;
587  return 0;
588  }
589 
590  long get_integer(PROGMEMString key)
591  {
592  if (key == NULL || find_key(key))
593  {
594  return get_integer_worker();
595  }
596  fMType = -1;
597  return 0;
598  }
599 
600  double get_double(const msg_id keyID)
601  {
602  if (find_key(keyID))
603  {
604  return get_double_worker();
605  }
606  fMType = -1;
607  return 0;
608  }
609 
610  double get_double(const char* key)
611  {
612  if (key == NULL || find_key(key))
613  {
614  return get_double_worker();
615  }
616  fMType = -1;
617  return 0;
618  }
619 
620  double get_double(PROGMEMString key)
621  {
622  if (key == NULL || find_key(key))
623  {
624  return get_double_worker();
625  }
626  fMType = -1;
627  return 0;
628  }
629 
630  const char* get_string(const msg_id keyID, char* buffer, size_t maxlen)
631  {
632  if (find_key(keyID))
633  {
634  return get_string_worker(buffer, maxlen);
635  }
636  buffer[0] = '\0';
637  fMType = -1;
638  return NULL;
639  }
640 
641  const char* get_string(const char* key, char* buffer, size_t maxlen)
642  {
643  if (key == NULL || find_key(key))
644  {
645  return get_string_worker(buffer, maxlen);
646  }
647  buffer[0] = '\0';
648  fMType = -1;
649  return NULL;
650 
651  }
652 
653  const char* get_string(PROGMEMString key, char* buffer, size_t maxlen)
654  {
655  if (key == NULL || find_key(key))
656  {
657  return get_string_worker(buffer, maxlen);
658  }
659  buffer[0] = '\0';
660  fMType = -1;
661  return NULL;
662  }
663 
664  bool get_boolean(const msg_id key)
665  {
666  return (bool)get_integer(key);
667  }
668  bool get_boolean(const char* key)
669  {
670  return (bool)get_integer(key);
671  }
672  bool get_boolean(PROGMEMString key)
673  {
674  return (bool)get_integer(key);
675  }
676  int8_t get_int8(const msg_id key)
677  {
678  return (int8_t)get_integer(key);
679  }
680  int8_t get_int8(const char* key)
681  {
682  return (int8_t)get_integer(key);
683  }
684  int8_t get_int8(PROGMEMString key)
685  {
686  return (int8_t)get_integer(key);
687  }
688  int16_t get_int16(const msg_id key)
689  {
690  return (int16_t)get_integer(key);
691  }
692  int16_t get_int16(const char* key)
693  {
694  return (int16_t)get_integer(key);
695  }
696  int16_t get_int16(PROGMEMString key)
697  {
698  return (int16_t)get_integer(key);
699  }
700  int32_t get_int32(const msg_id key)
701  {
702  return (int16_t)get_integer(key);
703  }
704  int32_t get_int32(const char* key)
705  {
706  return (int16_t)get_integer(key);
707  }
708  int32_t get_int32(PROGMEMString key)
709  {
710  return (int16_t)get_integer(key);
711  }
712  uint8_t get_uint8(const msg_id key)
713  {
714  return (uint8_t)get_integer(key);
715  }
716  uint8_t get_uint8(const char* key)
717  {
718  return (uint8_t)get_integer(key);
719  }
720  uint8_t get_uint8(PROGMEMString key)
721  {
722  return (uint8_t)get_integer(key);
723  }
724  uint16_t get_uint16(const uint16_t key)
725  {
726  return (uint16_t)get_integer(key);
727  }
728  uint16_t get_uint16(const char* key)
729  {
730  return (uint16_t)get_integer(key);
731  }
732  uint16_t get_uint16(PROGMEMString key)
733  {
734  return (uint16_t)get_integer(key);
735  }
736  uint32_t get_uint32(const msg_id key)
737  {
738  return (uint32_t)get_integer(key);
739  }
740  uint32_t get_uint32(const char* key)
741  {
742  return (uint32_t)get_integer(key);
743  }
744  uint32_t get_uint32(PROGMEMString key)
745  {
746  return (uint32_t)get_integer(key);
747  }
748  float get_float(const msg_id key)
749  {
750  return (float)get_double(key);
751  }
752  float get_float(const char* key)
753  {
754  return (float)get_double(key);
755  }
756  float get_float(PROGMEMString key)
757  {
758  return (float)get_double(key);
759  }
760 
761  void end()
762  {
763  while (!fEOM)
764  {
765  find_key(static_cast<const char*>(NULL));
766  }
767  }
768 
769  private:
770  bool find_key(const msg_id keyID)
771  {
772  while (!fEOM)
773  {
774  bool match = false;
775  uint8_t t = read_uint8();
776  switch (t)
777  {
778  case 0x00:
779  {
780  // String
781  DEBUG_PRINTLN("[KEYSTRING]");
782  uint16_t lencrc = read_uint16();
783  uint16_t len = read_uint16();
784  // TODO verify lencrc
785  UNUSED_ARG(lencrc);
786 
787  uint16_t crc = read_uint16();
788  uint16_t recrc = 0;
789  while (len-- > 0)
790  {
791  int8_t ch = read_int8();
792  recrc = update_crc(recrc, ch);
793  }
794  if (recrc == crc)
795  {
796  match = (crc == keyID);
797  }
798  else
799  {
800  DEBUG_PRINT("crc=");
801  DEBUG_PRINT_HEX(crc);
802  DEBUG_PRINT(" expected=");
803  DEBUG_PRINT_HEX(recrc);
804  DEBUG_PRINTLN("CRC BAD4");
805  DEBUG_FLUSH();
806  }
807  break;
808  }
809  case 0x01:
810  {
811  // Hash
812  DEBUG_PRINTLN("[KEYCRC]");
813  uint16_t crc = read_uint16();
814  match = (keyID == crc);
815  break;
816  }
817  case 0xFF:
818  // EOM
819  fEOM = true;
820  return false;
821  default:
822  DEBUG_PRINTLN("BAD MSG");
823  return false;
824  }
825  fMType = read_uint8();
826  if (match)
827  return true;
828 
829  // skip value
830  get_integer_worker();
831  }
832  return false;
833  }
834 
835  bool find_key(const char* key)
836  {
837  unsigned keylen = (key != NULL) ? strlen(key) : 0;
838  while (!fEOM)
839  {
840  bool match = false;
841  uint8_t t = read_uint8();
842  switch (t)
843  {
844  case 0x00:
845  {
846  // String
847  DEBUG_PRINTLN("[KEYSTRING]");
848  uint16_t lencrc = read_uint16();
849  uint16_t len = read_uint16();
850  // TODO verify lencrc
851  UNUSED_ARG(lencrc);
852 
853  uint16_t crc = read_uint16();
854  uint16_t recrc = 0;
855  const char* k = key;
856  match = (keylen == len);
857  while (len-- > 0)
858  {
859  int8_t ch = read_int8();
860  DEBUG_PRINT((char)ch);
861  DEBUG_PRINT(" - ");
862  if (k != NULL)
863  {
864  DEBUG_PRINTLN((char)*k);
865  }
866  recrc = update_crc(recrc, ch);
867  if (match && *k++ != ch)
868  match = false;
869  }
870  DEBUG_PRINT("pmatch=");
871  DEBUG_PRINTLN(match);
872  if (recrc != crc)
873  {
874  DEBUG_PRINT("crc=");
875  DEBUG_PRINT_HEX(crc);
876  DEBUG_PRINT(" expected=");
877  DEBUG_PRINT_HEX(recrc);
878  DEBUG_PRINTLN("CRC BAD4");
879  DEBUG_FLUSH();
880  }
881  break;
882  }
883  case 0x01:
884  {
885  // Hash
886  DEBUG_PRINTLN("[KEYCRC]");
887  uint16_t crc = read_uint16();
888  uint16_t keycrc = 0xFFFF;
889  const uint8_t* b = (uint8_t*)key;
890  const uint8_t* buf_end = (uint8_t*)key + keylen;
891  while (b < buf_end)
892  {
893  keycrc = update_crc(keycrc, *b++);
894  }
895  match = (keylen != 0 && keycrc == crc);
896  break;
897  }
898  case 0xFF:
899  // EOM
900  fEOM = true;
901  return false;
902  default:
903  DEBUG_PRINTLN("BAD MSG");
904  return false;
905  }
906  fMType = read_uint8();
907  if (match)
908  return true;
909 
910  // skip value
911  get_integer_worker();
912  }
913  return false;
914  }
915 
916  bool find_key(PROGMEMString keyP)
917  {
918  const char* key = (const char*)keyP;
919  unsigned keylen = (key != NULL) ? strlen_P(key) : 0;
920  while (!fEOM)
921  {
922  bool match = false;
923  uint8_t t = read_uint8();
924  switch (t)
925  {
926  case 0x00:
927  {
928  // String
929  DEBUG_PRINTLN("[KEYSTRING]");
930  uint16_t lencrc = read_uint16();
931  uint16_t len = read_uint16();
932  // TODO verify lencrc
933  UNUSED_ARG(lencrc);
934 
935  uint16_t crc = read_uint16();
936  uint16_t recrc = 0;
937  const char* k = key;
938  match = (keylen == len);
939  while (len-- > 0)
940  {
941  int8_t ch = read_int8();
942  DEBUG_PRINT((char)ch);
943  DEBUG_PRINT(" - ");
944  if (k != NULL)
945  {
946  DEBUG_PRINTLN((char)*k);
947  }
948  recrc = update_crc(recrc, ch);
949  if (match && pgm_read_byte(k++) != ch)
950  match = false;
951  }
952  DEBUG_PRINT("[match=");
953  DEBUG_PRINTLN(match);
954  if (recrc != crc)
955  {
956  DEBUG_PRINT("crc=");
957  DEBUG_PRINT_HEX(crc);
958  DEBUG_PRINT(" expected=");
959  DEBUG_PRINT_HEX(recrc);
960  DEBUG_PRINTLN("CRC BAD4");
961  DEBUG_FLUSH();
962  }
963  break;
964  }
965  case 0x01:
966  {
967  // Hash
968  DEBUG_PRINTLN("[KEYCRC]");
969  uint16_t crc = read_uint16();
970  uint16_t keycrc = 0xFFFF;
971  const uint8_t* b = (uint8_t*)key;
972  const uint8_t* buf_end = (uint8_t*)key + keylen;
973  while (b < buf_end)
974  {
975  keycrc = update_crc(keycrc, pgm_read_byte(b++));
976  }
977  match = (keylen != 0 && keycrc == crc);
978  break;
979  }
980  case 0xFF:
981  // EOM
982  fEOM = true;
983  return false;
984  default:
985  DEBUG_PRINTLN("BAD MSG");
986  return false;
987  }
988  fMType = read_uint8();
989  if (match)
990  return true;
991 
992  // skip value
993  get_integer_worker();
994  }
995  return false;
996  }
997 
998  long get_integer_worker()
999  {
1000  long ret = 0;
1001  switch (fMType)
1002  {
1003  case 0x00:
1004  {
1005  // Skip String
1006  uint16_t lencrc = read_uint16();
1007  uint16_t len = read_uint16();
1008  // TODO verify lencrc
1009  UNUSED_ARG(lencrc);
1010 
1011  uint16_t crc = read_uint16();
1012  uint16_t recrc = 0;
1013  while (len-- > 0)
1014  {
1015  uint8_t ch = read_uint8();
1016  recrc = update_crc(recrc, ch);
1017  }
1018  if (recrc != crc)
1019  {
1020  DEBUG_PRINTLN("CRC BAD1");
1021  }
1022  break;
1023  }
1024  case 0x01:
1025  {
1026  // Skip Hash
1027  uint16_t crc = read_uint16();
1028  UNUSED_ARG(crc);
1029  break;
1030  }
1031  case 0x02:
1032  {
1033  // int8
1034  uint16_t crc = read_uint16();
1035  int8_t val = read_int8();
1036  uint16_t recrc = 0;
1037  for (unsigned i = 0; i < sizeof(val); i++)
1038  {
1039  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1040  }
1041  if (recrc == crc)
1042  ret = val;
1043  break;
1044  }
1045  case 0x03:
1046  {
1047  // int16
1048  uint16_t crc = read_uint16();
1049  int16_t val = read_int16();
1050  uint16_t recrc = 0;
1051  for (unsigned i = 0; i < sizeof(val); i++)
1052  {
1053  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1054  }
1055  if (recrc == crc)
1056  ret = val;
1057  break;
1058  }
1059  case 0x04:
1060  {
1061  // int32
1062  uint16_t crc = read_uint16();
1063  int32_t val = read_int32();
1064  uint16_t recrc = 0;
1065  for (unsigned i = 0; i < sizeof(val); i++)
1066  {
1067  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1068  }
1069  if (recrc == crc)
1070  ret = val;
1071  break;
1072  }
1073  case 0x05:
1074  {
1075  // uint8
1076  uint16_t crc = read_uint16();
1077  uint8_t val = read_uint8();
1078  uint16_t recrc = 0;
1079  for (unsigned i = 0; i < sizeof(val); i++)
1080  {
1081  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1082  }
1083  if (recrc == crc)
1084  ret = val;
1085  break;
1086  }
1087  case 0x06:
1088  {
1089  // uint16
1090  uint16_t crc = read_uint16();
1091  uint16_t val = read_uint16();
1092  uint16_t recrc = 0;
1093  for (unsigned i = 0; i < sizeof(val); i++)
1094  {
1095  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1096  }
1097  if (recrc == crc)
1098  ret = val;
1099  break;
1100  }
1101  case 0x07:
1102  {
1103  // uint32
1104  uint16_t crc = read_uint16();
1105  uint32_t val = read_uint32();
1106  uint16_t recrc = 0;
1107  for (unsigned i = 0; i < sizeof(val); i++)
1108  {
1109  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1110  }
1111  if (recrc == crc)
1112  ret = val;
1113  break;
1114  }
1115  case 0x08:
1116  {
1117  // uint32
1118  uint16_t crc = read_uint16();
1119  float val = read_float();
1120  uint16_t recrc = 0;
1121  for (unsigned i = 0; i < sizeof(val); i++)
1122  {
1123  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1124  }
1125  if (recrc == crc)
1126  ret = (long)val;
1127  break;
1128  }
1129  case 0x09:
1130  {
1131  // double
1132  uint16_t crc = read_uint16();
1133  double val = read_double();
1134  uint16_t recrc = 0;
1135  for (unsigned i = 0; i < sizeof(val); i++)
1136  {
1137  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1138  }
1139  if (recrc == crc)
1140  ret = (long)val;
1141  break;
1142  }
1143  case 0x0A:
1144  // true
1145  ret = true;
1146  break;
1147  case 0x0B:
1148  // false
1149  ret = false;
1150  break;
1151  case 0x0C:
1152  // null
1153  ret = 0;
1154  break;
1155  case 0x0D:
1156  // buffer
1157  break;
1158  case 0xFF:
1159  // EOM
1160  fEOM = true;
1161  break;
1162  }
1163  return ret;
1164  }
1165 
1166  double get_double_worker()
1167  {
1168  double ret = 0;
1169  switch (fMType)
1170  {
1171  case 0x00:
1172  {
1173  // Skip String
1174  uint16_t lencrc = read_uint16();
1175  uint16_t len = read_uint16();
1176  // TODO verify lencrc
1177  UNUSED_ARG(lencrc);
1178 
1179  uint16_t crc = read_uint16();
1180  uint16_t recrc = 0;
1181  while (len-- > 0)
1182  {
1183  uint8_t ch = read_uint8();
1184  recrc = update_crc(recrc, ch);
1185  }
1186  if (recrc != crc)
1187  {
1188  DEBUG_PRINTLN("CRC BAD2");
1189  }
1190  break;
1191  }
1192  case 0x01:
1193  {
1194  // Skip Hash
1195  uint16_t crc = read_uint16();
1196  UNUSED_ARG(crc)
1197  break;
1198  }
1199  case 0x02:
1200  {
1201  // int8
1202  uint16_t crc = read_uint16();
1203  int8_t val = read_int8();
1204  uint16_t recrc = 0;
1205  for (unsigned i = 0; i < sizeof(val); i++)
1206  {
1207  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1208  }
1209  if (recrc == crc)
1210  ret = val;
1211  break;
1212  }
1213  case 0x03:
1214  {
1215  // int16
1216  uint16_t crc = read_uint16();
1217  int16_t val = read_int16();
1218  uint16_t recrc = 0;
1219  for (unsigned i = 0; i < sizeof(val); i++)
1220  {
1221  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1222  }
1223  if (recrc == crc)
1224  ret = val;
1225  break;
1226  }
1227  case 0x04:
1228  {
1229  // int32
1230  uint16_t crc = read_uint16();
1231  int32_t val = read_int32();
1232  uint16_t recrc = 0;
1233  for (unsigned i = 0; i < sizeof(val); i++)
1234  {
1235  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1236  }
1237  if (recrc == crc)
1238  ret = val;
1239  break;
1240  }
1241  case 0x05:
1242  {
1243  // uint8
1244  uint16_t crc = read_uint16();
1245  uint8_t val = read_uint8();
1246  uint16_t recrc = 0;
1247  for (unsigned i = 0; i < sizeof(val); i++)
1248  {
1249  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1250  }
1251  if (recrc == crc)
1252  ret = val;
1253  break;
1254  }
1255  case 0x06:
1256  {
1257  // uint16
1258  uint16_t crc = read_uint16();
1259  uint16_t val = read_uint16();
1260  uint16_t recrc = 0;
1261  for (unsigned i = 0; i < sizeof(val); i++)
1262  {
1263  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1264  }
1265  if (recrc == crc)
1266  ret = val;
1267  break;
1268  }
1269  case 0x07:
1270  {
1271  // uint32
1272  uint16_t crc = read_uint16();
1273  uint32_t val = read_uint32();
1274  uint16_t recrc = 0;
1275  for (unsigned i = 0; i < sizeof(val); i++)
1276  {
1277  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1278  }
1279  if (recrc == crc)
1280  ret = val;
1281  break;
1282  }
1283  case 0x08:
1284  {
1285  // uint32
1286  uint16_t crc = read_uint16();
1287  float val = read_float();
1288  uint16_t recrc = 0;
1289  for (unsigned i = 0; i < sizeof(val); i++)
1290  {
1291  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1292  }
1293  if (recrc == crc)
1294  ret = val;
1295  break;
1296  }
1297  case 0x09:
1298  {
1299  // double
1300  uint16_t crc = read_uint16();
1301  double val = read_double();
1302  uint16_t recrc = 0;
1303  for (unsigned i = 0; i < sizeof(val); i++)
1304  {
1305  recrc = update_crc(recrc, ((uint8_t*)&val)[i]);
1306  }
1307  if (recrc == crc)
1308  ret = val;
1309  break;
1310  }
1311  case 0x0A:
1312  // true
1313  ret = true;
1314  break;
1315  case 0x0B:
1316  // false
1317  ret = false;
1318  break;
1319  case 0x0C:
1320  // null
1321  ret = 0;
1322  break;
1323  case 0x0D:
1324  // buffer
1325  break;
1326  case 0xFF:
1327  // EOM
1328  fEOM = true;
1329  break;
1330  }
1331  return ret;
1332  }
1333 
1334  const char* get_string_worker(char* buffer, size_t maxlen)
1335  {
1336  const char* ret = NULL;
1337  switch (fMType)
1338  {
1339  case 0x00:
1340  {
1341  // Skip String
1342  uint16_t lencrc = read_uint16();
1343  uint16_t len = read_uint16();
1344  // TODO verify lencrc
1345  UNUSED_ARG(lencrc);
1346 
1347  uint16_t crc = read_uint16();
1348  uint16_t recrc = 0;
1349  char* b = buffer;
1350 
1351  // DEBUG_PRINT("crc : "); DEBUG_PRINTLN_HEX(crc);
1352  // DEBUG_PRINT("len : "); DEBUG_PRINTLN(len);
1353  while (len-- > 0)
1354  {
1355  uint8_t ch = read_uint8();
1356  if (maxlen > 0)
1357  {
1358  *b = ch;
1359  if (maxlen - 1 > 0)
1360  b++;
1361  *b = '\0';
1362  // DEBUG_PRINT("str : "); DEBUG_PRINTLN(buffer);
1363  maxlen--;
1364  }
1365  recrc = update_crc(recrc, ch);
1366  }
1367  // DEBUG_PRINT("recrc : "); DEBUG_PRINTLN_HEX(recrc);
1368  if (recrc == crc)
1369  {
1370  ret = buffer;
1371  }
1372  else
1373  {
1374  buffer[0] = '\0';
1375  DEBUG_PRINTLN("CRC BAD3");
1376  }
1377  break;
1378  }
1379  default:
1380  {
1381  // skip value
1382  get_integer_worker();
1383  break;
1384  }
1385  }
1386  return ret;
1387  }
1388 
1389  static void process()
1390  {
1391  smq_id recvTopicID = (sizeof(smq_id) == sizeof(uint32_t)) ? read_uint32() : read_uint16();
1392  DEBUG_PRINT("PROCESS: "); DEBUG_PRINTLN_HEX(recvTopicID);
1393  for (Message* msg = *tail(); msg != NULL; msg = msg->fNext)
1394  {
1395  // smq_id topicID = (sizeof(smq_id) == sizeof(uint32_t)) ?
1396  // pgm_read_dword(&msg->fTopic) : pgm_read_word(&msg->fTopic);
1397  smq_id topicID = msg->fTopic;
1398  if (recvTopicID == topicID)
1399  {
1400  msg->fMType = -1;
1401  msg->fEOM = false;
1402  // DEBUG_PRINTLN("CALLING MSG");
1403  // DEBUG_PRINT("fHandler=");
1404  // DEBUG_PRINTLN_HEX((size_t)topics->fHandler);
1405  msg->fHandler(*msg);
1406  msg->end();
1407  break;
1408  }
1409  }
1410  }
1411 
1412  static void sendSubscriberList()
1413  {
1414  unsigned count = 0;
1415  for (Message* msg = *tail(); msg != NULL; msg = msg->fNext)
1416  count++;
1417  if (count != 0)
1418  {
1419  send_string_hash("subscribers");
1420  DEBUG_PRINTLN("subscribers = "); DEBUG_PRINTLN(count);
1421  send_raw_bytes(&count, sizeof(count));
1422  for (Message* msg = *tail(); msg != NULL; msg = msg->fNext)
1423  {
1424  // smq_id topicID = (sizeof(smq_id) == sizeof(uint32_t)) ?
1425  // pgm_read_dword(&msg->fTopic) : pgm_read_word(&msg->fTopic);
1426  smq_id topicID = msg->fTopic;
1427  DEBUG_PRINT(" ["); DEBUG_PRINTLN_HEX(topicID);
1428  send_raw_bytes(&topicID, sizeof(topicID));
1429  }
1430  send_end();
1431  sSMQ->flush();
1432  }
1433  }
1434 
1435  smq_id fTopic;
1436  MessageHandler fHandler;
1437  Message* fNext;
1438  bool fEOM = true;
1439  int fMType = -1;
1440 
1441  static Message** tail()
1442  {
1443  static Message* sTail;
1444  return &sTail;
1445  }
1446  friend class SMQ;
1447  };
1448 
1449 private:
1450  static inline uint16_t update_crc(uint16_t crc, const uint8_t data)
1451  {
1452  // crc-16 poly 0x8005 (x^16 + x^15 + x^2 + 1)
1453  static const PROGMEM uint16_t crc16_table[256] =
1454  {
1455  0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
1456  0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
1457  0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
1458  0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
1459  0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
1460  0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
1461  0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
1462  0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
1463  0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
1464  0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
1465  0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
1466  0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
1467  0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
1468  0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
1469  0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
1470  0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
1471  };
1472  return (crc >> 8) ^ pgm_read_word_near(&crc16_table[(crc ^ data) & 0xFF]);
1473  }
1474 
1475  static uint16_t calc_crc(const void* buf, size_t len, uint16_t crc)
1476  {
1477  const uint8_t* b = (uint8_t*)buf;
1478  const uint8_t* buf_end = (uint8_t*)buf + len;
1479  while (b < buf_end)
1480  {
1481  crc = update_crc(crc, *b++);
1482  }
1483  return crc;
1484  }
1485 
1486  static void send_raw_bytes(const void* buf, size_t len)
1487  {
1488  sSMQ->write((uint8_t*)buf, len);
1489  sSMQ->flush();
1490  }
1491 
1492  static void send_data(const void* buf, uint16_t len)
1493  {
1494  uint16_t crc = 0;
1495  const uint8_t* b = (uint8_t*)buf;
1496  const uint8_t* buf_end = (uint8_t*)buf + len;
1497  while (b < buf_end)
1498  {
1499  crc = update_crc(crc, *b++);
1500  }
1501  send_raw_bytes(&crc, sizeof(crc));
1502  send_raw_bytes(buf, len);
1503  }
1504 
1505  static void send_data(PROGMEMString pbuf, uint16_t len)
1506  {
1507  uint16_t crc = 0;
1508  const uint8_t* pb = (uint8_t*)pbuf;
1509  const uint8_t* pbuf_end = (uint8_t*)pbuf + len;
1510  while (pb < pbuf_end)
1511  {
1512  crc = update_crc(crc, pgm_read_byte(pb++));
1513  }
1514  send_raw_bytes(&crc, sizeof(crc));
1515  pb = (uint8_t*)pbuf;
1516  pbuf_end = (uint8_t*)pbuf + len;
1517  while (pb < pbuf_end)
1518  {
1519  byte b = pgm_read_byte(pb++);
1520  sSMQ->write((uint8_t*)&b, 1);
1521  }
1522  sSMQ->flush();
1523  }
1524 
1525  static int read(void* buf, size_t len)
1526  {
1527  char* b = (char*)buf;
1528  char* b_end = b + len;
1529  while (b < b_end)
1530  {
1531  while (!sSMQ->available())
1532  ;
1533  int v = sSMQ->read();
1534  if (v != -1)
1535  *b++ = v;
1536  }
1537  int cnt = b - (char*)buf;
1538  if (cnt > 0)
1539  {
1540  DEBUG_PRINT(cnt); DEBUG_PRINT("<== [0x");
1541  for (int i = 0; i < cnt; i++)
1542  {
1543  DEBUG_PRINT_HEX(((uint8_t*)buf)[i]);
1544  DEBUG_PRINT(" ");
1545  }
1546  DEBUG_PRINTLN("]");
1547  DEBUG_FLUSH();
1548  }
1549  return cnt;
1550  }
1551 
1552  static int8_t read_int8()
1553  {
1554  int8_t val;
1555  read(&val, sizeof(val));
1556  return val;
1557  }
1558 
1559  static int16_t read_int16()
1560  {
1561  int16_t val;
1562  read(&val, sizeof(val));
1563  return val;
1564  }
1565 
1566  static int32_t read_int32()
1567  {
1568  int32_t val;
1569  read(&val, sizeof(val));
1570  return val;
1571  }
1572 
1573  static uint8_t read_uint8()
1574  {
1575  uint8_t val;
1576  read(&val, sizeof(val));
1577  return val;
1578  }
1579 
1580  static uint16_t read_uint16()
1581  {
1582  uint16_t val;
1583  read(&val, sizeof(val));
1584  return val;
1585  }
1586 
1587  static uint32_t read_uint32()
1588  {
1589  uint32_t val;
1590  read(&val, sizeof(val));
1591  return val;
1592  }
1593 
1594  static float read_float()
1595  {
1596  float val;
1597  read(&val, sizeof(val));
1598  return val;
1599  }
1600 
1601  static double read_double()
1602  {
1603  double val;
1604  read(&val, sizeof(val));
1605  return val;
1606  }
1607 
1608  static uint8_t* read_buffer(uint8_t* buf, uint16_t len, uint16_t bufsize)
1609  {
1610  uint8_t* p = buf;
1611  uint8_t* pend = p + min(len, bufsize);
1612  while (p < pend)
1613  {
1614  while (!sSMQ->available())
1615  ;
1616  *p++ = sSMQ->read();
1617  }
1618  if (len > bufsize)
1619  {
1620  /* Skip data that is bigger than our buffer */
1621  len = len - bufsize;
1622  while (len--)
1623  read_uint8();
1624  /* message was truncated and is probably not valid */
1625  return NULL;
1626  }
1627  return buf;
1628  }
1629 };
1630 
1631 typedef void (*SMQMessageHandler)(class SMQ::Message& msg);
1632 
1633 #define SMQMSG_FUNC_DECL(topic) \
1634  static void SMQHandler_##topic(SMQ::Message& msg)
1635 #define SMQMESSAGE(topic, handler) \
1636  SMQMSG_FUNC_DECL(topic); \
1637  SMQ::Message SMQMSG_##topic(SMQID(#topic), SMQHandler_##topic); \
1638  SMQMSG_FUNC_DECL(topic) { UNUSED_ARG(msg) handler }
1639 
1640 #endif
SMQ::process
static void process()
Definition: ReelTwoSMQ.h:74
SMQ::sendTopic
static bool sendTopic(PROGMEMString str)
Definition: ReelTwoSMQ.h:161
SMQ::send_null
static void send_null(const msg_id id)
Definition: ReelTwoSMQ.h:433
SMQ::send_string
static void send_string(const char *key, const char *val)
Definition: ReelTwoSMQ.h:214
DEBUG_PRINT
#define DEBUG_PRINT(s)
Definition: ReelTwo.h:189
SMQMessageHandler
void(* SMQMessageHandler)(class SMQ::Message &msg)
Definition: ReelTwoSMQ.h:1631
ReelTwo.h
sSMQ
SMQ sSMQ
Definition: ReelTwoSMQ32.h:2517
SMQ::send_uint8
static void send_uint8(const char *key, uint8_t val)
Definition: ReelTwoSMQ.h:308
SMQ::send_end
static void send_end()
Definition: ReelTwoSMQ.h:463
SMQ::sendTopic
static bool sendTopic(const smq_id id)
Definition: ReelTwoSMQ.h:155
SMQ::send_uint32
static void send_uint32(const msg_id id, uint32_t val)
Definition: ReelTwoSMQ.h:340
DEBUG_PRINTLN_HEX
#define DEBUG_PRINTLN_HEX(s)
Definition: ReelTwo.h:191
SMQ::send_double
static void send_double(const msg_id id, double val)
Definition: ReelTwoSMQ.h:388
SMQ::send_double
static void send_double(PROGMEMString key, double val)
Definition: ReelTwoSMQ.h:396
SMQ::send_double
static void send_double(const char *key, double val)
Definition: ReelTwoSMQ.h:404
smq_id
uint16_t smq_id
Definition: ReelTwoSMQ.h:42
SMQ::send_uint16
static void send_uint16(const char *key, uint16_t val)
Definition: ReelTwoSMQ.h:332
DEBUG_PRINTLN
#define DEBUG_PRINTLN(s)
Definition: ReelTwo.h:188
SMQ::send_start
static void send_start(PROGMEMString str)
Definition: ReelTwoSMQ.h:179
SMQ::send_string_id
static void send_string_id(const msg_id id)
Definition: ReelTwoSMQ.h:126
SMQ::send_boolean
static void send_boolean(const char *key, bool val)
Definition: ReelTwoSMQ.h:426
SMQ::MessageHandler
void(* MessageHandler)(Message &msg)
Definition: ReelTwoSMQ.h:470
SMQ::send_int32
static void send_int32(PROGMEMString key, int32_t val)
Definition: ReelTwoSMQ.h:284
SMQ::send_int16
static void send_int16(PROGMEMString key, int16_t val)
Definition: ReelTwoSMQ.h:252
SMQ::send_uint32
static void send_uint32(PROGMEMString key, uint32_t val)
Definition: ReelTwoSMQ.h:348
SMQ::send_int16
static void send_int16(const msg_id id, int16_t val)
Definition: ReelTwoSMQ.h:244
DEBUG_FLUSH
#define DEBUG_FLUSH()
Definition: ReelTwo.h:193
SMQ::send_ready
static bool send_ready()
Definition: ReelTwoSMQ.h:150
SMQ::send_start
static void send_start(const char *str)
Definition: ReelTwoSMQ.h:185
SMQ::send_int16
static void send_int16(const char *key, int16_t val)
Definition: ReelTwoSMQ.h:260
SMQ::send_start
static void send_start(const smq_id id)
Definition: ReelTwoSMQ.h:173
SMQ::send_float
static void send_float(PROGMEMString key, float val)
Definition: ReelTwoSMQ.h:372
SMQ::send_uint8
static void send_uint8(PROGMEMString key, uint8_t val)
Definition: ReelTwoSMQ.h:300
SMQ::send_string
static void send_string(PROGMEMString str)
Definition: ReelTwoSMQ.h:116
SMQ::send_string
static void send_string(const msg_id id, const char *val)
Definition: ReelTwoSMQ.h:196
SMQ
Serial Message Queue.
Definition: ReelTwoSMQ.h:54
SMQ::send_uint16
static void send_uint16(const msg_id id, uint16_t val)
Definition: ReelTwoSMQ.h:316
SMQ::send_boolean
static void send_boolean(PROGMEMString key, bool val)
Definition: ReelTwoSMQ.h:419
SMQ::send_int8
static void send_int8(const msg_id id, int8_t val)
Definition: ReelTwoSMQ.h:220
SMQ::send_float
static void send_float(const msg_id id, float val)
Definition: ReelTwoSMQ.h:364
SMQ::send_int8
static void send_int8(const char *key, int8_t val)
Definition: ReelTwoSMQ.h:236
SMQ::send_int32
static void send_int32(const char *key, int32_t val)
Definition: ReelTwoSMQ.h:276
SMQ::send_uint32
static void send_uint32(const char *key, uint32_t val)
Definition: ReelTwoSMQ.h:356
DEBUG_PRINT_HEX
#define DEBUG_PRINT_HEX(s)
Definition: ReelTwo.h:192
SMQ::send_uint8
static void send_uint8(const msg_id id, uint8_t val)
Definition: ReelTwoSMQ.h:292
SMQ::send_uint16
static void send_uint16(PROGMEMString key, uint16_t val)
Definition: ReelTwoSMQ.h:324
SMQ::send_null
static void send_null(const char *key)
Definition: ReelTwoSMQ.h:447
SMQ::send_string
static void send_string(PROGMEMString key, const char *val)
Definition: ReelTwoSMQ.h:202
SMQ::send_string_hash
static void send_string_hash(const char *str)
Definition: ReelTwoSMQ.h:133
SMQ::send_int8
static void send_int8(PROGMEMString key, int8_t val)
Definition: ReelTwoSMQ.h:228
SMQ::send_float
static void send_float(const char *key, float val)
Definition: ReelTwoSMQ.h:380
PROGMEMString
const typedef __FlashStringHelper * PROGMEMString
Definition: ReelTwo.h:235
msg_id
uint16_t msg_id
Definition: ReelTwoSMQ.h:40
SMQ::send_int32
static void send_int32(const msg_id id, int32_t val)
Definition: ReelTwoSMQ.h:268
SMQ::send_start_hash
static void send_start_hash(const char *str)
Definition: ReelTwoSMQ.h:191
UNUSED_ARG
#define UNUSED_ARG(arg)
Definition: ReelTwo.h:25
SMQ::sendTopic
static bool sendTopic(const char *str)
Definition: ReelTwoSMQ.h:167
SMQ::send_boolean
static void send_boolean(const msg_id id, bool val)
Definition: ReelTwoSMQ.h:412
SMQ::ready
static void ready()
Definition: ReelTwoSMQ.h:57
SMQ::send_null
static void send_null(PROGMEMString key)
Definition: ReelTwoSMQ.h:440
SMQ::send_string
static void send_string(const char *str)
Definition: ReelTwoSMQ.h:106
SMQ::send_string
static void send_string(PROGMEMString key, PROGMEMString val)
Definition: ReelTwoSMQ.h:208