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