This commit is contained in:
me-no-dev
2020-05-17 11:48:31 +03:00
parent a761281d8c
commit ecc96060da
10 changed files with 949 additions and 627 deletions

View File

@ -190,7 +190,7 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
} }
//RTC pins PULL settings //RTC pins PULL settings
if(rtc_reg) { if(esp32_gpioMux[pin].rtc != -1) {
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin].mux); ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[pin].mux);
if(mode & PULLUP) { if(mode & PULLUP) {
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[pin].pullup) & ~(rtc_io_desc[pin].pulldown); ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[pin].pullup) & ~(rtc_io_desc[pin].pulldown);

View File

@ -70,34 +70,6 @@ extern void tcpipInit();
// Event handler for Ethernet
void ETHClass::eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
system_event_t event;
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
event.event_id = SYSTEM_EVENT_ETH_CONNECTED;
((ETHClass*)(arg))->eth_link = ETH_LINK_UP;
break;
case ETHERNET_EVENT_DISCONNECTED:
event.event_id = SYSTEM_EVENT_ETH_DISCONNECTED;
((ETHClass*)(arg))->eth_link = ETH_LINK_DOWN;
break;
case ETHERNET_EVENT_START:
event.event_id = SYSTEM_EVENT_ETH_START;
((ETHClass*)(arg))->started = true;
break;
case ETHERNET_EVENT_STOP:
event.event_id = SYSTEM_EVENT_ETH_STOP;
((ETHClass*)(arg))->started = false;
break;
default:
break;
}
WiFi._eventCallback(arg, &event);
}
#else #else
static int _eth_phy_mdc_pin = -1; static int _eth_phy_mdc_pin = -1;
static int _eth_phy_mdio_pin = -1; static int _eth_phy_mdio_pin = -1;
@ -144,9 +116,6 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
tcpipInit(); tcpipInit();
tcpip_adapter_set_default_eth_handlers(); tcpip_adapter_set_default_eth_handlers();
esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, this);
//ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
esp_eth_mac_t *eth_mac = NULL; esp_eth_mac_t *eth_mac = NULL;
#if CONFIG_ETH_SPI_ETHERNET_DM9051 #if CONFIG_ETH_SPI_ETHERNET_DM9051
if(type == ETH_PHY_DM9051){ if(type == ETH_PHY_DM9051){

View File

@ -46,6 +46,8 @@ extern "C" {
// ---------------------------------------------------- Private functions ------------------------------------------------ // ---------------------------------------------------- Private functions ------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress());
static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs); static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
@ -76,6 +78,25 @@ static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& r
return true; return true;
} }
void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, const char * password=NULL, uint8_t channel=6, wifi_auth_mode_t authmode=WIFI_AUTH_WPA_WPA2_PSK, uint8_t ssid_hidden=0, uint8_t max_connections=4, uint16_t beacon_interval=100){
wifi_config->ap.channel = channel;
wifi_config->ap.max_connection = max_connections;
wifi_config->ap.beacon_interval = beacon_interval;
wifi_config->ap.ssid_hidden = ssid_hidden;
wifi_config->ap.authmode = WIFI_AUTH_OPEN;
wifi_config->ap.ssid_len = 0;
wifi_config->ap.ssid[0] = 0;
wifi_config->ap.password[0] = 0;
if(ssid != NULL && ssid[0] != 0){
snprintf((char*)wifi_config->ap.ssid, 32, ssid);
wifi_config->ap.ssid_len = strlen(ssid);
if(password != NULL && password[0] != 0){
wifi_config->ap.authmode = authmode;
snprintf((char*)wifi_config->ap.password, 64, password);
}
}
}
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------- AP function ----------------------------------------------------- // ----------------------------------------------------- AP function -----------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
@ -110,29 +131,21 @@ bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel,
return false; return false;
} }
esp_wifi_start();
wifi_config_t conf; wifi_config_t conf;
strlcpy(reinterpret_cast<char*>(conf.ap.ssid), ssid, sizeof(conf.ap.ssid));
conf.ap.channel = channel;
conf.ap.ssid_len = strlen(reinterpret_cast<char *>(conf.ap.ssid));
conf.ap.ssid_hidden = ssid_hidden;
conf.ap.max_connection = max_connection;
conf.ap.beacon_interval = 100;
if(!passphrase || strlen(passphrase) == 0) {
conf.ap.authmode = WIFI_AUTH_OPEN;
*conf.ap.password = 0;
} else {
conf.ap.authmode = WIFI_AUTH_WPA2_PSK;
strlcpy(reinterpret_cast<char*>(conf.ap.password), passphrase, sizeof(conf.ap.password));
}
wifi_config_t conf_current; wifi_config_t conf_current;
esp_wifi_get_config(WIFI_IF_AP, &conf_current); wifi_softap_config(&conf, ssid, passphrase, channel, WIFI_AUTH_WPA_WPA2_PSK, ssid_hidden, max_connection);
if(!softap_config_equal(conf, conf_current) && esp_wifi_set_config(WIFI_IF_AP, &conf) != ESP_OK) { esp_err_t err = esp_wifi_get_config(WIFI_IF_AP, &conf_current);
if(err){
log_e("get AP config failed");
return false; return false;
} }
if(!softap_config_equal(conf, conf_current)) {
err = esp_wifi_set_config(WIFI_IF_AP, &conf);
if(err){
log_e("set AP config failed");
return false;
}
}
return true; return true;
} }
@ -146,34 +159,15 @@ bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel,
*/ */
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
{ {
esp_err_t err = ESP_OK;
if(!WiFi.enableAP(true)) { if(!WiFi.enableAP(true)) {
// enable AP failed // enable AP failed
return false; return false;
} }
esp_wifi_start(); err = set_esp_interface_ip(ESP_IF_WIFI_AP, local_ip, gateway, subnet);
return err == ESP_OK;
tcpip_adapter_ip_info_t info;
info.ip.addr = static_cast<uint32_t>(local_ip);
info.gw.addr = static_cast<uint32_t>(gateway);
info.netmask.addr = static_cast<uint32_t>(subnet);
tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP);
if(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info) == ESP_OK) {
dhcps_lease_t lease;
lease.enable = true;
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (11 << 24);
tcpip_adapter_dhcps_option(
(tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET,
(tcpip_adapter_dhcp_option_id_t)REQUESTED_IP_ADDRESS,
(void*)&lease, sizeof(dhcps_lease_t)
);
return tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP) == ESP_OK;
}
return false;
} }
@ -187,17 +181,15 @@ bool WiFiAPClass::softAPdisconnect(bool wifioff)
{ {
bool ret; bool ret;
wifi_config_t conf; wifi_config_t conf;
wifi_softap_config(&conf);
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return ESP_ERR_INVALID_STATE; return false;
} }
*conf.ap.ssid = 0;
*conf.ap.password = 0;
conf.ap.authmode = WIFI_AUTH_OPEN; // auth must be open if pass=0
ret = esp_wifi_set_config(WIFI_IF_AP, &conf) == ESP_OK; ret = esp_wifi_set_config(WIFI_IF_AP, &conf) == ESP_OK;
if(wifioff) { if(ret && wifioff) {
ret = WiFi.enableAP(false) == ESP_OK; ret = WiFi.enableAP(false) == ESP_OK;
} }
@ -227,11 +219,14 @@ uint8_t WiFiAPClass::softAPgetStationNum()
*/ */
IPAddress WiFiAPClass::softAPIP() IPAddress WiFiAPClass::softAPIP()
{ {
tcpip_adapter_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip); esp_netif_ip_info_t ip;
if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return IPAddress(ip.ip.addr); return IPAddress(ip.ip.addr);
} }
@ -241,11 +236,14 @@ IPAddress WiFiAPClass::softAPIP()
*/ */
IPAddress WiFiAPClass::softAPBroadcastIP() IPAddress WiFiAPClass::softAPBroadcastIP()
{ {
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
} }
@ -255,11 +253,14 @@ IPAddress WiFiAPClass::softAPBroadcastIP()
*/ */
IPAddress WiFiAPClass::softAPNetworkID() IPAddress WiFiAPClass::softAPNetworkID()
{ {
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
} }
@ -269,11 +270,14 @@ IPAddress WiFiAPClass::softAPNetworkID()
*/ */
uint8_t WiFiAPClass::softAPSubnetCIDR() uint8_t WiFiAPClass::softAPSubnetCIDR()
{ {
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return (uint8_t)0; return IPAddress();
}
if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
} }
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr));
} }
@ -317,8 +321,8 @@ const char * WiFiAPClass::softAPgetHostname()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return hostname; return hostname;
} }
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_AP, &hostname)) { if(esp_netif_get_hostname(get_esp_interface_netif(ESP_IF_WIFI_AP), &hostname) != ESP_OK){
return hostname; log_e("Netif Get Hostname Failed!");
} }
return hostname; return hostname;
} }
@ -333,7 +337,7 @@ bool WiFiAPClass::softAPsetHostname(const char * hostname)
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false; return false;
} }
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP, hostname) == ESP_OK; return esp_netif_set_hostname(get_esp_interface_netif(ESP_IF_WIFI_AP), hostname) == ESP_OK;
} }
/** /**
@ -345,7 +349,7 @@ bool WiFiAPClass::softAPenableIpV6()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false; return false;
} }
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_AP) == ESP_OK; return esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_AP)) == ESP_OK;
} }
/** /**
@ -354,11 +358,11 @@ bool WiFiAPClass::softAPenableIpV6()
*/ */
IPv6Address WiFiAPClass::softAPIPv6() IPv6Address WiFiAPClass::softAPIPv6()
{ {
static ip6_addr_t addr; esp_ip6_addr_t addr;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPv6Address(); return IPv6Address();
} }
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_AP, &addr)) { if(esp_netif_get_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_AP), &addr)) {
return IPv6Address(); return IPv6Address();
} }
return IPv6Address(addr.addr); return IPv6Address(addr.addr);

View File

