kiss.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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 "kiss.h"
  14. kiss_buffer_t rx_buffer;
  15. kiss_buffer_t tx_buffer;
  16. kiss_settings_t kiss_settings;
  17. void static kiss_clear_tx_buffer(void)
  18. {
  19. ESP_LOGD(TNC_TAG, "TNC buffer cleared.");
  20. tx_buffer.index = 0;
  21. tx_buffer.status = FRAME_INCOMPLETE;
  22. }
  23. void static kiss_append_tx_buffer(uint8_t chr)
  24. {
  25. ESP_LOGD(TNC_TAG, "Appending %x to KISS TX buffer.", chr);
  26. // ERROR - Packet Buffer Overflow
  27. if (tx_buffer.index >= tx_buffer.max_len)
  28. {
  29. ESP_LOGE(TNC_TAG, "TNC TX buffer overflow");
  30. kiss_clear_tx_buffer();
  31. }
  32. tx_buffer.buf[(tx_buffer.index)] = chr;
  33. tx_buffer.index = tx_buffer.index + 1;
  34. }
  35. void kiss_transmit(uint8_t type, uint8_t *data, uint32_t len)
  36. {
  37. uint32_t i;
  38. // TODO: Cancel TX to BLE TX Buffer if overflow is detected
  39. // TODO: Can we eliminate TX buffer and use BLE Buffer only?????
  40. kiss_clear_tx_buffer();
  41. kiss_append_tx_buffer(KISS_FEND);
  42. kiss_append_tx_buffer(type);
  43. // cycle
  44. for (i=0; i<(len); i++)
  45. {
  46. if (data[i] == KISS_FEND)
  47. {
  48. kiss_append_tx_buffer(KISS_FESC);
  49. kiss_append_tx_buffer(KISS_TFEND);
  50. }
  51. else if (data[i] == KISS_FESC)
  52. {
  53. kiss_append_tx_buffer(KISS_FESC);
  54. kiss_append_tx_buffer(KISS_TFESC);
  55. }
  56. else
  57. {
  58. kiss_append_tx_buffer(data[i]);
  59. }
  60. }
  61. kiss_append_tx_buffer(KISS_FEND);
  62. // activate callback function
  63. kiss_settings.tx_callback(tx_buffer.buf, tx_buffer.index);
  64. }
  65. void kiss_clear_buffer(void)
  66. {
  67. ESP_LOGD(TNC_TAG, "TNC buffer cleared.");
  68. rx_buffer.index = 0;
  69. }
  70. void kiss_append_buffer(uint8_t chr)
  71. {
  72. ESP_LOGD(TNC_TAG, "Appending %x to TNC buffer.", chr);
  73. // ERROR - Packet Buffer Overflow
  74. if (rx_buffer.index >= rx_buffer.max_len)
  75. {
  76. ESP_LOGE(TNC_TAG, "TNC buffer overflow");
  77. kiss_clear_buffer();
  78. }
  79. rx_buffer.buf[(rx_buffer.index)] = chr;
  80. rx_buffer.index = rx_buffer.index + 1;
  81. }
  82. //extern RingbufHandle_t radio_tx_buf;
  83. // Frame Format
  84. // [ Command Byte ][ Data ]
  85. void kiss_process_frame(void)
  86. {
  87. // minimum kiss frame is 2 bytes
  88. if (rx_buffer.index < 2)
  89. return;
  90. uint8_t data_byte, tnc_number;
  91. data_byte = rx_buffer.buf[0];
  92. tnc_number = (data_byte >> 4) & 0x0F;
  93. // confirm packet is for this device
  94. if (tnc_number == kiss_settings.tnc_number)
  95. kiss_settings.rx_callback(rx_buffer.buf, rx_buffer.index);
  96. kiss_clear_buffer();
  97. }
  98. // TNC needs the ability to RX KISS frame, decode it, schedule it, and then send out via APRS or Arrow-Net
  99. // TNC needs the ability to switch to RX mode,
  100. void kiss_init(uint8_t tnc_number, kiss_cb_t tx_cb, kiss_cb_t rx_cb)
  101. {
  102. // TODO: make frame buffer dynamic
  103. rx_buffer.max_len = FRAME_BUFFER_SIZE;
  104. tx_buffer.max_len = FRAME_BUFFER_SIZE;
  105. // set tnc number
  106. kiss_settings.tnc_number = tnc_number;
  107. // set callback functions
  108. kiss_settings.rx_callback = rx_cb;
  109. kiss_settings.tx_callback = tx_cb;
  110. }
  111. // Decode KISS-TNC data from SPP Interface and combine until there is
  112. // is a valid packet. Pass valid packet / frame to AX.25 engine.
  113. // Data Flow:
  114. // (1) SPP interface hands over data array which is runs a state machine to decode the KISS Frame
  115. // (2) Decoded information is uploaded thrown into a buffer
  116. // (3) When frame is complete the state machine will copy or indicate to another task to dump the buffer
  117. // If the frame is not completed, the state machine will wait until more data is provided by the SPP interface.
  118. // If the frame is corrupted or the buffer fills, the frame will be dumped and the error must be logged.
  119. KISS_STATE_t kiss_state = FRAME_END;
  120. void kiss_receive(uint8_t* data, uint16_t len)
  121. {
  122. uint32_t i;
  123. uint8_t chr;
  124. for (i=0; i<len; i++)
  125. {
  126. chr = data[i];
  127. switch(kiss_state) {
  128. case ESC_MODE: {
  129. if (chr == KISS_TFEND)
  130. {
  131. kiss_append_buffer(KISS_FEND); // append FEND to frame
  132. kiss_state = FRAME_ASS; // return to assembly
  133. }
  134. else if (chr == KISS_TFESC)
  135. {
  136. kiss_append_buffer(KISS_FESC); // append FESC to frame
  137. kiss_state = FRAME_ASS; // return to assembly
  138. }
  139. else if (chr == KISS_FEND)
  140. {
  141. kiss_process_frame(); // process frame
  142. kiss_state = FRAME_END; // end frame assembly
  143. }
  144. else
  145. {
  146. // log error
  147. kiss_append_buffer(chr); // append chr to frame
  148. kiss_state = FRAME_ASS; // return to assembly
  149. }
  150. break;
  151. }
  152. case FRAME_END: {
  153. if (chr != KISS_FEND)
  154. {
  155. kiss_append_buffer(chr); // append chr to frame
  156. kiss_state = FRAME_ASS; // return to assembly
  157. }
  158. else
  159. {
  160. kiss_state = FRAME_END; // stay in frame end
  161. }
  162. break;
  163. }
  164. case FRAME_ASS: {
  165. if (chr == KISS_FESC)
  166. {
  167. kiss_state = ESC_MODE;
  168. }
  169. else if (chr == KISS_FEND)
  170. {
  171. kiss_process_frame(); // process frame
  172. kiss_state = FRAME_END; // end frame assembly
  173. }
  174. else
  175. {
  176. kiss_append_buffer(chr); // append chr to frame
  177. kiss_state = FRAME_ASS; // continue frame assembly
  178. }
  179. break;
  180. default: {
  181. ESP_LOGE(TNC_TAG, "TNC FSM Error");
  182. }
  183. }
  184. }
  185. }
  186. }