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
Diff: main.cpp
- Revision:
- 114:8a5d70bbc1b2
- Parent:
- 113:d9666fe4d0ed
- Child:
- 115:b8ddff0e782f
diff -r d9666fe4d0ed -r 8a5d70bbc1b2 main.cpp --- a/main.cpp Sat Aug 05 08:45:32 2017 +0000 +++ b/main.cpp Sun Aug 06 10:29:41 2017 +0000 @@ -7,7 +7,7 @@ // Notes and Instructions // http://bit.ly/PPP-Blinky-Instructions -// http://bit.ly/win-rasdial-config +// http://bit.ly/win-rasdial-config // Handy reading material // https://technet.microsoft.com/en-us/library/cc957992.aspx @@ -37,31 +37,31 @@ // The #define below enables/disables a second (OPTIONAL) serial port that prints out interesting diagnostic messages. // Change to SERIAL_PORT_MONITOR_YES to enable diagnostics messages. You need to wire a second serial port to your mbed hardware to monitor this. // Note - the LPC11U24 does NOT have a second serial port -#define SERIAL_PORT_MONITOR_YES /* change to SERIAL_PORT_MONITOR_YES for debug messages */ +#define SERIAL_PORT_MONITOR_NO /* change to SERIAL_PORT_MONITOR_YES for debug messages */ // here we define the OPTIONAL, second debug serial port for the various target boards // insert your target board's port here if it's not in yet - if it works, please send it to me - thanks!!! -#if !defined(SERIAL_PORT_MONITOR_NO) -#if defined(TARGET_LPC1768) -Serial xx(p9, p10); // Second serial port on LPC1768 - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO -#elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_L053R8) || defined(TARGET_NUCLEO_L476RG) || defined(TARGET_NUCLEO_F401RE) -Serial xx(PC_10, PC_11); // Second serial port on NUCLEO boards - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO -#elif defined(TARGET_LPC11U24) -#error The LPC11U24 does not have a second serial port to use for debugging - change SERIAL_PORT_MONITOR_YES back to SERIAL_PORT_MONITOR_NO +#ifdef SERIAL_PORT_MONITOR_YES + #if defined(TARGET_LPC1768) + Serial xx(p9, p10); // Second serial port on LPC1768 - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO + #elif defined(TARGET_NUCLEO_F446RE) || defined(TARGET_NUCLEO_L152RE) || defined(TARGET_NUCLEO_L053R8) || defined(TARGET_NUCLEO_L476RG) || defined(TARGET_NUCLEO_F401RE) + Serial xx(PC_10, PC_11); // Second serial port on NUCLEO boards - not required to run, if you get compile error here, change #define SERIAL_PORT_MONITOR_YES to #define SERIAL_PORT_MONITOR_NO + #elif defined(TARGET_LPC11U24) + #error The LPC11U24 does not have a second serial port to use for debugging - change SERIAL_PORT_MONITOR_YES back to SERIAL_PORT_MONITOR_NO + #else + #error Add your target board's second serial port here if you want to use debugging - or choose SERIAL_PORT_MONITOR_NO + #endif + #define debug(x...) xx.printf (x) /* if we have a serial port we print debug messages */ #else -#error Add your target board's second serial port here if you want to use debugging - or choose SERIAL_PORT_MONITOR_NO -#endif - -#define debug(x...) xx.printf (x) /* if we have a serial port we print debug messages */ - -#else -#define debug(x...) {} /* if we don't have a serial port we do nothing */ + #define debug(x...) {} /* if we don't have a serial port we do nothing */ #endif // verbosity flags used in debug printouts - change to 1 to see increasingly more detailed debug info. #define v0 1 #define v1 0 #define v2 0 +#define IP_HEADER_DUMP_YES /* YES for ip header dump */ +#define TCP_HEADER_DUMP_YES /* YES for tcp header dump */ // this is the webpage we serve when we get an HTTP request to root (/) // keep size under ~900 bytes to fit into a single PPP packet @@ -98,7 +98,6 @@ // a structure to keep all our ppp globals in struct pppType { int online; // we hunt for a PPP connection if this is zero - unsigned int ident; // our IP ident value int crc; // for calculating IP and TCP CRCs int ledState; // state of LED1 int httpPageCount; @@ -121,6 +120,9 @@ int frameStartIndex; // frame start marker int frameEndIndex; // frame end marker } hdlc; // hdlc frame objects + struct { + unsigned int ident; // our IP ident value (outgoing frame count) + } ip; // ip related object }; pppType ppp; // our global - definitely not thread safe @@ -135,7 +137,7 @@ ppp.rx.head=0; ppp.rx.buflevel=0; ppp.pkt.len=0; - ppp.ident=1000; + ppp.ip.ident=10000; // easy to recognize in ip packet dumps ppp.ledState=0; ppp.hdlc.frameStartIndex=0; ppp.httpPageCount=0; @@ -183,8 +185,8 @@ if (ch == 0x7E) { ppp.online = 1; debug("HDLC Frame (0x7E)\n"); - } - } + } + } ppp.rx.head = hd; // update head pointer ppp.rx.buflevel++; } @@ -365,7 +367,6 @@ unsigned int dataCheckSum(unsigned char * ptr, int len) { - unsigned int sum=0; unsigned char placeHolder; if (len&1) { @@ -472,85 +473,78 @@ void IGMPpacket() // internet group management protocol { - if (v0) { - debug("IGMP type=%d \n", ppp.pkt.buf[28]); - } + if (v0) debug("IGMP type=%d \n", ppp.pkt.buf[28]); } -void dumpHeaderIP () +void dumpHeaderIP (int outGoing) { - if (v0) { - char * ipPkt = ppp.pkt.buf+4; // ip packet start -#ifndef SERIAL_PORT_MONITOR_NO - char * version = ipPkt; // top 4 bits - char * ihl = ipPkt; // bottom 4 bits - char * dscp = ipPkt+1; // top 6 bits - char * ecn = ipPkt+1; // lower 2 bits - char * pktLen = ipPkt+2; // 2 bytes - char * ident = ipPkt+4; // 2 bytes - char * flags = ipPkt+6; // 2 bits - char * ttl = ipPkt+8; // 1 byte - char * protocol = ipPkt+9; // 1 byte - char * headercheck= ipPkt+10; // 2 bytes +#if defined(IP_HEADER_DUMP_YES) && defined(SERIAL_PORT_MONITOR_YES) + char * ipPkt = ppp.pkt.buf+4; // ip packet start + char * ident = ipPkt+4; // 2 bytes + char * srcAdr = ipPkt+12; // 4 bytes + char * dstAdr = ipPkt+16; // 4 bytes = total of 20 bytes +#ifdef UNUSED_IP_VARIABLES + char * version = ipPkt; // top 4 bits + char * ihl = ipPkt; // bottom 4 bits + char * dscp = ipPkt+1; // top 6 bits + char * ecn = ipPkt+1; // lower 2 bits + char * pktLen = ipPkt+2; // 2 bytes + char * flags = ipPkt+6; // 2 bits + char * ttl = ipPkt+8; // 1 byte + char * protocol = ipPkt+9; // 1 byte + char * headercheck= ipPkt+10; // 2 bytes + int versionIP = (version[0]>>4)&0xf; + int headerSizeIP = (ihl[0]&0xf)*4; + int dscpIP = (dscp[0]>>2)&0x3f; + int ecnIP = ecn[0]&3; + int packetLength = (pktLen[0]<<8)|pktLen[1]; // ip total packet length + int flagsIP = flags[0]>>14&3; + int ttlIP = ttl[0]; + int protocolIP = protocol[0]; + unsigned int checksumIP = (headercheck[0]<<8)|headercheck[1]; #endif - char * srcAdr = ipPkt+12; // 4 bytes - char * dstAdr = ipPkt+16; // 4 bytes = total of 20 bytes - -#ifndef SERIAL_PORT_MONITOR_NO - int versionIP = (version[0]>>4)&0xf; - int headerSizeIP = (ihl[0]&0xf)*4; - int dscpIP = (dscp[0]>>2)&0x3f; - int ecnIP = ecn[0]&3; - int packetLength = (pktLen[0]<<8)|pktLen[1]; // ip total packet length - int identIP = (ident[0]<<8)|ident[1]; - int flagsIP = flags[0]>>14&3; - int ttlIP = ttl[0]; - int protocolIP = protocol[0]; - unsigned int checksumIP = (headercheck[0]<<8)|headercheck[1]; + int identIP = (ident[0]<<8)|ident[1]; +#ifndef DUMP_FULL_IP_ADDRESS + xx.printf("IP %d.%d.%d.%d %d.%d.%d.%d ",srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3], dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]); // full ip addresses +#else + xx.printf("IP %d %d ",srcAdr[3], dstAdr[3]); // short format - only least significant byte of the ip addresses #endif - - char srcIP [16]; - snprintf(srcIP,16, "%d.%d.%d.%d", srcAdr[0],srcAdr[1],srcAdr[2],srcAdr[3]); - char dstIP [16]; - snprintf(dstIP,16, "%d.%d.%d.%d", dstAdr[0],dstAdr[1],dstAdr[2],dstAdr[3]); - debug("IP %s %s v%d h%d d%d e%d L%03d ",srcIP,dstIP,versionIP,headerSizeIP,dscpIP,ecnIP,packetLength); - debug("i%04x f%d t%d p%d C%04x\n",identIP,flagsIP,ttlIP,protocolIP,checksumIP); - while ( pc.readable() ) fillbuf(); - } + xx.printf("Ident %05d ",identIP); // ident is a good way to correlate our dumps with net monitor or wireshark traces +#ifndef TCP_HEADER_DUMP_YES + xx.putc('\n'); // there is no TCP header dump, so terminate the line with \n +#endif +#endif } -void dumpHeaderTCP() +void dumpHeaderTCP(int outGoing) { - if( v0 ) { - int headerSizeIP = (ppp.pkt.buf[4]&0xf)*4; // header size of ip portion - char * tcpStart = ppp.pkt.buf+4+headerSizeIP; // start of tcp packet -#ifndef SERIAL_PORT_MONITOR_NO - char * seqtcp = tcpStart + 4; // 4 bytes - char * acktcp = tcpStart + 8; // 4 bytes -#endif - char * flagbitstcp = tcpStart + 12; // 9 bits -#ifndef SERIAL_PORT_MONITOR_NO - unsigned int seq = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]); - unsigned int ack = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]); -#endif - int flags = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; +#if defined(TCP_HEADER_DUMP_YES) && defined(SERIAL_PORT_MONITOR_YES) + int headerSizeIP = (ppp.pkt.buf[4]&0xf)*4; // header size of ip portion + char * tcpStart = ppp.pkt.buf+4+headerSizeIP; // start of tcp packet + char * seqtcp = tcpStart + 4; // 4 bytes + char * acktcp = tcpStart + 8; // 4 bytes + char * flagbitstcp = tcpStart + 12; // 9 bits + unsigned int seq = (seqtcp[0]<<24)|(seqtcp[1]<<16)|(seqtcp[2]<<8)|(seqtcp[3]); + unsigned int ack = (acktcp[0]<<24)|(acktcp[1]<<16)|(acktcp[2]<<8)|(acktcp[3]); + if (seq && ack) {} // shut up the compiler about unused variables + int flags = ((flagbitstcp[0]&1)<<8)|flagbitstcp[1]; - char flagInfo[10]; // text string presentating the TCP flags - memset(flagInfo,'.', 9); // fill string with "........." - memset(flagInfo+9,0,1); // null terminate string + char flagInfo[9]; // text string presentating the 8 most important TCP flags + memset(flagInfo,'.', 8); // fill string with "........" + flagInfo[8]=0; // null terminate string - if (flags & (1<<0)) flagInfo[8]='F'; - if (flags & (1<<1)) flagInfo[7]='S'; - if (flags & (1<<2)) flagInfo[6]='R'; - if (flags & (1<<3)) flagInfo[5]='P'; - if (flags & (1<<4)) flagInfo[4]='A'; - if (flags & (1<<5)) flagInfo[3]='U'; - if (flags & (1<<6)) flagInfo[2]='E'; - if (flags & (1<<7)) flagInfo[1]='C'; - if (flags & (1<<8)) flagInfo[0]='N'; - debug("TCP Flags %s Seq %u Ack %u\n", flagInfo, seq, ack); // show the flags in debug - while ( pc.readable() ) fillbuf(); - } + if (flags & (1<<0)) flagInfo[7]='F'; + if (flags & (1<<1)) flagInfo[6]='S'; + if (flags & (1<<2)) flagInfo[5]='R'; + if (flags & (1<<3)) flagInfo[4]='P'; + if (flags & (1<<4)) flagInfo[3]='A'; + if (flags & (1<<5)) flagInfo[2]='U'; + if (flags & (1<<6)) flagInfo[1]='E'; + if (flags & (1<<7)) flagInfo[0]='C'; + xx.printf("%s Seq %10u\n", flagInfo, seq); // tcp flags and the sequence number + if( (flags == (1<<4)) && outGoing ) // if this is a pure ack its probably then of the TCP link + xx.putc('\n'); // so insert an extra line to mark the end of the conversation +#endif } int httpResponse(char * dataStart) @@ -566,7 +560,7 @@ xFetch = strncmp(dataStart, "GET /x", 6); // found GET /x , respond to both HTTP/1.<anything> // for example, in linux, xFetch can be used as: echo GET /x | nc 172.10.10.2 if( (httpGetRoot==0) || (xFetch==0) ) { - n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK\r\nServer: mbed-PPP-Blinky\r\n"); // 200 OK header + n=n+sprintf(n+dataStart,"HTTP/1.1 200 OK \r\nServer: mbed-PPP-Blinky \r\n"); // 200 OK header } else { n=n+sprintf(n+dataStart,"HTTP/1.1 404 Not Found\r\nServer: mbed-PPP-Blinky\r\n"); // 404 header } @@ -695,14 +689,12 @@ windowsizetcp[0]=2; // tcp window size = 700 windowsizetcp[1]=0xbc; // tcp windows size = 700 - int doFin = 0; // flag to see if we have to send an extra FIN message to shut down the link - // A sparse TCP flag interpreter that implements stateless TCP connections switch ( flagsTCP ) { case TCP_FLAG_SYN: flagsOut = TCP_FLAG_SYN | TCP_FLAG_ACK; // something wants to connect - acknowledge it - seq_out = seq_in+0x1000U; // create a new sequence number using their sequence as a base + seq_out = seq_in+0x10000000U; // create a new sequence number using their sequence as a base ack_out++; // for SYN flag we have to increase the sequence by 1 break; case TCP_FLAG_ACK | TCP_FLAG_PSH: @@ -715,7 +707,6 @@ break; case TCP_FLAG_FIN | TCP_FLAG_PSH | TCP_FLAG_ACK: case TCP_FLAG_FIN | TCP_FLAG_ACK: - case TCP_FLAG_RST: ack_out++; // for FIN flag we always have to increase sequence by 1 break; case TCP_FLAG_FIN: @@ -737,8 +728,6 @@ memcpy(srctcp, dsttcp,2); memcpy(dsttcp, tempHold,2); // swap ip port source/dest -sendTCP: - acktcp[0]=ack_out>>24; acktcp[1]=ack_out>>16; acktcp[2]=ack_out>>8; @@ -751,10 +740,10 @@ flagbitstcp[1] = flagsOut; // update the TCP flags - // increment the ip ident number - ppp.ident++; // get next ident number for our packet - ident[0] = ppp.ident>>8; - ident[1] = ppp.ident>>0; // insert OUR ident + // increment our outgoing ip packet counter + ppp.ip.ident++; // get next ident number for our packet + ident[0] = ppp.ip.ident>>8; + ident[1] = ppp.ip.ident>>0; // insert OUR ident // Now we recalculate all the header sizes int newPacketSize = headerSizeIP + headerSizeTCP + dataLen; // calculate size of the outgoing packet @@ -786,17 +775,10 @@ checksumtcp[0]=pseudoHeaderSum>>8; checksumtcp[1]=pseudoHeaderSum; memcpy( tcp-12, tempHold, 12); // restore the 12 bytes that the pseudo-header overwrote - -// dumpHeaderIP(); -// dumpHeaderTCP(); - + dumpHeaderIP(1); // dump outgoing IP header + dumpHeaderTCP(1); // dump outgoing TCP header + wait_ms(8); // wait long enoug to get 90 characters printed at 115200 bps send_pppFrame(); // All preparation complete - send the TCP response - - if (doFin==1) { // they want to shut down the link, so we have to send another packet to close our side of the link - doFin=0; - flagsOut = TCP_FLAG_ACK | TCP_FLAG_FIN; // tell them we are also finished - goto sendTCP; // send our final packet for this conversation. - } } void dumpDataTCP() @@ -816,8 +798,8 @@ void TCPpacket() { - dumpHeaderIP(); - dumpHeaderTCP(); + dumpHeaderIP(0); // dump incoming packet header + dumpHeaderTCP(0); // dump incoming packet header if (v2) { dumpDataTCP(); } @@ -951,9 +933,9 @@ int rx = pc_getBuf(); // get the character if (rx==FRAME_7E) { ppp.hdlc.frameEndIndex=oldTail; // mark the frame end character - + processHDLCFrame(ppp.hdlc.frameStartIndex, ppp.hdlc.frameEndIndex); // process the frame - + ppp.rx.rtail = ppp.rx.tail; ppp.hdlc.frameStartIndex = ppp.rx.tail; // where next frame will start break; @@ -965,7 +947,7 @@ void scanForConnectString() { while(ppp.online == 0) { - fillbuf(); + fillbuf(); // gather received characters // search for Windows Dialup Networking "Direct Connection Between Two Computers" expected connect string char * found1 = strstr( (char *)ppp.rx.buf, "CLIENT" ); if (found1 != NULL) { @@ -984,6 +966,22 @@ + + + + + + + + + + + + + + + + int main() { pc.baud(115200); // USB virtual serial port