diff options
Diffstat (limited to 'ax25ipd/kiss.c')
-rw-r--r-- | ax25ipd/kiss.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/ax25ipd/kiss.c b/ax25ipd/kiss.c new file mode 100644 index 0000000..6042cf0 --- /dev/null +++ b/ax25ipd/kiss.c @@ -0,0 +1,201 @@ +/* kiss.c KISS assembly and byte-stuffing stuff + * + * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc. + * This software may be freely used, distributed, or modified, providing + * this header is not removed. + * + * This is the only module that knows about the internal structure of + * KISS frames. + */ + +/* + * dual port changes Feb 95 ve3pnx & ve3djf + */ + +#include <stdio.h> +#include "ax25ipd.h" + +#define FEND 0xc0 +#define FESC 0xdb +#define TFEND 0xdc +#define TFESC 0xdd + +unsigned char iframe[MAX_FRAME]; +unsigned char *ifptr; +int ifcount; +int iescaped; + +unsigned char oframe[MAX_FRAME]; +unsigned char *ofptr; +int ofcount; + +#define PTABLE_SIZE 10 + +struct param_table_entry { + unsigned char parameter; + unsigned char value; +} param_tbl[PTABLE_SIZE]; + +int param_tbl_top; + + +/* + * Initialize the KISS variables + */ + +void +kiss_init() +{ + ifptr = iframe; + ifcount = 0; + iescaped = 0; + ofptr = oframe; + ofcount = 0; + param_tbl_top = 0; +} + +/* + * Assemble a kiss frame from random hunks of incoming data + * Calls the "from_kiss" routine with the kiss frame when a + * frame has been assembled. + */ + +void +assemble_kiss(buf, l) +unsigned char *buf; +int l; +{ + int i; + unsigned char c; + + for(i=0;i<l;i++,buf++){ + c = *buf; + if(c==FEND){ + if(ifcount>0){ + /* Make sure that the control byte is zero */ + if(*iframe=='\0' || *iframe==0x10) { + /* Room for CRC in buffer? */ + if(ifcount < (MAX_FRAME - 2)) { + stats.kiss_in++; + from_kiss(iframe+1,ifcount-1); + } else { + stats.kiss_toobig++; + LOGL2("assemble_kiss: dumped - frame too large\n"); + } + } else { + stats.kiss_badtype++; + LOGL2("assemble_kiss: dumped - control byte non-zero\n"); + } + } + ifcount = 0; + iescaped = 0; + ifptr = iframe; + continue; + } + if(c==FESC){ + iescaped=1; + continue; + } + if(iescaped){ + if(c==TFEND)c = FEND; + if(c==TFESC)c = FESC; + iescaped = 0; + } + if(ifcount < MAX_FRAME){ + *ifptr = c; + ifptr++; + ifcount++; + } + } /* for every character in the buffer */ +} + +/* convert a standard AX25 frame into a kiss frame */ +void +send_kiss(type, buf, l) +unsigned char type; +unsigned char *buf; +int l; +{ +#define KISSEMIT(x) if(ofcount<MAX_FRAME){*ofptr=(x);ofptr++;ofcount++;} + + int i; + + ofptr = oframe; + ofcount = 0; + + KISSEMIT(FEND); + + if(type==FEND){ + KISSEMIT(FESC); + KISSEMIT(TFEND); + }else if (type==FESC){ + KISSEMIT(FESC); + KISSEMIT(TFESC); + }else { + KISSEMIT(type); + } + + for(i=0;i<l;i++,buf++){ + if(*buf==FEND){ + KISSEMIT(FESC); + KISSEMIT(TFEND); + }else if (*buf==FESC){ + KISSEMIT(FESC); + KISSEMIT(TFESC); + }else { + KISSEMIT(*buf); + } + } /* for each character in the incoming AX25 frame */ + + KISSEMIT(FEND); + + send_tty(oframe, ofcount); +} + +/* Add an entry to the parameter table */ +void +param_add(p, v) +int p; +int v; +{ + if(param_tbl_top >= PTABLE_SIZE){ + fprintf(stderr,"param table is full; entry ignored.\n"); + } + param_tbl[param_tbl_top].parameter = p&0xff; + param_tbl[param_tbl_top].value = v&0xff; + LOGL4("added param: %d\t%d\n", + param_tbl[param_tbl_top].parameter, + param_tbl[param_tbl_top].value); + param_tbl_top++; + return; +} + +/* dump the contents of the parameter table */ +void +dump_params() +{ + int i; + + LOGL1("\n%d parameters\n",param_tbl_top); + for(i=0;i<param_tbl_top;i++){ + LOGL1(" %d\t%d\n", + param_tbl[i].parameter, + param_tbl[i].value); + } + fflush(stdout); +} + +/* send the parameters to the TNC */ +void +send_params() +{ + int i; + unsigned char p, v; + + for(i=0;i<param_tbl_top;i++){ + p = param_tbl[i].parameter; + v = param_tbl[i].value; + send_kiss(p, &v, 1); + LOGL2("send_params: param %d %d\n",p,v); + } +} |