diff --git a/.cache/clangd/index/Gui.cpp.BDF53DB313293DD9.idx b/.cache/clangd/index/Gui.cpp.BDF53DB313293DD9.idx index ccaa137..31db9bf 100644 Binary files a/.cache/clangd/index/Gui.cpp.BDF53DB313293DD9.idx and b/.cache/clangd/index/Gui.cpp.BDF53DB313293DD9.idx differ diff --git a/.cache/clangd/index/KnxWorker.cpp.DE6DF2C0B88ED24E.idx b/.cache/clangd/index/KnxWorker.cpp.DE6DF2C0B88ED24E.idx index 7a4551b..08a1b97 100644 Binary files a/.cache/clangd/index/KnxWorker.cpp.DE6DF2C0B88ED24E.idx and b/.cache/clangd/index/KnxWorker.cpp.DE6DF2C0B88ED24E.idx differ diff --git a/.cache/clangd/index/Wifi.cpp.C29FF4A35AE66387.idx b/.cache/clangd/index/Wifi.cpp.C29FF4A35AE66387.idx new file mode 100644 index 0000000..0866fec Binary files /dev/null and b/.cache/clangd/index/Wifi.cpp.C29FF4A35AE66387.idx differ diff --git a/.cache/clangd/index/Wifi.hpp.162A78F89BACD645.idx b/.cache/clangd/index/Wifi.hpp.162A78F89BACD645.idx new file mode 100644 index 0000000..79e8051 Binary files /dev/null and b/.cache/clangd/index/Wifi.hpp.162A78F89BACD645.idx differ diff --git a/.cache/clangd/index/WifiSetting.cpp.32D695A00E7D2B78.idx b/.cache/clangd/index/WifiSetting.cpp.32D695A00E7D2B78.idx new file mode 100644 index 0000000..c8f3fb2 Binary files /dev/null and b/.cache/clangd/index/WifiSetting.cpp.32D695A00E7D2B78.idx differ diff --git a/.cache/clangd/index/WifiSetting.hpp.617DEB6E05017D99.idx b/.cache/clangd/index/WifiSetting.hpp.617DEB6E05017D99.idx new file mode 100644 index 0000000..3facedb Binary files /dev/null and b/.cache/clangd/index/WifiSetting.hpp.617DEB6E05017D99.idx differ diff --git a/.cache/clangd/index/dummy_src.c.937707F10F7A77D5.idx b/.cache/clangd/index/dummy_src.c.937707F10F7A77D5.idx new file mode 100644 index 0000000..a5621d5 Binary files /dev/null and b/.cache/clangd/index/dummy_src.c.937707F10F7A77D5.idx differ diff --git a/.cache/clangd/index/eppp_link.c.2E03D586AFD1FF4F.idx b/.cache/clangd/index/eppp_link.c.2E03D586AFD1FF4F.idx new file mode 100644 index 0000000..3803ced Binary files /dev/null and b/.cache/clangd/index/eppp_link.c.2E03D586AFD1FF4F.idx differ diff --git a/.cache/clangd/index/eppp_link.h.CCFEC7EC885FDE4E.idx b/.cache/clangd/index/eppp_link.h.CCFEC7EC885FDE4E.idx new file mode 100644 index 0000000..f956dc9 Binary files /dev/null and b/.cache/clangd/index/eppp_link.h.CCFEC7EC885FDE4E.idx differ diff --git a/.cache/clangd/index/eppp_netif_tun.c.975A8A01D945D14D.idx b/.cache/clangd/index/eppp_netif_tun.c.975A8A01D945D14D.idx new file mode 100644 index 0000000..8935f02 Binary files /dev/null and b/.cache/clangd/index/eppp_netif_tun.c.975A8A01D945D14D.idx differ diff --git a/.cache/clangd/index/eppp_transport.h.26A3DD4EC720C50B.idx b/.cache/clangd/index/eppp_transport.h.26A3DD4EC720C50B.idx new file mode 100644 index 0000000..0692f68 Binary files /dev/null and b/.cache/clangd/index/eppp_transport.h.26A3DD4EC720C50B.idx differ diff --git a/.cache/clangd/index/eppp_transport_eth.h.4EEA5373FE78DB6C.idx b/.cache/clangd/index/eppp_transport_eth.h.4EEA5373FE78DB6C.idx new file mode 100644 index 0000000..55e15b2 Binary files /dev/null and b/.cache/clangd/index/eppp_transport_eth.h.4EEA5373FE78DB6C.idx differ diff --git a/.cache/clangd/index/eppp_transport_sdio.h.B1015B5BD18935D4.idx b/.cache/clangd/index/eppp_transport_sdio.h.B1015B5BD18935D4.idx new file mode 100644 index 0000000..afe4bcf Binary files /dev/null and b/.cache/clangd/index/eppp_transport_sdio.h.B1015B5BD18935D4.idx differ diff --git a/.cache/clangd/index/eppp_transport_spi.h.DE45996856305F01.idx b/.cache/clangd/index/eppp_transport_spi.h.DE45996856305F01.idx new file mode 100644 index 0000000..8db779c Binary files /dev/null and b/.cache/clangd/index/eppp_transport_spi.h.DE45996856305F01.idx differ diff --git a/.cache/clangd/index/eppp_transport_uart.h.BE0B3D7DE59C39E5.idx b/.cache/clangd/index/eppp_transport_uart.h.BE0B3D7DE59C39E5.idx new file mode 100644 index 0000000..4268839 Binary files /dev/null and b/.cache/clangd/index/eppp_transport_uart.h.BE0B3D7DE59C39E5.idx differ diff --git a/.cache/clangd/index/eppp_uart.c.DEBA285523A8ECA2.idx b/.cache/clangd/index/eppp_uart.c.DEBA285523A8ECA2.idx new file mode 100644 index 0000000..8298494 Binary files /dev/null and b/.cache/clangd/index/eppp_uart.c.DEBA285523A8ECA2.idx differ diff --git a/.cache/clangd/index/esp_eap_client_remote_api.h.704340461D1684FC.idx b/.cache/clangd/index/esp_eap_client_remote_api.h.704340461D1684FC.idx new file mode 100644 index 0000000..5a98946 Binary files /dev/null and b/.cache/clangd/index/esp_eap_client_remote_api.h.704340461D1684FC.idx differ diff --git a/.cache/clangd/index/esp_eap_client_remote_weak.c.5853FEB5AE6CC649.idx b/.cache/clangd/index/esp_eap_client_remote_weak.c.5853FEB5AE6CC649.idx new file mode 100644 index 0000000..2d7e8e5 Binary files /dev/null and b/.cache/clangd/index/esp_eap_client_remote_weak.c.5853FEB5AE6CC649.idx differ diff --git a/.cache/clangd/index/esp_eap_client_with_remote.c.AD773EF39B093983.idx b/.cache/clangd/index/esp_eap_client_with_remote.c.AD773EF39B093983.idx new file mode 100644 index 0000000..368f296 Binary files /dev/null and b/.cache/clangd/index/esp_eap_client_with_remote.c.AD773EF39B093983.idx differ diff --git a/.cache/clangd/index/esp_hosted.h.88634F67E417235D.idx b/.cache/clangd/index/esp_hosted.h.88634F67E417235D.idx new file mode 100644 index 0000000..c998fec Binary files /dev/null and b/.cache/clangd/index/esp_hosted.h.88634F67E417235D.idx differ diff --git a/.cache/clangd/index/esp_hosted_api.c.F67950DA579E23AE.idx b/.cache/clangd/index/esp_hosted_api.c.F67950DA579E23AE.idx new file mode 100644 index 0000000..92c2145 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_api.c.F67950DA579E23AE.idx differ diff --git a/.cache/clangd/index/esp_hosted_api_priv.h.D1C3720B648CFE57.idx b/.cache/clangd/index/esp_hosted_api_priv.h.D1C3720B648CFE57.idx new file mode 100644 index 0000000..e722786 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_api_priv.h.D1C3720B648CFE57.idx differ diff --git a/.cache/clangd/index/esp_hosted_api_types.h.66A00F78D798CABF.idx b/.cache/clangd/index/esp_hosted_api_types.h.66A00F78D798CABF.idx new file mode 100644 index 0000000..3f5e776 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_api_types.h.66A00F78D798CABF.idx differ diff --git a/.cache/clangd/index/esp_hosted_bitmasks.h.A4FEB717F2F5202A.idx b/.cache/clangd/index/esp_hosted_bitmasks.h.A4FEB717F2F5202A.idx new file mode 100644 index 0000000..37f3bde Binary files /dev/null and b/.cache/clangd/index/esp_hosted_bitmasks.h.A4FEB717F2F5202A.idx differ diff --git a/.cache/clangd/index/esp_hosted_bt.h.5DA9D74D39290E5B.idx b/.cache/clangd/index/esp_hosted_bt.h.5DA9D74D39290E5B.idx new file mode 100644 index 0000000..4ff5b6a Binary files /dev/null and b/.cache/clangd/index/esp_hosted_bt.h.5DA9D74D39290E5B.idx differ diff --git a/.cache/clangd/index/esp_hosted_cli.c.78325FAB785DE501.idx b/.cache/clangd/index/esp_hosted_cli.c.78325FAB785DE501.idx new file mode 100644 index 0000000..5cf89c9 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_cli.c.78325FAB785DE501.idx differ diff --git a/.cache/clangd/index/esp_hosted_cli.h.C10C75EB8ABE1FE5.idx b/.cache/clangd/index/esp_hosted_cli.h.C10C75EB8ABE1FE5.idx new file mode 100644 index 0000000..b5039da Binary files /dev/null and b/.cache/clangd/index/esp_hosted_cli.h.C10C75EB8ABE1FE5.idx differ diff --git a/.cache/clangd/index/esp_hosted_event.h.69C66AF9D30EAD3C.idx b/.cache/clangd/index/esp_hosted_event.h.69C66AF9D30EAD3C.idx new file mode 100644 index 0000000..f44d7db Binary files /dev/null and b/.cache/clangd/index/esp_hosted_event.h.69C66AF9D30EAD3C.idx differ diff --git a/.cache/clangd/index/esp_hosted_header.h.7A9CFE159AD0F960.idx b/.cache/clangd/index/esp_hosted_header.h.7A9CFE159AD0F960.idx new file mode 100644 index 0000000..259d175 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_header.h.7A9CFE159AD0F960.idx differ diff --git a/.cache/clangd/index/esp_hosted_host_fw_ver.h.7627B76907D54D09.idx b/.cache/clangd/index/esp_hosted_host_fw_ver.h.7627B76907D54D09.idx new file mode 100644 index 0000000..d82920f Binary files /dev/null and b/.cache/clangd/index/esp_hosted_host_fw_ver.h.7627B76907D54D09.idx differ diff --git a/.cache/clangd/index/esp_hosted_interface.h.947B542023F75F47.idx b/.cache/clangd/index/esp_hosted_interface.h.947B542023F75F47.idx new file mode 100644 index 0000000..e02f6ac Binary files /dev/null and b/.cache/clangd/index/esp_hosted_interface.h.947B542023F75F47.idx differ diff --git a/.cache/clangd/index/esp_hosted_log.h.3FB129A88206FF4D.idx b/.cache/clangd/index/esp_hosted_log.h.3FB129A88206FF4D.idx new file mode 100644 index 0000000..052097d Binary files /dev/null and b/.cache/clangd/index/esp_hosted_log.h.3FB129A88206FF4D.idx differ diff --git a/.cache/clangd/index/esp_hosted_misc.h.080FBE5065AD0A05.idx b/.cache/clangd/index/esp_hosted_misc.h.080FBE5065AD0A05.idx new file mode 100644 index 0000000..d8ab6e4 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_misc.h.080FBE5065AD0A05.idx differ diff --git a/.cache/clangd/index/esp_hosted_os_abstraction.h.F59EB2EF24F2F584.idx b/.cache/clangd/index/esp_hosted_os_abstraction.h.F59EB2EF24F2F584.idx new file mode 100644 index 0000000..174e090 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_os_abstraction.h.F59EB2EF24F2F584.idx differ diff --git a/.cache/clangd/index/esp_hosted_ota.h.B9A770B02567C901.idx b/.cache/clangd/index/esp_hosted_ota.h.B9A770B02567C901.idx new file mode 100644 index 0000000..fb7ed31 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_ota.h.B9A770B02567C901.idx differ diff --git a/.cache/clangd/index/esp_hosted_ota_api.c.22700A302F254A42.idx b/.cache/clangd/index/esp_hosted_ota_api.c.22700A302F254A42.idx new file mode 100644 index 0000000..d596ad5 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_ota_api.c.22700A302F254A42.idx differ diff --git a/.cache/clangd/index/esp_hosted_power_save.h.5052E5D651C4F69F.idx b/.cache/clangd/index/esp_hosted_power_save.h.5052E5D651C4F69F.idx new file mode 100644 index 0000000..9324cb1 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_power_save.h.5052E5D651C4F69F.idx differ diff --git a/.cache/clangd/index/esp_hosted_rpc.h.A887B45C608DFEEC.idx b/.cache/clangd/index/esp_hosted_rpc.h.A887B45C608DFEEC.idx new file mode 100644 index 0000000..9efe274 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_rpc.h.A887B45C608DFEEC.idx differ diff --git a/.cache/clangd/index/esp_hosted_rpc.pb-c.c.AB353D6201F8DFB3.idx b/.cache/clangd/index/esp_hosted_rpc.pb-c.c.AB353D6201F8DFB3.idx new file mode 100644 index 0000000..3016995 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_rpc.pb-c.c.AB353D6201F8DFB3.idx differ diff --git a/.cache/clangd/index/esp_hosted_rpc.pb-c.h.D5B4418169E035FC.idx b/.cache/clangd/index/esp_hosted_rpc.pb-c.h.D5B4418169E035FC.idx new file mode 100644 index 0000000..26de35d Binary files /dev/null and b/.cache/clangd/index/esp_hosted_rpc.pb-c.h.D5B4418169E035FC.idx differ diff --git a/.cache/clangd/index/esp_hosted_transport.h.D4B05EE6F1410C3F.idx b/.cache/clangd/index/esp_hosted_transport.h.D4B05EE6F1410C3F.idx new file mode 100644 index 0000000..77f0c0e Binary files /dev/null and b/.cache/clangd/index/esp_hosted_transport.h.D4B05EE6F1410C3F.idx differ diff --git a/.cache/clangd/index/esp_hosted_transport_config.c.285CA3A462BBC6E2.idx b/.cache/clangd/index/esp_hosted_transport_config.c.285CA3A462BBC6E2.idx new file mode 100644 index 0000000..0658b18 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_transport_config.c.285CA3A462BBC6E2.idx differ diff --git a/.cache/clangd/index/esp_hosted_transport_config.h.1C6B8D1864ED1D4E.idx b/.cache/clangd/index/esp_hosted_transport_config.h.1C6B8D1864ED1D4E.idx new file mode 100644 index 0000000..406a9fe Binary files /dev/null and b/.cache/clangd/index/esp_hosted_transport_config.h.1C6B8D1864ED1D4E.idx differ diff --git a/.cache/clangd/index/esp_hosted_transport_init.h.BA4F0D475C713A2B.idx b/.cache/clangd/index/esp_hosted_transport_init.h.BA4F0D475C713A2B.idx new file mode 100644 index 0000000..304ac90 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_transport_init.h.BA4F0D475C713A2B.idx differ diff --git a/.cache/clangd/index/esp_hosted_wifi_remote_glue.h.3AAD8704EB9A0EAD.idx b/.cache/clangd/index/esp_hosted_wifi_remote_glue.h.3AAD8704EB9A0EAD.idx new file mode 100644 index 0000000..f7cebc2 Binary files /dev/null and b/.cache/clangd/index/esp_hosted_wifi_remote_glue.h.3AAD8704EB9A0EAD.idx differ diff --git a/.cache/clangd/index/esp_wifi.h.8387B57FF7F48BBF.idx b/.cache/clangd/index/esp_wifi.h.8387B57FF7F48BBF.idx new file mode 100644 index 0000000..0ea6a73 Binary files /dev/null and b/.cache/clangd/index/esp_wifi.h.8387B57FF7F48BBF.idx differ diff --git a/.cache/clangd/index/esp_wifi_crypto_types.h.FA4407EA60D1DE22.idx b/.cache/clangd/index/esp_wifi_crypto_types.h.FA4407EA60D1DE22.idx new file mode 100644 index 0000000..b30810c Binary files /dev/null and b/.cache/clangd/index/esp_wifi_crypto_types.h.FA4407EA60D1DE22.idx differ diff --git a/.cache/clangd/index/esp_wifi_default.h.0508E7DAE07C27C1.idx b/.cache/clangd/index/esp_wifi_default.h.0508E7DAE07C27C1.idx new file mode 100644 index 0000000..c64981e Binary files /dev/null and b/.cache/clangd/index/esp_wifi_default.h.0508E7DAE07C27C1.idx differ diff --git a/.cache/clangd/index/esp_wifi_he_types.h.5897DC6773DC6223.idx b/.cache/clangd/index/esp_wifi_he_types.h.5897DC6773DC6223.idx new file mode 100644 index 0000000..be78482 Binary files /dev/null and b/.cache/clangd/index/esp_wifi_he_types.h.5897DC6773DC6223.idx differ diff --git a/.cache/clangd/index/esp_wifi_remote.c.FE6CCFA6684E75BA.idx b/.cache/clangd/index/esp_wifi_remote.c.FE6CCFA6684E75BA.idx new file mode 100644 index 0000000..fb5b153 Binary files /dev/null and b/.cache/clangd/index/esp_wifi_remote.c.FE6CCFA6684E75BA.idx differ diff --git a/.cache/clangd/index/esp_wifi_remote.h.2F657EDC3A913664.idx b/.cache/clangd/index/esp_wifi_remote.h.2F657EDC3A913664.idx new file mode 100644 index 0000000..bb887ad Binary files /dev/null and b/.cache/clangd/index/esp_wifi_remote.h.2F657EDC3A913664.idx differ diff --git a/.cache/clangd/index/esp_wifi_remote_api.h.35E7BE79F397BC68.idx b/.cache/clangd/index/esp_wifi_remote_api.h.35E7BE79F397BC68.idx new file mode 100644 index 0000000..dadb5e4 Binary files /dev/null and b/.cache/clangd/index/esp_wifi_remote_api.h.35E7BE79F397BC68.idx differ diff --git a/.cache/clangd/index/esp_wifi_remote_net.c.28A6E402ABB7F4E4.idx b/.cache/clangd/index/esp_wifi_remote_net.c.28A6E402ABB7F4E4.idx new file mode 100644 index 0000000..23e430a Binary files /dev/null and b/.cache/clangd/index/esp_wifi_remote_net.c.28A6E402ABB7F4E4.idx differ diff --git a/.cache/clangd/index/esp_wifi_remote_weak.c.FD8A90EF81EFFEA1.idx b/.cache/clangd/index/esp_wifi_remote_weak.c.FD8A90EF81EFFEA1.idx new file mode 100644 index 0000000..7aca92f Binary files /dev/null and b/.cache/clangd/index/esp_wifi_remote_weak.c.FD8A90EF81EFFEA1.idx differ diff --git a/.cache/clangd/index/esp_wifi_types.h.B2AFACB5E12A7114.idx b/.cache/clangd/index/esp_wifi_types.h.B2AFACB5E12A7114.idx new file mode 100644 index 0000000..a080585 Binary files /dev/null and b/.cache/clangd/index/esp_wifi_types.h.B2AFACB5E12A7114.idx differ diff --git a/.cache/clangd/index/esp_wifi_types_generic.h.E2F6F0D5325F5DDD.idx b/.cache/clangd/index/esp_wifi_types_generic.h.E2F6F0D5325F5DDD.idx new file mode 100644 index 0000000..5269bd5 Binary files /dev/null and b/.cache/clangd/index/esp_wifi_types_generic.h.E2F6F0D5325F5DDD.idx differ diff --git a/.cache/clangd/index/esp_wifi_types_native.h.325C720922C44271.idx b/.cache/clangd/index/esp_wifi_types_native.h.325C720922C44271.idx new file mode 100644 index 0000000..29fac6d Binary files /dev/null and b/.cache/clangd/index/esp_wifi_types_native.h.325C720922C44271.idx differ diff --git a/.cache/clangd/index/esp_wifi_weak.c.D4DD9C0DD687A1B2.idx b/.cache/clangd/index/esp_wifi_weak.c.D4DD9C0DD687A1B2.idx new file mode 100644 index 0000000..80455cc Binary files /dev/null and b/.cache/clangd/index/esp_wifi_weak.c.D4DD9C0DD687A1B2.idx differ diff --git a/.cache/clangd/index/esp_wifi_with_remote.c.0EC6322E0DE81557.idx b/.cache/clangd/index/esp_wifi_with_remote.c.0EC6322E0DE81557.idx new file mode 100644 index 0000000..f1b490c Binary files /dev/null and b/.cache/clangd/index/esp_wifi_with_remote.c.0EC6322E0DE81557.idx differ diff --git a/.cache/clangd/index/essl.c.79284C64436600AE.idx b/.cache/clangd/index/essl.c.79284C64436600AE.idx new file mode 100644 index 0000000..4d5d948 Binary files /dev/null and b/.cache/clangd/index/essl.c.79284C64436600AE.idx differ diff --git a/.cache/clangd/index/essl.h.E179A8BB7133927B.idx b/.cache/clangd/index/essl.h.E179A8BB7133927B.idx new file mode 100644 index 0000000..3961666 Binary files /dev/null and b/.cache/clangd/index/essl.h.E179A8BB7133927B.idx differ diff --git a/.cache/clangd/index/essl_internal.h.4580020F3D7D6C0A.idx b/.cache/clangd/index/essl_internal.h.4580020F3D7D6C0A.idx new file mode 100644 index 0000000..4ef2300 Binary files /dev/null and b/.cache/clangd/index/essl_internal.h.4580020F3D7D6C0A.idx differ diff --git a/.cache/clangd/index/essl_sdio.c.373167E7E153E0DF.idx b/.cache/clangd/index/essl_sdio.c.373167E7E153E0DF.idx new file mode 100644 index 0000000..68dfb8e Binary files /dev/null and b/.cache/clangd/index/essl_sdio.c.373167E7E153E0DF.idx differ diff --git a/.cache/clangd/index/essl_sdio.h.8263E8560D7CDC4E.idx b/.cache/clangd/index/essl_sdio.h.8263E8560D7CDC4E.idx new file mode 100644 index 0000000..308a8dc Binary files /dev/null and b/.cache/clangd/index/essl_sdio.h.8263E8560D7CDC4E.idx differ diff --git a/.cache/clangd/index/essl_sdio_defs.c.8B23DF0636E39374.idx b/.cache/clangd/index/essl_sdio_defs.c.8B23DF0636E39374.idx new file mode 100644 index 0000000..b70abdd Binary files /dev/null and b/.cache/clangd/index/essl_sdio_defs.c.8B23DF0636E39374.idx differ diff --git a/.cache/clangd/index/essl_sdio_defs.h.BD99651CE834C4BF.idx b/.cache/clangd/index/essl_sdio_defs.h.BD99651CE834C4BF.idx new file mode 100644 index 0000000..91bfee9 Binary files /dev/null and b/.cache/clangd/index/essl_sdio_defs.h.BD99651CE834C4BF.idx differ diff --git a/.cache/clangd/index/essl_spi.c.3EEC7CB94F9A5665.idx b/.cache/clangd/index/essl_spi.c.3EEC7CB94F9A5665.idx new file mode 100644 index 0000000..e407c58 Binary files /dev/null and b/.cache/clangd/index/essl_spi.c.3EEC7CB94F9A5665.idx differ diff --git a/.cache/clangd/index/essl_spi.h.30A149EE4ADEABE0.idx b/.cache/clangd/index/essl_spi.h.30A149EE4ADEABE0.idx new file mode 100644 index 0000000..26fb8c8 Binary files /dev/null and b/.cache/clangd/index/essl_spi.h.30A149EE4ADEABE0.idx differ diff --git a/.cache/clangd/index/hci_drv.h.80AC44FFFBD25EE1.idx b/.cache/clangd/index/hci_drv.h.80AC44FFFBD25EE1.idx new file mode 100644 index 0000000..fd901f5 Binary files /dev/null and b/.cache/clangd/index/hci_drv.h.80AC44FFFBD25EE1.idx differ diff --git a/.cache/clangd/index/hci_stub_drv.c.BEDE1065D46E1462.idx b/.cache/clangd/index/hci_stub_drv.c.BEDE1065D46E1462.idx new file mode 100644 index 0000000..71ae838 Binary files /dev/null and b/.cache/clangd/index/hci_stub_drv.c.BEDE1065D46E1462.idx differ diff --git a/.cache/clangd/index/main.cpp.7C677863E2582AB3.idx b/.cache/clangd/index/main.cpp.7C677863E2582AB3.idx index c47504a..9b7e379 100644 Binary files a/.cache/clangd/index/main.cpp.7C677863E2582AB3.idx and b/.cache/clangd/index/main.cpp.7C677863E2582AB3.idx differ diff --git a/.cache/clangd/index/mempool.c.A498C115B2827EA2.idx b/.cache/clangd/index/mempool.c.A498C115B2827EA2.idx new file mode 100644 index 0000000..5ae93d2 Binary files /dev/null and b/.cache/clangd/index/mempool.c.A498C115B2827EA2.idx differ diff --git a/.cache/clangd/index/mempool.h.4558DB1E1032684F.idx b/.cache/clangd/index/mempool.h.4558DB1E1032684F.idx new file mode 100644 index 0000000..6d59f2c Binary files /dev/null and b/.cache/clangd/index/mempool.h.4558DB1E1032684F.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_bt_config.h.03057F429790AB84.idx b/.cache/clangd/index/port_esp_hosted_host_bt_config.h.03057F429790AB84.idx new file mode 100644 index 0000000..ebcd96f Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_bt_config.h.03057F429790AB84.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_config.h.02B1374BBB1A5026.idx b/.cache/clangd/index/port_esp_hosted_host_config.h.02B1374BBB1A5026.idx new file mode 100644 index 0000000..2475116 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_config.h.02B1374BBB1A5026.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_init.c.AF2147A6FCAF5F60.idx b/.cache/clangd/index/port_esp_hosted_host_init.c.AF2147A6FCAF5F60.idx new file mode 100644 index 0000000..1139409 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_init.c.AF2147A6FCAF5F60.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_log.h.DFE70CAABE54995D.idx b/.cache/clangd/index/port_esp_hosted_host_log.h.DFE70CAABE54995D.idx new file mode 100644 index 0000000..5e5953d Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_log.h.DFE70CAABE54995D.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_os.c.EA140AA0BB5CBECC.idx b/.cache/clangd/index/port_esp_hosted_host_os.c.EA140AA0BB5CBECC.idx new file mode 100644 index 0000000..9df7a31 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_os.c.EA140AA0BB5CBECC.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_os.h.2F41780B8D5A3CBC.idx b/.cache/clangd/index/port_esp_hosted_host_os.h.2F41780B8D5A3CBC.idx new file mode 100644 index 0000000..e8a4dc9 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_os.h.2F41780B8D5A3CBC.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_sdio.c.FB9FFACEADA90BDF.idx b/.cache/clangd/index/port_esp_hosted_host_sdio.c.FB9FFACEADA90BDF.idx new file mode 100644 index 0000000..6fa5606 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_sdio.c.FB9FFACEADA90BDF.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_sdio.h.A822C00DD9610335.idx b/.cache/clangd/index/port_esp_hosted_host_sdio.h.A822C00DD9610335.idx new file mode 100644 index 0000000..6450e3a Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_sdio.h.A822C00DD9610335.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_transport_defaults.c.A9E16CE80BA0CAA3.idx b/.cache/clangd/index/port_esp_hosted_host_transport_defaults.c.A9E16CE80BA0CAA3.idx new file mode 100644 index 0000000..48ac797 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_transport_defaults.c.A9E16CE80BA0CAA3.idx differ diff --git a/.cache/clangd/index/port_esp_hosted_host_wifi_config.h.8CBC4B7CBF48DB74.idx b/.cache/clangd/index/port_esp_hosted_host_wifi_config.h.8CBC4B7CBF48DB74.idx new file mode 100644 index 0000000..b787c74 Binary files /dev/null and b/.cache/clangd/index/port_esp_hosted_host_wifi_config.h.8CBC4B7CBF48DB74.idx differ diff --git a/.cache/clangd/index/power_save_drv.c.3CF1B859522FD4A7.idx b/.cache/clangd/index/power_save_drv.c.3CF1B859522FD4A7.idx new file mode 100644 index 0000000..bf48170 Binary files /dev/null and b/.cache/clangd/index/power_save_drv.c.3CF1B859522FD4A7.idx differ diff --git a/.cache/clangd/index/power_save_drv.h.7FC60F1CDB131368.idx b/.cache/clangd/index/power_save_drv.h.7FC60F1CDB131368.idx new file mode 100644 index 0000000..7a476be Binary files /dev/null and b/.cache/clangd/index/power_save_drv.h.7FC60F1CDB131368.idx differ diff --git a/.cache/clangd/index/protobuf-c.c.B49FA27706FB0470.idx b/.cache/clangd/index/protobuf-c.c.B49FA27706FB0470.idx new file mode 100644 index 0000000..6d1afd1 Binary files /dev/null and b/.cache/clangd/index/protobuf-c.c.B49FA27706FB0470.idx differ diff --git a/.cache/clangd/index/protobuf-c.h.60A993736F5EDBD6.idx b/.cache/clangd/index/protobuf-c.h.60A993736F5EDBD6.idx new file mode 100644 index 0000000..adcefaf Binary files /dev/null and b/.cache/clangd/index/protobuf-c.h.60A993736F5EDBD6.idx differ diff --git a/.cache/clangd/index/rpc_core.c.84427EA79E90FA79.idx b/.cache/clangd/index/rpc_core.c.84427EA79E90FA79.idx new file mode 100644 index 0000000..e78643f Binary files /dev/null and b/.cache/clangd/index/rpc_core.c.84427EA79E90FA79.idx differ diff --git a/.cache/clangd/index/rpc_core.h.42CE1B5CEE1978BC.idx b/.cache/clangd/index/rpc_core.h.42CE1B5CEE1978BC.idx new file mode 100644 index 0000000..c1a76ca Binary files /dev/null and b/.cache/clangd/index/rpc_core.h.42CE1B5CEE1978BC.idx differ diff --git a/.cache/clangd/index/rpc_evt.c.97B25DA38FC40342.idx b/.cache/clangd/index/rpc_evt.c.97B25DA38FC40342.idx new file mode 100644 index 0000000..3c28c74 Binary files /dev/null and b/.cache/clangd/index/rpc_evt.c.97B25DA38FC40342.idx differ diff --git a/.cache/clangd/index/rpc_req.c.CEBC3918574B8C58.idx b/.cache/clangd/index/rpc_req.c.CEBC3918574B8C58.idx new file mode 100644 index 0000000..760b7b1 Binary files /dev/null and b/.cache/clangd/index/rpc_req.c.CEBC3918574B8C58.idx differ diff --git a/.cache/clangd/index/rpc_rsp.c.3492F700A0408ABF.idx b/.cache/clangd/index/rpc_rsp.c.3492F700A0408ABF.idx new file mode 100644 index 0000000..0479833 Binary files /dev/null and b/.cache/clangd/index/rpc_rsp.c.3492F700A0408ABF.idx differ diff --git a/.cache/clangd/index/rpc_slave_if.c.B3BB3DEFA043A24D.idx b/.cache/clangd/index/rpc_slave_if.c.B3BB3DEFA043A24D.idx new file mode 100644 index 0000000..785a252 Binary files /dev/null and b/.cache/clangd/index/rpc_slave_if.c.B3BB3DEFA043A24D.idx differ diff --git a/.cache/clangd/index/rpc_slave_if.h.5B1AF72F0A68536B.idx b/.cache/clangd/index/rpc_slave_if.h.5B1AF72F0A68536B.idx new file mode 100644 index 0000000..bf2c5d5 Binary files /dev/null and b/.cache/clangd/index/rpc_slave_if.h.5B1AF72F0A68536B.idx differ diff --git a/.cache/clangd/index/rpc_utils.c.F036C75B308F9A60.idx b/.cache/clangd/index/rpc_utils.c.F036C75B308F9A60.idx new file mode 100644 index 0000000..708df99 Binary files /dev/null and b/.cache/clangd/index/rpc_utils.c.F036C75B308F9A60.idx differ diff --git a/.cache/clangd/index/rpc_utils.h.67A5A4272B9D59EF.idx b/.cache/clangd/index/rpc_utils.h.67A5A4272B9D59EF.idx new file mode 100644 index 0000000..cd9d6c1 Binary files /dev/null and b/.cache/clangd/index/rpc_utils.h.67A5A4272B9D59EF.idx differ diff --git a/.cache/clangd/index/rpc_wrap.c.74197E55DA2CF77D.idx b/.cache/clangd/index/rpc_wrap.c.74197E55DA2CF77D.idx new file mode 100644 index 0000000..6db25ff Binary files /dev/null and b/.cache/clangd/index/rpc_wrap.c.74197E55DA2CF77D.idx differ diff --git a/.cache/clangd/index/rpc_wrap.h.3274D14CE6CC43E7.idx b/.cache/clangd/index/rpc_wrap.h.3274D14CE6CC43E7.idx new file mode 100644 index 0000000..e2a26ff Binary files /dev/null and b/.cache/clangd/index/rpc_wrap.h.3274D14CE6CC43E7.idx differ diff --git a/.cache/clangd/index/sdio_drv.c.6CEDE7BC968EEF62.idx b/.cache/clangd/index/sdio_drv.c.6CEDE7BC968EEF62.idx new file mode 100644 index 0000000..0ca1f32 Binary files /dev/null and b/.cache/clangd/index/sdio_drv.c.6CEDE7BC968EEF62.idx differ diff --git a/.cache/clangd/index/sdio_drv.h.EEADD180F253222A.idx b/.cache/clangd/index/sdio_drv.h.EEADD180F253222A.idx new file mode 100644 index 0000000..564afe6 Binary files /dev/null and b/.cache/clangd/index/sdio_drv.h.EEADD180F253222A.idx differ diff --git a/.cache/clangd/index/sdio_reg.h.DB0ECBE5DA7DC7A5.idx b/.cache/clangd/index/sdio_reg.h.DB0ECBE5DA7DC7A5.idx new file mode 100644 index 0000000..cf47445 Binary files /dev/null and b/.cache/clangd/index/sdio_reg.h.DB0ECBE5DA7DC7A5.idx differ diff --git a/.cache/clangd/index/serial_drv.c.A75547949C44C722.idx b/.cache/clangd/index/serial_drv.c.A75547949C44C722.idx new file mode 100644 index 0000000..2fb398c Binary files /dev/null and b/.cache/clangd/index/serial_drv.c.A75547949C44C722.idx differ diff --git a/.cache/clangd/index/serial_drv.h.A778990C22602A2E.idx b/.cache/clangd/index/serial_drv.h.A778990C22602A2E.idx new file mode 100644 index 0000000..c8f573a Binary files /dev/null and b/.cache/clangd/index/serial_drv.h.A778990C22602A2E.idx differ diff --git a/.cache/clangd/index/serial_if.c.32545F152DA6FDE5.idx b/.cache/clangd/index/serial_if.c.32545F152DA6FDE5.idx new file mode 100644 index 0000000..3a1eae8 Binary files /dev/null and b/.cache/clangd/index/serial_if.c.32545F152DA6FDE5.idx differ diff --git a/.cache/clangd/index/serial_if.h.2225B9E25030E890.idx b/.cache/clangd/index/serial_if.h.2225B9E25030E890.idx new file mode 100644 index 0000000..de38163 Binary files /dev/null and b/.cache/clangd/index/serial_if.h.2225B9E25030E890.idx differ diff --git a/.cache/clangd/index/serial_ll_if.c.98EADD1B80B925B4.idx b/.cache/clangd/index/serial_ll_if.c.98EADD1B80B925B4.idx new file mode 100644 index 0000000..7050d45 Binary files /dev/null and b/.cache/clangd/index/serial_ll_if.c.98EADD1B80B925B4.idx differ diff --git a/.cache/clangd/index/serial_ll_if.h.59E1813F038D7565.idx b/.cache/clangd/index/serial_ll_if.h.59E1813F038D7565.idx new file mode 100644 index 0000000..d4204d4 Binary files /dev/null and b/.cache/clangd/index/serial_ll_if.h.59E1813F038D7565.idx differ diff --git a/.cache/clangd/index/stats.c.B3DFCB1C3838F931.idx b/.cache/clangd/index/stats.c.B3DFCB1C3838F931.idx new file mode 100644 index 0000000..fc0a544 Binary files /dev/null and b/.cache/clangd/index/stats.c.B3DFCB1C3838F931.idx differ diff --git a/.cache/clangd/index/stats.h.E3E4F04B4307804A.idx b/.cache/clangd/index/stats.h.E3E4F04B4307804A.idx new file mode 100644 index 0000000..81fb23b Binary files /dev/null and b/.cache/clangd/index/stats.h.E3E4F04B4307804A.idx differ diff --git a/.cache/clangd/index/transport_drv.c.E843A2807C57AEF6.idx b/.cache/clangd/index/transport_drv.c.E843A2807C57AEF6.idx new file mode 100644 index 0000000..bf2b694 Binary files /dev/null and b/.cache/clangd/index/transport_drv.c.E843A2807C57AEF6.idx differ diff --git a/.cache/clangd/index/transport_drv.h.C0D6EEB42C2F557B.idx b/.cache/clangd/index/transport_drv.h.C0D6EEB42C2F557B.idx new file mode 100644 index 0000000..8a7d4e9 Binary files /dev/null and b/.cache/clangd/index/transport_drv.h.C0D6EEB42C2F557B.idx differ diff --git a/dependencies.lock b/dependencies.lock index a7224b1..6d3593f 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -25,6 +25,32 @@ dependencies: registry_url: https://components.espressif.com type: service version: 0.5.3 + espressif/eppp_link: + component_hash: + 9472e6825f4bb71eca2b39cf1bc92659c1ac60bfd7416560ad033a7dd8641b17 + dependencies: + - name: espressif/esp_serial_slave_link + registry_url: https://components.espressif.com + require: private + version: ^1.1.0 + - name: idf + require: private + version: '>=5.2' + source: + registry_url: https://components.espressif.com + type: service + version: 1.1.4 + espressif/esp_hosted: + component_hash: + b5fed813114be315487289225970d5fb5b4ef5f73fb73f2d2332862d0dad19bb + dependencies: + - name: idf + require: private + version: '>=5.3' + source: + registry_url: https://components.espressif.com + type: service + version: 2.9.7 espressif/esp_lcd_touch: component_hash: 3f85a7d95af876f1a6ecca8eb90a81614890d0f03a038390804e5a77e2caf862 @@ -192,6 +218,38 @@ dependencies: - esp32c5 - esp32c6 version: 0.6.1 + espressif/esp_serial_slave_link: + component_hash: + ac1776806de0a6e371c84e87898bb983e19ce62aa7f1e2e5c4a3b0234a575d2c + dependencies: + - name: idf + require: private + version: '>=5.0' + source: + registry_url: https://components.espressif.com + type: service + version: 1.1.2 + espressif/esp_wifi_remote: + component_hash: + 94d453bb6aa79ebbe909d6e6525107353880c8a0c8b5d8f86103c83dae055362 + dependencies: + - name: espressif/esp_hosted + registry_url: https://components.espressif.com + require: private + rules: + - if: target in [esp32h2, esp32p4] + version: '>=0.0.6' + - name: espressif/wifi_remote_over_eppp + registry_url: https://components.espressif.com + require: private + version: '>=0.1' + - name: idf + require: private + version: '>=5.3' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.2.4 espressif/freetype: component_hash: cd5e2d8458e6e8d73f1120ac474467cabb669d8ea4b25050bf6a348c1e89225e @@ -248,6 +306,21 @@ dependencies: registry_url: https://components.espressif.com type: service version: 1.6.52 + espressif/wifi_remote_over_eppp: + component_hash: + e1b4c485ed5afe36615b9b555dfdcbe4be33898dc3732b5bedf235bba45bd286 + dependencies: + - name: espressif/eppp_link + registry_url: https://components.espressif.com + require: private + version: '>=0.1' + - name: idf + require: private + version: '>=5.3' + source: + registry_url: https://components.espressif.com + type: service + version: 0.3.0 espressif/zlib: component_hash: d901723af51f13fc8e5824f39f32239c847956e8fd951a05266588dc5cfbb9ae @@ -296,9 +369,10 @@ direct_dependencies: - espressif/esp_lcd_touch_gt911 - espressif/esp_lvgl_adapter - espressif/esp_lvgl_port +- espressif/esp_wifi_remote - idf - lvgl/lvgl - waveshare/esp_lcd_jd9365_10_1 -manifest_hash: df48f0c889a77855e4d9de37a676a02669553fe2b7fdf43547783bcf8f97c123 +manifest_hash: 0e36b3139b75b9c8d45ce136355b7427d1e8020070f386f167b627461b004349 target: esp32p4 version: 2.0.0 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 6ac5b22..2b5d5c7 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "KnxWorker.cpp" "Nvs.cpp" "main.cpp" "Display.cpp" "Touch.cpp" "Gui.cpp" +idf_component_register(SRCS "KnxWorker.cpp" "Nvs.cpp" "main.cpp" "Display.cpp" "Touch.cpp" "Gui.cpp" "Wifi.cpp" "Gui/WifiSetting.cpp" PRIV_REQUIRES spi_flash esp_driver_ppa esp_lcd - REQUIRES esp_mm esp_driver_ppa esp_timer lvgl knx + REQUIRES esp_mm esp_driver_ppa esp_timer lvgl knx esp_wifi_remote esp_netif esp_event nvs_flash INCLUDE_DIRS "") diff --git a/main/Gui.cpp b/main/Gui.cpp index 3e002e8..4cca194 100644 --- a/main/Gui.cpp +++ b/main/Gui.cpp @@ -1,10 +1,18 @@ #include "Gui.hpp" #include "esp_lv_adapter.h" +#include "Gui/WifiSetting.hpp" lv_obj_t * Gui::label2 = nullptr; lv_obj_t * label = nullptr; KnxWorker Gui::knxWorker; // Define the static member +static void screen_long_press_handler(lv_event_t * e) +{ + if (lv_event_get_code(e) == LV_EVENT_LONG_PRESSED) { + WifiSetting::instance().show(); + } +} + static void event_handler(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); @@ -42,6 +50,9 @@ void Gui::create() lv_label_set_text(label, "Toggle"); lv_obj_center(label); + // Add long press handler for WiFi settings + lv_obj_add_event_cb(lv_scr_act(), screen_long_press_handler, + LV_EVENT_LONG_PRESSED, NULL); esp_lv_adapter_unlock(); } diff --git a/main/Gui/WifiSetting.cpp b/main/Gui/WifiSetting.cpp index 4329c89..a5d44e2 100644 --- a/main/Gui/WifiSetting.cpp +++ b/main/Gui/WifiSetting.cpp @@ -1 +1,411 @@ -#include "WifiSetting.hpp" \ No newline at end of file +#include "WifiSetting.hpp" +#include "../Wifi.hpp" +#include "esp_lv_adapter.h" +#include "esp_log.h" +#include + +static const char* TAG = "WifiSetting"; + +WifiSetting& WifiSetting::instance() { + static WifiSetting instance; + return instance; +} + +void WifiSetting::show() { + if (visible_) { + return; + } + + ESP_LOGI(TAG, "Showing WiFi settings"); + + if (esp_lv_adapter_lock(-1) == ESP_OK) { + createUI(); + visible_ = true; + + Wifi::instance().setStatusCallback([](bool connected) { + if (esp_lv_adapter_lock(100) == ESP_OK) { + WifiSetting::instance().updateStatusDisplay(); + esp_lv_adapter_unlock(); + } + }); + + refreshNetworkList(); + refreshSavedNetworks(); + updateStatusDisplay(); + + esp_lv_adapter_unlock(); + } +} + +void WifiSetting::hide() { + if (!visible_) { + return; + } + + ESP_LOGI(TAG, "Hiding WiFi settings"); + + if (esp_lv_adapter_lock(-1) == ESP_OK) { + Wifi::instance().setStatusCallback(nullptr); + + if (overlay_) { + lv_obj_del(overlay_); + overlay_ = nullptr; + statusLabel_ = nullptr; + disconnectBtn_ = nullptr; + networkList_ = nullptr; + savedList_ = nullptr; + passwordDialog_ = nullptr; + passwordInput_ = nullptr; + keyboard_ = nullptr; + } + visible_ = false; + esp_lv_adapter_unlock(); + } +} + +bool WifiSetting::isVisible() { + return visible_; +} + +void WifiSetting::createUI() { + overlay_ = lv_obj_create(lv_scr_act()); + lv_obj_set_size(overlay_, LV_PCT(100), LV_PCT(100)); + lv_obj_set_style_bg_color(overlay_, lv_color_hex(0x202020), 0); + lv_obj_set_style_bg_opa(overlay_, LV_OPA_COVER, 0); + lv_obj_set_style_pad_all(overlay_, 10, 0); + lv_obj_clear_flag(overlay_, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* header = lv_obj_create(overlay_); + lv_obj_set_size(header, LV_PCT(100), 50); + lv_obj_align(header, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_style_bg_color(header, lv_color_hex(0x303030), 0); + lv_obj_set_style_pad_all(header, 5, 0); + lv_obj_clear_flag(header, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* closeBtn = lv_btn_create(header); + lv_obj_set_size(closeBtn, 40, 40); + lv_obj_align(closeBtn, LV_ALIGN_LEFT_MID, 0, 0); + lv_obj_set_style_bg_color(closeBtn, lv_color_hex(0x804040), 0); + lv_obj_add_event_cb(closeBtn, onCloseClick, LV_EVENT_CLICKED, nullptr); + + lv_obj_t* closeLbl = lv_label_create(closeBtn); + lv_label_set_text(closeLbl, "X"); + lv_obj_center(closeLbl); + + lv_obj_t* titleLbl = lv_label_create(header); + lv_label_set_text(titleLbl, "WiFi Settings"); + lv_obj_set_style_text_font(titleLbl, &lv_font_montserrat_14, 0); + lv_obj_align(titleLbl, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t* statusSection = lv_obj_create(overlay_); + lv_obj_set_size(statusSection, LV_PCT(100), 80); + lv_obj_align_to(statusSection, header, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); + lv_obj_set_style_bg_color(statusSection, lv_color_hex(0x303030), 0); + lv_obj_set_style_pad_all(statusSection, 10, 0); + lv_obj_clear_flag(statusSection, LV_OBJ_FLAG_SCROLLABLE); + + statusLabel_ = lv_label_create(statusSection); + lv_label_set_text(statusLabel_, "Status: Nicht verbunden"); + lv_obj_align(statusLabel_, LV_ALIGN_LEFT_MID, 0, 0); + + disconnectBtn_ = lv_btn_create(statusSection); + lv_obj_set_size(disconnectBtn_, 100, 40); + lv_obj_align(disconnectBtn_, LV_ALIGN_RIGHT_MID, 0, 0); + lv_obj_add_event_cb(disconnectBtn_, onDisconnectClick, LV_EVENT_CLICKED, nullptr); + lv_obj_add_flag(disconnectBtn_, LV_OBJ_FLAG_HIDDEN); + + lv_obj_t* disconnectLbl = lv_label_create(disconnectBtn_); + lv_label_set_text(disconnectLbl, "Trennen"); + lv_obj_center(disconnectLbl); + + lv_obj_t* availableSection = lv_obj_create(overlay_); + lv_obj_set_size(availableSection, LV_PCT(100), 280); + lv_obj_align_to(availableSection, statusSection, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); + lv_obj_set_style_bg_color(availableSection, lv_color_hex(0x303030), 0); + lv_obj_set_style_pad_all(availableSection, 10, 0); + lv_obj_clear_flag(availableSection, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* availableHeader = lv_obj_create(availableSection); + lv_obj_set_size(availableHeader, LV_PCT(100), 40); + lv_obj_align(availableHeader, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_style_bg_opa(availableHeader, LV_OPA_TRANSP, 0); + lv_obj_set_style_border_width(availableHeader, 0, 0); + lv_obj_set_style_pad_all(availableHeader, 0, 0); + lv_obj_clear_flag(availableHeader, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* availableLbl = lv_label_create(availableHeader); + lv_label_set_text(availableLbl, "Verfuegbare Netzwerke:"); + lv_obj_align(availableLbl, LV_ALIGN_LEFT_MID, 0, 0); + + lv_obj_t* scanBtn = lv_btn_create(availableHeader); + lv_obj_set_size(scanBtn, 100, 35); + lv_obj_align(scanBtn, LV_ALIGN_RIGHT_MID, 0, 0); + lv_obj_add_event_cb(scanBtn, onScanClick, LV_EVENT_CLICKED, nullptr); + + lv_obj_t* scanLbl = lv_label_create(scanBtn); + lv_label_set_text(scanLbl, "Scannen"); + lv_obj_center(scanLbl); + + networkList_ = lv_list_create(availableSection); + lv_obj_set_size(networkList_, LV_PCT(100), 220); + lv_obj_align_to(networkList_, availableHeader, LV_ALIGN_OUT_BOTTOM_MID, 0, 5); + lv_obj_set_style_bg_color(networkList_, lv_color_hex(0x252525), 0); + + lv_obj_t* savedSection = lv_obj_create(overlay_); + lv_obj_set_size(savedSection, LV_PCT(100), 200); + lv_obj_align_to(savedSection, availableSection, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); + lv_obj_set_style_bg_color(savedSection, lv_color_hex(0x303030), 0); + lv_obj_set_style_pad_all(savedSection, 10, 0); + lv_obj_clear_flag(savedSection, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* savedLbl = lv_label_create(savedSection); + lv_label_set_text(savedLbl, "Gespeicherte Netzwerke:"); + lv_obj_align(savedLbl, LV_ALIGN_TOP_LEFT, 0, 0); + + savedList_ = lv_list_create(savedSection); + lv_obj_set_size(savedList_, LV_PCT(100), 150); + lv_obj_align(savedList_, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_obj_set_style_bg_color(savedList_, lv_color_hex(0x252525), 0); +} + +void WifiSetting::refreshNetworkList() { + ESP_LOGI(TAG, "Starting network scan"); + + if (networkList_) { + lv_obj_clean(networkList_); + lv_obj_t* scanningLbl = lv_list_add_text(networkList_, "Scanning..."); + (void)scanningLbl; + } + + Wifi::instance().scan([](std::vector& networks) { + WifiSetting& settings = WifiSetting::instance(); + settings.scannedNetworks_ = networks; + + if (esp_lv_adapter_lock(100) == ESP_OK) { + if (settings.networkList_) { + lv_obj_clean(settings.networkList_); + + for (const auto& ap : networks) { + char signalStr[64]; + int bars = 0; + if (ap.rssi >= -50) bars = 4; + else if (ap.rssi >= -60) bars = 3; + else if (ap.rssi >= -70) bars = 2; + else bars = 1; + + const char* barSymbols[] = {"[# ]", "[## ]", "[### ]", "[####]"}; + snprintf(signalStr, sizeof(signalStr), "%s %s %ddBm", + (const char*)ap.ssid, barSymbols[bars - 1], ap.rssi); + + lv_obj_t* btn = lv_list_add_btn(settings.networkList_, LV_SYMBOL_WIFI, signalStr); + lv_obj_add_event_cb(btn, onNetworkSelect, LV_EVENT_CLICKED, nullptr); + + size_t ssidLen = strlen((const char*)ap.ssid); + char* ssidCopy = (char*)lv_malloc(ssidLen + 1); + strcpy(ssidCopy, (const char*)ap.ssid); + lv_obj_set_user_data(btn, ssidCopy); + } + + if (networks.empty()) { + lv_list_add_text(settings.networkList_, "Keine Netzwerke gefunden"); + } + } + esp_lv_adapter_unlock(); + } + }); +} + +void WifiSetting::refreshSavedNetworks() { + if (!savedList_) return; + + lv_obj_clean(savedList_); + + auto savedNetworks = Wifi::instance().getSavedNetworks(); + + for (const auto& ssid : savedNetworks) { + lv_obj_t* item = lv_obj_create(savedList_); + lv_obj_set_size(item, LV_PCT(100), 40); + lv_obj_set_style_bg_color(item, lv_color_hex(0x353535), 0); + lv_obj_set_style_pad_all(item, 5, 0); + lv_obj_clear_flag(item, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* nameLbl = lv_label_create(item); + lv_label_set_text(nameLbl, ssid.c_str()); + lv_obj_align(nameLbl, LV_ALIGN_LEFT_MID, 0, 0); + + lv_obj_t* deleteBtn = lv_btn_create(item); + lv_obj_set_size(deleteBtn, 80, 30); + lv_obj_align(deleteBtn, LV_ALIGN_RIGHT_MID, 0, 0); + lv_obj_set_style_bg_color(deleteBtn, lv_color_hex(0x804040), 0); + lv_obj_add_event_cb(deleteBtn, onDeleteSavedClick, LV_EVENT_CLICKED, nullptr); + + char* ssidCopy = (char*)lv_malloc(ssid.size() + 1); + strcpy(ssidCopy, ssid.c_str()); + lv_obj_set_user_data(deleteBtn, ssidCopy); + + lv_obj_t* deleteLbl = lv_label_create(deleteBtn); + lv_label_set_text(deleteLbl, "Loeschen"); + lv_obj_center(deleteLbl); + } + + if (savedNetworks.empty()) { + lv_list_add_text(savedList_, "Keine gespeicherten Netzwerke"); + } +} + +void WifiSetting::updateStatusDisplay() { + if (!statusLabel_ || !disconnectBtn_) return; + + Wifi& wifi = Wifi::instance(); + + if (wifi.isConnected()) { + char statusText[64]; + snprintf(statusText, sizeof(statusText), "Verbunden: %s", wifi.getCurrentSSID().c_str()); + lv_label_set_text(statusLabel_, statusText); + lv_obj_clear_flag(disconnectBtn_, LV_OBJ_FLAG_HIDDEN); + } else { + lv_label_set_text(statusLabel_, "Status: Nicht verbunden"); + lv_obj_add_flag(disconnectBtn_, LV_OBJ_FLAG_HIDDEN); + } +} + +static void showPasswordDialogAsync(void* arg) { + WifiSetting::instance().createPasswordDialogUI(); +} + +void WifiSetting::showPasswordDialog(const char* ssid) { + selectedSSID_ = ssid; + lv_async_call(showPasswordDialogAsync, nullptr); +} + +void WifiSetting::createPasswordDialogUI() { + if (passwordDialog_) return; + + ESP_LOGI(TAG, "Creating password dialog for: %s", selectedSSID_.c_str()); + + passwordDialog_ = lv_obj_create(lv_scr_act()); + lv_obj_set_size(passwordDialog_, LV_PCT(100), LV_PCT(100)); + lv_obj_set_pos(passwordDialog_, 0, 0); + lv_obj_set_style_bg_color(passwordDialog_, lv_color_hex(0x303030), 0); + lv_obj_set_style_bg_opa(passwordDialog_, LV_OPA_COVER, 0); + lv_obj_set_style_pad_all(passwordDialog_, 20, 0); + lv_obj_clear_flag(passwordDialog_, LV_OBJ_FLAG_SCROLLABLE); + + char title[64]; + snprintf(title, sizeof(title), "Verbinden mit: %s", selectedSSID_.c_str()); + lv_obj_t* titleLbl = lv_label_create(passwordDialog_); + lv_label_set_text(titleLbl, title); + lv_obj_align(titleLbl, LV_ALIGN_TOP_MID, 0, 10); + + lv_obj_t* pwLabel = lv_label_create(passwordDialog_); + lv_label_set_text(pwLabel, "Passwort:"); + lv_obj_align(pwLabel, LV_ALIGN_TOP_LEFT, 10, 50); + + passwordInput_ = lv_textarea_create(passwordDialog_); + lv_obj_set_size(passwordInput_, LV_PCT(90), 50); + lv_obj_align(passwordInput_, LV_ALIGN_TOP_MID, 0, 80); + lv_textarea_set_password_mode(passwordInput_, true); + lv_textarea_set_one_line(passwordInput_, true); + lv_textarea_set_placeholder_text(passwordInput_, "Passwort eingeben..."); + + lv_obj_t* cancelBtn = lv_btn_create(passwordDialog_); + lv_obj_set_size(cancelBtn, 150, 50); + lv_obj_align(cancelBtn, LV_ALIGN_TOP_LEFT, 20, 150); + lv_obj_set_style_bg_color(cancelBtn, lv_color_hex(0x606060), 0); + lv_obj_add_event_cb(cancelBtn, onCancelClick, LV_EVENT_CLICKED, nullptr); + + lv_obj_t* cancelLbl = lv_label_create(cancelBtn); + lv_label_set_text(cancelLbl, "Abbrechen"); + lv_obj_center(cancelLbl); + + lv_obj_t* connectBtn = lv_btn_create(passwordDialog_); + lv_obj_set_size(connectBtn, 150, 50); + lv_obj_align(connectBtn, LV_ALIGN_TOP_RIGHT, -20, 150); + lv_obj_set_style_bg_color(connectBtn, lv_color_hex(0x408040), 0); + lv_obj_add_event_cb(connectBtn, onConnectClick, LV_EVENT_CLICKED, nullptr); + + lv_obj_t* connectLbl = lv_label_create(connectBtn); + lv_label_set_text(connectLbl, "Verbinden"); + lv_obj_center(connectLbl); + + keyboard_ = lv_keyboard_create(passwordDialog_); + lv_obj_set_size(keyboard_, LV_PCT(100), 300); + lv_obj_align(keyboard_, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_keyboard_set_textarea(keyboard_, passwordInput_); + lv_obj_add_event_cb(keyboard_, onKeyboardReady, LV_EVENT_READY, nullptr); + + ESP_LOGI(TAG, "Password dialog created"); +} + +void WifiSetting::hidePasswordDialog() { + if (passwordDialog_) { + lv_obj_del(passwordDialog_); + passwordDialog_ = nullptr; + passwordInput_ = nullptr; + keyboard_ = nullptr; + } + selectedSSID_.clear(); +} + +void WifiSetting::onCloseClick(lv_event_t* e) { + (void)e; + WifiSetting::instance().hide(); +} + +void WifiSetting::onNetworkSelect(lv_event_t* e) { + lv_obj_t* btn = (lv_obj_t*)lv_event_get_target(e); + char* ssid = (char*)lv_obj_get_user_data(btn); + if (ssid) { + ESP_LOGI(TAG, "Selected network: %s", ssid); + WifiSetting::instance().showPasswordDialog(ssid); + } +} + +void WifiSetting::onScanClick(lv_event_t* e) { + (void)e; + WifiSetting::instance().refreshNetworkList(); +} + +void WifiSetting::onDisconnectClick(lv_event_t* e) { + (void)e; + Wifi::instance().disconnect(); + WifiSetting::instance().updateStatusDisplay(); +} + +void WifiSetting::onConnectClick(lv_event_t* e) { + (void)e; + WifiSetting& settings = WifiSetting::instance(); + + if (settings.passwordInput_ && !settings.selectedSSID_.empty()) { + const char* password = lv_textarea_get_text(settings.passwordInput_); + + ESP_LOGI(TAG, "Connecting to %s", settings.selectedSSID_.c_str()); + + Wifi::instance().connect(settings.selectedSSID_.c_str(), password); + Wifi::instance().saveNetwork(settings.selectedSSID_.c_str(), password); + + settings.hidePasswordDialog(); + settings.refreshSavedNetworks(); + } +} + +void WifiSetting::onCancelClick(lv_event_t* e) { + (void)e; + WifiSetting::instance().hidePasswordDialog(); +} + +void WifiSetting::onDeleteSavedClick(lv_event_t* e) { + lv_obj_t* btn = (lv_obj_t*)lv_event_get_target(e); + char* ssid = (char*)lv_obj_get_user_data(btn); + if (ssid) { + ESP_LOGI(TAG, "Deleting saved network: %s", ssid); + Wifi::instance().removeNetwork(ssid); + lv_free(ssid); + WifiSetting::instance().refreshSavedNetworks(); + } +} + +void WifiSetting::onKeyboardReady(lv_event_t* e) { + (void)e; + onConnectClick(nullptr); +} diff --git a/main/Gui/WifiSetting.hpp b/main/Gui/WifiSetting.hpp index 84134d4..92e89c4 100644 --- a/main/Gui/WifiSetting.hpp +++ b/main/Gui/WifiSetting.hpp @@ -1,6 +1,51 @@ #pragma once +#include "lvgl.h" +#include "esp_wifi.h" +#include +#include class WifiSetting { - -} \ No newline at end of file +public: + static WifiSetting& instance(); + + void show(); + void hide(); + bool isVisible(); + void createPasswordDialogUI(); + +private: + WifiSetting() = default; + WifiSetting(const WifiSetting&) = delete; + WifiSetting& operator=(const WifiSetting&) = delete; + + void createUI(); + void refreshNetworkList(); + void refreshSavedNetworks(); + void updateStatusDisplay(); + void showPasswordDialog(const char* ssid); + void hidePasswordDialog(); + + static void onCloseClick(lv_event_t* e); + static void onNetworkSelect(lv_event_t* e); + static void onScanClick(lv_event_t* e); + static void onDisconnectClick(lv_event_t* e); + static void onConnectClick(lv_event_t* e); + static void onCancelClick(lv_event_t* e); + static void onDeleteSavedClick(lv_event_t* e); + static void onKeyboardReady(lv_event_t* e); + + lv_obj_t* overlay_ = nullptr; + lv_obj_t* statusLabel_ = nullptr; + lv_obj_t* disconnectBtn_ = nullptr; + lv_obj_t* networkList_ = nullptr; + lv_obj_t* savedList_ = nullptr; + lv_obj_t* passwordDialog_ = nullptr; + lv_obj_t* passwordInput_ = nullptr; + lv_obj_t* keyboard_ = nullptr; + + std::string selectedSSID_; + std::vector scannedNetworks_; + + bool visible_ = false; +}; diff --git a/main/Wifi.cpp b/main/Wifi.cpp new file mode 100644 index 0000000..6cae024 --- /dev/null +++ b/main/Wifi.cpp @@ -0,0 +1,315 @@ +#include "Wifi.hpp" +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "nvs_flash.h" +#include "nvs.h" +#include +#include + +static const char* TAG = "Wifi"; + +Wifi& Wifi::instance() { + static Wifi instance; + return instance; +} + +void Wifi::eventHandler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { + Wifi& wifi = Wifi::instance(); + + if (event_base == WIFI_EVENT) { + switch (event_id) { + case WIFI_EVENT_STA_START: + ESP_LOGI(TAG, "WiFi station started"); + break; + case WIFI_EVENT_STA_DISCONNECTED: + ESP_LOGI(TAG, "WiFi disconnected"); + wifi.connected_ = false; + wifi.currentSSID_ = ""; + if (wifi.statusCallback_) { + wifi.statusCallback_(false); + } + xEventGroupSetBits(wifi.wifiEventGroup_, WIFI_FAIL_BIT); + break; + case WIFI_EVENT_SCAN_DONE: + ESP_LOGI(TAG, "WiFi scan done"); + xEventGroupSetBits(wifi.wifiEventGroup_, WIFI_SCAN_DONE_BIT); + break; + default: + break; + } + } else if (event_base == IP_EVENT) { + if (event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data; + ESP_LOGI(TAG, "Got IP: " IPSTR, IP2STR(&event->ip_info.ip)); + wifi.connected_ = true; + if (wifi.statusCallback_) { + wifi.statusCallback_(true); + } + xEventGroupSetBits(wifi.wifiEventGroup_, WIFI_CONNECTED_BIT); + } + } +} + +void Wifi::init() { + if (initialized_) { + return; + } + + ESP_LOGI(TAG, "Initializing WiFi"); + + wifiEventGroup_ = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &eventHandler, + nullptr, + nullptr)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &eventHandler, + nullptr, + nullptr)); + + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_start()); + + initialized_ = true; + + auto savedNetworks = getSavedNetworks(); + if (!savedNetworks.empty()) { + std::string password; + if (getSavedPassword(savedNetworks[0].c_str(), password)) { + ESP_LOGI(TAG, "Auto-connecting to saved network: %s", savedNetworks[0].c_str()); + connect(savedNetworks[0].c_str(), password.c_str()); + } + } + + ESP_LOGI(TAG, "WiFi initialized"); +} + +void Wifi::scan(std::function&)> callback) { + scanCallback_ = callback; + + xEventGroupClearBits(wifiEventGroup_, WIFI_SCAN_DONE_BIT); + + wifi_scan_config_t scan_config = {}; + scan_config.ssid = nullptr; + scan_config.bssid = nullptr; + scan_config.channel = 0; + scan_config.show_hidden = false; + scan_config.scan_type = WIFI_SCAN_TYPE_ACTIVE; + scan_config.scan_time.active.min = 100; + scan_config.scan_time.active.max = 300; + + ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); + + xTaskCreate([](void* arg) { + Wifi& wifi = Wifi::instance(); + + xEventGroupWaitBits(wifi.wifiEventGroup_, WIFI_SCAN_DONE_BIT, + pdTRUE, pdFALSE, pdMS_TO_TICKS(10000)); + + uint16_t ap_count = 0; + esp_wifi_scan_get_ap_num(&ap_count); + + std::vector ap_records(ap_count); + if (ap_count > 0) { + esp_wifi_scan_get_ap_records(&ap_count, ap_records.data()); + } + + ESP_LOGI(TAG, "Found %d access points", ap_count); + + if (wifi.scanCallback_) { + wifi.scanCallback_(ap_records); + } + + vTaskDelete(nullptr); + }, "wifi_scan", 4096, nullptr, 5, nullptr); +} + +void Wifi::connect(const char* ssid, const char* password) { + ESP_LOGI(TAG, "Connecting to %s", ssid); + + xEventGroupClearBits(wifiEventGroup_, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT); + + wifi_config_t wifi_config = {}; + strncpy((char*)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid) - 1); + strncpy((char*)wifi_config.sta.password, password, sizeof(wifi_config.sta.password) - 1); + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + wifi_config.sta.pmf_cfg.capable = true; + wifi_config.sta.pmf_cfg.required = false; + + currentSSID_ = ssid; + + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_connect()); +} + +void Wifi::disconnect() { + ESP_LOGI(TAG, "Disconnecting"); + esp_wifi_disconnect(); + connected_ = false; + currentSSID_ = ""; +} + +bool Wifi::isConnected() { + return connected_; +} + +std::string Wifi::getCurrentSSID() { + return currentSSID_; +} + +void Wifi::setStatusCallback(std::function callback) { + statusCallback_ = callback; +} + +void Wifi::saveNetwork(const char* ssid, const char* password) { + nvs_handle_t handle; + esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error opening NVS: %s", esp_err_to_name(err)); + return; + } + + char key[32]; + snprintf(key, sizeof(key), "pw_%s", ssid); + + size_t key_len = strlen(key); + if (key_len > 15) { + key[15] = '\0'; + } + + err = nvs_set_str(handle, key, password); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error saving password: %s", esp_err_to_name(err)); + } + + auto networks = getSavedNetworks(); + bool found = false; + for (const auto& net : networks) { + if (net == ssid) { + found = true; + break; + } + } + + if (!found) { + networks.insert(networks.begin(), ssid); + if (networks.size() > MAX_SAVED_NETWORKS) { + networks.pop_back(); + } + + std::string networkList; + for (size_t i = 0; i < networks.size(); i++) { + if (i > 0) networkList += ";"; + networkList += networks[i]; + } + nvs_set_str(handle, "networks", networkList.c_str()); + } + + nvs_commit(handle); + nvs_close(handle); + + ESP_LOGI(TAG, "Saved network: %s", ssid); +} + +void Wifi::removeNetwork(const char* ssid) { + nvs_handle_t handle; + esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error opening NVS: %s", esp_err_to_name(err)); + return; + } + + char key[32]; + snprintf(key, sizeof(key), "pw_%s", ssid); + size_t key_len = strlen(key); + if (key_len > 15) { + key[15] = '\0'; + } + nvs_erase_key(handle, key); + + auto networks = getSavedNetworks(); + std::string ssidStr(ssid); + networks.erase(std::remove(networks.begin(), networks.end(), ssidStr), networks.end()); + + std::string networkList; + for (size_t i = 0; i < networks.size(); i++) { + if (i > 0) networkList += ";"; + networkList += networks[i]; + } + nvs_set_str(handle, "networks", networkList.c_str()); + + nvs_commit(handle); + nvs_close(handle); + + ESP_LOGI(TAG, "Removed network: %s", ssid); +} + +std::vector Wifi::getSavedNetworks() { + std::vector networks; + + nvs_handle_t handle; + esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &handle); + if (err != ESP_OK) { + return networks; + } + + size_t required_size = 0; + err = nvs_get_str(handle, "networks", nullptr, &required_size); + if (err == ESP_OK && required_size > 0) { + std::string networkList(required_size, '\0'); + nvs_get_str(handle, "networks", &networkList[0], &required_size); + + size_t start = 0; + size_t end = networkList.find(';'); + while (end != std::string::npos) { + networks.push_back(networkList.substr(start, end - start)); + start = end + 1; + end = networkList.find(';', start); + } + if (start < networkList.size() - 1) { + networks.push_back(networkList.substr(start)); + } + } + + nvs_close(handle); + return networks; +} + +bool Wifi::getSavedPassword(const char* ssid, std::string& password) { + nvs_handle_t handle; + esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &handle); + if (err != ESP_OK) { + return false; + } + + char key[32]; + snprintf(key, sizeof(key), "pw_%s", ssid); + size_t key_len = strlen(key); + if (key_len > 15) { + key[15] = '\0'; + } + + size_t required_size = 0; + err = nvs_get_str(handle, key, nullptr, &required_size); + if (err == ESP_OK && required_size > 0) { + password.resize(required_size); + nvs_get_str(handle, key, &password[0], &required_size); + nvs_close(handle); + return true; + } + + nvs_close(handle); + return false; +} diff --git a/main/Wifi.hpp b/main/Wifi.hpp new file mode 100644 index 0000000..1eedc6d --- /dev/null +++ b/main/Wifi.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include "esp_wifi.h" +#include "esp_event.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" + +class Wifi { +public: + static Wifi& instance(); + + void init(); + void scan(std::function&)> callback); + void connect(const char* ssid, const char* password); + void disconnect(); + bool isConnected(); + std::string getCurrentSSID(); + + void saveNetwork(const char* ssid, const char* password); + void removeNetwork(const char* ssid); + std::vector getSavedNetworks(); + bool getSavedPassword(const char* ssid, std::string& password); + + void setStatusCallback(std::function callback); + +private: + Wifi() = default; + Wifi(const Wifi&) = delete; + Wifi& operator=(const Wifi&) = delete; + + static void eventHandler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data); + + void loadSavedNetworksFromNvs(); + void saveSavedNetworksToNvs(); + + bool initialized_ = false; + bool connected_ = false; + std::string currentSSID_; + EventGroupHandle_t wifiEventGroup_ = nullptr; + std::function&)> scanCallback_; + std::function statusCallback_; + + static constexpr int WIFI_CONNECTED_BIT = BIT0; + static constexpr int WIFI_FAIL_BIT = BIT1; + static constexpr int WIFI_SCAN_DONE_BIT = BIT2; + + static constexpr const char* NVS_NAMESPACE = "wifi_creds"; + static constexpr int MAX_SAVED_NETWORKS = 10; +}; diff --git a/main/idf_component.yml b/main/idf_component.yml index 2ab90c5..0751256 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -19,3 +19,4 @@ dependencies: espressif/esp_lvgl_port: ^2.3.0 espressif/esp_lcd_touch_gt911: '*' espressif/esp_lvgl_adapter: '*' + espressif/esp_wifi_remote: '*' diff --git a/main/main.cpp b/main/main.cpp index 9f15e51..5dd8d0e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -9,6 +9,7 @@ #include "Gui.hpp" #include "Nvs.hpp" #include "KnxWorker.hpp" +#include "Wifi.hpp" #define TAG "App" @@ -19,6 +20,7 @@ public: void init() { // Initialize hardware nvs.init(); + Wifi::instance().init(); display.init(); touch.init(); diff --git a/partitions.csv b/partitions.csv new file mode 100644 index 0000000..cfe71e9 --- /dev/null +++ b/partitions.csv @@ -0,0 +1,4 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x200000,