Added WebSocket protocol
Websocket.cpp@0:6d4dbf28d4ee, 2017-04-19 (annotated)
- Committer:
- mauricioaschmitz
- Date:
- Wed Apr 19 21:26:46 2017 +0000
- Revision:
- 0:6d4dbf28d4ee
Added WebSocket protocol
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mauricioaschmitz | 0:6d4dbf28d4ee | 1 | #include "Websocket.h" |
mauricioaschmitz | 0:6d4dbf28d4ee | 2 | #include "Pmed_reset.h" |
mauricioaschmitz | 0:6d4dbf28d4ee | 3 | #include "Log.h" |
mauricioaschmitz | 0:6d4dbf28d4ee | 4 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 5 | #define MAX_TRY_WRITE 20 |
mauricioaschmitz | 0:6d4dbf28d4ee | 6 | #define MAX_TRY_READ 10 |
mauricioaschmitz | 0:6d4dbf28d4ee | 7 | #define MAX_TRY_CONNECT 50 |
mauricioaschmitz | 0:6d4dbf28d4ee | 8 | #define WAIT_CONNECT_TIME 10000 |
mauricioaschmitz | 0:6d4dbf28d4ee | 9 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 10 | //Debug is disabled by default |
mauricioaschmitz | 0:6d4dbf28d4ee | 11 | #if 0 |
mauricioaschmitz | 0:6d4dbf28d4ee | 12 | #define DBG(x, ...) std::printf("[WebSocket : DBG]"x"\r\n", ##__VA_ARGS__); |
mauricioaschmitz | 0:6d4dbf28d4ee | 13 | #define WARN(x, ...) std::printf("[WebSocket : WARN]"x"\r\n", ##__VA_ARGS__); |
mauricioaschmitz | 0:6d4dbf28d4ee | 14 | #define ERR(x, ...) std::printf("[WebSocket : ERR]"x"\r\n", ##__VA_ARGS__); |
mauricioaschmitz | 0:6d4dbf28d4ee | 15 | #else |
mauricioaschmitz | 0:6d4dbf28d4ee | 16 | #define DBG(x, ...) |
mauricioaschmitz | 0:6d4dbf28d4ee | 17 | #define WARN(x, ...) |
mauricioaschmitz | 0:6d4dbf28d4ee | 18 | #define ERR(x, ...) |
mauricioaschmitz | 0:6d4dbf28d4ee | 19 | #endif |
mauricioaschmitz | 0:6d4dbf28d4ee | 20 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 21 | #define INFO(x, ...) printf("[WebSocket : INFO]"x"\r\n", ##__VA_ARGS__); |
mauricioaschmitz | 0:6d4dbf28d4ee | 22 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 23 | char * Websocket::captureMessage; |
mauricioaschmitz | 0:6d4dbf28d4ee | 24 | bool Websocket::haveMessage; |
mauricioaschmitz | 0:6d4dbf28d4ee | 25 | bool Websocket::isConect; |
mauricioaschmitz | 0:6d4dbf28d4ee | 26 | bool disconnectedWS = false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 27 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 28 | void Websocket::Websocket_Thread(void const *arg) |
mauricioaschmitz | 0:6d4dbf28d4ee | 29 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 30 | //Log::writeEntry("WebSocket Thread Start"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 31 | printf("Thread WebSocket Iniciada\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 32 | int i = 0, f = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 33 | char *comando = NULL; |
mauricioaschmitz | 0:6d4dbf28d4ee | 34 | char *tomada = NULL; |
mauricioaschmitz | 0:6d4dbf28d4ee | 35 | char *canal = NULL; |
mauricioaschmitz | 0:6d4dbf28d4ee | 36 | char *limite = NULL; |
mauricioaschmitz | 0:6d4dbf28d4ee | 37 | char server[30]; |
mauricioaschmitz | 0:6d4dbf28d4ee | 38 | char buffer[1024] = {}; |
mauricioaschmitz | 0:6d4dbf28d4ee | 39 | //bool external = false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 40 | strcpy(server, "ws://"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 41 | strcat(server, Settings::get_networkServer()); |
mauricioaschmitz | 0:6d4dbf28d4ee | 42 | strcat(server, ":8080"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 43 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 44 | //printf("Servidor WS: %s", server); |
mauricioaschmitz | 0:6d4dbf28d4ee | 45 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 46 | Websocket ws(server); |
mauricioaschmitz | 0:6d4dbf28d4ee | 47 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 48 | while(1){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 49 | if(ws.is_connected()){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 50 | if (f == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 51 | //Log::writeEntry("WebSocket Conectado."); |
mauricioaschmitz | 0:6d4dbf28d4ee | 52 | //printf("\nMensagem do MBED para servidor WebSocket em PHP\n\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 53 | //ws.send("#*MBEDStart*#Mensagem do MBED para servidor WebSocket em PHP\n"); //mensagem para registrar login do mbed no banco de dados (ainda por implementar) |
mauricioaschmitz | 0:6d4dbf28d4ee | 54 | f = 1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 55 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 56 | if(disconnectedWS != false){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 57 | disconnectedWS = false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 58 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 59 | if(haveMessage){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 60 | ws.send(captureMessage); |
mauricioaschmitz | 0:6d4dbf28d4ee | 61 | haveMessage = false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 62 | captureMessage = NULL; |
mauricioaschmitz | 0:6d4dbf28d4ee | 63 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 64 | if (ws.read(buffer)) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 65 | //ws.send("#*MBEDTest*#"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 66 | //printf("Recebido Mensagem WebSocket: %s\r\n", buffer); |
mauricioaschmitz | 0:6d4dbf28d4ee | 67 | comando = strtok(buffer, ":"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 68 | if(strcmp(comando, "test") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 69 | //printf("\r\nRecebido por WebSocket o Comando de Teste."); |
mauricioaschmitz | 0:6d4dbf28d4ee | 70 | ws.send("#*MBEDTest*#"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 71 | //Log::writeEntry("Recebido por WebSocket o Comando de Teste."); |
mauricioaschmitz | 0:6d4dbf28d4ee | 72 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 73 | if(strcmp(comando, "capture") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 74 | tomada = strtok(NULL, ":"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 75 | canal = strtok(NULL, " "); |
mauricioaschmitz | 0:6d4dbf28d4ee | 76 | /* |
mauricioaschmitz | 0:6d4dbf28d4ee | 77 | printf("Comando: %s\n", comando); |
mauricioaschmitz | 0:6d4dbf28d4ee | 78 | printf("Tomada: %s\n", tomada); |
mauricioaschmitz | 0:6d4dbf28d4ee | 79 | printf("Canal: %s\n", canal); |
mauricioaschmitz | 0:6d4dbf28d4ee | 80 | printf("Tamanho da string: %d\n", strlen(buffer)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 81 | */ |
mauricioaschmitz | 0:6d4dbf28d4ee | 82 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 83 | EventDetector::externalCapture(atoi(tomada), canal[0]); |
mauricioaschmitz | 0:6d4dbf28d4ee | 84 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 85 | if(strcmp(comando, "reset") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 86 | Pmed_reset("Reiniciando o MBED por WebSocket."); |
mauricioaschmitz | 0:6d4dbf28d4ee | 87 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 88 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 89 | if(strcmp(comando, "setLimit") == 0 || strcmp(comando, "setStandByLimit") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 90 | tomada = strtok(NULL, ":"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 91 | canal = strtok(NULL, ":"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 92 | limite = strtok(NULL, " "); |
mauricioaschmitz | 0:6d4dbf28d4ee | 93 | for(i=0; (unsigned)i < _PRTGMD_SETTINGS_MAX_NUMBER_OF_OUTLETS_; i++){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 94 | if(atoi(tomada) == Settings::get_outlet(i)){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 95 | if(strcmp(comando, "setLimit") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 96 | if(strcmp(canal, "p") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 97 | printf("Entrou canal fase e setou limite %s para tomada %s\r\n", limite, tomada); |
mauricioaschmitz | 0:6d4dbf28d4ee | 98 | Settings::set_limit(i*2,strtod(limite, NULL)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 99 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 100 | if(strcmp(canal, "d") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 101 | printf("Entrou canal fuga e setou limite %s para tomada %s\r\n", limite, tomada); |
mauricioaschmitz | 0:6d4dbf28d4ee | 102 | Settings::set_limit(i*2+1,strtod(limite, NULL)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 103 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 104 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 105 | if(strcmp(comando, "setStandByLimit") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 106 | if(strcmp(canal, "p") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 107 | printf("Entrou canal StandBy de fase e setou limite %s para tomada %s\r\n", limite, tomada); |
mauricioaschmitz | 0:6d4dbf28d4ee | 108 | Settings::set_standbyLimit(i*2,strtod(limite, NULL)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 109 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 110 | if(strcmp(canal, "d") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 111 | printf("Entrou canal StandBy de fuga e setou limite %s para tomada %s\r\n", limite, tomada); |
mauricioaschmitz | 0:6d4dbf28d4ee | 112 | Settings::set_standbyLimit(i*2+1,strtod(limite, NULL)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 113 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 114 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 115 | break; |
mauricioaschmitz | 0:6d4dbf28d4ee | 116 | }else{ |
mauricioaschmitz | 0:6d4dbf28d4ee | 117 | if(i == _PRTGMD_SETTINGS_MAX_NUMBER_OF_OUTLETS_ - 1){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 118 | printf("Tomada %d nao encontrada para atualizar limite!\r\n", atoi(tomada)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 119 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 120 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 121 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 122 | //printf("Comando: %s\n", comando); |
mauricioaschmitz | 0:6d4dbf28d4ee | 123 | //printf("Tomada: %d\n", atoi(tomada)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 124 | //printf("Canal: %s\n", canal); |
mauricioaschmitz | 0:6d4dbf28d4ee | 125 | //printf("Limite: %f\n", strtod(limite, NULL)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 126 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 127 | /* |
mauricioaschmitz | 0:6d4dbf28d4ee | 128 | if(strcmp(comando, "iniciar") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 129 | printf("\n\nChegou o Iniciar!!!\n\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 130 | external = true; |
mauricioaschmitz | 0:6d4dbf28d4ee | 131 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 132 | if(strcmp(comando, "parar") == 0){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 133 | printf("\n\nChegou o Parar!!!\n\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 134 | external = false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 135 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 136 | if(external){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 137 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 138 | }*/ |
mauricioaschmitz | 0:6d4dbf28d4ee | 139 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 140 | /* |
mauricioaschmitz | 0:6d4dbf28d4ee | 141 | if (!ws.is_connected()){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 142 | printf("Caiu a conexao!!!\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 143 | Thread::wait(Settings::get_delayTry()); |
mauricioaschmitz | 0:6d4dbf28d4ee | 144 | for(int i=0; i < MAX_TRY_CONNECT; i++){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 145 | Thread::wait(Settings::get_delayTry()); |
mauricioaschmitz | 0:6d4dbf28d4ee | 146 | //if(ws.connect()){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 147 | // break; |
mauricioaschmitz | 0:6d4dbf28d4ee | 148 | //} |
mauricioaschmitz | 0:6d4dbf28d4ee | 149 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 150 | //Websocket ws("ws://192.168.103.101:8080"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 151 | ws.connect(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 152 | }*/ |
mauricioaschmitz | 0:6d4dbf28d4ee | 153 | }else{ |
mauricioaschmitz | 0:6d4dbf28d4ee | 154 | if(!disconnectedWS){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 155 | if(ws.close()){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 156 | disconnectedWS = true; |
mauricioaschmitz | 0:6d4dbf28d4ee | 157 | Log::writeEntry("WebSocket Desconectado."); |
mauricioaschmitz | 0:6d4dbf28d4ee | 158 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 159 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 160 | Thread::wait(WAIT_CONNECT_TIME); |
mauricioaschmitz | 0:6d4dbf28d4ee | 161 | if(ws.connect()){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 162 | //Log::writeEntry("WebSocket Conectado."); |
mauricioaschmitz | 0:6d4dbf28d4ee | 163 | printf("Thread WebSocket Conectou no Servidor %s\r\n", Settings::get_networkServer()); |
mauricioaschmitz | 0:6d4dbf28d4ee | 164 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 165 | //Thread::wait(10000); |
mauricioaschmitz | 0:6d4dbf28d4ee | 166 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 167 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 168 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 169 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 170 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 171 | Websocket::Websocket(char const * url) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 172 | fillFields(url); |
mauricioaschmitz | 0:6d4dbf28d4ee | 173 | socket.set_blocking(false, 400); |
mauricioaschmitz | 0:6d4dbf28d4ee | 174 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 175 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 176 | bool Websocket::wsIsConnected(){ |
mauricioaschmitz | 0:6d4dbf28d4ee | 177 | return isConect; |
mauricioaschmitz | 0:6d4dbf28d4ee | 178 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 179 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 180 | void Websocket::fillFields(char const * url) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 181 | int ret = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 182 | if(ret) |
mauricioaschmitz | 0:6d4dbf28d4ee | 183 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 184 | ERR("URL parsing failed; please use: \"ws://ip-or-domain[:port]/path\""); |
mauricioaschmitz | 0:6d4dbf28d4ee | 185 | return; |
mauricioaschmitz | 0:6d4dbf28d4ee | 186 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 187 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 188 | if(port == 0) //TODO do handle WSS->443 |
mauricioaschmitz | 0:6d4dbf28d4ee | 189 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 190 | port = 80; |
mauricioaschmitz | 0:6d4dbf28d4ee | 191 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 192 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 193 | if(strcmp(scheme, "ws")) |
mauricioaschmitz | 0:6d4dbf28d4ee | 194 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 195 | ERR("Wrong scheme, please use \"ws\" instead"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 196 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 197 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 198 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 199 | 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 |
mauricioaschmitz | 0:6d4dbf28d4ee | 200 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 201 | char* schemePtr = (char*) url; |
mauricioaschmitz | 0:6d4dbf28d4ee | 202 | char* hostPtr = (char*) strstr(url, "://"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 203 | if(hostPtr == NULL) |
mauricioaschmitz | 0:6d4dbf28d4ee | 204 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 205 | WARN("Could not find host"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 206 | return -1; //URL is invalid |
mauricioaschmitz | 0:6d4dbf28d4ee | 207 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 208 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 209 | if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char |
mauricioaschmitz | 0:6d4dbf28d4ee | 210 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 211 | WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1); |
mauricioaschmitz | 0:6d4dbf28d4ee | 212 | return -1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 213 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 214 | memcpy(scheme, schemePtr, hostPtr - schemePtr); |
mauricioaschmitz | 0:6d4dbf28d4ee | 215 | scheme[hostPtr - schemePtr] = '\0'; |
mauricioaschmitz | 0:6d4dbf28d4ee | 216 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 217 | hostPtr+=3; |
mauricioaschmitz | 0:6d4dbf28d4ee | 218 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 219 | size_t hostLen = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 220 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 221 | char* portPtr = strchr(hostPtr, ':'); |
mauricioaschmitz | 0:6d4dbf28d4ee | 222 | if( portPtr != NULL ) |
mauricioaschmitz | 0:6d4dbf28d4ee | 223 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 224 | hostLen = portPtr - hostPtr; |
mauricioaschmitz | 0:6d4dbf28d4ee | 225 | portPtr++; |
mauricioaschmitz | 0:6d4dbf28d4ee | 226 | if( sscanf(portPtr, "%hu", port) != 1) |
mauricioaschmitz | 0:6d4dbf28d4ee | 227 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 228 | WARN("Could not find port"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 229 | return -1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 230 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 231 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 232 | else |
mauricioaschmitz | 0:6d4dbf28d4ee | 233 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 234 | *port=0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 235 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 236 | char* pathPtr = strchr(hostPtr, '/'); |
mauricioaschmitz | 0:6d4dbf28d4ee | 237 | if( hostLen == 0 ) |
mauricioaschmitz | 0:6d4dbf28d4ee | 238 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 239 | hostLen = pathPtr - hostPtr; |
mauricioaschmitz | 0:6d4dbf28d4ee | 240 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 241 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 242 | if( maxHostLen < hostLen + 1 ) //including NULL-terminating char |
mauricioaschmitz | 0:6d4dbf28d4ee | 243 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 244 | WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1); |
mauricioaschmitz | 0:6d4dbf28d4ee | 245 | return -1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 246 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 247 | memcpy(host, hostPtr, hostLen); |
mauricioaschmitz | 0:6d4dbf28d4ee | 248 | host[hostLen] = '\0'; |
mauricioaschmitz | 0:6d4dbf28d4ee | 249 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 250 | size_t pathLen; |
mauricioaschmitz | 0:6d4dbf28d4ee | 251 | char* fragmentPtr = strchr(hostPtr, '#'); |
mauricioaschmitz | 0:6d4dbf28d4ee | 252 | if(fragmentPtr != NULL) |
mauricioaschmitz | 0:6d4dbf28d4ee | 253 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 254 | pathLen = fragmentPtr - pathPtr; |
mauricioaschmitz | 0:6d4dbf28d4ee | 255 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 256 | else |
mauricioaschmitz | 0:6d4dbf28d4ee | 257 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 258 | pathLen = strlen(pathPtr); |
mauricioaschmitz | 0:6d4dbf28d4ee | 259 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 260 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 261 | if( maxPathLen < pathLen + 1 ) //including NULL-terminating char |
mauricioaschmitz | 0:6d4dbf28d4ee | 262 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 263 | WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1); |
mauricioaschmitz | 0:6d4dbf28d4ee | 264 | return -1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 265 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 266 | memcpy(path, pathPtr, pathLen); |
mauricioaschmitz | 0:6d4dbf28d4ee | 267 | path[pathLen] = '\0'; |
mauricioaschmitz | 0:6d4dbf28d4ee | 268 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 269 | return 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 270 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 271 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 272 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 273 | bool Websocket::connect() { |
mauricioaschmitz | 0:6d4dbf28d4ee | 274 | char cmd[200]; |
mauricioaschmitz | 0:6d4dbf28d4ee | 275 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 276 | while (socket.connect(host, port) < 0) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 277 | ERR("Unable to connect to (%s) on port (%d)", host, port); |
mauricioaschmitz | 0:6d4dbf28d4ee | 278 | Thread::wait(200); |
mauricioaschmitz | 0:6d4dbf28d4ee | 279 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 280 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 281 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 282 | // sent http header to upgrade to the ws protocol |
mauricioaschmitz | 0:6d4dbf28d4ee | 283 | sprintf(cmd, "GET %s HTTP/1.1\r\n", path); |
mauricioaschmitz | 0:6d4dbf28d4ee | 284 | write(cmd, strlen(cmd)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 285 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 286 | sprintf(cmd, "Host: %s:%d\r\n", host, port); |
mauricioaschmitz | 0:6d4dbf28d4ee | 287 | write(cmd, strlen(cmd)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 288 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 289 | sprintf(cmd, "Upgrade: WebSocket\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 290 | write(cmd, strlen(cmd)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 291 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 292 | sprintf(cmd, "Connection: Upgrade\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 293 | write(cmd, strlen(cmd)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 294 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 295 | sprintf(cmd, "Sec-WebSocket-Key: L159VM0TWUzyDxwJEIEzjw==\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 296 | write(cmd, strlen(cmd)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 297 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 298 | sprintf(cmd, "Sec-WebSocket-Version: 13\r\n\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 299 | int ret = write(cmd, strlen(cmd)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 300 | if ((unsigned)ret != strlen(cmd)) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 301 | close(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 302 | ERR("Could not send request"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 303 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 304 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 305 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 306 | ret = read(cmd, 200, 100); |
mauricioaschmitz | 0:6d4dbf28d4ee | 307 | if (ret < 0) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 308 | close(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 309 | ERR("Could not receive answer\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 310 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 311 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 312 | cmd[ret] = '\0'; |
mauricioaschmitz | 0:6d4dbf28d4ee | 313 | DBG("recv: %s\r\n", cmd); |
mauricioaschmitz | 0:6d4dbf28d4ee | 314 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 315 | if ( strstr(cmd, "DdLWT/1JcX+nQFHebYP+rqEx5xI=") == NULL ) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 316 | ERR("Wrong answer from server, got \"%s\" instead\r\n", cmd); |
mauricioaschmitz | 0:6d4dbf28d4ee | 317 | do { |
mauricioaschmitz | 0:6d4dbf28d4ee | 318 | ret = read(cmd, 200, 100); |
mauricioaschmitz | 0:6d4dbf28d4ee | 319 | if (ret < 0) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 320 | ERR("Could not receive answer\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 321 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 322 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 323 | cmd[ret] = '\0'; |
mauricioaschmitz | 0:6d4dbf28d4ee | 324 | printf("%s",cmd); |
mauricioaschmitz | 0:6d4dbf28d4ee | 325 | } while (ret > 0); |
mauricioaschmitz | 0:6d4dbf28d4ee | 326 | close(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 327 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 328 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 329 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 330 | //INFO("\r\nhost: %s\r\npath: %s\r\nport: %d\r\n\r\n", host, path, port); |
mauricioaschmitz | 0:6d4dbf28d4ee | 331 | return true; |
mauricioaschmitz | 0:6d4dbf28d4ee | 332 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 333 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 334 | int Websocket::sendLength(uint32_t len, char * msg) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 335 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 336 | if (len < 126) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 337 | msg[0] = len | (1<<7); |
mauricioaschmitz | 0:6d4dbf28d4ee | 338 | return 1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 339 | } else if (len < 65535) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 340 | msg[0] = 126 | (1<<7); |
mauricioaschmitz | 0:6d4dbf28d4ee | 341 | msg[1] = (len >> 8) & 0xff; |
mauricioaschmitz | 0:6d4dbf28d4ee | 342 | msg[2] = len & 0xff; |
mauricioaschmitz | 0:6d4dbf28d4ee | 343 | return 3; |
mauricioaschmitz | 0:6d4dbf28d4ee | 344 | } else { |
mauricioaschmitz | 0:6d4dbf28d4ee | 345 | msg[0] = 127 | (1<<7); |
mauricioaschmitz | 0:6d4dbf28d4ee | 346 | for (int i = 0; i < 8; i++) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 347 | msg[i+1] = (len >> i*8) & 0xff; |
mauricioaschmitz | 0:6d4dbf28d4ee | 348 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 349 | return 9; |
mauricioaschmitz | 0:6d4dbf28d4ee | 350 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 351 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 352 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 353 | int Websocket::readChar(char * pC, bool block) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 354 | return read(pC, 1, 1); |
mauricioaschmitz | 0:6d4dbf28d4ee | 355 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 356 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 357 | int Websocket::sendOpcode(uint8_t opcode, char * msg) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 358 | msg[0] = 0x80 | (opcode & 0x0f); |
mauricioaschmitz | 0:6d4dbf28d4ee | 359 | return 1; |
mauricioaschmitz | 0:6d4dbf28d4ee | 360 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 361 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 362 | int Websocket::sendMask(char * msg) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 363 | for (int i = 0; i < 4; i++) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 364 | msg[i] = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 365 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 366 | return 4; |
mauricioaschmitz | 0:6d4dbf28d4ee | 367 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 368 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 369 | int Websocket::send(char * str) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 370 | char msg[strlen(str) + 15]; |
mauricioaschmitz | 0:6d4dbf28d4ee | 371 | int idx = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 372 | idx = sendOpcode(0x01, msg); |
mauricioaschmitz | 0:6d4dbf28d4ee | 373 | idx += sendLength(strlen(str), msg + idx); |
mauricioaschmitz | 0:6d4dbf28d4ee | 374 | idx += sendMask(msg + idx); |
mauricioaschmitz | 0:6d4dbf28d4ee | 375 | memcpy(msg+idx, str, strlen(str)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 376 | int res = write(msg, idx + strlen(str)); |
mauricioaschmitz | 0:6d4dbf28d4ee | 377 | return res; |
mauricioaschmitz | 0:6d4dbf28d4ee | 378 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 379 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 380 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 381 | bool Websocket::read(char * message) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 382 | int i = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 383 | uint32_t len_msg; |
mauricioaschmitz | 0:6d4dbf28d4ee | 384 | char opcode = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 385 | char c; |
mauricioaschmitz | 0:6d4dbf28d4ee | 386 | char mask[4] = {0, 0, 0, 0}; |
mauricioaschmitz | 0:6d4dbf28d4ee | 387 | bool is_masked = false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 388 | Timer tmr; |
mauricioaschmitz | 0:6d4dbf28d4ee | 389 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 390 | // read the opcode |
mauricioaschmitz | 0:6d4dbf28d4ee | 391 | tmr.start(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 392 | while (true) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 393 | if (tmr.read() > 3) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 394 | DBG("timeout ws\r\n"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 395 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 396 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 397 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 398 | if(!socket.is_connected()) |
mauricioaschmitz | 0:6d4dbf28d4ee | 399 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 400 | WARN("Connection was closed by server"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 401 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 402 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 403 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 404 | socket.set_blocking(false, 1); |
mauricioaschmitz | 0:6d4dbf28d4ee | 405 | if (socket.receive(&opcode, 1) != 1) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 406 | socket.set_blocking(false, 2000); |
mauricioaschmitz | 0:6d4dbf28d4ee | 407 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 408 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 409 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 410 | socket.set_blocking(false, 2000); |
mauricioaschmitz | 0:6d4dbf28d4ee | 411 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 412 | if (opcode == 0x81) |
mauricioaschmitz | 0:6d4dbf28d4ee | 413 | break; |
mauricioaschmitz | 0:6d4dbf28d4ee | 414 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 415 | DBG("opcode: 0x%X\r\n", opcode); |
mauricioaschmitz | 0:6d4dbf28d4ee | 416 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 417 | readChar(&c); |
mauricioaschmitz | 0:6d4dbf28d4ee | 418 | len_msg = c & 0x7f; |
mauricioaschmitz | 0:6d4dbf28d4ee | 419 | is_masked = c & 0x80; |
mauricioaschmitz | 0:6d4dbf28d4ee | 420 | if (len_msg == 126) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 421 | readChar(&c); |
mauricioaschmitz | 0:6d4dbf28d4ee | 422 | len_msg = c << 8; |
mauricioaschmitz | 0:6d4dbf28d4ee | 423 | readChar(&c); |
mauricioaschmitz | 0:6d4dbf28d4ee | 424 | len_msg += c; |
mauricioaschmitz | 0:6d4dbf28d4ee | 425 | } else if (len_msg == 127) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 426 | len_msg = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 427 | for (int i = 0; i < 8; i++) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 428 | readChar(&c); |
mauricioaschmitz | 0:6d4dbf28d4ee | 429 | len_msg += (c << (7-i)*8); |
mauricioaschmitz | 0:6d4dbf28d4ee | 430 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 431 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 432 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 433 | if (len_msg == 0) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 434 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 435 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 436 | DBG("length: %d\r\n", len_msg); |
mauricioaschmitz | 0:6d4dbf28d4ee | 437 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 438 | if (is_masked) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 439 | for (i = 0; i < 4; i++) |
mauricioaschmitz | 0:6d4dbf28d4ee | 440 | readChar(&c); |
mauricioaschmitz | 0:6d4dbf28d4ee | 441 | mask[i] = c; |
mauricioaschmitz | 0:6d4dbf28d4ee | 442 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 443 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 444 | int nb = read(message, len_msg, len_msg); |
mauricioaschmitz | 0:6d4dbf28d4ee | 445 | if (nb != len_msg) |
mauricioaschmitz | 0:6d4dbf28d4ee | 446 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 447 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 448 | for (i = 0; (unsigned)i < len_msg; i++) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 449 | message[i] = message[i] ^ mask[i % 4]; |
mauricioaschmitz | 0:6d4dbf28d4ee | 450 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 451 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 452 | message[len_msg] = '\0'; |
mauricioaschmitz | 0:6d4dbf28d4ee | 453 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 454 | return true; |
mauricioaschmitz | 0:6d4dbf28d4ee | 455 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 456 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 457 | bool Websocket::close() { |
mauricioaschmitz | 0:6d4dbf28d4ee | 458 | //if (!is_connected()) |
mauricioaschmitz | 0:6d4dbf28d4ee | 459 | //return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 460 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 461 | int ret = socket.close(true); |
mauricioaschmitz | 0:6d4dbf28d4ee | 462 | if (ret < 0) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 463 | ERR("Could not disconnect"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 464 | return false; |
mauricioaschmitz | 0:6d4dbf28d4ee | 465 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 466 | return true; |
mauricioaschmitz | 0:6d4dbf28d4ee | 467 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 468 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 469 | bool Websocket::is_connected() { |
mauricioaschmitz | 0:6d4dbf28d4ee | 470 | isConect = socket.is_connected(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 471 | return socket.is_connected(); |
mauricioaschmitz | 0:6d4dbf28d4ee | 472 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 473 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 474 | char* Websocket::getPath() { |
mauricioaschmitz | 0:6d4dbf28d4ee | 475 | return path; |
mauricioaschmitz | 0:6d4dbf28d4ee | 476 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 477 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 478 | int Websocket::write(char * str, int len) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 479 | int res = 0, idx = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 480 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 481 | for (int j = 0; j < MAX_TRY_WRITE; j++) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 482 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 483 | if(!socket.is_connected()) |
mauricioaschmitz | 0:6d4dbf28d4ee | 484 | { |
mauricioaschmitz | 0:6d4dbf28d4ee | 485 | WARN("Connection was closed by server"); |
mauricioaschmitz | 0:6d4dbf28d4ee | 486 | break; |
mauricioaschmitz | 0:6d4dbf28d4ee | 487 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 488 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 489 | if ((res = socket.send_all(str + idx, len - idx)) == -1) |
mauricioaschmitz | 0:6d4dbf28d4ee | 490 | continue; |
mauricioaschmitz | 0:6d4dbf28d4ee | 491 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 492 | idx += res; |
mauricioaschmitz | 0:6d4dbf28d4ee | 493 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 494 | if (idx == len) |
mauricioaschmitz | 0:6d4dbf28d4ee | 495 | return len; |
mauricioaschmitz | 0:6d4dbf28d4ee | 496 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 497 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 498 | return (idx == 0) ? -1 : idx; |
mauricioaschmitz | 0:6d4dbf28d4ee | 499 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 500 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 501 | int Websocket::read(char * str, int len, int min_len) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 502 | int res = 0, idx = 0; |
mauricioaschmitz | 0:6d4dbf28d4ee | 503 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 504 | for (int j = 0; j < MAX_TRY_WRITE; j++) { |
mauricioaschmitz | 0:6d4dbf28d4ee | 505 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 506 | if ((res = socket.receive_all(str + idx, len - idx)) == -1) |
mauricioaschmitz | 0:6d4dbf28d4ee | 507 | continue; |
mauricioaschmitz | 0:6d4dbf28d4ee | 508 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 509 | idx += res; |
mauricioaschmitz | 0:6d4dbf28d4ee | 510 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 511 | if (idx == len || (min_len != -1 && idx > min_len)) |
mauricioaschmitz | 0:6d4dbf28d4ee | 512 | return idx; |
mauricioaschmitz | 0:6d4dbf28d4ee | 513 | } |
mauricioaschmitz | 0:6d4dbf28d4ee | 514 | |
mauricioaschmitz | 0:6d4dbf28d4ee | 515 | return (idx == 0) ? -1 : idx; |
mauricioaschmitz | 0:6d4dbf28d4ee | 516 | } |