/* L1 driver diagnosis: the device becomes its own access point. * * Ladder (docs/architecture.md): prove each layer before climbing. * L0 SDIO control path — proven (RPC works) * L1 wifi data path AT ALL — this file: SoftAP + DHCP + HTTP, no external network * L2 STA to any network — phone hotspot * L3 STA to "Outside" — the real network * L4 gateway + Tatlock — only after L3 * * Join DESKLOCK-DIAG (pass desklock123) with a phone: * - association -> log + on-screen counter * - DHCP lease from us -> IP_EVENT_AP_STAIPASSIGNED = SDIO data path PROVEN * - http://192.168.4.1/ -> full TCP round trip PROVEN */ #include #include "esp_event.h" #include "esp_http_server.h" #include "esp_log.h" #include "esp_netif.h" #include "esp_wifi.h" #include "nvs_flash.h" #include "desklock.h" static const char *TAG = "wifidiag"; static int s_assoc; static int s_leases; static int s_http_hits; static void show(void) { char line[96]; snprintf(line, sizeof(line), "DIAG AP: assoc %d | lease %d | http %d", s_assoc, s_leases, s_http_hits); face_status(line); ESP_LOGI(TAG, "%s", line); } static void diag_event(void *arg, esp_event_base_t base, int32_t id, void *data) { (void)arg; (void)data; if (base == WIFI_EVENT && id == WIFI_EVENT_AP_STACONNECTED) { s_assoc++; ESP_LOGI(TAG, "L1a: station ASSOCIATED (radio + auth OK)"); } else if (base == WIFI_EVENT && id == WIFI_EVENT_AP_STADISCONNECTED) { if (s_assoc > 0) { s_assoc--; } } else if (base == IP_EVENT && id == IP_EVENT_AP_STAIPASSIGNED) { s_leases++; ESP_LOGI(TAG, "L1b: DHCP LEASE ASSIGNED — SDIO DATA PATH PROVEN"); } show(); } static esp_err_t hello_get(httpd_req_t *req) { s_http_hits++; ESP_LOGI(TAG, "L1c: HTTP GET — FULL TCP ROUND TRIP PROVEN"); show(); return httpd_resp_sendstr(req, "desklock diag: data path OK\n"); } void wifi_diag_start(void) { esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ESP_ERROR_CHECK(nvs_flash_init()); } ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_ap(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, diag_event, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_AP_STAIPASSIGNED, diag_event, NULL)); wifi_config_t ap = { .ap = { .ssid = "DESKLOCK-DIAG", .password = "desklock123", .authmode = WIFI_AUTH_WPA2_PSK, .max_connection = 4, .channel = 6, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap)); ESP_ERROR_CHECK(esp_wifi_start()); httpd_handle_t server = NULL; httpd_config_t hcfg = HTTPD_DEFAULT_CONFIG(); if (httpd_start(&server, &hcfg) == ESP_OK) { static const httpd_uri_t root = { .uri = "/", .method = HTTP_GET, .handler = hello_get }; httpd_register_uri_handler(server, &root); } else { ESP_LOGE(TAG, "httpd_start failed"); face_status("DIAG: httpd FAILED"); } ESP_LOGI(TAG, "L1 diag AP up: join DESKLOCK-DIAG / desklock123, open http://192.168.4.1/"); face_status("DIAG: join DESKLOCK-DIAG"); }