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