Client of WebSocket protocol
Fork of WebSocketClient by
Revision 8:c9da00db9d33, committed 2017-02-24
- Comitter:
- mauricioaschmitz
- Date:
- Fri Feb 24 20:06:49 2017 +0000
- Parent:
- 7:4567996414a5
- Commit message:
- Added project prtgmdWebSocketClient
Changed in this revision
diff -r 4567996414a5 -r c9da00db9d33 Websocket.cpp --- a/Websocket.cpp Fri Feb 08 12:33:04 2013 +0000 +++ b/Websocket.cpp Fri Feb 24 20:06:49 2017 +0000 @@ -1,7 +1,11 @@ #include "Websocket.h" +#include "Pmed_reset.h" +#include "Log.h" #define MAX_TRY_WRITE 20 #define MAX_TRY_READ 10 +#define MAX_TRY_CONNECT 50 +#define WAIT_CONNECT_TIME 10000 //Debug is disabled by default #if 0 @@ -14,14 +18,166 @@ #define ERR(x, ...) #endif -#define INFO(x, ...) printf("[WebSocket : INFO]"x"\r\n", ##__VA_ARGS__); +#define INFO(x, ...) printf("[WebSocket : INFO]"x"\r\n", ##__VA_ARGS__); + +char * Websocket::captureMessage; +bool Websocket::haveMessage; +bool Websocket::isConect; +bool disconnectedWS = false; -Websocket::Websocket(char * url) { +void Websocket::Websocket_Thread(void const *arg) +{ + //Log::writeEntry("WebSocket Thread Start"); + printf("Thread WebSocket Iniciada\r\n"); + int i = 0, f = 0; + char *comando = NULL; + char *tomada = NULL; + char *canal = NULL; + char *limite = NULL; + char server[30]; + char buffer[1024] = {}; + //bool external = false; + strcpy(server, "ws://"); + strcat(server, Settings::get_networkServer()); + strcat(server, ":8080"); + + //printf("Servidor WS: %s", server); + + Websocket ws(server); + + while(1){ + if(ws.is_connected()){ + if (f == 0){ + //Log::writeEntry("WebSocket Conectado."); + //printf("\nMensagem do MBED para servidor WebSocket em PHP\n\n"); + //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) + f = 1; + } + if(disconnectedWS != false){ + disconnectedWS = false; + } + if(haveMessage){ + ws.send(captureMessage); + haveMessage = false; + captureMessage = NULL; + } + if (ws.read(buffer)) { + //ws.send("#*MBEDTest*#"); + //printf("Recebido Mensagem WebSocket: %s\r\n", buffer); + comando = strtok(buffer, ":"); + if(strcmp(comando, "test") == 0){ + //printf("\r\nRecebido por WebSocket o Comando de Teste."); + ws.send("#*MBEDTest*#"); + //Log::writeEntry("Recebido por WebSocket o Comando de Teste."); + } + if(strcmp(comando, "capture") == 0){ + tomada = strtok(NULL, ":"); + canal = strtok(NULL, " "); + /* + printf("Comando: %s\n", comando); + printf("Tomada: %s\n", tomada); + printf("Canal: %s\n", canal); + printf("Tamanho da string: %d\n", strlen(buffer)); + */ + + EventDetector::externalCapture(atoi(tomada), canal[0]); + } + if(strcmp(comando, "reset") == 0){ + Pmed_reset("Reiniciando o MBED por WebSocket."); + } + + if(strcmp(comando, "setLimit") == 0 || strcmp(comando, "setStandByLimit") == 0){ + tomada = strtok(NULL, ":"); + canal = strtok(NULL, ":"); + limite = strtok(NULL, " "); + for(i=0; (unsigned)i < _PRTGMD_SETTINGS_MAX_NUMBER_OF_OUTLETS_; i++){ + if(atoi(tomada) == Settings::get_outlet(i)){ + if(strcmp(comando, "setLimit") == 0){ + if(strcmp(canal, "p") == 0){ + printf("Entrou canal fase e setou limite %s para tomada %s\r\n", limite, tomada); + Settings::set_limit(i*2,strtod(limite, NULL)); + } + if(strcmp(canal, "d") == 0){ + printf("Entrou canal fuga e setou limite %s para tomada %s\r\n", limite, tomada); + Settings::set_limit(i*2+1,strtod(limite, NULL)); + } + } + if(strcmp(comando, "setStandByLimit") == 0){ + if(strcmp(canal, "p") == 0){ + printf("Entrou canal StandBy de fase e setou limite %s para tomada %s\r\n", limite, tomada); + Settings::set_standbyLimit(i*2,strtod(limite, NULL)); + } + if(strcmp(canal, "d") == 0){ + printf("Entrou canal StandBy de fuga e setou limite %s para tomada %s\r\n", limite, tomada); + Settings::set_standbyLimit(i*2+1,strtod(limite, NULL)); + } + } + break; + }else{ + if(i == _PRTGMD_SETTINGS_MAX_NUMBER_OF_OUTLETS_ - 1){ + printf("Tomada %d nao encontrada para atualizar limite!\r\n", atoi(tomada)); + } + } + } + //printf("Comando: %s\n", comando); + //printf("Tomada: %d\n", atoi(tomada)); + //printf("Canal: %s\n", canal); + //printf("Limite: %f\n", strtod(limite, NULL)); + } + /* + if(strcmp(comando, "iniciar") == 0){ + printf("\n\nChegou o Iniciar!!!\n\n"); + external = true; + } + if(strcmp(comando, "parar") == 0){ + printf("\n\nChegou o Parar!!!\n\n"); + external = false; + } + if(external){ + + }*/ + } + /* + if (!ws.is_connected()){ + printf("Caiu a conexao!!!\n"); + Thread::wait(Settings::get_delayTry()); + for(int i=0; i < MAX_TRY_CONNECT; i++){ + Thread::wait(Settings::get_delayTry()); + //if(ws.connect()){ + // break; + //} + } + //Websocket ws("ws://192.168.103.101:8080"); + ws.connect(); + }*/ + }else{ + if(!disconnectedWS){ + if(ws.close()){ + disconnectedWS = true; + Log::writeEntry("WebSocket Desconectado."); + } + } + Thread::wait(WAIT_CONNECT_TIME); + if(ws.connect()){ + //Log::writeEntry("WebSocket Conectado."); + printf("Thread WebSocket Conectou no Servidor %s\r\n", Settings::get_networkServer()); + } + //Thread::wait(10000); + } + } + +} + +Websocket::Websocket(char const * url) { fillFields(url); socket.set_blocking(false, 400); } -void Websocket::fillFields(char * url) { +bool Websocket::wsIsConnected(){ + return isConect; +} + +void Websocket::fillFields(char const * url) { int ret = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path)); if(ret) { @@ -119,7 +275,7 @@ while (socket.connect(host, port) < 0) { ERR("Unable to connect to (%s) on port (%d)", host, port); - wait(0.2); + Thread::wait(200); return false; } @@ -141,19 +297,18 @@ sprintf(cmd, "Sec-WebSocket-Version: 13\r\n\r\n"); int ret = write(cmd, strlen(cmd)); - if (ret != strlen(cmd)) { + if ((unsigned)ret != strlen(cmd)) { close(); ERR("Could not send request"); return false; } - + ret = read(cmd, 200, 100); if (ret < 0) { close(); ERR("Could not receive answer\r\n"); return false; } - cmd[ret] = '\0'; DBG("recv: %s\r\n", cmd); @@ -171,8 +326,8 @@ close(); return false; } - - INFO("\r\nhost: %s\r\npath: %s\r\nport: %d\r\n\r\n", host, path, port); + + //INFO("\r\nhost: %s\r\npath: %s\r\nport: %d\r\n\r\n", host, path, port); return true; } @@ -290,7 +445,7 @@ if (nb != len_msg) return false; - for (i = 0; i < len_msg; i++) { + for (i = 0; (unsigned)i < len_msg; i++) { message[i] = message[i] ^ mask[i % 4]; } @@ -300,10 +455,10 @@ } bool Websocket::close() { - if (!is_connected()) - return false; + //if (!is_connected()) + //return false; - int ret = socket.close(); + int ret = socket.close(true); if (ret < 0) { ERR("Could not disconnect"); return false; @@ -312,6 +467,7 @@ } bool Websocket::is_connected() { + isConect = socket.is_connected(); return socket.is_connected(); }
diff -r 4567996414a5 -r c9da00db9d33 Websocket.h --- a/Websocket.h Fri Feb 08 12:33:04 2013 +0000 +++ b/Websocket.h Fri Feb 24 20:06:49 2017 +0000 @@ -32,8 +32,12 @@ #define WEBSOCKET_H #include "mbed.h" +#include "rtos.h" #include "TCPSocketConnection.h" +#include "EventDetector.h" + +extern void Websocket_Thread(void const *arg); /** Websocket client Class. * @@ -68,12 +72,34 @@ class Websocket { public: + + /* + * Prepare message get from mailbox + * + * + */ + static void ReceiveMessage(char * dados){ haveMessage = true; captureMessage = dados; } + + /* + * Get status of connection + * + * + */ + static bool wsIsConnected(); + + + /** + * Thread to start Websocket + * + */ + static void Websocket_Thread(void const *arg); + /** * Constructor * * @param url The Websocket url in the form "ws://ip_domain[:port]/path" (by default: port = 80) */ - Websocket(char * url); + Websocket(char const * url); /** * Connect to the websocket url @@ -123,7 +149,7 @@ private: - void fillFields(char * url); + void fillFields(char const * url); int parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL int sendOpcode(uint8_t opcode, char * msg); int sendLength(uint32_t len, char * msg); @@ -139,6 +165,11 @@ int read(char * buf, int len, int min_len = -1); int write(char * buf, int len); + + static char * captureMessage; + static bool haveMessage; + static bool isConect; + }; #endif
diff -r 4567996414a5 -r c9da00db9d33 WebsocketCaptureMonitor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebsocketCaptureMonitor.cpp Fri Feb 24 20:06:49 2017 +0000 @@ -0,0 +1,246 @@ +#include "WebsocketCaptureMonitor.h" +#include "Pmed_reset.h" +#include "Log.h" +//#include "Settings.h" + +void WebsocketCaptureMonitor::WebsocketCaptureMonitor_Thread(void const *arg) +{ + //Log::writeEntry("WebSocket Capture Thread Start"); + char mensagem[600]; + CaptureMailbox& mbox = EventDetector::GetMailbox(); + osEvent evt; + while(true){ + evt = mbox.get(); + if(evt.status == osEventMail) + { + //printf("Entrou monitor de captura!!!!\n\n"); + CaptureEvent* cap = (CaptureEvent*)evt.value.p; + + //printf("Request=[%s]\n",mensagem); + //Websocket::ReceiveMessage(mensagem); + //memset(mensagem, 0, 600); + //printf("Saiu do monitor de captura!!!!\n\n"); + + //testar porque não funciona, ideia era se o websocket não estiver conectado, abrir um socket e enviar por post direto + PrepareMessage(cap, mensagem, true); + Websocket::ReceiveMessage(mensagem); + + //if(Websocket::wsIsConnected()){ + //PrepareMessage(cap, mensagem, true); + //Websocket::ReceiveMessage(mensagem); + /* + printf("WebSocket conectado para o envio de dados!!!\n"); + strcpy(tmp, mensagem); + strcpy(mensagem, "#*InsertCaptureDB*#"); + strcat(mensagem, tmp); + + //memset(tmp,0,600); + //alguma forma de tentar conectar o websocket + */ + //} + //else + //{ + //TCPSocketConnection sock; + //DoPost(sock,Settings::get_networkServer(),cap); + //} + mbox.free(cap); + } + } +} + +void WebsocketCaptureMonitor::PrepareMessage(CaptureEvent* dados, char *strfinal, bool isWS){ + char str[400]; + char aux[_PRTGMD_SETTINGS_DEFAULT_MAX_HARMONICS_]; + int i; + + const char *header1 = "POST /Ptgm-Scripts/capture.php HTTP/1.1\r\n"; + //"Host: 192.168.1.26\r\n" + //"Content-Length: " + + const char *header2 = "\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "\r\n"; + + //str = (char *) malloc(450); + //strfinal = (char *) malloc(450); + memset(str,0,400); + memset(strfinal,0,500); + + if(isWS){ + strcat(strfinal, "#*InsertCaptureDB*#"); + } + + strcat(strfinal, header1); + strcat(strfinal, "Host: "); + strcat(strfinal, Settings::get_networkServer() ); + strcat(strfinal, "\r\n"); + + sprintf(aux,"TYPE=0%d",dados->get_Type()); + strcat(str, aux); + + sprintf(aux,"&OUTLET=%02d",dados->get_OutletNumber()); + strcat(str, aux); + + sprintf(aux,"&RFID=%s", dados->get_RFID()); + strcat(str,aux); + + sprintf(aux,"&OFFSET=%04d",dados->get_Offset()); + strcat(str,aux); + + float f = dados->get_Gain(); + sprintf(aux,"&GAIN=%08X", *(unsigned int*)&f); + strcat(str,aux); + + f = dados->get_RMSValue(); + sprintf(aux,"&RMS=%08X",*(unsigned int*)&f); + strcat(str,aux); + + f = dados->get_MeanValue(); + sprintf(aux,"&MV=%08X",*(unsigned int*)&f); + strcat(str,aux); + + /* Adicionados para alteracao */ + //printf("MV %f MV2 %f\n", dados->get_MeanValue(), dados->get_MV2()); + f = dados->get_MV2(); + sprintf(aux,"&MV2=%08X",*(unsigned int*)&f); + strcat(str,aux); + + sprintf(aux,"&UNDER=%04d",dados->get_Under()); + strcat(str,aux); + + sprintf(aux,"&OVER=%04d",dados->get_Over()); + strcat(str,aux); + + sprintf(aux,"&DURATION=%04d",dados->get_Duration()); + strcat(str,aux); + /* Ate Aqui */ + + strcat(str,"&SIN="); + for(i=0;i<Settings::get_maxHarmonics();i++) + { + char s[10]; + //According to RFC1738,RFC3986 the semicolon is a reserved character and must be encoded + f = dados->get_SineValue(i); + sprintf(s,"%08X",*(unsigned int*)&f); + strcat(str,s); + if (i < (Settings::get_maxHarmonics() - 1)) + strcat(str, "%3B"); + } + + strcat(str,"&COS="); + for(i=0;i<Settings::get_maxHarmonics();i++) + { + char c[10]; + //According to RFC1738,RFC3986 the semicolon is a reserved character and must be encoded + f = dados->get_CossineValue(i); + sprintf(c,"%08X",*(unsigned int*)&f); + strcat(str,c); + if (i < (Settings::get_maxHarmonics()-1)) + strcat(str, "%3B"); + } + strcat(str,"\r\n"); + + char len[5]; + sprintf(len,"%d",strlen(str)); + + strcat(strfinal, "Content-Length: "); + strcat(strfinal, len); + strcat(strfinal, header2); + strcat(strfinal, str); + strcat(strfinal, "\r\n"); + + //printf("Request=[%s]\n",strfinal); + //printf("Tamanho STR %d\n", strlen(str)); + //printf("Tamanho STRFINAL %d\n", strlen(strfinal)); + } + + void WebsocketCaptureMonitor::DoPost(TCPSocketConnection sock, char *host, CaptureEvent* dados){ + char http_cmd[400]; + int escritos, r=-1, i; + //FILE *f; + + //Timer t; + //t.start(); + + //printf("HTTP Socket %s:%d\n", host, sock.get_port()); + //printf("Antes Connect\n"); + //rs= sock.connect(host, 80); + //printf("%d\n", rs); + //printf("Depois Connect "); + + //t.stop(); + //printf("HHTP: The time taken in connection was %d useconds\n", t.read_us()); + + //http_cmd = (char *) malloc(500); + memset(http_cmd, 0, 600); + PrepareMessage( dados,http_cmd, false ); + //printf("Fuga\n"); + //printf("Tamanho do comando %d\n", strlen(http_cmd)); + //printf("Comando: /* %s */\n", http_cmd); + + //http_cmd = prepare_POST( dados ); + + //printf("Tamanho comando %d\n", strlen(http_cmd)); + //printf("Request \n [%s]\n", http_cmd); + + + for(i=0; i < _PRTGMD_SETTINGS_DEFAULT_TRIES_ ; i++){ + r = sock.connect(host, 80); + if (r < 0) { + printf("Error: Unable to connect to (%s) on port (%d) Try %d\n", host, 80, i); + Thread::wait(Settings::get_delayTry()); + } + else + break; + } + if (r == 0){ + for(i=0; i < _PRTGMD_SETTINGS_DEFAULT_TRIES_ ; i++){ + escritos = sock.send_all(http_cmd, strlen(http_cmd)); + if(escritos != strlen(http_cmd)){ + printf("Erro ao gravar no socket HTTP!! Escritos %d\t Tam %d Try %d\n", escritos, strlen(http_cmd), i); + Thread::wait(Settings::get_delayTry()); + } + else + break; + } + if ( i != _PRTGMD_SETTINGS_DEFAULT_TRIES_ ) + Thread::wait(Settings::get_delaySend()); + else{ + //printf("Reset\n"); + /*f = fopen(FILENAMERESET, "a"); + if (f == NULL) + f = fopen(FILENAMERESET, "w"); + fprintf(f, "Reset - Connect\n"); + fclose(f);*/ + + Pmed_reset(PMEDLOG_HTTP_CONNECT); + } + + //Codigo para buscar o retorno do servidor HTTP + /* + printf("Vai pegar retorno\n"); + + char buffer[300]; + int ret; + while (true) { + ret = sock.receive(buffer, sizeof(buffer)-1); + if (ret <= 0) + break; + buffer[ret] = '\0'; + printf("Received %d chars from server:\n%s\n", ret, buffer); + } + */ + } + else{ + printf("Reset\n"); + /*f = fopen(FILENAMERESET, "a"); + if (f == NULL) + f = fopen(FILENAMERESET, "w"); + fprintf(f, "Reset - Send\n"); + fclose(f);*/ + + Pmed_reset(PMEDLOG_HTTP_SEND); + } + + sock.close(); +} \ No newline at end of file
diff -r 4567996414a5 -r c9da00db9d33 WebsocketCaptureMonitor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebsocketCaptureMonitor.h Fri Feb 24 20:06:49 2017 +0000 @@ -0,0 +1,34 @@ +#include "mbed.h" +#include "rtos.h" +#include "EventDetector.h" +#include "Websocket.h" +#include "EthernetInterface.h" +#include "Settings.h" + +extern void WebsocketCaptureMonitor_Thread(void const *arg); + +class WebsocketCaptureMonitor +{ + public: + /** + * Thread to start Websocket Capture Monitor + * + */ + static void WebsocketCaptureMonitor_Thread(void const *arg); + + /* + * Prepare message get from mailbox + * + * + */ + static void PrepareMessage(CaptureEvent* dados,char *strfinal, bool isWS); + + /* + * Send data + * + * + */ + + static void DoPost(TCPSocketConnection sock, char *host, CaptureEvent* dados); + +};