Committer:
donatien
Date:
Thu May 31 16:02:12 2012 +0000
Revision:
0:87e52bb764c5

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:87e52bb764c5 1 #define __DEBUG__ 4 //Maximum verbosity
donatien 0:87e52bb764c5 2 #ifndef __MODULE__
donatien 0:87e52bb764c5 3 #define __MODULE__ "Websocket.cpp"
donatien 0:87e52bb764c5 4 #endif
donatien 0:87e52bb764c5 5
donatien 0:87e52bb764c5 6 #include "core/fwk.h"
donatien 0:87e52bb764c5 7
donatien 0:87e52bb764c5 8 #include "Websocket.h"
donatien 0:87e52bb764c5 9 #include <string>
donatien 0:87e52bb764c5 10
donatien 0:87e52bb764c5 11
donatien 0:87e52bb764c5 12 Websocket::Websocket(char * url) : m_sockHandle(-1) {
donatien 0:87e52bb764c5 13 //server_ip = NULL;
donatien 0:87e52bb764c5 14
donatien 0:87e52bb764c5 15 std::memset(&m_sockAddr, 0, sizeof(struct sockaddr_in));
donatien 0:87e52bb764c5 16
donatien 0:87e52bb764c5 17 fillFields(url);
donatien 0:87e52bb764c5 18 }
donatien 0:87e52bb764c5 19
donatien 0:87e52bb764c5 20
donatien 0:87e52bb764c5 21 void Websocket::fillFields(char * url) {
donatien 0:87e52bb764c5 22 char *res = NULL;
donatien 0:87e52bb764c5 23 char *res1 = NULL;
donatien 0:87e52bb764c5 24
donatien 0:87e52bb764c5 25 char buf[50];
donatien 0:87e52bb764c5 26 strcpy(buf, url);
donatien 0:87e52bb764c5 27
donatien 0:87e52bb764c5 28 res = strtok(buf, ":");
donatien 0:87e52bb764c5 29 if (strcmp(res, "ws")) {
donatien 0:87e52bb764c5 30 #ifdef DEBUG
donatien 0:87e52bb764c5 31 printf("\r\nFormat error: please use: \"ws://ip-or-domain[:port]/path\"\r\n\r\n");
donatien 0:87e52bb764c5 32 #endif
donatien 0:87e52bb764c5 33 } else {
donatien 0:87e52bb764c5 34 //ip_domain and port
donatien 0:87e52bb764c5 35 res = strtok(NULL, "/");
donatien 0:87e52bb764c5 36
donatien 0:87e52bb764c5 37 //path
donatien 0:87e52bb764c5 38 res1 = strtok(NULL, " ");
donatien 0:87e52bb764c5 39 if (res1 != NULL) {
donatien 0:87e52bb764c5 40 path = res1;
donatien 0:87e52bb764c5 41 }
donatien 0:87e52bb764c5 42
donatien 0:87e52bb764c5 43 //ip_domain
donatien 0:87e52bb764c5 44 res = strtok(res, ":");
donatien 0:87e52bb764c5 45
donatien 0:87e52bb764c5 46 //port
donatien 0:87e52bb764c5 47 res1 = strtok(NULL, " ");
donatien 0:87e52bb764c5 48 //port
donatien 0:87e52bb764c5 49 if (res1 != NULL) {
donatien 0:87e52bb764c5 50 port = res1;
donatien 0:87e52bb764c5 51 } else {
donatien 0:87e52bb764c5 52 port = "80";
donatien 0:87e52bb764c5 53 }
donatien 0:87e52bb764c5 54
donatien 0:87e52bb764c5 55 if (res != NULL) {
donatien 0:87e52bb764c5 56 ip_domain = res;
donatien 0:87e52bb764c5 57
donatien 0:87e52bb764c5 58 //if we use ethernet, we must decode ip address or use dnsresolver
donatien 0:87e52bb764c5 59 strcpy(buf, res);
donatien 0:87e52bb764c5 60
donatien 0:87e52bb764c5 61 //we try to decode the ip address
donatien 0:87e52bb764c5 62 if (buf[0] >= '0' && buf[0] <= '9') {
donatien 0:87e52bb764c5 63 res = strtok(buf, ".");
donatien 0:87e52bb764c5 64 int i = 0;
donatien 0:87e52bb764c5 65 int ip[4];
donatien 0:87e52bb764c5 66 while (res != NULL) {
donatien 0:87e52bb764c5 67 ip[i] = atoi(res);
donatien 0:87e52bb764c5 68 res = strtok(NULL, ".");
donatien 0:87e52bb764c5 69 i++;
donatien 0:87e52bb764c5 70 }
donatien 0:87e52bb764c5 71 //server_ip = new IpAddr(ip[0], ip[1], ip[2], ip[3]);
donatien 0:87e52bb764c5 72 m_sockAddr.sin_addr.s_addr = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | ip[3]; //Could do this easier if using inet_pton()
donatien 0:87e52bb764c5 73
donatien 0:87e52bb764c5 74 }
donatien 0:87e52bb764c5 75 }
donatien 0:87e52bb764c5 76 }
donatien 0:87e52bb764c5 77 }
donatien 0:87e52bb764c5 78
donatien 0:87e52bb764c5 79
donatien 0:87e52bb764c5 80 bool Websocket::connect() {
donatien 0:87e52bb764c5 81 char cmd[192];
donatien 0:87e52bb764c5 82
donatien 0:87e52bb764c5 83 //Resolve DNS if needed
donatien 0:87e52bb764c5 84 if(m_sockAddr.sin_addr.s_addr == 0)
donatien 0:87e52bb764c5 85 {
donatien 0:87e52bb764c5 86 DBG("Resolving DNS socket");
donatien 0:87e52bb764c5 87 struct hostent *server = socket::gethostbyname(ip_domain.c_str());
donatien 0:87e52bb764c5 88 if(server == NULL)
donatien 0:87e52bb764c5 89 {
donatien 0:87e52bb764c5 90 return false;
donatien 0:87e52bb764c5 91 }
donatien 0:87e52bb764c5 92 memcpy((char*)&m_sockAddr.sin_addr.s_addr, (char*)server->h_addr_list[0], server->h_length);
donatien 0:87e52bb764c5 93 }
donatien 0:87e52bb764c5 94
donatien 0:87e52bb764c5 95 m_sockAddr.sin_family = AF_INET;
donatien 0:87e52bb764c5 96 m_sockAddr.sin_port = htons(atoi(port.c_str()));
donatien 0:87e52bb764c5 97
donatien 0:87e52bb764c5 98 //Create socket
donatien 0:87e52bb764c5 99 DBG("Creating socket");
donatien 0:87e52bb764c5 100 m_sockHandle = socket::socket(AF_INET, SOCK_STREAM, 0);
donatien 0:87e52bb764c5 101 if (m_sockHandle < 0)
donatien 0:87e52bb764c5 102 {
donatien 0:87e52bb764c5 103 ERR("Could not create socket");
donatien 0:87e52bb764c5 104 return false;
donatien 0:87e52bb764c5 105 }
donatien 0:87e52bb764c5 106 DBG("Handle is %d",m_sockHandle);
donatien 0:87e52bb764c5 107
donatien 0:87e52bb764c5 108 //Connect
donatien 0:87e52bb764c5 109 DBG("Connecting socket to %s:%d", inet_ntoa(m_sockAddr.sin_addr), ntohs(m_sockAddr.sin_port));
donatien 0:87e52bb764c5 110 int ret = socket::connect(m_sockHandle, (const struct sockaddr *)&m_sockAddr, sizeof(m_sockAddr));
donatien 0:87e52bb764c5 111 if (ret < 0)
donatien 0:87e52bb764c5 112 {
donatien 0:87e52bb764c5 113 socket::close(m_sockHandle);
donatien 0:87e52bb764c5 114 ERR("Could not connect");
donatien 0:87e52bb764c5 115 return false;
donatien 0:87e52bb764c5 116 }
donatien 0:87e52bb764c5 117
donatien 0:87e52bb764c5 118 m_connected = true;
donatien 0:87e52bb764c5 119
donatien 0:87e52bb764c5 120 DBG("Sending HTTP request");
donatien 0:87e52bb764c5 121 //send websocket HTTP header
donatien 0:87e52bb764c5 122 sprintf(cmd, "GET /%s HTTP/1.1\r\n", path.c_str());
donatien 0:87e52bb764c5 123 write((uint8_t*)cmd, strlen(cmd));
donatien 0:87e52bb764c5 124
donatien 0:87e52bb764c5 125 sprintf(cmd, "Host: %s:%s\r\n", ip_domain.c_str(), port.c_str());
donatien 0:87e52bb764c5 126 write((uint8_t*)cmd, strlen(cmd));
donatien 0:87e52bb764c5 127
donatien 0:87e52bb764c5 128 sprintf(cmd, "Upgrade: WebSocket\r\n");
donatien 0:87e52bb764c5 129 write((uint8_t*)cmd, strlen(cmd));
donatien 0:87e52bb764c5 130
donatien 0:87e52bb764c5 131 sprintf(cmd, "Connection: Upgrade\r\n");
donatien 0:87e52bb764c5 132 write((uint8_t*)cmd, strlen(cmd));
donatien 0:87e52bb764c5 133
donatien 0:87e52bb764c5 134 // socket::send(m_sockHandle, "Origin: null\r\n", strlen("Origin: null\r\n"), 0);
donatien 0:87e52bb764c5 135
donatien 0:87e52bb764c5 136 sprintf(cmd, "Sec-WebSocket-Key: L159VM0TWUzyDxwJEIEzjw==\r\n");
donatien 0:87e52bb764c5 137 write((uint8_t*)cmd, strlen(cmd));
donatien 0:87e52bb764c5 138
donatien 0:87e52bb764c5 139 sprintf(cmd, "Sec-WebSocket-Version: 13\r\n\r\n");
donatien 0:87e52bb764c5 140 ret = write((uint8_t*)cmd, strlen(cmd));
donatien 0:87e52bb764c5 141 if(ret < 0)
donatien 0:87e52bb764c5 142 {
donatien 0:87e52bb764c5 143 close();
donatien 0:87e52bb764c5 144 ERR("Could not send request");
donatien 0:87e52bb764c5 145 m_connected = false;
donatien 0:87e52bb764c5 146 return false;
donatien 0:87e52bb764c5 147 }
donatien 0:87e52bb764c5 148
donatien 0:87e52bb764c5 149 DBG("Waiting for answer");
donatien 0:87e52bb764c5 150 ret = read((uint8_t*)cmd, 0, 192);
donatien 0:87e52bb764c5 151 if(ret < 0)
donatien 0:87e52bb764c5 152 {
donatien 0:87e52bb764c5 153 close();
donatien 0:87e52bb764c5 154 ERR("Could not receive answer");
donatien 0:87e52bb764c5 155 m_connected = false;
donatien 0:87e52bb764c5 156 return false;
donatien 0:87e52bb764c5 157 }
donatien 0:87e52bb764c5 158 cmd[ret] = '\0';
donatien 0:87e52bb764c5 159
donatien 0:87e52bb764c5 160 DBG("Comparing answer");
donatien 0:87e52bb764c5 161 if( strstr(cmd, "Sec-WebSocket-Accept: DdLWT/1JcX+nQFHebYP+rqEx5xI=") == NULL )
donatien 0:87e52bb764c5 162 {
donatien 0:87e52bb764c5 163 ERR("Wrong answer from server, got \"%s\" instead", cmd);
donatien 0:87e52bb764c5 164 do{
donatien 0:87e52bb764c5 165 ret = read((uint8_t*)cmd, 0, 192);
donatien 0:87e52bb764c5 166 if(ret < 0)
donatien 0:87e52bb764c5 167 {
donatien 0:87e52bb764c5 168 ERR("Could not receive answer");
donatien 0:87e52bb764c5 169 return false;
donatien 0:87e52bb764c5 170 }
donatien 0:87e52bb764c5 171 cmd[ret] = '\0';
donatien 0:87e52bb764c5 172 printf("%s",cmd);
donatien 0:87e52bb764c5 173 } while(ret > 0);
donatien 0:87e52bb764c5 174 close();
donatien 0:87e52bb764c5 175 m_connected = false;
donatien 0:87e52bb764c5 176 return false;
donatien 0:87e52bb764c5 177 }
donatien 0:87e52bb764c5 178 DBG("\r\nip_domain: %s\r\npath: /%s\r\nport: %s\r\n\r\n",this->ip_domain.c_str(), this->path.c_str(), this->port.c_str());
donatien 0:87e52bb764c5 179 return true;
donatien 0:87e52bb764c5 180 }
donatien 0:87e52bb764c5 181
donatien 0:87e52bb764c5 182 void Websocket::sendLength(uint32_t len) {
donatien 0:87e52bb764c5 183 if (len < 126) {
donatien 0:87e52bb764c5 184 sendChar(len | (1<<7));
donatien 0:87e52bb764c5 185 } else if (len < 65535) {
donatien 0:87e52bb764c5 186 sendChar(126 | (1<<7));
donatien 0:87e52bb764c5 187 sendChar(len & 0xff);
donatien 0:87e52bb764c5 188 sendChar((len >> 8) & 0xff);
donatien 0:87e52bb764c5 189 } else {
donatien 0:87e52bb764c5 190 sendChar(127 | (1<<7));
donatien 0:87e52bb764c5 191 for (int i = 0; i < 8; i++) {
donatien 0:87e52bb764c5 192 sendChar((len >> i*8) & 0xff);
donatien 0:87e52bb764c5 193 }
donatien 0:87e52bb764c5 194 }
donatien 0:87e52bb764c5 195 }
donatien 0:87e52bb764c5 196
donatien 0:87e52bb764c5 197 void Websocket::sendChar(uint8_t c) {
donatien 0:87e52bb764c5 198 write(&c, 1);
donatien 0:87e52bb764c5 199 }
donatien 0:87e52bb764c5 200
donatien 0:87e52bb764c5 201 bool Websocket::readChar(uint8_t* pC, bool block)
donatien 0:87e52bb764c5 202 {
donatien 0:87e52bb764c5 203 int ret = read(pC, 1, block?36000000:3000);
donatien 0:87e52bb764c5 204 if(ret < 0)
donatien 0:87e52bb764c5 205 {
donatien 0:87e52bb764c5 206 return false;
donatien 0:87e52bb764c5 207 }
donatien 0:87e52bb764c5 208 return true;
donatien 0:87e52bb764c5 209 }
donatien 0:87e52bb764c5 210
donatien 0:87e52bb764c5 211 void Websocket::sendOpcode(uint8_t opcode) {
donatien 0:87e52bb764c5 212 sendChar(0x80 | (opcode & 0x0f));
donatien 0:87e52bb764c5 213 }
donatien 0:87e52bb764c5 214
donatien 0:87e52bb764c5 215 void Websocket::sendMask() {
donatien 0:87e52bb764c5 216 for (int i = 0; i < 4; i++) {
donatien 0:87e52bb764c5 217 sendChar(0);
donatien 0:87e52bb764c5 218 }
donatien 0:87e52bb764c5 219 }
donatien 0:87e52bb764c5 220
donatien 0:87e52bb764c5 221 void Websocket::send(char * str) {
donatien 0:87e52bb764c5 222 sendOpcode(0x01);
donatien 0:87e52bb764c5 223 sendLength(strlen(str));
donatien 0:87e52bb764c5 224 sendMask();
donatien 0:87e52bb764c5 225
donatien 0:87e52bb764c5 226 write((uint8_t*)str, strlen(str));
donatien 0:87e52bb764c5 227 }
donatien 0:87e52bb764c5 228
donatien 0:87e52bb764c5 229
donatien 0:87e52bb764c5 230
donatien 0:87e52bb764c5 231 bool Websocket::read(char * message) {
donatien 0:87e52bb764c5 232 int i = 0;
donatien 0:87e52bb764c5 233 //int length_buffer = 0;
donatien 0:87e52bb764c5 234 uint32_t len_msg;
donatien 0:87e52bb764c5 235 char opcode = 0;
donatien 0:87e52bb764c5 236 uint8_t c;
donatien 0:87e52bb764c5 237 char mask[4] = {0, 0, 0, 0};
donatien 0:87e52bb764c5 238 Timer tmr;
donatien 0:87e52bb764c5 239
donatien 0:87e52bb764c5 240 //length_buffer = wifi->readable();
donatien 0:87e52bb764c5 241
donatien 0:87e52bb764c5 242 // read the opcode
donatien 0:87e52bb764c5 243 tmr.start();
donatien 0:87e52bb764c5 244 while (true) {
donatien 0:87e52bb764c5 245 if (tmr.read() > 3) {
donatien 0:87e52bb764c5 246 return false;
donatien 0:87e52bb764c5 247 }
donatien 0:87e52bb764c5 248 if(!readChar((uint8_t*)&c, false))
donatien 0:87e52bb764c5 249 {
donatien 0:87e52bb764c5 250 return false;
donatien 0:87e52bb764c5 251 }
donatien 0:87e52bb764c5 252
donatien 0:87e52bb764c5 253 opcode = c;
donatien 0:87e52bb764c5 254 if (opcode == 0x81) {
donatien 0:87e52bb764c5 255 break;
donatien 0:87e52bb764c5 256 }
donatien 0:87e52bb764c5 257 }
donatien 0:87e52bb764c5 258 #ifdef DEBUG
donatien 0:87e52bb764c5 259 printf("opcode: 0x%X\r\n", opcode);
donatien 0:87e52bb764c5 260 #endif
donatien 0:87e52bb764c5 261 readChar((uint8_t*)&c);
donatien 0:87e52bb764c5 262 len_msg = c & 0x7f;
donatien 0:87e52bb764c5 263 if (len_msg == 126) {
donatien 0:87e52bb764c5 264 readChar((uint8_t*)&c);
donatien 0:87e52bb764c5 265 len_msg = c;
donatien 0:87e52bb764c5 266 readChar((uint8_t*)&c);
donatien 0:87e52bb764c5 267 len_msg += c << 8;
donatien 0:87e52bb764c5 268 } else if (len_msg == 127) {
donatien 0:87e52bb764c5 269 len_msg = 0;
donatien 0:87e52bb764c5 270 for (i = 0; i < 8; i++) {
donatien 0:87e52bb764c5 271 readChar((uint8_t*)&c);
donatien 0:87e52bb764c5 272 len_msg += c << i*8;
donatien 0:87e52bb764c5 273 }
donatien 0:87e52bb764c5 274 }
donatien 0:87e52bb764c5 275 if(len_msg == 0) {
donatien 0:87e52bb764c5 276 return false;
donatien 0:87e52bb764c5 277 }
donatien 0:87e52bb764c5 278 #ifdef DEBUG
donatien 0:87e52bb764c5 279 printf("length: %d\r\n", len_msg);
donatien 0:87e52bb764c5 280 #endif
donatien 0:87e52bb764c5 281 if ((len_msg & 0x80)) {
donatien 0:87e52bb764c5 282 for (i = 0; i < 4; i++)
donatien 0:87e52bb764c5 283 readChar((uint8_t*)&c);
donatien 0:87e52bb764c5 284 mask[i] = c;
donatien 0:87e52bb764c5 285 }
donatien 0:87e52bb764c5 286
donatien 0:87e52bb764c5 287
donatien 0:87e52bb764c5 288
donatien 0:87e52bb764c5 289 for (i = 0; i < len_msg; i++) {
donatien 0:87e52bb764c5 290 readChar((uint8_t*)&c);
donatien 0:87e52bb764c5 291 message[i] = c ^ mask[i % 4];
donatien 0:87e52bb764c5 292 }
donatien 0:87e52bb764c5 293
donatien 0:87e52bb764c5 294 message[len_msg] = 0;
donatien 0:87e52bb764c5 295 return true;
donatien 0:87e52bb764c5 296 }
donatien 0:87e52bb764c5 297
donatien 0:87e52bb764c5 298 bool Websocket::close() {
donatien 0:87e52bb764c5 299 if((m_sockHandle < 0) || !m_connected)
donatien 0:87e52bb764c5 300 {
donatien 0:87e52bb764c5 301 return false;
donatien 0:87e52bb764c5 302 }
donatien 0:87e52bb764c5 303 m_connected = false;
donatien 0:87e52bb764c5 304 int ret = socket::close(m_sockHandle);
donatien 0:87e52bb764c5 305 if (ret < 0)
donatien 0:87e52bb764c5 306 {
donatien 0:87e52bb764c5 307 ERR("Could not disconnect");
donatien 0:87e52bb764c5 308 return false;
donatien 0:87e52bb764c5 309 }
donatien 0:87e52bb764c5 310 return true;
donatien 0:87e52bb764c5 311 }
donatien 0:87e52bb764c5 312
donatien 0:87e52bb764c5 313
donatien 0:87e52bb764c5 314
donatien 0:87e52bb764c5 315 bool Websocket::connected() {
donatien 0:87e52bb764c5 316 return m_connected;
donatien 0:87e52bb764c5 317 }
donatien 0:87e52bb764c5 318
donatien 0:87e52bb764c5 319 std::string Websocket::getPath() {
donatien 0:87e52bb764c5 320 return path;
donatien 0:87e52bb764c5 321 }
donatien 0:87e52bb764c5 322
donatien 0:87e52bb764c5 323 int Websocket::waitReadable(uint32_t timeout)
donatien 0:87e52bb764c5 324 {
donatien 0:87e52bb764c5 325 //Creating FS set
donatien 0:87e52bb764c5 326 fd_set socksSet;
donatien 0:87e52bb764c5 327 FD_ZERO(&socksSet);
donatien 0:87e52bb764c5 328 FD_SET(m_sockHandle, &socksSet);
donatien 0:87e52bb764c5 329 struct timeval t_val;
donatien 0:87e52bb764c5 330 t_val.tv_sec = timeout / 1000;
donatien 0:87e52bb764c5 331 t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
donatien 0:87e52bb764c5 332 int ret = socket::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val);
donatien 0:87e52bb764c5 333 if(ret <= 0 || !FD_ISSET(m_sockHandle, &socksSet))
donatien 0:87e52bb764c5 334 {
donatien 0:87e52bb764c5 335 return -1; //Timeout
donatien 0:87e52bb764c5 336 }
donatien 0:87e52bb764c5 337 return 0;
donatien 0:87e52bb764c5 338 }
donatien 0:87e52bb764c5 339
donatien 0:87e52bb764c5 340 int Websocket::waitWriteable(uint32_t timeout)
donatien 0:87e52bb764c5 341 {
donatien 0:87e52bb764c5 342 //Creating FS set
donatien 0:87e52bb764c5 343 fd_set socksSet;
donatien 0:87e52bb764c5 344 FD_ZERO(&socksSet);
donatien 0:87e52bb764c5 345 FD_SET(m_sockHandle, &socksSet);
donatien 0:87e52bb764c5 346 struct timeval t_val;
donatien 0:87e52bb764c5 347 t_val.tv_sec = timeout / 1000;
donatien 0:87e52bb764c5 348 t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
donatien 0:87e52bb764c5 349 int ret = socket::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val);
donatien 0:87e52bb764c5 350 if(ret <= 0 || !FD_ISSET(m_sockHandle, &socksSet))
donatien 0:87e52bb764c5 351 {
donatien 0:87e52bb764c5 352 return -1; //Timeout
donatien 0:87e52bb764c5 353 }
donatien 0:87e52bb764c5 354 return 0;
donatien 0:87e52bb764c5 355 }
donatien 0:87e52bb764c5 356
donatien 0:87e52bb764c5 357 int Websocket::read(uint8_t* buf, int minLen, int maxLen, uint32_t timeout)
donatien 0:87e52bb764c5 358 {
donatien 0:87e52bb764c5 359 if(!m_connected)
donatien 0:87e52bb764c5 360 {
donatien 0:87e52bb764c5 361 return -1;
donatien 0:87e52bb764c5 362 }
donatien 0:87e52bb764c5 363 int readLen = 0;
donatien 0:87e52bb764c5 364 do
donatien 0:87e52bb764c5 365 {
donatien 0:87e52bb764c5 366 int ret = waitReadable(timeout);
donatien 0:87e52bb764c5 367 if(ret == -1)
donatien 0:87e52bb764c5 368 {
donatien 0:87e52bb764c5 369 WARN("Wait readable returned %d",ret);
donatien 0:87e52bb764c5 370 close();
donatien 0:87e52bb764c5 371 return -1;
donatien 0:87e52bb764c5 372 }
donatien 0:87e52bb764c5 373 ret = socket::recv(m_sockHandle, buf + readLen, maxLen - readLen, 0/*MSG_DONTWAIT*/);
donatien 0:87e52bb764c5 374 if(ret > 0)
donatien 0:87e52bb764c5 375 {
donatien 0:87e52bb764c5 376 readLen += ret;
donatien 0:87e52bb764c5 377 }
donatien 0:87e52bb764c5 378 else if(ret==0) //Connection closed
donatien 0:87e52bb764c5 379 {
donatien 0:87e52bb764c5 380 WARN("Recv returned %d",ret);
donatien 0:87e52bb764c5 381 return readLen;
donatien 0:87e52bb764c5 382 }
donatien 0:87e52bb764c5 383 else
donatien 0:87e52bb764c5 384 {
donatien 0:87e52bb764c5 385 WARN("Recv returned %d",ret);
donatien 0:87e52bb764c5 386 close();
donatien 0:87e52bb764c5 387 return -1;
donatien 0:87e52bb764c5 388 }
donatien 0:87e52bb764c5 389 } while(readLen < minLen);
donatien 0:87e52bb764c5 390 return readLen;
donatien 0:87e52bb764c5 391 }
donatien 0:87e52bb764c5 392
donatien 0:87e52bb764c5 393 int Websocket::write(uint8_t* buf, int len, uint32_t timeout)
donatien 0:87e52bb764c5 394 {
donatien 0:87e52bb764c5 395 if(!m_connected)
donatien 0:87e52bb764c5 396 {
donatien 0:87e52bb764c5 397 return -1;
donatien 0:87e52bb764c5 398 }
donatien 0:87e52bb764c5 399 int writtenLen = 0;
donatien 0:87e52bb764c5 400 do
donatien 0:87e52bb764c5 401 {
donatien 0:87e52bb764c5 402 int ret = waitWriteable(timeout);
donatien 0:87e52bb764c5 403 if(ret == -1)
donatien 0:87e52bb764c5 404 {
donatien 0:87e52bb764c5 405 WARN("Wait writeable returned %d",ret);
donatien 0:87e52bb764c5 406 close();
donatien 0:87e52bb764c5 407 return -1;
donatien 0:87e52bb764c5 408 }
donatien 0:87e52bb764c5 409 ret = socket::send(m_sockHandle, buf + writtenLen, len - writtenLen, 0/*MSG_DONTWAIT*/); //FIXME Probably DO WAIT to avoid overflow
donatien 0:87e52bb764c5 410 if(ret > 0)
donatien 0:87e52bb764c5 411 {
donatien 0:87e52bb764c5 412 writtenLen += ret;
donatien 0:87e52bb764c5 413 }
donatien 0:87e52bb764c5 414 else if(ret==0) //Connection closed
donatien 0:87e52bb764c5 415 {
donatien 0:87e52bb764c5 416 WARN("Send returned %d",ret);
donatien 0:87e52bb764c5 417 return writtenLen;
donatien 0:87e52bb764c5 418 }
donatien 0:87e52bb764c5 419 else
donatien 0:87e52bb764c5 420 {
donatien 0:87e52bb764c5 421 WARN("Send returned %d",ret);
donatien 0:87e52bb764c5 422 close(); //Must reset
donatien 0:87e52bb764c5 423 return -1;
donatien 0:87e52bb764c5 424 }
donatien 0:87e52bb764c5 425 } while(writtenLen < len);
donatien 0:87e52bb764c5 426 return writtenLen;
donatien 0:87e52bb764c5 427 }
donatien 0:87e52bb764c5 428
donatien 0:87e52bb764c5 429 void Websocket::timeoutHandler()
donatien 0:87e52bb764c5 430 {
donatien 0:87e52bb764c5 431
donatien 0:87e52bb764c5 432 }