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:
- 4:a469050d5b80
- Parent:
- 3:bcc66de0bdcd
- Child:
- 5:27624c02189f
diff -r bcc66de0bdcd -r a469050d5b80 main.cpp --- a/main.cpp Tue Dec 27 18:38:49 2016 +0000 +++ b/main.cpp Thu Dec 29 04:21:29 2016 +0000 @@ -2,59 +2,179 @@ // Proof-of-concept for TCP/IP using Windows 7/8/10 Dial Up Networking over MBED USB Virtual COM Port -// Toggles LED1 every time the PC tries to establish a Dial-up Networking Connection +// Toggles LED1 every time the PC sends an IP packet over the PPP link + +// Note - turn off all authentication, passwords, compression etc. Simplest link possible. Serial pc(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem +Serial xx(PC_10, PC_11); // debug port - use a second USB serial port to monitor -DigitalOut myled(LED1); +DigitalOut led1(LED1); + +#define FRAME_7E (0x7e) +#define BUFLEN (1<<14) +char rxbuf[BUFLEN]; +char frbuf[3000]; // buffer for ppp frame -#define BUFLEN (1<<12) -char rxbuf[BUFLEN]; +struct { + int online; + struct { + char * buf; + int head; + int tail; + } rx; // serial port buffer + struct { + int len; + int crc; + char * buf; + } pkt; // ppp buffer +} ppp; -int headPointer = 0; // head of receive buffer -int tailPointer = 0; // tail of receive buffer +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;} + +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 void rxHandler() // serial port receive interrupt handler { - rxbuf[headPointer]=pc.getc(); // insert in buffer + ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in buffer __disable_irq(); - headPointer=(headPointer+1)&(BUFLEN-1); + ppp.rx.head=(ppp.rx.head+1)&(BUFLEN-1); __enable_irq(); } int pc_readable() // check if buffer has data { - return (headPointer==tailPointer) ? 0 : 1 ; + return (ppp.rx.head==ppp.rx.tail) ? 0 : 1 ; } int pc_getBuf() // get one character from the buffer { if (pc_readable()) { - int x = rxbuf[tailPointer]; - tailPointer=(tailPointer+1)&(BUFLEN-1); + int x = ppp.rx.buf[ ppp.rx.tail ]; + ppp.rx.tail=(ppp.rx.tail+1)&(BUFLEN-1); return x; } return -1; } -// ppp frame start/end flag -#define FRAME_START_END 0x7e + +void scanForConnectString(); // scan for connect attempts from pc int main() { pc.baud(115200); + xx.baud(115200); + xx.puts("\x1b[2J\x1b[H"); // VT100 terminal control code for screen clear/home + + pppInitStruct(); // structure containing all the PPP stuff + pc.attach(&rxHandler,Serial::RxIrq); // activate the receive interrupt handler - int flagCount=0; + + int frameStartIndex, frameEndIndex; + int frameBusy=0; + while(1) { while ( pc_readable() ) { int rx = pc_getBuf(); - if (rx == FRAME_START_END) flagCount++; - char * clientFound = strstr( rxbuf, "CLIENTCLIENT" ); // look for string - if( clientFound ) { - strcpy( clientFound, "FOUND!FOUND!" ); // overwrite found string - pc.printf("CLIENTSERVER"); // respond to PC + if (frameBusy) { + if (rx==FRAME_7E) { + frameBusy=0; // done gathering frame + frameEndIndex=ppp.rx.tail-1; // remember where frame ends + void processFrame(int start, int end); // process a received frame + processFrame(frameStartIndex, frameEndIndex); + } + } + else { + if (rx==FRAME_7E) { + frameBusy=1; // start gathering frame + frameStartIndex=ppp.rx.tail; // remember where frame starts + } } - if ( flagCount>0 ) myled = ((flagCount/2)%2); // toggle on PPP frame found + } + 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.pkt.crc = crcG; + ppp.rx.head=0; // reuse rxbuf + ppp.rx.tail=0; // reuse rxbuf + void determinePacketType(); // declare early + determinePacketType(); } + +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)&0xff; // update crc lo + ppp.pkt.buf[ ppp.pkt.len-1 ] = ((~crcG)>>8)&0xff; // update crc hi + pc.putc(0x7e); + 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); +} + +void LCPrequestFrame() { + ppp.pkt.buf[4]=2; // change to an ACK packet + sendFrame(); // return their request + ppp.pkt.buf[4]=1; // change back to a request + ppp.pkt.buf[5] = ppp.pkt.buf[5]+1; // take the next id + ppp.pkt.buf[16] = ppp.pkt.buf[16] ^ 0x33; // modify magic number + ppp.pkt.buf[17] = ppp.pkt.buf[16] ^ 0x33; // modify magic number + sendFrame(); // send our request +} + +void LCPackFrame() { + xx.printf("== PPP is up ==\n"); +} + +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 iPcpFrame() { + xx.printf("== IPCP 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); + led1 = ppp.pkt.buf[3] & 1; // This is the sequence number so the led blinks on packets +} + +void determinePacketType() { + char pktLCPReqType [] = { 0xff, 3, 0xc0, 0x21, 1 }; // LCP requeswt packet + char pktLCPAckType [] = { 0xff, 3, 0xc0, 0x21, 2 }; // LCP ack packet + char pktIPCPtype [] = { 0x80, 0x21, 1 }; // ip control packet + if(0); + else if (0==memcmp( ppp.pkt.buf,pktLCPReqType,5)) LCPrequestFrame(); + else if (0==memcmp( ppp.pkt.buf,pktLCPAckType,5)) LCPackFrame(); + else if (0==memcmp( ppp.pkt.buf,pktIPCPtype,3 )) iPcpFrame(); + 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 + } +}