Lab2_web / Mbed 2 deprecated webserverBlinky

Dependencies:   mbed

Fork of webserverBlinky by RealTimeCompLab2

Revision:
9:0992486d4a30
Parent:
8:48e40f1ff316
Child:
10:74f8233f72c0
diff -r 48e40f1ff316 -r 0992486d4a30 main.cpp
--- a/main.cpp	Thu Dec 29 17:25:16 2016 +0000
+++ b/main.cpp	Fri Dec 30 13:11:43 2016 +0000
@@ -6,18 +6,21 @@
 
 // Note - turn off all authentication, passwords, compression etc. Simplest link possible.
 
-// Nice links
+// Handy links
 // http://atari.kensclassics.org/wcomlog.htm
 // https://technet.microsoft.com/en-us/library/cc957992.aspx
 // http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
+// https://en.wikibooks.org/wiki/Serial_Programming/IP_Over_Serial_Connections
 
 Serial pc(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem on your pc
 Serial xx(PC_10, PC_11); // debug port - use a second USB serial port to monitor
 
+#define debug(x) xx.printf( x )
+
 DigitalOut led1(LED1);
 
 #define FRAME_7E (0x7e)
-#define BUFLEN (1<<14)
+#define BUFLEN (1<<12)
 char rxbuf[BUFLEN];
 char frbuf[3000]; // buffer for ppp frame
 
@@ -27,6 +30,7 @@
         char * buf;
         int head; 
         int tail; 
+        int total;
     } rx; // serial port buffer
     struct {
         int id;
@@ -36,17 +40,19 @@
     } pkt; // ppp buffer
 } ppp;
 
-void pppInitStruct(){ ppp.online=0; ppp.rx.buf=rxbuf; ppp.rx.tail=0; ppp.rx.head=0; ppp.pkt.buf=frbuf; ppp.pkt.len=0;}
+void pppInitStruct(){ ppp.online=0; ppp.rx.buf=rxbuf; ppp.rx.tail=0; ppp.rx.head=0; ppp.rx.total=0; ppp.pkt.buf=frbuf; ppp.pkt.len=0;}
 
 int crcG; // frame check sequence (CRC) holder
 void crcDo(int x){for (int i=0;i<8;i++){crcG=((crcG&1)^(x&1))?(crcG>>1)^0x8408:crcG>>1;x>>=1;}} // crc calculator
 void crcReset(){crcG=0xffff;} // crc restart
+int crcBuf(char * buf, int size){crcReset();for(int i=0;i<size;i++)crcDo(*buf++);return crcG;} // crc on a block of memory
 
 void rxHandler() // serial port receive interrupt handler
 {
     ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in buffer
     __disable_irq();
     ppp.rx.head=(ppp.rx.head+1)&(BUFLEN-1);
+    ppp.rx.total++;
     __enable_irq();
 }
 
@@ -67,22 +73,181 @@
 
 void scanForConnectString(); // scan for connect attempts from pc
 
