1af57ed9fSAtsushi Murai /* 2af57ed9fSAtsushi Murai * PPP Async HDLC Module 3af57ed9fSAtsushi Murai * 4af57ed9fSAtsushi Murai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5af57ed9fSAtsushi Murai * 6af57ed9fSAtsushi Murai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7af57ed9fSAtsushi Murai * 8af57ed9fSAtsushi Murai * Redistribution and use in source and binary forms are permitted 9af57ed9fSAtsushi Murai * provided that the above copyright notice and this paragraph are 10af57ed9fSAtsushi Murai * duplicated in all such forms and that any documentation, 11af57ed9fSAtsushi Murai * advertising materials, and other materials related to such 12af57ed9fSAtsushi Murai * distribution and use acknowledge that the software was developed 13af57ed9fSAtsushi Murai * by the Internet Initiative Japan, Inc. The name of the 14af57ed9fSAtsushi Murai * IIJ may not be used to endorse or promote products derived 15af57ed9fSAtsushi Murai * from this software without specific prior written permission. 16af57ed9fSAtsushi Murai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17af57ed9fSAtsushi Murai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18af57ed9fSAtsushi Murai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19af57ed9fSAtsushi Murai * 20af57ed9fSAtsushi Murai * $Id:$ 21af57ed9fSAtsushi Murai * 22af57ed9fSAtsushi Murai */ 23af57ed9fSAtsushi Murai #include "fsm.h" 24af57ed9fSAtsushi Murai #include "hdlc.h" 25af57ed9fSAtsushi Murai #include "lcp.h" 26af57ed9fSAtsushi Murai #include "lcpproto.h" 27af57ed9fSAtsushi Murai #include "modem.h" 28af57ed9fSAtsushi Murai 29af57ed9fSAtsushi Murai #define HDLCSIZE (MAX_MRU*2+6) 30af57ed9fSAtsushi Murai 31af57ed9fSAtsushi Murai struct async_state { 32af57ed9fSAtsushi Murai int mode; 33af57ed9fSAtsushi Murai int length; 34af57ed9fSAtsushi Murai struct mbuf *hpacket; 35af57ed9fSAtsushi Murai u_char hbuff[HDLCSIZE]; /* recv buffer */ 36af57ed9fSAtsushi Murai u_char xbuff[HDLCSIZE]; /* xmit buffer */ 37af57ed9fSAtsushi Murai u_long my_accmap; 38af57ed9fSAtsushi Murai u_long his_accmap; 39af57ed9fSAtsushi Murai } AsyncState; 40af57ed9fSAtsushi Murai 41af57ed9fSAtsushi Murai #define MODE_HUNT 0x01 42af57ed9fSAtsushi Murai #define MODE_ESC 0x02 43af57ed9fSAtsushi Murai 44af57ed9fSAtsushi Murai void 45af57ed9fSAtsushi Murai AsyncInit() 46af57ed9fSAtsushi Murai { 47af57ed9fSAtsushi Murai struct async_state *stp = &AsyncState; 48af57ed9fSAtsushi Murai 49af57ed9fSAtsushi Murai stp->mode = MODE_HUNT; 50af57ed9fSAtsushi Murai stp->my_accmap = stp->his_accmap = 0xffffffff; 51af57ed9fSAtsushi Murai } 52af57ed9fSAtsushi Murai 53af57ed9fSAtsushi Murai void 54af57ed9fSAtsushi Murai SetLinkParams(lcp) 55af57ed9fSAtsushi Murai struct lcpstate *lcp; 56af57ed9fSAtsushi Murai { 57af57ed9fSAtsushi Murai struct async_state *stp = &AsyncState; 58af57ed9fSAtsushi Murai 59af57ed9fSAtsushi Murai stp->my_accmap = lcp->want_accmap; 60af57ed9fSAtsushi Murai stp->his_accmap = lcp->his_accmap; 61af57ed9fSAtsushi Murai } 62af57ed9fSAtsushi Murai 63af57ed9fSAtsushi Murai /* 64af57ed9fSAtsushi Murai * Encode into async HDLC byte code if necessary 65af57ed9fSAtsushi Murai */ 66af57ed9fSAtsushi Murai static void 67af57ed9fSAtsushi Murai HdlcPutByte(cp, c, proto) 68af57ed9fSAtsushi Murai u_char **cp; 69af57ed9fSAtsushi Murai u_char c; 70af57ed9fSAtsushi Murai int proto; 71af57ed9fSAtsushi Murai { 72af57ed9fSAtsushi Murai u_char *wp; 73af57ed9fSAtsushi Murai 74af57ed9fSAtsushi Murai wp = *cp; 75af57ed9fSAtsushi Murai if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c)))) 76af57ed9fSAtsushi Murai || (c == HDLC_ESC) || (c == HDLC_SYN)) { 77af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 78af57ed9fSAtsushi Murai c ^= HDLC_XOR; 79af57ed9fSAtsushi Murai } 80af57ed9fSAtsushi Murai if (EscMap[32] && EscMap[c >> 3] & (c&7)) { 81af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 82af57ed9fSAtsushi Murai c ^= HDLC_XOR; 83af57ed9fSAtsushi Murai } 84af57ed9fSAtsushi Murai *wp++ = c; 85af57ed9fSAtsushi Murai *cp = wp; 86af57ed9fSAtsushi Murai } 87af57ed9fSAtsushi Murai 88af57ed9fSAtsushi Murai void 89af57ed9fSAtsushi Murai AsyncOutput(pri, bp, proto) 90af57ed9fSAtsushi Murai int pri; 91af57ed9fSAtsushi Murai struct mbuf *bp; 92af57ed9fSAtsushi Murai int proto; 93af57ed9fSAtsushi Murai { 94af57ed9fSAtsushi Murai struct async_state *hs = &AsyncState; 95af57ed9fSAtsushi Murai u_char *cp, *sp, *ep; 96af57ed9fSAtsushi Murai struct mbuf *wp; 97af57ed9fSAtsushi Murai int cnt; 98af57ed9fSAtsushi Murai 99af57ed9fSAtsushi Murai if (plength(bp) > HDLCSIZE) { 100af57ed9fSAtsushi Murai pfree(bp); 101af57ed9fSAtsushi Murai return; 102af57ed9fSAtsushi Murai } 103af57ed9fSAtsushi Murai cp = hs->xbuff; 104af57ed9fSAtsushi Murai ep = cp + HDLCSIZE - 10; 105af57ed9fSAtsushi Murai wp = bp; 106af57ed9fSAtsushi Murai *cp ++ = HDLC_SYN; 107af57ed9fSAtsushi Murai while (wp) { 108af57ed9fSAtsushi Murai sp = MBUF_CTOP(wp); 109af57ed9fSAtsushi Murai for (cnt = wp->cnt; cnt > 0; cnt--) { 110af57ed9fSAtsushi Murai HdlcPutByte(&cp, *sp++, proto); 111af57ed9fSAtsushi Murai if (cp >= ep) { 112af57ed9fSAtsushi Murai pfree(bp); 113af57ed9fSAtsushi Murai return; 114af57ed9fSAtsushi Murai } 115af57ed9fSAtsushi Murai } 116af57ed9fSAtsushi Murai wp = wp->next; 117af57ed9fSAtsushi Murai } 118af57ed9fSAtsushi Murai *cp ++ = HDLC_SYN; 119af57ed9fSAtsushi Murai 120af57ed9fSAtsushi Murai cnt = cp - hs->xbuff; 121af57ed9fSAtsushi Murai LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt); 122af57ed9fSAtsushi Murai WriteModem(pri, (char *)hs->xbuff, cnt); 123af57ed9fSAtsushi Murai OsAddOutOctets(cnt); 124af57ed9fSAtsushi Murai pfree(bp); 125af57ed9fSAtsushi Murai } 126af57ed9fSAtsushi Murai 127af57ed9fSAtsushi Murai struct mbuf * 128af57ed9fSAtsushi Murai AsyncDecode(c) 129af57ed9fSAtsushi Murai u_char c; 130af57ed9fSAtsushi Murai { 131af57ed9fSAtsushi Murai struct async_state *hs = &AsyncState; 132af57ed9fSAtsushi Murai struct mbuf *bp; 133af57ed9fSAtsushi Murai 134af57ed9fSAtsushi Murai if ((hs->mode & MODE_HUNT) && c != HDLC_SYN) 135af57ed9fSAtsushi Murai return(NULLBUFF); 136af57ed9fSAtsushi Murai 137af57ed9fSAtsushi Murai switch (c) { 138af57ed9fSAtsushi Murai case HDLC_SYN: 139af57ed9fSAtsushi Murai hs->mode &= ~MODE_HUNT; 140af57ed9fSAtsushi Murai if (hs->length) { /* packet is ready. */ 141af57ed9fSAtsushi Murai bp = mballoc(hs->length, MB_ASYNC); 142af57ed9fSAtsushi Murai mbwrite(bp, hs->hbuff, hs->length); 143af57ed9fSAtsushi Murai hs->length = 0; 144af57ed9fSAtsushi Murai return(bp); 145af57ed9fSAtsushi Murai } 146af57ed9fSAtsushi Murai break; 147af57ed9fSAtsushi Murai case HDLC_ESC: 148af57ed9fSAtsushi Murai if (!(hs->mode & MODE_ESC)) { 149af57ed9fSAtsushi Murai hs->mode |= MODE_ESC; 150af57ed9fSAtsushi Murai break; 151af57ed9fSAtsushi Murai } 152af57ed9fSAtsushi Murai /* Fall into ... */ 153af57ed9fSAtsushi Murai default: 154af57ed9fSAtsushi Murai if (hs->length >= HDLCSIZE) { 155af57ed9fSAtsushi Murai /* packet is too large, discard it */ 156af57ed9fSAtsushi Murai logprintf("too large, diacarding.\n"); 157af57ed9fSAtsushi Murai hs->length = 0; 158af57ed9fSAtsushi Murai hs->mode = MODE_HUNT; 159af57ed9fSAtsushi Murai break; 160af57ed9fSAtsushi Murai } 161af57ed9fSAtsushi Murai if (hs->mode & MODE_ESC) { 162af57ed9fSAtsushi Murai c ^= HDLC_XOR; 163af57ed9fSAtsushi Murai hs->mode &= ~MODE_ESC; 164af57ed9fSAtsushi Murai } 165af57ed9fSAtsushi Murai hs->hbuff[hs->length++] = c; 166af57ed9fSAtsushi Murai break; 167af57ed9fSAtsushi Murai } 168af57ed9fSAtsushi Murai return NULLBUFF; 169af57ed9fSAtsushi Murai } 170af57ed9fSAtsushi Murai 171af57ed9fSAtsushi Murai void 172af57ed9fSAtsushi Murai AsyncInput(buff, cnt) 173af57ed9fSAtsushi Murai u_char *buff; 174af57ed9fSAtsushi Murai int cnt; 175af57ed9fSAtsushi Murai { 176af57ed9fSAtsushi Murai struct mbuf *bp; 177af57ed9fSAtsushi Murai 178af57ed9fSAtsushi Murai OsAddInOctets(cnt); 179af57ed9fSAtsushi Murai while (cnt > 0) { 180af57ed9fSAtsushi Murai bp = AsyncDecode(*buff++); 181af57ed9fSAtsushi Murai if (bp) 182af57ed9fSAtsushi Murai HdlcInput(bp); 183af57ed9fSAtsushi Murai cnt--; 184af57ed9fSAtsushi Murai } 185af57ed9fSAtsushi Murai } 186