kenji tanaka / Mbed 2 deprecated Sha1Test

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }