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: PPP-Blinky/ppp-blinky.cpp
- Revision:
- 184:4133f557d4d4
- Parent:
- 183:6d3ba874b267
- Child:
- 185:4cd8f91e9d49
--- a/PPP-Blinky/ppp-blinky.cpp Mon Sep 11 18:00:26 2017 +0000 +++ b/PPP-Blinky/ppp-blinky.cpp Mon Sep 11 23:33:27 2017 +0000 @@ -797,9 +797,9 @@ } /// Encode a buffer in base-64 +const static char lut [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; void enc64(char * in, char * out, int len) { - const static char lut [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; int i,j,a,b,c; i=0; j=0; @@ -828,20 +828,27 @@ int webSocketHandler(char * dataStart) { int n=0; // byte counter - char * key = strstr(dataStart, "Sec-WebSocket-Key: "); // search for the key in the payload + char * key = strstr(dataStart, "Sec-WebSocket-Key:"); // search for the key in the payload if (key != NULL) { + key = key + 18; // skip over the key ident string "Sec-WebSocket-Key:" if (v0) putsWhileCheckingInput("WebSocket Request\n"); - char challenge [70]; - strncpy(challenge,key+19,70); // a local buffer - *strchr(challenge,'\r')=0; // insert null so we can use sprintf - strncat(challenge,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",70); // append websocket gui code + while ( strchr(lut, *key) == NULL) key++; // skip non-valid base-64 characters (whitespace) + char challenge [80]; + int i=0; + char * copyTo = challenge; + while (strchr(lut, *key) != NULL) { // copy while we see valid base-64 characters + if (i++ >40) break; // prevent buffer overflow + *copyTo++ = *key++; // copy next valid base-64 character + } + strcpy(copyTo,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); // append websocket gui code + if (0) debugPrintf("Challenge is %s\n", challenge); // the string we hash for the challenge char shaOutput [20]; // sha1 output - sha1( shaOutput, challenge, strlen(challenge)); + sha1( shaOutput, challenge, strlen(challenge)); // hash the challenge char encOut[50]; - enc64( shaOutput, encOut, 20); + enc64( shaOutput, encOut, 20); // base-64 encode char * versionstring = strstr(dataStart, "Sec-WebSocket-Version:"); char * version = challenge; - strncpy(version, versionstring,70); // copy version string + strncpy(version, versionstring,70); // copy their version string *strchr(version,'\r')=0; // null terminate so we can sprintf it memset(dataStart,0,500); // blank out old data befor send the websocket response header n=n+sprintf(dataStart+n, "HTTP/1.1 101 Switching Protocols\r\n"); @@ -942,7 +949,9 @@ n=2; // our close command is only two bytes long because we don't use the four mask bytes dataStart[1]=0; // we don't have mask bytes on } else { - if (v1) putsWhileCheckingInput("TCP data received\n"); // all other tcp push packets + if ( len > 1 ) { // we assume a length of 1 is a keep-alive or push packet + if (v1) putsWhileCheckingInput("TCP data received\n"); // all other tcp push packets + } } return n; // total byte size of our response } @@ -965,7 +974,7 @@ n=n+sprintf(pbuf+n, outGoing ? "\x1b[34m" : "\x1b[30m" ); // VT100 color code, print black for incoming, blue for outgoing headers checkPc(); n=n+sprintf(pbuf+n, "IP:%d ipHeader:%d tcpHeader:%d tcpData:%d\n", packetLengthIp, headerSizeIp, headerSizeTcp, tcpDataSize); // 1 for more verbose - if (n>70) putsWhileCheckingInput("n>pbuf in dumpDataTCP()\n"); + if (n>70) putsWhileCheckingInput("n>pbuf overflow in dumpDataTCP()\n"); checkPc(); putsWhileCheckingInput( pbuf ); if (tcpDataSize > 0) { @@ -1008,19 +1017,19 @@ int dataLen = 0; // most of our responses will have zero TCP data, only a header int flagsOut = TCP_FLAG_ACK; // the default case is an ACK packet - ppp.tcp->windowR = __REV16( 700 ); // set tcp window size to 700 bytes + ppp.tcp->windowR = __REV16( 1200 ); // set tcp window size to 120 bytes // A sparse TCP flag interpreter that implements stateless TCP connections switch ( ppp.tcp->flag.All ) { - case TCP_FLAG_ACK: // handle ack messages by ignoring them - return; case TCP_FLAG_SYN: flagsOut = TCP_FLAG_SYN | TCP_FLAG_ACK; // something wants to connect - acknowledge it seq_out = seq_in+0x10000000U; // create a new sequence number using their sequence as a starting point, increase the highest digit ack_out++; // for SYN flag we have to increase the sequence by 1 break; + case TCP_FLAG_ACK: case TCP_FLAG_ACK | TCP_FLAG_PSH: + if ( (ppp.tcp->flag.All == TCP_FLAG_ACK) && (tcpDataSize == 0)) return; // handle zero-size ack messages by ignoring them if ( (strncmp(tcpDataIn, "GET /", 5) == 0) ) { // check for an http GET command flagsOut = TCP_FLAG_ACK | TCP_FLAG_PSH; // we have data, set the PSH flag dataLen = httpResponse(tcpDataOut); // send an http response @@ -1254,7 +1263,10 @@ void initializePpp() { debugBaudRate(115200); // baud rate for (optional) debug serial port - debugPrintf("\x1b[2J\x1b[H\x1b[30mmbed PPP-Blinky HTTP & WebSocket server ready :)\n"); // VT100 codes for clear_screen, home, black_text - Tera Term is a handy VT100 terminal + debugPrintf("\x1b[2J\x1b[H\x1b[30m"); + wait_ms(200); // a brief wait so a human can see the reset event + debugPrintf("mbed PPP-Blinky HTTP & WebSocket server ready :)\n"); // VT100 codes for clear_screen, home, black_text - Tera Term is a handy VT100 terminal + pppInitStruct(); // initialize all the variables/properties/buffers pc.baud(115200); // pc serial port acting as a dial-up modem - for PPP traffic pc.attach(&pppReceiveHandler, RawSerial::RxIrq); // set up serial port receive interrupt handler