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