Counter

Dependencies:   EthernetInterface NTPClient SDFileSystem TextLCD WebSocketClient mbed-rtos mbed Socket lwip-eth lwip-sys lwip FATFileSystem

Committer:
Tuxitheone
Date:
Mon Feb 29 18:59:15 2016 +0000
Revision:
0:ecaf3e593122
TankCounter

Who changed what in which revision?

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