Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

314 lines
6.0 KiB

  1. #include <usbd_cdc_if.h>
  2. #include <strobe_rng_init.h>
  3. #include <string.h>
  4. #include <board.h>
  5. #include <misc.h>
  6. #include <radio.h>
  7. #include <delay.h>
  8. char *
  9. findeol(char *pos, size_t len)
  10. {
  11. while (len) {
  12. if (*pos == '\r' || *pos == '\n')
  13. return pos;
  14. pos++;
  15. len--;
  16. }
  17. return NULL;
  18. }
  19. void
  20. hexdump(uint8_t *ptr, size_t len)
  21. {
  22. int i;
  23. for (i = 0; i < len; i++)
  24. usb_printf("%02x", ptr[i]);
  25. }
  26. void
  27. txdone(void)
  28. {
  29. usb_printf("txdone\r\n");
  30. }
  31. void
  32. txtimeout(void)
  33. {
  34. usb_printf("txtimeout\r\n");
  35. }
  36. void
  37. rxdone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
  38. {
  39. usb_printf("rxdone: size: %hu, rssi: %hd, snr: %d\r\ndata: ", size, rssi, snr);
  40. hexdump(payload, size);
  41. usb_printf("\r\n");
  42. }
  43. void
  44. rxtimeout(void)
  45. {
  46. usb_printf("rxtimeout\r\n");
  47. }
  48. void
  49. rxerr(void)
  50. {
  51. usb_printf("rxerr\r\n");
  52. }
  53. RadioEvents_t revents = {
  54. .TxDone = txdone,
  55. .TxTimeout = txtimeout,
  56. .RxDone = rxdone,
  57. .RxTimeout = rxtimeout,
  58. .RxError = rxerr,
  59. };
  60. static uint8_t
  61. hexchartonib(char s)
  62. {
  63. switch (s) {
  64. case '0'...'9':
  65. return s - '0';
  66. case 'a'...'f':
  67. return s - 'a' + 10;
  68. case 'A'...'F':
  69. return s - 'A' + 10;
  70. default:
  71. return -1;
  72. }
  73. }
  74. static bool
  75. hexdecode(char *buf, size_t len, uint8_t *out)
  76. {
  77. uint8_t topchr, botchr;
  78. if (len % 2)
  79. return false;
  80. /* NB: only needed to silence a bad gcc warning */
  81. topchr = -1;
  82. while (len) {
  83. if (len % 2) {
  84. /* bottom nibble */
  85. botchr = hexchartonib(*buf);
  86. if (topchr == -1 || botchr == -1)
  87. return false;
  88. *out = topchr << 4 | botchr;
  89. out++;
  90. } else {
  91. /* top nibble */
  92. topchr = hexchartonib(*buf);
  93. }
  94. len--;
  95. buf++;
  96. }
  97. return true;
  98. }
  99. static const char pktstart[] = "pkt:";
  100. static const size_t pktstartlen = sizeof pktstart - 1;
  101. static uint8_t pktbuf[128];
  102. static void
  103. process_line(char *start, char *end)
  104. {
  105. size_t len;
  106. /* trim off leading CR/NL */
  107. while (start < end && (*start == '\r' || *start == '\n'))
  108. start++;
  109. len = end - start;
  110. if (len >= pktstartlen && memcmp(start, pktstart, sizeof pktstart - 1) == 0) {
  111. start += pktstartlen;
  112. len -= pktstartlen;
  113. if (len % 2) {
  114. usb_printf("invalid pkt len\r\n");
  115. return;
  116. }
  117. if (!hexdecode(start, len, pktbuf)) {
  118. usb_printf("invalid pkt\r\n");
  119. return;
  120. }
  121. Radio.Send(pktbuf, len / 2);
  122. return;
  123. }
  124. usb_printf("line: %.*s", end - start, start);
  125. }
  126. int
  127. main(void)
  128. {
  129. uint8_t bytes[8];
  130. strobe_rng_init();
  131. BoardInitMcu();
  132. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
  133. #if 1
  134. wait_for_vcp();
  135. usb_printf("starting...\r\n");
  136. bare_strobe_randomize(bytes, sizeof bytes);
  137. hexdump(bytes, sizeof bytes);
  138. usb_printf("\r\n");
  139. #endif
  140. Radio.Init(&revents);
  141. usb_printf("foo\r\n");
  142. Radio.ReadBuffer(0x00, bytes, sizeof bytes);
  143. usb_printf("regs 0x00: ");
  144. hexdump(bytes, sizeof bytes);
  145. usb_printf("\r\n");
  146. Radio.ReadBuffer(0x40, bytes, sizeof bytes);
  147. usb_printf("regs 0x40: ");
  148. hexdump(bytes, sizeof bytes);
  149. usb_printf("\r\n");
  150. uint32_t v;
  151. v = Radio.Random();
  152. usb_printf("rr: %#x\r\n", v);
  153. v = Radio.Random();
  154. usb_printf("rr: %#x\r\n", v);
  155. v = Radio.Random();
  156. usb_printf("rr: %#x\r\n", v);
  157. usb_printf("gs: %#x\r\n", Radio.GetStatus());
  158. usb_printf("set modem\r\n", v);
  159. Radio.SetModem(MODEM_LORA);
  160. usb_printf("check rffreq: %d\r\n", (int)Radio.CheckRfFrequency(914350 * 1000));
  161. usb_printf("set channel\r\n", v);
  162. Radio.SetChannel(914350 * 1000);
  163. v = Radio.Random();
  164. usb_printf("rr: %#x\r\n", v);
  165. usb_printf("rssi: %#hx\r\n", Radio.Rssi(MODEM_LORA));
  166. /* RX/TX parameters */
  167. const uint8_t modem = MODEM_LORA;
  168. const uint8_t bandwidth = 0 /* 128 kHz */;
  169. const uint8_t datarate = 7 /* 128 chips */;
  170. const uint8_t coderate = 1 /* 4/5 */;
  171. const uint8_t preambleLen = 4 /* symbols */;
  172. const uint8_t fixLen = 0 /* variable */;
  173. const uint8_t crcOn = 1 /* on */;
  174. const uint8_t freqHopOn = 0 /* off */;
  175. const bool iqInverted = false /* not inverted */;
  176. Radio.SetRxConfig(modem, bandwidth, datarate, coderate, 0/*afc*/,
  177. preambleLen, 5/*symTimeout*/, fixLen, 0/*payloadlen*/, crcOn,
  178. freqHopOn, 0/*hopPeriod*/, iqInverted, true/*rxcont*/);
  179. Radio.SetTxConfig(modem, 11/*power*/, 0/*fdev*/, bandwidth, datarate,
  180. coderate, preambleLen, fixLen, crcOn, freqHopOn, 0/*hopPeriod*/,
  181. iqInverted, 1000/*timeout*/);
  182. uint8_t sendmsg[] = "testing lora123";
  183. usb_printf("sending...\r\n");
  184. Radio.Send(sendmsg, sizeof sendmsg);
  185. DelayMs(200);
  186. Radio.Send(sendmsg, sizeof sendmsg);
  187. DelayMs(200);
  188. Radio.Send(sendmsg, sizeof sendmsg);
  189. DelayMs(200);
  190. usb_printf("rx(0)...\r\n");
  191. Radio.Rx(0);
  192. char inpbuf[1024];
  193. char *lastcheck;
  194. char *endchr;
  195. int inpbufpos = 0;
  196. int cpylen;
  197. loop:
  198. BoardLowPowerHandler();
  199. if (Radio.IrqProcess != NULL)
  200. Radio.IrqProcess();
  201. /* while we have data */
  202. while (CDC_RX_LEN) {
  203. /* store last position */
  204. lastcheck = &inpbuf[inpbufpos];
  205. /* calculate how much space left */
  206. cpylen = MIN(sizeof inpbuf - inpbufpos, CDC_RX_LEN);
  207. /* copy into buffer */
  208. memcpy(&inpbuf[inpbufpos], CDC_RX_BUFFER, cpylen);
  209. /* and point to end of buffer */
  210. inpbufpos += cpylen;
  211. do {
  212. /* find first end of line characters */
  213. endchr = findeol(lastcheck, cpylen);
  214. if (endchr != NULL) {
  215. /* if so, process it */
  216. process_line(inpbuf, endchr);
  217. /* skip end of line char */
  218. endchr++;
  219. /* move remaining buffer to the beginning */
  220. memmove(inpbuf, endchr, inpbufpos - (endchr - inpbuf));
  221. /* and store new length */
  222. inpbufpos = inpbufpos - (endchr - inpbuf);
  223. /* mark begining of stream as last checked */
  224. lastcheck = inpbuf;
  225. /* and try to process another line */
  226. continue;
  227. } else if (inpbufpos == sizeof inpbuf) {
  228. /* we overflowed the buffer */
  229. /* XXX - best way is to throw away this line */
  230. inpbufpos = 0;
  231. }
  232. } while (0);
  233. /* if we copied all the data */
  234. if (cpylen == CDC_RX_LEN) {
  235. /* declare that we are ready to receive more data */
  236. CDC_RX_LEN = 0;
  237. USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  238. } else {
  239. /* if not, move the remaining to the begining and try again */
  240. memmove(CDC_RX_BUFFER, &CDC_RX_BUFFER[cpylen], CDC_RX_LEN - cpylen);
  241. CDC_RX_LEN -= cpylen;
  242. }
  243. }
  244. goto loop;
  245. }