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
15static 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
46static 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
83struct 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
91static inline void slip_proto_init(struct slip_proto * slip)
92{
93	memset(slip->ibuf, 0, sizeof(slip->ibuf));
94	memset(slip->obuf, 0, sizeof(slip->obuf));
95	slip->more = 0;
96	slip->pos = 0;
97	slip->esc = 0;
98}
99
100extern int slip_proto_read(int fd, void *buf, int len,
101			   struct slip_proto *slip);
102extern int slip_proto_write(int fd, void *buf, int len,
103			    struct slip_proto *slip);
104
105#endif
106