diff --git a/app/include/lwip/app/ping.h b/app/include/lwip/app/ping.h index 21e26e9101..cb4330c55b 100644 --- a/app/include/lwip/app/ping.h +++ b/app/include/lwip/app/ping.h @@ -54,6 +54,7 @@ struct ping_option{ ping_recv_function recv_function; ping_sent_function sent_function; void* reverse; + struct ping_msg *parent_msg; }; struct ping_msg{ @@ -75,6 +76,7 @@ struct ping_resp{ uint32 bytes; uint32 total_bytes; uint32 total_time; + uint8 ttl; sint8 ping_err; }; diff --git a/app/include/user_modules.h b/app/include/user_modules.h index 0b28dbe757..c3d7affa0d 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -38,6 +38,7 @@ //#define LUA_USE_MODULES_MDNS #define LUA_USE_MODULES_MQTT #define LUA_USE_MODULES_NET +#define LUA_USE_MODULES_NET_INFO #define LUA_USE_MODULES_NODE #define LUA_USE_MODULES_OW //#define LUA_USE_MODULES_PCM diff --git a/app/lwip/app/ping.c b/app/lwip/app/ping.c index 38045c5b69..5e3bd310ba 100644 --- a/app/lwip/app/ping.c +++ b/app/lwip/app/ping.c @@ -164,7 +164,14 @@ ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr) pingresp.resp_time = delay; pingresp.seqno = ntohs(iecho->seqno); pingresp.ping_err = 0; - pingmsg->ping_opt->recv_function(pingmsg->ping_opt,(void*) &pingresp); + pingresp.ttl = iphdr->_ttl; + + // hand back pointer to message without breaking compatibility + pingmsg->ping_opt->parent_msg = pingmsg; + +// pingmsg->ping_opt->recv_function(pingmsg,(void*) &pingresp); + pingmsg->ping_opt->recv_function(pingmsg->ping_opt, (void*) &pingresp); + } } seqno = iecho->seqno; diff --git a/app/modules/net_info.c b/app/modules/net_info.c new file mode 100644 index 0000000000..dbaf2a9712 --- /dev/null +++ b/app/modules/net_info.c @@ -0,0 +1,197 @@ +/* + * http://blog.mclemon.io/esp8266-contributing-to-the-nodemcu-ecosystem + * https://github.com/smcl/nodemcu-firmware/blob/cc04aaf92c1c076c30ef0b0eee43b3f924137440/app/modules/test.c + * + * extracted ping function + * adopted jan 2017 for commit to nodeMCU by Wolfgang Rosner + */ + + +#include "module.h" +#include "lauxlib.h" +#include "platform.h" + +// #include +// #include +// #include +// #include +#include "mem.h" + +#include "lwip/ip_addr.h" +#include "espconn.h" +#include "lwip/dns.h" +#include "lwip/app/ping.h" +#include "lwip/raw.h" + + +#include "task/task.h" + + + +// https://github.com/nodemcu/nodemcu-firmware/wiki/[DRAFT]-How-to-write-a-C-module#debug-and-error-messages + +#define NET_INFO_DEBUG_ON + +#define log_prefix " ### DEBUG: net_info ### : " + +#if defined(DEVELOP_VERSION) + #define NET_INFO_DEBUG_ON +#endif +#if defined(NET_INFO_DEBUG_ON) + #define NET_INFO_DEBUG(format, ...) dbg_printf("%s"format"", log_prefix, ##__VA_ARGS__) +#else + #define NET_INFO_DEBUG(...) +#endif +#if defined(NODE_ERROR) + #define NET_INFO_ERR(format, ...) NODE_ERR("%s"format"\n", log_prefix, ##__VA_ARGS__) +#else + #define NET_INFO_ERR(...) +#endif + + +#define NET_INFO_PRIORITY_OUTPUT TASK_PRIORITY_MEDIUM +#define NET_INFO_PRIORITY_ERROR TASK_PRIORITY_MEDIUM + +// these statics should go away for reentrancy and maybe other reasons! +static int ping_callback_ref; +static int ping_host_count; +static ip_addr_t ping_host_ip; +struct ping_option *ping_opt = NULL; + +void ping_received(void *arg, void *data) { + // this would require change of the interface + // struct ping_msg *pingmsg = (struct ping_msg*)arg; + // struct ping_option *pingopt = pingmsg->ping_opt; + struct ping_option *pingopt = (struct ping_option*)arg; + struct ping_msg *pingmsg = pingopt->parent_msg ; + + struct ping_resp *pingresp = (struct ping_resp*)data; + + char ipaddrstr[16]; + ip_addr_t source_ip; + + source_ip.addr = pingopt->ip; + ipaddr_ntoa_r(&source_ip, ipaddrstr, sizeof(ipaddrstr)); + + if (ping_callback_ref != LUA_NOREF) { + lua_State *L = lua_getstate(); + lua_rawgeti(L, LUA_REGISTRYINDEX, ping_callback_ref); + lua_pushinteger(L, pingresp->bytes); + lua_pushstring(L, ipaddrstr); + lua_pushinteger(L, pingresp->seqno); + lua_pushinteger(L, pingresp->ttl); + lua_pushinteger(L, pingresp->resp_time); + lua_call(L, 5, 0); + } +} + +static void ping_by_hostname(const char *name, ip_addr_t *ipaddr, void *arg) { + if (!ping_opt) { + ping_opt = (struct ping_option *)os_zalloc(sizeof(struct ping_option)); + } else { + os_memset (ping_opt, 0, sizeof(struct ping_option)); + } + + if (ipaddr == NULL) { + lua_State *L = lua_getstate(); + luaL_error(L, "SEVERE problem resolving hostname - network and DNS accessible?\n"); + return; + } + if (ipaddr->addr == IPADDR_NONE) { + lua_State *L = lua_getstate(); + luaL_error(L, "problem resolving hostname - maybe nonexistent host?\n"); + return; + } + + ping_opt->count = ping_host_count; + ping_opt->ip = ipaddr->addr; + ping_opt->coarse_time = 0; + ping_opt->recv_function = &ping_received; + + ping_start(ping_opt); +} + + +/** + * test.ping() + * Description: + * Send ICMP ping request to address, optionally call callback when response received + * + * Syntax: + * wifi.sta.getconfig(ssid, password) --Set STATION configuration, Auto-connect by default, Connects to any BSSID + * test.ping(address) -- send 4 ping requests to target address + * test.ping(address, n) -- send n ping requests to target address + * test.ping(address, n, callback) -- send n ping requests to target address + * Parameters: + * address: string + * n: number of requests to send + * callback: + * Returns: + * Nothing. + * + * Example: + * test.ping("192.168.0.1") -- send 4 pings to 192.168.0.1 + * test.ping("192.168.0.1", 10) -- send 10 pings to 192.168.0.1 + * test.ping("192.168.0.1", 10, got_ping) -- send 10 pings to 192.168.0.1, call got_ping() with the + * -- ping results + */ + +static int net_info_ping(lua_State *L) +{ + const char *ping_target; + unsigned count = 4; + + // retrieve address arg (mandatory) + if (lua_isstring(L, 1)) { + ping_target = luaL_checkstring(L, 1); + } else { + return luaL_error(L, "no address specified"); + } + + // retrieve count arg (optional) + if (lua_isnumber(L, 2)) { + count = luaL_checkinteger(L, 2); + } + + // retrieve callback arg (optional) + if (ping_callback_ref != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, ping_callback_ref); + ping_callback_ref = LUA_NOREF; + + if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION) + ping_callback_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + // attempt to parse ping target as IP + uint32 ip = ipaddr_addr(ping_target); + + if (ip != IPADDR_NONE) { + if (!ping_opt) { + ping_opt = (struct ping_option *)os_zalloc(sizeof(struct ping_option)); + } else { + os_memset (ping_opt, 0, sizeof(struct ping_option)); + } + + + ping_opt->count = count; + ping_opt->ip = ip; + ping_opt->coarse_time = 0; + ping_opt->recv_function = &ping_received; + + ping_start(ping_opt); + } else { + ping_host_count = count; + + struct espconn *ping_dns_lookup; + espconn_create(ping_dns_lookup); + espconn_gethostbyname(ping_dns_lookup, ping_target, &ping_host_ip, ping_by_hostname); + } + + return 0; +} + +// Module function map +LROT_BEGIN(net_info) + LROT_FUNCENTRY( ping, net_info_ping ) +LROT_END( net_ifo, NULL, 0 ) + +NODEMCU_MODULE(NET_INFO, "net_info", net_info, NULL); diff --git a/mkdocs.yml b/mkdocs.yml index 4d704d1751..7a99fc1617 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -83,6 +83,7 @@ pages: - 'mdns': 'modules/mdns.md' - 'mqtt': 'modules/mqtt.md' - 'net': 'modules/net.md' + - 'net_info': 'en/modules/net_info.md' - 'node': 'modules/node.md' - 'ow (1-Wire)': 'modules/ow.md' - 'pcm' : 'modules/pcm.md'