websocket client

Fork of WebSocketClient by Samuel Mokrani

Committer:
kanehara
Date:
Thu Feb 04 15:49:27 2016 +0000
Revision:
9:6275000e9224
Parent:
8:a909ee26be2d
fix the newline character.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kanehara 9:6275000e9224 1 #include "Websocket.h"
kanehara 9:6275000e9224 2
kanehara 9:6275000e9224 3 #define MAX_TRY_WRITE 20
kanehara 9:6275000e9224 4 #define MAX_TRY_READ 10
kanehara 9:6275000e9224 5
kanehara 9:6275000e9224 6 //Debug is disabled by default
kanehara 9:6275000e9224 7 #ifdef DEBUG
kanehara 9:6275000e9224 8 #define DBG(x, ...) std::printf("[WebSocket : DBG]"x"\r\n", ##__VA_ARGS__);
kanehara 9:6275000e9224 9 #define WARN(x, ...) std::printf("[WebSocket : WARN]"x"\r\n", ##__VA_ARGS__);
kanehara 9:6275000e9224 10 #define ERR(x, ...) std::printf("[WebSocket : ERR]"x"\r\n", ##__VA_ARGS__);
kanehara 9:6275000e9224 11 #define INFO(x, ...) printf("[WebSocket : INFO]"x"\r\n", ##__VA_ARGS__);
kanehara 9:6275000e9224 12 #else
kanehara 9:6275000e9224 13 #define DBG(x, ...)
kanehara 9:6275000e9224 14 #define WARN(x, ...)
kanehara 9:6275000e9224 15 #define ERR(x, ...)
kanehara 9:6275000e9224 16 #define INFO(x, ...)
kanehara 9:6275000e9224 17 #endif
kanehara 9:6275000e9224 18
kanehara 9:6275000e9224 19 Websocket::Websocket(const char * url) {
kanehara 9:6275000e9224 20 fillFields(url);
kanehara 9:6275000e9224 21 socket.set_blocking(false, 400);
kanehara 9:6275000e9224 22 }
kanehara 9:6275000e9224 23
kanehara 9:6275000e9224 24 Websocket::~Websocket () {
kanehara 9:6275000e9224 25 close ();
kanehara 9:6275000e9224 26 }
kanehara 9:6275000e9224 27
kanehara 9:6275000e9224 28 void Websocket::setFnPing (void (*fn)()) {
kanehara 9:6275000e9224 29 fnPing = fn;
kanehara 9:6275000e9224 30 }
kanehara 9:6275000e9224 31
kanehara 9:6275000e9224 32 void Websocket::fillFields(const char * url) {
kanehara 9:6275000e9224 33 int ret = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));
kanehara 9:6275000e9224 34 if(ret)
kanehara 9:6275000e9224 35 {
kanehara 9:6275000e9224 36 ERR("URL parsing failed; please use: \"ws://ip-or-domain[:port]/path\"");
kanehara 9:6275000e9224 37 return;
kanehara 9:6275000e9224 38 }
kanehara 9:6275000e9224 39
kanehara 9:6275000e9224 40 if(port == 0) //TODO do handle WSS->443
kanehara 9:6275000e9224 41 {
kanehara 9:6275000e9224 42 port = 80;
kanehara 9:6275000e9224 43 }
kanehara 9:6275000e9224 44
kanehara 9:6275000e9224 45 if(strcmp(scheme, "ws"))
kanehara 9:6275000e9224 46 {
kanehara 9:6275000e9224 47 ERR("Wrong scheme, please use \"ws\" instead");
kanehara 9:6275000e9224 48 }
kanehara 9:6275000e9224 49 }
kanehara 9:6275000e9224 50
kanehara 9:6275000e9224 51 int Websocket::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL
kanehara 9:6275000e9224 52 {
kanehara 9:6275000e9224 53 char* schemePtr = (char*) url;
kanehara 9:6275000e9224 54 char* hostPtr = (char*) strstr(url, "://");
kanehara 9:6275000e9224 55 if(hostPtr == NULL)
kanehara 9:6275000e9224 56 {
kanehara 9:6275000e9224 57 WARN("Could not find host");
kanehara 9:6275000e9224 58 return -1; //URL is invalid
kanehara 9:6275000e9224 59 }
kanehara 9:6275000e9224 60
kanehara 9:6275000e9224 61 if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char
kanehara 9:6275000e9224 62 {
kanehara 9:6275000e9224 63 WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
kanehara 9:6275000e9224 64 return -1;
kanehara 9:6275000e9224 65 }
kanehara 9:6275000e9224 66 memcpy(scheme, schemePtr, hostPtr - schemePtr);
kanehara 9:6275000e9224 67 scheme[hostPtr - schemePtr] = '\0';
kanehara 9:6275000e9224 68
kanehara 9:6275000e9224 69 hostPtr+=3;
kanehara 9:6275000e9224 70
kanehara 9:6275000e9224 71 size_t hostLen = 0;
kanehara 9:6275000e9224 72
kanehara 9:6275000e9224 73 char* portPtr = strchr(hostPtr, ':');
kanehara 9:6275000e9224 74 if( portPtr != NULL )
kanehara 9:6275000e9224 75 {
kanehara 9:6275000e9224 76 hostLen = portPtr - hostPtr;
kanehara 9:6275000e9224 77 portPtr++;
kanehara 9:6275000e9224 78 if( sscanf(portPtr, "%hu", port) != 1)
kanehara 9:6275000e9224 79 {
kanehara 9:6275000e9224 80 WARN("Could not find port");
kanehara 9:6275000e9224 81 return -1;
kanehara 9:6275000e9224 82 }
kanehara 9:6275000e9224 83 }
kanehara 9:6275000e9224 84 else
kanehara 9:6275000e9224 85 {
kanehara 9:6275000e9224 86 *port=0;
kanehara 9:6275000e9224 87 }
kanehara 9:6275000e9224 88 char* pathPtr = strchr(hostPtr, '/');
kanehara 9:6275000e9224 89 if( hostLen == 0 )
kanehara 9:6275000e9224 90 {
kanehara 9:6275000e9224 91 hostLen = pathPtr - hostPtr;
kanehara 9:6275000e9224 92 }
kanehara 9:6275000e9224 93
kanehara 9:6275000e9224 94 if( maxHostLen < hostLen + 1 ) //including NULL-terminating char
kanehara 9:6275000e9224 95 {
kanehara 9:6275000e9224 96 WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
kanehara 9:6275000e9224 97 return -1;
kanehara 9:6275000e9224 98 }
kanehara 9:6275000e9224 99 memcpy(host, hostPtr, hostLen);
kanehara 9:6275000e9224 100 host[hostLen] = '\0';
kanehara 9:6275000e9224 101
kanehara 9:6275000e9224 102 size_t pathLen;
kanehara 9:6275000e9224 103 char* fragmentPtr = strchr(hostPtr, '#');
kanehara 9:6275000e9224 104 if(fragmentPtr != NULL)
kanehara 9:6275000e9224 105 {
kanehara 9:6275000e9224 106 pathLen = fragmentPtr - pathPtr;
kanehara 9:6275000e9224 107 }
kanehara 9:6275000e9224 108 else
kanehara 9:6275000e9224 109 {
kanehara 9:6275000e9224 110 pathLen = strlen(pathPtr);
kanehara 9:6275000e9224 111 }
kanehara 9:6275000e9224 112
kanehara 9:6275000e9224 113 if( maxPathLen < pathLen + 1 ) //including NULL-terminating char
kanehara 9:6275000e9224 114 {
kanehara 9:6275000e9224 115 WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
kanehara 9:6275000e9224 116 return -1;
kanehara 9:6275000e9224 117 }
kanehara 9:6275000e9224 118 memcpy(path, pathPtr, pathLen);
kanehara 9:6275000e9224 119 path[pathLen] = '\0';
kanehara 9:6275000e9224 120
kanehara 9:6275000e9224 121 return 0;
kanehara 9:6275000e9224 122 }
kanehara 9:6275000e9224 123
kanehara 9:6275000e9224 124
kanehara 9:6275000e9224 125 bool Websocket::connect() {
kanehara 9:6275000e9224 126 // char cmd[200];
kanehara 9:6275000e9224 127
kanehara 9:6275000e9224 128 while (socket.connect(host, port) < 0) {
kanehara 9:6275000e9224 129 ERR("Unable to connect to (%s) on port (%d)", host, port);
kanehara 9:6275000e9224 130 wait(0.2);
kanehara 9:6275000e9224 131 return false;
kanehara 9:6275000e9224 132 }
kanehara 9:6275000e9224 133
kanehara 9:6275000e9224 134 // sent http header to upgrade to the ws protocol
kanehara 9:6275000e9224 135 membuf.size = sprintf(membuf.ptr, "GET %s HTTP/1.1\r\n", path);
kanehara 9:6275000e9224 136 write(membuf.ptr, membuf.size);
kanehara 9:6275000e9224 137
kanehara 9:6275000e9224 138 membuf.size = sprintf(membuf.ptr, "Host: %s:%d\r\n", host, port);
kanehara 9:6275000e9224 139 write(membuf.ptr, membuf.size);
kanehara 9:6275000e9224 140
kanehara 9:6275000e9224 141 membuf.size = sprintf(membuf.ptr, "Upgrade: WebSocket\r\n");
kanehara 9:6275000e9224 142 write(membuf.ptr, membuf.size);
kanehara 9:6275000e9224 143
kanehara 9:6275000e9224 144 membuf.size = sprintf(membuf.ptr, "Connection: Upgrade\r\n");
kanehara 9:6275000e9224 145 write(membuf.ptr, membuf.size);
kanehara 9:6275000e9224 146
kanehara 9:6275000e9224 147 membuf.size = sprintf(membuf.ptr, "Sec-WebSocket-Key: L159VM0TWUzyDxwJEIEzjw==\r\n");
kanehara 9:6275000e9224 148 write(membuf.ptr, membuf.size);
kanehara 9:6275000e9224 149
kanehara 9:6275000e9224 150 membuf.size = sprintf(membuf.ptr, "Sec-WebSocket-Version: 13\r\n\r\n");
kanehara 9:6275000e9224 151 int ret = write(membuf.ptr, membuf.size);
kanehara 9:6275000e9224 152 if (ret != membuf.size) {
kanehara 9:6275000e9224 153 close();
kanehara 9:6275000e9224 154 ERR("Could not send request");
kanehara 9:6275000e9224 155 return false;
kanehara 9:6275000e9224 156 }
kanehara 9:6275000e9224 157
kanehara 9:6275000e9224 158 membuf.size = read(membuf.ptr, 200, 100);
kanehara 9:6275000e9224 159 if (membuf.size < 0) {
kanehara 9:6275000e9224 160 close();
kanehara 9:6275000e9224 161 ERR("Could not receive answer\r\n");
kanehara 9:6275000e9224 162 return false;
kanehara 9:6275000e9224 163 }
kanehara 9:6275000e9224 164
kanehara 9:6275000e9224 165 membuf.ptr[membuf.size] = '\0';
kanehara 9:6275000e9224 166 DBG("recv: %s\r\n", membuf.ptr);
kanehara 9:6275000e9224 167
kanehara 9:6275000e9224 168 char* p = strstr (membuf.ptr, "DdLWT/1JcX+nQFHebYP+rqEx5xI=");
kanehara 9:6275000e9224 169 if (p == NULL) {
kanehara 9:6275000e9224 170 ERR("Wrong answer from server, got \"%s\" instead\r\n", membuf.ptr);
kanehara 9:6275000e9224 171 do {
kanehara 9:6275000e9224 172 membuf.size = read(membuf.ptr, 200, 100);
kanehara 9:6275000e9224 173 if (membuf.size < 0) {
kanehara 9:6275000e9224 174 ERR("Could not receive answer\r\n");
kanehara 9:6275000e9224 175 return false;
kanehara 9:6275000e9224 176 }
kanehara 9:6275000e9224 177 membuf.ptr[membuf.size] = '\0';
kanehara 9:6275000e9224 178 } while (membuf.size > 0);
kanehara 9:6275000e9224 179 close();
kanehara 9:6275000e9224 180 return false;
kanehara 9:6275000e9224 181 }
kanehara 9:6275000e9224 182
kanehara 9:6275000e9224 183 INFO("\r\nhost: %s\r\npath: %s\r\nport: %d\r\n\r\n", host, path, port);
kanehara 9:6275000e9224 184 p = strstr (p, "\r\n\r\n");
kanehara 9:6275000e9224 185 if (p) {
kanehara 9:6275000e9224 186 membuf.skipTo (p + 4);
kanehara 9:6275000e9224 187 }
kanehara 9:6275000e9224 188 return true;
kanehara 9:6275000e9224 189 }
kanehara 9:6275000e9224 190
kanehara 9:6275000e9224 191 int Websocket::sendLength(uint32_t len, char * msg) {
kanehara 9:6275000e9224 192
kanehara 9:6275000e9224 193 if (len < 126) {
kanehara 9:6275000e9224 194 msg[0] = len | (1<<7);
kanehara 9:6275000e9224 195 return 1;
kanehara 9:6275000e9224 196 } else if (len < 65535) {
kanehara 9:6275000e9224 197 msg[0] = 126 | (1<<7);
kanehara 9:6275000e9224 198 msg[1] = (len >> 8) & 0xff;
kanehara 9:6275000e9224 199 msg[2] = len & 0xff;
kanehara 9:6275000e9224 200 return 3;
kanehara 9:6275000e9224 201 } else {
kanehara 9:6275000e9224 202 msg[0] = 127 | (1<<7);
kanehara 9:6275000e9224 203 for (int i = 0; i < 8; i++) {
kanehara 9:6275000e9224 204 msg[i+1] = (len >> i*8) & 0xff;
kanehara 9:6275000e9224 205 }
kanehara 9:6275000e9224 206 return 9;
kanehara 9:6275000e9224 207 }
kanehara 9:6275000e9224 208 }
kanehara 9:6275000e9224 209
kanehara 9:6275000e9224 210 int Websocket::readChar(char * pC, bool block) {
kanehara 9:6275000e9224 211 return read(pC, 1, 1);
kanehara 9:6275000e9224 212 }
kanehara 9:6275000e9224 213
kanehara 9:6275000e9224 214 int Websocket::sendOpcode(uint8_t opcode, char * msg) {
kanehara 9:6275000e9224 215 msg[0] = 0x80 | (opcode & 0x0f);
kanehara 9:6275000e9224 216 return 1;
kanehara 9:6275000e9224 217 }
kanehara 9:6275000e9224 218
kanehara 9:6275000e9224 219 int Websocket::sendMask(char * msg) {
kanehara 9:6275000e9224 220 for (int i = 0; i < 4; i++) {
kanehara 9:6275000e9224 221 msg[i] = 0;
kanehara 9:6275000e9224 222 }
kanehara 9:6275000e9224 223 return 4;
kanehara 9:6275000e9224 224 }
kanehara 9:6275000e9224 225
kanehara 9:6275000e9224 226 int Websocket::sendOp(uint8_t opcode, size_t len, char* str) {
kanehara 9:6275000e9224 227 char msg[strlen(str) + 15];
kanehara 9:6275000e9224 228 int idx = 0;
kanehara 9:6275000e9224 229 idx = sendOpcode(opcode, msg);
kanehara 9:6275000e9224 230 idx += sendLength(len, msg + idx);
kanehara 9:6275000e9224 231 idx += sendMask(msg + idx);
kanehara 9:6275000e9224 232 memcpy(msg + idx, str, len);
kanehara 9:6275000e9224 233 int res = write(msg, idx + len);
kanehara 9:6275000e9224 234 return res;
kanehara 9:6275000e9224 235 }
kanehara 9:6275000e9224 236
kanehara 9:6275000e9224 237 int Websocket::send(char * str) {
kanehara 9:6275000e9224 238 return sendOp(0x01, strlen(str), str);
kanehara 9:6275000e9224 239 }
kanehara 9:6275000e9224 240
kanehara 9:6275000e9224 241 int Websocket::sendBin(size_t len, char* str) {
kanehara 9:6275000e9224 242 return sendOp(0x02, len, str);
kanehara 9:6275000e9224 243 }
kanehara 9:6275000e9224 244
kanehara 9:6275000e9224 245 bool Websocket::read(char * message, size_t& size) {
kanehara 9:6275000e9224 246 uint8_t opcode = 0;
kanehara 9:6275000e9224 247 Timer tmr;
kanehara 9:6275000e9224 248
kanehara 9:6275000e9224 249 // read the opcode
kanehara 9:6275000e9224 250 tmr.start();
kanehara 9:6275000e9224 251 while (true) {
kanehara 9:6275000e9224 252 if (tmr.read() > 3) {
kanehara 9:6275000e9224 253 DBG("timeout ws\r\n");
kanehara 9:6275000e9224 254 return false;
kanehara 9:6275000e9224 255 }
kanehara 9:6275000e9224 256
kanehara 9:6275000e9224 257 if(!socket.is_connected())
kanehara 9:6275000e9224 258 {
kanehara 9:6275000e9224 259 WARN("Connection was closed by server");
kanehara 9:6275000e9224 260 return false;
kanehara 9:6275000e9224 261 }
kanehara 9:6275000e9224 262
kanehara 9:6275000e9224 263 if (membuf.size > 0) {
kanehara 9:6275000e9224 264 opcode = (uint8_t)*membuf.ptr;
kanehara 9:6275000e9224 265 membuf.skip (1);
kanehara 9:6275000e9224 266 } else {
kanehara 9:6275000e9224 267 socket.set_blocking(false, 1);
kanehara 9:6275000e9224 268 if (socket.receive((char*)&opcode, 1) != 1) {
kanehara 9:6275000e9224 269 socket.set_blocking(false, 2000);
kanehara 9:6275000e9224 270 return false;
kanehara 9:6275000e9224 271 }
kanehara 9:6275000e9224 272 }
kanehara 9:6275000e9224 273
kanehara 9:6275000e9224 274 socket.set_blocking(false, 2000);
kanehara 9:6275000e9224 275
kanehara 9:6275000e9224 276 DBG("opcode: 0x%X", opcode);
kanehara 9:6275000e9224 277
kanehara 9:6275000e9224 278 switch (opcode) {
kanehara 9:6275000e9224 279 case 0x81:
kanehara 9:6275000e9224 280 case 0x82:
kanehara 9:6275000e9224 281 DBG ("readBinFrame ()");
kanehara 9:6275000e9224 282 return readBinFrame (message, size);
kanehara 9:6275000e9224 283 case 0x89:
kanehara 9:6275000e9224 284 DBG ("readPing ()");
kanehara 9:6275000e9224 285 return readPing ();
kanehara 9:6275000e9224 286 default:;
kanehara 9:6275000e9224 287 }
kanehara 9:6275000e9224 288 }
kanehara 9:6275000e9224 289
kanehara 9:6275000e9224 290 return false;
kanehara 9:6275000e9224 291 }
kanehara 9:6275000e9224 292
kanehara 9:6275000e9224 293 bool Websocket::close() {
kanehara 9:6275000e9224 294 if (!is_connected())
kanehara 9:6275000e9224 295 return false;
kanehara 9:6275000e9224 296
kanehara 9:6275000e9224 297 int ret = socket.close();
kanehara 9:6275000e9224 298 if (ret < 0) {
kanehara 9:6275000e9224 299 ERR("Could not disconnect");
kanehara 9:6275000e9224 300 return false;
kanehara 9:6275000e9224 301 }
kanehara 9:6275000e9224 302 return true;
kanehara 9:6275000e9224 303 }
kanehara 9:6275000e9224 304
kanehara 9:6275000e9224 305 bool Websocket::is_connected() {
kanehara 9:6275000e9224 306 return socket.is_connected();
kanehara 9:6275000e9224 307 }
kanehara 9:6275000e9224 308
kanehara 9:6275000e9224 309 char* Websocket::getPath() {
kanehara 9:6275000e9224 310 return path;
kanehara 9:6275000e9224 311 }
kanehara 9:6275000e9224 312
kanehara 9:6275000e9224 313 int Websocket::write(char * str, int len) {
kanehara 9:6275000e9224 314 int res = 0, idx = 0;
kanehara 9:6275000e9224 315
kanehara 9:6275000e9224 316 for (int j = 0; j < MAX_TRY_WRITE; j++) {
kanehara 9:6275000e9224 317
kanehara 9:6275000e9224 318 if(!socket.is_connected())
kanehara 9:6275000e9224 319 {
kanehara 9:6275000e9224 320 WARN("Connection was closed by server");
kanehara 9:6275000e9224 321 break;
kanehara 9:6275000e9224 322 }
kanehara 9:6275000e9224 323
kanehara 9:6275000e9224 324 if ((res = socket.send_all(str + idx, len - idx)) == -1)
kanehara 9:6275000e9224 325 continue;
kanehara 9:6275000e9224 326
kanehara 9:6275000e9224 327 idx += res;
kanehara 9:6275000e9224 328
kanehara 9:6275000e9224 329 if (idx == len)
kanehara 9:6275000e9224 330 return len;
kanehara 9:6275000e9224 331 }
kanehara 9:6275000e9224 332
kanehara 9:6275000e9224 333 return (idx == 0) ? -1 : idx;
kanehara 9:6275000e9224 334 }
kanehara 9:6275000e9224 335
kanehara 9:6275000e9224 336 int Websocket::read(char * str, int len, int min_len) {
kanehara 9:6275000e9224 337 if (len == 0)
kanehara 9:6275000e9224 338 return 0;
kanehara 9:6275000e9224 339 if (membuf.size > 0) {
kanehara 9:6275000e9224 340 int s;
kanehara 9:6275000e9224 341 s = len < membuf.size ? len : membuf.size;
kanehara 9:6275000e9224 342 memcpy (str, membuf.ptr, s);
kanehara 9:6275000e9224 343 membuf.skip (s);
kanehara 9:6275000e9224 344 if (min_len != -1 && s >= min_len)
kanehara 9:6275000e9224 345 return s;
kanehara 9:6275000e9224 346 str += s;
kanehara 9:6275000e9224 347 len -= s;
kanehara 9:6275000e9224 348 min_len -= s;
kanehara 9:6275000e9224 349 }
kanehara 9:6275000e9224 350 int res = 0, idx = 0;
kanehara 9:6275000e9224 351
kanehara 9:6275000e9224 352 for (int j = 0; j < MAX_TRY_WRITE; j++) {
kanehara 9:6275000e9224 353
kanehara 9:6275000e9224 354 if ((res = socket.receive_all(str + idx, len - idx)) == -1)
kanehara 9:6275000e9224 355 continue;
kanehara 9:6275000e9224 356
kanehara 9:6275000e9224 357 idx += res;
kanehara 9:6275000e9224 358
kanehara 9:6275000e9224 359 if (idx == len || (min_len != -1 && idx > min_len))
kanehara 9:6275000e9224 360 return idx;
kanehara 9:6275000e9224 361 }
kanehara 9:6275000e9224 362
kanehara 9:6275000e9224 363 return (idx == 0) ? -1 : idx;
kanehara 9:6275000e9224 364 }
kanehara 9:6275000e9224 365
kanehara 9:6275000e9224 366 uint32_t Websocket::readLenFrame (char* mask) {
kanehara 9:6275000e9224 367 uint32_t len_msg;
kanehara 9:6275000e9224 368 char c;
kanehara 9:6275000e9224 369 bool is_masked;
kanehara 9:6275000e9224 370 int i;
kanehara 9:6275000e9224 371 size_t s;
kanehara 9:6275000e9224 372
kanehara 9:6275000e9224 373 s = read (&c, 1, 1);
kanehara 9:6275000e9224 374 if (s < 1) return 0;
kanehara 9:6275000e9224 375 len_msg = c & 0x7f;
kanehara 9:6275000e9224 376 is_masked = c & 0x80;
kanehara 9:6275000e9224 377 if (len_msg == 126) {
kanehara 9:6275000e9224 378 s = read (&c, 1, 1);
kanehara 9:6275000e9224 379 if (s < 1) return 0;
kanehara 9:6275000e9224 380 len_msg = c << 8;
kanehara 9:6275000e9224 381 s = read (&c, 1, 1);
kanehara 9:6275000e9224 382 if (s < 1) return 0;
kanehara 9:6275000e9224 383 len_msg += c;
kanehara 9:6275000e9224 384 } else if (len_msg == 127) {
kanehara 9:6275000e9224 385 len_msg = 0;
kanehara 9:6275000e9224 386 for (int i = 0; i < 8; i++) {
kanehara 9:6275000e9224 387 s = read (&c, 1, 1);
kanehara 9:6275000e9224 388 len_msg += (c << (7 - i) * 8);
kanehara 9:6275000e9224 389 }
kanehara 9:6275000e9224 390 }
kanehara 9:6275000e9224 391 if (is_masked) {
kanehara 9:6275000e9224 392 DBG ("is_masked");
kanehara 9:6275000e9224 393 for (i = 0; i < 4; i++) {
kanehara 9:6275000e9224 394 s = read (&c, 1, 1);
kanehara 9:6275000e9224 395 if (s < 1) return 0;
kanehara 9:6275000e9224 396 if (mask)
kanehara 9:6275000e9224 397 mask[i] = c;
kanehara 9:6275000e9224 398 }
kanehara 9:6275000e9224 399 }
kanehara 9:6275000e9224 400
kanehara 9:6275000e9224 401 return len_msg;
kanehara 9:6275000e9224 402 }
kanehara 9:6275000e9224 403
kanehara 9:6275000e9224 404 bool Websocket::readBinFrame (char* message, size_t& size) {
kanehara 9:6275000e9224 405 int i;
kanehara 9:6275000e9224 406 uint32_t len_msg;
kanehara 9:6275000e9224 407 char mask[4] = {0, 0, 0, 0};
kanehara 9:6275000e9224 408
kanehara 9:6275000e9224 409 len_msg = readLenFrame (mask);
kanehara 9:6275000e9224 410 DBG("length: %d", len_msg);
kanehara 9:6275000e9224 411 if (len_msg == 0) {
kanehara 9:6275000e9224 412 return false;
kanehara 9:6275000e9224 413 }
kanehara 9:6275000e9224 414 if (size < len_msg)
kanehara 9:6275000e9224 415 len_msg = size;
kanehara 9:6275000e9224 416
kanehara 9:6275000e9224 417 int nb = read(message, len_msg, len_msg);
kanehara 9:6275000e9224 418 if (nb != len_msg)
kanehara 9:6275000e9224 419 return false;
kanehara 9:6275000e9224 420
kanehara 9:6275000e9224 421 for (i = 0; i < len_msg; i++) {
kanehara 9:6275000e9224 422 message[i] = message[i] ^ mask[i % 4];
kanehara 9:6275000e9224 423 }
kanehara 9:6275000e9224 424 size = len_msg;
kanehara 9:6275000e9224 425
kanehara 9:6275000e9224 426 return true;
kanehara 9:6275000e9224 427 }
kanehara 9:6275000e9224 428
kanehara 9:6275000e9224 429 bool Websocket::readPing () {
kanehara 9:6275000e9224 430 uint32_t len_msg = readLenFrame (NULL);
kanehara 9:6275000e9224 431 char data[len_msg];
kanehara 9:6275000e9224 432 int nb = read(data, len_msg, len_msg);
kanehara 9:6275000e9224 433 DBG ("ping");
kanehara 9:6275000e9224 434 sendOp (0x0A, 0, NULL);
kanehara 9:6275000e9224 435 if (fnPing) {
kanehara 9:6275000e9224 436 fnPing ();
kanehara 9:6275000e9224 437 }
kanehara 9:6275000e9224 438 return false;
kanehara 9:6275000e9224 439 }