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