@ -40,6 +40,7 @@ extern "C" {
#include "lwip/opt.h" #include "lwip/opt.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "dhcpserver/dhcpserver_options.h"
#include "esp_ipc.h" #include "esp_ipc.h"
} //extern "C" } //extern "C"
@ -48,135 +49,519 @@ extern "C" {
#include <vector> #include <vector>
#include "sdkconfig.h" #include "sdkconfig.h"
static xQueueHandle _network_event_queue; ESP_EVENT_DEFINE_BASE(ARDUINO_EVENTS);
static TaskHandle_t _network_event_task_handle = NULL; /*
static EventGroupHandle_t _network_event_group = NULL; * Private (exposable) methods
* */
static esp_netif_t* esp_netifs[ESP_IF_MAX] = {NULL, NULL, NULL};
esp_interface_t get_esp_netif_interface(esp_netif_t* esp_netif){
for(int i=0; i<ESP_IF_MAX; i++){
if(esp_netifs[i] != NULL && esp_netifs[i] == esp_netif){
return (esp_interface_t)i;
}
}
return ESP_IF_MAX;
}
esp_err_t postToSysQueue(system_prov_event_t *data) void add_esp_interface_netif(esp_interface_t interface, esp_netif_t* esp_netif){
{ if(interface < ESP_IF_MAX){
if (xQueueSend(_network_event_queue, &data, portMAX_DELAY) != pdPASS) { esp_netifs[interface] = esp_netif;
log_w("Network Event Queue Send Failed!"); }
}
esp_netif_t* get_esp_interface_netif(esp_interface_t interface){
if(interface < ESP_IF_MAX){
return esp_netifs[interface];
}
return NULL;
}
esp_err_t set_esp_interface_hostname(esp_interface_t interface, const char * hostname){
if(interface < ESP_IF_MAX){
return esp_netif_set_hostname(esp_netifs[interface], hostname);
}
return ESP_FAIL; return ESP_FAIL;
} }
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress()){
esp_netif_t *esp_netif = esp_netifs[interface];
esp_netif_dhcp_status_t status = ESP_NETIF_DHCP_INIT;
esp_netif_ip_info_t info;
info.ip.addr = static_cast<uint32_t>(local_ip);
info.gw.addr = static_cast<uint32_t>(gateway);
info.netmask.addr = static_cast<uint32_t>(subnet);
esp_err_t err = ESP_OK;
if(interface != ESP_IF_WIFI_AP){
err = esp_netif_dhcpc_get_status(esp_netif, &status);
if(err){
log_e("DHCPC Get Status Failed! 0x%04x", err);
return err;
}
err = esp_netif_dhcpc_stop(esp_netif);
if(err){
log_e("DHCPC Stop Failed! 0x%04x", err);
return err;
}
err = esp_netif_set_ip_info(esp_netif, &info);
if(err){
log_e("Netif Set IP Failed! 0x%04x", err);
return err;
}
if(info.ip.addr == 0){
err = esp_netif_dhcpc_start(esp_netif);
if(err){
log_e("DHCPC Start Failed! 0x%04x", err);
return err;
}
}
} else {
err = esp_netif_dhcps_get_status(esp_netif, &status);
if(err){
log_e("DHCPS Get Status Failed! 0x%04x", err);
return err;
}
err = esp_netif_dhcps_stop(esp_netif);
if(err){
log_e("DHCPS Stop Failed! 0x%04x", err);
return err;
}
err = esp_netif_set_ip_info(esp_netif, &info);
if(err){
log_e("Netif Set IP Failed! 0x%04x", err);
return err;
}
dhcps_lease_t lease;
lease.enable = true;
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (11 << 24);
err = tcpip_adapter_dhcps_option(
(tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET,
(tcpip_adapter_dhcp_option_id_t)REQUESTED_IP_ADDRESS,
(void*)&lease, sizeof(dhcps_lease_t)
);
if(err){
log_e("DHCPS Set Lease Failed! 0x%04x", err);
return err;
}
err = esp_netif_dhcps_start(esp_netif);
if(err){
log_e("DHCPS Start Failed! 0x%04x", err);
return err;
}
}
return err;
}
esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns=IPAddress(), IPAddress backup_dns=IPAddress(), IPAddress fallback_dns=IPAddress()){
esp_netif_t *esp_netif = esp_netifs[interface];
esp_netif_dns_info_t dns;
dns.ip.type = ESP_IPADDR_TYPE_V4;
dns.ip.u_addr.ip4.addr = static_cast<uint32_t>(main_dns);
if(dns.ip.u_addr.ip4.addr && esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_MAIN, &dns) != ESP_OK){
log_e("Set Main DNS Failed!");
return ESP_FAIL;
}
if(interface != ESP_IF_WIFI_AP){
dns.ip.u_addr.ip4.addr = static_cast<uint32_t>(backup_dns);
if(dns.ip.u_addr.ip4.addr && esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_BACKUP, &dns) != ESP_OK){
log_e("Set Backup DNS Failed!");
return ESP_FAIL;
}
dns.ip.u_addr.ip4.addr = static_cast<uint32_t>(fallback_dns);
if(dns.ip.u_addr.ip4.addr && esp_netif_set_dns_info(esp_netif, ESP_NETIF_DNS_FALLBACK, &dns) != ESP_OK){
log_e("Set Fallback DNS Failed!");
return ESP_FAIL;
}
}
return ESP_OK; return ESP_OK;
} }
static void _network_event_task(void * arg){ static const char * auth_mode_str(int authmode)
system_prov_event_t *data; {
for (;;) { switch (authmode) {
if(xQueueReceive(_network_event_queue, &data, portMAX_DELAY) == pdTRUE){ case WIFI_AUTH_OPEN:
if(data->prov_event != NULL){ return ("OPEN");
WiFiGenericClass::_eventCallback(arg, data->sys_event, data->prov_event); break;
free(data->sys_event); case WIFI_AUTH_WEP:
free(data->prov_event); return ("WEP");
} else { break;
WiFiGenericClass::_eventCallback(arg, data->sys_event, NULL); case WIFI_AUTH_WPA_PSK:
return ("PSK");
break;
case WIFI_AUTH_WPA2_PSK:
return ("WPA2_PSK");
break;
case WIFI_AUTH_WPA_WPA2_PSK:
return ("WPA_WPA2_PSK");
break;
case WIFI_AUTH_WPA2_ENTERPRISE:
return ("WPA2_ENTERPRISE");
break;
default:
break;
} }
return ("UNKNOWN");
}
static char default_hostname[32] = {0,};
static const char * get_esp_netif_hostname(){
if(default_hostname[0] == 0){
uint8_t eth_mac[6];
esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
snprintf(default_hostname, 32, "%s%02X%02X%02X", CONFIG_IDF_TARGET "-", eth_mac[3], eth_mac[4], eth_mac[5]);
}
return (const char *)default_hostname;
}
static void set_esp_netif_hostname(const char * name){
if(name){
snprintf(default_hostname, 32, "%s", name);
}
}
static xQueueHandle _arduino_event_queue;
static TaskHandle_t _arduino_event_task_handle = NULL;
static EventGroupHandle_t _arduino_event_group = NULL;
static void _arduino_event_task(void * arg){
arduino_event_t *data = NULL;
for (;;) {
if(xQueueReceive(_arduino_event_queue, &data, portMAX_DELAY) == pdTRUE){
WiFiGenericClass::_eventCallback(data);
free(data); free(data);
data = NULL;
} }
} }
vTaskDelete(NULL); vTaskDelete(NULL);
_network_event_task_handle = NULL; _arduino_event_task_handle = NULL;
} }
static esp_err_t _network_event_cb(void* arg, system_event_t *event) { esp_err_t postArduinoEvent(arduino_event_t *data)
system_prov_event_t *sys_prov_data = (system_prov_event_t *)malloc(sizeof(system_prov_event_t)); {
if(sys_prov_data == NULL) { if(data == NULL){
return ESP_FAIL; return ESP_FAIL;
} }
sys_prov_data->sys_event = event; arduino_event_t * event = (arduino_event_t*)malloc(sizeof(arduino_event_t));
sys_prov_data->prov_event = NULL; if(event == NULL){
if (postToSysQueue(sys_prov_data) != ESP_OK){ log_e("Arduino Event Malloc Failed!");
free(sys_prov_data); return ESP_FAIL;
}
memcpy(event, data, sizeof(arduino_event_t));
if (xQueueSend(_arduino_event_queue, &event, portMAX_DELAY) != pdPASS) {
log_e("Arduino Event Send Failed!");
return ESP_FAIL; return ESP_FAIL;
} }
return ESP_OK; return ESP_OK;
} }
static void _network_event_cb(void* arg, esp_event_base_t base, int32_t id, void* data) { static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
system_event_t *event = (system_event_t *)data; arduino_event_t arduino_event;
if(_network_event_cb(arg, event) != ESP_OK){ arduino_event.event_id = ARDUINO_EVENT_MAX;
log_e("event dispatch failed");
/*
* STA
* */
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
log_v("STA Started");
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_START;
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_STOP) {
log_v("STA Stopped");
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_STOP;
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) {
wifi_event_sta_authmode_change_t * event = (wifi_event_sta_authmode_change_t*)event_data;
log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode));
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE;
memcpy(&arduino_event.event_info.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
wifi_event_sta_connected_t * event = (wifi_event_sta_connected_t*)event_data;
log_v("STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode));
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_CONNECTED;
memcpy(&arduino_event.event_info.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
wifi_event_sta_disconnected_t * event = (wifi_event_sta_disconnected_t*)event_data;
log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason);
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_DISCONNECTED;
memcpy(&arduino_event.event_info.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t));
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
log_v("STA Got %sIP:" IPSTR, event->ip_changed?"New ":"Same ", IP2STR(&event->ip_info.ip));
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP;
memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t));
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_LOST_IP) {
log_v("STA IP Lost");
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP;
/*
* SCAN
* */
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
wifi_event_sta_scan_done_t * event = (wifi_event_sta_scan_done_t*)event_data;
log_v("SCAN Done: ID: %u, Status: %u, Results: %u", event->scan_id, event->status, event->number);
arduino_event.event_id = ARDUINO_EVENT_WIFI_SCAN_DONE;
memcpy(&arduino_event.event_info.wifi_scan_done, event_data, sizeof(wifi_event_sta_scan_done_t));
/*
* AP
* */
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START) {
log_v("AP Started");
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_START;
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STOP) {
log_v("AP Stopped");
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STOP;
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_PROBEREQRECVED) {
wifi_event_ap_probe_req_rx_t * event = (wifi_event_ap_probe_req_rx_t*)event_data;
log_v("AP Probe Request: RSSI: %d, MAC: " MACSTR, event->rssi, MAC2STR(event->mac));
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED;
memcpy(&arduino_event.event_info.wifi_ap_probereqrecved, event_data, sizeof(wifi_event_ap_probe_req_rx_t));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
log_v("AP Station Connected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid);
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STACONNECTED;
memcpy(&arduino_event.event_info.wifi_ap_staconnected, event_data, sizeof(wifi_event_ap_staconnected_t));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
log_v("AP Station Disconnected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid);
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STADISCONNECTED;
memcpy(&arduino_event.event_info.wifi_ap_stadisconnected, event_data, sizeof(wifi_event_ap_stadisconnected_t));
} else if (event_base == IP_EVENT && event_id == IP_EVENT_AP_STAIPASSIGNED) {
ip_event_ap_staipassigned_t * event = (ip_event_ap_staipassigned_t*)event_data;
log_v("AP Station IP Assigned:" IPSTR, IP2STR(&event->ip));
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED;
memcpy(&arduino_event.event_info.wifi_ap_staipassigned, event_data, sizeof(ip_event_ap_staipassigned_t));
/*
* ETH
* */
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_CONNECTED) {
log_v("Ethernet Link Up");
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
arduino_event.event_id = ARDUINO_EVENT_ETH_CONNECTED;
memcpy(&arduino_event.event_info.eth_connected, event_data, sizeof(esp_eth_handle_t));
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_DISCONNECTED) {
log_v("Ethernet Link Down");
arduino_event.event_id = ARDUINO_EVENT_ETH_DISCONNECTED;
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_START) {
log_v("Ethernet Started");
arduino_event.event_id = ARDUINO_EVENT_ETH_START;
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_STOP) {
log_v("Ethernet Stopped");
arduino_event.event_id = ARDUINO_EVENT_ETH_STOP;
} else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
log_v("Ethernet got %sip:" IPSTR, event->ip_changed?"new":"", IP2STR(&event->ip_info.ip));
arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP;
memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t));
/*
* IPv6
* */
} else if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) {
ip_event_got_ip6_t * event = (ip_event_got_ip6_t*)event_data;
esp_interface_t iface = get_esp_netif_interface(event->esp_netif);
log_v("IF[%d] Got IPv6: IP Index: %d, Zone: %d, " IPV6STR, iface, event->ip_index, event->ip6_info.ip.zone, IPV62STR(event->ip6_info.ip));
memcpy(&arduino_event.event_info.got_ip6, event_data, sizeof(ip_event_got_ip6_t));
if(iface == ESP_IF_WIFI_STA){
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP6;
} else if(iface == ESP_IF_WIFI_AP){
arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_GOT_IP6;
} else if(iface == ESP_IF_ETH){
arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6;
}
/*
* WPS
* */
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_SUCCESS) {
arduino_event.event_id = ARDUINO_EVENT_WPS_ER_SUCCESS;
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_FAILED) {
wifi_event_sta_wps_fail_reason_t * event = (wifi_event_sta_wps_fail_reason_t*)event_data;
arduino_event.event_id = ARDUINO_EVENT_WPS_ER_FAILED;
memcpy(&arduino_event.event_info.wps_fail_reason, event_data, sizeof(wifi_event_sta_wps_fail_reason_t));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_TIMEOUT) {
arduino_event.event_id = ARDUINO_EVENT_WPS_ER_TIMEOUT;
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_PIN) {
wifi_event_sta_wps_er_pin_t * event = (wifi_event_sta_wps_er_pin_t*)event_data;
arduino_event.event_id = ARDUINO_EVENT_WPS_ER_PIN;
memcpy(&arduino_event.event_info.wps_er_pin, event_data, sizeof(wifi_event_sta_wps_er_pin_t));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP) {
arduino_event.event_id = ARDUINO_EVENT_WPS_ER_PBC_OVERLAP;
/*
* SMART CONFIG
* */
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
log_v("SC Scan Done");
arduino_event.event_id = ARDUINO_EVENT_SC_SCAN_DONE;
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
log_v("SC Found Channel");
arduino_event.event_id = ARDUINO_EVENT_SC_FOUND_CHANNEL;
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
smartconfig_event_got_ssid_pswd_t *event = (smartconfig_event_got_ssid_pswd_t *)event_data;
log_v("SC: SSID: %s, Password: %s", (const char *)event->ssid, (const char *)event->password);
arduino_event.event_id = ARDUINO_EVENT_SC_GOT_SSID_PSWD;
memcpy(&arduino_event.event_info.sc_got_ssid_pswd, event_data, sizeof(smartconfig_event_got_ssid_pswd_t));
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
log_v("SC Send Ack Done");
arduino_event.event_id = ARDUINO_EVENT_SC_SEND_ACK_DONE;
/*
* Provisioning
* */
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_INIT) {
log_v("Provisioning Initialized!");
arduino_event.event_id = ARDUINO_EVENT_PROV_INIT;
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_DEINIT) {
log_v("Provisioning Uninitialized!");
arduino_event.event_id = ARDUINO_EVENT_PROV_DEINIT;
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_START) {
log_v("Provisioning Start!");
arduino_event.event_id = ARDUINO_EVENT_PROV_START;
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_END) {
log_v("Provisioning End!");
wifi_prov_mgr_deinit();
arduino_event.event_id = ARDUINO_EVENT_PROV_END;
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_CRED_RECV) {
wifi_sta_config_t *event = (wifi_sta_config_t *)event_data;
log_v("Provisioned Credentials: SSID: %s, Password: %s", (const char *) event->ssid, (const char *) event->password);
arduino_event.event_id = ARDUINO_EVENT_PROV_CRED_RECV;
memcpy(&arduino_event.event_info.prov_cred_recv, event_data, sizeof(wifi_sta_config_t));
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_CRED_FAIL) {
wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)event_data;
log_e("Provisioning Failed: Reason : %s", (*reason == WIFI_PROV_STA_AUTH_ERROR)?"Authentication Failed":"AP Not Found");
arduino_event.event_id = ARDUINO_EVENT_PROV_CRED_FAIL;
memcpy(&arduino_event.event_info.prov_fail_reason, event_data, sizeof(wifi_prov_sta_fail_reason_t));
} else if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_CRED_SUCCESS) {
log_v("Provisioning Success!");
arduino_event.event_id = ARDUINO_EVENT_PROV_CRED_SUCCESS;
}
if(arduino_event.event_id < ARDUINO_EVENT_MAX){
postArduinoEvent(&arduino_event);
} }
} }
// static esp_err_t _network_event_cb(void *arg, system_event_t *event){
// if (xQueueSend(_network_event_queue, event, portMAX_DELAY) != pdPASS) {
// log_w("Network Event Queue Send Failed!");
// return ESP_FAIL;
// }
// return ESP_OK;
// }
ESP_EVENT_DEFINE_BASE(SYSTEM_EVENT);
static bool _start_network_event_task(){ static bool _start_network_event_task(){
if(!_network_event_group){ if(!_arduino_event_group){
_network_event_group = xEventGroupCreate(); _arduino_event_group = xEventGroupCreate();
if(!_network_event_group){ if(!_arduino_event_group){
log_e("Network Event Group Create Failed!"); log_e("Network Event Group Create Failed!");
return false; return false;
} }
xEventGroupSetBits(_network_event_group, WIFI_DNS_IDLE_BIT); xEventGroupSetBits(_arduino_event_group, WIFI_DNS_IDLE_BIT);
} }
if(!_network_event_queue){ if(!_arduino_event_queue){
_network_event_queue = xQueueCreate(32, sizeof(system_prov_event_t)); _arduino_event_queue = xQueueCreate(32, sizeof(arduino_event_t*));
if(!_network_event_queue){ if(!_arduino_event_queue){
log_e("Network Event Queue Create Failed!"); log_e("Network Event Queue Create Failed!");
return false; return false;
} }
} }
if(!_network_event_task_handle){
xTaskCreateUniversal(_network_event_task, "network_event", 4096, NULL, ESP_TASKD_EVENT_PRIO - 1, &_network_event_task_handle, CONFIG_ARDUINO_EVENT_RUNNING_CORE);
if(!_network_event_task_handle){
log_e("Network Event Task Start Failed!");
return false;
}
}
esp_err_t err = esp_event_loop_create_default(); esp_err_t err = esp_event_loop_create_default();
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
log_e("esp_event_loop_create_default failed!");
return err; return err;
} }
return esp_event_handler_register(SYSTEM_EVENT, ESP_EVENT_ANY_ID, _network_event_cb, NULL) == ESP_OK; if(!_arduino_event_task_handle){
//return esp_event_loop_init(&_network_event_cb, NULL) == ESP_OK; xTaskCreateUniversal(_arduino_event_task, "arduino_events", 4096, NULL, ESP_TASKD_EVENT_PRIO - 1, &_arduino_event_task_handle, CONFIG_ARDUINO_EVENT_RUNNING_CORE);
if(!_arduino_event_task_handle){
log_e("Network Event Task Start Failed!");
return false;
}
} }
void tcpipInit(){ if(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){
log_e("event_handler_instance_register for WIFI_EVENT Failed!");
return false;
}
if(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){
log_e("event_handler_instance_register for IP_EVENT Failed!");
return false;
}
if(esp_event_handler_instance_register(SC_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){
log_e("event_handler_instance_register for SC_EVENT Failed!");
return false;
}
if(esp_event_handler_instance_register(ETH_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){
log_e("event_handler_instance_register for ETH_EVENT Failed!");
return false;
}
if(esp_event_handler_instance_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)){
log_e("event_handler_instance_register for WIFI_PROV_EVENT Failed!");
return false;
}
return true;
}
bool tcpipInit(){
static bool initialized = false; static bool initialized = false;
if(!initialized && _start_network_event_task()){ if(!initialized){
initialized = true; initialized = true;
#ifdef ESP_IDF_VERSION_MAJOR #if CONFIG_IDF_TARGET_ESP32
uint8_t mac[8]; uint8_t mac[8];
if(esp_efuse_mac_get_default(mac) == ESP_OK){ if(esp_efuse_mac_get_default(mac) == ESP_OK){
esp_base_mac_addr_set(mac); esp_base_mac_addr_set(mac);
} }
esp_event_loop_create_default();
#endif #endif
esp_netif_init(); initialized = esp_netif_init() == ESP_OK;
if(initialized){
initialized = _start_network_event_task();
} else {
log_e("esp_netif_init failed!");
} }
} }
return initialized;
}
/*
* WiFi INIT
* */
static bool lowLevelInitDone = false; static bool lowLevelInitDone = false;
static bool wifiLowLevelInit(bool persistent){ bool wifiLowLevelInit(bool persistent){
if(!lowLevelInitDone){ if(!lowLevelInitDone){
tcpipInit(); lowLevelInitDone = true;
if(!tcpipInit()){
lowLevelInitDone = false;
return lowLevelInitDone;
}
if(esp_netifs[ESP_IF_WIFI_AP] == NULL){
esp_netifs[ESP_IF_WIFI_AP] = esp_netif_create_default_wifi_ap();
}
if(esp_netifs[ESP_IF_WIFI_STA] == NULL){
esp_netifs[ESP_IF_WIFI_STA] = esp_netif_create_default_wifi_sta();
}
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_err_t err = esp_wifi_init(&cfg); esp_err_t err = esp_wifi_init(&cfg);
if(err){ if(err){
log_e("esp_wifi_init %d", err); log_e("esp_wifi_init %d", err);
return false; lowLevelInitDone = false;
return lowLevelInitDone;
} }
if(!persistent){ if(!persistent){
esp_wifi_set_storage(WIFI_STORAGE_RAM); lowLevelInitDone = esp_wifi_set_storage(WIFI_STORAGE_RAM) == ESP_OK;
} }
lowLevelInitDone = true;
} }
return true; return lowLevelInitDone;
} }
static bool wifiLowLevelDeinit(){ static bool wifiLowLevelDeinit(){
//deinit not working yet! if(lowLevelInitDone){
//esp_wifi_deinit(); lowLevelInitDone = esp_wifi_deinit() == ESP_OK;
}
return true; return true;
} }
@ -186,16 +571,14 @@ static bool espWiFiStart(){
if(_esp_wifi_started){ if(_esp_wifi_started){
return true; return true;
} }
_esp_wifi_started = true;
esp_err_t err = esp_wifi_start(); esp_err_t err = esp_wifi_start();
if (err != ESP_OK) { if (err != ESP_OK) {
_esp_wifi_started = false;
log_e("esp_wifi_start %d", err); log_e("esp_wifi_start %d", err);
return false; return _esp_wifi_started;
} }
_esp_wifi_started = true; return _esp_wifi_started;
system_event_t event;
event.event_id = SYSTEM_EVENT_WIFI_READY;
WiFiGenericClass::_eventCallback(nullptr, &event, NULL);
return true;
} }
static bool espWiFiStop(){ static bool espWiFiStop(){
@ -223,10 +606,9 @@ typedef struct WiFiEventCbList {
WiFiEventCb cb; WiFiEventCb cb;
WiFiEventFuncCb fcb; WiFiEventFuncCb fcb;
WiFiEventSysCb scb; WiFiEventSysCb scb;
WiFiProvEventCb provcb; arduino_event_id_t event;
system_event_id_t event;
WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), provcb(NULL), event(SYSTEM_EVENT_WIFI_READY) {} WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), event(ARDUINO_EVENT_WIFI_READY) {}
} WiFiEventCbList_t; } WiFiEventCbList_t;
wifi_event_id_t WiFiEventCbList::current_id = 1; wifi_event_id_t WiFiEventCbList::current_id = 1;
@ -243,33 +625,43 @@ WiFiGenericClass::WiFiGenericClass()
} }
const char * WiFiGenericClass::getHostname()
{
return get_esp_netif_hostname();
}
void WiFiGenericClass::setHostname(const char * hostname)
{
return set_esp_netif_hostname(hostname);
}
int WiFiGenericClass::setStatusBits(int bits){ int WiFiGenericClass::setStatusBits(int bits){
if(!_network_event_group){ if(!_arduino_event_group){
return 0; return 0;
} }
return xEventGroupSetBits(_network_event_group, bits); return xEventGroupSetBits(_arduino_event_group, bits);
} }
int WiFiGenericClass::clearStatusBits(int bits){ int WiFiGenericClass::clearStatusBits(int bits){
if(!_network_event_group){ if(!_arduino_event_group){
return 0; return 0;
} }
return xEventGroupClearBits(_network_event_group, bits); return xEventGroupClearBits(_arduino_event_group, bits);
} }
int WiFiGenericClass::getStatusBits(){ int WiFiGenericClass::getStatusBits(){
if(!_network_event_group){ if(!_arduino_event_group){
return 0; return 0;
} }
return xEventGroupGetBits(_network_event_group); return xEventGroupGetBits(_arduino_event_group);
} }
int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){ int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){
if(!_network_event_group){ if(!_arduino_event_group){
return 0; return 0;
} }
return xEventGroupWaitBits( return xEventGroupWaitBits(
_network_event_group, // The event group being tested. _arduino_event_group, // The event group being tested.
bits, // The bits within the event group to wait for. bits, // The bits within the event group to wait for.
pdFALSE, // BIT_0 and BIT_4 should be cleared before returning. pdFALSE, // BIT_0 and BIT_4 should be cleared before returning.
pdTRUE, // Don't wait for both bits, either bit will do. pdTRUE, // Don't wait for both bits, either bit will do.
@ -281,21 +673,7 @@ int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){
* @param cbEvent WiFiEventCb * @param cbEvent WiFiEventCb
* @param event optional filter (WIFI_EVENT_MAX is all events) * @param event optional filter (WIFI_EVENT_MAX is all events)
*/ */
wifi_event_id_t WiFiGenericClass::onEvent(WiFiProvEventCb cbEvent, system_event_id_t event) wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, arduino_event_id_t event)
{
if(!cbEvent){
return 0;
}
WiFiEventCbList_t newEventHandler;
newEventHandler.cb = NULL;
newEventHandler.fcb = NULL;
newEventHandler.scb = NULL;
newEventHandler.provcb = cbEvent;
newEventHandler.event = event;
cbEventList.push_back(newEventHandler);
return newEventHandler.id;
}
wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t event)
{ {
if(!cbEvent) { if(!cbEvent) {
return 0; return 0;
@ -304,13 +682,12 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t
newEventHandler.cb = cbEvent; newEventHandler.cb = cbEvent;
newEventHandler.fcb = NULL; newEventHandler.fcb = NULL;
newEventHandler.scb = NULL; newEventHandler.scb = NULL;
newEventHandler.provcb = NULL;
newEventHandler.event = event; newEventHandler.event = event;
cbEventList.push_back(newEventHandler); cbEventList.push_back(newEventHandler);
return newEventHandler.id; return newEventHandler.id;
} }
wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, system_event_id_t event) wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event)
{ {
if(!cbEvent) { if(!cbEvent) {
return 0; return 0;
@ -319,13 +696,12 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, system_event_
newEventHandler.cb = NULL; newEventHandler.cb = NULL;
newEventHandler.fcb = cbEvent; newEventHandler.fcb = cbEvent;
newEventHandler.scb = NULL; newEventHandler.scb = NULL;
newEventHandler.provcb = NULL;
newEventHandler.event = event; newEventHandler.event = event;
cbEventList.push_back(newEventHandler); cbEventList.push_back(newEventHandler);
return newEventHandler.id; return newEventHandler.id;
} }
wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_id_t event) wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event)
{ {
if(!cbEvent) { if(!cbEvent) {
return 0; return 0;
@ -334,7 +710,6 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_i
newEventHandler.cb = NULL; newEventHandler.cb = NULL;
newEventHandler.fcb = NULL; newEventHandler.fcb = NULL;
newEventHandler.scb = cbEvent; newEventHandler.scb = cbEvent;
newEventHandler.provcb = NULL;
newEventHandler.event = event; newEventHandler.event = event;
cbEventList.push_back(newEventHandler); cbEventList.push_back(newEventHandler);
return newEventHandler.id; return newEventHandler.id;
@ -345,7 +720,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_i
* @param cbEvent WiFiEventCb * @param cbEvent WiFiEventCb
* @param event optional filter (WIFI_EVENT_MAX is all events) * @param event optional filter (WIFI_EVENT_MAX is all events)
*/ */
void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, system_event_id_t event) void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, arduino_event_id_t event)
{ {
if(!cbEvent) { if(!cbEvent) {
return; return;
@ -359,7 +734,7 @@ void WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, system_event_id_t event)
} }
} }
void WiFiGenericClass::removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event) void WiFiGenericClass::removeEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event)
{ {
if(!cbEvent) { if(!cbEvent) {
return; return;
@ -388,34 +763,42 @@ void WiFiGenericClass::removeEvent(wifi_event_id_t id)
* @param arg * @param arg
*/ */
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_LOST_IP", "STA_WPS_ER_SUCCESS", "STA_WPS_ER_FAILED", "STA_WPS_ER_TIMEOUT", "STA_WPS_ER_PIN", "STA_WPS_ER_PBC_OVERLAP", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_STAIPASSIGNED", "AP_PROBEREQRECVED", "GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "MAX"}; const char * arduino_event_names[] = {
"WIFI_READY",
"SCAN_DONE",
"STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_GOT_IP6", "STA_LOST_IP",
"AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_STAIPASSIGNED", "AP_PROBEREQRECVED", "AP_GOT_IP6",
"ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "ETH_GOT_IP6",
"WPS_ER_SUCCESS", "WPS_ER_FAILED", "WPS_ER_TIMEOUT", "WPS_ER_PIN", "WPS_ER_PBC_OVERLAP",
"SC_SCAN_DONE", "SC_FOUND_CHANNEL", "SC_GOT_SSID_PSWD", "SC_SEND_ACK_DONE",
"PROV_INIT", "PROV_DEINIT", "PROV_START", "PROV_END", "PROV_CRED_RECV", "PROV_CRED_FAIL", "PROV_CRED_SUCCESS"
};
#endif #endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN
const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "UNSPECIFIED", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT", "CONNECTION_FAIL" }; const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "UNSPECIFIED", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT", "CONNECTION_FAIL" };
#define reason2str(r) ((r>176)?system_event_reasons[r-176]:system_event_reasons[r-1]) #define reason2str(r) ((r>176)?system_event_reasons[r-176]:system_event_reasons[r-1])
#endif #endif
esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event, wifi_prov_event_t *prov_event) esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event)
{ {
if(WiFi.isProvEnabled()) { if(event->event_id < ARDUINO_EVENT_MAX) {
wifi_prov_mgr_event_handler(arg,event); log_d("Arduino Event: %d - %s", event->event_id, arduino_event_names[event->event_id]);
} }
if(event->event_id < 26) { if(event->event_id == ARDUINO_EVENT_WIFI_SCAN_DONE) {
log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]);
}
if(event->event_id == SYSTEM_EVENT_SCAN_DONE) {
WiFiScanClass::_scanDone(); WiFiScanClass::_scanDone();
} else if(event->event_id == SYSTEM_EVENT_STA_START) { } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_START) {
WiFiSTAClass::_setStatus(WL_DISCONNECTED); WiFiSTAClass::_setStatus(WL_DISCONNECTED);
setStatusBits(STA_STARTED_BIT); setStatusBits(STA_STARTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_STA_STOP) { } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_STOP) {
WiFiSTAClass::_setStatus(WL_NO_SHIELD); WiFiSTAClass::_setStatus(WL_NO_SHIELD);
clearStatusBits(STA_STARTED_BIT | STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT); clearStatusBits(STA_STARTED_BIT | STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT);
} else if(event->event_id == SYSTEM_EVENT_STA_CONNECTED) { } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_CONNECTED) {
WiFiSTAClass::_setStatus(WL_IDLE_STATUS); WiFiSTAClass::_setStatus(WL_IDLE_STATUS);
setStatusBits(STA_CONNECTED_BIT); setStatusBits(STA_CONNECTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
uint8_t reason = event->event_info.disconnected.reason; //esp_netif_create_ip6_linklocal(esp_netifs[ESP_IF_WIFI_STA]);
} else if(event->event_id == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
uint8_t reason = event->event_info.wifi_sta_disconnected.reason;
log_w("Reason: %u - %s", reason, reason2str(reason)); log_w("Reason: %u - %s", reason, reason2str(reason));
if(reason == WIFI_REASON_NO_AP_FOUND) { if(reason == WIFI_REASON_NO_AP_FOUND) {
WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL); WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL);
@ -436,7 +819,7 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event, wif
WiFi.disconnect(); WiFi.disconnect();
WiFi.begin(); WiFi.begin();
} }
} else if(event->event_id == SYSTEM_EVENT_STA_GOT_IP) { } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr); uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr);
uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr); uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr);
@ -448,31 +831,31 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event, wif
#endif #endif
WiFiSTAClass::_setStatus(WL_CONNECTED); WiFiSTAClass::_setStatus(WL_CONNECTED);
setStatusBits(STA_HAS_IP_BIT | STA_CONNECTED_BIT); setStatusBits(STA_HAS_IP_BIT | STA_CONNECTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_STA_LOST_IP) { } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_LOST_IP) {
WiFiSTAClass::_setStatus(WL_IDLE_STATUS); WiFiSTAClass::_setStatus(WL_IDLE_STATUS);
clearStatusBits(STA_HAS_IP_BIT); clearStatusBits(STA_HAS_IP_BIT);
} else if(event->event_id == SYSTEM_EVENT_AP_START) { } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_START) {
setStatusBits(AP_STARTED_BIT); setStatusBits(AP_STARTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_AP_STOP) { } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_STOP) {
clearStatusBits(AP_STARTED_BIT | AP_HAS_CLIENT_BIT); clearStatusBits(AP_STARTED_BIT | AP_HAS_CLIENT_BIT);
} else if(event->event_id == SYSTEM_EVENT_AP_STACONNECTED) { } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_STACONNECTED) {
setStatusBits(AP_HAS_CLIENT_BIT); setStatusBits(AP_HAS_CLIENT_BIT);
} else if(event->event_id == SYSTEM_EVENT_AP_STADISCONNECTED) { } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_STADISCONNECTED) {
wifi_sta_list_t clients; wifi_sta_list_t clients;
if(esp_wifi_ap_get_sta_list(&clients) != ESP_OK || !clients.num){ if(esp_wifi_ap_get_sta_list(&clients) != ESP_OK || !clients.num){
clearStatusBits(AP_HAS_CLIENT_BIT); clearStatusBits(AP_HAS_CLIENT_BIT);
} }
} else if(event->event_id == SYSTEM_EVENT_ETH_START) { } else if(event->event_id == ARDUINO_EVENT_ETH_START) {
setStatusBits(ETH_STARTED_BIT); setStatusBits(ETH_STARTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_ETH_STOP) { } else if(event->event_id == ARDUINO_EVENT_ETH_STOP) {
clearStatusBits(ETH_STARTED_BIT | ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT); clearStatusBits(ETH_STARTED_BIT | ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT);
} else if(event->event_id == SYSTEM_EVENT_ETH_CONNECTED) { } else if(event->event_id == ARDUINO_EVENT_ETH_CONNECTED) {
setStatusBits(ETH_CONNECTED_BIT); setStatusBits(ETH_CONNECTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_ETH_DISCONNECTED) { } else if(event->event_id == ARDUINO_EVENT_ETH_DISCONNECTED) {
clearStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT); clearStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT);
} else if(event->event_id == SYSTEM_EVENT_ETH_GOT_IP) { } else if(event->event_id == ARDUINO_EVENT_ETH_GOT_IP) {
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr); uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr);
uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr); uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr);
@ -484,33 +867,37 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event, wif
#endif #endif
setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT); setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT);
} else if(event->event_id == SYSTEM_EVENT_GOT_IP6) { } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP6) {
if(event->event_info.got_ip6.if_index == TCPIP_ADAPTER_IF_AP){
setStatusBits(AP_HAS_IP6_BIT);
} else if(event->event_info.got_ip6.if_index == TCPIP_ADAPTER_IF_STA){
setStatusBits(STA_CONNECTED_BIT | STA_HAS_IP6_BIT); setStatusBits(STA_CONNECTED_BIT | STA_HAS_IP6_BIT);
} else if(event->event_info.got_ip6.if_index == TCPIP_ADAPTER_IF_ETH){ } else if(event->event_id == ARDUINO_EVENT_WIFI_AP_GOT_IP6) {
setStatusBits(AP_HAS_IP6_BIT);
} else if(event->event_id == ARDUINO_EVENT_ETH_GOT_IP6) {
setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP6_BIT); setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP6_BIT);
} } else if(event->event_id == ARDUINO_EVENT_SC_GOT_SSID_PSWD) {
WiFi.begin(
(const char *)event->event_info.sc_got_ssid_pswd.ssid,
(const char *)event->event_info.sc_got_ssid_pswd.password,
0,
((event->event_info.sc_got_ssid_pswd.bssid_set == true)?event->event_info.sc_got_ssid_pswd.bssid:NULL)
);
} else if(event->event_id == ARDUINO_EVENT_SC_SEND_ACK_DONE) {
esp_smartconfig_stop();
WiFiSTAClass::_smartConfigDone = true;
} }
for(uint32_t i = 0; i < cbEventList.size(); i++) { for(uint32_t i = 0; i < cbEventList.size(); i++) {
WiFiEventCbList_t entry = cbEventList[i]; WiFiEventCbList_t entry = cbEventList[i];
if(entry.cb || entry.fcb || entry.scb) { if(entry.cb || entry.fcb || entry.scb) {
if(entry.event == (system_event_id_t) event->event_id || entry.event == SYSTEM_EVENT_MAX) { if(entry.event == (arduino_event_id_t) event->event_id || entry.event == ARDUINO_EVENT_MAX) {
if(entry.cb) { if(entry.cb) {
entry.cb((system_event_id_t) event->event_id); entry.cb((arduino_event_id_t) event->event_id);
} else if(entry.fcb) { } else if(entry.fcb) {
entry.fcb((system_event_id_t) event->event_id, (system_event_info_t) event->event_info); entry.fcb((arduino_event_id_t) event->event_id, (arduino_event_info_t) event->event_info);
} else { } else {
entry.scb(event); entry.scb(event);
} }
} }
} }
if(entry.provcb) {
entry.provcb(event,prov_event);
}
} }
return ESP_OK; return ESP_OK;
} }
@ -570,6 +957,13 @@ bool WiFiGenericClass::mode(wifi_mode_t m)
} }
esp_err_t err; esp_err_t err;
if(m & WIFI_MODE_STA){
err = set_esp_interface_hostname(ESP_IF_WIFI_STA, get_esp_netif_hostname());
if(err){
log_e("Could not set hostname! %d", err);
return false;
}
}
err = esp_wifi_set_mode(m); err = esp_wifi_set_mode(m);
if(err){ if(err){
log_e("Could not set mode! %d", err); log_e("Could not set mode! %d", err);
@ -607,7 +1001,7 @@ wifi_mode_t WiFiGenericClass::getMode()
return WIFI_MODE_NULL; return WIFI_MODE_NULL;
} }
wifi_mode_t mode; wifi_mode_t mode;
if(esp_wifi_get_mode(&mode) == ESP_ERR_WIFI_NOT_INIT){ if(esp_wifi_get_mode(&mode) != ESP_OK){
log_w("WiFi not started"); log_w("WiFi not started");
return WIFI_MODE_NULL; return WIFI_MODE_NULL;
} }
@ -739,7 +1133,7 @@ static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, v
if(ipaddr) { if(ipaddr) {
(*reinterpret_cast<IPAddress*>(callback_arg)) = ipaddr->u_addr.ip4.addr; (*reinterpret_cast<IPAddress*>(callback_arg)) = ipaddr->u_addr.ip4.addr;
} }
xEventGroupSetBits(_network_event_group, WIFI_DNS_DONE_BIT); xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT);
} }
/** /**

View File

@ -23,29 +23,86 @@
#ifndef ESP32WIFIGENERIC_H_ #ifndef ESP32WIFIGENERIC_H_
#define ESP32WIFIGENERIC_H_ #define ESP32WIFIGENERIC_H_
#include <esp_err.h> #include "esp_err.h"
#include <esp_event.h> #include "esp_event.h"
#include <functional> #include <functional>
#include "WiFiType.h" #include "WiFiType.h"
#include "IPAddress.h" #include "IPAddress.h"
#include <wifi_provisioning/manager.h> #include "esp_smartconfig.h"
#include "wifi_provisioning/manager.h"
typedef struct ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS);
{
wifi_prov_cb_event_t event;
void *event_data;
}wifi_prov_event_t;
typedef struct typedef enum {
{ ARDUINO_EVENT_WIFI_READY = 0,
wifi_prov_event_t *prov_event; ARDUINO_EVENT_WIFI_SCAN_DONE,
system_event_t *sys_event; ARDUINO_EVENT_WIFI_STA_START,
}system_prov_event_t; ARDUINO_EVENT_WIFI_STA_STOP,
ARDUINO_EVENT_WIFI_STA_CONNECTED,
ARDUINO_EVENT_WIFI_STA_DISCONNECTED,
ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE,
ARDUINO_EVENT_WIFI_STA_GOT_IP,
ARDUINO_EVENT_WIFI_STA_GOT_IP6,
ARDUINO_EVENT_WIFI_STA_LOST_IP,
ARDUINO_EVENT_WIFI_AP_START,
ARDUINO_EVENT_WIFI_AP_STOP,
ARDUINO_EVENT_WIFI_AP_STACONNECTED,
ARDUINO_EVENT_WIFI_AP_STADISCONNECTED,
ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED,
ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED,
ARDUINO_EVENT_WIFI_AP_GOT_IP6,
ARDUINO_EVENT_ETH_START,
ARDUINO_EVENT_ETH_STOP,
ARDUINO_EVENT_ETH_CONNECTED,
ARDUINO_EVENT_ETH_DISCONNECTED,
ARDUINO_EVENT_ETH_GOT_IP,
ARDUINO_EVENT_ETH_GOT_IP6,
ARDUINO_EVENT_WPS_ER_SUCCESS,
ARDUINO_EVENT_WPS_ER_FAILED,
ARDUINO_EVENT_WPS_ER_TIMEOUT,
ARDUINO_EVENT_WPS_ER_PIN,
ARDUINO_EVENT_WPS_ER_PBC_OVERLAP,
ARDUINO_EVENT_SC_SCAN_DONE,
ARDUINO_EVENT_SC_FOUND_CHANNEL,
ARDUINO_EVENT_SC_GOT_SSID_PSWD,
ARDUINO_EVENT_SC_SEND_ACK_DONE,
ARDUINO_EVENT_PROV_INIT,
ARDUINO_EVENT_PROV_DEINIT,
ARDUINO_EVENT_PROV_START,
ARDUINO_EVENT_PROV_END,
ARDUINO_EVENT_PROV_CRED_RECV,
ARDUINO_EVENT_PROV_CRED_FAIL,
ARDUINO_EVENT_PROV_CRED_SUCCESS,
ARDUINO_EVENT_MAX
} arduino_event_id_t;
typedef void (*WiFiEventCb)(system_event_id_t event); typedef union {
typedef std::function<void(system_event_id_t event, system_event_info_t info)> WiFiEventFuncCb; wifi_event_sta_scan_done_t wifi_scan_done;
typedef void (*WiFiEventSysCb)(system_event_t *event); wifi_event_sta_authmode_change_t wifi_sta_authmode_change;
typedef void (*WiFiProvEventCb)(system_event_t *sys_event, wifi_prov_event_t *prov_event); wifi_event_sta_connected_t wifi_sta_connected;
wifi_event_sta_disconnected_t wifi_sta_disconnected;
wifi_event_sta_wps_er_pin_t wps_er_pin;
wifi_event_sta_wps_fail_reason_t wps_fail_reason;
wifi_event_ap_probe_req_rx_t wifi_ap_probereqrecved;
wifi_event_ap_staconnected_t wifi_ap_staconnected;
wifi_event_ap_stadisconnected_t wifi_ap_stadisconnected;
ip_event_ap_staipassigned_t wifi_ap_staipassigned;
ip_event_got_ip_t got_ip;
ip_event_got_ip6_t got_ip6;
smartconfig_event_got_ssid_pswd_t sc_got_ssid_pswd;
esp_eth_handle_t eth_connected;
wifi_sta_config_t prov_cred_recv;
wifi_prov_sta_fail_reason_t prov_fail_reason;
} arduino_event_info_t;
typedef struct{
arduino_event_id_t event_id;
arduino_event_info_t event_info;
} arduino_event_t;
typedef void (*WiFiEventCb)(arduino_event_id_t event);
typedef std::function<void(arduino_event_id_t event, arduino_event_info_t info)> WiFiEventFuncCb;
typedef void (*WiFiEventSysCb)(arduino_event_t *event);
typedef size_t wifi_event_id_t; typedef size_t wifi_event_id_t;
@ -85,12 +142,11 @@ class WiFiGenericClass
public: public:
WiFiGenericClass(); WiFiGenericClass();
wifi_event_id_t onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
wifi_event_id_t onEvent(WiFiProvEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); void removeEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
void removeEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); void removeEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
void removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX);
void removeEvent(wifi_event_id_t id); void removeEvent(wifi_event_id_t id);
static int getStatusBits(); static int getStatusBits();
@ -114,7 +170,10 @@ class WiFiGenericClass
bool setTxPower(wifi_power_t power); bool setTxPower(wifi_power_t power);
wifi_power_t getTxPower(); wifi_power_t getTxPower();
static esp_err_t _eventCallback(void *arg, system_event_t *event, wifi_prov_event_t *prov_event=NULL); static const char * getHostname();
static void setHostname(const char * hostname);
static esp_err_t _eventCallback(arduino_event_t *event);
protected: protected:
static bool _persistent; static bool _persistent;

View File

@ -24,20 +24,24 @@
#include <string.h> #include <string.h>
#include <esp_err.h> #include <esp_err.h>
#include <esp_wifi.h> #include <esp_wifi.h>
#include <esp_event_loop.h> #include <esp_event.h>
#include <esp32-hal.h> #include <esp32-hal.h>
#include <wifi_provisioning/scheme_ble.h> #include <nvs_flash.h>
#if CONFIG_IDF_TARGET_ESP32
#include "wifi_provisioning/scheme_ble.h"
#endif
#include <wifi_provisioning/scheme_softap.h> #include <wifi_provisioning/scheme_softap.h>
#include <wifi_provisioning/manager.h> #include <wifi_provisioning/manager.h>
#undef IPADDR_NONE #undef IPADDR_NONE
#include "WiFi.h" #include "WiFi.h"
wifi_prov_mgr_config_t config; bool wifiLowLevelInit(bool persistent);
scheme_t prov_scheme;
extern esp_err_t postToSysQueue(system_prov_event_t *); #if CONFIG_IDF_TARGET_ESP32
static const uint8_t custom_service_uuid[16] = { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, static const uint8_t custom_service_uuid[16] = { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, }; 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, };
#endif
#define SERV_NAME_PREFIX_PROV "PROV_" #define SERV_NAME_PREFIX_PROV "PROV_"
@ -48,61 +52,13 @@ bool WiFiProvClass::isProvEnabled()
return prov_enable; return prov_enable;
} }
void provSchemeBLE() static void get_device_service_name(prov_scheme_t prov_scheme, char *service_name, size_t max)
{ {
prov_scheme = WIFI_PROV_SCHEME_BLE; uint8_t eth_mac[6] = {0,0,0,0,0,0};
config.scheme = wifi_prov_scheme_ble; if(esp_wifi_get_mac(WIFI_IF_STA, eth_mac) != ESP_OK){
} log_e("esp_wifi_get_mac failed!");
void provSchemeSoftAP()
{
prov_scheme = WIFI_PROV_SCHEME_SOFTAP;
config.scheme = wifi_prov_scheme_softap;
}
static void prov_event_handler(void *user_data, wifi_prov_cb_event_t event, void *event_data)
{
if (!event) {
return; return;
} }
system_prov_event_t *sys_prov = (system_prov_event_t *)malloc(sizeof(system_prov_event_t));
if(sys_prov == NULL) {
log_e("Malloc Failed");
return;
}
sys_prov->prov_event = (wifi_prov_event_t *)malloc(sizeof(wifi_prov_event_t));
if(sys_prov->prov_event == NULL) {
log_e("Malloc Failed");
free(sys_prov);
return;
}
sys_prov->sys_event = (system_event_t *)malloc(sizeof(system_event_t));
if(sys_prov->sys_event == NULL) {
log_e("Malloc Failed");
free(sys_prov->prov_event);
free(sys_prov);
return;
}
sys_prov->prov_event->event = event;
sys_prov->prov_event->event_data = event_data;
sys_prov->sys_event->event_id = SYSTEM_EVENT_MAX;
esp_err_t check = postToSysQueue(sys_prov);
if(check == ESP_FAIL) {
log_e("Provisioning event not send to queue");
free(sys_prov->sys_event);
free(sys_prov->prov_event);
free(sys_prov);
}
}
static void get_device_service_name(char *service_name, size_t max)
{
uint8_t eth_mac[6];
WiFi.macAddress(eth_mac);
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
if(prov_scheme == WIFI_PROV_SCHEME_BLE) { if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
snprintf(service_name, max, "%s%02X%02X%02X",SERV_NAME_PREFIX_BLE, eth_mac[3], eth_mac[4], eth_mac[5]); snprintf(service_name, max, "%s%02X%02X%02X",SERV_NAME_PREFIX_BLE, eth_mac[3], eth_mac[4], eth_mac[5]);
@ -114,17 +70,22 @@ static void get_device_service_name(char *service_name, size_t max)
#endif #endif
} }
void WiFiProvClass :: beginProvision(void (*scheme_cb)(), wifi_prov_event_handler_t scheme_event_handler, wifi_prov_security_t security, const char * pop, const char *service_name, const char *service_key, uint8_t * uuid) static esp_err_t custom_prov_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen, void *priv_data){
if (inbuf) {
log_d("Received data: %.*s", inlen, (char *)inbuf);
}
*outbuf = NULL;
*outlen = 0;
return ESP_OK;
}
void WiFiProvClass :: beginProvision(prov_scheme_t prov_scheme, scheme_handler_t scheme_handler, wifi_prov_security_t security, const char * pop, const char *service_name, const char *service_key, uint8_t * uuid)
{ {
prov_enable = true; prov_enable = true;
bool provisioned = false; bool provisioned = false;
scheme_cb(); static char service_name_temp[32];
config.scheme_event_handler = scheme_event_handler;
config.app_event_handler = {
.event_cb = prov_event_handler,
.user_data = NULL
};
wifi_prov_mgr_config_t config;
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
if(prov_scheme == WIFI_PROV_SCHEME_BLE) { if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
config.scheme = wifi_prov_scheme_ble; config.scheme = wifi_prov_scheme_ble;
@ -133,11 +94,37 @@ void WiFiProvClass :: beginProvision(void (*scheme_cb)(), wifi_prov_event_handle
config.scheme = wifi_prov_scheme_softap; config.scheme = wifi_prov_scheme_softap;
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
} }
if(scheme_handler == WIFI_PROV_SCHEME_HANDLER_NONE){
#endif
wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE;
memcpy(&config.scheme_event_handler, &scheme_event_handler, sizeof(wifi_prov_event_handler_t));
#if CONFIG_IDF_TARGET_ESP32
} else if(scheme_handler == WIFI_PROV_SCHEME_HANDLER_FREE_BTDM){
wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM;
memcpy(&config.scheme_event_handler, &scheme_event_handler, sizeof(wifi_prov_event_handler_t));
} else if(scheme_handler == WIFI_PROV_SCHEME_HANDLER_FREE_BT){
wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT;
memcpy(&config.scheme_event_handler, &scheme_event_handler, sizeof(wifi_prov_event_handler_t));
} else if(scheme_handler == WIFI_PROV_SCHEME_HANDLER_FREE_BLE){
wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE;
memcpy(&config.scheme_event_handler, &scheme_event_handler, sizeof(wifi_prov_event_handler_t));
} else {
log_e("Unknown scheme handler!");
return;
}
#endif #endif
wifi_prov_mgr_init(config); wifiLowLevelInit(true);
WiFi.mode(WIFI_MODE_AP); if(wifi_prov_mgr_init(config) != ESP_OK){
wifi_prov_mgr_is_provisioned(&provisioned); log_e("wifi_prov_mgr_init failed!");
return;
}
if(wifi_prov_mgr_is_provisioned(&provisioned) != ESP_OK){
log_e("wifi_prov_mgr_is_provisioned failed!");
wifi_prov_mgr_deinit();
return;
}
if(provisioned == false) { if(provisioned == false) {
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
if(prov_scheme == WIFI_PROV_SCHEME_BLE) { if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
@ -150,37 +137,45 @@ void WiFiProvClass :: beginProvision(void (*scheme_cb)(), wifi_prov_event_handle
#endif #endif
if(service_name == NULL) { if(service_name == NULL) {
char service_name_temp[12]; get_device_service_name(prov_scheme, service_name_temp, 32);
get_device_service_name(service_name_temp,sizeof(service_name_temp));
service_name = (const char *)service_name_temp; service_name = (const char *)service_name_temp;
} }
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
if(prov_scheme == WIFI_PROV_SCHEME_BLE) { if(prov_scheme == WIFI_PROV_SCHEME_BLE) {
log_i("Starting AP using BLE\n service_name : %s\n pop : %s",service_name,pop); log_i("Starting AP using BLE. service_name : %s, pop : %s",service_name,pop);
} else { } else {
#endif #endif
if(service_key == NULL) { if(service_key == NULL) {
log_i("Starting AP using SOFTAP\n service_name : %s\n pop : %s",service_name,pop); log_i("Starting provisioning AP using SOFTAP. service_name : %s, pop : %s",service_name,pop);
} else { } else {
log_i("Starting AP using SOFTAP\n service_name : %s\n password : %s\n pop : %s",service_name,service_key,pop); log_i("Starting provisioning AP using SOFTAP. service_name : %s, password : %s, pop : %s",service_name,service_key,pop);
} }
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
} }
#endif #endif
wifi_prov_mgr_start_provisioning(security,pop,service_name,service_key); if(wifi_prov_mgr_endpoint_create("custom-data") != ESP_OK){
log_e("wifi_prov_mgr_endpoint_create failed!");
return;
}
if(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key) != ESP_OK){
log_e("wifi_prov_mgr_start_provisioning failed!");
return;
}
if(wifi_prov_mgr_endpoint_register("custom-data", custom_prov_data_handler, NULL) != ESP_OK){
log_e("wifi_prov_mgr_endpoint_register failed!");
return;
}
} else { } else {
wifi_prov_mgr_deinit(); wifi_prov_mgr_deinit();
WiFi.mode(WIFI_MODE_STA); log_i("Aleardy Provisioned");
log_i("Aleardy Provisioned, starting Wi-Fi STA");
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
wifi_config_t conf; static wifi_config_t conf;
esp_wifi_get_config(WIFI_IF_STA,&conf); esp_wifi_get_config(WIFI_IF_STA,&conf);
log_i("SSID : %s\n",conf.sta.ssid); log_i("Attempting connect to AP: %s\n",conf.sta.ssid);
#endif #endif
log_i("CONNECTING TO THE ACCESS POINT : "); esp_wifi_start();
WiFi.begin(); WiFi.begin();
} }
} }

View File

@ -17,19 +17,27 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "WiFi.h"
#include "wifi_provisioning/manager.h" #include "wifi_provisioning/manager.h"
#include "wifi_provisioning/scheme_ble.h"
#include "nvs_flash.h"
#include "SimpleBLE.h"
//Select the scheme using which you want to provision
typedef enum
{
WIFI_PROV_SCHEME_BLE,
WIFI_PROV_SCHEME_SOFTAP
}scheme_t;
extern void provSchemeSoftAP(); //Select the scheme using which you want to provision
extern void provSchemeBLE(); typedef enum {
WIFI_PROV_SCHEME_SOFTAP,
#if CONFIG_IDF_TARGET_ESP32
WIFI_PROV_SCHEME_BLE,
#endif
WIFI_PROV_SCHEME_MAX
} prov_scheme_t;
typedef enum {
WIFI_PROV_SCHEME_HANDLER_NONE,
#if CONFIG_IDF_TARGET_ESP32
WIFI_PROV_SCHEME_HANDLER_FREE_BTDM,
WIFI_PROV_SCHEME_HANDLER_FREE_BLE,
WIFI_PROV_SCHEME_HANDLER_FREE_BT,
#endif
WIFI_PROV_SCHEME_HANDLER_MAX
} scheme_handler_t;
//Provisioning class //Provisioning class
class WiFiProvClass class WiFiProvClass
@ -43,15 +51,6 @@ class WiFiProvClass
} }
bool isProvEnabled(); bool isProvEnabled();
void beginProvision(prov_scheme_t prov_scheme = WIFI_PROV_SCHEME_SOFTAP, scheme_handler_t scheme_handler = WIFI_PROV_SCHEME_HANDLER_NONE,
void beginProvision(void (*scheme_cb)() = provSchemeSoftAP, wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE, wifi_prov_security_t security = WIFI_PROV_SECURITY_1, const char * pop = "abcd1234", const char * service_name = NULL, const char * service_key = NULL, uint8_t *uuid = NULL); wifi_prov_security_t security = WIFI_PROV_SECURITY_1, const char * pop = "abcd1234", const char * service_name = NULL, const char * service_key = NULL, uint8_t *uuid = NULL);
}; };
/*
Event Handler for BLE
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT
Event Handler for SOFTAP
- WIFI_PROV_EVENT_HANDLER_NONE
*/

