summaryrefslogtreecommitdiffstats
path: root/ax25ipd/kiss.c
diff options
context:
space:
mode:
Diffstat (limited to 'ax25ipd/kiss.c')
-rw-r--r--ax25ipd/kiss.c201
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);
+ }
+}