async.c revision 6059
1151497Sru/* 2151497Sru * PPP Async HDLC Module 3151497Sru * 4151497Sru * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5151497Sru * 6151497Sru * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7151497Sru * 8151497Sru * Redistribution and use in source and binary forms are permitted 9151497Sru * provided that the above copyright notice and this paragraph are 10151497Sru * duplicated in all such forms and that any documentation, 11151497Sru * advertising materials, and other materials related to such 12151497Sru * distribution and use acknowledge that the software was developed 13151497Sru * by the Internet Initiative Japan, Inc. The name of the 14151497Sru * IIJ may not be used to endorse or promote products derived 15151497Sru * from this software without specific prior written permission. 16151497Sru * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17151497Sru * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18151497Sru * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19151497Sru * 20151497Sru * $Id:$ 21151497Sru * 22151497Sru */ 23151497Sru#include "fsm.h" 24151497Sru#include "hdlc.h" 25151497Sru#include "lcp.h" 26151497Sru#include "lcpproto.h" 27151497Sru#include "modem.h" 28151497Sru 29151497Sru#define HDLCSIZE (MAX_MRU*2+6) 30151497Sru 31151497Srustruct async_state { 32151497Sru int mode; 33151497Sru int length; 34151497Sru struct mbuf *hpacket; 35151497Sru u_char hbuff[HDLCSIZE]; /* recv buffer */ 36151497Sru u_char xbuff[HDLCSIZE]; /* xmit buffer */ 37151497Sru u_long my_accmap; 38151497Sru u_long his_accmap; 39151497Sru} AsyncState; 40151497Sru 41151497Sru#define MODE_HUNT 0x01 42151497Sru#define MODE_ESC 0x02 43151497Sru 44151497Sruvoid 45151497SruAsyncInit() 46151497Sru{ 47151497Sru struct async_state *stp = &AsyncState; 48151497Sru 49151497Sru stp->mode = MODE_HUNT; 50151497Sru stp->my_accmap = stp->his_accmap = 0xffffffff; 51151497Sru} 52151497Sru 53151497Sruvoid 54151497SruSetLinkParams(lcp) 55151497Srustruct lcpstate *lcp; 56151497Sru{ 57151497Sru struct async_state *stp = &AsyncState; 58151497Sru 59151497Sru stp->my_accmap = lcp->want_accmap; 60151497Sru stp->his_accmap = lcp->his_accmap; 61151497Sru} 62151497Sru 63151497Sru/* 64151497Sru * Encode into async HDLC byte code if necessary 65151497Sru */ 66151497Srustatic void 67151497SruHdlcPutByte(cp, c, proto) 68151497Sruu_char **cp; 69151497Sruu_char c; 70151497Sruint proto; 71151497Sru{ 72151497Sru u_char *wp; 73151497Sru 74151497Sru wp = *cp; 75151497Sru if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c)))) 76151497Sru || (c == HDLC_ESC) || (c == HDLC_SYN)) { 77151497Sru *wp++ = HDLC_ESC; 78151497Sru c ^= HDLC_XOR; 79151497Sru } 80151497Sru if (EscMap[32] && EscMap[c >> 3] & (c&7)) { 81151497Sru *wp++ = HDLC_ESC; 82151497Sru c ^= HDLC_XOR; 83151497Sru } 84151497Sru *wp++ = c; 85151497Sru *cp = wp; 86151497Sru} 87151497Sru 88151497Sruvoid 89151497SruAsyncOutput(pri, bp, proto) 90151497Sruint pri; 91151497Srustruct mbuf *bp; 92151497Sruint proto; 93151497Sru{ 94151497Sru struct async_state *hs = &AsyncState; 95151497Sru u_char *cp, *sp, *ep; 96151497Sru struct mbuf *wp; 97151497Sru int cnt; 98151497Sru 99151497Sru if (plength(bp) > HDLCSIZE) { 100151497Sru pfree(bp); 101151497Sru return; 102151497Sru } 103151497Sru cp = hs->xbuff; 104151497Sru ep = cp + HDLCSIZE - 10; 105151497Sru wp = bp; 106151497Sru *cp ++ = HDLC_SYN; 107151497Sru while (wp) { 108151497Sru sp = MBUF_CTOP(wp); 109151497Sru for (cnt = wp->cnt; cnt > 0; cnt--) { 110151497Sru HdlcPutByte(&cp, *sp++, proto); 111151497Sru if (cp >= ep) { 112151497Sru pfree(bp); 113151497Sru return; 114151497Sru } 115151497Sru } 116151497Sru wp = wp->next; 117151497Sru } 118151497Sru *cp ++ = HDLC_SYN; 119151497Sru 120151497Sru cnt = cp - hs->xbuff; 121151497Sru LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt); 122151497Sru WriteModem(pri, (char *)hs->xbuff, cnt); 123151497Sru OsAddOutOctets(cnt); 124151497Sru pfree(bp); 125151497Sru} 126151497Sru 127151497Srustruct mbuf * 128151497SruAsyncDecode(c) 129151497Sruu_char c; 130151497Sru{ 131151497Sru struct async_state *hs = &AsyncState; 132151497Sru struct mbuf *bp; 133151497Sru 134151497Sru if ((hs->mode & MODE_HUNT) && c != HDLC_SYN) 135151497Sru return(NULLBUFF); 136151497Sru 137151497Sru switch (c) { 138151497Sru case HDLC_SYN: 139151497Sru hs->mode &= ~MODE_HUNT; 140151497Sru if (hs->length) { /* packet is ready. */ 141151497Sru bp = mballoc(hs->length, MB_ASYNC); 142151497Sru mbwrite(bp, hs->hbuff, hs->length); 143151497Sru hs->length = 0; 144151497Sru return(bp); 145151497Sru } 146151497Sru break; 147151497Sru case HDLC_ESC: 148151497Sru if (!(hs->mode & MODE_ESC)) { 149151497Sru hs->mode |= MODE_ESC; 150151497Sru break; 151151497Sru } 152151497Sru /* Fall into ... */ 153151497Sru default: 154151497Sru if (hs->length >= HDLCSIZE) { 155151497Sru /* packet is too large, discard it */ 156151497Sru logprintf("too large, diacarding.\n"); 157151497Sru hs->length = 0; 158151497Sru hs->mode = MODE_HUNT; 159151497Sru break; 160151497Sru } 161151497Sru if (hs->mode & MODE_ESC) { 162151497Sru c ^= HDLC_XOR; 163151497Sru hs->mode &= ~MODE_ESC; 164151497Sru } 165151497Sru hs->hbuff[hs->length++] = c; 166151497Sru break; 167151497Sru } 168151497Sru return NULLBUFF; 169151497Sru} 170151497Sru 171151497Sruvoid 172151497SruAsyncInput(buff, cnt) 173151497Sruu_char *buff; 174151497Sruint cnt; 175151497Sru{ 176151497Sru struct mbuf *bp; 177151497Sru 178151497Sru OsAddInOctets(cnt); 179151497Sru while (cnt > 0) { 180151497Sru bp = AsyncDecode(*buff++); 181151497Sru if (bp) 182151497Sru HdlcInput(bp); 183151497Sru cnt--; 184151497Sru } 185151497Sru} 186151497Sru