kenji tanaka
/
Sha1Test
WebSocketServer test
main.cpp
- Committer:
- gtk2k
- Date:
- 2012-04-29
- Revision:
- 0:74be48b504a5
File content as of revision 0:74be48b504a5:
#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 } } }