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.
HTTPWebSocketHandler.cpp
00001 #include "HTTPWebSocketHandler.h" 00002 #include "md5.h" 00003 #include "TemperatureSensor.h" 00004 #include "RGBLed.h" 00005 00006 extern TemperatureSensor sensor; 00007 extern RGBLed rgb; 00008 00009 HTTPWebSocketConnectingState::HTTPWebSocketConnectingState() { 00010 memset(challange, 0, 16); 00011 } 00012 00013 HTTPStatus HTTPWebSocketConnectingState::init(HTTPConnection *conn) { 00014 uint32_t key1Part= computeKeyPart(conn->getField("Sec-WebSocket-Key1")); 00015 uint32_t key2Part= computeKeyPart(conn->getField("Sec-WebSocket-Key2")); 00016 00017 challange[0]= (key1Part >> 24) & 0xFF; 00018 challange[1]= (key1Part >> 16) & 0xFF; 00019 challange[2]= (key1Part >> 8) & 0xFF; 00020 challange[3]= (key1Part >> 0) & 0xFF; 00021 challange[4]= (key2Part >> 24) & 0xFF; 00022 challange[5]= (key2Part >> 16) & 0xFF; 00023 challange[6]= (key2Part >> 8) & 0xFF; 00024 challange[7]= (key2Part >> 0) & 0xFF; 00025 00026 char headers[1024]; 00027 char *str; 00028 00029 memset(headers, 0, 1024); 00030 strcat(headers, "Upgrade: WebSocket\r\n"); 00031 strcat(headers, "Connection: Upgrade\r\n"); 00032 00033 // The host field string can have junk at the end... 00034 str= (char*) conn->getField("Host"); 00035 for (char *p= str; *p != 0; p++) { 00036 if(!isprint(*p)) { 00037 *p= 0; 00038 } 00039 } 00040 strcat(headers, "Sec-WebSocket-Location: ws://"); 00041 strcat(headers, str); 00042 strcat(headers, conn->getURL()); 00043 strcat(headers, "\r\n"); 00044 00045 // The host field string can have junk at the end... 00046 str= (char*) conn->getField("Origin"); 00047 for (char *p= str; *p != 0; p++) { 00048 if(!isprint(*p)) { 00049 *p= 0; 00050 } 00051 } 00052 strcat(headers, "Sec-WebSocket-Origin: "); 00053 strcat(headers, str); 00054 strcat(headers, "\r\n"); 00055 conn->setLength(16); 00056 conn->setHeaderFields(headers); 00057 00058 printf("\n%s\n", headers); 00059 00060 return HTTP_SwitchProtocols; 00061 } 00062 00063 HTTPHandle HTTPWebSocketConnectingState::data(HTTPConnection *conn, void *data, int len) { 00064 // The body needs to hold key3, and only key3 00065 if (len != 8) { 00066 printf("key3 length error\n"); 00067 return HTTP_Failed; 00068 } 00069 00070 // Copy key3 into the challange 00071 memcpy(challange+8, data, 8); 00072 00073 printf("Challange: "); 00074 for (int i= 0; i<16; i++) { 00075 printf("%02x ", challange[i]); 00076 } 00077 printf("\n"); 00078 00079 return HTTP_Success; 00080 } 00081 00082 HTTPHandle HTTPWebSocketConnectingState::send(HTTPConnection *conn, int maxData) { 00083 MD5 md5; 00084 md5.update(challange, 16); 00085 const char *hex= md5.finalize().hexdigest().c_str(); 00086 char binary[16]; 00087 hexStringToBinary(hex, binary); 00088 conn->write(binary, 16, (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE)); 00089 00090 printf("MD5 bin: "); 00091 for (int i= 0; i<16; i++) { 00092 printf("%02x ", binary[i]); 00093 } 00094 printf("\n"); 00095 00096 delete conn->data; 00097 conn->data= new HTTPWebSocketStreamingState(); 00098 return HTTP_Success; 00099 } 00100 00101 uint32_t HTTPWebSocketConnectingState::extractNumber(const char *keyValue) { 00102 uint32_t value= 0; 00103 while (*keyValue) { 00104 if (isdigit(*keyValue)) { 00105 value= value*10 + (*keyValue-'0'); 00106 }; 00107 keyValue++; 00108 }; 00109 return value; 00110 } 00111 00112 uint32_t HTTPWebSocketConnectingState::countSpaces(const char *keyValue) { 00113 uint32_t count= 0; 00114 while (*keyValue) { 00115 if (*keyValue == 0x20) { 00116 count++; 00117 } 00118 keyValue++; 00119 } 00120 return count; 00121 } 00122 00123 uint32_t HTTPWebSocketConnectingState::computeKeyPart(const char *keyValue) { 00124 if (keyValue != NULL) { 00125 printf("key:%s:\n", keyValue); 00126 uint32_t keyPart= extractNumber(keyValue) / countSpaces(keyValue); 00127 printf("keyPart: %08x\n", keyPart); 00128 return keyPart; 00129 } 00130 // No key value 00131 return 0; 00132 } 00133 00134 void HTTPWebSocketConnectingState::hexStringToBinary(const char *hex, char *binary) { 00135 while (*hex) { 00136 char c; 00137 00138 c= *hex++; 00139 *binary= (c < '@' ? c-'0' : c-'a'+10) << 4; 00140 c= *hex++; 00141 *binary |= (c < '@' ? c-'0' : c-'a'+10); 00142 binary++; 00143 } 00144 } 00145 00146 //----- 00147 00148 HTTPWebSocketStreamingState::HTTPWebSocketStreamingState() : led(LED2) { 00149 sendCnt= 0; 00150 } 00151 00152 HTTPStatus HTTPWebSocketStreamingState::init(HTTPConnection *conn) { 00153 return HTTP_InternalServerError; // ignored 00154 } 00155 00156 HTTPHandle HTTPWebSocketStreamingState::data(HTTPConnection *conn, void *data, int len) { 00157 char *str= ((char*)data)+1; // skip leading 0x00 00158 str[len]= 0; // stop on trailing 0xFF 00159 //printf("IN:%d:%s\n", len, str); 00160 rgb.setRgb(str); 00161 return HTTP_Success; 00162 } 00163 00164 HTTPHandle HTTPWebSocketStreamingState::send(HTTPConnection *conn, int maxData) { 00165 char buffer[80]; 00166 int len; 00167 00168 if (sendCnt > 1000) { 00169 sprintf(buffer, "%c%f,%f,%f\n%c", 0x00, sensor.getPercentOfScale(), sensor.getResistance(), sensor.getKelvin(), 0xFF); 00170 len= strlen(buffer+1); 00171 conn->write(buffer, len+1); 00172 sendCnt= 0; 00173 //led= !led; 00174 } else { 00175 sensor.measure(); 00176 sendCnt++; 00177 } 00178 00179 return HTTP_Success; 00180 } 00181 00182 //----- 00183 00184 // Register headers required by this handler. Headers that are not registered will 00185 // be stripped by the server. 00186 void HTTPWebSocketHandler::reg(HTTPServer *server) { 00187 server->registerField("Sec-WebSocket-Key1"); 00188 server->registerField("Sec-WebSocket-Key2"); 00189 server->registerField("Host"); 00190 server->registerField("Origin"); 00191 } 00192 00193 HTTPStatus HTTPWebSocketHandler::init(HTTPConnection *conn) const { 00194 // Todo: validate headers 00195 HTTPWebSocketState *state= new HTTPWebSocketConnectingState(); 00196 conn->data= state; 00197 HTTPStatus status= state->init(conn); 00198 printf("init: %d\n", status); 00199 return status; 00200 } 00201 00202 HTTPHandle HTTPWebSocketHandler::data(HTTPConnection *conn, void *data, int len) const { 00203 HTTPWebSocketState *state= (HTTPWebSocketState *) conn->data; 00204 HTTPHandle result= state->data(conn, data, len); 00205 //printf("data: %d\n", result); 00206 return result; 00207 } 00208 00209 HTTPHandle HTTPWebSocketHandler::send(HTTPConnection *conn, int maxData) const { 00210 HTTPWebSocketState *state= (HTTPWebSocketState *) conn->data; 00211 HTTPHandle result= state->send(conn, maxData); 00212 //printf("send: %d\n", result); 00213 return result; 00214 } 00215
Generated on Wed Jul 13 2022 23:42:33 by
1.7.2