kiss.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * tnc_kiss.c
  3. *
  4. * Created on: Feb 26, 2019
  5. * Author: curiousmuch
  6. */
  7. // basic set of functions at this moment which decodes KISS
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "freertos/ringbuf.h"
  11. #include "esp_log.h"
  12. #include <stdio.h>
  13. #include "cc1200.h"
  14. #include "fcs_calc.h"
  15. #include "kiss.h"
  16. buffer_handle_t buffer_handle;
  17. tnc_settings_t tnc_settings;
  18. void kiss_clear_buffer(void)
  19. {
  20. ESP_LOGD(TNC_TAG, "TNC buffer cleared.");
  21. buffer_handle.index = 0;
  22. }
  23. void kiss_append_buffer(uint8_t chr)
  24. {
  25. ESP_LOGD(TNC_TAG, "Appending %x to TNC buffer.", chr);
  26. // ERROR - Packet Buffer Overflow
  27. if (buffer_handle.index >= buffer_handle.max_len)
  28. {
  29. ESP_LOGE(TNC_TAG, "TNC buffer overflow");
  30. kiss_clear_buffer();
  31. }
  32. buffer_handle.buf[(buffer_handle.index)] = chr;
  33. buffer_handle.index = buffer_handle.index + 1;
  34. }
  35. extern RingbufHandle_t radio_tx_buf;
  36. // Frame Format
  37. // [ Command Byte ][ Data ]
  38. void kiss_process_frame(void)
  39. {
  40. uint8_t data_byte, tnc_number;
  41. data_byte = buffer_handle.buf[0];
  42. tnc_number = (data_byte >> 4) & 0x0F; // TODO: Have KISS code respect TNC number
  43. switch( data_byte ) {
  44. case KISS_DATAFRAME: {
  45. ESP_LOGI(TNC_TAG, "Received Data Frame - Length %d", (buffer_handle.index));
  46. // unblock AX.25 code to process code
  47. uint32_t fcs = fcs_calc(&buffer_handle.buf[1], buffer_handle.index-1);
  48. buffer_handle.buf[buffer_handle.index] = fcs & 0xFF;
  49. buffer_handle.buf[buffer_handle.index+1] = fcs>>8 & 0xFF;
  50. xRingbufferSend(radio_tx_buf, &buffer_handle.buf[1], ((buffer_handle.index+1)*sizeof(uint8_t)), 10/portTICK_PERIOD_MS);
  51. ESP_LOG_BUFFER_HEXDUMP(TNC_TAG, &buffer_handle.buf[1], buffer_handle.index+1, ESP_LOG_INFO);
  52. //cc1200_radio_APRSTXPacket(buffer_handle.buf, (buffer_handle.index+2), tnc_settings.tx_delay, tnc_settings.tx_tail);
  53. break;
  54. }
  55. case KISS_CMD_TXDELAY: {
  56. ESP_LOGI(TNC_TAG, "Updated TX Delay");
  57. tnc_settings.tx_delay = buffer_handle.buf[1];
  58. break;
  59. }
  60. case KISS_CMD_P: {
  61. ESP_LOGI(TNC_TAG, "Update Persistence");
  62. tnc_settings.persistence = buffer_handle.buf[1];
  63. break;
  64. }
  65. case KISS_CMD_SLOTTIME: {
  66. ESP_LOGI(TNC_TAG, "Updated Slottime");
  67. tnc_settings.slot_time = buffer_handle.buf[1];
  68. break;
  69. }
  70. case KISS_CMD_TXTAIL: {
  71. ESP_LOGI(TNC_TAG, "Updated TX Tail");
  72. tnc_settings.tx_tail= buffer_handle.buf[1];
  73. break;
  74. }
  75. case KISS_CMD_FULLDUPLEX: {
  76. ESP_LOGI(TNC_TAG, "Updated Full/Half Duplex Setting");
  77. tnc_settings.full_duplex = buffer_handle.buf[1];
  78. break;
  79. }
  80. // case KISS_CMD_SETHARDWARE: {
  81. // break;
  82. // }
  83. // case KISS_CMD_RETURN: {
  84. // tnc_settings.tx_delay = buffer_handle.buff_ptr[1];
  85. // break;
  86. // }
  87. default: {
  88. // error
  89. break;
  90. }
  91. }
  92. kiss_clear_buffer();
  93. return;
  94. }
  95. void kiss_set_tnc_paramters(tnc_settings_t s)
  96. {
  97. tnc_settings.tx_delay = s.tx_delay;
  98. tnc_settings.persistence = s.persistence;
  99. tnc_settings.slot_time = s.slot_time;
  100. tnc_settings.tx_tail = s.tx_tail;
  101. tnc_settings.full_duplex = s.full_duplex;
  102. // tnc_settings.tnc_number = s.tnc_number;
  103. }
  104. // TNC needs the ability to RX KISS frame, decode it, schedule it, and then send out via APRS or Arrow-Net
  105. // TNC needs the ability to switch to RX mode,
  106. void kiss_init(void)
  107. {
  108. buffer_handle.max_len = FRAME_BUFFER_SIZE; // TODO: make frame buffer dynamic
  109. // tnc_settings.max_frame_size = FRAME_BUFFER_SIZE;
  110. // TODO: Store / retrieve default TNC settings from flash?
  111. // set default TNC settings
  112. tnc_settings.tx_delay = 5;
  113. tnc_settings.persistence = 63;
  114. tnc_settings.slot_time = 10;
  115. tnc_settings.tx_tail = 1;
  116. tnc_settings.full_duplex = 0;
  117. // setup TNC task with queue
  118. }
  119. // Decode KISS-TNC data from SPP Interface and combine until there is
  120. // is a valid packet. Pass valid packet / frame to AX.25 engine.
  121. // Data Flow:
  122. // (1) SPP interface hands over data array which is runs a state machine to decode the KISS Frame
  123. // (2) Decoded information is uploaded thrown into a buffer
  124. // (3) When frame is complete the state machine will copy or indicate to another task to dump the buffer
  125. // If the frame is not completed, the state machine will wait until more data is provided by the SPP interface.
  126. // If the frame is corrupted or the buffer fills, the frame will be dumped and the error must be logged.
  127. KISS_STATE_t kiss_state = FRAME_END;
  128. void kiss_receive(uint8_t* data, uint16_t len)
  129. {
  130. uint32_t i;
  131. uint8_t chr;
  132. for (i=0; i<len; i++)
  133. {
  134. chr = data[i];
  135. switch(kiss_state) {
  136. case ESC_MODE: {
  137. if (chr == KISS_TFEND)
  138. {
  139. kiss_append_buffer(KISS_FEND); // append FEND to frame
  140. kiss_state = FRAME_ASS; // return to assembly
  141. }
  142. else if (chr == KISS_TFESC)
  143. {
  144. kiss_append_buffer(KISS_FESC); // append FESC to frame
  145. kiss_state = FRAME_ASS; // return to assembly
  146. }
  147. else if (chr == KISS_FEND)
  148. {
  149. kiss_process_frame(); // process frame
  150. kiss_state = FRAME_END; // end frame assembly
  151. }
  152. else
  153. {
  154. // log error
  155. kiss_append_buffer(chr); // append chr to frame
  156. kiss_state = FRAME_ASS; // return to assembly
  157. }
  158. break;
  159. }
  160. case FRAME_END: {
  161. if (chr != KISS_FEND)
  162. {
  163. kiss_append_buffer(chr); // append chr to frame
  164. kiss_state = FRAME_ASS; // return to assembly
  165. }
  166. else
  167. {
  168. kiss_state = FRAME_END; // stay in frame end
  169. }
  170. break;
  171. }
  172. case FRAME_ASS: {
  173. if (chr == KISS_FESC)
  174. {
  175. kiss_state = ESC_MODE;
  176. }
  177. else if (chr == KISS_FEND)
  178. {
  179. kiss_process_frame(); // process frame
  180. kiss_state = FRAME_END; // end frame assembly
  181. }
  182. else
  183. {
  184. kiss_append_buffer(chr); // append chr to frame
  185. kiss_state = FRAME_ASS; // continue frame assembly
  186. }
  187. break;
  188. default: {
  189. ESP_LOGE(TNC_TAG, "TNC FSM Error");
  190. }
  191. }
  192. }
  193. }
  194. }