RealtimeCompLab2

Dependencies:   mbed

Fork of PPP-Blinky by Nicolas Nackel

Committer:
nixnax
Date:
Fri Dec 30 13:11:43 2016 +0000
Revision:
9:0992486d4a30
Parent:
8:48e40f1ff316
Child:
10:74f8233f72c0
printing first incoming ip packets

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 9:0992486d4a30 9 // Handy links
nixnax 6:fba4c2e817b8 10 // http://atari.kensclassics.org/wcomlog.htm
nixnax 6:fba4c2e817b8 11 // https://technet.microsoft.com/en-us/library/cc957992.aspx
nixnax 6:fba4c2e817b8 12 // http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
nixnax 9:0992486d4a30 13 // https://en.wikibooks.org/wiki/Serial_Programming/IP_Over_Serial_Connections
nixnax 6:fba4c2e817b8 14
nixnax 6:fba4c2e817b8 15 Serial pc(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem on your pc
nixnax 4:a469050d5b80 16 Serial xx(PC_10, PC_11); // debug port - use a second USB serial port to monitor
nixnax 0:2cf4880c312a 17
nixnax 9:0992486d4a30 18 #define debug(x) xx.printf( x )
nixnax 9:0992486d4a30 19
nixnax 4:a469050d5b80 20 DigitalOut led1(LED1);
nixnax 4:a469050d5b80 21
nixnax 4:a469050d5b80 22 #define FRAME_7E (0x7e)
nixnax 9:0992486d4a30 23 #define BUFLEN (1<<12)
nixnax 4:a469050d5b80 24 char rxbuf[BUFLEN];
nixnax 4:a469050d5b80 25 char frbuf[3000]; // buffer for ppp frame
nixnax 0:2cf4880c312a 26
nixnax 4:a469050d5b80 27 struct {
nixnax 4:a469050d5b80 28 int online;
nixnax 4:a469050d5b80 29 struct {
nixnax 4:a469050d5b80 30 char * buf;
nixnax 4:a469050d5b80 31 int head;
nixnax 4:a469050d5b80 32 int tail;
nixnax 9:0992486d4a30 33 int total;
nixnax 4:a469050d5b80 34 } rx; // serial port buffer
nixnax 4:a469050d5b80 35 struct {
nixnax 6:fba4c2e817b8 36 int id;
nixnax 4:a469050d5b80 37 int len;
nixnax 4:a469050d5b80 38 int crc;
nixnax 4:a469050d5b80 39 char * buf;
nixnax 4:a469050d5b80 40 } pkt; // ppp buffer
nixnax 4:a469050d5b80 41 } ppp;
nixnax 0:2cf4880c312a 42
nixnax 9:0992486d4a30 43 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;}
nixnax 4:a469050d5b80 44
nixnax 4:a469050d5b80 45 int crcG; // frame check sequence (CRC) holder
nixnax 4:a469050d5b80 46 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 47 void crcReset(){crcG=0xffff;} // crc restart
nixnax 9:0992486d4a30 48 int crcBuf(char * buf, int size){crcReset();for(int i=0;i<size;i++)crcDo(*buf++);return crcG;} // crc on a block of memory
nixnax 0:2cf4880c312a 49
nixnax 0:2cf4880c312a 50 void rxHandler() // serial port receive interrupt handler
nixnax 0:2cf4880c312a 51 {
nixnax 4:a469050d5b80 52 ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in buffer
nixnax 0:2cf4880c312a 53 __disable_irq();
nixnax 4:a469050d5b80 54 ppp.rx.head=(ppp.rx.head+1)&(BUFLEN-1);
nixnax 9:0992486d4a30 55 ppp.rx.total++;
nixnax 0:2cf4880c312a 56 __enable_irq();
nixnax 0:2cf4880c312a 57 }
nixnax 0:2cf4880c312a 58
nixnax 0:2cf4880c312a 59 int pc_readable() // check if buffer has data
nixnax 0:2cf4880c312a 60 {
nixnax 4:a469050d5b80 61 return (ppp.rx.head==ppp.rx.tail) ? 0 : 1 ;
nixnax 0:2cf4880c312a 62 }
nixnax 0:2cf4880c312a 63
nixnax 0:2cf4880c312a 64 int pc_getBuf() // get one character from the buffer
nixnax 0:2cf4880c312a 65 {
nixnax 0:2cf4880c312a 66 if (pc_readable()) {
nixnax 4:a469050d5b80 67 int x = ppp.rx.buf[ ppp.rx.tail ];
nixnax 4:a469050d5b80 68 ppp.rx.tail=(ppp.rx.tail+1)&(BUFLEN-1);
nixnax 0:2cf4880c312a 69 return x;
nixnax 0:2cf4880c312a 70 }
nixnax 0:2cf4880c312a 71 return -1;
nixnax 0:2cf4880c312a 72 }
nixnax 0:2cf4880c312a 73
nixnax 4:a469050d5b80 74 void scanForConnectString(); // scan for connect attempts from pc
nixnax 1:9e03798d4367 75
nixnax 9:0992486d4a30 76 void processFrame(int start, int end) { // process received frame
nixnax 9:0992486d4a30 77 if(start==end) { xx.printf("Null Frame c=%d\n",ppp.rx.total); pc.putc(0x7e); return; }
nixnax 9:0992486d4a30 78 crcReset();
nixnax 9:0992486d4a30 79 char * dest = ppp.pkt.buf;
nixnax 9:0992486d4a30 80 ppp.pkt.len=0;
nixnax 9:0992486d4a30 81 int unstuff=0;
nixnax 9:0992486d4a30 82 for (int i=start; i<end; i++) {
nixnax 9:0992486d4a30 83 if (unstuff==0) {
nixnax 9:0992486d4a30 84 if (rxbuf[i]==0x7d) unstuff=1;
nixnax 9:0992486d4a30 85 else { *dest++ = rxbuf[i]; ppp.pkt.len++; crcDo(rxbuf[i]);}
nixnax 9:0992486d4a30 86 } else {
nixnax 9:0992486d4a30 87 *dest++ = rxbuf[i]^0x20; ppp.pkt.len++; crcDo((int)rxbuf[i]^0x20);
nixnax 9:0992486d4a30 88 unstuff=0;
nixnax 9:0992486d4a30 89 }
nixnax 9:0992486d4a30 90 }
nixnax 9:0992486d4a30 91 ppp.pkt.crc = crcG & 0xffff;
nixnax 9:0992486d4a30 92 if (ppp.pkt.crc == 0xf0b8) { // check for good CRC
nixnax 9:0992486d4a30 93 void determinePacketType(); // declare early
nixnax 9:0992486d4a30 94 determinePacketType();
nixnax 9:0992486d4a30 95 } else {
nixnax 9:0992486d4a30 96 xx.printf("CRC was %x \n",ppp.pkt.crc);
nixnax 9:0992486d4a30 97 for(int i=0;i<ppp.pkt.len;i++)xx.printf("%02x ", ppp.pkt.buf[i]);
nixnax 9:0992486d4a30 98 xx.printf("\nLen = %d\n", ppp.pkt.len);
nixnax 9:0992486d4a30 99 }
nixnax 9:0992486d4a30 100 }
nixnax 9:0992486d4a30 101
nixnax 9:0992486d4a30 102
nixnax 9:0992486d4a30 103 void generalFrame() {
nixnax 9:0992486d4a30 104 debug("== General Frame ==\n");
nixnax 9:0992486d4a30 105 for(int i=0;i<ppp.pkt.len;i++) xx.printf("%02x ", ppp.pkt.buf[i]);
nixnax 9:0992486d4a30 106 xx.printf(" C %02x %02x L=%d\n", ppp.pkt.crc&0xff, (ppp.pkt.crc>>8)&0xff, ppp.pkt.len);
nixnax 9:0992486d4a30 107 }
nixnax 9:0992486d4a30 108
nixnax 9:0992486d4a30 109 void sendFrame(){
nixnax 9:0992486d4a30 110 int crc = crcBuf(ppp.pkt.buf, ppp.pkt.len-2); // get crc
nixnax 9:0992486d4a30 111 ppp.pkt.buf[ ppp.pkt.len-2 ] = (~crc>>0); // fcs lo
nixnax 9:0992486d4a30 112 ppp.pkt.buf[ ppp.pkt.len-1 ] = (~crc>>8); // fcs hi
nixnax 9:0992486d4a30 113 pc.putc(0x7e); // frame flag
nixnax 9:0992486d4a30 114 for(int i=0;i<ppp.pkt.len;i++) {
nixnax 9:0992486d4a30 115 unsigned int cc = (unsigned int)ppp.pkt.buf[i];
nixnax 9:0992486d4a30 116 if (cc>32) pc.putc(cc); else {pc.putc(0x7d); pc.putc(cc+32);}
nixnax 9:0992486d4a30 117 }
nixnax 9:0992486d4a30 118 pc.putc(0x7e); // frame flag
nixnax 9:0992486d4a30 119 }
nixnax 9:0992486d4a30 120
nixnax 9:0992486d4a30 121 void ipRequestHandler(){
nixnax 9:0992486d4a30 122 debug("IPCP Conf ");
nixnax 9:0992486d4a30 123 if ( ppp.pkt.buf[7] != 4 ) {
nixnax 9:0992486d4a30 124 debug("Rej\n"); // reject if any options are requested
nixnax 9:0992486d4a30 125 ppp.pkt.buf[4]=4;
nixnax 9:0992486d4a30 126 sendFrame();
nixnax 9:0992486d4a30 127 } else {
nixnax 9:0992486d4a30 128 debug("Ack\n");
nixnax 9:0992486d4a30 129 ppp.pkt.buf[4]=2; // ack the minimum
nixnax 9:0992486d4a30 130 sendFrame(); // acknowledge
nixnax 9:0992486d4a30 131 // send our own request now
nixnax 9:0992486d4a30 132 debug("IPCP Ask\n");
nixnax 9:0992486d4a30 133 ppp.pkt.buf[4]=1; // request the minimum
nixnax 9:0992486d4a30 134 ppp.pkt.buf[5]++; // next sequence
nixnax 9:0992486d4a30 135 sendFrame(); // this is our request
nixnax 9:0992486d4a30 136 }
nixnax 9:0992486d4a30 137 }
nixnax 9:0992486d4a30 138
nixnax 9:0992486d4a30 139 void ipAckHandler(){ debug("IPCP Grant\n"); }
nixnax 9:0992486d4a30 140
nixnax 9:0992486d4a30 141 void ipNackHandler(){ debug("IPCP Nack\n"); }
nixnax 9:0992486d4a30 142
nixnax 9:0992486d4a30 143 void ipDefaultHandler(){ debug("IPCP Other\n"); }
nixnax 9:0992486d4a30 144
nixnax 9:0992486d4a30 145 void IPCPframe() {
nixnax 9:0992486d4a30 146 led1 = ppp.pkt.buf[5] & 1; // This is the sequence number so the led blinks on packets
nixnax 9:0992486d4a30 147 //ppp.pkt.id = ppp.pkt.buf[5]; // remember the sequence number
nixnax 9:0992486d4a30 148 int code = ppp.pkt.buf[4]; // packet type is here
nixnax 9:0992486d4a30 149 switch (code) {
nixnax 9:0992486d4a30 150 case 1: ipRequestHandler(); break;
nixnax 9:0992486d4a30 151 case 2: ipAckHandler(); break;
nixnax 9:0992486d4a30 152 case 3: ipNackHandler(); break;
nixnax 9:0992486d4a30 153 default: ipDefaultHandler();
nixnax 9:0992486d4a30 154 }
nixnax 9:0992486d4a30 155 }
nixnax 9:0992486d4a30 156
nixnax 9:0992486d4a30 157 void IPframe() {
nixnax 9:0992486d4a30 158 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] );
nixnax 9:0992486d4a30 159 }
nixnax 9:0992486d4a30 160
nixnax 9:0992486d4a30 161
nixnax 9:0992486d4a30 162
nixnax 9:0992486d4a30 163 void LCPconfReq() {
nixnax 9:0992486d4a30 164 debug("LCP Conf ");
nixnax 9:0992486d4a30 165 if (ppp.pkt.buf[7] != 4) {
nixnax 9:0992486d4a30 166 ppp.pkt.buf[4]=4; // allow only minimal requests
nixnax 9:0992486d4a30 167 debug("Rej\n");
nixnax 9:0992486d4a30 168 sendFrame();
nixnax 9:0992486d4a30 169 } else {
nixnax 9:0992486d4a30 170 ppp.pkt.buf[4]=2; // ack zero conf
nixnax 9:0992486d4a30 171 debug("Ack\n");
nixnax 9:0992486d4a30 172 sendFrame();
nixnax 9:0992486d4a30 173 debug("LCP ask\n");
nixnax 9:0992486d4a30 174 ppp.pkt.buf[4]=1; // request zero conf
nixnax 9:0992486d4a30 175 sendFrame();
nixnax 9:0992486d4a30 176 }
nixnax 9:0992486d4a30 177 }
nixnax 9:0992486d4a30 178
nixnax 9:0992486d4a30 179 void LCPconfAck() {
nixnax 9:0992486d4a30 180 debug("LCP Ack\n");
nixnax 9:0992486d4a30 181 }
nixnax 9:0992486d4a30 182
nixnax 9:0992486d4a30 183 void LCPend(){
nixnax 9:0992486d4a30 184 debug("LCP End\n");
nixnax 9:0992486d4a30 185 ppp.online=0;
nixnax 9:0992486d4a30 186 ppp.pkt.buf[4]=6;
nixnax 9:0992486d4a30 187 sendFrame();
nixnax 9:0992486d4a30 188 }
nixnax 9:0992486d4a30 189
nixnax 9:0992486d4a30 190 void LCPother(){
nixnax 9:0992486d4a30 191 debug("LCP Other\n");
nixnax 9:0992486d4a30 192 generalFrame();
nixnax 9:0992486d4a30 193 }
nixnax 9:0992486d4a30 194
nixnax 9:0992486d4a30 195 void LCPframe(){
nixnax 9:0992486d4a30 196 int code = ppp.pkt.buf[4];
nixnax 9:0992486d4a30 197 switch (code) {
nixnax 9:0992486d4a30 198 case 1: LCPconfReq(); break;
nixnax 9:0992486d4a30 199 case 2: LCPconfAck(); break;
nixnax 9:0992486d4a30 200 case 5: LCPend(); break;
nixnax 9:0992486d4a30 201 default: LCPother();
nixnax 9:0992486d4a30 202 }
nixnax 9:0992486d4a30 203 }
nixnax 9:0992486d4a30 204
nixnax 9:0992486d4a30 205 void xx21frame() {
nixnax 9:0992486d4a30 206 debug("Unknown frame type ff 03 xx 21\n");
nixnax 9:0992486d4a30 207 }
nixnax 9:0992486d4a30 208
nixnax 9:0992486d4a30 209 void determinePacketType() {
nixnax 9:0992486d4a30 210 if ( ppp.pkt.buf[0] != 0xff ) {debug("byte0 != ff\n"); return;}
nixnax 9:0992486d4a30 211 if ( ppp.pkt.buf[1] != 3 ) {debug("byte1 != 3\n"); return;}
nixnax 9:0992486d4a30 212 if ( ppp.pkt.buf[3] != 0x21 ) {debug("byte2 != 21\n"); return;}
nixnax 9:0992486d4a30 213 int packetType = ppp.pkt.buf[2];
nixnax 9:0992486d4a30 214 switch (packetType) {
nixnax 9:0992486d4a30 215 case 0xc0: LCPframe(); break;
nixnax 9:0992486d4a30 216 case 0x80: IPCPframe(); break;
nixnax 9:0992486d4a30 217 case 0x00: IPframe(); break;
nixnax 9:0992486d4a30 218 default: xx21frame(); break;
nixnax 9:0992486d4a30 219 }
nixnax 9:0992486d4a30 220 }
nixnax 9:0992486d4a30 221
nixnax 9:0992486d4a30 222 void scanForConnectString() {
nixnax 9:0992486d4a30 223 if ( ppp.online==0 ) {
nixnax 9:0992486d4a30 224 char * clientFound = strstr( rxbuf, "CLIENTCLIENT" ); // look for PC string
nixnax 9:0992486d4a30 225 if( clientFound ) {
nixnax 9:0992486d4a30 226 strcpy( clientFound, "FOUND!FOUND!" ); // overwrite so we don't get fixated
nixnax 9:0992486d4a30 227 pc.printf("CLIENTSERVER"); // respond to PC
nixnax 9:0992486d4a30 228 ppp.online=1; // we can stop looking for the string
nixnax 9:0992486d4a30 229 debug("Connect string found\n");
nixnax 9:0992486d4a30 230 }
nixnax 9:0992486d4a30 231 }
nixnax 9:0992486d4a30 232 }
nixnax 9:0992486d4a30 233
nixnax 0:2cf4880c312a 234 int main()
nixnax 0:2cf4880c312a 235 {
nixnax 9:0992486d4a30 236 pc.baud(9600);
nixnax 4:a469050d5b80 237 xx.baud(115200);
nixnax 9:0992486d4a30 238 xx.puts("\x1b[2J\x1b[HReady\n"); // VT100 code for clear screen & home
nixnax 4:a469050d5b80 239
nixnax 9:0992486d4a30 240 pppInitStruct(); // initialize all the PPP properties
nixnax 4:a469050d5b80 241
nixnax 9:0992486d4a30 242 pc.attach(&rxHandler,Serial::RxIrq); // start the receive handler
nixnax 4:a469050d5b80 243
nixnax 9:0992486d4a30 244 int frameStartIndex, frameEndIndex; int frameBusy=0;
nixnax 4:a469050d5b80 245
nixnax 0:2cf4880c312a 246 while(1) {
nixnax 9:0992486d4a30 247 if ( ppp.online==0 ) scanForConnectString(); // try to connect
nixnax 0:2cf4880c312a 248 while ( pc_readable() ) {
nixnax 1:9e03798d4367 249 int rx = pc_getBuf();
nixnax 9:0992486d4a30 250 wait(0.001);
nixnax 4:a469050d5b80 251 if (frameBusy) {
nixnax 4:a469050d5b80 252 if (rx==FRAME_7E) {
nixnax 4:a469050d5b80 253 frameBusy=0; // done gathering frame
nixnax 4:a469050d5b80 254 frameEndIndex=ppp.rx.tail-1; // remember where frame ends
nixnax 4:a469050d5b80 255 void processFrame(int start, int end); // process a received frame
nixnax 4:a469050d5b80 256 processFrame(frameStartIndex, frameEndIndex);
nixnax 4:a469050d5b80 257 }
nixnax 4:a469050d5b80 258 }
nixnax 4:a469050d5b80 259 else {
nixnax 4:a469050d5b80 260 if (rx==FRAME_7E) {
nixnax 4:a469050d5b80 261 frameBusy=1; // start gathering frame
nixnax 9:0992486d4a30 262 frameStartIndex=ppp.rx.tail; // remember where frame started
nixnax 4:a469050d5b80 263 }
nixnax 0:2cf4880c312a 264 }
nixnax 4:a469050d5b80 265 }
nixnax 7:ab147f5e97ac 266 }
nixnax 7:ab147f5e97ac 267 }