kenji tanaka
/
Sha1Test
WebSocketServer test
Diff: main.cpp
- Revision:
- 0:74be48b504a5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Apr 29 03:58:08 2012 +0000 @@ -0,0 +1,333 @@ +#include <string> +#include <sstream> +#include "mbed.h" +#include "TextLCD.h" +#include "EthernetNetIf.h" +#include "TCPSocket.h" +#include "sha1config.h" +#include "sha1.h" + +//EthernetNetIf eth; +EthernetNetIf eth( + IpAddr(192,168,0,2), //IP Address + IpAddr(255,255,255,0), //Network Mask + IpAddr(192,168,0,1), //Gateway + IpAddr(192,168,0,1) //DNS +); + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +TCPSocket tcp; //The listening port where requests are queued +TCPSocket* link; //The port where accepted requests can communicate +IpAddr localIp = IpAddr(192, 168, 0, 2); +int localPort = 80; +Host local(localIp, localPort); //mbed IP +Host client; + +TextLCD lcd(p24, p26, p27, p28, p29, p30); + +TCPSocketErr accErr; +int wsState = 0; + +// encode64 from http://uinu.org/archives/105 +string encode64(char *Buf,int Length) { + char *Codes64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int Byte3=0; + string Result=""; + for (int i=0; i<Length; i++) { + Byte3=(Byte3<<8)+(int)Buf[i]; + if ((i+1)%3==0) { + Result=Result+Codes64[(Byte3>>18)&0x3F]; + Result=Result+Codes64[(Byte3>>12)&0x3F]; + Result=Result+Codes64[(Byte3>>6)&0x3F]; + Result=Result+Codes64[(Byte3)&0x3F]; + Byte3=0; + } + } + + int Rest=Length%3; + switch (Rest) { + case 1: + Byte3=Byte3<<4; + Result=Result+Codes64[(Byte3>>6)&0x3F]; + Result=Result+Codes64[(Byte3)&0x3F]; + Result=Result+"=="; + break; + case 2: + Byte3=Byte3<<2; + Result=Result+Codes64[(Byte3>>12)&0x3F]; + Result=Result+Codes64[(Byte3>>6 )&0x3F]; + Result=Result+Codes64[(Byte3)&0x3F]; + Result=Result+"="; + break; + } + return Result; +} + +void onLinkSocketEvent(TCPSocketEvent e) { + switch (e) { + case TCPSOCKET_CONNECTED: + printf("TCP Socket Connected\n"); + break; + case TCPSOCKET_WRITEABLE: + //Can now write some data... + printf("TCP Socket Writable\n"); + break; + case TCPSOCKET_READABLE: + //Can now read dome data... + printf("TCP Socket Readable\n"); + // Read in any available data into the buffer + char buff[256]; + while ( int len = link->recv(buff, 256) ) { + // And send straight back out again + //link->send(buff, len); + printf("len = %d\n", len); + if (wsState == 0) { + buff[len]=0; // make terminater + printf("%s\n", (char*)buff); + for (int i = 0; i < len; i++) { + if (buff[i] == 'K' && buff[i + 1] == 'e' && buff[i + 2] == 'y') { + for (int j = i + 1; j < len; j++) { + if (buff[j] == '\r') { + i += 5; + int keyLen = j - i; + char strKey[keyLen + 1]; + strKey[keyLen] = 0; + strncpy(strKey, buff + i, keyLen); + char guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + strcat(strKey, guid); + unsigned char hash[20]; + sha1((unsigned char*)strKey,strlen((char*)strKey),hash); + string accept = encode64((char*)hash, 20); + string hsRes = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "; + hsRes += accept; + hsRes += "\r\n\r\n"; + printf("%s\n", hsRes.c_str()); + link->send(hsRes.c_str(), hsRes.size()); + wsState = 1; + return; + } + } + } + } + } else { + if (len == 0) { + link->close(); + return; + } + bool fin = (buff[0] & 0x80) == 0x80; + int opcode = buff[0] & 0x0f; + if (opcode == 0x9) { + buff[0] += 1; + link->send(buff, len); + return; + } + int dataLen = buff[1] & 0x7f; + if (!fin || dataLen > 125) { + link->close(); + return; + } + int i = 0; + for (i = 0; i < dataLen; i++) { + buff[6 + i] = buff[6 + i] ^ buff[2 + (i % 4)]; + } + printf("data length:%d\n", dataLen); + buff[6 + dataLen] = 0; + if (opcode == 1) { + printf("received data:%s\n", buff + 6); + char sendData[2 + dataLen + 1]; + sendData[0] = buff[0]; + sendData[1] = buff[1] & 0x7f; + for (i = 0; i < dataLen; i++) { + sendData[2 + i] = buff[6 + i]; + } + sendData[2 + dataLen] = 0; + link->send(sendData, 2 + dataLen); + } else if (opcode == 2) { + led1 = buff[6 + 0]; + led2 = buff[6 + 1]; + led3 = buff[6 + 2]; + led4 = buff[6 + 3]; + } + } + }; + break; + case TCPSOCKET_CONTIMEOUT: + printf("TCP Socket Timeout\n"); + break; + case TCPSOCKET_CONRST: + printf("TCP Socket CONRST\n"); + break; + case TCPSOCKET_CONABRT: + printf("TCP Socket CONABRT\n"); + break; + case TCPSOCKET_ERROR: + printf("TCP Socket Error\n"); + link->close(); + break; + case TCPSOCKET_DISCONNECTED: + printf("TCP Socket Disconnected\n"); + wsState = 0; + link->close(); + break; + default: + printf("DEFAULT\n"); + } +} + +void onTCPSocketEvent(TCPSocketEvent e) { + switch (e) { + case TCPSOCKET_CONNECTED: + printf("Connected\n"); + break; + + case TCPSOCKET_ACCEPT: { + accErr = tcp.accept(&client,&link); + switch (accErr) { + case TCPSOCKET_SETUP: + printf("Err:Setup\n"); + break; //TCPSocket not properly configured. + case TCPSOCKET_TIMEOUT: + printf("Err:Timeout\n"); + break; //Connection timed out. + case TCPSOCKET_IF: + printf("Err:Interface\n"); + break; //Interface has problems, does not exist or is not initialized. + case TCPSOCKET_MEM: + printf("Err:Memory\n"); + break; //Not enough mem. + case TCPSOCKET_INUSE: + printf("Err:In use\n"); + break; //Interface / Port is in use. + case TCPSOCKET_EMPTY: + printf("Err:Empty\n"); + break; //Connections queue is empty. + case TCPSOCKET_RST: + printf("Err:Reset\n"); + break; //Connection was reset by remote host. + case TCPSOCKET_OK: + printf("Accepted: "); + break; //Success. + } + link->setOnEvent(&onLinkSocketEvent); + IpAddr clientIp = client.getIp(); + printf("Incoming TCP connection from %d.%d.%d.%d\n", + clientIp[0], clientIp[1], clientIp[2], clientIp[3]); + } + break; + + case TCPSOCKET_READABLE: + printf("Readable\n"); + break; + + case TCPSOCKET_WRITEABLE: + printf("Writeable\n"); + break; + + case TCPSOCKET_CONTIMEOUT: + printf("Timeout\n"); + break; + + case TCPSOCKET_CONRST: + printf("Reset\n"); + break; + case TCPSOCKET_CONABRT: + printf("Aborted\n"); + break; + + case TCPSOCKET_ERROR: + printf("Error\n"); + break; + + case TCPSOCKET_DISCONNECTED: + printf("Disconnected\n"); + tcp.close(); + break; + } +} + +int main() { + printf("Setting up...\n"); + EthernetErr ethErr = eth.setup(); + if (ethErr) { + printf("Error %d in setup.\n", ethErr); + return -1; + } + + printf("Setup OK\n"); + //****End of basic setup***** + + tcp.setOnEvent(&onTCPSocketEvent); //Generate method to deal with requests + + //Bind to local port + printf("Init bind..\n"); + TCPSocketErr bindErr = tcp.bind(local); + switch (bindErr) { + case TCPSOCKET_SETUP: + printf("Err:Setup\n"); + return -1; //TCPSocket not properly configured. + case TCPSOCKET_TIMEOUT: + printf("Err:Timeout\n"); + return -1; //Connection timed out. + case TCPSOCKET_IF: + printf("Err:Interface\n"); + return -1; //Interface has problems, does not exist or is not initialized. + case TCPSOCKET_MEM: + printf("Err:Memory\n"); + return -1; //Not enough mem. + case TCPSOCKET_INUSE: + printf("Err:In use\n"); + return -1; //Interface / Port is in use. + case TCPSOCKET_EMPTY: + printf("Err:Empty\n"); + return -1; //Connections queue is empty. + case TCPSOCKET_RST: + printf("Err:Reset\n"); + return -1; //Connection was reset by remote host. + case TCPSOCKET_OK: + printf("Bound to port\n"); + break; //Success. + } + + //Listen to local port + printf("Init listen..\n"); + TCPSocketErr listenErr = tcp.listen(); + switch (listenErr) { + case TCPSOCKET_SETUP: + printf("Err:Setup\n"); + return -1; //TCPSocket not properly configured. + case TCPSOCKET_TIMEOUT: + printf("Err:Timeout\n"); + return -1; //Connection timed out. + case TCPSOCKET_IF: + printf("Err:Interface\n"); + return -1; //Interface has problems, does not exist or is not initialized. + case TCPSOCKET_MEM: + printf("Err:Memory\n"); + return -1; //Not enough mem. + case TCPSOCKET_INUSE: + printf("Err:In use\n"); + return -1; //Interface / Port is in use. + case TCPSOCKET_EMPTY: + printf("Err:Empty\n"); + return -1; //Connections queue is empty. + case TCPSOCKET_RST: + printf("Err:Reset\n"); + return -1; //Connection was reset by remote host. + case TCPSOCKET_OK: + printf("Listening\n"); + break; //Success. + } + + Timer tmr; + tmr.start(); + while (1) { + Net::poll(); + if (tmr.read() > 2) { + tmr.reset(); + //led1=!led1; //Show that we are alive + } + } +}