Guest User

Untitled

a guest
Feb 23rd, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.10 KB | None | 0 0
  1. /**
  2. * Proof-of-concept for establishing design bassis for an extremely compact
  3. * data transfer protocol for wireless data transmission
  4. *
  5. * The idea is to have a protocol that is flexible in that arbitrary data types
  6. * can be passed without the wasted space that would be caused by a struct-based
  7. * approach that would need to reserve more space than required for a given message
  8. *
  9. * This example uses a byte for each data point to determine its type. This seems
  10. * wasteful to use up a full extra byte for each data type, however, as seen with
  11. * Node 5 in the example below, the end goal is to have abstract types associated
  12. * with sensor data. Thus we have a type-space of 255 possible sensor types which
  13. * will carry semantic weight as well as deeper indication of how to parse out the
  14. * subsequent bytes
  15. *
  16. * The general messaging format will look like:
  17. *
  18. * NODE_ID MSG_ID MSG_COUNT DATA_TYPE DATA DATA_TYPE DATA ... etc
  19. *
  20. * e.g. Air quality sample data point #100 from node 3 might look like:
  21. *
  22. * 3 100 1 AIR_QUALITY 20 1234567
  23. *
  24. * where AIR_QAULITY is a constant in the type space, 20 is some meaningful value
  25. * for the specified type and 1234567 is a bogus timestamp. The protocol would
  26. * know to parse out the IDs, and the number of records, and then parse the
  27. * remainder of the message according to the type and data of each record
  28. *
  29. * Or another example which does not require a timestamp:
  30. *
  31. * 3 101 BATTERY_LEVEL 39
  32. *
  33. * Where the BATTERY_LEVEL data type is protocol-determined to be divided by 10
  34. *
  35. * In reality, there will be multiple nodes each with multiple data points. So,
  36. * for example:
  37. *
  38. * 2 1 3 BAT 39 GPS 3 42.04507 -87.68770 DUST 20 12345 3 1 1 BAT 42
  39. *
  40. * Is a messages containing Node 2 data message #1, with battery, GPS, and
  41. * air quality records (with the latter having a timestamp) and Node 3 having
  42. * only a battery value to deliver
  43. *
  44. * The following example does some sanity checking on standard numerica data
  45. * types, then includes a sensor node data set for Node 5
  46. *
  47. **/
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50.  
  51. #define CHAR 1
  52. #define INT8 2
  53. #define UINT8 3
  54. #define INT16 4
  55. #define UINT16 5
  56.  
  57. #define BATTERY 6
  58. #define GPS 7
  59. #define AIR_PARTICULATE 8
  60.  
  61.  
  62. /** Utilities for traversing the byte message */
  63.  
  64. uint8_t next_8_bit(uint8_t* data, int len, int* index, uint8_t* val)
  65. {
  66. *val = data[*index];
  67. *index += 1;
  68. if (*index > len) {
  69. printf("\nBAD BYTE SEQUENCE\n");
  70. return 0;
  71. }
  72. return 1;
  73. }
  74.  
  75. uint8_t next_16_bit(uint8_t* data, int len, int* index, uint16_t* val)
  76. {
  77. if (*index > len-2) {
  78. printf("\nBAD BYTE SEQUENCE: Not enough data for 16-bit value\n");
  79. return 0;
  80. }
  81. *val = (data[*index] << 8) | (data[*index+1] & 0xff);
  82. *index += 2;
  83. return 1;
  84. }
  85.  
  86. uint8_t next_32_bit(uint8_t* data, int len, int* index, uint32_t* val)
  87. {
  88. if (*index > len-4) {
  89. printf("\nBAD BYTE SEQUENCE: Not enough data for 32-bit value\n");
  90. return 0;
  91. }
  92. *val = (data[*index] << 24)
  93. | (data[*index+1] << 16)
  94. | (data[*index+2] << 8)
  95. | (data[*index+3] & 0xff);
  96. *index += 4;
  97. return 1;
  98. }
  99.  
  100. void printval8(uint8_t val, uint8_t data_type)
  101. {
  102. if (data_type == CHAR) {
  103. printf("%c ", (char)val);
  104. } else if (data_type == INT8) {
  105. printf("%d ", (int8_t)val);
  106. } else if (data_type == UINT8) {
  107. printf("%d ", val);
  108. }
  109. }
  110.  
  111. void printval16(uint16_t val, uint8_t data_type)
  112. {
  113. if (data_type == INT16) {
  114. printf("%d ", (int16_t)val);
  115. } else if (data_type == UINT16) {
  116. printf("%d ", val);
  117. }
  118. }
  119.  
  120. /**
  121. * Floating points are not supported. Instead, types will be protocol defined
  122. * to divide by a power of 10 according to required precision for that specific
  123. * data type
  124. */
  125.  
  126. /**
  127. * This example byte sequence will result in human-readable print of:
  128. *
  129. * NODE ID: 3; MSG ID: 1; MSG COUNT: 8; MESSAGES:
  130. * ! ~ A Z a z 0 255
  131. *
  132. * NODE ID: 4; MSG ID: 1; MSG COUNT: 7; MESSAGES:
  133. * -128 127 65535 0 32767 -32768 0
  134. *
  135. * NODE ID: 5; MSG ID: 1; MSG COUNT: 3; MESSAGES:
  136. * BAT: 3.9; SATS: 3; LAT: 42.04507; LON: -87.68770; DUST: 20; TIMESTAMP: 12345;
  137. *
  138. **/
  139. int main(int argc, char** argv)
  140. {
  141. int32_t latitude = 4204507;
  142. int32_t longitude = -8768770;
  143. uint8_t example[] = {
  144.  
  145. // Node 3, some 8-bit testing
  146. 3, 1, 8,
  147. CHAR, '!',
  148. CHAR, '~',
  149. CHAR, 'A',
  150. CHAR, 'Z',
  151. CHAR, 'a',
  152. CHAR, 'z',
  153.  
  154. UINT8, 0,
  155. UINT8, 255,
  156.  
  157. // Node 4, 8 and 16-bit testing
  158. 4, 1, 7,
  159.  
  160. INT8, -128,
  161. INT8, 127,
  162.  
  163. UINT16, 65535 >> 8, 65535 & 0xff,
  164. UINT16, 0 >> 8, 0 & 0xff,
  165.  
  166. INT16, 32767 >> 8, 32767 & 0xff,
  167. INT16, -32768 >> 8, -32768 & 0xff,
  168. INT16, 0 >> 8, 0 & 0xff,
  169.  
  170. // Node 5 starts to look like real sensor data
  171. 5, 1, 3,
  172.  
  173. BATTERY, 39,
  174. GPS, 3,
  175. latitude >> 24, latitude >> 16,
  176. latitude >> 8, latitude & 0xff,
  177.  
  178. longitude >> 24, longitude >> 16,
  179. longitude >> 8, longitude & 0xff,
  180.  
  181. AIR_PARTICULATE, 20, 12345 >> 8, 12345 & 0xff
  182. };
  183. int len = sizeof(example);
  184.  
  185. uint8_t node_id;
  186. uint8_t msg_id;
  187. uint8_t record_count;
  188. uint8_t data_type;
  189. uint8_t val8;
  190. uint16_t val16;
  191. uint32_t val32;
  192. for (int i=0; i+4<sizeof(example);) { // min 5 bytes for a node message
  193. node_id = example[i++];
  194. msg_id = example[i++];
  195. record_count = example[i++];
  196. printf("NODE ID: %d; MSG ID: %d; MSG COUNT: %d; MESSAGES:\n",
  197. node_id, msg_id, record_count);
  198. for (int j=0; j<record_count; j++) {
  199. data_type = example[i++];
  200. switch(data_type) {
  201. /* 8-bit type testing */
  202. case CHAR :
  203. case INT8 :
  204. case UINT8 :
  205. if (!next_8_bit(example, len, &i, &val8)) break;
  206. printval8(val8, data_type);
  207. break;
  208. /* 16-bit type testing */
  209. case INT16 :
  210. case UINT16 :
  211. if (!next_16_bit(example, len, &i, &val16)) break;
  212. printval16(val16, data_type);
  213. break;
  214. /* abstract types */
  215. case BATTERY :
  216. if (!next_8_bit(example, len, &i, &val8)) break;
  217. printf("BAT: %2.1f; ", val8 / 10.0);
  218. break;
  219. case GPS :
  220. if (!next_8_bit(example, len, &i, &val8)) break;
  221. printf("SATS: %d; ", val8);
  222. if (!next_32_bit(example, len, &i, &val32)) break;
  223. printf("LAT: %8.5f; ", (int32_t)val32 / 100000.0);
  224. if (!next_32_bit(example, len, &i, &val32)) break;
  225. printf("LON: %8.5f; ", (int32_t)val32 / 100000.0);
  226. break;
  227. case AIR_PARTICULATE :
  228. if (!next_8_bit(example, len, &i, &val8)) break;
  229. printf("DUST: %d; ", val8);
  230. if (!next_16_bit(example, len, &i, &val16)) break;
  231. printf("TIMESTAMP: %d; ", val16);
  232. break;
  233. }
  234. }
  235. printf("\n\n");
  236. }
  237. }
Add Comment
Please, Sign In to add comment