RealtimeCompLab2

Dependencies:   mbed

Fork of PPP-Blinky by Nicolas Nackel

Committer:
nixnax
Date:
Thu Dec 29 04:34:25 2016 +0000
Revision:
5:27624c02189f
Parent:
4:a469050d5b80
Child:
6:fba4c2e817b8
small changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nixnax 0:2cf4880c312a 1 #include "mbed.h"
nixnax 0:2cf4880c312a 2
nixnax 0:2cf4880c312a 3 // Proof-of-concept for TCP/IP using Windows 7/8/10 Dial Up Networking over MBED USB Virtual COM Port
nixnax 0:2cf4880c312a 4
nixnax 4:a469050d5b80 5 // Toggles LED1 every time the PC sends an IP packet over the PPP link
nixnax 4:a469050d5b80 6
nixnax 4:a469050d5b80 7 // Note - turn off all authentication, passwords, compression etc. Simplest link possible.
nixnax 0:2cf4880c312a 8
nixnax 0:2cf4880c312a 9 Serial pc(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem
nixnax 4:a469050d5b80 10 Serial xx(PC_10, PC_11); // debug port - use a second USB serial port to monitor
nixnax 0:2cf4880c312a 11
nixnax 4:a469050d5b80 12 DigitalOut led1(LED1);
nixnax 4:a469050d5b80 13
nixnax 4:a469050d5b80 14 #define FRAME_7E (0x7e)
nixnax 4:a469050d5b80 15 #define BUFLEN (1<<14)
nixnax 4:a469050d5b80 16 char rxbuf[BUFLEN];
nixnax 4:a469050d5b80 17 char frbuf[3000]; // buffer for ppp frame
nixnax 0:2cf4880c312a 18
nixnax 4:a469050d5b80 19 struct {
nixnax 4:a469050d5b80 20 int online;
nixnax 4:a469050d5b80 21 struct {
nixnax 4:a469050d5b80 22 char * buf;
nixnax 4:a469050d5b80 23 int head;
nixnax 4:a469050d5b80 24 int tail;
nixnax 4:a469050d5b80 25 } rx; // serial port buffer
nixnax 4:a469050d5b80 26 struct {
nixnax 4:a469050d5b80 27 int len;
nixnax 4:a469050d5b80 28 int crc;
nixnax 4:a469050d5b80 29 char * buf;
nixnax 4:a469050d5b80 30 } pkt; // ppp buffer
nixnax 4:a469050d5b80 31 } ppp;
nixnax 0:2cf4880c312a 32
nixnax 4:a469050d5b80 33 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;}
nixnax 4:a469050d5b80 34
nixnax 4:a469050d5b80 35 int crcG; // frame check sequence (CRC) holder
nixnax 4:a469050d5b80 36 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
nixnax 4:a469050d5b80 37 void crcReset(){crcG=0xffff;} // crc restart
nixnax 0:2cf4880c312a 38
nixnax 0:2cf4880c312a 39 void rxHandler() // serial port receive interrupt handler
nixnax 0:2cf4880c312a 40 {
nixnax 4:a469050d5b80 41 ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in buffer
nixnax 0:2cf4880c312a 42 __disable_irq();
nixnax 4:a469050d5b80 43 ppp.rx.head=(ppp.rx.head+1)&(BUFLEN-1);
nixnax 0:2cf4880c312a 44 __enable_irq();
nixnax 0:2cf4880c312a 45 }
nixnax 0:2cf4880c312a 46
nixnax 0:2cf4880c312a 47 int pc_readable() // check if buffer has data
nixnax 0:2cf4880c312a 48 {
nixnax 4:a469050d5b80 49 return (ppp.rx.head==ppp.rx.tail) ? 0 : 1 ;
nixnax 0:2cf4880c312a 50 }
nixnax 0:2cf4880c312a 51
nixnax 0:2cf4880c312a 52 int pc_getBuf() // get one character from the buffer
nixnax 0:2cf4880c312a 53 {
nixnax 0:2cf4880c312a 54 if (pc_readable()) {
nixnax 4:a469050d5b80 55 int x = ppp.rx.buf[ ppp.rx.tail ];
nixnax 4:a469050d5b80 56 ppp.rx.tail=(ppp.rx.tail+1)&(BUFLEN-1);
nixnax 0:2cf4880c312a 57 return x;
nixnax 0:2cf4880c312a 58 }
nixnax 0:2cf4880c312a 59 return -1;
nixnax 0:2cf4880c312a 60 }
nixnax 0:2cf4880c312a 61
nixnax 4:a469050d5b80 62
nixnax 4:a469050d5b80 63 void scanForConnectString(); // scan for connect attempts from pc
nixnax 1:9e03798d4367 64
nixnax 0:2cf4880c312a 65 int main()
nixnax 0:2cf4880c312a 66 {
nixnax 0:2cf4880c312a 67 pc.baud(115200);
nixnax 4:a469050d5b80 68 xx.baud(115200);
nixnax 4:a469050d5b80 69 xx.puts("\x1b[2J\x1b[H"); // VT100 terminal control code for screen clear/home
nixnax 4:a469050d5b80 70
nixnax 4:a469050d5b80 71 pppInitStruct(); // structure containing all the PPP stuff
nixnax 4:a469050d5b80 72
nixnax 0:2cf4880c312a 73 pc.attach(&rxHandler,Serial::RxIrq); // activate the receive interrupt handler
nixnax 4:a469050d5b80 74
nixnax 4:a469050d5b80 75 int frameStartIndex, frameEndIndex;
nixnax 4:a469050d5b80 76 int frameBusy=0;
nixnax 4:a469050d5b80 77
nixnax 0:2cf4880c312a 78 while(1) {
nixnax 0:2cf4880c312a 79 while ( pc_readable() ) {
nixnax 1:9e03798d4367 80 int rx = pc_getBuf();
nixnax 4:a469050d5b80 81 if (frameBusy) {
nixnax 4:a469050d5b80 82 if (rx==FRAME_7E) {
nixnax 4:a469050d5b80 83 frameBusy=0; // done gathering frame
nixnax 4:a469050d5b80 84 frameEndIndex=ppp.rx.tail-1; // remember where frame ends
nixnax 4:a469050d5b80 85 void processFrame(int start, int end); // process a received frame
nixnax 4:a469050d5b80 86 processFrame(frameStartIndex, frameEndIndex);
nixnax 4:a469050d5b80 87 }
nixnax 4:a469050d5b80 88 }
nixnax 4:a469050d5b80 89 else {
nixnax 4:a469050d5b80 90 if (rx==FRAME_7E) {
nixnax 4:a469050d5b80 91 frameBusy=1; // start gathering frame
nixnax 4:a469050d5b80 92 frameStartIndex=ppp.rx.tail; // remember where frame starts
nixnax 4:a469050d5b80 93 }
nixnax 0:2cf4880c312a 94 }
nixnax 4:a469050d5b80 95 }
nixnax 4:a469050d5b80 96 if (ppp.online==0) scanForConnectString(); // try to connect
nixnax 4:a469050d5b80 97 }
nixnax 4:a469050d5b80 98 }
nixnax 4:a469050d5b80 99
nixnax 4:a469050d5b80 100 void processFrame(int start, int end) {
nixnax 4:a469050d5b80 101 crcReset();
nixnax 4:a469050d5b80 102 char * dest = ppp.pkt.buf;
nixnax 4:a469050d5b80 103 ppp.pkt.len=0;
nixnax 4:a469050d5b80 104 int special=0;
nixnax 4:a469050d5b80 105 for (int i=start; i<end; i++) {
nixnax 4:a469050d5b80 106 if (special==0) {
nixnax 4:a469050d5b80 107 if (rxbuf[i]==0x7d) special=1;
nixnax 4:a469050d5b80 108 else { *dest++ = rxbuf[i]; ppp.pkt.len++; crcDo(rxbuf[i]);}
nixnax 4:a469050d5b80 109 } else {
nixnax 4:a469050d5b80 110 *dest++ = rxbuf[i]-32; ppp.pkt.len++; crcDo(rxbuf[i]-32);
nixnax 4:a469050d5b80 111 special=0;
nixnax 0:2cf4880c312a 112 }
nixnax 0:2cf4880c312a 113 }
nixnax 4:a469050d5b80 114 ppp.pkt.crc = crcG;
nixnax 4:a469050d5b80 115 ppp.rx.head=0; // reuse rxbuf
nixnax 4:a469050d5b80 116 ppp.rx.tail=0; // reuse rxbuf
nixnax 4:a469050d5b80 117 void determinePacketType(); // declare early
nixnax 4:a469050d5b80 118 determinePacketType();
nixnax 0:2cf4880c312a 119 }
nixnax 4:a469050d5b80 120
nixnax 4:a469050d5b80 121 void sendFrame(){
nixnax 4:a469050d5b80 122 crcReset(); for(int i=0;i<ppp.pkt.len-2;i++) crcDo(ppp.pkt.buf[i]);
nixnax 4:a469050d5b80 123 ppp.pkt.buf[ ppp.pkt.len-2 ] = ((~crcG)>>0)&0xff; // update crc lo
nixnax 4:a469050d5b80 124 ppp.pkt.buf[ ppp.pkt.len-1 ] = ((~crcG)>>8)&0xff; // update crc hi
nixnax 4:a469050d5b80 125 pc.putc(0x7e);
nixnax 4:a469050d5b80 126 for(int i=0;i<ppp.pkt.len;i++) {
nixnax 4:a469050d5b80 127 unsigned int cc = (unsigned int)ppp.pkt.buf[i];
nixnax 4:a469050d5b80 128 if (cc>32) pc.putc(cc);
nixnax 4:a469050d5b80 129 else {
nixnax 4:a469050d5b80 130 pc.putc(0x7d); pc.putc(cc+32);
nixnax 4:a469050d5b80 131 }
nixnax 4:a469050d5b80 132 }
nixnax 4:a469050d5b80 133 pc.putc(0x7e);
nixnax 4:a469050d5b80 134 }
nixnax 4:a469050d5b80 135
nixnax 4:a469050d5b80 136 void LCPrequestFrame() {
nixnax 5:27624c02189f 137 ppp.pkt.buf[4]=2; // change to an ACK packet
nixnax 5:27624c02189f 138 sendFrame(); // acknowledge their request
nixnax 5:27624c02189f 139 // this is the right time to send our LCP setup request to them
nixnax 5:27624c02189f 140 ppp.pkt.buf[4]=1; // change back to a request
nixnax 5:27624c02189f 141 ppp.pkt.buf[5] = ppp.pkt.buf[5]+1; // take the next id
nixnax 5:27624c02189f 142 ppp.pkt.buf[16] = ppp.pkt.buf[16] ^ 0x33; // modify magic number
nixnax 5:27624c02189f 143 ppp.pkt.buf[17] = ppp.pkt.buf[16] ^ 0x33; // modify magic number
nixnax 5:27624c02189f 144 sendFrame(); // send our request
nixnax 5:27624c02189f 145
nixnax 4:a469050d5b80 146 }
nixnax 4:a469050d5b80 147
nixnax 4:a469050d5b80 148 void LCPackFrame() {
nixnax 4:a469050d5b80 149 xx.printf("== PPP is up ==\n");
nixnax 5:27624c02189f 150 }
nixnax 4:a469050d5b80 151
nixnax 4:a469050d5b80 152 void generalFrame() {
nixnax 4:a469050d5b80 153 xx.printf("== General Frame ==\n");
nixnax 4:a469050d5b80 154 for(int i=0;i<ppp.pkt.len;i++) xx.printf("%02x ", ppp.pkt.buf[i]);
nixnax 4:a469050d5b80 155 xx.printf(" C %02x %02x L=%d\n", ppp.pkt.crc&0xff, (ppp.pkt.crc>>8)&0xff, ppp.pkt.len);
nixnax 4:a469050d5b80 156 }
nixnax 4:a469050d5b80 157
nixnax 4:a469050d5b80 158 void iPcpFrame() {
nixnax 4:a469050d5b80 159 xx.printf("== IPCP Frame ==\n");
nixnax 4:a469050d5b80 160 for(int i=0;i<ppp.pkt.len;i++) xx.printf("%02x ", ppp.pkt.buf[i]);
nixnax 4:a469050d5b80 161 xx.printf(" C %02x %02x L=%d\n", ppp.pkt.crc&0xff, (ppp.pkt.crc>>8)&0xff, ppp.pkt.len);
nixnax 4:a469050d5b80 162 led1 = ppp.pkt.buf[3] & 1; // This is the sequence number so the led blinks on packets
nixnax 4:a469050d5b80 163 }
nixnax 4:a469050d5b80 164
nixnax 4:a469050d5b80 165 void determinePacketType() {
nixnax 4:a469050d5b80 166 char pktLCPReqType [] = { 0xff, 3, 0xc0, 0x21, 1 }; // LCP requeswt packet
nixnax 4:a469050d5b80 167 char pktLCPAckType [] = { 0xff, 3, 0xc0, 0x21, 2 }; // LCP ack packet
nixnax 4:a469050d5b80 168 char pktIPCPtype [] = { 0x80, 0x21, 1 }; // ip control packet
nixnax 4:a469050d5b80 169 if(0);
nixnax 4:a469050d5b80 170 else if (0==memcmp( ppp.pkt.buf,pktLCPReqType,5)) LCPrequestFrame();
nixnax 4:a469050d5b80 171 else if (0==memcmp( ppp.pkt.buf,pktLCPAckType,5)) LCPackFrame();
nixnax 4:a469050d5b80 172 else if (0==memcmp( ppp.pkt.buf,pktIPCPtype,3 )) iPcpFrame();
nixnax 4:a469050d5b80 173 else generalFrame(); // default handler
nixnax 4:a469050d5b80 174 }
nixnax 4:a469050d5b80 175
nixnax 4:a469050d5b80 176 void scanForConnectString(){
nixnax 4:a469050d5b80 177 char * clientFound = strstr( rxbuf, "CLIENTCLIENT" ); // look for PC string
nixnax 4:a469050d5b80 178 if( clientFound ) {
nixnax 4:a469050d5b80 179 strcpy( clientFound, "FOUND!FOUND!" ); // overwrite so we don't get fixated
nixnax 4:a469050d5b80 180 pc.printf("CLIENTSERVER"); // respond to PC
nixnax 4:a469050d5b80 181 }
nixnax 4:a469050d5b80 182 }