1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00

esp32: multi ap slots

This commit is contained in:
Andy Green 2017-05-13 10:26:59 +08:00
parent 54236bd437
commit b2f8bc5638
6 changed files with 342 additions and 87 deletions

View file

@ -3144,6 +3144,8 @@ lws_stats_log_dump(struct lws_context *context)
lwsl_notice("LWSSTATS_C_WRITEABLE_CB: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB)); lwsl_notice("LWSSTATS_C_WRITEABLE_CB: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB));
lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_FAILED: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_FAILED)); lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_FAILED: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_FAILED));
lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)); lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED));
lwsl_notice("LWSSTATS_C_SSL_CONNS_HAD_RX: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX));
lwsl_notice("LWSSTATS_C_TIMEOUTS: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_TIMEOUTS)); lwsl_notice("LWSSTATS_C_TIMEOUTS: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_TIMEOUTS));
lwsl_notice("LWSSTATS_C_SERVICE_ENTRY: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SERVICE_ENTRY)); lwsl_notice("LWSSTATS_C_SERVICE_ENTRY: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_C_SERVICE_ENTRY));
lwsl_notice("LWSSTATS_B_READ: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_B_READ)); lwsl_notice("LWSSTATS_B_READ: %8llu\n", (unsigned long long)lws_stats_get(context, LWSSTATS_B_READ));
@ -3154,6 +3156,12 @@ lws_stats_log_dump(struct lws_context *context)
lwsl_notice(" Avg accept delay: %8llums\n", lwsl_notice(" Avg accept delay: %8llums\n",
(unsigned long long)(lws_stats_get(context, LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) / (unsigned long long)(lws_stats_get(context, LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) /
lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)) / 1000); lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)) / 1000);
lwsl_notice("LWSSTATS_MS_SSL_RX_DELAY: %8llums\n", (unsigned long long)lws_stats_get(context, LWSSTATS_MS_SSL_RX_DELAY) / 1000);
if (lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX))
lwsl_notice(" Avg accept-rx delay: %8llums\n",
(unsigned long long)(lws_stats_get(context, LWSSTATS_MS_SSL_RX_DELAY) /
lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX)) / 1000);
lwsl_notice("LWSSTATS_MS_WRITABLE_DELAY: %8lluus\n", lwsl_notice("LWSSTATS_MS_WRITABLE_DELAY: %8lluus\n",
(unsigned long long)lws_stats_get(context, LWSSTATS_MS_WRITABLE_DELAY)); (unsigned long long)lws_stats_get(context, LWSSTATS_MS_WRITABLE_DELAY));
lwsl_notice("LWSSTATS_MS_WORST_WRITABLE_DELAY: %8lluus\n", lwsl_notice("LWSSTATS_MS_WORST_WRITABLE_DELAY: %8lluus\n",

View file

@ -555,8 +555,7 @@ lws_esp32_identify_physical_device(void);
/* lws-plat-esp32 provides these */ /* lws-plat-esp32 provides these */
extern void (*lws_cb_scan_done)(void *); typedef void (*lws_cb_scan_done)(uint16_t count, wifi_ap_record_t *recs, void *arg);
extern void *lws_cb_scan_done_arg;
struct lws_esp32 { struct lws_esp32 {
char sta_ip[16]; char sta_ip[16];
@ -567,11 +566,15 @@ struct lws_esp32 {
char model[16]; char model[16];
char group[16]; char group[16];
char role[16]; char role[16];
char ssid[4][16];
char password[4][32];
char active_ssid[32]; char active_ssid[32];
char access_pw[16]; char access_pw[16];
mdns_server_t *mdns; mdns_server_t *mdns;
char region; char region;
char inet; char inet;
lws_cb_scan_done scan_consumer;
void *scan_consumer_arg;
}; };
struct lws_esp32_image { struct lws_esp32_image {
@ -598,6 +601,8 @@ extern struct lws_context *
lws_esp32_init(struct lws_context_creation_info *); lws_esp32_init(struct lws_context_creation_info *);
extern int extern int
lws_esp32_wlan_nvs_get(int retry); lws_esp32_wlan_nvs_get(int retry);
extern esp_err_t
lws_nvs_set_str(nvs_handle handle, const char* key, const char* value);
extern void extern void
lws_esp32_restart_guided(uint32_t type); lws_esp32_restart_guided(uint32_t type);
extern const esp_partition_t * extern const esp_partition_t *
@ -4808,6 +4813,7 @@ enum {
LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */ LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */
LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connections */ LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connections */
LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL connections */ LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL connections */
LWSSTATS_C_SSL_CONNS_HAD_RX, /**< count of accepted SSL conns that have had some RX */
LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */ LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */
LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop */ LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop */
LWSSTATS_B_READ, /**< aggregate bytes read */ LWSSTATS_B_READ, /**< aggregate bytes read */
@ -4816,6 +4822,7 @@ enum {
LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, /**< aggregate delay in accepting connection */ LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, /**< aggregate delay in accepting connection */
LWSSTATS_MS_WRITABLE_DELAY, /**< aggregate delay between asking for writable and getting cb */ LWSSTATS_MS_WRITABLE_DELAY, /**< aggregate delay between asking for writable and getting cb */
LWSSTATS_MS_WORST_WRITABLE_DELAY, /**< single worst delay between asking for writable and getting cb */ LWSSTATS_MS_WORST_WRITABLE_DELAY, /**< single worst delay between asking for writable and getting cb */
LWSSTATS_MS_SSL_RX_DELAY, /**< aggregate delay between ssl accept complete and first RX */
/* Add new things just above here ---^ /* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility */ * This is part of the ABI, don't needlessly break compatibility */

View file

@ -625,16 +625,34 @@ enum lws_gapss {
* don't get an IP within a timeout and retries, * don't get an IP within a timeout and retries,
* blacklist it and go back * blacklist it and go back
*/ */
LWS_GAPSS_STAT_HAPPY,
};
static const char *gapss_str[] = {
"LWS_GAPSS_INITIAL",
"LWS_GAPSS_SCAN",
"LWS_GAPSS_AP",
"LWS_GAPSS_AP_SCAN",
"LWS_GAPSS_STAT_GRP_AP",
"LWS_GAPSS_STAT_GRP_AP_SCAN",
"LWS_GAPSS_STAT",
"LWS_GAPSS_STAT_HAPPY",
}; };
static romfs_t lws_esp32_romfs; static romfs_t lws_esp32_romfs;
static TimerHandle_t leds_timer; static TimerHandle_t leds_timer, scan_timer;
//static enum lws_gapss gapss = LWS_GAPSS_INITIAL; static enum lws_gapss gapss = LWS_GAPSS_INITIAL;
struct esp32_file { struct esp32_file {
const struct inode *i; const struct inode *i;
}; };
static void lws_gapss_to(enum lws_gapss to)
{
lwsl_notice("gapss from %s to %s\n", gapss_str[gapss], gapss_str[to]);
gapss = to;
}
uint32_t lws_esp32_get_reboot_type(void) uint32_t lws_esp32_get_reboot_type(void)
{ {
uint32_t *p = (uint32_t *)LWS_MAGIC_REBOOT_TYPE_ADS, val = *p; uint32_t *p = (uint32_t *)LWS_MAGIC_REBOOT_TYPE_ADS, val = *p;
@ -674,17 +692,178 @@ void lws_esp32_restart_guided(uint32_t type)
esp_restart(); esp_restart();
} }
/*
* esp-idf goes crazy with zero length str nvs. Use this as a workaround
* to delete the key in that case.
*/
esp_err_t lws_nvs_set_str(nvs_handle handle, const char* key, const char* value)
{
if (*value)
return nvs_set_str(handle, key, value);
return nvs_erase_key(handle, key);
}
static wifi_scan_config_t scan_config = {
.ssid = 0,
.bssid = 0,
.channel = 0,
.show_hidden = true
};
static char scan_ongoing = 0i, scan_timer_exists = 0;
static int try_slot = -1;
static wifi_config_t config = {
.ap = {
.channel = 6,
.authmode = WIFI_AUTH_OPEN,
.max_connection = 1,
} }, sta_config = {
.sta = {
.bssid_set = 0,
} };
static void lws_esp32_scan_timer_cb(TimerHandle_t th)
{
int n;
scan_ongoing = 0;
n = esp_wifi_scan_start(&scan_config, false);
if (n != ESP_OK)
lwsl_err("scan start failed %d\n", n);
}
static int
start_scan()
{
/* if no APs configured, no point... */
if (!lws_esp32.ssid[0][0] &&
!lws_esp32.ssid[1][0] &&
!lws_esp32.ssid[2][0] &&
!lws_esp32.ssid[3][0])
return 0;
if (scan_timer_exists && !scan_ongoing) {
scan_ongoing = 1;
xTimerStart(scan_timer, 0);
} else
lwsl_notice("%s: ignoring, no scan timer\n", __func__);
return 0;
}
static void
end_scan()
{
wifi_ap_record_t ap_records[10];
uint16_t count_ap_records;
int n, m;
count_ap_records = ARRAY_SIZE(ap_records);
if (esp_wifi_scan_get_ap_records(&count_ap_records, ap_records) != ESP_OK) {
lwsl_err("%s: failed\n", __func__);
return;
}
if (!count_ap_records)
goto passthru;
if (gapss != LWS_GAPSS_SCAN) {
lwsl_notice("ignoring scan as gapss %s\n", gapss_str[gapss]);
goto passthru;
}
/* no point if no APs set up */
if (!lws_esp32.ssid[0][0] &&
!lws_esp32.ssid[1][0] &&
!lws_esp32.ssid[2][0] &&
!lws_esp32.ssid[3][0])
goto passthru;
lwsl_notice("checking %d scan records\n", count_ap_records);
for (n = 0; n < 4; n++) {
if (!lws_esp32.ssid[(n + try_slot + 1) & 3][0])
continue;
lwsl_notice("looking for %s\n", lws_esp32.ssid[(n + try_slot + 1) & 3]);
/* this ssid appears in scan results? */
for (m = 0; m < count_ap_records; m++) {
// lwsl_notice(" %s\n", ap_records[m].ssid);
if (strcmp((char *)ap_records[m].ssid, lws_esp32.ssid[(n + try_slot + 1) & 3]) == 0)
goto hit;
}
continue;
hit:
m = (n + try_slot + 1) & 3;
try_slot = m;
lwsl_notice("Attempting connection with slot %d: %s:\n", m,
lws_esp32.ssid[m]);
/* set the ssid we last tried to connect to */
strncpy(lws_esp32.active_ssid, lws_esp32.ssid[m],
sizeof(lws_esp32.active_ssid) - 1);
lws_esp32.active_ssid[sizeof(lws_esp32.active_ssid) - 1] = '\0';
strncpy((char *)sta_config.sta.ssid, lws_esp32.ssid[m], sizeof(sta_config.sta.ssid) - 1);
strncpy((char *)sta_config.sta.password, lws_esp32.password[m], sizeof(sta_config.sta.password) - 1);
tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, (const char *)&config.ap.ssid[7]);
lws_gapss_to(LWS_GAPSS_STAT);
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
esp_wifi_connect();
mdns_init(TCPIP_ADAPTER_IF_STA, &lws_esp32.mdns);
mdns_set_hostname(lws_esp32.mdns, (const char *)&config.ap.ssid[7]);
mdns_set_instance(lws_esp32.mdns, "instance");
break;
}
if (n == 4)
start_scan();
passthru:
if (lws_esp32.scan_consumer)
lws_esp32.scan_consumer(count_ap_records, ap_records, lws_esp32.scan_consumer_arg);
}
esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event) esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
{ {
char slot[8];
nvs_handle nvh;
uint32_t use;
switch(event->event_id) { switch(event->event_id) {
case SYSTEM_EVENT_STA_START: case SYSTEM_EVENT_STA_START:
esp_wifi_connect(); //esp_wifi_connect();
break; // break;
/* fallthru */
case SYSTEM_EVENT_STA_DISCONNECTED: case SYSTEM_EVENT_STA_DISCONNECTED:
lwsl_notice("SYSTEM_EVENT_STA_DISCONNECTED\n");
lws_esp32.inet = 0; lws_esp32.inet = 0;
lws_esp32.sta_ip[0] = '\0';
lws_esp32.sta_mask[0] = '\0';
lws_esp32.sta_gw[0] = '\0';
lws_gapss_to(LWS_GAPSS_SCAN);
lws_esp32.inet = 0;
start_scan();
esp_wifi_connect(); esp_wifi_connect();
break; break;
case SYSTEM_EVENT_STA_GOT_IP: case SYSTEM_EVENT_STA_GOT_IP:
lwsl_notice("SYSTEM_EVENT_STA_GOT_IP\n");
lws_esp32.inet = 1; lws_esp32.inet = 1;
render_ip(lws_esp32.sta_ip, sizeof(lws_esp32.sta_ip) - 1, render_ip(lws_esp32.sta_ip, sizeof(lws_esp32.sta_ip) - 1,
(uint8_t *)&event->event_info.got_ip.ip_info.ip); (uint8_t *)&event->event_info.got_ip.ip_info.ip);
@ -692,8 +871,23 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event)
(uint8_t *)&event->event_info.got_ip.ip_info.netmask); (uint8_t *)&event->event_info.got_ip.ip_info.netmask);
render_ip(lws_esp32.sta_gw, sizeof(lws_esp32.sta_gw) - 1, render_ip(lws_esp32.sta_gw, sizeof(lws_esp32.sta_gw) - 1,
(uint8_t *)&event->event_info.got_ip.ip_info.gw); (uint8_t *)&event->event_info.got_ip.ip_info.gw);
lwsl_notice(" --- Got IP %s\n", lws_esp32.sta_ip);
if (!nvs_open("lws-station", NVS_READWRITE, &nvh)) {
lws_snprintf(slot, sizeof(slot) - 1, "%duse", try_slot);
use = 0;
nvs_get_u32(nvh, slot, &use);
nvs_set_u32(nvh, slot, use + 1);
nvs_commit(nvh);
nvs_close(nvh);
}
lws_gapss_to(LWS_GAPSS_STAT_HAPPY);
break; break;
case SYSTEM_EVENT_SCAN_DONE: case SYSTEM_EVENT_SCAN_DONE:
lwsl_notice("SYSTEM_EVENT_SCAN_DONE\n");
end_scan();
break; break;
default: default:
break; break;
@ -794,41 +988,38 @@ static const struct lws_plat_file_ops fops = {
.LWS_FOP_SEEK_CUR = esp32_lws_fops_seek_cur, .LWS_FOP_SEEK_CUR = esp32_lws_fops_seek_cur,
}; };
static wifi_config_t config = {
.ap = {
.channel = 6,
.authmode = WIFI_AUTH_OPEN,
.max_connection = 1,
} }, sta_config = {
.sta = {
.bssid_set = 0,
} };
int int
lws_esp32_wlan_nvs_get(int retry) lws_esp32_wlan_nvs_get(int retry)
{ {
nvs_handle nvh; nvs_handle nvh;
char r[2], lws_esp32_force_ap = 0; char r[2], lws_esp32_force_ap = 0, slot[12];
size_t s; size_t s;
uint8_t mac[6]; uint8_t mac[6];
int n, m;
esp_efuse_read_mac(mac); esp_efuse_mac_get_default(mac);
mac[5] |= 1; /* match the AP MAC */ mac[5] |= 1; /* match the AP MAC */
snprintf(lws_esp32.serial, sizeof(lws_esp32.serial) - 1, "%02X%02X%02X", mac[3], mac[4], mac[5]); snprintf(lws_esp32.serial, sizeof(lws_esp32.serial) - 1, "%02X%02X%02X", mac[3], mac[4], mac[5]);
ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh)); ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
s = sizeof(config.sta.ssid) - 1; config.sta.ssid[0] = '\0';
if (nvs_get_str(nvh, "ssid0", (char *)sta_config.sta.ssid, &s) != ESP_OK) config.sta.password[0] = '\0';
lws_esp32_force_ap = 1;
/* set the ssid we last tried to connect to */ for (n = 0; n < 4; n++) {
strncpy(lws_esp32.active_ssid, (char *)sta_config.sta.ssid, sizeof(lws_esp32.active_ssid) - 1); lws_snprintf(slot, sizeof(slot) - 1, "%dssid", n);
lws_esp32.active_ssid[sizeof(lws_esp32.active_ssid) - 1] = '\0'; s = sizeof(lws_esp32.ssid[0]) - 1;
lws_esp32.ssid[n][0] = '\0';
m = nvs_get_str(nvh, slot, lws_esp32.ssid[n], &s);
lwsl_notice("%s: %s: %d\n", slot, lws_esp32.ssid[n], m);
lws_snprintf(slot, sizeof(slot) - 1, "%dpassword", n);
s = sizeof(lws_esp32.password[0]) - 1;
lws_esp32.password[n][0] = '\0';
m = nvs_get_str(nvh, slot, lws_esp32.password[n], &s);
lwsl_notice("%s: %s: %d\n", slot, lws_esp32.password[n], m);
}
s = sizeof(config.sta.password) - 1;
if (nvs_get_str(nvh, "password0", (char *)sta_config.sta.password, &s) != ESP_OK)
lws_esp32_force_ap = 1;
s = sizeof(lws_esp32.serial) - 1; s = sizeof(lws_esp32.serial) - 1;
if (nvs_get_str(nvh, "serial", lws_esp32.serial, &s) != ESP_OK) if (nvs_get_str(nvh, "serial", lws_esp32.serial, &s) != ESP_OK)
lws_esp32_force_ap = 1; lws_esp32_force_ap = 1;
@ -857,15 +1048,8 @@ lws_esp32_wlan_nvs_get(int retry)
nvs_close(nvh); nvs_close(nvh);
if (retry && sta_config.sta.ssid[0]) { lws_gapss_to(LWS_GAPSS_SCAN);
tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, (const char *)&config.ap.ssid[7]); start_scan();
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config));
ESP_ERROR_CHECK( esp_wifi_connect());
ESP_ERROR_CHECK(mdns_init(TCPIP_ADAPTER_IF_STA, &lws_esp32.mdns));
mdns_set_hostname(lws_esp32.mdns, (const char *)&config.ap.ssid[7]);
mdns_set_instance(lws_esp32.mdns, "instance");
}
return lws_esp32_force_ap; return lws_esp32_force_ap;
} }
@ -873,6 +1057,26 @@ lws_esp32_wlan_nvs_get(int retry)
void void
lws_esp32_wlan_config(void) lws_esp32_wlan_config(void)
{ {
ledc_timer_config_t ledc_timer = {
.bit_num = LEDC_TIMER_13_BIT,
.freq_hz = 5000,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_num = LEDC_TIMER_0
};
ledc_timer_config(&ledc_timer);
/* user code needs to provide lws_esp32_leds_timer_cb */
leds_timer = xTimerCreate("lws_leds", pdMS_TO_TICKS(25), 1, NULL,
(TimerCallbackFunction_t)lws_esp32_leds_timer_cb);
scan_timer = xTimerCreate("lws_scan", pdMS_TO_TICKS(10000), 0, NULL,
(TimerCallbackFunction_t)lws_esp32_scan_timer_cb);
scan_timer_exists = 1;
xTimerStart(leds_timer, 0);
lws_esp32_wlan_nvs_get(0); lws_esp32_wlan_nvs_get(0);
tcpip_adapter_init(); tcpip_adapter_init();
} }
@ -891,6 +1095,8 @@ lws_esp32_wlan_start_ap(void)
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config)); ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config));
ESP_ERROR_CHECK( esp_wifi_start()); ESP_ERROR_CHECK( esp_wifi_start());
esp_wifi_scan_start(&scan_config, false);
if (sta_config.sta.ssid[0]) { if (sta_config.sta.ssid[0]) {
tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, (const char *)&config.ap.ssid[7]); tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, (const char *)&config.ap.ssid[7]);
esp_wifi_set_auto_connect(1); esp_wifi_set_auto_connect(1);
@ -1011,11 +1217,12 @@ lws_esp32_set_creation_defaults(struct lws_context_creation_info *info)
info->port = 443; info->port = 443;
info->fd_limit_per_thread = 30; info->fd_limit_per_thread = 30;
info->max_http_header_pool = 2; info->max_http_header_pool = 3;
info->max_http_header_data = 1024; info->max_http_header_data = 1024;
info->pt_serv_buf_size = 4096; info->pt_serv_buf_size = 4096;
info->keepalive_timeout = 5; info->keepalive_timeout = 30;
info->simultaneous_ssl_restriction = 2; info->timeout_secs = 30;
info->simultaneous_ssl_restriction = 3;
info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
@ -1068,20 +1275,6 @@ lws_esp32_init(struct lws_context_creation_info *info)
char buf[512]; char buf[512];
size_t s; size_t s;
int n; int n;
ledc_timer_config_t ledc_timer = {
.bit_num = LEDC_TIMER_13_BIT,
.freq_hz = 5000,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.timer_num = LEDC_TIMER_0
};
ledc_timer_config(&ledc_timer);
/* user code needs to provide lws_esp32_leds_timer_cb */
leds_timer = xTimerCreate("lws_leds", pdMS_TO_TICKS(25), 1, NULL,
(TimerCallbackFunction_t)lws_esp32_leds_timer_cb);
xTimerStart(leds_timer, 0);
ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh)); ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh));
n = 0; n = 0;

