1 /*
2  * SPDX-FileCopyrightText: 2016 Cesanta Software Limited
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  *
6  * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD
7  */
8 
9 #include <stdint.h>
10 #include "slip.h"
11 #include "stub_io.h"
12 
SLIP_send_frame_delimiter(void)13 void SLIP_send_frame_delimiter(void) {
14   stub_tx_one_char('\xc0');
15 }
16 
SLIP_send_frame_data(char ch)17 void SLIP_send_frame_data(char ch) {
18   if(ch == '\xc0') {
19 	stub_tx_one_char('\xdb');
20 	stub_tx_one_char('\xdc');
21   } else if (ch == '\xdb') {
22 	stub_tx_one_char('\xdb');
23 	stub_tx_one_char('\xdd');
24   } else {
25 	stub_tx_one_char(ch);
26   }
27 }
28 
SLIP_send_frame_data_buf(const void * buf,uint32_t size)29 void SLIP_send_frame_data_buf(const void *buf, uint32_t size) {
30   const uint8_t *buf_c = (const uint8_t *)buf;
31   for(int i = 0; i < size; i++) {
32 	SLIP_send_frame_data(buf_c[i]);
33   }
34 }
35 
SLIP_send(const void * pkt,uint32_t size)36 void SLIP_send(const void *pkt, uint32_t size) {
37   SLIP_send_frame_delimiter();
38   SLIP_send_frame_data_buf(pkt, size);
39   SLIP_send_frame_delimiter();
40 }
41 
SLIP_recv_byte(char byte,slip_state_t * state)42 int16_t SLIP_recv_byte(char byte, slip_state_t *state)
43 {
44   if (byte == '\xc0') {
45 	if (*state == SLIP_NO_FRAME) {
46 	  *state = SLIP_FRAME;
47 	  return SLIP_NO_BYTE;
48 	} else {
49 	  *state = SLIP_NO_FRAME;
50 	  return SLIP_FINISHED_FRAME;
51 	}
52   }
53 
54   switch(*state) {
55   case SLIP_NO_FRAME:
56 	return SLIP_NO_BYTE;
57   case SLIP_FRAME:
58 	if (byte == '\xdb') {
59 	  *state = SLIP_FRAME_ESCAPING;
60 	  return SLIP_NO_BYTE;
61 	}
62 	return byte;
63   case SLIP_FRAME_ESCAPING:
64 	if (byte == '\xdc') {
65 	  *state = SLIP_FRAME;
66 	  return '\xc0';
67 	}
68 	if (byte == '\xdd') {
69 	  *state = SLIP_FRAME;
70 	  return '\xdb';
71 	}
72 	return SLIP_NO_BYTE; /* actually a framing error */
73   }
74   return SLIP_NO_BYTE; /* actually a framing error */
75 }
76 
77 /* This function is needed for the synchornous I/O case,
78  * which is only flash_read command at the moment.
79  */
SLIP_recv(void * pkt,uint32_t max_len)80 uint32_t SLIP_recv(void *pkt, uint32_t max_len) {
81   uint32_t len = 0;
82   slip_state_t state = SLIP_NO_FRAME;
83   uint8_t *p = (uint8_t *) pkt;
84 
85   int16_t r;
86   do {
87 	r = SLIP_recv_byte(stub_rx_one_char(), &state);
88 	if(r >= 0 && len < max_len) {
89 	  p[len++] = (uint8_t)r;
90 	}
91   } while(r != SLIP_FINISHED_FRAME);
92 
93   return len;
94 }
95