On Thu, 11 Apr 2002, Tim Woodall wrote:

> On Thu, 11 Apr 2002, Tim Woodall wrote:
> 
> Been looking at the rp-pppoe code. It was the async stuff I was thinking of.
> 
> Interestingly, in the rp-pppoe code, one of the suggestions it makes for
> slow machines is to use async instead of sync. So I might stea^H^H^H^Hadapt
> the code from rp to see if it makes any difference.
> 
<snip diff listing>
This is irrelevant for pppoa3. rp is using select and the bug isn't that
read blocks for ever, just that read blocks when rp doesn't want it to.

pppoa3 wants read to block when there is no data.

However, I have got the async ppp stuff working :-)

(cribbed from rp-pppoe)

Unfortunately, it hasn't fixed my problem :-(

Regards,

Tim.

[tim@pauli /home/tim/cvs/speedtouch/src]$ cvs diff pppoa3.c
Index: pppoa3.c
===================================================================
RCS file: /cvsroot/speedtouch/speedtouch/src/pppoa3.c,v
retrieving revision 1.20
diff -u -r1.20 pppoa3.c
--- pppoa3.c    20 Mar 2002 09:26:46 -0000      1.20
+++ pppoa3.c    11 Apr 2002 21:52:09 -0000
@@ -26,6 +26,8 @@
 #ifndef _PPPOA3_C_
 #define _PPPOA3_C_
 
+#define TIMS
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -82,6 +84,78 @@
 /* Some constants */
 #include "pppoa3.h"
 
