From b350641bb9288294a0371765690510d5cb7eda36 Mon Sep 17 00:00:00 2001 From: dannybackx Date: Thu, 13 Apr 2017 06:05:47 +0200 Subject: [PATCH] work in progress --- cmd/cmd.h | 1 + cmd/handlers.c | 2 + esp-link/upnp.c | 149 +++++++++++++++++++++++++++++++++++++++--------- serial/slip.c | 2 +- serial/uart.c | 3 +- socket/socket.c | 84 ++++++++++++++++++++++----- 6 files changed, 200 insertions(+), 41 deletions(-) diff --git a/cmd/cmd.h b/cmd/cmd.h index 05f9b7b..9eae74a 100644 --- a/cmd/cmd.h +++ b/cmd/cmd.h @@ -71,6 +71,7 @@ typedef enum { CMD_UPNP_SCAN = 60, CMD_UPNP_ADD_PORT, CMD_UPNP_REMOVE_PORT, + CMD_UPNP_BEGIN, } CmdName; diff --git a/cmd/handlers.c b/cmd/handlers.c index ab795ae..ca350b2 100644 --- a/cmd/handlers.c +++ b/cmd/handlers.c @@ -43,6 +43,7 @@ void cmdMqttGetClientId(CmdPacket *cmd); void cmdUPnPScan(CmdPacket *cmd); void cmdUPnPAddPort(CmdPacket *cmd); void cmdUPnPRemovePort(CmdPacket *cmd); +void cmdUPnPBegin(CmdPacket *cmd); // keep track of last status sent to uC so we can notify it when it changes static uint8_t lastWifiStatus = wifiIsDisconnected; @@ -71,6 +72,7 @@ const CmdList commands[] = { {CMD_UPNP_SCAN, "UPNP_SCAN", cmdUPnPScan}, {CMD_UPNP_ADD_PORT, "UPNP_ADD_PORT", cmdUPnPAddPort}, {CMD_UPNP_REMOVE_PORT, "UPNP_REMOVE_PORT", cmdUPnPRemovePort}, + {CMD_UPNP_BEGIN, "UPNP_BEGIN", cmdUPnPBegin}, #ifdef MQTT {CMD_MQTT_SETUP, "MQTT_SETUP", MQTTCMD_Setup}, diff --git a/esp-link/upnp.c b/esp-link/upnp.c index dc7617b..5146bf5 100644 --- a/esp-link/upnp.c +++ b/esp-link/upnp.c @@ -3,6 +3,7 @@ #include "cmd.h" #include #include +#include #if 1 #define DBG_UPNP(format, ...) os_printf(format, ## __VA_ARGS__) @@ -26,7 +27,6 @@ static enum upnp_state_t upnp_state; static const char *upnp_ssdp_multicast = "239.255.255.250"; static short upnp_server_port = 1900; -static short upnp_local_port = -1; static const char *ssdp_message = "M-SEARCH * HTTP/1.1\r\n" "HOST: 239.255.255.250:1900\r\n" "ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n" @@ -48,8 +48,10 @@ typedef struct { uint16_t data_sent; } UPnPClient; +static UPnPClient *the_client; + // Functions -static void upnp_query_igd(); +static void upnp_query_igd(struct espconn *); static void ssdp_sent_cb(void *arg); static void ssdp_recv_cb(void *arg, char *pusrdata, unsigned short length); static void upnp_tcp_sent_cb(void *arg); @@ -61,7 +63,8 @@ static void upnp_tcp_recv(void *arg, char *pdata, unsigned short len); static void ICACHE_FLASH_ATTR ssdp_recv_cb(void *arg, char *pusrdata, unsigned short length) { - // struct espconn *con = (struct espconn *)arg; + struct espconn *con = (struct espconn *)arg; + UPnPClient *client = con->reverse; os_printf("ssdp_recv_cb : %d bytes\n", length); @@ -80,15 +83,16 @@ ssdp_recv_cb(void *arg, char *pusrdata, unsigned short length) { // FIXME this should be dynamically allocated os_strncpy(location, pusrdata+j, len); - DBG_UPNP("len %d message %s\n", len, pusrdata+j); + + os_printf("ssdp_recv_cb : %s\n", pusrdata+i+2); // Trigger next query - upnp_query_igd(); + upnp_query_igd(con); break; } break; default: - os_printf("UPnP FSM issue\n"); + os_printf("UPnP FSM issue, upnp_state = %d\n", (int)upnp_state); } } @@ -96,20 +100,28 @@ ssdp_recv_cb(void *arg, char *pusrdata, unsigned short length) { static void ICACHE_FLASH_ATTR ssdp_sent_cb(void *arg) { struct espconn *con = (struct espconn *)arg; - os_printf("ssdp_sent_cb\n"); + os_printf("ssdp_sent_cb, count %d\n", counter); +#if 0 if (upnp_state == upnp_multicasted && counter < counter_max) { counter++; espconn_sent(con, (uint8_t*)ssdp_message, ssdp_len); } +#else + os_printf("Disabled ssdp_sent_cb\n"); +#endif } -static void ICACHE_FLASH_ATTR upnp_query_igd(char *query) { - struct espconn *con = (struct espconn *)os_zalloc(sizeof(struct espconn)); +// BTW, use http/1.0 to avoid responses with transfer-encoding: chunked +const char *tmpl = "GET %s HTTP/1.0\r\n" + "Host: %s\r\n" + "Connection: close\r\n" + "User-Agent: esp-link\r\n\r\n"; - UPnPClient *client = (UPnPClient *)os_zalloc(sizeof(UPnPClient)); - client->con = con; - con->reverse = client; +static void ICACHE_FLASH_ATTR upnp_query_igd(struct espconn *con) { + UPnPClient *client = con->reverse; + + os_printf("upnp_query_igd\n"); con->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); upnp_state = upnp_found_igd; @@ -126,13 +138,21 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(char *query) { else con->proto.tcp->remote_port = 80; + os_printf("upnp_query_igd : location {%s} port %d\n", location, con->proto.tcp->remote_port); +// #if 0 // Continue doing so : now the path - for (i=7; location[i] && location[i] != '/'; i++) ; + char *path; + for (; location[i] && location[i] != '/'; i++) ; if (location[i] == '/') { - client->path = location + i; + path = location + i; q = i; } else - client->path = ""; // FIX ME not sure what to do if no path + path = ""; // FIX ME not sure what to do if no path + os_printf("path {%s}\n", path); + // os_printf("client ptr %08x\n", client); + client->path = path; + +// #if 0 // Now the smallest of p and q points to end of IP address if (p != 0) { location[p] = 0; @@ -141,11 +161,18 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(char *query) { } else { // take the whole string } char *host = location + 7; - +// #if 0 con->type = ESPCONN_TCP; con->state = ESPCONN_NONE; con->proto.tcp->local_port = espconn_port(); + /* + * strcpy(location, "http://192.168.1.1:8000/o8ee3npj36j/IGD/upnp/IGD.xml"); + * char *query = (char *)os_malloc(strlen(tmpl) + location_size); + * os_sprintf(query, tmpl, "/o8ee3npj36j/IGD/upnp/IGD.xml", "http://192.168.1.1:8000"); + * upnp_query_igd(query); + */ + client->data = query; client->data_len = strlen(query); @@ -155,18 +182,20 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(char *query) { if (UTILS_StrToIP(host, &con->proto.tcp->remote_ip)) { DBG_UPNP("UPnP: Connect to ip %s:%d\n", host, con->proto.tcp->remote_port); + client->ip = *(ip_addr_t *)&con->proto.tcp->remote_ip[0]; espconn_connect(con); } else { DBG_UPNP("UPnP: Connect to host %s:%d\n", host, con->proto.tcp->remote_port); espconn_gethostbyname(con, host, (ip_addr_t *)&con->proto.tcp->remote_ip[0], upnp_dns_found); } +// #endif } static void ICACHE_FLASH_ATTR upnp_tcp_sent_cb(void *arg) { // struct espconn *pCon = (struct espconn *)arg; - DBG_UPNP("UPNP: tcp_sent\n"); + os_printf("upnp_tcp_sent_cb (disabled)\n"); #if 0 if (client->data_sent != client->data_len) { // we only sent part of the buffer, send the rest @@ -183,6 +212,7 @@ upnp_tcp_sent_cb(void *arg) { static void ICACHE_FLASH_ATTR upnp_tcp_discon_cb(void *arg) { + os_printf("upnp_tcp_discon_cb (empty)\n"); // struct espconn *pespconn = (struct espconn *)arg; #if 0 @@ -194,6 +224,7 @@ upnp_tcp_discon_cb(void *arg) { static void ICACHE_FLASH_ATTR upnp_tcp_recon_cb(void *arg, sint8 errType) { + os_printf("upnp_tcp_recon_cb (empty)\n"); // struct espconn *pCon = (struct espconn *)arg; #if 0 @@ -207,9 +238,10 @@ upnp_tcp_recon_cb(void *arg, sint8 errType) { static void ICACHE_FLASH_ATTR upnp_tcp_connect_cb(void *arg) { struct espconn *con = (struct espconn *)arg; - UPnPClient* client = (UPnPClient *)con->reverse; + UPnPClient *client = (UPnPClient *)con->reverse; + + os_printf("upnp_tcp_connect_cb\n"); - DBG_UPNP("UPnP : connected\n"); espconn_regist_disconcb(con, upnp_tcp_discon_cb); espconn_regist_recvcb(con, upnp_tcp_recv); espconn_regist_sentcb(con, upnp_tcp_sent_cb); @@ -225,7 +257,7 @@ upnp_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { struct espconn *con = (struct espconn *)arg; UPnPClient* client = (UPnPClient *)con->reverse; - if(ipaddr == NULL) { + if (ipaddr == NULL) { os_printf("REST DNS: Got no ip, try to reconnect\n"); return; } @@ -234,7 +266,7 @@ upnp_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { *((uint8 *) &ipaddr->addr + 1), *((uint8 *) &ipaddr->addr + 2), *((uint8 *) &ipaddr->addr + 3)); - if(client->ip.addr == 0 && ipaddr->addr != 0) { + if (client && client->ip.addr == 0 && ipaddr->addr != 0) { os_memcpy(client->con->proto.tcp->remote_ip, &ipaddr->addr, 4); #ifdef CLIENT_SSL_ENABLE @@ -259,7 +291,7 @@ upnp_tcp_recv(void *arg, char *pdata, unsigned short len) { int inservice = 0, get_this = -1; - // os_printf("UPnP TCP Recv len %d\n", len); + os_printf("upnp_tcp_recv len %d\n", len); switch (upnp_state) { case upnp_found_igd: @@ -296,6 +328,7 @@ upnp_tcp_recv(void *arg, char *pdata, unsigned short len) { os_printf("UPnP TCP Recv len %d, %s\n", len, pdata); break; default: + os_printf("upnp_state (not treated) %d\n", (int)upnp_state); break; } } @@ -309,13 +342,28 @@ upnp_tcp_recv(void *arg, char *pdata, unsigned short len) { */ void ICACHE_FLASH_ATTR cmdUPnPScan(CmdPacket *cmd) { - upnp_state = upnp_none; - os_printf("cmdUPnPScan()\n"); + if (upnp_state == upnp_ready) { + // Return the IP address of the gateway, this indicates success. + if (the_client == 0) + cmdResponseStart(CMD_RESP_V, 0, 0); + else + cmdResponseStart(CMD_RESP_V, (uint32_t)the_client->ip.addr, 0); + cmdResponseEnd(); + return; + } + + upnp_state = upnp_none; + struct espconn *con = (struct espconn *)os_zalloc(sizeof(struct espconn)); if (con == NULL) { DBG_UPNP("SOCKET : Setup failed to alloc memory for client_pCon\n"); + + // Return 0, this means failure + cmdResponseStart(CMD_RESP_V, 0, 0); + cmdResponseEnd(); + return; } counter = 0; @@ -324,14 +372,23 @@ cmdUPnPScan(CmdPacket *cmd) { con->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); if (con->proto.udp == NULL) { DBG_UPNP("SOCKET : Setup failed to alloc memory for client->pCon->proto.udp\n"); + + // Return 0, this means failure + cmdResponseStart(CMD_RESP_V, 0, 0); + cmdResponseEnd(); + return; } + UPnPClient *client = (UPnPClient *)os_zalloc(sizeof(UPnPClient)); + client->con = con; + con->reverse = client; + the_client = client; + con->state = ESPCONN_NONE; con->proto.udp->remote_port = upnp_server_port; con->proto.udp->local_port = espconn_port(); - con->reverse = 0; espconn_regist_sentcb(con, ssdp_sent_cb); espconn_regist_recvcb(con, ssdp_recv_cb); @@ -342,13 +399,46 @@ cmdUPnPScan(CmdPacket *cmd) { espconn_create(con); } else { DBG_UPNP("SOCKET : failed to copy remote_ip to &con->proto.udp->remote_ip\n"); + + // Return 0, this means failure + cmdResponseStart(CMD_RESP_V, 0, 0); + cmdResponseEnd(); + return; } +#if 0 + // Return 0, this means failure + cmdResponseStart(CMD_RESP_V, 0, 0); // Danny + cmdResponseEnd(); // Danny + return; // Danny +#endif + + os_printf("Determining strlen(ssdp_message)\n"); ssdp_len = strlen(ssdp_message); + os_printf("strlen(ssdp_message) = %d\n", ssdp_len); espconn_sent(con, (uint8_t*)ssdp_message, ssdp_len); - DBG_UPNP("SOCKET : sending %d bytes\n", ssdp_len); + os_printf("espconn_sent() done\n"); +#if 0 + // Return 0, this means failure + cmdResponseStart(CMD_RESP_V, 0, 0); // Danny + cmdResponseEnd(); // Danny + return; // Danny +#endif + // DBG_UPNP("SOCKET : sending %d bytes\n", ssdp_len); upnp_state = upnp_multicasted; + +#if 0 + // Return 0, this means failure + cmdResponseStart(CMD_RESP_V, 0, 0); // Danny + cmdResponseEnd(); // Danny + return; // Danny +#endif + // Not ready yet --> indicate failure + cmdResponseStart(CMD_RESP_V, 0, 0); + cmdResponseEnd(); + + os_printf("Return at end of cmdUPnPScan(), upnp_state = upnp_multicasted\n"); } // BTW, use http/1.0 to avoid responses with transfer-encoding: chunked @@ -359,12 +449,19 @@ const char *tmpl = "GET %s HTTP/1.0\r\n" void ICACHE_FLASH_ATTR cmdUPnPAddPort(CmdPacket *cmd) { +#if 0 strcpy(location, "http://192.168.1.1:8000/o8ee3npj36j/IGD/upnp/IGD.xml"); char *query = (char *)os_malloc(strlen(tmpl) + location_size); os_sprintf(query, tmpl, "/o8ee3npj36j/IGD/upnp/IGD.xml", "http://192.168.1.1:8000"); upnp_query_igd(query); +#endif } void ICACHE_FLASH_ATTR cmdUPnPRemovePort(CmdPacket *cmd) { } + +void ICACHE_FLASH_ATTR +cmdUPnPBegin(CmdPacket *cmd) { + upnp_state = upnp_none; +} diff --git a/serial/slip.c b/serial/slip.c index 2f15186..43d035e 100644 --- a/serial/slip.c +++ b/serial/slip.c @@ -76,7 +76,7 @@ static void ICACHE_FLASH_ATTR slip_parse_char(char c) { if (c == SLIP_END) { // either start or end of packet, process whatever we may have accumulated - DBG("SLIP: start or end len=%d inpkt=%d\n", slip_len, slip_inpkt); + // DBG("SLIP: start or end len=%d inpkt=%d\n", slip_len, slip_inpkt); if (slip_len > 0) { if (slip_len > 2 && slip_inpkt) slip_process(); else console_process(slip_buf, slip_len); diff --git a/serial/uart.c b/serial/uart.c index 92233a0..5921c48 100644 --- a/serial/uart.c +++ b/serial/uart.c @@ -79,7 +79,8 @@ uart_config(uint8 uart_no, UartBautRate baudrate, uint32 conf0) // We do not enable framing error interrupts 'cause they tend to cause an interrupt avalanche // and instead just poll for them when we get a std RX interrupt. WRITE_PERI_REG(UART_CONF1(uart_no), - ((80 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | + // ((80 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | + ((40 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | ((100 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN | (4 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | diff --git a/socket/socket.c b/socket/socket.c index a17f216..47cd919 100644 --- a/socket/socket.c +++ b/socket/socket.c @@ -48,16 +48,60 @@ socketclient_recv_cb(void *arg, char *pusrdata, unsigned short length) { uint8_t clientNum = client->conn_num; uint8_t cb_type = USERCB_RECV; - DBG_SOCK("SOCKET #%d: Received %d bytes: %s\n", client-socketClient, length, pusrdata); + + // DBG_SOCK("SOCKET #%d: Received %d bytes: %s\n", client-socketClient, length, pusrdata); + // DBG_SOCK("SOCKET #%d: Received %d bytes, CB=0x%04X\n", client-socketClient, length, client->resp_cb); + DBG_SOCK("SOCKET #%d: Received %d bytes\n", client-socketClient, length); + +#if 0 + // Hack : only forward the LOCATION: field + for (int i=0; iresp_cb, 4); + cmdResponseBody(&cb_type, 1); + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&len, 2); + cmdResponseBody(pusrdata+i+2, len); + cmdResponseEnd(); + + DBG_SOCK("SOCKET #%d, CB 0x%04X: len %d message %s\n", client-socketClient, client->resp_cb, len, pusrdata+i+2); + + return; + } +#endif +#if 0 + if (length == 347) { + for (int i=0; i<8; i++) { + for (int j=0; j<16; j++) + os_printf("%02x ", pusrdata[i*16+j]); + for (int j=0; j<16; j++) { + int c = pusrdata[i*16+j]; + if (c > ' ' && c < 0x80) + os_printf("%c ", c); + else + os_printf(" "); + } + os_printf("\n"); + } + } +#endif + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 4); cmdResponseBody(&cb_type, 1); cmdResponseBody(&clientNum, 1); cmdResponseBody(&length, 2); cmdResponseBody(pusrdata, length); cmdResponseEnd(); - + if (client->sock_mode != SOCKET_TCP_SERVER) { // We don't wait for a response - DBG_SOCK("SOCKET #%d: disconnect after receiving\n", client-socketClient); + // DBG_SOCK("SOCKET #%d: disconnect after receiving\n", client-socketClient); espconn_disconnect(client->pCon); // disconnect from the server } } @@ -70,7 +114,7 @@ socketclient_sent_cb(void *arg) { uint8_t clientNum = client->conn_num; uint8_t cb_type = USERCB_SENT; - DBG_SOCK("SOCKET #%d: Sent\n", client-socketClient); + // DBG_SOCK("SOCKET #%d: Sent\n", client-socketClient); sint16 sentDataLen = client->data_sent; if (client->data_sent != client->data_len) { @@ -250,7 +294,7 @@ SOCKET_Setup(CmdPacket *cmd) { goto fail; } err--; - DBG_SOCK("SOCKET Setup listener flag\n"); + // DBG_SOCK("SOCKET Setup listener flag\n"); // clear connection structures the first time if (socketNum == 0xff) { @@ -274,7 +318,9 @@ SOCKET_Setup(CmdPacket *cmd) { os_free(client->pCon); } os_memset(client, 0, sizeof(SocketClient)); + DBG_SOCK("SOCKET #%d: Setup host=%s port=%d \n", clientNum, socket_host, port); + // DBG_SOCK("SOCKET #%d: Setup host=%s port=%d CB %04x\n", clientNum, socket_host, port, cmd->value); client->sock_mode = sock_mode; client->resp_cb = cmd->value; @@ -283,6 +329,17 @@ SOCKET_Setup(CmdPacket *cmd) { client->host = (char *)socket_host; client->port = port; + // Clear old similar sockets !! + for (int i=0; iport == port && client->host == (char *)socket_host) { + client->port = 0; // FIX ME + client->host = 0; // FIX ME + os_printf("Alert : clearing socket %d, while creating socket %d\n", i, clientNum); + } + } + if (sock_mode == SOCKET_UDP) { wifi_set_broadcast_if(STATIONAP_MODE); } @@ -324,7 +381,7 @@ SOCKET_Setup(CmdPacket *cmd) { espconn_regist_sentcb(client->pCon, socketclient_sent_cb); espconn_regist_recvcb(client->pCon, socketclient_recv_cb); if (sock_mode == SOCKET_UDP) { - DBG_SOCK("SOCKET #%d: Create connection to ip %s:%d\n", clientNum, client->host, client->port); + // DBG_SOCK("SOCKET #%d: Create connection to ip %s:%d\n", clientNum, client->host, client->port); if(UTILS_StrToIP((char *)client->host, &client->pCon->proto.udp->remote_ip)) { espconn_create(client->pCon); @@ -343,7 +400,7 @@ SOCKET_Setup(CmdPacket *cmd) { cmdResponseStart(CMD_RESP_V, clientNum, 0); cmdResponseEnd(); - DBG_SOCK("SOCKET #%d: setup finished\n", clientNum); + // DBG_SOCK("SOCKET #%d: setup finished\n", clientNum); return; fail: @@ -360,7 +417,7 @@ SOCKET_Send(CmdPacket *cmd) { // Get client uint32_t clientNum = cmd->value; SocketClient *client = socketClient + (clientNum % MAX_SOCKET); - DBG_SOCK("SOCKET #%d: send", clientNum); + // DBG_SOCK("SOCKET #%d: send", clientNum); if (cmd->argc != 1 && cmd->argc != 2) { DBG_SOCK("\nSOCKET #%d: send - wrong number of arguments\n", clientNum); @@ -369,7 +426,7 @@ SOCKET_Send(CmdPacket *cmd) { // Get data to sent client->data_len = cmdArgLen(&req); - DBG_SOCK(" dataLen=%d", client->data_len); + // DBG_SOCK(" dataLen=%d", client->data_len); if (client->data) os_free(client->data); client->data = (char*)os_zalloc(client->data_len); @@ -378,13 +435,13 @@ SOCKET_Send(CmdPacket *cmd) { goto fail; } cmdPopArg(&req, client->data, client->data_len); - DBG_SOCK(" socketData=%s", client->data); + // DBG_SOCK(" socketData=%s", client->data); // client->data_len = os_sprintf((char*)client->data, socketDataSet, socketData); - DBG_SOCK("\n"); + // DBG_SOCK("\n"); - DBG_SOCK("SOCKET #%d: Create connection to ip %s:%d\n", clientNum, client->host, client->port); + // DBG_SOCK("SOCKET #%d: Create connection to ip %s:%d\n", clientNum, client->host, client->port); if (client->sock_mode == SOCKET_TCP_SERVER) { // In TCP server mode we should be connected already and send the data immediately remot_info *premot = NULL; @@ -421,7 +478,8 @@ SOCKET_Send(CmdPacket *cmd) { } } else { // in UDP socket mode we send the data immediately client->data_sent = client->data_len <= 1400 ? client->data_len : 1400; - DBG_SOCK("SOCKET #%d: sending %d bytes: %s\n", clientNum, client->data_sent, client->data); + // DBG_SOCK("SOCKET #%d: sending %d bytes: %s\n", clientNum, client->data_sent, client->data); + // DBG_SOCK("SOCKET #%d: sending %d bytes\n", clientNum, client->data_sent); espconn_sent(client->pCon, (uint8_t*)client->data, client->data_sent); }