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