mirror of https://github.com/jeelabs/esp-link.git
parent
ac9e0d40c0
commit
955c5a9dc6
@ -0,0 +1,124 @@ |
||||
#include "esp8266.h" |
||||
#include "sntp.h" |
||||
#include "cmd.h" |
||||
#include <socket.h> |
||||
#include <ip_addr.h> |
||||
|
||||
#if 1 |
||||
#define DBG_SOCK(format, ...) os_printf(format, ## __VA_ARGS__) |
||||
#else |
||||
#define DBG_SOCK(format, ...) do { } while(0) |
||||
#endif |
||||
|
||||
#define location_size 80 |
||||
static const int counter_max = 4; |
||||
|
||||
enum upnp_state_t { |
||||
upnp_none, |
||||
upnp_multicasted, |
||||
upnp_found_igd |
||||
}; |
||||
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" |
||||
"MAN: \"ssdp:discover\"\r\n" |
||||
"MX: 2\r\n"; |
||||
static int ssdp_len; |
||||
static char location[location_size]; |
||||
static int counter; |
||||
|
||||
static void ICACHE_FLASH_ATTR |
||||
upnp_recv_cb(void *arg, char *pusrdata, unsigned short length) { |
||||
// struct espconn *pCon = (struct espconn *)arg;
|
||||
|
||||
os_printf("upnp_recv_cb : %d bytes\n", length); |
||||
|
||||
switch (upnp_state) { |
||||
case upnp_multicasted: |
||||
// Find the LOCATION: field
|
||||
for (int i=0; i<length-20; i++) |
||||
if (pusrdata[i] == 0x0D && pusrdata[i+1] == 0x0A |
||||
&& os_strncmp(pusrdata+i+2, "LOCATION:", 9) == 0) { |
||||
// find end of LOCATION field
|
||||
int j, k; |
||||
for (k=j=i+11; pusrdata[k] && pusrdata[k] != 0x0D; k++) ; |
||||
int len = k-j+1; |
||||
|
||||
pusrdata[k] = 0; // NULL terminate
|
||||
|
||||
// FIXME this should be dynamically allocated
|
||||
os_strncpy(location, pusrdata+j, len); |
||||
DBG_SOCK("len %d message %s\n", len, pusrdata+j); |
||||
|
||||
// Trigger next query
|
||||
break; |
||||
} |
||||
break; |
||||
default: |
||||
os_printf("UPnP FSM issue\n"); |
||||
} |
||||
} |
||||
|
||||
// Our packets are small, so this is not useful
|
||||
static void ICACHE_FLASH_ATTR |
||||
upnp_sent_cb(void *arg) { |
||||
struct espconn *con = (struct espconn *)arg; |
||||
os_printf("upnp_sent_cb\n"); |
||||
|
||||
if (counter < counter_max) { |
||||
counter++; |
||||
espconn_sent(con, (uint8_t*)ssdp_message, ssdp_len); |
||||
} |
||||
} |
||||
|
||||
void ICACHE_FLASH_ATTR |
||||
cmdUPnPScan(CmdPacket *cmd) { |
||||
upnp_state = upnp_none; |
||||
|
||||
os_printf("cmdUPnPScan()\n"); |
||||
// cmdResponseStart(CMD_RESP_V, wifiState, 0);
|
||||
// cmdResponseEnd();
|
||||
|
||||
struct espconn *con = (struct espconn *)os_zalloc(sizeof(struct espconn)); |
||||
if (con == NULL) { |
||||
DBG_SOCK("SOCKET : Setup failed to alloc memory for client_pCon\n"); |
||||
return; |
||||
} |
||||
counter = 0; |
||||
|
||||
con->type = ESPCONN_UDP; |
||||
con->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); |
||||
if (con->proto.udp == NULL) { |
||||
DBG_SOCK("SOCKET : Setup failed to alloc memory for client->pCon->proto.udp\n"); |
||||
return; |
||||
} |
||||
|
||||
con->state = ESPCONN_NONE; |
||||
|
||||
con->proto.udp->remote_port = upnp_server_port; |
||||
con->proto.udp->local_port = upnp_local_port; |
||||
|
||||
espconn_regist_sentcb(con, upnp_sent_cb); |
||||
espconn_regist_recvcb(con, upnp_recv_cb); |
||||
|
||||
DBG_SOCK("SOCKET : Create connection to ip %s:%d\n", upnp_ssdp_multicast, upnp_server_port); |
||||
|
||||
if (UTILS_StrToIP((char *)upnp_ssdp_multicast, &con->proto.udp->remote_ip)) { |
||||
espconn_create(con); |
||||
} else { |
||||
DBG_SOCK("SOCKET : failed to copy remote_ip to &con->proto.udp->remote_ip\n"); |
||||
return; |
||||
} |
||||
|
||||
ssdp_len = strlen(ssdp_message); |
||||
espconn_sent(con, (uint8_t*)ssdp_message, ssdp_len); |
||||
DBG_SOCK("SOCKET : sending %d bytes\n", ssdp_len); |
||||
upnp_state = upnp_multicasted; |
||||
} |
||||
|
Loading…
Reference in new issue