RealtimeCompLab2

Dependencies:   mbed

Fork of PPP-Blinky by Nicolas Nackel

Committer:
nixnax
Date:
Thu Dec 29 16:31:48 2016 +0000
Revision:
7:ab147f5e97ac
Parent:
6:fba4c2e817b8
Child:
8:48e40f1ff316
Fairly close on IP setup - one IPCP Conf Req is troublesome. PC won't Ack it.

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 6:fba4c2e817b8 9 // Nice 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 6:fba4c2e817b8 13
nixnax 6:fba4c2e817b8 14 Serial pc(USBTX, USBRX); // The USB com port - Set this up as a Dial-Up Modem on your pc
nixnax 4:a469050d5b80 15 Serial xx(PC_10, PC_11); // debug port - use a second USB serial port to monitor
nixnax 0:2cf4880c312a 16
nixnax 4:a469050d5b80 17 DigitalOut led1(LED1);
nixnax 4:a469050d5b80 18
nixnax 4:a469050d5b80 19 #define FRAME_7E (0x7e)
nixnax 4:a469050d5b80 20 #define BUFLEN (1<<14)
nixnax 4:a469050d5b80 21 char rxbuf[BUFLEN];
nixnax 4:a469050d5b80 22 char frbuf[3000]; // buffer for ppp frame
nixnax 0:2cf4880c312a 23
nixnax 4:a469050d5b80 24 struct {
nixnax 4:a469050d5b80 25 int online;
nixnax 4:a469050d5b80 26 struct {
nixnax 4:a469050d5b80 27 char * buf;
nixnax 4:a469050d5b80 28 int head;
nixnax 4:a469050d5b80 29 int tail;
nixnax 4:a469050d5b80 30 } rx; // serial port buffer
nixnax 4:a469050d5b80 31 struct {
nixnax 6:fba4c2e817b8 32 int id;
nixnax 4:a469050d5b80 33 int len;
nixnax 4:a469050d5b80 34 int crc;
nixnax 4:a469050d5b80 35 char * buf;
nixnax 4:a469050d5b80 36 } pkt; // ppp buffer
nixnax 4:a469050d5b80 37 } ppp;
nixnax 0:2cf4880c312a 38
nixnax 4:a469050d5b80 39 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 40
nixnax 4:a469050d5b80 41 int crcG; // frame check sequence (CRC) holder
nixnax 4:a469050d5b80 42 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 43 void crcReset(){crcG=0xffff;} // crc restart
nixnax 0:2cf4880c312a 44
nixnax 0:2cf4880c312a 45 void rxHandler() // serial port receive interrupt handler
nixnax 0:2cf4880c312a 46 {
nixnax 4:a469050d5b80 47 ppp.rx.buf[ppp.rx.head]=pc.getc(); // insert in buffer
nixnax 0:2cf4880c312a 48 __disable_irq();
nixnax 4:a469050d5b80 49 ppp.rx.head=(ppp.rx.head+1)&(BUFLEN-1);
nixnax 0:2cf4880c312a 50 __enable_irq();
nixnax 0:2cf4880c312a 51 }
nixnax 0:2cf4880c312a 52
nixnax 0:2cf4880c312a 53 int pc_readable() // check if buffer has data
nixnax 0:2cf4880c312a 54 {
nixnax 4:a469050d5b80 55 return (ppp.rx.head==ppp.rx.tail) ? 0 : 1 ;
nixnax 0:2cf4880c312a 56 }
nixnax 0:2cf4880c312a 57
nixnax 0:2cf4880c312a 58 int pc_getBuf() // get one character from the buffer
nixnax 0:2cf4880c312a 59 {
nixnax 0:2cf4880c312a 60 if (pc_readable()) {
nixnax 4:a469050d5b80 61 int x = ppp.rx.buf[ ppp.rx.tail ];
nixnax 4:a469050d5b80 62 ppp.rx.tail=(ppp.rx.tail+1)&(BUFLEN-1);
nixnax 0:2cf4880c312a 63 return x;
nixnax 0:2cf4880c312a 64 }
nixnax 0:2cf4880c312a 65 return -1;
nixnax 0:2cf4880c312a 66 }
nixnax 0:2cf4880c312a 67
nixnax 4:a469050d5b80 68 void scanForConnectString(); // scan for connect attempts from pc
nixnax 1:9e03798d4367 69
nixnax 0:2cf4880c312a 70 int main()
nixnax 0:2cf4880c312a 71 {
nixnax 6:fba4c2e817b8 72 pc.baud(19200);
nixnax 4:a469050d5b80 73 xx.baud(115200);
nixnax 4:a469050d5b80 74 xx.puts("\x1b[2J\x1b[H"); // VT100 terminal control code for screen clear/home
nixnax 4:a469050d5b80 75
nixnax 4:a469050d5b80 76 pppInitStruct(); // structure containing all the PPP stuff
nixnax 4:a469050d5b80 77
nixnax 0:2cf4880c312a 78 pc.attach(&rxHandler,Serial::RxIrq); // activate the receive interrupt handler
nixnax 4:a469050d5b80 79
nixnax 4:a469050d5b80 80 int frameStartIndex, frameEndIndex;
nixnax 4:a469050d5b80 81 int frameBusy=0;
nixnax 4:a469050d5b80 82
nixnax 0:2cf4880c312a 83 while(1) {
nixnax 0:2cf4880c312a 84 while ( pc_readable() ) {
nixnax 1:9e03798d4367 85 int rx = pc_getBuf();
nixnax 4:a469050d5b80 86 if (frameBusy) {
nixnax 4:a469050d5b80 87 if (rx==FRAME_7E) {
nixnax 4:a469050d5b80 88 frameBusy=0; // done gathering frame
nixnax 4:a469050d5b80 89 frameEndIndex=ppp.rx.tail-1; // remember where frame ends
nixnax 4:a469050d5b80 90 void processFrame(int start, int end); // process a received frame
nixnax 4:a469050d5b80 91 processFrame(frameStartIndex, frameEndIndex);
nixnax 4:a469050d5b80 92 }
nixnax 4:a469050d5b80 93 }
nixnax 4:a469050d5b80 94 else {
nixnax 4:a469050d5b80 95 if (rx==FRAME_7E) {
nixnax 4:a469050d5b80 96 frameBusy=1; // start gathering frame
nixnax 4:a469050d5b80 97 frameStartIndex=ppp.rx.tail; // remember where frame starts
nixnax 4:a469050d5b80 98 }
nixnax 0:2cf4880c312a 99 }
nixnax 4:a469050d5b80 100 }
nixnax 4:a469050d5b80 101 if (ppp.online==0) scanForConnectString(); // try to connect
nixnax 4:a469050d5b80 102 }
nixnax 4:a469050d5b80 103 }
nixnax 4:a469050d5b80 104
nixnax 4:a469050d5b80 105 void processFrame(int start, int end) {
nixnax 4:a469050d5b80 106 crcReset();
nixnax 4:a469050d5b80 107 char * dest = ppp.pkt.buf;
nixnax 4:a469050d5b80 108 ppp.pkt.len=0;
nixnax 4:a469050d5b80 109 int special=0;
nixnax 4:a469050d5b80 110 for (int i=start; i<end; i++) {
nixnax 4:a469050d5b80 111 if (special==0) {
nixnax 4:a469050d5b80 112 if (rxbuf[i]==0x7d) special=1;
nixnax 4:a469050d5b80 113 else { *dest++ = rxbuf[i]; ppp.pkt.len++; crcDo(rxbuf[i]);}
nixnax 4:a469050d5b80 114 } else {
nixnax 4:a469050d5b80 115 *dest++ = rxbuf[i]-32; ppp.pkt.len++; crcDo(rxbuf[i]-32);
nixnax 4:a469050d5b80 116 special=0;
nixnax 0:2cf4880c312a 117 }
nixnax 0:2cf4880c312a 118 }
nixnax 4:a469050d5b80 119 ppp.rx.head=0; // reuse rxbuf
nixnax 4:a469050d5b80 120 ppp.rx.tail=0; // reuse rxbuf
nixnax 6:fba4c2e817b8 121 ppp.pkt.crc = crcG;
nixnax 6:fba4c2e817b8 122 if (crcG == 0xf0b8) { // check for good CRC
nixnax 6:fba4c2e817b8 123 void determinePacketType(); // declare early
nixnax 6:fba4c2e817b8 124 determinePacketType();
nixnax 6:fba4c2e817b8 125 }
nixnax 0:2cf4880c312a 126 }
nixnax 4:a469050d5b80 127
nixnax 6:fba4c2e817b8 128
nixnax 7:ab147f5e97ac 129 void generalFrame() {
nixnax 7:ab147f5e97ac 130 xx.printf("== General Frame ==\n");
nixnax 7:ab147f5e97ac 131 for(int i=0;i<ppp.pkt.len;i++) xx.printf("%02x ", ppp.pkt.buf[i]);
nixnax 7:ab147f5e97ac 132 xx.printf(" C %02x %02x L=%d\n", ppp.pkt.crc&0xff, (ppp.pkt.crc>>8)&0xff, ppp.pkt.len);
nixnax 7:ab147f5e97ac 133 }
nixnax 7:ab147f5e97ac 134
nixnax 7:ab147f5e97ac 135
nixnax 4:a469050d5b80 136 void sendFrame(){
nixnax 4:a469050d5b80 137 crcReset(); for(int i=0;i<ppp.pkt.len-2;i++) crcDo(ppp.pkt.buf[i]);
nixnax 6:fba4c2e817b8 138 ppp.pkt.buf[ ppp.pkt.len-2 ] = ((~crcG)>>0); // build crc lo
nixnax 6:fba4c2e817b8 139 ppp.pkt.buf[ ppp.pkt.len-1 ] = ((~crcG)>>8); // build crc hi
nixnax 6:fba4c2e817b8 140 pc.putc(0x7e); // start of frame
nixnax 4:a469050d5b80 141 for(int i=0;i<ppp.pkt.len;i++) {
nixnax 4:a469050d5b80 142 unsigned int cc = (unsigned int)ppp.pkt.buf[i];
nixnax 6:fba4c2e817b8 143 if (cc>32) pc.putc(cc); else {pc.putc(0x7d);pc.putc(cc+32);}
nixnax 4:a469050d5b80 144 }
nixnax 6:fba4c2e817b8 145 pc.putc(0x7e); // end of frame
nixnax 4:a469050d5b80 146 }
nixnax 4:a469050d5b80 147
nixnax 6:fba4c2e817b8 148
nixnax 6:fba4c2e817b8 149
nixnax 4:a469050d5b80 150 void LCPrequestFrame() {
nixnax 7:ab147f5e97ac 151 xx.printf("== LCP Request ==\n");
nixnax 7:ab147f5e97ac 152 if (ppp.pkt.buf[7] != 4) {
nixnax 7:ab147f5e97ac 153 ppp.pkt.buf[4]=4; // nack everything until zero len
nixnax 7:ab147f5e97ac 154 sendFrame();
nixnax 7:ab147f5e97ac 155 } else {
nixnax 7:ab147f5e97ac 156 ppp.pkt.buf[4]=2; // ack zero conf
nixnax 7:ab147f5e97ac 157 sendFrame();
nixnax 7:ab147f5e97ac 158 // send our config request - also all zeros
nixnax 7:ab147f5e97ac 159 ppp.pkt.buf[4]=1; // request zero conf
nixnax 7:ab147f5e97ac 160 sendFrame();
nixnax 7:ab147f5e97ac 161 }
nixnax 7:ab147f5e97ac 162 }
nixnax 5:27624c02189f 163
nixnax 7:ab147f5e97ac 164
nixnax 7:ab147f5e97ac 165
nixnax 4:a469050d5b80 166
nixnax 4:a469050d5b80 167 void LCPackFrame() {
nixnax 7:ab147f5e97ac 168 xx.printf("== Saw Ack - PPP is up ==\n");
nixnax 5:27624c02189f 169 }
nixnax 4:a469050d5b80 170
nixnax 4:a469050d5b80 171
nixnax 6:fba4c2e817b8 172 void rejectIPcompression() {
nixnax 6:fba4c2e817b8 173 xx.printf("== IP Compression Reject Frame ==\n");
nixnax 6:fba4c2e817b8 174 generalFrame();
nixnax 6:fba4c2e817b8 175 static char rejectCompression [] = {0x80,0x21,4,0,0,10,2,6,0,45,15,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
nixnax 6:fba4c2e817b8 176 // 128/33=IPCP 4=Rej 0=id 0=sizeHigh 10=sizeLow 2,6,0,45,1=RejectCcompression
nixnax 6:fba4c2e817b8 177 ppp.pkt.len=sizeof( rejectCompression );
nixnax 6:fba4c2e817b8 178 memcpy( rejectCompression, ppp.pkt.buf, ppp.pkt.len);
nixnax 6:fba4c2e817b8 179 ppp.pkt.buf[3]=ppp.pkt.id;
nixnax 6:fba4c2e817b8 180 sendFrame();
nixnax 6:fba4c2e817b8 181 }
nixnax 6:fba4c2e817b8 182
nixnax 6:fba4c2e817b8 183 void ipRequestHandler(){
nixnax 6:fba4c2e817b8 184 xx.printf("== IP Request Frame ==\n");
nixnax 7:ab147f5e97ac 185 if( ppp.pkt.buf[7] != 10 ) {
nixnax 7:ab147f5e97ac 186 ppp.pkt.buf[4]=4; // Nack
nixnax 7:ab147f5e97ac 187 sendFrame(); // we want minimum config
nixnax 7:ab147f5e97ac 188 } else {
nixnax 7:ab147f5e97ac 189 ppp.pkt.buf[4]=2; // ack the minimum
nixnax 7:ab147f5e97ac 190 ppp.pkt.buf[10]=10; // ip addr 1
nixnax 7:ab147f5e97ac 191 ppp.pkt.buf[11]=10; // ip addr 2
nixnax 7:ab147f5e97ac 192 ppp.pkt.buf[12]=10; // ip addr 3
nixnax 7:ab147f5e97ac 193 ppp.pkt.buf[13]=10; // ip addr 4
nixnax 7:ab147f5e97ac 194 sendFrame(); // acknowledge
nixnax 7:ab147f5e97ac 195 xx.printf("zeroconf ack\n");
nixnax 7:ab147f5e97ac 196 // send our own request now
nixnax 7:ab147f5e97ac 197 ppp.pkt.buf[4]=1; // request the minimum
nixnax 7:ab147f5e97ac 198 ppp.pkt.buf[5]++; // next sequence
nixnax 7:ab147f5e97ac 199 sendFrame(); // this is our request
nixnax 7:ab147f5e97ac 200 }
nixnax 6:fba4c2e817b8 201 }
nixnax 6:fba4c2e817b8 202
nixnax 6:fba4c2e817b8 203 void ipAckHandler(){
nixnax 6:fba4c2e817b8 204 xx.printf("== IP Ack Frame ==\n");
nixnax 6:fba4c2e817b8 205 }
nixnax 6:fba4c2e817b8 206
nixnax 6:fba4c2e817b8 207 void ipNackHandler(){
nixnax 6:fba4c2e817b8 208 xx.printf("== IP Nack Frame ==\n");
nixnax 6:fba4c2e817b8 209 }
nixnax 6:fba4c2e817b8 210
nixnax 6:fba4c2e817b8 211 void ipDefaultHandler(){
nixnax 6:fba4c2e817b8 212 xx.printf("== IP Unknown Frame ==\n");
nixnax 6:fba4c2e817b8 213 }
nixnax 6:fba4c2e817b8 214
nixnax 6:fba4c2e817b8 215 void LCPgeneralFrame(){
nixnax 6:fba4c2e817b8 216 xx.printf("== LCP General Handler ==\n");
nixnax 6:fba4c2e817b8 217 generalFrame();
nixnax 6:fba4c2e817b8 218 }
nixnax 6:fba4c2e817b8 219
nixnax 6:fba4c2e817b8 220
nixnax 6:fba4c2e817b8 221 void LCPhandler(){
nixnax 6:fba4c2e817b8 222 int action = ppp.pkt.buf[4];
nixnax 6:fba4c2e817b8 223 if(0);
nixnax 6:fba4c2e817b8 224 else if ( action == 1 ) LCPrequestFrame();
nixnax 6:fba4c2e817b8 225 else if ( action == 2 ) LCPackFrame();
nixnax 6:fba4c2e817b8 226 else LCPgeneralFrame();
nixnax 6:fba4c2e817b8 227 }
nixnax 6:fba4c2e817b8 228
nixnax 6:fba4c2e817b8 229 void IPFrame() {
nixnax 7:ab147f5e97ac 230 led1 = ppp.pkt.buf[5] & 1; // This is the sequence number so the led blinks on packets
nixnax 7:ab147f5e97ac 231 //ppp.pkt.len = (((unsigned int)ppp.pkt.buf[4])<<8) + (((unsigned int)ppp.pkt.buf[5])<<0);
nixnax 7:ab147f5e97ac 232 ppp.pkt.id = ppp.pkt.buf[5]; // remember the sequence number
nixnax 7:ab147f5e97ac 233 int action = ppp.pkt.buf[4]; // packet type is here
nixnax 6:fba4c2e817b8 234 if(0);
nixnax 6:fba4c2e817b8 235 else if ( action == 1 ) ipRequestHandler();
nixnax 6:fba4c2e817b8 236 else if ( action == 2 ) ipAckHandler();
nixnax 6:fba4c2e817b8 237 else if ( action == 3 ) ipNackHandler();
nixnax 6:fba4c2e817b8 238 else ipDefaultHandler();
nixnax 4:a469050d5b80 239 }
nixnax 4:a469050d5b80 240
nixnax 4:a469050d5b80 241 void determinePacketType() {
nixnax 7:ab147f5e97ac 242 static char pktLCPReqType [] = { 0xff, 3, 0xc0, 0x21 }; // LCP packet
nixnax 7:ab147f5e97ac 243 static char pktIPCPtype [] = { 0xff, 3, 0x80, 0x21, }; // IP packet
nixnax 6:fba4c2e817b8 244
nixnax 4:a469050d5b80 245 if(0);
nixnax 6:fba4c2e817b8 246 else if (0==memcmp( ppp.pkt.buf,pktLCPReqType,4)) LCPhandler();
nixnax 7:ab147f5e97ac 247 else if (0==memcmp( ppp.pkt.buf,pktIPCPtype, 4)) IPFrame();
nixnax 4:a469050d5b80 248 else generalFrame(); // default handler
nixnax 4:a469050d5b80 249 }
nixnax 4:a469050d5b80 250
nixnax 4:a469050d5b80 251 void scanForConnectString(){
nixnax 4:a469050d5b80 252 char * clientFound = strstr( rxbuf, "CLIENTCLIENT" ); // look for PC string
nixnax 4:a469050d5b80 253 if( clientFound ) {
nixnax 4:a469050d5b80 254 strcpy( clientFound, "FOUND!FOUND!" ); // overwrite so we don't get fixated
nixnax 4:a469050d5b80 255 pc.printf("CLIENTSERVER"); // respond to PC
nixnax 4:a469050d5b80 256 }
nixnax 4:a469050d5b80 257 }