Ethernet Interfaceを使用したWebSocketサーバー
Dependencies: EthernetInterface TextLCD mbed-rtos mbed
main.cpp
00001 #include <string> 00002 #include <sstream> 00003 #include "mbed.h" 00004 #include "EthernetInterface.h" 00005 #include "TextLCD.h" 00006 #include "sha1config.h" 00007 #include "sha1.h" 00008 00009 const int WS_HANDSHAKE = 1; 00010 const int WS_CONNECT = 2; 00011 int wsState = 0; 00012 00013 DigitalOut led1(LED1); 00014 DigitalOut led2(LED2); 00015 DigitalOut led3(LED3); 00016 DigitalOut led4(LED4); 00017 TextLCD lcd(p24, p26, p27, p28, p29, p30); 00018 00019 string encode64(char *Buf,int Length) { 00020 char *Codes64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00021 int Byte3=0; 00022 string Result=""; 00023 for (int i=0; i<Length; i++) { 00024 Byte3=(Byte3<<8)+(int)Buf[i]; 00025 if ((i+1)%3==0) { 00026 Result=Result+Codes64[(Byte3>>18)&0x3F]; 00027 Result=Result+Codes64[(Byte3>>12)&0x3F]; 00028 Result=Result+Codes64[(Byte3>>6)&0x3F]; 00029 Result=Result+Codes64[(Byte3)&0x3F]; 00030 Byte3=0; 00031 } 00032 } 00033 00034 int Rest=Length%3; 00035 switch (Rest) { 00036 case 1: 00037 Byte3=Byte3<<4; 00038 Result=Result+Codes64[(Byte3>>6)&0x3F]; 00039 Result=Result+Codes64[(Byte3)&0x3F]; 00040 Result=Result+"=="; 00041 break; 00042 case 2: 00043 Byte3=Byte3<<2; 00044 Result=Result+Codes64[(Byte3>>12)&0x3F]; 00045 Result=Result+Codes64[(Byte3>>6 )&0x3F]; 00046 Result=Result+Codes64[(Byte3)&0x3F]; 00047 Result=Result+"="; 00048 break; 00049 } 00050 return Result; 00051 } 00052 00053 int main() { 00054 EthernetInterface eth; 00055 eth.init("192.168.0.2", "255.255.255.0", "192.168.0.2"); 00056 eth.connect(); 00057 lcd.cls(); 00058 lcd.printf("%s", eth.getIPAddress()); 00059 00060 TCPSocketServer server; 00061 server.bind(8080); 00062 server.listen(); 00063 printf("\nWait for new connection...\n"); 00064 TCPSocketConnection sock; 00065 server.accept(sock); 00066 wsState = WS_HANDSHAKE; 00067 char buff[600]; 00068 int len; 00069 while (true) { 00070 len = sock.receive(buff, sizeof(buff)-1); 00071 if (len <= 0){ 00072 printf("close by 0 length\n"); 00073 wsState = WS_HANDSHAKE; 00074 continue; 00075 } 00076 buff[len] = '\0'; 00077 switch(wsState){ 00078 case WS_HANDSHAKE: 00079 printf("Received %d chars from server:\n%s\n", len, buff); 00080 for (int i = 0; i < len; i++) { 00081 if (buff[i] == 'K' && buff[i + 1] == 'e' && buff[i + 2] == 'y') { 00082 for (int j = i + 1; j < len; j++) { 00083 if (buff[j] == '\r') { 00084 i += 5; 00085 int keyLen = j - i; 00086 char strKey[keyLen + 1]; 00087 strKey[keyLen] = 0; 00088 strncpy(strKey, buff + i, keyLen); 00089 char guid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 00090 strcat(strKey, guid); 00091 unsigned char hash[20]; 00092 sha1((unsigned char*)strKey,strlen((char*)strKey),hash); 00093 string accept = encode64((char*)hash, 20); 00094 string hsRes = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "; 00095 hsRes += accept; 00096 hsRes += "\r\n\r\n"; 00097 printf("%s", hsRes.c_str()); 00098 sock.send_all((char *)hsRes.c_str(), hsRes.size()); 00099 printf("change to WS_CONNECT state\n"); 00100 wsState = WS_CONNECT; 00101 break; 00102 } 00103 } 00104 } 00105 } 00106 break; 00107 case WS_CONNECT: 00108 bool fin = (buff[0] & 0x80) == 0x80; 00109 int opcode = buff[0] & 0x0f; 00110 if (opcode == 0x8) { 00111 printf("close by close opcode\n"); 00112 wsState = WS_HANDSHAKE; 00113 sock.close(); 00114 break; 00115 } 00116 if (opcode == 0x9) { 00117 buff[0] += 1; 00118 sock.send_all(buff, len); 00119 break; 00120 } 00121 int dataLen = buff[1] & 0x7f; 00122 if (!fin || dataLen > 125) { 00123 sock.close(); 00124 printf("close by illegal data length \n"); 00125 wsState = WS_HANDSHAKE; 00126 break; 00127 } 00128 int i = 0; 00129 for (i = 0; i < dataLen; i++) { 00130 buff[6 + i] = buff[6 + i] ^ buff[2 + (i % 4)]; 00131 } 00132 printf("data length:%d\n", dataLen); 00133 buff[6 + dataLen] = 0; 00134 if (opcode == 1) { 00135 printf("received data:%s\n", buff + 6); 00136 char sendData[2 + dataLen + 1]; 00137 sendData[0] = buff[0]; 00138 sendData[1] = buff[1] & 0x7f; 00139 for (i = 0; i < dataLen; i++) { 00140 sendData[2 + i] = buff[6 + i]; 00141 } 00142 sendData[2 + dataLen] = 0; 00143 sock.send_all(sendData, 2 + dataLen); 00144 } else if (opcode == 2) { 00145 led1 = buff[6 + 0]; 00146 led2 = buff[6 + 1]; 00147 led3 = buff[6 + 2]; 00148 led4 = buff[6 + 3]; 00149 } 00150 break; 00151 } 00152 } 00153 00154 sock.close(); 00155 eth.disconnect(); 00156 while(1) {} 00157 } 00158
Generated on Tue Jul 12 2022 23:08:07 by 1.7.2