+static unsigned short fcstab[256] = {
+    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/**********************************************************************
+*%FUNCTION: pppFCS16
+*%ARGUMENTS:
+* fcs -- current fcs
+* cp -- a buffer's worth of data
+* len -- length of buffer "cp"
+*%RETURNS:
+* A new FCS
+*%DESCRIPTION:
+* Updates the PPP FCS.
+***********************************************************************/
+static unsigned short pppFCS16(unsigned short fcs, 
+        unsigned char * cp, 
+        int len)
+{
+    while (len--)
+       fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
+    
+    return (fcs);
+}
+
+/* States for scanning PPP frames */
+#define STATE_WAITFOR_FRAME_ADDR 0
+#define STATE_DROP_PROTO         1
+#define STATE_BUILDING_PACKET    2
+
+/* Special PPP frame characters */
+#define FRAME_ESC    0x7D
+#define FRAME_FLAG   0x7E
+#define FRAME_ADDR   0xFF
+#define FRAME_CTRL   0x03
+#define FRAME_ENC    0x20
+
+#define PPPINITFCS16    0xffff  /* Initial FCS value */
+
+#define ASYNC_BUF_SIZE 1024
+
 /******************************************************************************
 * Local Prototypes
 ******************************************************************************/
@@ -209,7 +283,7 @@
 static pthread_mutex_t report_mutex;
 
 /* Reading and writing buffers */
-#define syncHDLC 1
+#define syncHDLC 0
 #define BUFFER_SIZE (64*1024)
 #define HDLC_HEADER_SIZE 2
 
@@ -490,6 +564,7 @@
 
        if(isatty(STDIN_FILENO)) {
 #ifdef N_HDLC
+#if syncHDLC
                int disc = N_HDLC;
 
                if(ioctl(STDIN_FILENO, TIOCSETD, &disc) < 0) {
@@ -497,7 +572,7 @@
                        return(-1);
                }
                report(2, REPORT_DEBUG|REPORT_DATE, "N_HDLC line set up\n");
-
+#endif
 #elif defined TTYDISC
                int disc = TTYDISC;
 
@@ -1050,6 +1125,238 @@
 
 }
 
+
+#ifdef TIMS
+
+/*
+* Function     : ppp_read
+* Return value : data read length
+* Description  : Reads size bytes from fd and put them in the buffer
+*                It sync hdlc 
+*/
+
+static int ppp_read(int fd, unsigned char *buffer, int size)
+{
+
+       /*
+       * we must handle HDLC framing, since this is what pppd
+       * sends to us. I use some code from rp-pppoe
+       */
+
+       if(size > BUFFER_SIZE) {
+               report(0, REPORT_ERROR|REPORT_DATE, "Error %d bytes requested but the 
+buffer is %d bytes long\n", size, BUFFER_SIZE);
+               return(0);
+       }
+
+       for(;;) {
+
+               /* supress leading 2 bytes */
+               if(syncHDLC) {
+
+                       int r;
+
+                       do {
+                               r = read(fd, buffer, size);
+                       } while(r < 0 && errno == EINTR);
+
+                       if(r < 0) {
+                               report(0, REPORT_ERROR|REPORT_DATE|REPORT_PERROR, 
+"Error reading from pppd\n");
+                               return(-1);
+                       }
+
+                       if(!r)
+                               return(0);
+
+                       if(r < 3) {
+                               report(0, REPORT_ERROR|REPORT_DATE, "Read from ppp 
+short on data, r=%d => ignored\n", r);
+                               continue;
+                       }
+
+                       if(r == BUFFER_SIZE) {
+                               report(0, REPORT_ERROR|REPORT_DATE, "Read from ppp too 
+much data, r=%d => ignored\n", r);
+                               continue;
+                       }
+
+                       return(r - HDLC_HEADER_SIZE);
+
+               }
+               else {
+                   static int data=0;
+                   static unsigned char async_buf[ASYNC_BUF_SIZE];
+                   static unsigned char* ptr = async_buf;
+                   static int PPPState=STATE_WAITFOR_FRAME_ADDR;
+                   static int PPPPacketSize=0;
+                   static int PPPXorValue=0;
+                   
+                   if(!data) {
+                       ptr = async_buf;
+
+                       do {
+                               data = read(fd, async_buf, ASYNC_BUF_SIZE);
+                       } while(data < 0 && errno == EINTR);
+
+                       if(data < 0) {
+                           report(0, REPORT_ERROR|REPORT_DATE|REPORT_PERROR, "Error 
+reading from pppd\n");
+                           return(-1);
+                       }
+
+                       if(!data)
+                           return(0);
+                       report(2, REPORT_DEBUG|REPORT_DATE|REPORT_DUMP, "PPP packet 
+read from ppp(d) (%d bytes long)\n", async_buf, data, data);
+                   }
+
+                   /* ASSERT data>0 here */
+                   --data;
+                   
+                   if(PPPState == STATE_WAITFOR_FRAME_ADDR) {
+                       if (*ptr++ == FRAME_ADDR) {
+                           PPPState = STATE_DROP_PROTO;
+                           PPPPacketSize = 0;
+                           PPPXorValue = 0;
+                       }
+                   }
+                   
+                   if(PPPState == STATE_DROP_PROTO) {
+                       if (*ptr++ == (FRAME_CTRL ^ FRAME_ENC)) {
+                           PPPState = STATE_BUILDING_PACKET;
+                       }
+                   }
+
+                   /* Start building frame */
+                   if(PPPState == STATE_BUILDING_PACKET) {
+                       unsigned char c = *ptr++;
+                       switch(c) {
+                       case FRAME_ESC:
+                           PPPXorValue = FRAME_ENC;
+                           break;
+                       case FRAME_FLAG:
+                           PPPState = STATE_WAITFOR_FRAME_ADDR;
+                           if (PPPPacketSize < 2) {
+                               report(0, REPORT_ERROR|REPORT_DATE, "Read from ppp 
+short on data, PPPPacketSize=%d => ignored\n", PPPPacketSize);
+                               break;
+                           }
+                           return PPPPacketSize-2;
+                       default:
+                           if(PPPPacketSize == BUFFER_SIZE-HDLC_HEADER_SIZE) {
+                               report(0, REPORT_ERROR|REPORT_DATE, "Read from ppp too 
+much data, PPPPacketSize=%d => ignored\n", PPPPacketSize);
+                               PPPState = STATE_WAITFOR_FRAME_ADDR;
+                               break;
+                           }
+                           buffer[2+PPPPacketSize++] = c ^ PPPXorValue;
+                           PPPXorValue = 0;
+                       }
+                   }
+               }
+
+       }
+
+}
+
+/*
+* Function     : ppp_write
+* Return value : data written length
+* Description  : Writes size bytes to fd
+*/
+
+#define NOBUF_RETRIES 5
+static int ppp_write(int fd, unsigned char *buffer, int n)
+{
+       int r;
+       static int errs = 0;
+       int retries = 0;
+
+       if(syncHDLC) {
+
+               retry:
+
+               if((r = write(fd, buffer, n)) < 0) {
+
+                       /*
+                       * We sometimes run out of mbufs doing simultaneous
+                       * up- and down-loads on FreeBSD.  We should find out
+                       * why this is, but for now...
+                       */
+
+                       if(errno == ENOBUFS) {
+
+                               errs++;
+
+                               if((errs < 10 || errs % 100 == 0))
+                                       report(0, REPORT_ERROR|REPORT_DATE, 
+"ppp_write: %d ENOBUFS errors\n", errs);
+
+                               if(retries++ < NOBUF_RETRIES) {
+                                       /* retry after delay */
+                                       usleep(1000);
+                                       goto retry;
+                               }
+                               else {
+                                       /* throw away the packet */
+                                       return(0);
+                               }
+
+                       }
+                       else {
+                               report(0, REPORT_ERROR|REPORT_DATE|REPORT_PERROR, 
+"Error writing to ppp(d)\n");
+                       }
+               }
+               return(r);
+       }
+       else {
+           static unsigned char header[4000]={FRAME_ADDR, FRAME_CTRL};
+           unsigned char tail[2];
+           unsigned char* ptr = header+2;
+           unsigned short fcs;
+           int i;
+           unsigned char c;
+           /* Compute FCS */
+           fcs = pppFCS16(PPPINITFCS16, header, 2);
+           fcs = pppFCS16(fcs, buffer+2, n-2) ^ 0xffff;
+           tail[0] = fcs & 0x00ff;
+           tail[1] = (fcs >> 8) & 0x00ff;
+
+           /* Build a buffer to send to PPP */
+           *ptr++ = FRAME_FLAG;
+           *ptr++ = FRAME_ADDR;
+           *ptr++ = FRAME_ESC;
+           *ptr++ = FRAME_CTRL ^ FRAME_ENC;
+
+           for (i=2; i<n; i++) {
+               c = buffer[i];
+               if (c == FRAME_FLAG || c == FRAME_ADDR || c == FRAME_ESC || c < 0x20) {
+                   *ptr++ = FRAME_ESC;
+                   *ptr++ = c ^ FRAME_ENC;
+               } else {
+                   *ptr++ = c;
+               }
+           }
+           for (i=0; i<2; i++) {
+               c = tail[i];
+               if (c == FRAME_FLAG || c == FRAME_ADDR || c == FRAME_ESC || c < 0x20) {
+                   *ptr++ = FRAME_ESC;
+                   *ptr++ = c ^ FRAME_ENC;
+               } else {
+                   *ptr++ = c;
+               }
+           }
+           *ptr++ = FRAME_FLAG;
+
+           /* Ship it out */
+           if ((r = write(fd, header, (ptr-header))) < 0) {
+               report(0, REPORT_ERROR|REPORT_DATE|REPORT_PERROR, "Error writing to 
+ppp(d)\n");
+           }
+           else {
+               report(2, REPORT_DEBUG|REPORT_DATE|REPORT_DUMP, "PPP packet sent 
+(%d)\n",header,(ptr-header),(ptr-header));
+           }
+           
+           return r;
+       }
+
+       return(-1);
+
+}
+
+#else /* TIMS */
+
 /*
 * Function     : ppp_read
 * Return value : data read length
@@ -1170,6 +1477,8 @@
        return(-1);
 
 }
+
+#endif /* TIMS */
 
 /*
 * Function     : signal_handler


-- 
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t," 
and there was light.

     http://tjw.hn.org/      http://www.locofungus.btinternet.co.uk/



Liste de diffusion modem ALCATEL SpeedTouch USB
Pour se d�sinscrire : mailto:[EMAIL PROTECTED]?subject=unsubscribe

        

Reply via email to