RealtimeCompLab2
Dependencies: mbed
Fork of PPP-Blinky by
main.cpp@5:27624c02189f, 2016-12-29 (annotated)
- 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?
User | Revision | Line number | New 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 | } |