18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __UM_SLIP_COMMON_H 38c2ecf20Sopenharmony_ci#define __UM_SLIP_COMMON_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#define BUF_SIZE 1500 68c2ecf20Sopenharmony_ci /* two bytes each for a (pathological) max packet of escaped chars + * 78c2ecf20Sopenharmony_ci * terminating END char + initial END char */ 88c2ecf20Sopenharmony_ci#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* SLIP protocol characters. */ 118c2ecf20Sopenharmony_ci#define SLIP_END 0300 /* indicates end of frame */ 128c2ecf20Sopenharmony_ci#define SLIP_ESC 0333 /* indicates byte stuffing */ 138c2ecf20Sopenharmony_ci#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ 148c2ecf20Sopenharmony_ci#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, 178c2ecf20Sopenharmony_ci int *esc) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci int ret; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci switch(c){ 228c2ecf20Sopenharmony_ci case SLIP_END: 238c2ecf20Sopenharmony_ci *esc = 0; 248c2ecf20Sopenharmony_ci ret=*pos; 258c2ecf20Sopenharmony_ci *pos=0; 268c2ecf20Sopenharmony_ci return(ret); 278c2ecf20Sopenharmony_ci case SLIP_ESC: 288c2ecf20Sopenharmony_ci *esc = 1; 298c2ecf20Sopenharmony_ci return(0); 308c2ecf20Sopenharmony_ci case SLIP_ESC_ESC: 318c2ecf20Sopenharmony_ci if(*esc){ 328c2ecf20Sopenharmony_ci *esc = 0; 338c2ecf20Sopenharmony_ci c = SLIP_ESC; 348c2ecf20Sopenharmony_ci } 358c2ecf20Sopenharmony_ci break; 368c2ecf20Sopenharmony_ci case SLIP_ESC_END: 378c2ecf20Sopenharmony_ci if(*esc){ 388c2ecf20Sopenharmony_ci *esc = 0; 398c2ecf20Sopenharmony_ci c = SLIP_END; 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci break; 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci buf[(*pos)++] = c; 448c2ecf20Sopenharmony_ci return(0); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic inline int slip_esc(unsigned char *s, unsigned char *d, int len) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci unsigned char *ptr = d; 508c2ecf20Sopenharmony_ci unsigned char c; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci /* 538c2ecf20Sopenharmony_ci * Send an initial END character to flush out any 548c2ecf20Sopenharmony_ci * data that may have accumulated in the receiver 558c2ecf20Sopenharmony_ci * due to line noise. 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci *ptr++ = SLIP_END; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci /* 618c2ecf20Sopenharmony_ci * For each byte in the packet, send the appropriate 628c2ecf20Sopenharmony_ci * character sequence, according to the SLIP protocol. 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci while (len-- > 0) { 668c2ecf20Sopenharmony_ci switch(c = *s++) { 678c2ecf20Sopenharmony_ci case SLIP_END: 688c2ecf20Sopenharmony_ci *ptr++ = SLIP_ESC; 698c2ecf20Sopenharmony_ci *ptr++ = SLIP_ESC_END; 708c2ecf20Sopenharmony_ci break; 718c2ecf20Sopenharmony_ci case SLIP_ESC: 728c2ecf20Sopenharmony_ci *ptr++ = SLIP_ESC; 738c2ecf20Sopenharmony_ci *ptr++ = SLIP_ESC_ESC; 748c2ecf20Sopenharmony_ci break; 758c2ecf20Sopenharmony_ci default: 768c2ecf20Sopenharmony_ci *ptr++ = c; 778c2ecf20Sopenharmony_ci break; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci *ptr++ = SLIP_END; 818c2ecf20Sopenharmony_ci return (ptr - d); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct slip_proto { 858c2ecf20Sopenharmony_ci unsigned char ibuf[ENC_BUF_SIZE]; 868c2ecf20Sopenharmony_ci unsigned char obuf[ENC_BUF_SIZE]; 878c2ecf20Sopenharmony_ci int more; /* more data: do not read fd until ibuf has been drained */ 888c2ecf20Sopenharmony_ci int pos; 898c2ecf20Sopenharmony_ci int esc; 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic inline void slip_proto_init(struct slip_proto * slip) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci memset(slip->ibuf, 0, sizeof(slip->ibuf)); 958c2ecf20Sopenharmony_ci memset(slip->obuf, 0, sizeof(slip->obuf)); 968c2ecf20Sopenharmony_ci slip->more = 0; 978c2ecf20Sopenharmony_ci slip->pos = 0; 988c2ecf20Sopenharmony_ci slip->esc = 0; 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ciextern int slip_proto_read(int fd, void *buf, int len, 1028c2ecf20Sopenharmony_ci struct slip_proto *slip); 1038c2ecf20Sopenharmony_ciextern int slip_proto_write(int fd, void *buf, int len, 1048c2ecf20Sopenharmony_ci struct slip_proto *slip); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci#endif 107