View file

@ -1473,6 +1473,7 @@ struct lws {
struct lws *pending_read_list_prev, *pending_read_list_next; struct lws *pending_read_list_prev, *pending_read_list_next;
#if defined(LWS_WITH_STATS) #if defined(LWS_WITH_STATS)
uint64_t accept_start_us; uint64_t accept_start_us;
char seen_rx;
#endif #endif
#endif #endif
#ifdef LWS_WITH_HTTP_PROXY #ifdef LWS_WITH_HTTP_PROXY

View file

@ -365,6 +365,15 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
return LWS_SSL_CAPABLE_ERROR; return LWS_SSL_CAPABLE_ERROR;
} }
#endif #endif
#if defined(LWS_WITH_STATS)
if (!wsi->seen_rx) {
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_MS_SSL_RX_DELAY,
time_in_microseconds() - wsi->accept_start_us);
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNS_HAD_RX, 1);
wsi->seen_rx = 1;
}
#endif
lwsl_debug("%p: SSL_read says %d\n", wsi, n); lwsl_debug("%p: SSL_read says %d\n", wsi, n);
/* manpage: returning 0 means connection shut down */ /* manpage: returning 0 means connection shut down */
@ -762,6 +771,7 @@ accepted:
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, 1); lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, 1);
#if defined(LWS_WITH_STATS) #if defined(LWS_WITH_STATS)
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, time_in_microseconds() - wsi->accept_start_us); lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, time_in_microseconds() - wsi->accept_start_us);
wsi->accept_start_us = time_in_microseconds();
#endif #endif
/* OK, we are accepted... give him some time to negotiate */ /* OK, we are accepted... give him some time to negotiate */

