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
main.cpp
- Committer:
- nixnax
- Date:
- 2016-12-29
- Revision:
- 5:27624c02189f
- Parent:
- 4:a469050d5b80
- Child:
- 6:fba4c2e817b8
File content as of revision 5:27624c02189f:
#include "mbed.h" // 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 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 led1(LED1); #define FRAME_7E (0x7e) #define BUFLEN (1<<14) char rxbuf[BUFLEN]; char frbuf[3000]; // buffer for ppp frame 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; 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 { ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in buffer __disable_irq(); ppp.rx.head=(ppp.rx.head+1)&(BUFLEN-1); __enable_irq(); } int pc_readable() // check if buffer has data { return (ppp.rx.head==ppp.rx.tail) ? 0 : 1 ; } int pc_getBuf() // get one character from the buffer { if (pc_readable()) { int x = ppp.rx.buf[ ppp.rx.tail ]; ppp.rx.tail=(ppp.rx.tail+1)&(BUFLEN-1); return x; } return -1; } 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 frameStartIndex, frameEndIndex; int frameBusy=0; while(1) { while ( pc_readable() ) { int rx = pc_getBuf(); 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 (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(); // acknowledge their request // this is the right time to send our LCP setup request to them 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 } }