diff --git a/esp-link/upnp.c b/esp-link/upnp.c
index 67b03bc..f45bccd 100644
--- a/esp-link/upnp.c
+++ b/esp-link/upnp.c
@@ -46,6 +46,13 @@ enum upnp_state_t {
};
static enum upnp_state_t upnp_state;
+enum service_type_t {
+ service_type_unknown,
+ wanppp,
+ wanip
+};
+static enum service_type_t service_type = service_type_unknown;
+
/*
* Query #1 : SSDP protocol, this is a UDP multicast to discover a IGD device.
* (internet gateway device)
@@ -61,6 +68,14 @@ static int ssdp_len;
static char *control_url = 0;
static int counter;
+static const char *service_type_wanip = "urn:upnp-org:serviceId:WANIPConn1";
+static int service_type_wanip_len = 33;
+static const char *service_type_wanppp = "urn:upnp-org:serviceId:WANPPPConn1";
+static int service_type_wanppp_len = 34;
+
+static const char *connection_wanppp = "WANPPPConnection";
+static const char *connection_wanip = "WANIPConnection";
+
/*
* Query #2 : query the IGD for its device & service list.
* We search this list for the control URL of the router.
@@ -85,7 +100,9 @@ static const char *upnp_query_external_address =
"User-Agent: esp-link\r\n"
"Content-Length : %d\r\n" // XML length
"Content-Type: text/xml\r\n"
- "SOAPAction: \"urn:schemas-upnp-org:service:WANPPPConnection:1#GetExternalIPAddress\"\r\n"
+ // "SOAPAction: \"urn:schemas-upnp-org:service:WANPPPConnection:1#GetExternalIPAddress\"\r\n"
+ "SOAPAction: \"urn:schemas-upnp-org:service:%s:1#GetExternalIPAddress\"\r\n"
+ // WANPPPConnection
"Connection: Close\r\n"
"Cache-Control: no-cache\r\n"
"Pragma: no-cache\r\n"
@@ -95,7 +112,8 @@ static const char *upnp_query_external_address_xml =
"\r\n"
"\r\n"
"\r\n"
- "\r\n"
+ // "\r\n"
+ "\r\n"
"\r\n"
"\r\n"
"\r\n";
@@ -141,7 +159,8 @@ static const char *upnp_query_add_tmpl =
"User-Agent: esp-link\r\n"
"Content-Length: %d\r\n" // Length of XML
"Content-Type: text/xml\r\n"
- "SOAPAction: \"urn:schemas-upnp-org:service:WANPPPConnection:1#AddPortMapping\"\r\n"
+ // "SOAPAction: \"urn:schemas-upnp-org:service:WANPPPConnection:1#AddPortMapping\"\r\n"
+ "SOAPAction: \"urn:schemas-upnp-org:service:%s:1#AddPortMapping\"\r\n"
"Connection: Close\r\n"
"Cache-Control: no-cache\r\n"
"Pragma: no-cache\r\n\r\n%s"; // XML
@@ -151,7 +170,8 @@ static const char *upnp_query_add_xml =
"\r\n"
"\r\n"
- "\r\n"
+ // "\r\n"
+ "\r\n"
"\r\n"
"%d\r\n" // remote port
"TCP\r\n"
@@ -361,6 +381,7 @@ ssdp_sent_cb(void *arg) {
*/
static void ICACHE_FLASH_ATTR upnp_query_igd(UPnPClient *client) {
char *query, *xml;
+ char *p, *q;
// Create new espconn
client->con = (struct espconn *)os_zalloc(sizeof(struct espconn));
@@ -396,29 +417,42 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(UPnPClient *client) {
os_printf("Port to be added is %08x : %04x (remote %04x)\n", client->ip.addr, client->port, client->remote_port);
// Two step approach, as the XML also contains variable info, and we need to pass its length.
- xml = (char *)os_malloc(strlen(upnp_query_add_xml) + 32);
+ xml = (char *)os_malloc(strlen(upnp_query_add_xml) + strlen(connection_wanppp) + 32);
// FIXME byte order issue ?
- os_sprintf(xml, upnp_query_add_xml, client->remote_port, client->port,
- ip4_addr4(&client->ip), ip4_addr3(&client->ip),
- ip4_addr2(&client->ip), ip4_addr1(&client->ip));
+ os_sprintf(xml, upnp_query_add_xml,
+ (service_type == wanppp) ? connection_wanppp : connection_wanip,
+ client->remote_port, client->port,
+ ip4_addr1(&client->ip), ip4_addr2(&client->ip),
+ ip4_addr3(&client->ip), ip4_addr4(&client->ip));
+
+ // os_printf("XML %s\n", xml);
+ // os_printf("Control URL %s\n", client->control_url);
+ // return; // Danny
// Step 2 : create the headers.
query = (char *)os_malloc(strlen(upnp_query_add_tmpl) + strlen(client->control_url) + strlen(client->host) + 10 + strlen(xml));
os_sprintf(query, upnp_query_add_tmpl,
client->control_url, client->host,
- strlen(xml), xml);
+ strlen(xml),
+ (service_type == wanppp) ? connection_wanppp : connection_wanip,
+ xml);
// Don't forget to free the temporary string storage for step 1.
os_free(xml);
-#if 1
+ // os_printf("QUERY %s\n", query);
+ // os_printf("Control URL %s\n", client->control_url);
+ // return; // Danny
+
+#if 0
// Production : no debug output
break;
#else
//os_printf("Query : %s\n", query);
// Just calling os_printf() produces empty lines (\r\n)
- char *p, *q;
+
+ os_printf("Query : ");
for (p=query; *p; p++) {
for (q=p; *q && *q != '\r'; q++) ;
*q = 0;
@@ -426,6 +460,7 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(UPnPClient *client) {
*q = '\r';
p=q+1;
}
+ // return; // Danny
break;
#endif
@@ -456,7 +491,6 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(UPnPClient *client) {
#else
//os_printf("Query : %s\n", query);
// Just calling os_printf() produces empty lines (\r\n)
- char *p, *q;
for (p=query; *p; p++) {
for (q=p; *q && *q != '\r'; q++) ;
*q = 0;
@@ -468,12 +502,21 @@ static void ICACHE_FLASH_ATTR upnp_query_igd(UPnPClient *client) {
#endif
case upnp_query_extaddress:
+ // Step 1
+ xml = os_malloc(strlen(upnp_query_external_address_xml) + strlen(connection_wanppp));
+ os_sprintf(xml, upnp_query_external_address_xml,
+ (service_type == wanppp) ? connection_wanppp : connection_wanip);
+
+ // Step 2
query = os_malloc(strlen(upnp_query_external_address) + strlen(the_client->control_url) +
- strlen(the_client->host) + 8 + strlen(upnp_query_external_address_xml));
+ strlen(the_client->host) + 8 + strlen(xml) + strlen(connection_wanppp));
os_sprintf(query, upnp_query_external_address,
the_client->control_url, the_client->host,
- strlen(upnp_query_external_address_xml), upnp_query_external_address_xml);
-#if 1
+ strlen(xml),
+ (service_type == wanppp) ? connection_wanppp : connection_wanip,
+ xml);
+ os_free(xml);
+#if 0
// Production : no debug output
break;
#else
@@ -555,6 +598,7 @@ upnp_tcp_discon_cb(void *arg) {
// Kick SM into next state, trigger next query
switch (upnp_state) {
case upnp_found_igd:
+ os_printf("upnp_tcp_discon_cb set state to READY\n");
upnp_state = upnp_ready;
break;
@@ -641,12 +685,34 @@ upnp_tcp_recv_cb(void *arg, char *pdata, unsigned short len) {
case upnp_found_igd:
// Find a service with specific id, remember its control-url.
for (int i=0; i", 13) == 0) {
+ int k, l;
+ for (k=i+13; pdata[k] && pdata[k] != '<'; k++) ;
+ for (l=i; l", 9) == 0) {
inservice++;
+#if 0
+ // Debug
+ int k, l;
+ for (k=i, l=0; l<4 && k", 10) == 0) {
inservice--;
- } else if (strncasecmp(pdata+i, "urn:upnp-org:serviceId:WANPPPConn1", 34) == 0) {
+ } else if (strncasecmp(pdata+i, service_type_wanip, service_type_wanip_len) == 0) {
+ get_this = inservice;
+ service_type = wanip;
+ } else if (strncasecmp(pdata+i, service_type_wanppp, service_type_wanppp_len) == 0) {
get_this = inservice;
+ service_type = wanppp;
} else if (get_this == inservice && strncasecmp(pdata+i, "", 12) == 0) {
get_this = -1;
int j;
@@ -669,9 +735,9 @@ upnp_tcp_recv_cb(void *arg, char *pdata, unsigned short len) {
case upnp_ready:
break;
case upnp_adding_port:
- // FIXME
// os_printf("UPnP TCP Recv len %d, %s\n", len, pdata);
os_printf("UPnP TCP Recv len %d\n", len);
+ // FIXME should interpret the result
break;
case upnp_removing_port:
// FIXME
@@ -710,6 +776,14 @@ void ICACHE_FLASH_ATTR
cmdUPnPScan(CmdPacket *cmd) {
os_printf("cmdUPnPScan()\n");
+ // States that signify we're not ready --> reply immediately, with NULL
+ if (upnp_state == upnp_multicasted || upnp_state == upnp_found_igd) {
+ cmdResponseStart(CMD_RESP_V, 0, 0);
+ cmdResponseEnd();
+ return;
+ }
+
+ // If we're ready, return indicating the IP address of the router
if (upnp_state == upnp_ready) {
// Return the IP address of the gateway, this indicates success.
if (the_client == 0)
@@ -720,6 +794,7 @@ cmdUPnPScan(CmdPacket *cmd) {
return;
}
+ // Otherwise, start a scan already
upnp_state = upnp_none;
struct espconn *con = (struct espconn *)os_zalloc(sizeof(struct espconn));
@@ -835,6 +910,14 @@ cmdUPnPAddPort(CmdPacket *cmd) {
the_client->port = local_port;
the_client->remote_port = remote_port;
+#if 0
+ // Stop right here
+ // Return 0 -> ok
+ cmdResponseStart(CMD_RESP_V, 0, 0);
+ cmdResponseEnd();
+ return;
+#endif
+
upnp_state = upnp_adding_port;
upnp_query_igd(the_client);