View file

@ -85,14 +85,14 @@ struct per_vhost_data__esplws_scan {
}; };
static const struct store_json store_json[] = { static const struct store_json store_json[] = {
{ "\"ssid0\":\"", "ssid0" }, { "\"ssid0\":\"", "0ssid" },
{ ",\"pw0\":\"", "password0" }, { ",\"pw0\":\"", "0password" },
{ "\"ssid1\":\"", "ssid1" }, { "\"ssid1\":\"", "1ssid" },
{ ",\"pw1\":\"", "password1" }, { ",\"pw1\":\"", "1password" },
{ "\"ssid2\":\"", "ssid2" }, { "\"ssid2\":\"", "2ssid" },
{ ",\"pw2\":\"", "password2" }, { ",\"pw2\":\"", "2password" },
{ "\"ssid3\":\"", "ssid3" }, { "\"ssid3\":\"", "3ssid" },
{ ",\"pw3\":\"", "password3" }, { ",\"pw3\":\"", "3password" },
{ ",\"access_pw\":\"", "access_pw" }, { ",\"access_pw\":\"", "access_pw" },
{ "{\"group\":\"", "group" }, { "{\"group\":\"", "group" },
{ "{\"role\":\"", "role" }, { "{\"role\":\"", "role" },
@ -106,9 +106,6 @@ static wifi_scan_config_t scan_config = {
.show_hidden = true .show_hidden = true
}; };
extern void (*lws_cb_scan_done)(void *);
extern void *lws_cb_scan_done_arg;
const esp_partition_t * const esp_partition_t *
ota_choose_part(void); ota_choose_part(void);
@ -130,7 +127,7 @@ enum enum_param_names {
static void static void
scan_finished(void *v); scan_finished(uint16_t count, wifi_ap_record_t *recs, void *v);
static int static int
esplws_simple_arg(char *dest, int len, const char *in, const char *match) esplws_simple_arg(char *dest, int len, const char *in, const char *match)
@ -161,8 +158,8 @@ scan_start(struct per_vhost_data__esplws_scan *vhd)
return; return;
vhd->scan_ongoing = 1; vhd->scan_ongoing = 1;
lws_cb_scan_done = scan_finished; lws_esp32.scan_consumer = scan_finished;
lws_cb_scan_done_arg = vhd; lws_esp32.scan_consumer_arg = vhd;
n = esp_wifi_scan_start(&scan_config, false); n = esp_wifi_scan_start(&scan_config, false);
if (n != ESP_OK) if (n != ESP_OK)
lwsl_err("scan start failed %d\n", n); lwsl_err("scan start failed %d\n", n);
@ -216,18 +213,21 @@ client_connection(struct per_vhost_data__esplws_scan *vhd, const char *file)
} }
static void static void
scan_finished(void *v) scan_finished(uint16_t count, wifi_ap_record_t *recs, void *v)
{ {
struct per_vhost_data__esplws_scan *vhd = v; struct per_vhost_data__esplws_scan *vhd = v;
struct per_session_data__esplws_scan *p = vhd->live_pss_list; struct per_session_data__esplws_scan *p = vhd->live_pss_list;
lwsl_notice("%s: count %d\n", __func__, count);
vhd->scan_ongoing = 0; vhd->scan_ongoing = 0;
vhd->count_ap_records = ARRAY_SIZE(vhd->ap_records); if (count < ARRAY_SIZE(vhd->ap_records))
if (esp_wifi_scan_get_ap_records(&vhd->count_ap_records, vhd->ap_records) != ESP_OK) { vhd->count_ap_records = count;
lwsl_err("%s: failed\n", __func__); else
return; vhd->count_ap_records = ARRAY_SIZE(vhd->ap_records);
}
memcpy(vhd->ap_records, recs, vhd->count_ap_records * sizeof(*recs));
while (p) { while (p) {
if (p->scan_state != SCAN_STATE_INITIAL && p->scan_state != SCAN_STATE_NONE) if (p->scan_state != SCAN_STATE_INITIAL && p->scan_state != SCAN_STATE_NONE)
@ -333,7 +333,6 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
vhd->vhost = lws_get_vhost(wsi); vhd->vhost = lws_get_vhost(wsi);
vhd->timer = xTimerCreate("x", pdMS_TO_TICKS(10000), 1, vhd, vhd->timer = xTimerCreate("x", pdMS_TO_TICKS(10000), 1, vhd,
(TimerCallbackFunction_t)timer_cb); (TimerCallbackFunction_t)timer_cb);
xTimerStart(vhd->timer, 0);
vhd->scan_ongoing = 0; vhd->scan_ongoing = 0;
strcpy(vhd->json, " { }"); strcpy(vhd->json, " { }");
scan_start(vhd); scan_start(vhd);
@ -347,6 +346,11 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
break; break;
case LWS_CALLBACK_ESTABLISHED: case LWS_CALLBACK_ESTABLISHED:
lwsl_notice("%s: ESTABLISHED\n", __func__);
if (!vhd->live_pss_list) {
scan_start(vhd);
xTimerStart(vhd->timer, 0);
}
vhd->count_live_pss++; vhd->count_live_pss++;
pss->next = vhd->live_pss_list; pss->next = vhd->live_pss_list;
vhd->live_pss_list = pss; vhd->live_pss_list = pss;
@ -374,7 +378,7 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
struct timeval t; struct timeval t;
uint8_t mac[6]; uint8_t mac[6];
struct lws_esp32_image i; struct lws_esp32_image i;
char img_factory[512], img_ota[512], group[16]; char img_factory[512], img_ota[512], group[16], role[16];
int grt; int grt;
case SCAN_STATE_INITIAL: case SCAN_STATE_INITIAL:
@ -385,7 +389,10 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
pss->last_send = t; pss->last_send = t;
ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh)); if (nvs_open("lws-station", NVS_READWRITE, &nvh)) {
lwsl_err("unable to open nvs\n");
return -1;
}
n = 0; n = 0;
if (nvs_get_blob(nvh, "ssl-pub.pem", NULL, &s) == ESP_OK) if (nvs_get_blob(nvh, "ssl-pub.pem", NULL, &s) == ESP_OK)
n = 1; n = 1;
@ -393,7 +400,9 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
n |= 2; n |= 2;
s = sizeof(group) - 1; s = sizeof(group) - 1;
group[0] = '\0'; group[0] = '\0';
role[0] = '\0';
nvs_get_str(nvh, "group", group, &s); nvs_get_str(nvh, "group", group, &s);
nvs_get_str(nvh, "role", role, &s);
nvs_close(nvh); nvs_close(nvh);
@ -405,7 +414,7 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
grt = lws_esp32_get_reboot_type(); grt = lws_esp32_get_reboot_type();
esp_efuse_read_mac(mac); esp_efuse_mac_get_default(mac);
strcpy(img_factory, " { \"date\": \"Empty\" }"); strcpy(img_factory, " { \"date\": \"Empty\" }");
strcpy(img_ota, " { \"date\": \"Empty\" }"); strcpy(img_ota, " { \"date\": \"Empty\" }");
@ -431,6 +440,7 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
" \"conn_mask\":\"%s\",\n" " \"conn_mask\":\"%s\",\n"
" \"conn_gw\":\"%s\",\n" " \"conn_gw\":\"%s\",\n"
" \"group\":\"%s\",\n" " \"group\":\"%s\",\n"
" \"role\":\"%s\",\n"
" \"img_factory\": %s,\n" " \"img_factory\": %s,\n"
" \"img_ota\": %s,\n", " \"img_ota\": %s,\n",
lws_esp32.model, lws_esp32.model,
@ -445,7 +455,7 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
lws_esp32.sta_ip, lws_esp32.sta_ip,
lws_esp32.sta_mask, lws_esp32.sta_mask,
lws_esp32.sta_gw, lws_esp32.sta_gw,
group, group, role,
img_factory, img_factory,
img_ota img_ota
); );
@ -486,13 +496,13 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason,
s = sizeof(ssid) - 1; s = sizeof(ssid) - 1;
ssid[0] = '\0'; ssid[0] = '\0';
lws_snprintf(name, sizeof(name) - 1, "ssid%d", m); lws_snprintf(name, sizeof(name) - 1, "%dssid", m);
nvs_get_str(nvh, name, ssid, &s); nvs_get_str(nvh, name, ssid, &s);
lws_snprintf(name, sizeof(name) - 1, "password%d", m); lws_snprintf(name, sizeof(name) - 1, "%dpassword", m);
s = 10; s = 10;
nvs_get_str(nvh, name, NULL, &s); nvs_get_str(nvh, name, NULL, &s);
pp = !!s; pp = !!s;
lws_snprintf(name, sizeof(name) - 1, "use%d", m); lws_snprintf(name, sizeof(name) - 1, "%duse", m);
nvs_get_u32(nvh, name, &use); nvs_get_u32(nvh, name, &use);
p += snprintf((char *)p, end - p, p += snprintf((char *)p, end - p,
@ -568,8 +578,8 @@ issue:
{ {
const char *sect = "\"app\": {", *b; const char *sect = "\"app\": {", *b;
nvs_handle nvh; nvs_handle nvh;
char p[64]; char p[64], use[6];
int n; int n, si = -1;
if (strstr((const char *)in, "identify")) { if (strstr((const char *)in, "identify")) {
lws_esp32_identify_physical_device(); lws_esp32_identify_physical_device();
@ -591,6 +601,11 @@ issue:
break; break;
} }
if (!esplws_simple_arg(p, sizeof(p), in, ",\"slot\":\""))
si = atoi(p);
lwsl_notice("si %d\n", si);
for (n = 0; n < ARRAY_SIZE(store_json); n++) { for (n = 0; n < ARRAY_SIZE(store_json); n++) {
if (esplws_simple_arg(p, sizeof(p), in, store_json[n].j)) if (esplws_simple_arg(p, sizeof(p), in, store_json[n].j))
continue; continue;
@ -599,7 +614,7 @@ issue:
if (n == 8 && lws_esp32_get_reboot_type() != LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON) if (n == 8 && lws_esp32_get_reboot_type() != LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON)
continue; continue;
lwsl_notice("%s '%s\n", store_json[n].nvs, p); //lwsl_notice("%s: %s '%s'\n", __func__, store_json[n].nvs, p);
if (n == 9) { if (n == 9) {
strncpy(lws_esp32.group, p, sizeof(lws_esp32.group) - 1); strncpy(lws_esp32.group, p, sizeof(lws_esp32.group) - 1);
lws_esp32.group[sizeof(lws_esp32.group) - 1] = '\0'; lws_esp32.group[sizeof(lws_esp32.group) - 1] = '\0';
@ -609,10 +624,29 @@ issue:
lws_esp32.role[sizeof(lws_esp32.role) - 1] = '\0'; lws_esp32.role[sizeof(lws_esp32.role) - 1] = '\0';
} }
if (nvs_set_str(nvh, store_json[n].nvs, p) != ESP_OK) { if (lws_nvs_set_str(nvh, store_json[n].nvs, p) != ESP_OK) {
lwsl_err("Unable to store %s in nvm\n", store_json[n].nvs); lwsl_err("Unable to store %s in nvm\n", store_json[n].nvs);
goto bail_nvs; goto bail_nvs;
} }
if (si != -1 && n < 8) {
if (!(n & 1)) {
strncpy(lws_esp32.ssid[(n >> 1) & 3], p,
sizeof(lws_esp32.ssid[0]));
lws_esp32.ssid[(n >> 1) & 3]
[sizeof(lws_esp32.ssid[0]) - 1] = '\0';
lws_snprintf(use, sizeof(use) - 1, "%duse", si);
lwsl_notice("resetting %s to 0\n", use);
nvs_set_u32(nvh, use, 0);
} else {
strncpy(lws_esp32.password[(n >> 1) & 3], p,
sizeof(lws_esp32.password[0]));
lws_esp32.password[(n >> 1) & 3]
[sizeof(lws_esp32.password[0]) - 1] = '\0';
}
}
} }
nvs_commit(nvh); nvs_commit(nvh);
@ -702,6 +736,8 @@ auton:
vhd->count_live_pss--; vhd->count_live_pss--;
} }
if (!vhd->live_pss_list)
xTimerStop(vhd->timer, 0);
break; break;
/* "factory" POST handling */ /* "factory" POST handling */
@ -738,7 +774,7 @@ auton:
if (lws_esp32_get_reboot_type() == LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON) { if (lws_esp32_get_reboot_type() == LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON) {
if (lws_spa_get_string(pss->spa, EPN_SERIAL)) { if (lws_spa_get_string(pss->spa, EPN_SERIAL)) {
if (nvs_set_str(nvh, "serial", lws_spa_get_string(pss->spa, EPN_SERIAL)) != ESP_OK) { if (lws_nvs_set_str(nvh, "serial", lws_spa_get_string(pss->spa, EPN_SERIAL)) != ESP_OK) {
lwsl_err("Unable to store serial in nvm\n"); lwsl_err("Unable to store serial in nvm\n");
goto bail_nvs; goto bail_nvs;
} }
@ -747,7 +783,7 @@ auton:
} }
if (lws_spa_get_string(pss->spa, EPN_OPTS)) { if (lws_spa_get_string(pss->spa, EPN_OPTS)) {
if (nvs_set_str(nvh, "opts", lws_spa_get_string(pss->spa, EPN_OPTS)) != ESP_OK) { if (lws_nvs_set_str(nvh, "opts", lws_spa_get_string(pss->spa, EPN_OPTS)) != ESP_OK) {
lwsl_err("Unable to store options in nvm\n"); lwsl_err("Unable to store options in nvm\n");
goto bail_nvs; goto bail_nvs;
} }