Ethernet Interfaceを使用したWebSocketサーバー

Dependencies:   EthernetInterface TextLCD mbed-rtos mbed

Committer:
gtk2k
Date:
Sat Mar 30 02:02:51 2013 +0000
Revision:
0:98ff551a3a1a
Ethernet Interface?????WebSocketServer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gtk2k 0:98ff551a3a1a 1 #include <string>
gtk2k 0:98ff551a3a1a 2 #include <sstream>
gtk2k 0:98ff551a3a1a 3 #include "mbed.h"
gtk2k 0:98ff551a3a1a 4 #include "EthernetInterface.h"
gtk2k 0:98ff551a3a1a 5 #include "TextLCD.h"
gtk2k 0:98ff551a3a1a 6 #include "sha1config.h"
gtk2k 0:98ff551a3a1a 7 #include "sha1.h"
gtk2k 0:98ff551a3a1a 8
gtk2k 0:98ff551a3a1a 9 const int WS_HANDSHAKE = 1;
gtk2k 0:98ff551a3a1a 10 const int WS_CONNECT = 2;
gtk2k 0:98ff551a3a1a 11 int wsState = 0;
gtk2k 0:98ff551a3a1a 12
gtk2k 0:98ff551a3a1a 13 DigitalOut led1(LED1);
gtk2k 0:98ff551a3a1a 14 DigitalOut led2(LED2);
gtk2k 0:98ff551a3a1a 15 DigitalOut led3(LED3);
gtk2k 0:98ff551a3a1a 16 DigitalOut led4(LED4);
gtk2k 0:98ff551a3a1a 17 TextLCD lcd(p24, p26, p27, p28, p29, p30);
gtk2k 0:98ff551a3a1a 18
gtk2k 0:98ff551a3a1a 19 string encode64(char *Buf,int Length) {
gtk2k 0:98ff551a3a1a 20 char *Codes64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
gtk2k 0:98ff551a3a1a 21 int Byte3=0;
gtk2k 0:98ff551a3a1a 22 string Result="";
gtk2k 0:98ff551a3a1a 23 for (int i=0; i<Length; i++) {
gtk2k 0:98ff551a3a1a 24 Byte3=(Byte3<<8)+(int)Buf[i];
gtk2k 0:98ff551a3a1a 25 if ((i+1)%3==0) {
gtk2k 0:98ff551a3a1a 26 Result=Result+Codes64[(Byte3>>18)&0x3F];
gtk2k 0:98ff551a3a1a 27 Result=Result+Codes64[(Byte3>>12)&0x3F];
gtk2k 0:98ff551a3a1a 28 Result=Result+Codes64[(Byte3>>6)&0x3F];
gtk2k 0:98ff551a3a1a 29 Result=Result+Codes64[(Byte3)&0x3F];
gtk2k 0:98ff551a3a1a 30 Byte3=0;
gtk2k 0:98ff551a3a1a 31 }
gtk2k 0:98ff551a3a1a 32 }
gtk2k 0:98ff551a3a1a 33
gtk2k 0:98ff551a3a1a 34 int Rest=Length%3;
gtk2k 0:98ff551a3a1a 35 switch (Rest) {
gtk2k 0:98ff551a3a1a 36 case 1:
gtk2k 0:98ff551a3a1a 37 Byte3=Byte3<<4;
gtk2k 0:98ff551a3a1a 38 Result=Result+Codes64[(Byte3>>6)&0x3F];
gtk2k 0:98ff551a3a1a 39 Result=Result+Codes64[(Byte3)&0x3F];
gtk2k 0:98ff551a3a1a 40 Result=Result+"==";
gtk2k 0:98ff551a3a1a 41 break;
gtk2k 0:98ff551a3a1a 42 case 2:
gtk2k 0:98ff551a3a1a 43 Byte3=Byte3<<2;
gtk2k 0:98ff551a3a1a 44 Result=Result+Codes64[(Byte3>>12)&0x3F];
gtk2k 0:98ff551a3a1a 45 Result=Result+Codes64[(Byte3>>6 )&0x3F];
gtk2k 0:98ff551a3a1a 46 Result=Result+Codes64[(Byte3)&0x3F];
gtk2k 0:98ff551a3a1a 47 Result=Result+"=";
gtk2k 0:98ff551a3a1a 48 break;
gtk2k 0:98ff551a3a1a 49 }
gtk2k 0:98ff551a3a1a 50 return Result;
gtk2k 0:98ff551a3a1a 51 }
gtk2k 0:98ff551a3a1a 52
gtk2k 0:98ff551a3a1a 53 int main() {
gtk2k 0:98ff551a3a1a 54 EthernetInterface eth;
gtk2k 0:98ff551a3a1a 55 eth.init("192.168.0.2", "255.255.255.0", "192.168.0.2");
gtk2k 0:98ff551a3a1a 56 eth.connect();
gtk2k 0:98ff551a3a1a 57 lcd.cls();
gtk2k 0:98ff551a3a1a 58 lcd.printf("%s", eth.getIPAddress());
gtk2k 0:98ff551a3a1a 59
gtk2k 0:98ff551a3a1a 60 TCPSocketServer server;
gtk2k 0:98ff551a3a1a 61 server.bind(8080);
gtk2k 0:98ff551a3a1a 62 server.listen();
gtk2k 0:98ff551a3a1a 63 printf("\nWait for new connection...\n");
gtk2k 0:98ff551a3a1a 64 TCPSocketConnection sock;
gtk2k 0:98ff551a3a1a 65 server.accept(sock);
gtk2k 0:98ff551a3a1a 66 wsState = WS_HANDSHAKE;
gtk2k 0:98ff551a3a1a 67 char buff[600];
gtk2k 0:98ff551a3a1a 68 int len;
gtk2k 0:98ff551a3a1a 69 while (true) {
gtk2k 0:98ff551a3a1a 70 len = sock.receive(buff, sizeof(buff)-1);
gtk2k 0:98ff551a3a1a 71 if (len <= 0){
gtk2k 0:98ff551a3a1a 72 printf("close by 0 length\n");
gtk2k 0:98ff551a3a1a 73 wsState = WS_HANDSHAKE;
gtk2k 0:98ff551a3a1a 74 continue;
gtk2k 0:98ff551a3a1a 75 }
gtk2k 0:98ff551a3a1a 76 buff[len] = '\0';
gtk2k 0:98ff551a3a1a 77 switch(wsState){
gtk2k 0:98ff551a3a1a 78 case WS_HANDSHAKE:
gtk2k 0:98ff551a3a1a 79 printf("Received %d chars from server:\n%s\n", len, buff);
gtk2k 0:98ff551a3a1a 80 for (int i = 0; i < len; i++) {
gtk2k 0:98ff551a3a1a 81 if (buff[i] == 'K' && buff[i + 1] == 'e' && buff[i + 2] == 'y') {
gtk2k 0:98ff551a3a1a 82 for (int j = i + 1; j < len; j++) {
gtk2k 0:98ff551a3a1a 83 if (buff[j] == '\r') {
gtk2k 0:98ff551a3a1a 84 i += 5;
gtk2k 0:98ff551a3a1a 85 int keyLen = j - i;
gtk2k 0:98ff551a3a1a 86 char strKey[keyLen + 1];
gtk2k 0:98ff551a3a1a 87 strKey[keyLen] = 0;
gtk2k 0:98ff551a3a1a 88 strncpy(strKey, buff + i, keyLen);
gtk2k 0:98ff551a3a1a 89 char guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
gtk2k 0:98ff551a3a1a 90 strcat(strKey, guid);
gtk2k 0:98ff551a3a1a 91 unsigned char hash[20];
gtk2k 0:98ff551a3a1a 92 sha1((unsigned char*)strKey,strlen((char*)strKey),hash);
gtk2k 0:98ff551a3a1a 93 string accept = encode64((char*)hash, 20);
gtk2k 0:98ff551a3a1a 94 string hsRes = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ";
gtk2k 0:98ff551a3a1a 95 hsRes += accept;
gtk2k 0:98ff551a3a1a 96 hsRes += "\r\n\r\n";
gtk2k 0:98ff551a3a1a 97 printf("%s", hsRes.c_str());
gtk2k 0:98ff551a3a1a 98 sock.send_all((char *)hsRes.c_str(), hsRes.size());
gtk2k 0:98ff551a3a1a 99 printf("change to WS_CONNECT state\n");
gtk2k 0:98ff551a3a1a 100 wsState = WS_CONNECT;
gtk2k 0:98ff551a3a1a 101 break;
gtk2k 0:98ff551a3a1a 102 }
gtk2k 0:98ff551a3a1a 103 }
gtk2k 0:98ff551a3a1a 104 }
gtk2k 0:98ff551a3a1a 105 }
gtk2k 0:98ff551a3a1a 106 break;
gtk2k 0:98ff551a3a1a 107 case WS_CONNECT:
gtk2k 0:98ff551a3a1a 108 bool fin = (buff[0] & 0x80) == 0x80;
gtk2k 0:98ff551a3a1a 109 int opcode = buff[0] & 0x0f;
gtk2k 0:98ff551a3a1a 110 if (opcode == 0x8) {
gtk2k 0:98ff551a3a1a 111 printf("close by close opcode\n");
gtk2k 0:98ff551a3a1a 112 wsState = WS_HANDSHAKE;
gtk2k 0:98ff551a3a1a 113 sock.close();
gtk2k 0:98ff551a3a1a 114 break;
gtk2k 0:98ff551a3a1a 115 }
gtk2k 0:98ff551a3a1a 116 if (opcode == 0x9) {
gtk2k 0:98ff551a3a1a 117 buff[0] += 1;
gtk2k 0:98ff551a3a1a 118 sock.send_all(buff, len);
gtk2k 0:98ff551a3a1a 119 break;
gtk2k 0:98ff551a3a1a 120 }
gtk2k 0:98ff551a3a1a 121 int dataLen = buff[1] & 0x7f;
gtk2k 0:98ff551a3a1a 122 if (!fin || dataLen > 125) {
gtk2k 0:98ff551a3a1a 123 sock.close();
gtk2k 0:98ff551a3a1a 124 printf("close by illegal data length \n");
gtk2k 0:98ff551a3a1a 125 wsState = WS_HANDSHAKE;
gtk2k 0:98ff551a3a1a 126 break;
gtk2k 0:98ff551a3a1a 127 }
gtk2k 0:98ff551a3a1a 128 int i = 0;
gtk2k 0:98ff551a3a1a 129 for (i = 0; i < dataLen; i++) {
gtk2k 0:98ff551a3a1a 130 buff[6 + i] = buff[6 + i] ^ buff[2 + (i % 4)];
gtk2k 0:98ff551a3a1a 131 }
gtk2k 0:98ff551a3a1a 132 printf("data length:%d\n", dataLen);
gtk2k 0:98ff551a3a1a 133 buff[6 + dataLen] = 0;
gtk2k 0:98ff551a3a1a 134 if (opcode == 1) {
gtk2k 0:98ff551a3a1a 135 printf("received data:%s\n", buff + 6);
gtk2k 0:98ff551a3a1a 136 char sendData[2 + dataLen + 1];
gtk2k 0:98ff551a3a1a 137 sendData[0] = buff[0];
gtk2k 0:98ff551a3a1a 138 sendData[1] = buff[1] & 0x7f;
gtk2k 0:98ff551a3a1a 139 for (i = 0; i < dataLen; i++) {
gtk2k 0:98ff551a3a1a 140 sendData[2 + i] = buff[6 + i];
gtk2k 0:98ff551a3a1a 141 }
gtk2k 0:98ff551a3a1a 142 sendData[2 + dataLen] = 0;
gtk2k 0:98ff551a3a1a 143 sock.send_all(sendData, 2 + dataLen);
gtk2k 0:98ff551a3a1a 144 } else if (opcode == 2) {
gtk2k 0:98ff551a3a1a 145 led1 = buff[6 + 0];
gtk2k 0:98ff551a3a1a 146 led2 = buff[6 + 1];
gtk2k 0:98ff551a3a1a 147 led3 = buff[6 + 2];
gtk2k 0:98ff551a3a1a 148 led4 = buff[6 + 3];
gtk2k 0:98ff551a3a1a 149 }
gtk2k 0:98ff551a3a1a 150 break;
gtk2k 0:98ff551a3a1a 151 }
gtk2k 0:98ff551a3a1a 152 }
gtk2k 0:98ff551a3a1a 153
gtk2k 0:98ff551a3a1a 154 sock.close();
gtk2k 0:98ff551a3a1a 155 eth.disconnect();
gtk2k 0:98ff551a3a1a 156 while(1) {}
gtk2k 0:98ff551a3a1a 157 }
gtk2k 0:98ff551a3a1a 158