View File

@ -48,6 +48,9 @@ extern "C" {
// ---------------------------------------------------- Private functions ------------------------------------------------ // ---------------------------------------------------- Private functions ------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns=IPAddress(), IPAddress backup_dns=IPAddress(), IPAddress fallback_dns=IPAddress());
esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPAddress(), IPAddress gateway=IPAddress(), IPAddress subnet=IPAddress());
static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs); static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs);
@ -65,6 +68,36 @@ static bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs)
return true; return true;
} }
static void wifi_sta_config(wifi_config_t * wifi_config, const char * ssid=NULL, const char * password=NULL, const uint8_t * bssid=NULL, uint8_t channel=0, wifi_scan_method_t scan_method=WIFI_ALL_CHANNEL_SCAN, wifi_sort_method_t sort_method=WIFI_CONNECT_AP_BY_SIGNAL, uint16_t listen_interval=0, bool pmf_required=false){
wifi_config->sta.channel = channel;
wifi_config->sta.listen_interval = listen_interval;
wifi_config->sta.scan_method = scan_method;//WIFI_ALL_CHANNEL_SCAN or WIFI_FAST_SCAN
wifi_config->sta.sort_method = sort_method;//WIFI_CONNECT_AP_BY_SIGNAL or WIFI_CONNECT_AP_BY_SECURITY
wifi_config->sta.threshold.rssi = -75;
wifi_config->sta.pmf_cfg.capable = true;
wifi_config->sta.pmf_cfg.required = pmf_required;
wifi_config->sta.bssid_set = 0;
memset(wifi_config->sta.bssid, 0, 6);
wifi_config->sta.threshold.authmode = WIFI_AUTH_OPEN;
wifi_config->sta.ssid[0] = 0;
wifi_config->sta.password[0] = 0;
if(ssid != NULL && ssid[0] != 0){
snprintf((char*)wifi_config->sta.ssid, 32, ssid);
if(password != NULL && password[0] != 0){
wifi_config->sta.threshold.authmode = WIFI_AUTH_WEP;
if(strlen(password) == 64){
memcpy((char*)wifi_config->sta.password, password, 64);
} else {
snprintf((char*)wifi_config->sta.password, 64, password);
}
}
if(bssid != NULL){
wifi_config->sta.bssid_set = 1;
memcpy(wifi_config->sta.bssid, bssid, 6);
}
}
}
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------- STA function ----------------------------------------------------- // ---------------------------------------------------- STA function -----------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
@ -131,54 +164,45 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_
} }
wifi_config_t conf; wifi_config_t conf;
memset(&conf, 0, sizeof(wifi_config_t));
strcpy(reinterpret_cast<char*>(conf.sta.ssid), ssid);
if(passphrase) {
if (strlen(passphrase) == 64){ // it's not a passphrase, is the PSK
memcpy(reinterpret_cast<char*>(conf.sta.password), passphrase, 64);
} else {
strcpy(reinterpret_cast<char*>(conf.sta.password), passphrase);
}
}
if(bssid) {
conf.sta.bssid_set = 1;
memcpy((void *) &conf.sta.bssid[0], (void *) bssid, 6);
}
if(channel > 0 && channel <= 13) {
conf.sta.channel = channel;
}
wifi_config_t current_conf; wifi_config_t current_conf;
esp_wifi_get_config(WIFI_IF_STA, &current_conf);
wifi_sta_config(&conf, ssid, passphrase, bssid, channel);
if(esp_wifi_get_config(ESP_IF_WIFI_STA, &current_conf) != ESP_OK){
log_e("get current config failed!");
return WL_CONNECT_FAILED;
}
if(!sta_config_equal(current_conf, conf)) { if(!sta_config_equal(current_conf, conf)) {
if(esp_wifi_disconnect()){ if(esp_wifi_disconnect()){
log_e("disconnect failed!"); log_e("disconnect failed!");
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
esp_wifi_set_config(WIFI_IF_STA, &conf); if(esp_wifi_set_config(ESP_IF_WIFI_STA, &conf) != ESP_OK){
log_e("set config failed!");
return WL_CONNECT_FAILED;
}
} else if(status() == WL_CONNECTED){ } else if(status() == WL_CONNECTED){
return WL_CONNECTED; return WL_CONNECTED;
} else { } else {
esp_wifi_set_config(WIFI_IF_STA, &conf); if(esp_wifi_set_config(ESP_IF_WIFI_STA, &conf) != ESP_OK){
log_e("set config failed!");
return WL_CONNECT_FAILED;
}
} }
if(!_useStaticIp){ if(!_useStaticIp){
if(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){ if(set_esp_interface_ip(ESP_IF_WIFI_STA) != ESP_OK) {
log_e("dhcp client start failed!");
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
} else {
tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
} }
if(connect && esp_wifi_connect()) { if(connect){
if(esp_wifi_connect() != ESP_OK) {
log_e("connect failed!"); log_e("connect failed!");
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
}
return status(); return status();
} }
@ -201,24 +225,23 @@ wl_status_t WiFiSTAClass::begin()
} }
wifi_config_t current_conf; wifi_config_t current_conf;
if(esp_wifi_get_config(WIFI_IF_STA, &current_conf) != ESP_OK || esp_wifi_set_config(WIFI_IF_STA, &current_conf) != ESP_OK) { if(esp_wifi_get_config(ESP_IF_WIFI_STA, &current_conf) != ESP_OK || esp_wifi_set_config(ESP_IF_WIFI_STA, &current_conf) != ESP_OK) {
log_e("config failed"); log_e("config failed");
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
if(!_useStaticIp) { if(!_useStaticIp && set_esp_interface_ip(ESP_IF_WIFI_STA) != ESP_OK) {
if(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){ log_e("set ip failed!");
log_e("dhcp client start failed!");
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
} else {
tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
}
if(status() != WL_CONNECTED && esp_wifi_connect()){ if(status() != WL_CONNECTED){
log_e("connect failed!"); esp_err_t err = esp_wifi_connect();
if(err){
log_e("connect failed! 0x%x", err);
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
}
return status(); return status();
} }
@ -245,11 +268,11 @@ bool WiFiSTAClass::reconnect()
bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap) bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap)
{ {
wifi_config_t conf; wifi_config_t conf;
wifi_sta_config(&conf);
if(WiFi.getMode() & WIFI_MODE_STA){ if(WiFi.getMode() & WIFI_MODE_STA){
if(eraseap){ if(eraseap){
memset(&conf, 0, sizeof(wifi_config_t)); if(esp_wifi_set_config(ESP_IF_WIFI_STA, &conf)){
if(esp_wifi_set_config(WIFI_IF_STA, &conf)){
log_e("clear config failed!"); log_e("clear config failed!");
} }
} }
@ -281,58 +304,11 @@ bool WiFiSTAClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subne
if(!WiFi.enableSTA(true)) { if(!WiFi.enableSTA(true)) {
return false; return false;
} }
err = set_esp_interface_ip(ESP_IF_WIFI_STA, local_ip, gateway, subnet);
tcpip_adapter_ip_info_t info; if(err == ESP_OK){
err = set_esp_interface_dns(ESP_IF_WIFI_STA, dns1, dns2);
if(local_ip != (uint32_t)0x00000000){
info.ip.addr = static_cast<uint32_t>(local_ip);
info.gw.addr = static_cast<uint32_t>(gateway);
info.netmask.addr = static_cast<uint32_t>(subnet);
} else {
info.ip.addr = 0;
info.gw.addr = 0;
info.netmask.addr = 0;
} }
return err == ESP_OK;
err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED){
log_e("DHCP could not be stopped! Error: %d", err);
return false;
}
err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &info);
if(err != ERR_OK){
log_e("STA IP could not be configured! Error: %d", err);
return false;
}
if(info.ip.addr){
_useStaticIp = true;
} else {
err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
if(err == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){
log_e("dhcp client start failed!");
return false;
}
_useStaticIp = false;
}
ip_addr_t d;
d.type = IPADDR_TYPE_V4;
if(dns1 != (uint32_t)0x00000000) {
// Set DNS1-Server
d.u_addr.ip4.addr = static_cast<uint32_t>(dns1);
dns_setserver(0, &d);
}
if(dns2 != (uint32_t)0x00000000) {
// Set DNS2-Server
d.u_addr.ip4.addr = static_cast<uint32_t>(dns2);
dns_setserver(1, &d);
}
return true;
} }
/** /**
@ -353,9 +329,6 @@ bool WiFiSTAClass::isConnected()
*/ */
bool WiFiSTAClass::setAutoConnect(bool autoConnect) bool WiFiSTAClass::setAutoConnect(bool autoConnect)
{ {
/*bool ret;
ret = esp_wifi_set_auto_connect(autoConnect);
return ret;*/
return false;//now deprecated return false;//now deprecated
} }
@ -366,9 +339,6 @@ bool WiFiSTAClass::setAutoConnect(bool autoConnect)
*/ */
bool WiFiSTAClass::getAutoConnect() bool WiFiSTAClass::getAutoConnect()
{ {
/*bool autoConnect;
esp_wifi_get_auto_connect(&autoConnect);
return autoConnect;*/
return false;//now deprecated return false;//now deprecated
} }
@ -410,8 +380,11 @@ IPAddress WiFiSTAClass::localIP()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return IPAddress(ip.ip.addr); return IPAddress(ip.ip.addr);
} }
@ -424,7 +397,7 @@ IPAddress WiFiSTAClass::localIP()
uint8_t* WiFiSTAClass::macAddress(uint8_t* mac) uint8_t* WiFiSTAClass::macAddress(uint8_t* mac)
{ {
if(WiFiGenericClass::getMode() != WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() != WIFI_MODE_NULL){
esp_wifi_get_mac(WIFI_IF_STA, mac); esp_wifi_get_mac(ESP_IF_WIFI_STA, mac);
} }
else{ else{
esp_read_mac(mac, ESP_MAC_WIFI_STA); esp_read_mac(mac, ESP_MAC_WIFI_STA);
@ -444,7 +417,7 @@ String WiFiSTAClass::macAddress(void)
esp_read_mac(mac, ESP_MAC_WIFI_STA); esp_read_mac(mac, ESP_MAC_WIFI_STA);
} }
else{ else{
esp_wifi_get_mac(WIFI_IF_STA, mac); esp_wifi_get_mac(ESP_IF_WIFI_STA, mac);
} }
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(macStr); return String(macStr);
@ -459,8 +432,11 @@ IPAddress WiFiSTAClass::subnetMask()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return IPAddress(ip.netmask.addr); return IPAddress(ip.netmask.addr);
} }
@ -473,8 +449,11 @@ IPAddress WiFiSTAClass::gatewayIP()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return IPAddress(ip.gw.addr); return IPAddress(ip.gw.addr);
} }
@ -501,8 +480,11 @@ IPAddress WiFiSTAClass::broadcastIP()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
} }
@ -515,8 +497,11 @@ IPAddress WiFiSTAClass::networkID()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress(); return IPAddress();
} }
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
} }
@ -529,8 +514,11 @@ uint8_t WiFiSTAClass::subnetCIDR()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return (uint8_t)0; return (uint8_t)0;
} }
tcpip_adapter_ip_info_t ip; esp_netif_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip); if(esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK){
log_e("Netif Get IP Failed!");
return IPAddress();
}
return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr));
} }
@ -560,7 +548,7 @@ String WiFiSTAClass::psk() const
return String(); return String();
} }
wifi_config_t conf; wifi_config_t conf;
esp_wifi_get_config(WIFI_IF_STA, &conf); esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
return String(reinterpret_cast<char*>(conf.sta.password)); return String(reinterpret_cast<char*>(conf.sta.password));
} }
@ -613,35 +601,6 @@ int8_t WiFiSTAClass::RSSI(void)
return 0; return 0;
} }
/**
* Get the station interface Host name.
* @return char array hostname
*/
const char * WiFiSTAClass::getHostname()
{
const char * hostname = NULL;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return hostname;
}
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &hostname)){
return NULL;
}
return hostname;
}
/**
* Set the station interface Host name.
* @param hostname pointer to const string
* @return true on success
*/
bool WiFiSTAClass::setHostname(const char * hostname)
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false;
}
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, hostname) == 0;
}
/** /**
* Enable IPv6 on the station interface. * Enable IPv6 on the station interface.
* @return true on success * @return true on success
@ -651,7 +610,7 @@ bool WiFiSTAClass::enableIpV6()
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false; return false;
} }
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA) == 0; return esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA)) == ESP_OK;
} }
/** /**
@ -660,11 +619,11 @@ bool WiFiSTAClass::enableIpV6()
*/ */
IPv6Address WiFiSTAClass::localIPv6() IPv6Address WiFiSTAClass::localIPv6()
{ {
static ip6_addr_t addr; esp_ip6_addr_t addr;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){ if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPv6Address(); return IPv6Address();
} }
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_STA, &addr)){ if(esp_netif_get_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA), &addr)) {
return IPv6Address(); return IPv6Address();
} }
return IPv6Address(addr.addr); return IPv6Address(addr.addr);
@ -676,6 +635,7 @@ bool WiFiSTAClass::_smartConfigDone = false;
bool WiFiSTAClass::beginSmartConfig() { bool WiFiSTAClass::beginSmartConfig() {
esp_err_t err;
if (_smartConfigStarted) { if (_smartConfigStarted) {
return false; return false;
} }
@ -683,24 +643,23 @@ bool WiFiSTAClass::beginSmartConfig() {
if (!WiFi.mode(WIFI_STA)) { if (!WiFi.mode(WIFI_STA)) {
return false; return false;
} }
esp_wifi_disconnect(); esp_wifi_disconnect();
esp_err_t err;
#ifdef ESP_IDF_VERSION_MAJOR
esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, _smartConfigCallback, this);
smartconfig_start_config_t conf = SMARTCONFIG_START_CONFIG_DEFAULT(); smartconfig_start_config_t conf = SMARTCONFIG_START_CONFIG_DEFAULT();
err = esp_smartconfig_set_type(SC_TYPE_ESPTOUCH);
if (err != ESP_OK) {
log_e("SmartConfig Set Type Failed!");
return false;
}
err = esp_smartconfig_start(&conf); err = esp_smartconfig_start(&conf);
#else if (err != ESP_OK) {
err = esp_smartconfig_start(reinterpret_cast<sc_callback_t>(&WiFiSTAClass::_smartConfigCallback), 1); log_e("SmartConfig Start Failed!");
#endif return false;
if (err == ESP_OK) { }
_smartConfigStarted = true; _smartConfigStarted = true;
_smartConfigDone = false; _smartConfigDone = false;
return true; return true;
} }
return false;
}
bool WiFiSTAClass::stopSmartConfig() { bool WiFiSTAClass::stopSmartConfig() {
if (!_smartConfigStarted) { if (!_smartConfigStarted) {
@ -722,79 +681,3 @@ bool WiFiSTAClass::smartConfigDone() {
return _smartConfigDone; return _smartConfigDone;
} }
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
const char * sc_type_strings[] = {
"ESPTOUCH",
"AIRKISS",
"ESPTOUCH_AIRKISS"
};
#endif
#ifdef ESP_IDF_VERSION_MAJOR //todo
void WiFiSTAClass::_smartConfigCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data){
smartconfig_event_t event = (smartconfig_event_t)event_id;
switch(event){
case SC_EVENT_SCAN_DONE:
log_d("smartconfig has finished to scan for APs");
break;
case SC_EVENT_FOUND_CHANNEL:
log_d("smartconfig has found the channel of the target AP");
break;
case SC_EVENT_GOT_SSID_PSWD:
{
log_d("smartconfig got the SSID and password");
smartconfig_event_got_ssid_pswd_t * data = (smartconfig_event_got_ssid_pswd_t*)event_data;
log_d("Type: %s", sc_type_strings[data->type]);
log_d("SSID: %s", (const char *)data->ssid);
log_d("Password: %s", (const char *)data->password);
log_d("Sender IP: " IPSTR, data->cellphone_ip[3], data->cellphone_ip[2], data->cellphone_ip[1], data->cellphone_ip[0]);
WiFi.begin((const char *)data->ssid, (const char *)data->password);
}
break;
case SC_EVENT_SEND_ACK_DONE:
log_d("smartconfig has sent ACK to the sender");
WiFi.stopSmartConfig();
break;
default: break;
}
}
#else
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
const char * sc_status_strings[] = {
"WAIT",
"FIND_CHANNEL",
"GETTING_SSID_PSWD",
"LINK",
"LINK_OVER"
};
#endif
void WiFiSTAClass::_smartConfigCallback(uint32_t st, void* result) {
smartconfig_status_t status = (smartconfig_status_t) st;
log_d("Status: %s", sc_status_strings[st % 5]);
if (status == SC_STATUS_GETTING_SSID_PSWD) {
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
smartconfig_type_t * type = (smartconfig_type_t *)result;
log_d("Type: %s", sc_type_strings[*type % 3]);
#endif
} else if (status == SC_STATUS_LINK) {
wifi_sta_config_t *sta_conf = reinterpret_cast<wifi_sta_config_t *>(result);
log_d("SSID: %s", (char *)(sta_conf->ssid));
sta_conf->bssid_set = 0;
esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t *)sta_conf);
esp_wifi_connect();
_smartConfigDone = true;
} else if (status == SC_STATUS_LINK_OVER) {
if(result){
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
ip4_addr_t * ip = (ip4_addr_t *)result;
log_d("Sender IP: " IPSTR, IP2STR(ip));
#endif
}
WiFi.stopSmartConfig();
}
}
#endif

