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