diff --git a/libs/network/esp32/jswrap_esp32_network.c b/libs/network/esp32/jswrap_esp32_network.c index dc0bf1976..4cfeb917b 100644 --- a/libs/network/esp32/jswrap_esp32_network.c +++ b/libs/network/esp32/jswrap_esp32_network.c @@ -47,6 +47,110 @@ The details include: */ +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "associated", + "params" : [ + ["details","JsVar","An object with event details"] + ] +} +The 'connected' event is called when an association with an access point has succeeded, i.e., a connection to the AP's network has been established. +The details include: + +* ssid - The SSID of the access point to which the association was established +* mac - The BSSID/mac address of the access point +* channel - The wifi channel used (an integer, typ 1..14) + +*/ + +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "auth_change", + "params" : [ + ["details","JsVar","An object with event details"] + ] +} +The 'auth_change' event is called when the authentication mode with the associated access point changes. +The details include: + +* oldMode - The old auth mode (string: open, wep, wpa, wpa2, wpa_wpa2) +* newMode - The new auth mode (string: open, wep, wpa, wpa2, wpa_wpa2) + +*/ + +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "dhcp_timeout" +} +The 'dhcp_timeout' event is called when a DHCP request to the connected access point fails and thus no IP address could be acquired (or renewed). +*/ + +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "connected", + "params" : [ + ["details","JsVar","An object with event details"] + ] +} +The 'connected' event is called when the connection with an access point is ready for traffic. In the case of a dynamic IP address configuration this is when an IP address is obtained, in the case of static IP address allocation this happens when an association is formed (in that case the 'associated' and 'connected' events are fired in rapid succession). +The details include: + +* ip - The IP address obtained as string +* netmask - The network's IP range mask as string +* gw - The network's default gateway as string + +*/ + +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "sta_joined", + "params" : [ + ["details","JsVar","An object with event details"] + ] +} +The 'sta_joined' event is called when a station establishes an association (i.e. connects) with the esp8266's access point. +The details include: + +* mac - The MAC address of the station in string format (00:00:00:00:00:00) + +*/ + +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "sta_left", + "params" : [ + ["details","JsVar","An object with event details"] + ] +} +The 'sta_left' event is called when a station disconnects from the esp8266's access point (or its association times out?). +The details include: + +* mac - The MAC address of the station in string format (00:00:00:00:00:00) + +*/ + +/*JSON{ + "type" : "event", + "class" : "Wifi", + "name" : "probe_recv", + "params" : [ + ["details","JsVar","An object with event details"] + ] +} +The 'probe_recv' event is called when a probe request is received from some station by the esp8266's access point. +The details include: + +* mac - The MAC address of the station in string format (00:00:00:00:00:00) +* rssi - The signal strength in dB of the probe request + +*/ + /** Get the global object for the Wifi library/module, this is used in order to send the * "on event" callbacks to the handlers. */ @@ -55,9 +159,31 @@ static JsVar *getWifiModule() { JsVar *m = jswrap_require(moduleName); jsvUnLock(moduleName); return m; -} - +} // End of getWifiModule +/** + * Given an ESP32 WiFi event type, determine the corresponding + * event handler name we should publish upon. For example, if we + * have an event of type "SYSTEM_EVENT_STA_CONNECTED" then we wish + * to publish an event upon "#onassociated". The implementation + * here is a simple switch as at this time we don't want to assume + * anything about the values of event types (i.e. whether they are small + * and sequential). If we could make assumptions about the event + * types we may have been able to use a lookup array. + * + * The mappings are: + * SYSTEM_EVENT_AP_PROBEREQRECVED - #onprobe_recv + * SYSTEM_EVENT_AP_STACONNECTED - #onsta_joined + * SYSTEM_EVENT_AP_STADISCONNECTED - #onsta_left + * SYSTEM_EVENT_STA_AUTHMODE_CHANGE - #onauth_change + * SYSTEM_EVENT_STA_CONNECTED - #onassociated + * SYSTEM_EVENT_STA_DISCONNECTED - #ondisconnected + * SYSTEM_EVENT_STA_GOT_IP - #onconnected + * + * See also: + * * event_handler() + * + */ static char *wifiGetEvent(uint32_t event) { switch(event) { case SYSTEM_EVENT_AP_PROBEREQRECVED: @@ -89,7 +215,7 @@ static char *wifiGetEvent(uint32_t event) { } ESP_LOGW(tag, "Unhandled event type: %d", event); return NULL; -} +} // End of wifiGetEvent /** * Invoke the JavaScript callback to notify the program that an ESP8266 @@ -111,6 +237,7 @@ static void sendWifiEvent( if (eventName == NULL) { return; } + ESP_LOGD(tag, "wifi.on(%s)\n", eventName); jsiQueueObjectCallbacks(module, eventName, params, 1); jsvUnLock(module); @@ -126,6 +253,14 @@ static void sendWifiEvent( static esp_err_t event_handler(void *ctx, system_event_t *event) { ESP_LOGD(tag, ">> event_handler"); + /* + * SYSTEM_EVENT_STA_DISCONNECT + * Structure contains: + * * ssid + * * ssid_len + * * bssid + * * reason + */ if (event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) { if (jsvIsFunction(g_jsDisconnectCallback)) { jsiQueueEvents(NULL, g_jsDisconnectCallback, NULL, 0); @@ -153,6 +288,39 @@ static esp_err_t event_handler(void *ctx, system_event_t *event) return ESP_OK; } // End of handle SYSTEM_EVENT_STA_DISCONNECTED + /** + * SYSTEM_EVENT_STA_CONNECTED + * Structure contains: + * * ssid + * * ssid_len + * * bssid + * * channel + * * authmode + */ + if (event->event_id == SYSTEM_EVENT_STA_CONNECTED) { + // Publish the on("associated") event to any one who has registered + // an interest. + JsVar *jsDetails = jsvNewObject(); + + char temp[33]; + memcpy(temp, event->event_info.connected.ssid, 32); + temp[32] = '\0'; + jsvObjectSetChildAndUnLock(jsDetails, "ssid", jsvNewFromString(temp)); + sprintf(temp, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + event->event_info.connected.bssid[0], + event->event_info.connected.bssid[1], + event->event_info.connected.bssid[2], + event->event_info.connected.bssid[3], + event->event_info.connected.bssid[4], + event->event_info.connected.bssid[5]); + jsvObjectSetChildAndUnLock(jsDetails, "mac", jsvNewFromString(temp)); + sprintf(temp, "%d", event->event_info.connected.channel); + jsvObjectSetChildAndUnLock(jsDetails, "channel", jsvNewFromString(temp)); + sendWifiEvent(event->event_id, jsDetails); + ESP_LOGD(tag, "<< event_handler - STA CONNECTED"); + return ESP_OK; + } // End of handle SYSTEM_EVENT_STA_CONNECTED + if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) { sendWifiCompletionCB(&g_jsGotIpCallback, NULL); diff --git a/targets/esp32/tests/mqttclient.js b/targets/esp32/tests/mqttclient.js new file mode 100644 index 000000000..3456f4619 --- /dev/null +++ b/targets/esp32/tests/mqttclient.js @@ -0,0 +1,18 @@ +var ssid="RASPI3"; +var password="password"; + +var wifi=require("Wifi"); +wifi.connect(ssid, {password: password}, function() { + console.log("Connected to access point"); + var mqtt = require("MQTT").create("192.168.5.1"); + mqtt.on("connected", function() { + console.log("MQTT connected"); + mqtt.subscribe("test"); + mqtt.on('publish', function (pub) { + console.log("topic: "+pub.topic); + console.log("message: "+pub.message); + }); + }); + console.log("Doing a connect"); + mqtt.connect(); +}); \ No newline at end of file diff --git a/targets/esp32/tests/wifiEvents.js b/targets/esp32/tests/wifiEvents.js new file mode 100644 index 000000000..25b129584 --- /dev/null +++ b/targets/esp32/tests/wifiEvents.js @@ -0,0 +1,32 @@ +// Test ESP32 WiFi event callbacks +var ssid="RASPI3"; +var password="password"; + +var wifi=require("Wifi"); +wifi.on("associated", function(details) { + console.log("Event-> associated: " + JSON.stringify(details)); +}); +wifi.on("connected", function(details) { + console.log("Event-> connected: " + JSON.stringify(details)); +}); +wifi.on("disconnected", function(details) { + console.log("Event-> disconnected: " + JSON.stringify(details)); +}); +wifi.on("auth_change", function(details) { + console.log("Event-> auth_change: " + JSON.stringify(details)); +}); +wifi.on("dhcp_timeout", function(details) { + console.log("Event-> dhcp_timeout: " + JSON.stringify(details)); +}); +wifi.on("probe_recv", function(details) { + console.log("Event-> probe_recv: " + JSON.stringify(details)); +}); +wifi.on("sta_joined", function(details) { + console.log("Event-> sta_joined: " + JSON.stringify(details)); +}); +wifi.on("sta_left", function(details) { + console.log("Event-> sta_left: " + JSON.stringify(details)); +}); +wifi.connect(ssid, {password: password}, function() { + console.log("Connect completed"); +}); \ No newline at end of file