async.c revision 6735
119304Speter/* 219304Speter * PPP Async HDLC Module 319304Speter * 419304Speter * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 519304Speter * 619304Speter * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 719304Speter * 819304Speter * Redistribution and use in source and binary forms are permitted 919304Speter * provided that the above copyright notice and this paragraph are 1019304Speter * duplicated in all such forms and that any documentation, 1119304Speter * advertising materials, and other materials related to such 1219304Speter * distribution and use acknowledge that the software was developed 13254225Speter * by the Internet Initiative Japan, Inc. The name of the 1419304Speter * IIJ may not be used to endorse or promote products derived 1519304Speter * from this software without specific prior written permission. 1619304Speter * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1719304Speter * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1819304Speter * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1919304Speter * 2019304Speter * $Id:$ 2119304Speter * 2219304Speter */ 2319304Speter#include "fsm.h" 2419304Speter#include "hdlc.h" 2519304Speter#include "lcp.h" 2619304Speter#include "lcpproto.h" 2719304Speter#include "modem.h" 2819304Speter#include "vars.h" 2919304Speter 3019304Speter#define HDLCSIZE (MAX_MRU*2+6) 31281373Sbapt 3219304Speterstruct async_state { 3319304Speter int mode; 34254225Speter int length; 3519304Speter u_char hbuff[HDLCSIZE]; /* recv buffer */ 3619304Speter u_char xbuff[HDLCSIZE]; /* xmit buffer */ 3719304Speter u_long my_accmap; 3819304Speter u_long his_accmap; 3919304Speter} AsyncState; 4019304Speter 4119304Speter#define MODE_HUNT 0x01 4219304Speter#define MODE_ESC 0x02 4319304Speter 4419304Spetervoid 4519304SpeterAsyncInit() 4619304Speter{ 4719304Speter struct async_state *stp = &AsyncState; 4819304Speter 4919304Speter stp->mode = MODE_HUNT; 5019304Speter stp->length = 0; 5119304Speter stp->my_accmap = stp->his_accmap = 0xffffffff; 5219304Speter} 5319304Speter 5419304Spetervoid 5519304SpeterSetLinkParams(lcp) 5619304Speterstruct lcpstate *lcp; 5719304Speter{ 5819304Speter struct async_state *stp = &AsyncState; 5919304Speter 6019304Speter stp->my_accmap = lcp->want_accmap; 6119304Speter stp->his_accmap = lcp->his_accmap; 6219304Speter} 6319304Speter 6419304Speter/* 6519304Speter * Encode into async HDLC byte code if necessary 6619304Speter */ 6719304Speterstatic void 6819304SpeterHdlcPutByte(cp, c, proto) 6919304Speteru_char **cp; 7019304Speteru_char c; 7119304Speterint proto; 7219304Speter{ 7319304Speter u_char *wp; 7419304Speter 7519304Speter wp = *cp; 7619304Speter if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c)))) 7719304Speter || (c == HDLC_ESC) || (c == HDLC_SYN)) { 78281373Sbapt *wp++ = HDLC_ESC; 7919304Speter c ^= HDLC_XOR; 8019304Speter } 81254225Speter if (EscMap[32] && EscMap[c >> 3] & (c&7)) { 8219304Speter *wp++ = HDLC_ESC; 8319304Speter c ^= HDLC_XOR; 8419304Speter } 8519304Speter *wp++ = c; 8619304Speter *cp = wp; 8719304Speter} 8819304Speter 8919304Spetervoid 9019304SpeterAsyncOutput(pri, bp, proto) 9119304Speterint pri; 9219304Speterstruct mbuf *bp; 9319304Speterint proto; 9419304Speter{ 9519304Speter struct async_state *hs = &AsyncState; 9619304Speter u_char *cp, *sp, *ep; 9719304Speter struct mbuf *wp; 9819304Speter int cnt; 9919304Speter 10019304Speter if (plength(bp) > HDLCSIZE) { 10119304Speter pfree(bp); 10219304Speter return; 10319304Speter } 104 cp = hs->xbuff; 105 ep = cp + HDLCSIZE - 10; 106 wp = bp; 107 *cp ++ = HDLC_SYN; 108 while (wp) { 109 sp = MBUF_CTOP(wp); 110 for (cnt = wp->cnt; cnt > 0; cnt--) { 111 HdlcPutByte(&cp, *sp++, proto); 112 if (cp >= ep) { 113 pfree(bp); 114 return; 115 } 116 } 117 wp = wp->next; 118 } 119 *cp ++ = HDLC_SYN; 120 121 cnt = cp - hs->xbuff; 122 LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt); 123 WriteModem(pri, (char *)hs->xbuff, cnt); 124 OsAddOutOctets(cnt); 125 pfree(bp); 126} 127 128struct mbuf * 129AsyncDecode(c) 130u_char c; 131{ 132 struct async_state *hs = &AsyncState; 133 struct mbuf *bp; 134 135 if ((hs->mode & MODE_HUNT) && c != HDLC_SYN) 136 return(NULLBUFF); 137 138 switch (c) { 139 case HDLC_SYN: 140 hs->mode &= ~MODE_HUNT; 141 if (hs->length) { /* packet is ready. */ 142 bp = mballoc(hs->length, MB_ASYNC); 143 mbwrite(bp, hs->hbuff, hs->length); 144 hs->length = 0; 145 return(bp); 146 } 147 break; 148 case HDLC_ESC: 149 if (!(hs->mode & MODE_ESC)) { 150 hs->mode |= MODE_ESC; 151 break; 152 } 153 /* Fall into ... */ 154 default: 155 if (hs->length >= HDLCSIZE) { 156 /* packet is too large, discard it */ 157 logprintf("too large, diacarding.\n"); 158 hs->length = 0; 159 hs->mode = MODE_HUNT; 160 break; 161 } 162 if (hs->mode & MODE_ESC) { 163 c ^= HDLC_XOR; 164 hs->mode &= ~MODE_ESC; 165 } 166 hs->hbuff[hs->length++] = c; 167 break; 168 } 169 return NULLBUFF; 170} 171 172void 173AsyncInput(buff, cnt) 174u_char *buff; 175int cnt; 176{ 177 struct mbuf *bp; 178 179 OsAddInOctets(cnt); 180 if (DEV_IS_SYNC) { 181 bp = mballoc(cnt, MB_ASYNC); 182 bcopy(buff, MBUF_CTOP(bp), cnt); 183 bp->cnt = cnt; 184 HdlcInput(bp); 185 } else { 186 while (cnt > 0) { 187 bp = AsyncDecode(*buff++); 188 if (bp) 189 HdlcInput(bp); 190 cnt--; 191 } 192 } 193} 194