+void processFrame(int start, int end) { // process received frame
+    if(start==end) { xx.printf("Null Frame c=%d\n",ppp.rx.total); pc.putc(0x7e); return; }
+    crcReset();
+    char * dest = ppp.pkt.buf;
+    ppp.pkt.len=0;
+    int unstuff=0;
+    for (int i=start; i<end; i++) {
+        if (unstuff==0) {
+            if (rxbuf[i]==0x7d) unstuff=1; 
+            else { *dest++ = rxbuf[i]; ppp.pkt.len++; crcDo(rxbuf[i]);}
+        } else {
+            *dest++ = rxbuf[i]^0x20; ppp.pkt.len++; crcDo((int)rxbuf[i]^0x20);
+            unstuff=0;
+        }
+    }
+    ppp.pkt.crc = crcG & 0xffff;
+    if (ppp.pkt.crc == 0xf0b8) { // check for good CRC
+        void determinePacketType(); // declare early
+        determinePacketType();
+    } else {
+         xx.printf("CRC was %x \n",ppp.pkt.crc);
+         for(int i=0;i<ppp.pkt.len;i++)xx.printf("%02x ", ppp.pkt.buf[i]);
+         xx.printf("\nLen = %d\n", ppp.pkt.len);
+    }
+}
+
+
+void generalFrame() {
+    debug("== General Frame ==\n");
+    for(int i=0;i<ppp.pkt.len;i++) xx.printf("%02x ", ppp.pkt.buf[i]);
+    xx.printf(" C %02x %02x L=%d\n", ppp.pkt.crc&0xff, (ppp.pkt.crc>>8)&0xff, ppp.pkt.len);
+}    
+
+void sendFrame(){
+    int crc = crcBuf(ppp.pkt.buf, ppp.pkt.len-2); // get crc
+    ppp.pkt.buf[ ppp.pkt.len-2 ] = (~crc>>0); // fcs lo
+    ppp.pkt.buf[ ppp.pkt.len-1 ] = (~crc>>8); // fcs hi
+    pc.putc(0x7e); // frame flag
+    for(int i=0;i<ppp.pkt.len;i++) {
+        unsigned int cc = (unsigned int)ppp.pkt.buf[i];
+        if (cc>32) pc.putc(cc); else {pc.putc(0x7d); pc.putc(cc+32);}
+    } 
+    pc.putc(0x7e); // frame flag
+}
+
+void ipRequestHandler(){
+    debug("IPCP Conf ");
+    if ( ppp.pkt.buf[7] != 4 ) {
+        debug("Rej\n"); // reject if any options are requested
+        ppp.pkt.buf[4]=4;
+        sendFrame();
+    } else  {
+        debug("Ack\n");
+        ppp.pkt.buf[4]=2; // ack the minimum
+        sendFrame(); // acknowledge
+        // send our own request now
+        debug("IPCP Ask\n");
+        ppp.pkt.buf[4]=1; // request the minimum
+        ppp.pkt.buf[5]++; // next sequence
+        sendFrame(); // this is our request
+    }
+}
+
+void ipAckHandler(){ debug("IPCP Grant\n"); }
+
+void ipNackHandler(){ debug("IPCP Nack\n"); }
+
+void ipDefaultHandler(){ debug("IPCP Other\n"); }
+
+void IPCPframe() {
+    led1 = ppp.pkt.buf[5] & 1; // This is the sequence number so the led blinks on packets
+    //ppp.pkt.id = ppp.pkt.buf[5]; // remember the sequence number 
+    int code = ppp.pkt.buf[4]; // packet type is here
+    switch (code) {
+        case 1: ipRequestHandler(); break;
+        case 2: ipAckHandler(); break;
+        case 3: ipNackHandler(); break;
+        default: ipDefaultHandler();    
+    }
+}    
+
+void IPframe() {
+    xx.printf("IP frame proto %3d len %4d %d.%d.%d.%d  %d.%d.%d.%d\n", ppp.pkt.buf[13],(ppp.pkt.buf[6]<<8)+ppp.pkt.buf[7],ppp.pkt.buf[16],ppp.pkt.buf[17],ppp.pkt.buf[18],ppp.pkt.buf[19],ppp.pkt.buf[20],ppp.pkt.buf[21],ppp.pkt.buf[22],ppp.pkt.buf[23] );
+}    
+
+
+
+void LCPconfReq() {
+    debug("LCP Conf ");
+    if (ppp.pkt.buf[7] != 4) {
+        ppp.pkt.buf[4]=4; // allow only minimal requests
+        debug("Rej\n");
+        sendFrame(); 
+    } else {
+        ppp.pkt.buf[4]=2; // ack zero conf
+        debug("Ack\n");
+        sendFrame();
+        debug("LCP ask\n");
+        ppp.pkt.buf[4]=1; // request zero conf
+        sendFrame();
+    }
+}
+
+void LCPconfAck() {
+    debug("LCP Ack\n");
+} 
+
+void LCPend(){
+     debug("LCP End\n");
+     ppp.online=0; 
+     ppp.pkt.buf[4]=6;
+     sendFrame();
+}
+
+void LCPother(){
+     debug("LCP Other\n");
+     generalFrame();
+}
+
+void LCPframe(){
+     int code = ppp.pkt.buf[4];
+     switch (code) {
+         case 1: LCPconfReq(); break;
+         case 2: LCPconfAck(); break;
+         case 5: LCPend(); break;
+         default: LCPother();
+     }
+}
+
+void xx21frame() {
+    debug("Unknown frame type ff 03 xx 21\n");
+}
+
+void determinePacketType() {
+    if ( ppp.pkt.buf[0] != 0xff ) {debug("byte0 != ff\n"); return;}
+    if ( ppp.pkt.buf[1] != 3    ) {debug("byte1 !=  3\n"); return;}
+    if ( ppp.pkt.buf[3] != 0x21 ) {debug("byte2 != 21\n"); return;}
+    int packetType = ppp.pkt.buf[2];
+    switch (packetType) {
+        case 0xc0: LCPframe(); break; 
+        case 0x80: IPCPframe(); break;
+        case 0x00: IPframe(); break;
+        default: xx21frame(); break;
+    }
+}    
+
+void scanForConnectString() {
+    if ( ppp.online==0 ) {
+        char * clientFound = strstr( rxbuf, "CLIENTCLIENT" ); // look for PC string
+        if( clientFound ) { 
+            strcpy( clientFound, "FOUND!FOUND!" ); // overwrite so we don't get fixated
+            pc.printf("CLIENTSERVER"); // respond to PC
+            ppp.online=1; // we can stop looking for the string
+            debug("Connect string found\n");
+        }
+    }
+}
+
 int main()
 {
-    pc.baud(19200);
+    pc.baud(9600);
     xx.baud(115200); 
-    xx.puts("\x1b[2J\x1b[H"); // VT100 terminal control code for screen clear/home
+    xx.puts("\x1b[2J\x1b[HReady\n"); // VT100 code for clear screen & home
     
-    pppInitStruct(); // structure containing all the PPP stuff
+    pppInitStruct(); // initialize all the PPP properties
 
-    pc.attach(&rxHandler,Serial::RxIrq); // activate the receive interrupt handler
+    pc.attach(&rxHandler,Serial::RxIrq); // start the receive handler
 
-    int frameStartIndex, frameEndIndex;
-    int frameBusy=0;
+    int frameStartIndex, frameEndIndex; int frameBusy=0;
 
     while(1) {
+        if ( ppp.online==0 ) scanForConnectString(); // try to connect
         while ( pc_readable() ) {
             int rx = pc_getBuf();
+            wait(0.001);
             if (frameBusy) { 
                 if (rx==FRAME_7E) {
                     frameBusy=0; // done gathering frame
@@ -94,146 +259,9 @@
             else {
                 if (rx==FRAME_7E) {
                     frameBusy=1; // start gathering frame
-                    frameStartIndex=ppp.rx.tail; // remember where frame starts
+                    frameStartIndex=ppp.rx.tail; // remember where frame started
                 }
             }
         }
-        if (ppp.online==0) scanForConnectString(); // try to connect
-    }
-}
-
-void processFrame(int start, int end) {
-    crcReset();
-    char * dest = ppp.pkt.buf;
-    ppp.pkt.len=0;
-    int special=0;
-    for (int i=start; i<end; i++) {
-        if (special==0) {
-            if (rxbuf[i]==0x7d) special=1; 
-            else { *dest++ = rxbuf[i]; ppp.pkt.len++; crcDo(rxbuf[i]);}
-        } else {
-            *dest++ = rxbuf[i]-32; ppp.pkt.len++; crcDo(rxbuf[i]-32);
-            special=0;
-        }
-    }
-    ppp.rx.head=0; // reuse rxbuf
-    ppp.rx.tail=0; // reuse rxbuf
-    ppp.pkt.crc = crcG;
-    if (crcG == 0xf0b8) { // check for good CRC
-        void determinePacketType(); // declare early
-        determinePacketType();
-    }
-}
-
-
-void generalFrame() {
-    xx.printf("== General Frame ==\n");
-    for(int i=0;i<ppp.pkt.len;i++) xx.printf("%02x ", ppp.pkt.buf[i]);
-    xx.printf(" C %02x %02x L=%d\n", ppp.pkt.crc&0xff, (ppp.pkt.crc>>8)&0xff, ppp.pkt.len);
-}    
-
-
-void sendFrame(){
-    crcReset(); for(int i=0;i<ppp.pkt.len-2;i++) crcDo(ppp.pkt.buf[i]);
-    ppp.pkt.buf[ ppp.pkt.len-2 ] = ((~crcG)>>0); // build crc lo
-    ppp.pkt.buf[ ppp.pkt.len-1 ] = ((~crcG)>>8); // build crc hi
-    pc.putc(0x7e); // start of frame
-    for(int i=0;i<ppp.pkt.len;i++) {
-        unsigned int cc = (unsigned int)ppp.pkt.buf[i];
-        if (cc>32) pc.putc(cc); else {pc.putc(0x7d);pc.putc(cc+32);}
-    } 
-    pc.putc(0x7e); // end of frame
-}
-
-
-
-void LCPrequestFrame() {
-    xx.printf("== LCP Request ==\n");
-    if (ppp.pkt.buf[7] != 4) {
-        ppp.pkt.buf[4]=4; // nack everything until zero len
-        sendFrame(); 
-    } else {
-        ppp.pkt.buf[4]=2; // ack zero conf
-        sendFrame();
-        // send our config request - also all zeros
-        ppp.pkt.buf[4]=1; // request zero conf
-        sendFrame();
     }
 }
-
-void LCPackFrame() {
-    xx.printf("== Saw Ack - PPP is up ==\n");
-} 
-
-
-void ipRequestHandler(){
-    xx.printf("== IP Request Frame ==\n");
-    generalFrame();
-    if ( ppp.pkt.buf[7] != 4 ) {
-        ppp.pkt.buf[4]=4; // Nack
-        sendFrame();
-    } else  {
-        ppp.pkt.buf[4]=2; // ack the minimum
-        sendFrame(); // acknowledge
-        xx.printf("zeroconf ack\n");
-        // send our own request now
-        ppp.pkt.buf[4]=1; // request the minimum
-        ppp.pkt.buf[5]++; // next sequence
-        sendFrame(); // this is our request
-    }
-}
-
-void ipAckHandler(){
-    xx.printf("== IP Ack Frame ==\n");
-}
-
-void ipNackHandler(){
-     xx.printf("== IP Nack Frame ==\n");
-}
-
-void ipDefaultHandler(){
-     xx.printf("== IP Unknown Frame ==\n");
-}
-
-void LCPgeneralFrame(){
-     xx.printf("== LCP General Handler ==\n");
-     generalFrame();
-}
-
-
-void LCPhandler(){
-     int action = ppp.pkt.buf[4];
-     if(0);
-     else if ( action == 1 ) LCPrequestFrame();
-     else if ( action == 2 ) LCPackFrame();
-     else LCPgeneralFrame();
-}
-
-void IPFrame() {
-    led1 = ppp.pkt.buf[5] & 1; // This is the sequence number so the led blinks on packets
-    ppp.pkt.id = ppp.pkt.buf[5]; // remember the sequence number 
-    int action = ppp.pkt.buf[4]; // packet type is here
-    if(0);
-    else if ( action == 1 ) ipRequestHandler();
-    else if ( action == 2 ) ipAckHandler();
-    else if ( action == 3 ) ipNackHandler();
-    else ipDefaultHandler();    
-}    
-
-void determinePacketType() {
-    static char pktLCPReqType  [] = { 0xff, 3, 0xc0, 0x21  }; // LCP packet
-    static char pktIPCPtype    [] = { 0xff, 3, 0x80, 0x21, }; // IP packet
-
-    if(0);
-    else if (0==memcmp( ppp.pkt.buf,pktLCPReqType,4)) LCPhandler(); 
-    else if (0==memcmp( ppp.pkt.buf,pktIPCPtype,  4)) IPFrame(); 
-    else generalFrame(); // default handler
-}    
-
-void scanForConnectString(){
-    char * clientFound = strstr( rxbuf, "CLIENTCLIENT" ); // look for PC string
-    if( clientFound ) { 
-        strcpy( clientFound, "FOUND!FOUND!" ); // overwrite so we don't get fixated
-        pc.printf("CLIENTSERVER"); // respond to PC
-    }
-}