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" 2853c9f6c0SAtsushi Murai #include "vars.h" 29af57ed9fSAtsushi Murai 30af57ed9fSAtsushi Murai #define HDLCSIZE (MAX_MRU*2+6) 31af57ed9fSAtsushi Murai 32af57ed9fSAtsushi Murai struct async_state { 33af57ed9fSAtsushi Murai int mode; 34af57ed9fSAtsushi Murai int length; 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; 5053c9f6c0SAtsushi Murai stp->length = 0; 51af57ed9fSAtsushi Murai stp->my_accmap = stp->his_accmap = 0xffffffff; 52af57ed9fSAtsushi Murai } 53af57ed9fSAtsushi Murai 54af57ed9fSAtsushi Murai void 55af57ed9fSAtsushi Murai SetLinkParams(lcp) 56af57ed9fSAtsushi Murai struct lcpstate *lcp; 57af57ed9fSAtsushi Murai { 58af57ed9fSAtsushi Murai struct async_state *stp = &AsyncState; 59af57ed9fSAtsushi Murai 60af57ed9fSAtsushi Murai stp->my_accmap = lcp->want_accmap; 61af57ed9fSAtsushi Murai stp->his_accmap = lcp->his_accmap; 62af57ed9fSAtsushi Murai } 63af57ed9fSAtsushi Murai 64af57ed9fSAtsushi Murai /* 65af57ed9fSAtsushi Murai * Encode into async HDLC byte code if necessary 66af57ed9fSAtsushi Murai */ 67af57ed9fSAtsushi Murai static void 68af57ed9fSAtsushi Murai HdlcPutByte(cp, c, proto) 69af57ed9fSAtsushi Murai u_char **cp; 70af57ed9fSAtsushi Murai u_char c; 71af57ed9fSAtsushi Murai int proto; 72af57ed9fSAtsushi Murai { 73af57ed9fSAtsushi Murai u_char *wp; 74af57ed9fSAtsushi Murai 75af57ed9fSAtsushi Murai wp = *cp; 76af57ed9fSAtsushi Murai if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1<<c)))) 77af57ed9fSAtsushi Murai || (c == HDLC_ESC) || (c == HDLC_SYN)) { 78af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 79af57ed9fSAtsushi Murai c ^= HDLC_XOR; 80af57ed9fSAtsushi Murai } 81af57ed9fSAtsushi Murai if (EscMap[32] && EscMap[c >> 3] & (c&7)) { 82af57ed9fSAtsushi Murai *wp++ = HDLC_ESC; 83af57ed9fSAtsushi Murai c ^= HDLC_XOR; 84af57ed9fSAtsushi Murai } 85af57ed9fSAtsushi Murai *wp++ = c; 86af57ed9fSAtsushi Murai *cp = wp; 87af57ed9fSAtsushi Murai } 88af57ed9fSAtsushi Murai 89af57ed9fSAtsushi Murai void 90af57ed9fSAtsushi Murai AsyncOutput(pri, bp, proto) 91af57ed9fSAtsushi Murai int pri; 92af57ed9fSAtsushi Murai struct mbuf *bp; 93af57ed9fSAtsushi Murai int proto; 94af57ed9fSAtsushi Murai { 95af57ed9fSAtsushi Murai struct async_state *hs = &AsyncState; 96af57ed9fSAtsushi Murai u_char *cp, *sp, *ep; 97af57ed9fSAtsushi Murai struct mbuf *wp; 98af57ed9fSAtsushi Murai int cnt; 99af57ed9fSAtsushi Murai 100af57ed9fSAtsushi Murai if (plength(bp) > HDLCSIZE) { 101af57ed9fSAtsushi Murai pfree(bp); 102af57ed9fSAtsushi Murai return; 103af57ed9fSAtsushi Murai } 104af57ed9fSAtsushi Murai cp = hs->xbuff; 105af57ed9fSAtsushi Murai ep = cp + HDLCSIZE - 10; 106af57ed9fSAtsushi Murai wp = bp; 107af57ed9fSAtsushi Murai *cp ++ = HDLC_SYN; 108af57ed9fSAtsushi Murai while (wp) { 109af57ed9fSAtsushi Murai sp = MBUF_CTOP(wp); 110af57ed9fSAtsushi Murai for (cnt = wp->cnt; cnt > 0; cnt--) { 111af57ed9fSAtsushi Murai HdlcPutByte(&cp, *sp++, proto); 112af57ed9fSAtsushi Murai if (cp >= ep) { 113af57ed9fSAtsushi Murai pfree(bp); 114af57ed9fSAtsushi Murai return; 115af57ed9fSAtsushi Murai } 116af57ed9fSAtsushi Murai } 117af57ed9fSAtsushi Murai wp = wp->next; 118af57ed9fSAtsushi Murai } 119af57ed9fSAtsushi Murai *cp ++ = HDLC_SYN; 120af57ed9fSAtsushi Murai 121af57ed9fSAtsushi Murai cnt = cp - hs->xbuff; 122af57ed9fSAtsushi Murai LogDumpBuff(LOG_ASYNC, "WriteModem", hs->xbuff, cnt); 123af57ed9fSAtsushi Murai WriteModem(pri, (char *)hs->xbuff, cnt); 124af57ed9fSAtsushi Murai OsAddOutOctets(cnt); 125af57ed9fSAtsushi Murai pfree(bp); 126af57ed9fSAtsushi Murai } 127af57ed9fSAtsushi Murai 128af57ed9fSAtsushi Murai struct mbuf * 129af57ed9fSAtsushi Murai AsyncDecode(c) 130af57ed9fSAtsushi Murai u_char c; 131af57ed9fSAtsushi Murai { 132af57ed9fSAtsushi Murai struct async_state *hs = &AsyncState; 133af57ed9fSAtsushi Murai struct mbuf *bp; 134af57ed9fSAtsushi Murai 135af57ed9fSAtsushi Murai if ((hs->mode & MODE_HUNT) && c != HDLC_SYN) 136af57ed9fSAtsushi Murai return(NULLBUFF); 137af57ed9fSAtsushi Murai 138af57ed9fSAtsushi Murai switch (c) { 139af57ed9fSAtsushi Murai case HDLC_SYN: 140af57ed9fSAtsushi Murai hs->mode &= ~MODE_HUNT; 141af57ed9fSAtsushi Murai if (hs->length) { /* packet is ready. */ 142af57ed9fSAtsushi Murai bp = mballoc(hs->length, MB_ASYNC); 143af57ed9fSAtsushi Murai mbwrite(bp, hs->hbuff, hs->length); 144af57ed9fSAtsushi Murai hs->length = 0; 145af57ed9fSAtsushi Murai return(bp); 146af57ed9fSAtsushi Murai } 147af57ed9fSAtsushi Murai break; 148af57ed9fSAtsushi Murai case HDLC_ESC: 149af57ed9fSAtsushi Murai if (!(hs->mode & MODE_ESC)) { 150af57ed9fSAtsushi Murai hs->mode |= MODE_ESC; 151af57ed9fSAtsushi Murai break; 152af57ed9fSAtsushi Murai } 153af57ed9fSAtsushi Murai /* Fall into ... */ 154af57ed9fSAtsushi Murai default: 155af57ed9fSAtsushi Murai if (hs->length >= HDLCSIZE) { 156af57ed9fSAtsushi Murai /* packet is too large, discard it */ 157af57ed9fSAtsushi Murai logprintf("too large, diacarding.\n"); 158af57ed9fSAtsushi Murai hs->length = 0; 159af57ed9fSAtsushi Murai hs->mode = MODE_HUNT; 160af57ed9fSAtsushi Murai break; 161af57ed9fSAtsushi Murai } 162af57ed9fSAtsushi Murai if (hs->mode & MODE_ESC) { 163af57ed9fSAtsushi Murai c ^= HDLC_XOR; 164af57ed9fSAtsushi Murai hs->mode &= ~MODE_ESC; 165af57ed9fSAtsushi Murai } 166af57ed9fSAtsushi Murai hs->hbuff[hs->length++] = c; 167af57ed9fSAtsushi Murai break; 168af57ed9fSAtsushi Murai } 169af57ed9fSAtsushi Murai return NULLBUFF; 170af57ed9fSAtsushi Murai } 171af57ed9fSAtsushi Murai 172af57ed9fSAtsushi Murai void 173af57ed9fSAtsushi Murai AsyncInput(buff, cnt) 174af57ed9fSAtsushi Murai u_char *buff; 175af57ed9fSAtsushi Murai int cnt; 176af57ed9fSAtsushi Murai { 177af57ed9fSAtsushi Murai struct mbuf *bp; 178af57ed9fSAtsushi Murai 179af57ed9fSAtsushi Murai OsAddInOctets(cnt); 18053c9f6c0SAtsushi Murai if (DEV_IS_SYNC) { 18153c9f6c0SAtsushi Murai bp = mballoc(cnt, MB_ASYNC); 18253c9f6c0SAtsushi Murai bcopy(buff, MBUF_CTOP(bp), cnt); 18353c9f6c0SAtsushi Murai bp->cnt = cnt; 18453c9f6c0SAtsushi Murai HdlcInput(bp); 18553c9f6c0SAtsushi Murai } else { 186af57ed9fSAtsushi Murai while (cnt > 0) { 187af57ed9fSAtsushi Murai bp = AsyncDecode(*buff++); 188af57ed9fSAtsushi Murai if (bp) 189af57ed9fSAtsushi Murai HdlcInput(bp); 190af57ed9fSAtsushi Murai cnt--; 191af57ed9fSAtsushi Murai } 192af57ed9fSAtsushi Murai } 19353c9f6c0SAtsushi Murai } 194