1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __UM_SLIP_COMMON_H |
3 | #define __UM_SLIP_COMMON_H |
4 | |
5 | #define BUF_SIZE 1500 |
6 | /* two bytes each for a (pathological) max packet of escaped chars + * |
7 | * terminating END char + initial END char */ |
8 | #define ENC_BUF_SIZE (2 * BUF_SIZE + 2) |
9 | |
10 | /* SLIP protocol characters. */ |
11 | #define SLIP_END 0300 /* indicates end of frame */ |
12 | #define SLIP_ESC 0333 /* indicates byte stuffing */ |
13 | #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ |
14 | #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ |
15 | |
16 | static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, |
17 | int *esc) |
18 | { |
19 | int ret; |
20 | |
21 | switch(c){ |
22 | case SLIP_END: |
23 | *esc = 0; |
24 | ret=*pos; |
25 | *pos=0; |
26 | return(ret); |
27 | case SLIP_ESC: |
28 | *esc = 1; |
29 | return(0); |
30 | case SLIP_ESC_ESC: |
31 | if(*esc){ |
32 | *esc = 0; |
33 | c = SLIP_ESC; |
34 | } |
35 | break; |
36 | case SLIP_ESC_END: |
37 | if(*esc){ |
38 | *esc = 0; |
39 | c = SLIP_END; |
40 | } |
41 | break; |
42 | } |
43 | buf[(*pos)++] = c; |
44 | return(0); |
45 | } |
46 | |
47 | static inline int slip_esc(unsigned char *s, unsigned char *d, int len) |
48 | { |
49 | unsigned char *ptr = d; |
50 | unsigned char c; |
51 | |
52 | /* |
53 | * Send an initial END character to flush out any |
54 | * data that may have accumulated in the receiver |
55 | * due to line noise. |
56 | */ |
57 | |
58 | *ptr++ = SLIP_END; |
59 | |
60 | /* |
61 | * For each byte in the packet, send the appropriate |
62 | * character sequence, according to the SLIP protocol. |
63 | */ |
64 | |
65 | while (len-- > 0) { |
66 | switch(c = *s++) { |
67 | case SLIP_END: |
68 | *ptr++ = SLIP_ESC; |
69 | *ptr++ = SLIP_ESC_END; |
70 | break; |
71 | case SLIP_ESC: |
72 | *ptr++ = SLIP_ESC; |
73 | *ptr++ = SLIP_ESC_ESC; |
74 | break; |
75 | default: |
76 | *ptr++ = c; |
77 | break; |
78 | } |
79 | } |
80 | *ptr++ = SLIP_END; |
81 | return (ptr - d); |
82 | } |
83 | |
84 | struct slip_proto { |
85 | unsigned char ibuf[ENC_BUF_SIZE]; |
86 | unsigned char obuf[ENC_BUF_SIZE]; |
87 | int more; /* more data: do not read fd until ibuf has been drained */ |
88 | int pos; |
89 | int esc; |
90 | }; |
91 | |
92 | static inline void slip_proto_init(struct slip_proto * slip) |
93 | { |
94 | memset(slip->ibuf, 0, sizeof(slip->ibuf)); |
95 | memset(slip->obuf, 0, sizeof(slip->obuf)); |
96 | slip->more = 0; |
97 | slip->pos = 0; |
98 | slip->esc = 0; |
99 | } |
100 | |
101 | extern int slip_proto_read(int fd, void *buf, int len, |
102 | struct slip_proto *slip); |
103 | extern int slip_proto_write(int fd, void *buf, int len, |
104 | struct slip_proto *slip); |
105 | |
106 | #endif |
107 | |