diff --git a/component.mk b/component.mk index 9afdeb6f..9b5235e1 100644 --- a/component.mk +++ b/component.mk @@ -19,12 +19,12 @@ endif build: cd $(COMPONENT_BUILD_DIR) ; \ echo "doing lws cmake" ; \ - cmake $(COMPONENT_PATH) -DLWS_C_FLAGS="$(CFLAGS) -DNDEBUG=1" \ + cmake $(COMPONENT_PATH) -DLWS_C_FLAGS="$(CFLAGS) " \ -DIDF_PATH=$(IDF_PATH) \ -DCROSS_PATH=$(CROSS_PATH) \ -DBUILD_DIR_BASE=$(BUILD_DIR_BASE) \ -DCMAKE_TOOLCHAIN_FILE=$(COMPONENT_PATH)/contrib/cross-esp32.cmake \ - -DCMAKE_BUILD_TYPE=RELEASE \ + -DCMAKE_BUILD_TYPE=DEBUG \ -DLWS_MBEDTLS_INCLUDE_DIRS="${IDF_PATH}/components/openssl/include;${IDF_PATH}/components/mbedtls/include;${IDF_PATH}/components/mbedtls/port/include" \ -DLWS_WITH_STATS=0 \ -DLWS_WITH_HTTP2=1 \ diff --git a/lib/alloc.c b/lib/alloc.c index 2060aac2..a7baca96 100644 --- a/lib/alloc.c +++ b/lib/alloc.c @@ -51,7 +51,7 @@ void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason)) static void *_realloc(void *ptr, size_t size, const char *reason) { if (size) { -#if defined(LWS_PLAT_ESP32) +#if defined(LWS_WITH_ESP32) lwsl_notice("%s: size %lu: %s\n", __func__, (unsigned long)size, reason); #else diff --git a/lib/handshake.c b/lib/handshake.c index a2f89333..e5a024b6 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -63,7 +63,7 @@ LWS_VISIBLE int lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len) { unsigned char *last_char, *oldbuf = buf; - lws_filepos_t body_chunk_len, inlen = len; + lws_filepos_t body_chunk_len; size_t n; switch (wsi->state) { @@ -105,7 +105,7 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len) buf += body_chunk_len; len -= body_chunk_len; } - lwsl_debug("%s: used up block of %d\n", __func__, (int)inlen); + lwsl_debug("%s: used up block\n", __func__); break; #endif @@ -271,7 +271,7 @@ postbody_completion: break; default: lwsl_err("%s: Unhandled state %d\n", __func__, wsi->state); - break; + goto bail; } read_ok: diff --git a/lib/http2/hpack.c b/lib/http2/hpack.c index 70aff4ac..f7fe9d36 100644 --- a/lib/http2/hpack.c +++ b/lib/http2/hpack.c @@ -594,12 +594,17 @@ lws_hpack_dynamic_size(struct lws *wsi, int size) dyn = &nwsi->h2.h2n->hpack_dyn_table; lwsl_info("%s: from %d to %d, lim %d\n", __func__, (int)dyn->num_entries, size, - nwsi->h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]); + nwsi->vhost->set.s[H2SET_HEADER_TABLE_SIZE]); - if (size > (int)nwsi->h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]) { + if (size > (int)nwsi->vhost->set.s[H2SET_HEADER_TABLE_SIZE]) { + lwsl_notice("rejecting hpack dyn size %u\n", size); +#if defined(LWS_WITH_ESP32) + size = nwsi->vhost->set.s[H2SET_HEADER_TABLE_SIZE]; +#else lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR, "Asked for header table bigger than we told"); goto bail; +#endif } dyn->virtual_payload_max = size; @@ -615,6 +620,8 @@ lws_hpack_dynamic_size(struct lws *wsi, int size) if (dyn->num_entries < min) min = dyn->num_entries; + // lwsl_notice("dte requested size %d\n", size); + dte = lws_zalloc(sizeof(*dte) * (size + 1), "dynamic table entries"); if (!dte) goto bail; diff --git a/lib/http2/http2.c b/lib/http2/http2.c index e69bb0d4..cdbf5020 100644 --- a/lib/http2/http2.c +++ b/lib/http2/http2.c @@ -540,7 +540,7 @@ int lws_h2_do_pps_send(struct lws *wsi) case LWS_H2_PPS_MY_SETTINGS: /* * if any of our settings varies from h2 "default defaults" - * then we must inform the perr + * then we must inform the peer */ for (n = 1; n < H2SET_COUNT; n++) if (h2n->set.s[n] != lws_h2_defaults.s[n]) { @@ -691,7 +691,7 @@ bail: /* * The frame header part has just completely arrived. - * Perform actions for frame completion. + * Perform actions for header completion. */ static int lws_h2_parse_frame_header(struct lws *wsi) @@ -1488,6 +1488,8 @@ lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen, h2n->inside += n; h2n->count += n - 1; + lwsl_notice("%s: count %d len %d\n", __func__, (int)h2n->count, (int)h2n->length); + break; case LWS_H2_FRAME_TYPE_PRIORITY: diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 90120eea..b1c3ff3b 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -741,7 +741,6 @@ just_kill_connection: if (wsi->protocol && !wsi->told_user_closed && wsi->protocol->callback && wsi->mode != LWSCM_RAW && (wsi->state_pre_close & _LSF_CCB)) { - lwsl_debug("calling back CLOSED %d %d\n", wsi->mode, wsi->state); wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED, wsi->user_space, NULL, 0); } else if (wsi->mode == LWSCM_HTTP_SERVING_ACCEPTED) { diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index a695b66f..f8d57050 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -658,6 +658,8 @@ struct lws_esp32 { void *scan_consumer_arg; struct lws_group_member *first; int extant_group_members; + + volatile char button_is_down; }; struct lws_esp32_image { diff --git a/lib/plat/lws-plat-esp32.c b/lib/plat/lws-plat-esp32.c index efc1291a..4344ebd9 100644 --- a/lib/plat/lws-plat-esp32.c +++ b/lib/plat/lws-plat-esp32.c @@ -1,5 +1,5 @@ /* - * libwebsockets - small server side websockets and web server implementation + * libwebsockets - lib/plat/lws-plat-esp32.c * * Copyright (C) 2010-2017 Andy Green * @@ -24,6 +24,11 @@ #include #include +#include "apps/sntp/sntp.h" + +#include +#include + int lws_plat_socket_offset(void) { @@ -72,18 +77,20 @@ lws_send_pipe_choked(struct lws *wsi) #if defined(LWS_WITH_HTTP2) wsi_eff = lws_get_network_wsi(wsi); #endif + int n; /* treat the fact we got a truncated send pending as if we're choked */ if (wsi_eff->trunc_len) return 1; FD_ZERO(&writefds); - FD_SET(wsi_eff->desc.sockfd, &writefds); + FD_SET(wsi_eff->desc.sockfd - LWIP_SOCKET_OFFSET, &writefds); - if (select(wsi_eff->desc.sockfd + 1, NULL, &writefds, NULL, &tv) < 1) - return 1; + n = select(wsi_eff->desc.sockfd + 1, NULL, &writefds, NULL, &tv); + if (n < 0) + return 1; /* choked */ - return 0; + return !n; /* n = 0 = not writable = choked */ } LWS_VISIBLE int @@ -93,7 +100,7 @@ lws_poll_listen_fd(struct lws_pollfd *fd) struct timeval tv = { 0, 0 }; FD_ZERO(&readfds); - FD_SET(fd->fd, &readfds); + FD_SET(fd->fd - LWIP_SOCKET_OFFSET, &readfds); return select(fd->fd + 1, &readfds, NULL, NULL, &tv); } @@ -139,16 +146,16 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) goto faked_service; if (!context->service_tid_detected) { - struct lws _lws; + struct lws *_lws = lws_zalloc(sizeof(*_lws), "tid probe"); - memset(&_lws, 0, sizeof(_lws)); - _lws.context = context; + _lws->context = context; context->service_tid_detected = context->vhost_list->protocols[0].callback( - &_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); + _lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); context->service_tid = context->service_tid_detected; context->service_tid_detected = 1; + lws_free(_lws); } /* @@ -178,24 +185,35 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) if (pt->fds[n].fd >= max_fd) max_fd = pt->fds[n].fd; if (pt->fds[n].events & LWS_POLLIN) - FD_SET(pt->fds[n].fd, &readfds); + FD_SET(pt->fds[n].fd - LWIP_SOCKET_OFFSET, &readfds); if (pt->fds[n].events & LWS_POLLOUT) - FD_SET(pt->fds[n].fd, &writefds); - FD_SET(pt->fds[n].fd, &errfds); + FD_SET(pt->fds[n].fd - LWIP_SOCKET_OFFSET, &writefds); + FD_SET(pt->fds[n].fd - LWIP_SOCKET_OFFSET, &errfds); } n = select(max_fd + 1, &readfds, &writefds, &errfds, ptv); - for (n = 0; n < pt->fds_count; n++) { - if (FD_ISSET(pt->fds[n].fd, &readfds)) - pt->fds[n].revents |= LWS_POLLIN; - if (FD_ISSET(pt->fds[n].fd, &writefds)) - pt->fds[n].revents |= LWS_POLLOUT; - if (FD_ISSET(pt->fds[n].fd, &errfds)) - pt->fds[n].revents |= LWS_POLLHUP; + n = 0; + for (m = 0; m < pt->fds_count; m++) { + c = 0; + if (FD_ISSET(pt->fds[m].fd - LWIP_SOCKET_OFFSET, &readfds)) { + pt->fds[m].revents |= LWS_POLLIN; + c = 1; + } + if (FD_ISSET(pt->fds[m].fd - LWIP_SOCKET_OFFSET, &writefds)) { + pt->fds[m].revents |= LWS_POLLOUT; + c = 1; + } + if (FD_ISSET(pt->fds[m].fd - LWIP_SOCKET_OFFSET, &errfds)) { + // lwsl_notice("errfds %d\n", pt->fds[m].fd); + pt->fds[m].revents |= LWS_POLLHUP; + c = 1; + } + + if (c) + n++; } } - #ifdef LWS_OPENSSL_SUPPORT if (!pt->rx_draining_ext_list && !lws_ssl_anybody_has_buffered_read_tsi(context, tsi) && !n) { @@ -245,7 +263,12 @@ lws_plat_check_connection_error(struct lws *wsi) LWS_VISIBLE int lws_plat_service(struct lws_context *context, int timeout_ms) { - return _lws_plat_service_tsi(context, timeout_ms, 0); + int n = _lws_plat_service_tsi(context, timeout_ms, 0); + + lws_service_fd_tsi(context, NULL, 0); + esp_task_wdt_reset(); + + return n; } LWS_VISIBLE int @@ -627,41 +650,46 @@ struct lws_esp32 lws_esp32 = { */ enum lws_gapss { - LWS_GAPSS_INITIAL, /* just started up, init and move to LWS_GAPSS_SCAN */ + LWS_GAPSS_INITIAL, /* just started up, init and move to + * LWS_GAPSS_SCAN */ LWS_GAPSS_SCAN, /* - * Unconnected, scanning: AP known in one of the config - * slots -> configure it, start timeout + LWS_GAPSS_STAT, - * if no AP already up in same group with lower MAC, - * after a random period start up our AP (LWS_GAPSS_AP) + * Unconnected, scanning: AP known in one of the + * config slots -> configure it, start timeout + + * LWS_GAPSS_STAT, if no AP already up in same + * group with lower MAC, after a random period + * start up our AP (LWS_GAPSS_AP) */ LWS_GAPSS_AP, /* - * Trying to be the group AP... periodically do a scan - * LWS_GAPSS_AP_SCAN, faster and then slower + * Trying to be the group AP... periodically do + * a scan LWS_GAPSS_AP_SCAN, faster and then + * slower */ LWS_GAPSS_AP_SCAN, /* - * doing a scan while trying to be the group AP... if - * we see a lower MAC being the AP for the same group - * AP, abandon being an AP and join that AP as a - * station + * doing a scan while trying to be the group + * AP... if we see a lower MAC being the AP for + * the same group AP, abandon being an AP and + * join that AP as a station */ LWS_GAPSS_STAT_GRP_AP, /* - * We have decided to join another group member who is - * being the AP, as its MAC is lower than ours. This - * is a stable state, but we still do periodic scans - * (LWS_GAPSS_STAT_GRP_AP_SCAN) and will always prefer - * an AP configured in a slot. + * We have decided to join another group member + * who is being the AP, as its MAC is lower than + * ours. This is a stable state, but we still + * do periodic scans LWS_GAPSS_STAT_GRP_AP_SCAN + * and will always prefer an AP configured in a + * slot. */ LWS_GAPSS_STAT_GRP_AP_SCAN, /* - * We have joined a group member who is doing the AP - * job... we want to check every now and then if a - * configured AP has appeared that we should better - * use instead. Otherwise stay in LWS_GAPSS_STAT_GRP_AP + * We have joined a group member who is doing + * the AP job... we want to check every now and + * then if a configured AP has appeared that we + * should better use instead. Otherwise stay in + * LWS_GAPSS_STAT_GRP_AP */ LWS_GAPSS_STAT, /* - * trying to connect to another non-group AP. If we - * don't get an IP within a timeout and retries, - * blacklist it and go back + * trying to connect to another non-group AP. + * If we don't get an IP within a timeout and + * retries, blacklist it and go back */ LWS_GAPSS_STAT_HAPPY, }; @@ -684,7 +712,6 @@ static TimerHandle_t leds_timer, scan_timer, debounce_timer #endif ; static enum lws_gapss gapss = LWS_GAPSS_INITIAL; -static char bdown; #define GPIO_SW 14 @@ -932,19 +959,20 @@ lws_esp32_button(int down) void IRAM_ATTR gpio_irq(void *arg) { - bdown ^= 1; gpio_set_intr_type(GPIO_SW, GPIO_INTR_DISABLE); xTimerStart(debounce_timer, 0); - - lws_esp32_button(bdown); } static void lws_esp32_debounce_timer_cb(TimerHandle_t th) { - if (bdown) + if (lws_esp32.button_is_down) gpio_set_intr_type(GPIO_SW, GPIO_INTR_POSEDGE); else gpio_set_intr_type(GPIO_SW, GPIO_INTR_NEGEDGE); + + lws_esp32.button_is_down = gpio_get_level(GPIO_SW); + + lws_esp32_button(lws_esp32.button_is_down); } @@ -978,7 +1006,7 @@ end_scan() int n, m; count_ap_records = ARRAY_SIZE(ap_records); - if (esp_wifi_scan_get_ap_records(&count_ap_records, ap_records) != ESP_OK) { + if (esp_wifi_scan_get_ap_records(&count_ap_records, ap_records)) { lwsl_err("%s: failed\n", __func__); return; } @@ -1005,13 +1033,15 @@ end_scan() 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]); + 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) + if (!strcmp((char *)ap_records[m].ssid, + lws_esp32.ssid[(n + try_slot + 1) & 3])) goto hit; } @@ -1027,10 +1057,13 @@ hit: 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); + 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]); + 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); @@ -1043,7 +1076,8 @@ hit: passthru: if (lws_esp32.scan_consumer) - lws_esp32.scan_consumer(count_ap_records, ap_records, lws_esp32.scan_consumer_arg); + lws_esp32.scan_consumer(count_ap_records, ap_records, + lws_esp32.scan_consumer_arg); } @@ -1120,6 +1154,8 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event) /* fallthru */ case SYSTEM_EVENT_STA_DISCONNECTED: lwsl_notice("SYSTEM_EVENT_STA_DISCONNECTED\n"); + if (sntp_enabled()) + sntp_stop(); lws_esp32.conn_ap = 0; lws_esp32.inet = 0; lws_esp32.sta_ip[0] = '\0'; @@ -1203,7 +1239,8 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event) } if (!mem) { - struct lws_group_member *mem = lws_malloc(sizeof(*mem), "group"); + struct lws_group_member *mem = + lws_malloc(sizeof(*mem), "group"); if (mem) { mem->last_seen = ~(uint64_t)0; strcpy(mem->model, lws_esp32.model); @@ -1211,27 +1248,35 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event) strcpy(mem->host, lws_esp32.hostname); strcpy(mem->mac, lws_esp32.mac); mem->flags = LWS_GROUP_FLAG_SELF; - lws_get_iframe_size(&mem->width, &mem->height); - memcpy(&mem->addr, &event->event_info.got_ip.ip_info.ip, - sizeof(mem->addr)); - memcpy(&mem->addrv6, &event->event_info.got_ip6.ip6_info.ip, - sizeof(mem->addrv6)); + lws_get_iframe_size(&mem->width, + &mem->height); + memcpy(&mem->addr, + &event->event_info.got_ip.ip_info.ip, + sizeof(mem->addr)); + memcpy(&mem->addrv6, + &event->event_info.got_ip6.ip6_info.ip, + sizeof(mem->addrv6)); mem->next = lws_esp32.first; lws_esp32.first = mem; lws_esp32.extant_group_members++; - lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_ADD, mem); + lws_group_member_event_call( + LWS_SYSTEM_GROUP_MEMBER_ADD, mem); } } else { /* update our IP */ - memcpy(&mem->addr, &event->event_info.got_ip.ip_info.ip, - sizeof(mem->addr)); - memcpy(&mem->addrv6, &event->event_info.got_ip6.ip6_info.ip, - sizeof(mem->addrv6)); - lws_group_member_event_call(LWS_SYSTEM_GROUP_MEMBER_CHANGE, mem); + memcpy(&mem->addr, + &event->event_info.got_ip.ip_info.ip, + sizeof(mem->addr)); + memcpy(&mem->addrv6, + &event->event_info.got_ip6.ip6_info.ip, + sizeof(mem->addrv6)); + lws_group_member_event_call( + LWS_SYSTEM_GROUP_MEMBER_CHANGE, mem); } - if (mdns_service_txt_set(lws_esp32.mdns, "_lwsgrmem", "_tcp", ARRAY_SIZE(txta), + if (mdns_service_txt_set(lws_esp32.mdns, "_lwsgrmem", + "_tcp", ARRAY_SIZE(txta), (const char **)txta)) lwsl_notice("txt set failed\n"); } else @@ -1242,6 +1287,11 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event) #endif lwsl_notice(" --- Got IP %s\n", lws_esp32.sta_ip); + if (!sntp_enabled()) { + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, "pool.ntp.org"); + sntp_init(); + } break; case SYSTEM_EVENT_SCAN_DONE: @@ -1258,7 +1308,7 @@ esp_err_t lws_esp32_event_passthru(void *ctx, system_event_t *event) static lws_fop_fd_t IRAM_ATTR esp32_lws_fops_open(const struct lws_plat_file_ops *fops, const char *filename, - const char *vfs_path, lws_fop_flags_t *flags) + const char *vfs_path, lws_fop_flags_t *flags) { struct esp32_file *f = malloc(sizeof(*f)); lws_fop_fd_t fop_fd; @@ -1359,9 +1409,11 @@ lws_esp32_wlan_nvs_get(int retry) esp_efuse_mac_get_default(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.mac, sizeof(lws_esp32.mac) - 1, "%02X%02X%02X%02X%02X%02X", mac[0], - mac[1], mac[2], mac[3], mac[4], mac[5]); + snprintf(lws_esp32.serial, sizeof(lws_esp32.serial) - 1, + "%02X%02X%02X", mac[3], mac[4], mac[5]); + snprintf(lws_esp32.mac, sizeof(lws_esp32.mac) - 1, + "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], + mac[4], mac[5]); ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh)); @@ -1489,7 +1541,8 @@ lws_esp32_wlan_start_ap(void) esp_wifi_scan_start(&scan_config, false); 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_ERROR_CHECK( esp_wifi_connect()); ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config)); @@ -1510,7 +1563,8 @@ lws_esp32_wlan_start_station(void) ESP_ERROR_CHECK( esp_wifi_start()); - 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_ERROR_CHECK( esp_wifi_connect()); @@ -1520,7 +1574,8 @@ lws_esp32_wlan_start_station(void) const esp_partition_t * lws_esp_ota_get_boot_partition(void) { - const esp_partition_t *part = esp_ota_get_boot_partition(), *factory_part, *ota; + const esp_partition_t *part = esp_ota_get_boot_partition(), + *factory_part, *ota; esp_image_header_t eih, ota_eih; uint32_t *p_force_factory_magic = (uint32_t *)LWS_MAGIC_REBOOT_TYPE_ADS; @@ -1535,7 +1590,7 @@ lws_esp_ota_get_boot_partition(void) if (eih.spi_mode == 0xff || *p_force_factory_magic == LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY || *p_force_factory_magic == LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON - ) { + ) { /* * we believed we were going to boot OTA, but we fell * back to FACTORY in the bootloader when we saw it @@ -1557,18 +1612,22 @@ lws_esp_ota_get_boot_partition(void) * it means we were just written and need to copy * ourselves into the FACTORY slot. */ - lwsl_notice("Copying FACTORY update into place 0x%x len 0x%x\n", - factory_part->address, factory_part->size); - esp_task_wdt_feed(); - if (spi_flash_erase_range(factory_part->address, factory_part->size) != ESP_OK) { + lwsl_notice("Copying FACTORY update into place " + "0x%x len 0x%x\n", factory_part->address, + factory_part->size); + esp_task_wdt_reset(); + if (spi_flash_erase_range(factory_part->address, + factory_part->size)) { lwsl_err("spi: Failed to erase\n"); goto retry; } for (n = 0; n < factory_part->size; n += sizeof(buf)) { - esp_task_wdt_feed(); - spi_flash_read(part->address + n , buf, sizeof(buf)); - if (spi_flash_write(factory_part->address + n, buf, sizeof(buf)) != ESP_OK) { + esp_task_wdt_reset(); + spi_flash_read(part->address + n , buf, + sizeof(buf)); + if (spi_flash_write(factory_part->address + n, + buf, sizeof(buf))) { lwsl_err("spi: Failed to write\n"); goto retry; } @@ -1578,8 +1637,8 @@ lws_esp_ota_get_boot_partition(void) spi_flash_erase_range(ota->address, 4096); /* - * with no viable OTA image, we will come back up in factory - * where the user can reload the OTA image + * with no viable OTA image, we will come back up in + * factory where the user can reload the OTA image */ lwsl_notice(" FACTORY copy successful, rebooting\n"); retry: @@ -1613,10 +1672,7 @@ lws_esp32_set_creation_defaults(struct lws_context_creation_info *info) info->timeout_secs = 30; info->simultaneous_ssl_restriction = 4; info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | - LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - -// info->ssl_cert_filepath = "default-cert.pem"; -// info->ssl_private_key_filepath = "default-key.pem"; + LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; } int @@ -1630,8 +1686,10 @@ lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i, spi_flash_read(part->address , &eih, sizeof(eih)); hdr = part->address + sizeof(eih); - if (eih.magic != ESP_IMAGE_HEADER_MAGIC) + if (eih.magic != ESP_IMAGE_HEADER_MAGIC) { + lwsl_notice("%s: bad image header magic\n", __func__); return 1; + } eis.data_len = 0; while (eih.segment_count-- && eis.data_len != 0xffffffff) { @@ -1810,7 +1868,8 @@ lws_esp32_init(struct lws_context_creation_info *info, struct lws_vhost **pvh) lws_esp32_romfs = (romfs_t)i.romfs; if (!romfs_mount_check(lws_esp32_romfs)) { - lwsl_err("Failed to mount ROMFS at %p 0x%x\n", lws_esp32_romfs, i.romfs); + lwsl_err("mount error on ROMFS at %p 0x%x\n", lws_esp32_romfs, + i.romfs); return NULL; } diff --git a/lib/pollfd.c b/lib/pollfd.c index 25c94827..8f44d1e8 100644 --- a/lib/pollfd.c +++ b/lib/pollfd.c @@ -127,7 +127,7 @@ _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa) pfd = &pt->fds[wsi->position_in_fds_table]; pa->fd = wsi->desc.sockfd; - lwsl_debug("%s: fd %d old events %d\n", __func__, pa->fd, pfd->events); + lwsl_debug("%s: wsi %p: fd %d events %d -> %d\n", __func__, wsi, pa->fd, pfd->events, (pfd->events & ~_and) | _or); pa->prev_events = pfd->events; pa->events = pfd->events = (pfd->events & ~_and) | _or; diff --git a/lib/service.c b/lib/service.c index 7a0196c5..cd13aa12 100644 --- a/lib/service.c +++ b/lib/service.c @@ -1029,7 +1029,6 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, #endif lws_plat_service_periodic(context); - lws_check_deferred_free(context, 0); #if defined(LWS_WITH_PEER_LIMITS) @@ -1060,7 +1059,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, /* we have to take copies, because he may be deleted */ wsi1 = wsi->timeout_list; tmp_fd = wsi->desc.sockfd; - if (lws_service_timeout_check(wsi, (unsigned int)now)) { + if (lws_service_timeout_check(wsi, now)) { /* he did time out... */ if (tmp_fd == our_fd) /* it was the guy we came to service! */ @@ -1082,8 +1081,9 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, const unsigned char *c; if (!ah->in_use || !ah->wsi || !ah->assigned || - (ah->wsi->vhost && now - ah->assigned < - ah->wsi->vhost->timeout_secs_ah_idle + 60)) { + (ah->wsi->vhost && + lws_compare_time_t(context, now, ah->assigned) < + ah->wsi->vhost->timeout_secs_ah_idle + 360)) { ah = ah->next; continue; } @@ -1174,7 +1174,9 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, !wsi->socket_is_permanently_unusable && !wsi->ws->send_check_ping && wsi->ws->time_next_ping_check && - wsi->ws->time_next_ping_check < now) { + lws_compare_time_t(context, now, + wsi->ws->time_next_ping_check) > + context->ws_ping_pong_interval) { lwsl_info("req pp on wsi %p\n", wsi); @@ -1184,9 +1186,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, context->timeout_secs); lws_callback_on_writable(wsi); wsi->ws->time_next_ping_check = - now + - wsi->context-> - ws_ping_pong_interval; + now; } wsi = wsi->same_vh_protocol_next; } @@ -1195,14 +1195,15 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, } } +#ifdef LWS_OPENSSL_SUPPORT /* * check the remaining cert lifetime daily */ - if (context->last_cert_check_s < now - (24 * 60 * 60)) { + n = lws_compare_time_t(context, now, context->last_cert_check_s); + if ((!context->last_cert_check_s || n > (24 * 60 * 60)) && + !lws_tls_check_all_cert_lifetimes(context)) context->last_cert_check_s = now; - - lws_tls_check_all_cert_lifetimes(context); - } +#endif /* the socket we came to service timed out, nothing to do */ if (timed_out) @@ -1214,7 +1215,6 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, /* no, here to service a socket descriptor */ wsi = wsi_from_fd(context, pollfd->fd); - if (!wsi) /* not lws connection ... leave revents alone and return */ return 0; @@ -1639,9 +1639,6 @@ drain: if (wsi->ah) { lwsl_debug("%s: %p: detaching\n", __func__, wsi); lws_header_table_force_to_detachable_state(wsi); - /* we can run the normal ah detach flow despite - * being in ws union mode, since all union members - * start with hdr */ lws_header_table_detach(wsi, 0); } diff --git a/lib/tls/mbedtls/ssl.c b/lib/tls/mbedtls/ssl.c index f46eabaa..57d75c19 100644 --- a/lib/tls/mbedtls/ssl.c +++ b/lib/tls/mbedtls/ssl.c @@ -191,7 +191,6 @@ lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len) if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->ssl)) { lws_set_blocking_send(wsi); - lwsl_notice("%s: want write\n", __func__); return LWS_SSL_CAPABLE_MORE_SERVICE; diff --git a/plugins/protocol_esp32_lws_ota.c b/plugins/protocol_esp32_lws_ota.c index d3e8808d..cfb5748b 100644 --- a/plugins/protocol_esp32_lws_ota.c +++ b/plugins/protocol_esp32_lws_ota.c @@ -192,8 +192,8 @@ callback_esplws_ota(struct lws *wsi, enum lws_callback_reasons reason, case LWS_CALLBACK_HTTP_BODY: /* create the POST argument parser if not already existing */ - //lwsl_notice("LWS_CALLBACK_HTTP_BODY (ota) %d %d %p\n", (int)pss->file_length, (int)len, pss->spa); - lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, 5); + // lwsl_notice("LWS_CALLBACK_HTTP_BODY (ota) %d %d %p\n", (int)pss->file_length, (int)len, pss->spa); + lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, 30); if (!pss->spa) { pss->spa = lws_spa_create(wsi, ota_param_names, ARRAY_SIZE(ota_param_names), 4096, diff --git a/plugins/protocol_esp32_lws_scan.c b/plugins/protocol_esp32_lws_scan.c index 019172c9..0030700d 100644 --- a/plugins/protocol_esp32_lws_scan.c +++ b/plugins/protocol_esp32_lws_scan.c @@ -69,8 +69,10 @@ struct per_vhost_data__esplws_scan { long file_length; long content_length; + int cert_remaining_days; + struct lws *cwsi; - char json[1024]; + char json[2048]; int json_len; uint16_t count_ap_records; @@ -249,7 +251,7 @@ scan_finished(uint16_t count, wifi_ap_record_t *recs, void *v) esp_wifi_connect(); } -static const char *ssl_names[] = { "ssl-pub.pem", "ssl-pri.pem" }; +static const char *ssl_names[] = { "ap-cert.pem", "ap-key.pem" }; static int file_upload_cb(void *data, const char *name, const char *filename, @@ -292,6 +294,7 @@ file_upload_cb(void *data, const char *name, const char *filename, n = 0; if (!strcmp(name, "pri")) n = 1; + lwsl_notice("writing %s\n", ssl_names[n]); n = nvs_set_blob(pss->nvh, ssl_names[n], pss->buffer, pss->file_length); if (n == ESP_OK) nvs_commit(pss->nvh); @@ -316,6 +319,9 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, lws_get_protocol(wsi)); unsigned char *start = pss->buffer + LWS_PRE - 1, *p = start, *end = pss->buffer + sizeof(pss->buffer) - 1; + union lws_tls_cert_info_results ir; + char subject[64]; + const char *pp; wifi_ap_record_t *r; int n, m; nvs_handle nvh; @@ -362,7 +368,6 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, break; case LWS_CALLBACK_SERVER_WRITEABLE: - if (vhd->autonomous_update_sampled) { p += snprintf((char *)p, end - p, " {\n \"auton\":\"1\",\n \"pos\": \"%ld\",\n" @@ -381,11 +386,15 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, char img_factory[384], img_ota[384], group[16], role[16]; int grt; + case SCAN_STATE_NONE: + + /* fallthru */ + case SCAN_STATE_INITIAL: gettimeofday(&t, NULL); - if (t.tv_sec - pss->last_send.tv_sec < 10) - return 0; + // if (t.tv_sec - pss->last_send.tv_sec < 10) + // return 0; pss->last_send = t; @@ -394,9 +403,9 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, return -1; } n = 0; - if (nvs_get_blob(nvh, "ssl-pub.pem", NULL, &s) == ESP_OK) + if (nvs_get_blob(nvh, "ap-cert.pem", NULL, &s) == ESP_OK) n = 1; - if (nvs_get_blob(nvh, "ssl-pri.pem", NULL, &s) == ESP_OK) + if (nvs_get_blob(nvh, "ap-key.pem", NULL, &s) == ESP_OK) n |= 2; s = sizeof(group) - 1; group[0] = '\0'; @@ -406,6 +415,26 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, nvs_close(nvh); + ir.ns.name[0] = '\0'; + subject[0] = '\0'; + + if (t.tv_sec > 1464083026 && + !lws_tls_vhost_cert_info(vhd->vhost, + LWS_TLS_CERT_INFO_VALIDITY_TO, &ir, 0)) { + vhd->cert_remaining_days = + (ir.time - t.tv_sec) / (24 * 3600); + ir.ns.name[0] = '\0'; + lws_tls_vhost_cert_info(vhd->vhost, + LWS_TLS_CERT_INFO_COMMON_NAME, &ir, + sizeof(ir.ns.name)); + strncpy(subject, ir.ns.name, sizeof(subject) - 1); + + ir.ns.name[0] = '\0'; + lws_tls_vhost_cert_info(vhd->vhost, + LWS_TLS_CERT_INFO_ISSUER_NAME, &ir, + sizeof(ir.ns.name)); + } + /* * this value in the JSON is just * used for UI indication. Each conditional feature confirms @@ -418,7 +447,7 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, strcpy(img_factory, " { \"date\": \"Empty\" }"); strcpy(img_ota, " { \"date\": \"Empty\" }"); - if (grt != LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON) { + // if (grt != LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON) { lws_esp32_get_image_info(esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL), &i, img_factory, sizeof(img_factory) - 1); @@ -432,7 +461,7 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, img_ota[sizeof(img_ota) - 1] = '\0'; if (img_ota[0] == 0xff || strlen(img_ota) < 8) strcpy(img_ota, " { \"date\": \"Empty\" }"); - } + // } p += snprintf((char *)p, end - p, "{ \"model\":\"%s\",\n" @@ -448,6 +477,11 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, " \"conn_ip\":\"%s\",\n" " \"conn_mask\":\"%s\",\n" " \"conn_gw\":\"%s\",\n" + " \"certdays\":\"%d\",\n" + " \"unixtime\":\"%llu\",\n" + " \"certissuer\":\"%s\",\n" + " \"certsubject\":\"%s\",\n" + " \"button\":\"%d\",\n" " \"group\":\"%s\",\n" " \"role\":\"%s\",\n", lws_esp32.model, @@ -462,6 +496,10 @@ callback_esplws_scan(struct lws *wsi, enum lws_callback_reasons reason, lws_esp32.sta_ip, lws_esp32.sta_mask, lws_esp32.sta_gw, + vhd->cert_remaining_days, + (unsigned long long)t.tv_sec, + ir.ns.name, subject, + ((volatile struct lws_esp32 *)(&lws_esp32))->button_is_down, group, role); p += snprintf((char *)p, end - p, " \"img_factory\": %s,\n" @@ -573,7 +611,6 @@ scan_state_final: return 0; } issue: -// lwsl_notice("issue: %d (%d)\n", p - start, n); m = lws_write(wsi, (unsigned char *)start, p - start, n); if (m < 0) { lwsl_err("ERROR %d writing to di socket\n", m); @@ -755,7 +792,6 @@ auton: case LWS_CALLBACK_HTTP_BODY: /* create the POST argument parser if not already existing */ - lwsl_notice("LWS_CALLBACK_HTTP_BODY (scan)\n"); if (!pss->spa) { pss->spa = lws_spa_create(wsi, param_names, ARRAY_SIZE(param_names), 1024, @@ -804,10 +840,13 @@ auton: } nvs_close(nvh); + pp = lws_spa_get_string(pss->spa, EPN_SERIAL); + if (!pp) + pp = "unknown"; pss->result_len = snprintf(pss->result + LWS_PRE, sizeof(pss->result) - LWS_PRE - 1, "Rebooting after storing certs...
connect to AP 'config-%s-%s' and continue here: " "https://192.168.4.1", - lws_esp32.model, lws_spa_get_string(pss->spa, EPN_SERIAL)); + lws_esp32.model, pp); if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end)) goto bail; @@ -830,6 +869,8 @@ auton: case LWS_CALLBACK_HTTP_WRITEABLE: lwsl_debug("LWS_CALLBACK_HTTP_WRITEABLE: sending %d\n", pss->result_len); + if (!pss->result_len) + break; n = lws_write(wsi, (unsigned char *)pss->result + LWS_PRE, pss->result_len, LWS_WRITE_HTTP); if (n < 0)