View File

@ -75,9 +75,6 @@ public:
bool enableIpV6(); bool enableIpV6();
IPv6Address localIPv6(); IPv6Address localIPv6();
const char * getHostname();
bool setHostname(const char * hostname);
// STA WiFi info // STA WiFi info
static wl_status_t status(); static wl_status_t status();
String SSID() const; String SSID() const;
@ -98,14 +95,9 @@ public:
bool stopSmartConfig(); bool stopSmartConfig();
bool smartConfigDone(); bool smartConfigDone();
static bool _smartConfigDone;
protected: protected:
static bool _smartConfigStarted; static bool _smartConfigStarted;
static bool _smartConfigDone;
#ifdef ESP_IDF_VERSION_MAJOR //todo
static void _smartConfigCallback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
#else
static void _smartConfigCallback(uint32_t status, void* result);
#endif
}; };

View File

@ -42,6 +42,33 @@ extern "C" {
#include "lwip/err.h" #include "lwip/err.h"
} }
static const char * cipher_str(int cipher)
{
switch (cipher) {
case WIFI_CIPHER_TYPE_NONE:
return ("NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
return ("WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
return ("WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
return ("TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
return ("CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
return ("TKIP_CCMP");
break;
default:
break;
}
return ("UNKNOWN");
}
bool WiFiScanClass::_scanAsync = false; bool WiFiScanClass::_scanAsync = false;
uint32_t WiFiScanClass::_scanStarted = 0; uint32_t WiFiScanClass::_scanStarted = 0;
uint32_t WiFiScanClass::_scanTimeout = 10000; uint32_t WiFiScanClass::_scanTimeout = 10000;