From 808bf50ff22ce20286ceb6ffd7db868feca091a3 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 6 Feb 2017 13:24:34 +0300 Subject: [PATCH] wifi: add SoftAPModeProbeRequestReceived event handler (#2917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add probe request event handler (#2910) - update WiFi events handling example to use new handler Pro tip: replace blinking LED with ‘analogWrite’ and connect the pin to a loudspeaker (or use a servo to hit a bell). Get notified when someone with a smartphone wanders around your country house. --- .../WiFiClientEvents/WiFiClientEvents.ino | 52 ---------- .../examples/WiFiEvents/WiFiEvents.ino | 99 +++++++++++++++++++ .../ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 13 +++ .../ESP8266WiFi/src/ESP8266WiFiGeneric.h | 1 + 4 files changed, 113 insertions(+), 52 deletions(-) delete mode 100644 libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino create mode 100644 libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino diff --git a/libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino b/libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino deleted file mode 100644 index 249e896e93..0000000000 --- a/libraries/ESP8266WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This sketch shows the WiFi event usage - * - */ - -#include - -const char* ssid = "your-ssid"; -const char* password = "your-password"; - - -void WiFiEvent(WiFiEvent_t event) { - Serial.printf("[WiFi-event] event: %d\n", event); - - switch(event) { - case WIFI_EVENT_STAMODE_GOT_IP: - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - break; - case WIFI_EVENT_STAMODE_DISCONNECTED: - Serial.println("WiFi lost connection"); - break; - } -} - -void setup() { - Serial.begin(115200); - - // delete old config - WiFi.disconnect(true); - - delay(1000); - - WiFi.onEvent(WiFiEvent); - - /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default, - would try to act as both a client and an access-point and could cause - network-issues with your other WiFi-devices on your WiFi-network. */ - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - - Serial.println(); - Serial.println(); - Serial.println("Wait for WiFi... "); -} - - -void loop() { - delay(1000); -} - diff --git a/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino b/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino new file mode 100644 index 0000000000..f050e9d60c --- /dev/null +++ b/libraries/ESP8266WiFi/examples/WiFiEvents/WiFiEvents.ino @@ -0,0 +1,99 @@ +/* + This sketch shows how to use WiFi event handlers. + + In this example, ESP8266 works in AP mode. + Three event handlers are demonstrated: + - station connects to the ESP8266 AP + - station disconnects from the ESP8266 AP + - ESP8266 AP receives a probe request from a station + + Written by Markus Sattler, 2015-12-29. + Updated for new event handlers by Ivan Grokhotkov, 2017-02-02. + This example is released into public domain, + or, at your option, CC0 licensed. +*/ + +#include +#include + +const char* ssid = "ap-ssid"; +const char* password = "ap-password"; + +WiFiEventHandler stationConnectedHandler; +WiFiEventHandler stationDisconnectedHandler; +WiFiEventHandler probeRequestPrintHandler; +WiFiEventHandler probeRequestBlinkHandler; + +bool blinkFlag; + +void setup() { + Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + + // Don't save WiFi configuration in flash - optional + WiFi.persistent(false); + + // Set up an access point + WiFi.mode(WIFI_AP); + WiFi.softAP(ssid, password); + + // Register event handlers. + // Callback functions will be called as long as these handler objects exist. + // Call "onStationConnected" each time a station connects + stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected); + // Call "onStationDisconnected" each time a station disconnects + stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected); + // Call "onProbeRequestPrint" and "onProbeRequestBlink" each time + // a probe request is received. + // Former will print MAC address of the station and RSSI to Serial, + // latter will blink an LED. + probeRequestPrintHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestPrint); + probeRequestBlinkHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestBlink); +} + +void onStationConnected(const WiFiEventSoftAPModeStationConnected& evt) { + Serial.print("Station connected: "); + Serial.println(macToString(evt.mac)); +} + +void onStationDisconnected(const WiFiEventSoftAPModeStationDisconnected& evt) { + Serial.print("Station disconnected: "); + Serial.println(macToString(evt.mac)); +} + +void onProbeRequestPrint(const WiFiEventSoftAPModeProbeRequestReceived& evt) { + Serial.print("Probe request from: "); + Serial.print(macToString(evt.mac)); + Serial.print(" RSSI: "); + Serial.println(evt.rssi); +} + +void onProbeRequestBlink(const WiFiEventSoftAPModeProbeRequestReceived&) { + // We can't use "delay" or other blocking functions in the event handler. + // Therefore we set a flag here and then check it inside "loop" function. + blinkFlag = true; +} + +void loop() { + if (millis() > 10000 && probeRequestPrintHandler) { + // After 10 seconds, disable the probe request event handler which prints. + // Other three event handlers remain active. + Serial.println("Not printing probe requests any more (LED should still blink)"); + probeRequestPrintHandler = WiFiEventHandler(); + } + if (blinkFlag) { + blinkFlag = false; + digitalWrite(LED_BUILTIN, LOW); + delay(100); + digitalWrite(LED_BUILTIN, HIGH); + } + delay(10); +} + +String macToString(const unsigned char* mac) { + char buf[20]; + snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(buf); +} diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index b8e8b08f1b..01d32920f3 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -186,6 +186,19 @@ WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationDisconnected(std::f return handler; } +WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeProbeRequestReceived(std::function f) +{ + WiFiEventHandler handler = std::make_shared(WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED, [f](System_Event_t* e){ + auto& src = e->event_info.ap_probereqrecved; + WiFiEventSoftAPModeProbeRequestReceived dst; + memcpy(dst.mac, src.mac, 6); + dst.rssi = src.rssi; + f(dst); + }); + sCbEventList.push_back(handler); + return handler; +} + // WiFiEventHandler ESP8266WiFiGenericClass::onWiFiModeChange(std::function f) // { // WiFiEventHandler handler = std::make_shared(WIFI_EVENT_MODE_CHANGE, [f](System_Event_t* e){ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h index 335d416b55..3ece467b05 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h @@ -61,6 +61,7 @@ class ESP8266WiFiGenericClass { WiFiEventHandler onStationModeDHCPTimeout(std::function); WiFiEventHandler onSoftAPModeStationConnected(std::function); WiFiEventHandler onSoftAPModeStationDisconnected(std::function); + WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function); // WiFiEventHandler onWiFiModeChange(std::function); int32_t channel(void);