Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of webserverBlinky by
Diff: main.cpp
- 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 - } -}