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.
main.cpp
00001 #include <string> 00002 #include <sstream> 00003 #include "mbed.h" 00004 #include "TextLCD.h" 00005 #include "EthernetNetIf.h" 00006 #include "TCPSocket.h" 00007 #include "sha1config.h" 00008 #include "sha1.h" 00009 00010 //EthernetNetIf eth; 00011 EthernetNetIf eth( 00012 IpAddr(192,168,0,2), //IP Address 00013 IpAddr(255,255,255,0), //Network Mask 00014 IpAddr(192,168,0,1), //Gateway 00015 IpAddr(192,168,0,1) //DNS 00016 ); 00017 00018 DigitalOut led1(LED1); 00019 DigitalOut led2(LED2); 00020 DigitalOut led3(LED3); 00021 DigitalOut led4(LED4); 00022 TCPSocket tcp; //The listening port where requests are queued 00023 TCPSocket* link; //The port where accepted requests can communicate 00024 IpAddr localIp = IpAddr(192, 168, 0, 2); 00025 int localPort = 80; 00026 Host local(localIp, localPort); //mbed IP 00027 Host client; 00028 00029 TextLCD lcd(p24, p26, p27, p28, p29, p30); 00030 00031 TCPSocketErr accErr; 00032 int wsState = 0; 00033 00034 // encode64 from http://uinu.org/archives/105 00035 string encode64(char *Buf,int Length) { 00036 char *Codes64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00037 int Byte3=0; 00038 string Result=""; 00039 for (int i=0; i<Length; i++) { 00040 Byte3=(Byte3<<8)+(int)Buf[i]; 00041 if ((i+1)%3==0) { 00042 Result=Result+Codes64[(Byte3>>18)&0x3F]; 00043 Result=Result+Codes64[(Byte3>>12)&0x3F]; 00044 Result=Result+Codes64[(Byte3>>6)&0x3F]; 00045 Result=Result+Codes64[(Byte3)&0x3F]; 00046 Byte3=0; 00047 } 00048 } 00049 00050 int Rest=Length%3; 00051 switch (Rest) { 00052 case 1: 00053 Byte3=Byte3<<4; 00054 Result=Result+Codes64[(Byte3>>6)&0x3F]; 00055 Result=Result+Codes64[(Byte3)&0x3F]; 00056 Result=Result+"=="; 00057 break; 00058 case 2: 00059 Byte3=Byte3<<2; 00060 Result=Result+Codes64[(Byte3>>12)&0x3F]; 00061 Result=Result+Codes64[(Byte3>>6 )&0x3F]; 00062 Result=Result+Codes64[(Byte3)&0x3F]; 00063 Result=Result+"="; 00064 break; 00065 } 00066 return Result; 00067 } 00068 00069 void onLinkSocketEvent(TCPSocketEvent e) { 00070 switch (e) { 00071 case TCPSOCKET_CONNECTED: 00072 printf("TCP Socket Connected\n"); 00073 break; 00074 case TCPSOCKET_WRITEABLE: 00075 //Can now write some data... 00076 printf("TCP Socket Writable\n"); 00077 break; 00078 case TCPSOCKET_READABLE: 00079 //Can now read dome data... 00080 printf("TCP Socket Readable\n"); 00081 // Read in any available data into the buffer 00082 char buff[256]; 00083 while ( int len = link->recv(buff, 256) ) { 00084 // And send straight back out again 00085 //link->send(buff, len); 00086 printf("len = %d\n", len); 00087 if (wsState == 0) { 00088 buff[len]=0; // make terminater 00089 printf("%s\n", (char*)buff); 00090 for (int i = 0; i < len; i++) { 00091 if (buff[i] == 'K' && buff[i + 1] == 'e' && buff[i + 2] == 'y') { 00092 for (int j = i + 1; j < len; j++) { 00093 if (buff[j] == '\r') { 00094 i += 5; 00095 int keyLen = j - i; 00096 char strKey[keyLen + 1]; 00097 strKey[keyLen] = 0; 00098 strncpy(strKey, buff + i, keyLen); 00099 char guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 00100 strcat(strKey, guid); 00101 unsigned char hash[20]; 00102 sha1((unsigned char*)strKey,strlen((char*)strKey),hash); 00103 string accept = encode64((char*)hash, 20); 00104 string hsRes = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "; 00105 hsRes += accept; 00106 hsRes += "\r\n\r\n"; 00107 printf("%s\n", hsRes.c_str()); 00108 link->send(hsRes.c_str(), hsRes.size()); 00109 wsState = 1; 00110 return; 00111 } 00112 } 00113 } 00114 } 00115 } else { 00116 if (len == 0) { 00117 link->close(); 00118 return; 00119 } 00120 bool fin = (buff[0] & 0x80) == 0x80; 00121 int opcode = buff[0] & 0x0f; 00122 if (opcode == 0x9) { 00123 buff[0] += 1; 00124 link->send(buff, len); 00125 return; 00126 } 00127 int dataLen = buff[1] & 0x7f; 00128 if (!fin || dataLen > 125) { 00129 link->close(); 00130 return; 00131 } 00132 int i = 0; 00133 for (i = 0; i < dataLen; i++) { 00134 buff[6 + i] = buff[6 + i] ^ buff[2 + (i % 4)]; 00135 } 00136 printf("data length:%d\n", dataLen); 00137 buff[6 + dataLen] = 0; 00138 if (opcode == 1) { 00139 printf("received data:%s\n", buff + 6); 00140 char sendData[2 + dataLen + 1]; 00141 sendData[0] = buff[0]; 00142 sendData[1] = buff[1] & 0x7f; 00143 for (i = 0; i < dataLen; i++) { 00144 sendData[2 + i] = buff[6 + i]; 00145 } 00146 sendData[2 + dataLen] = 0; 00147 link->send(sendData, 2 + dataLen); 00148 } else if (opcode == 2) { 00149 led1 = buff[6 + 0]; 00150 led2 = buff[6 + 1]; 00151 led3 = buff[6 + 2]; 00152 led4 = buff[6 + 3]; 00153 } 00154 } 00155 }; 00156 break; 00157 case TCPSOCKET_CONTIMEOUT: 00158 printf("TCP Socket Timeout\n"); 00159 break; 00160 case TCPSOCKET_CONRST: 00161 printf("TCP Socket CONRST\n"); 00162 break; 00163 case TCPSOCKET_CONABRT: 00164 printf("TCP Socket CONABRT\n"); 00165 break; 00166 case TCPSOCKET_ERROR: 00167 printf("TCP Socket Error\n"); 00168 link->close(); 00169 break; 00170 case TCPSOCKET_DISCONNECTED: 00171 printf("TCP Socket Disconnected\n"); 00172 wsState = 0; 00173 link->close(); 00174 break; 00175 default: 00176 printf("DEFAULT\n"); 00177 } 00178 } 00179 00180 void onTCPSocketEvent(TCPSocketEvent e) { 00181 switch (e) { 00182 case TCPSOCKET_CONNECTED: 00183 printf("Connected\n"); 00184 break; 00185 00186 case TCPSOCKET_ACCEPT: { 00187 accErr = tcp.accept(&client,&link); 00188 switch (accErr) { 00189 case TCPSOCKET_SETUP: 00190 printf("Err:Setup\n"); 00191 break; //TCPSocket not properly configured. 00192 case TCPSOCKET_TIMEOUT: 00193 printf("Err:Timeout\n"); 00194 break; //Connection timed out. 00195 case TCPSOCKET_IF: 00196 printf("Err:Interface\n"); 00197 break; //Interface has problems, does not exist or is not initialized. 00198 case TCPSOCKET_MEM: 00199 printf("Err:Memory\n"); 00200 break; //Not enough mem. 00201 case TCPSOCKET_INUSE: 00202 printf("Err:In use\n"); 00203 break; //Interface / Port is in use. 00204 case TCPSOCKET_EMPTY: 00205 printf("Err:Empty\n"); 00206 break; //Connections queue is empty. 00207 case TCPSOCKET_RST: 00208 printf("Err:Reset\n"); 00209 break; //Connection was reset by remote host. 00210 case TCPSOCKET_OK: 00211 printf("Accepted: "); 00212 break; //Success. 00213 } 00214 link->setOnEvent(&onLinkSocketEvent); 00215 IpAddr clientIp = client.getIp(); 00216 printf("Incoming TCP connection from %d.%d.%d.%d\n", 00217 clientIp[0], clientIp[1], clientIp[2], clientIp[3]); 00218 } 00219 break; 00220 00221 case TCPSOCKET_READABLE: 00222 printf("Readable\n"); 00223 break; 00224 00225 case TCPSOCKET_WRITEABLE: 00226 printf("Writeable\n"); 00227 break; 00228 00229 case TCPSOCKET_CONTIMEOUT: 00230 printf("Timeout\n"); 00231 break; 00232 00233 case TCPSOCKET_CONRST: 00234 printf("Reset\n"); 00235 break; 00236 case TCPSOCKET_CONABRT: 00237 printf("Aborted\n"); 00238 break; 00239 00240 case TCPSOCKET_ERROR: 00241 printf("Error\n"); 00242 break; 00243 00244 case TCPSOCKET_DISCONNECTED: 00245 printf("Disconnected\n"); 00246 tcp.close(); 00247 break; 00248 } 00249 } 00250 00251 int main() { 00252 printf("Setting up...\n"); 00253 EthernetErr ethErr = eth.setup(); 00254 if (ethErr) { 00255 printf("Error %d in setup.\n", ethErr); 00256 return -1; 00257 } 00258 00259 printf("Setup OK\n"); 00260 //****End of basic setup***** 00261 00262 tcp.setOnEvent(&onTCPSocketEvent); //Generate method to deal with requests 00263 00264 //Bind to local port 00265 printf("Init bind..\n"); 00266 TCPSocketErr bindErr = tcp.bind(local); 00267 switch (bindErr) { 00268 case TCPSOCKET_SETUP: 00269 printf("Err:Setup\n"); 00270 return -1; //TCPSocket not properly configured. 00271 case TCPSOCKET_TIMEOUT: 00272 printf("Err:Timeout\n"); 00273 return -1; //Connection timed out. 00274 case TCPSOCKET_IF: 00275 printf("Err:Interface\n"); 00276 return -1; //Interface has problems, does not exist or is not initialized. 00277 case TCPSOCKET_MEM: 00278 printf("Err:Memory\n"); 00279 return -1; //Not enough mem. 00280 case TCPSOCKET_INUSE: 00281 printf("Err:In use\n"); 00282 return -1; //Interface / Port is in use. 00283 case TCPSOCKET_EMPTY: 00284 printf("Err:Empty\n"); 00285 return -1; //Connections queue is empty. 00286 case TCPSOCKET_RST: 00287 printf("Err:Reset\n"); 00288 return -1; //Connection was reset by remote host. 00289 case TCPSOCKET_OK: 00290 printf("Bound to port\n"); 00291 break; //Success. 00292 } 00293 00294 //Listen to local port 00295 printf("Init listen..\n"); 00296 TCPSocketErr listenErr = tcp.listen(); 00297 switch (listenErr) { 00298 case TCPSOCKET_SETUP: 00299 printf("Err:Setup\n"); 00300 return -1; //TCPSocket not properly configured. 00301 case TCPSOCKET_TIMEOUT: 00302 printf("Err:Timeout\n"); 00303 return -1; //Connection timed out. 00304 case TCPSOCKET_IF: 00305 printf("Err:Interface\n"); 00306 return -1; //Interface has problems, does not exist or is not initialized. 00307 case TCPSOCKET_MEM: 00308 printf("Err:Memory\n"); 00309 return -1; //Not enough mem. 00310 case TCPSOCKET_INUSE: 00311 printf("Err:In use\n"); 00312 return -1; //Interface / Port is in use. 00313 case TCPSOCKET_EMPTY: 00314 printf("Err:Empty\n"); 00315 return -1; //Connections queue is empty. 00316 case TCPSOCKET_RST: 00317 printf("Err:Reset\n"); 00318 return -1; //Connection was reset by remote host. 00319 case TCPSOCKET_OK: 00320 printf("Listening\n"); 00321 break; //Success. 00322 } 00323 00324 Timer tmr; 00325 tmr.start(); 00326 while (1) { 00327 Net::poll(); 00328 if (tmr.read() > 2) { 00329 tmr.reset(); 00330 //led1=!led1; //Show that we are alive 00331 } 00332 } 00333 }
Generated on Tue Jul 12 2022 18:04:46 by
1.7.2