work in progress

pull/206/head
dannybackx 8 years ago
parent 40cc23d222
commit b350641bb9
  1. 1
      cmd/cmd.h
  2. 2
      cmd/handlers.c
  3. 149
      esp-link/upnp.c
  4. 2
      serial/slip.c
  5. 3
      serial/uart.c
  6. 82
      socket/socket.c

@ -71,6 +71,7 @@ typedef enum {
CMD_UPNP_SCAN = 60,
CMD_UPNP_ADD_PORT,
CMD_UPNP_REMOVE_PORT,
CMD_UPNP_BEGIN,
} CmdName;

@ -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},

@ -3,6 +3,7 @@
#include "cmd.h"
#include <socket.h>
#include <ip_addr.h>
#include <strings.h>
#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 <removing port> 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;
}

@ -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);

@ -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 |

@ -48,7 +48,51 @@ 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; i<length-20; i++)
if (pusrdata[i] == 0x0D && pusrdata[i+1] == 0x0A && pusrdata[i+2] == 'L'
&& os_strncmp(pusrdata+i+2, "LOCATION:", 9) == 0) {
// find end of LOCATION field
int j=i+11, k;
for (k=j; pusrdata[k] && pusrdata[k] != 0x0D; k++) ;
int len = k-i-1;
pusrdata[k] = 0;
cmdResponseStart(CMD_RESP_CB, client->resp_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);
@ -57,7 +101,7 @@ socketclient_recv_cb(void *arg, char *pusrdata, unsigned short 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; i<MAX_SOCKET; i++)
if (i != clientNum) {
SocketClient *client = socketClient + i;
if (client->port == 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);
}

Loading…
Cancel
Save