diff --git a/.gitignore b/.gitignore index f2fdd83..a1451e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /idf-project/*/build /idf-project/*/sdkconfig +/idf-project/*/sdkconfig.old .dub *.a diff --git a/.vscode/settings.json b/.vscode/settings.json index 74250cb..8ca33bc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "d.dubCompiler": "/opt/ldc-xtensa/bin/ldc2", - "d.dubArchType": "xtensa-esp32", + "d.dubArchType": "xtensa-esp32-none-elf", "d.stdlibPath": [ "/opt/ldc-xtensa/include/d" ], diff --git a/idf-project/debug/partitions.csv b/idf-project/debug/partitions.csv new file mode 120000 index 0000000..cfc8996 --- /dev/null +++ b/idf-project/debug/partitions.csv @@ -0,0 +1 @@ +../partitions.csv \ No newline at end of file diff --git a/idf-project/debug/sdkconfig.defaults b/idf-project/debug/sdkconfig.defaults index e69de29..40db29b 100644 --- a/idf-project/debug/sdkconfig.defaults +++ b/idf-project/debug/sdkconfig.defaults @@ -0,0 +1,2 @@ +#CONFIG_PARTITION_TABLE_CUSTOM=y +#CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y \ No newline at end of file diff --git a/idf-project/main.cmake b/idf-project/main.cmake index 59deb84..01621a2 100644 --- a/idf-project/main.cmake +++ b/idf-project/main.cmake @@ -1,7 +1,10 @@ idf_component_register( SRCS "../../../source/idfd/signalio/idfd_signalio_i2s_c_code.c" + "../../../source/idf/esp_wifi/idf_esp_wifi_c_code.c" + "../../../source/idf/sys/socket/idf_sys_socket_c_code.c" INCLUDE_DIRS "." ) target_link_libraries("${COMPONENT_LIB}" "${PROJECT_DIR}/dcode.a") target_link_options("${COMPONENT_LIB}" INTERFACE "-Wl,--start-group") # Allow forward references during linkage +#target_link_options("${COMPONENT_LIB}" INTERFACE "-Wl,--print-gc-sections") diff --git a/idf-project/partitions.csv b/idf-project/partitions.csv new file mode 100644 index 0000000..4de07fa --- /dev/null +++ b/idf-project/partitions.csv @@ -0,0 +1,5 @@ +# Name, Type, SubType, Offset, Size, Flags +# 4M total +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 0x3F0000, diff --git a/idf-project/release/partitions.csv b/idf-project/release/partitions.csv new file mode 120000 index 0000000..cfc8996 --- /dev/null +++ b/idf-project/release/partitions.csv @@ -0,0 +1 @@ +../partitions.csv \ No newline at end of file diff --git a/idf-project/release/sdkconfig.defaults b/idf-project/release/sdkconfig.defaults index 49ef162..21c9fc2 100644 --- a/idf-project/release/sdkconfig.defaults +++ b/idf-project/release/sdkconfig.defaults @@ -1,2 +1,4 @@ CONFIG_COMPILER_OPTIMIZATION_PERF=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=n +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y +#CONFIG_PARTITION_TABLE_CUSTOM=y +#CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y \ No newline at end of file diff --git a/source/app/http.d b/source/app/http.d index c3f82da..104251a 100644 --- a/source/app/http.d +++ b/source/app/http.d @@ -11,7 +11,7 @@ import idf.sys.socket : accept, AF_INET, bind, close, connect, htonl, htons, IPA import idfd.log : Logger; import ministd.string : startsWith; -import ministd.typecons : UniqueHeapArray; +import ministd.typecons : UniqueHeapArray, SharedHeap; @safe nothrow @nogc: @@ -22,11 +22,11 @@ struct HttpServer private ushort m_port; private int m_listenSocket; private long m_recvTimeoutUsecs; - private Drawer* m_drawer; + private SharedHeap!Drawer m_drawer; @disable this(); - this(Drawer* drawer, ushort port, long recvTimeoutUsecs = 2_000_000) + this(SharedHeap!Drawer drawer, ushort port, long recvTimeoutUsecs = 2_000_000) { m_drawer = drawer; m_port = port; diff --git a/source/app/main.d b/source/app/main.d index bf52d36..f1f3422 100644 --- a/source/app/main.d +++ b/source/app/main.d @@ -16,7 +16,7 @@ import idfd.signalio.i2s : I2SSignalGenerator; import idfd.signalio.router : route; import idfd.signalio.signal : Signal; -import ministd.typecons : UniqueHeapArray; +import ministd.typecons : UniqueHeapArray, SharedHeap; // dfmt off @safe: @@ -38,35 +38,35 @@ struct TScherm(TSchermCTConfig ctConfig) private enum log = Logger!"TScherm"(); private const TSchermRTConfig m_rtConfig; - private FrameBuffer m_fb; + private SharedHeap!FrameBuffer m_fb; private DMADescriptorRing m_dmaDescriptorRing; private I2SSignalGenerator m_signalGenerator; - // private Drawer m_drawer; - // private WiFiClient m_wifiClient; - // private HttpServer m_httpServer; + private SharedHeap!Drawer m_drawer; + private WiFiClient m_wifiClient; + private HttpServer m_httpServer; this(const TSchermRTConfig rtConfig) { m_rtConfig = rtConfig; - // Init network async { - // m_wifiClient = WiFiClient(rtConfig.ssid, rtConfig.password); - // m_wifiClient.startAsync; + log.info!"Initializing network (async)"; + + m_wifiClient = WiFiClient(rtConfig.ssid, rtConfig.password); + m_wifiClient.startAsync; } - // Init VGA { - log.info!"initializing VGA"; + log.info!"Initializing VGA"; - m_fb = FrameBuffer(m_rtConfig.vt); + m_fb = SharedHeap!FrameBuffer.create(m_rtConfig.vt); m_signalGenerator = I2SSignalGenerator( i2sIndex: 1, bitCount: 8, freq: m_rtConfig.vt.pixelClock, ); m_dmaDescriptorRing = DMADescriptorRing(m_rtConfig.vt.v.total); - m_dmaDescriptorRing.setBuffers((() @trusted => cast(ubyte[][]) m_fb.linesWithSync)()); + m_dmaDescriptorRing.setBuffers((() @trusted => cast(ubyte[][]) m_fb.get.linesWithSync)()); UniqueHeapArray!Signal signals = m_signalGenerator.getSignals; // route(from: signals.get[0], to: GPIOPin(m_rtConfig.redPin ), invert: false); // Red @@ -80,21 +80,23 @@ struct TScherm(TSchermCTConfig ctConfig) m_signalGenerator.startTransmitting(m_dmaDescriptorRing.firstDescriptor); - // m_drawer = Drawer(&m_fb); + m_drawer = SharedHeap!Drawer.create(m_fb); log.info!"VGA initialization complete"; } - // Wait for async network init to complete { - // m_wifiClient.waitForConnection; + log.info!"Waiting for network to initialize"; + + m_wifiClient.waitForConnection; - // log.info!"Network initialization complete"; + log.info!"Network initialization complete"; } { - // m_httpServer = HttpServer(&m_drawer, m_rtConfig.httpPort); - // m_httpServer.start; + log.info!"Starting http server (in another task)"; + m_httpServer = HttpServer(m_drawer, m_rtConfig.httpPort); + m_httpServer.start; } } @@ -132,10 +134,10 @@ void app_main() tScherm.m_fb.fill(Color.WHITE); pause(200); - tScherm.drawImage!"zeus.raw"; - pause(800); - tScherm.drawImage!"reavershark.raw"; - pause(800); + // tScherm.drawImage!"zeus.raw"; + // pause(800); + // tScherm.drawImage!"reavershark.raw"; + // pause(800); tScherm.m_fb.fillIteratingColorsDiagonal!"x+y/vDivide"; pause(200); diff --git a/source/app/vga/draw.d b/source/app/vga/draw.d index 7689549..399138f 100644 --- a/source/app/vga/draw.d +++ b/source/app/vga/draw.d @@ -7,6 +7,7 @@ import app.vga.framebuffer : FrameBuffer; import idfd.log : Logger; import ministd.traits : isInstanceOf; +import ministd.typecons : SharedHeap; @safe nothrow @nogc: @@ -14,17 +15,20 @@ struct Box { size_t x1, x2, y1, y2; - bool valid() const pure => x1 < x2 && y1 < y2; +const pure nothrow @nogc: - size_t width() const pure => x2 - x1; - size_t height() const pure => y2 - y1; + bool valid() => x1 < x2 && y1 < y2; + + size_t width() => x2 - x1; + size_t height() => y2 - y1; } struct Drawer { +@nogc: private enum log = Logger!"Drawer"(); - private FrameBuffer* m_fb; + private SharedHeap!FrameBuffer m_fb; private Color m_backgroundColor; private size_t m_separatorX; private Color m_separatorColor; @@ -32,8 +36,8 @@ struct Drawer @disable this(); - this(FrameBuffer* fb) - in (fb !is null) + this(SharedHeap!FrameBuffer fb) + in (!fb.empty) { m_fb = fb; @@ -64,7 +68,7 @@ struct Drawer in (m_separatorX < m_fb.activeWidth) { foreach (y; 0 .. m_fb.activeHeight) - (*m_fb)[y, m_separatorX] = m_separatorColor; + m_fb[y, m_separatorX] = m_separatorColor; } private void scrollBoxDown( @@ -84,9 +88,9 @@ struct Drawer foreach (x; box.x1 .. box.x2) { if (y + amount < box.y2) - (*m_fb)[y, x] = (*m_fb)[y + amount, x]; + m_fb[y, x] = m_fb[y + amount, x]; else - (*m_fb)[y, x] = background; + (m_fb)[y, x] = background; } } @@ -110,7 +114,7 @@ struct Drawer foreach (x; 0 .. font.glyphWidth) { Color color = glyph[y][x] > 0x80 ? m_textColor : m_backgroundColor; - (*m_fb)[box.y1 + y, box.x1 + xOffset + x] = color; + m_fb[box.y1 + y, box.x1 + xOffset + x] = color; } } } diff --git a/source/app/vga/framebuffer.d b/source/app/vga/framebuffer.d index 3f4e910..9ceb61b 100644 --- a/source/app/vga/framebuffer.d +++ b/source/app/vga/framebuffer.d @@ -14,6 +14,7 @@ import ministd.heap_caps : dallocArrayCaps; struct FrameBuffer { +@nogc: enum log = Logger!"FrameBuffer"(); private const VideoTimings m_vt; @@ -125,7 +126,7 @@ struct FrameBuffer void fillIteratingColorsDiagonal(string indexFunc = "x+y/vDivide")() { - immutable Color[] colors = [ + static immutable Color[] colors = [ Color.WHITE, Color.BLACK, ]; diff --git a/source/app/vga/video_timings.d b/source/app/vga/video_timings.d index 4018cb5..5c94869 100644 --- a/source/app/vga/video_timings.d +++ b/source/app/vga/video_timings.d @@ -7,16 +7,17 @@ struct VideoTimings { struct Dimension { +const pure nothrow @nogc: uint front, sync, back, res; - uint total() const pure => front + sync + back + res; - uint frontStart() const pure => 0; - uint frontEnd() const pure => front; - uint syncStart() const pure => front; - uint syncEnd() const pure => front + sync; - uint backStart() const pure => front + sync; - uint backEnd() const pure => front + sync + back; - uint resStart() const pure => front + sync + back; - uint resEnd() const pure => front + sync + back + res; + uint total() => front + sync + back + res; + uint frontStart() => 0; + uint frontEnd() => front; + uint syncStart() => front; + uint syncEnd() => front + sync; + uint backStart() => front + sync; + uint backEnd() => front + sync + back; + uint resStart() => front + sync + back; + uint resEnd() => front + sync + back + res; } ulong pixelClock; diff --git a/source/idf/esp_hw_support/esp_interface.d b/source/idf/esp_hw_support/esp_interface.d new file mode 100644 index 0000000..b27b99c --- /dev/null +++ b/source/idf/esp_hw_support/esp_interface.d @@ -0,0 +1,11 @@ +module idf.esp_hw_support.esp_interface; + +@safe pure nothrow extern(C): + +enum esp_interface_t +{ + ESP_IF_WIFI_STA = 0, /**< ESP32 station interface */ + ESP_IF_WIFI_AP, /**< ESP32 soft-AP interface */ + ESP_IF_ETH, /**< ESP32 ethernet interface */ + ESP_IF_MAX +} diff --git a/source/idf/esp_netif/package.d b/source/idf/esp_netif/package.d new file mode 100644 index 0000000..9cd42bf --- /dev/null +++ b/source/idf/esp_netif/package.d @@ -0,0 +1,64 @@ +module idf.esp_netif; + +import idf.esp_common.esp_err : esp_err_t; +import idf.esp_event : esp_event_base_t; + +@safe nothrow @nogc extern (C): +// dfmt off + +alias esp_netif_t = void; + +/** IP event declarations */ +enum ip_event_t +{ + IP_EVENT_STA_GOT_IP, /*!< station got IP from connected AP */ + IP_EVENT_STA_LOST_IP, /*!< station lost IP and the IP is reset to 0 */ + IP_EVENT_AP_STAIPASSIGNED, /*!< soft-AP assign an IP to a connected station */ + IP_EVENT_GOT_IP6, /*!< station or ap or ethernet interface v6IP addr is preferred */ + IP_EVENT_ETH_GOT_IP, /*!< ethernet got IP from connected AP */ + IP_EVENT_ETH_LOST_IP, /*!< ethernet lost IP and the IP is reset to 0 */ + IP_EVENT_PPP_GOT_IP, /*!< PPP interface got IP */ + IP_EVENT_PPP_LOST_IP, /*!< PPP interface lost IP */ +} + +/** + * @brief IPv4 address + * + */ +struct esp_ip4_addr_t +{ + uint addr; /*!< IPv4 address */ +} + +struct esp_netif_ip_info_t +{ + esp_ip4_addr_t ip; /**< Interface IPV4 address */ + esp_ip4_addr_t netmask; /**< Interface IPV4 netmask */ + esp_ip4_addr_t gw; /**< Interface IPV4 gateway address */ +} + +/** + * @brief Event structure for IP_EVENT_GOT_IP event + * + */ +struct ip_event_got_ip_t +{ + int if_index; /*!< Interface index for which the event is received (left for legacy compilation) */ + esp_netif_t* esp_netif; /*!< Pointer to corresponding esp-netif object */ + esp_netif_ip_info_t ip_info; /*!< IP address, netmask, gatway IP address */ + bool ip_changed; /*!< Whether the assigned IP has changed or not */ +} + +/** + * @brief Initialize the underlying TCP/IP stack + * + * @return + * - ESP_OK on success + * - ESP_FAIL if initializing failed + + * @note This function should be called exactly once from application code, when the application starts up. + */ +esp_err_t esp_netif_init(); + +/** @brief IP event base declaration */ +extern __gshared esp_event_base_t IP_EVENT; diff --git a/source/idf/esp_wifi/esp_private/wifi_os_adapter.d b/source/idf/esp_wifi/esp_private/wifi_os_adapter.d new file mode 100644 index 0000000..3bebaf4 --- /dev/null +++ b/source/idf/esp_wifi/esp_private/wifi_os_adapter.d @@ -0,0 +1,151 @@ +module idf.esp_wifi.esp_private.wifi_os_adapter; + +import core.stdc.stdarg : va_list; + +@safe nothrow @nogc extern (C): + +// dfmt off +enum ESP_WIFI_OS_ADAPTER_VERSION = 0x00000008; +enum ESP_WIFI_OS_ADAPTER_MAGIC = 0xDEADBEAF; + +enum OSI_FUNCS_TIME_BLOCKING = 0xffffffff; + +enum OSI_QUEUE_SEND_FRONT = 0; +enum OSI_QUEUE_SEND_BACK = 1; +enum OSI_QUEUE_SEND_OVERWRITE = 2; +// dfmt on + +struct wifi_osi_funcs_t +{ + int _version; + bool function() _env_is_chip; + void function(int cpu_no, uint intr_source, uint intr_num, int intr_prio) _set_intr; + void function(uint intr_source, uint intr_num) _clear_intr; + void function(int n, void* f, void* arg) _set_isr; + void function(uint mask) _ints_on; + void function(uint mask) _ints_off; + bool function() _is_from_isr; + void* function() _spin_lock_create; + void function(void* lock) _spin_lock_delete; + uint function(void* wifi_int_mux) _wifi_int_disable; + void function(void* wifi_int_mux, uint tmp) _wifi_int_restore; + void function() _task_yield_from_isr; + void* function(uint max, uint init) _semphr_create; + void function(void* semphr) _semphr_delete; + int function(void* semphr, uint block_time_tick) _semphr_take; + int function(void* semphr) _semphr_give; + void* function() _wifi_thread_semphr_get; + void* function() _mutex_create; + void* function() _recursive_mutex_create; + void function(void* mutex) _mutex_delete; + int function(void* mutex) _mutex_lock; + int function(void* mutex) _mutex_unlock; + void* function(uint queue_len, uint item_size) _queue_create; + void function(void* queue) _queue_delete; + int function(void* queue, void* item, uint block_time_tick) _queue_send; + int function(void* queue, void* item, void* hptw) _queue_send_from_isr; + int function(void* queue, void* item, uint block_time_tick) _queue_send_to_back; + int function(void* queue, void* item, uint block_time_tick) _queue_send_to_front; + int function(void* queue, void* item, uint block_time_tick) _queue_recv; + uint function(void* queue) _queue_msg_waiting; + void* function() _event_group_create; + void function(void* event) _event_group_delete; + uint function(void* event, uint bits) _event_group_set_bits; + uint function(void* event, uint bits) _event_group_clear_bits; + uint function(void* event, uint bits_to_wait_for, int clear_on_exit, int wait_for_all_bits, uint block_time_tick) _event_group_wait_bits; + int function(void* task_func, const char* name, uint stack_depth, void* param, uint prio, void* task_handle, uint core_id) _task_create_pinned_to_core; + int function(void* task_func, const char* name, uint stack_depth, void* param, uint prio, void* task_handle) _task_create; + void function(void* task_handle) _task_delete; + void function(uint tick) _task_delay; + int function(uint ms) _task_ms_to_tick; + void* function() _task_get_current_task; + int function() _task_get_max_priority; + void* function(uint size) _malloc; + void function(void* p) _free; + int function(const char* event_base, int event_id, void* event_data, size_t event_data_size, uint ticks_to_wait) _event_post; + uint function() _get_free_heap_size; + uint function() _rand; + void function() _dport_access_stall_other_cpu_start_wrap; + void function() _dport_access_stall_other_cpu_end_wrap; + void function() _wifi_apb80m_request; + void function() _wifi_apb80m_release; + void function() _phy_disable; + void function() _phy_enable; + + static if (is(typeof(CONFIG_IDF_TARGET_ESP32)) || is(typeof(CONFIG_IDF_TARGET_ESP32S2))) + { + void function() _phy_common_clock_enable; + void function() _phy_common_clock_disable; + } + + int function(const char* country) _phy_update_country_info; + int function(ubyte* mac, uint type) _read_mac; + void function(void* timer, uint tmout, bool repeat) _timer_arm; + void function(void* timer) _timer_disarm; + void function(void* ptimer) _timer_done; + void function(void* ptimer, void* pfunction, void* parg) _timer_setfn; + void function(void* ptimer, uint us, bool repeat) _timer_arm_us; + void function() _wifi_reset_mac; + void function() _wifi_clock_enable; + void function() _wifi_clock_disable; + void function() _wifi_rtc_enable_iso; + void function() _wifi_rtc_disable_iso; + long function() _esp_timer_get_time; + int function(uint handle, const char* key, byte value) _nvs_set_i8; + int function(uint handle, const char* key, byte* out_value) _nvs_get_i8; + int function(uint handle, const char* key, ubyte value) _nvs_set_u8; + int function(uint handle, const char* key, ubyte* out_value) _nvs_get_u8; + int function(uint handle, const char* key, ushort value) _nvs_set_u16; + int function(uint handle, const char* key, ushort* out_value) _nvs_get_u16; + int function(const char* name, uint open_mode, uint* out_handle) _nvs_open; + void function(uint handle) _nvs_close; + int function(uint handle) _nvs_commit; + int function(uint handle, const char* key, const void* value, size_t length) _nvs_set_blob; + int function(uint handle, const char* key, void* out_value, size_t* length) _nvs_get_blob; + int function(uint handle, const char* key) _nvs_erase_key; + int function(ubyte* buf, size_t len) _get_random; + int function(void* t) _get_time; + ulong function() _random; + + static if (is(typeof(CONFIG_IDF_TARGET_ESP32S2)) || is(typeof(CONFIG_IDF_TARGET_ESP32S3)) || is( + CONFIG_IDF_TARGET_ESP32C3)) + { + uint function() _slowclk_cal_get; + } + + void function(uint level, const char* tag, const char* format, ...) _log_write; + void function(uint level, const char* tag, const char* format, va_list args) _log_writev; + uint function() _log_timestamp; + void* function(size_t size) _malloc_internal; + void* function(void* ptr, size_t size) _realloc_internal; + void* function(size_t n, size_t size) _calloc_internal; + void* function(size_t size) _zalloc_internal; + void* function(size_t size) _wifi_malloc; + void* function(void* ptr, size_t size) _wifi_realloc; + void* function(size_t n, size_t size) _wifi_calloc; + void* function(size_t size) _wifi_zalloc; + void* function(int queue_len, int item_size) _wifi_create_queue; + void function(void* queue) _wifi_delete_queue; + int function() _coex_init; + void function() _coex_deinit; + int function() _coex_enable; + void function() _coex_disable; + uint function() _coex_status_get; + void function(uint type, bool dissatisfy) _coex_condition_set; + int function(uint event, uint latency, uint duration) _coex_wifi_request; + int function(uint event) _coex_wifi_release; + int function(ubyte primary, ubyte secondary) _coex_wifi_channel_set; + int function(uint event, uint* duration) _coex_event_duration_get; + int function(uint event, ubyte* pti) _coex_pti_get; + void function(uint type, uint status) _coex_schm_status_bit_clear; + void function(uint type, uint status) _coex_schm_status_bit_set; + int function(uint interval) _coex_schm_interval_set; + uint function() _coex_schm_interval_get; + ubyte function() _coex_schm_curr_period_get; + void* function() _coex_schm_curr_phase_get; + int function(int idx) _coex_schm_curr_phase_idx_set; + int function() _coex_schm_curr_phase_idx_get; + int _magic; +} + +extern __gshared wifi_osi_funcs_t g_wifi_osi_funcs; diff --git a/source/idf/esp_wifi/esp_wifi.d b/source/idf/esp_wifi/esp_wifi.d new file mode 100644 index 0000000..5c4ab43 --- /dev/null +++ b/source/idf/esp_wifi/esp_wifi.d @@ -0,0 +1,252 @@ +module idf.esp_wifi.esp_wifi; + +import idf.esp_common.esp_err : esp_err_t, ESP_ERR_WIFI_BASE; +import idf.esp_event : system_event_handler_t; +import idf.esp_wifi.esp_private.wifi_os_adapter : g_wifi_osi_funcs, wifi_osi_funcs_t; +import idf.esp_wifi.esp_wifi_crypto_types : wpa_crypto_funcs_t; +import idf.esp_wifi.esp_wifi_types; +import idf.esp_event : esp_event_send_internal; +import idf.sdkconfig; + +@safe nothrow @nogc extern (C): +// dfmt off + +// +// Manifest constants +// + +enum ESP_ERR_WIFI_NOT_INIT = ESP_ERR_WIFI_BASE + 1; /*!< WiFi driver was not installed by esp_wifi_init */ +enum ESP_ERR_WIFI_NOT_STARTED = ESP_ERR_WIFI_BASE + 2; /*!< WiFi driver was not started by esp_wifi_start */ +enum ESP_ERR_WIFI_NOT_STOPPED = ESP_ERR_WIFI_BASE + 3; /*!< WiFi driver was not stopped by esp_wifi_stop */ +enum ESP_ERR_WIFI_IF = ESP_ERR_WIFI_BASE + 4; /*!< WiFi interface error */ +enum ESP_ERR_WIFI_MODE = ESP_ERR_WIFI_BASE + 5; /*!< WiFi mode error */ +enum ESP_ERR_WIFI_STATE = ESP_ERR_WIFI_BASE + 6; /*!< WiFi internal state error */ +enum ESP_ERR_WIFI_CONN = ESP_ERR_WIFI_BASE + 7; /*!< WiFi internal control block of station or soft-AP error */ +enum ESP_ERR_WIFI_NVS = ESP_ERR_WIFI_BASE + 8; /*!< WiFi internal NVS module error */ +enum ESP_ERR_WIFI_MAC = ESP_ERR_WIFI_BASE + 9; /*!< MAC address is invalid */ +enum ESP_ERR_WIFI_SSID = ESP_ERR_WIFI_BASE + 10; /*!< SSID is invalid */ +enum ESP_ERR_WIFI_PASSWORD = ESP_ERR_WIFI_BASE + 11; /*!< Password is invalid */ +enum ESP_ERR_WIFI_TIMEOUT = ESP_ERR_WIFI_BASE + 12; /*!< Timeout error */ +enum ESP_ERR_WIFI_WAKE_FAIL = ESP_ERR_WIFI_BASE + 13; /*!< WiFi is in sleep state(RF closed) and wakeup fail */ +enum ESP_ERR_WIFI_WOULD_BLOCK = ESP_ERR_WIFI_BASE + 14; /*!< The caller would block */ +enum ESP_ERR_WIFI_NOT_CONNECT = ESP_ERR_WIFI_BASE + 15; /*!< Station still in disconnect status */ + +enum ESP_ERR_WIFI_POST = ESP_ERR_WIFI_BASE + 18; /*!< Failed to post the event to WiFi task */ +enum ESP_ERR_WIFI_INIT_STATE = ESP_ERR_WIFI_BASE + 19; /*!< Invalid WiFi state when init/deinit is called */ +enum ESP_ERR_WIFI_STOP_STATE = ESP_ERR_WIFI_BASE + 20; /*!< Returned when WiFi is stopping */ +enum ESP_ERR_WIFI_NOT_ASSOC = ESP_ERR_WIFI_BASE + 21; /*!< The WiFi connection is not associated */ +enum ESP_ERR_WIFI_TX_DISALLOW = ESP_ERR_WIFI_BASE + 22; /*!< The WiFi TX is disallowed */ +enum ESP_ERR_WIFI_DISCARD = ESP_ERR_WIFI_BASE + 23; /*!< Discard frame */ +enum ESP_ERR_WIFI_ROC_IN_PROGRESS = ESP_ERR_WIFI_BASE + 28; /*!< ROC op is in progress */ + +static if (is(typeof(CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM))) + enum WIFI_STATIC_TX_BUFFER_NUM = CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM; +else + enum WIFI_STATIC_TX_BUFFER_NUM = 0; + +static if (is(typeof(CONFIG_ESP32_SPIRAM_SUPPORT)) || is(typeof(CONFIG_ESP32S2_SPIRAM_SUPPORT)) || is( + CONFIG_ESP32S3_SPIRAM_SUPPORT)) + enum WIFI_CACHE_TX_BUFFER_NUM = CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM; +else + enum WIFI_CACHE_TX_BUFFER_NUM = 0; + +static if (is(typeof(CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM))) + enum WIFI_DYNAMIC_TX_BUFFER_NUM = CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM; +else + enum WIFI_DYNAMIC_TX_BUFFER_NUM = 0; + +static if (is(typeof(CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF))) + enum WIFI_RX_MGMT_BUF_NUM_DEF = CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF; +else + enum WIFI_RX_MGMT_BUF_NUM_DEF = 0; + +enum WIFI_CSI_ENABLED = is(typeof(CONFIG_ESP32_WIFI_CSI_ENABLED)); +enum WIFI_AMPDU_RX_ENABLED = is(typeof(CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED)); +enum WIFI_AMPDU_TX_ENABLED = is(typeof(CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED)); +enum WIFI_AMSDU_TX_ENABLED = is(typeof(CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED)); +enum WIFI_NVS_ENABLED = is(typeof(CONFIG_ESP32_WIFI_NVS_ENABLED)); +enum WIFI_NANO_FORMAT_ENABLED = is(typeof(CONFIG_NEWLIB_NANO_FORMAT)); + +enum WIFI_INIT_CONFIG_MAGIC = 0x1F2F3F4F; + +static if (is(typeof(CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED))) + enum WIFI_DEFAULT_RX_BA_WIN = CONFIG_ESP32_WIFI_RX_BA_WIN; +else + enum WIFI_DEFAULT_RX_BA_WIN = 0; + +enum WIFI_TASK_CORE_ID = is(typeof(CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1)); + +static if (is(typeof(CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN))) + enum WIFI_SOFTAP_BEACON_MAX_LEN = CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN; +else + enum WIFI_SOFTAP_BEACON_MAX_LEN = 752; + +static if (is(typeof(CONFIG_ESP32_WIFI_MGMT_SBUF_NUM))) + enum WIFI_MGMT_SBUF_NUM = CONFIG_ESP32_WIFI_MGMT_SBUF_NUM; +else + enum WIFI_MGMT_SBUF_NUM = 32; + +enum WIFI_STA_DISCONNECTED_PM_ENABLED = is(typeof(CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE)); + +enum CONFIG_FEATURE_WPA3_SAE_BIT = 1 << 0; +enum CONFIG_FEATURE_CACHE_TX_BUF_BIT = 1 << 1; +enum CONFIG_FEATURE_FTM_INITIATOR_BIT = 1 << 2; +enum CONFIG_FEATURE_FTM_RESPONDER_BIT = 1 << 3; + +// +// Types +// + +/// WiFi stack configuration parameters passed to esp_wifi_init call. +struct wifi_init_config_t +{ + system_event_handler_t event_handler; /**< WiFi event handler */ + wifi_osi_funcs_t* osi_funcs; /**< WiFi OS functions */ + wpa_crypto_funcs_t wpa_crypto_funcs; /**< WiFi station crypto functions when connect */ + int static_rx_buf_num; /**< WiFi static RX buffer number */ + int dynamic_rx_buf_num; /**< WiFi dynamic RX buffer number */ + int tx_buf_type; /**< WiFi TX buffer type */ + int static_tx_buf_num; /**< WiFi static TX buffer number */ + int dynamic_tx_buf_num; /**< WiFi dynamic TX buffer number */ + int rx_mgmt_buf_type; /**< WiFi RX MGMT buffer type */ + int rx_mgmt_buf_num; /**< WiFi RX MGMT buffer number */ + int cache_tx_buf_num; /**< WiFi TX cache buffer number */ + int csi_enable; /**< WiFi channel state information enable flag */ + int ampdu_rx_enable; /**< WiFi AMPDU RX feature enable flag */ + int ampdu_tx_enable; /**< WiFi AMPDU TX feature enable flag */ + int amsdu_tx_enable; /**< WiFi AMSDU TX feature enable flag */ + int nvs_enable; /**< WiFi NVS flash enable flag */ + int nano_enable; /**< Nano option for printf/scan family enable flag */ + int rx_ba_win; /**< WiFi Block Ack RX window size */ + int wifi_task_core_id; /**< WiFi Task Core ID */ + int beacon_max_len; /**< WiFi softAP maximum length of the beacon */ + int mgmt_sbuf_num; /**< WiFi management short buffer number, the minimum value is 6, the maximum value is 32 */ + ulong feature_caps; /**< Enables additional WiFi features and capabilities */ + bool sta_disconnected_pm; /**< WiFi Power Management for station at disconnected status */ + int espnow_max_encrypt_num; /**< Maximum encrypt number of peers supported by espnow */ + int magic; /**< WiFi init magic number, it should be the last field */ +} + +alias wifi_promiscuous_cb_t = void function(void* buf, wifi_promiscuous_pkt_type_t type); +alias esp_vendor_ie_cb_t = void function(void* ctx, wifi_vendor_ie_type_t type, const ubyte[6] sa, const vendor_ie_data_t* vnd_ie, int rssi); +alias wifi_csi_cb_t = void function(void* ctx, wifi_csi_info_t* data); + + +// +// Global variables +// + +extern __gshared const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; +extern __gshared ulong g_wifi_feature_caps; + +// +// Functions +// + +@trusted +wifi_init_config_t WIFI_INIT_CONFIG_DEFAULT() +{ + return wifi_init_config_t( + event_handler : &esp_event_send_internal, + osi_funcs : &g_wifi_osi_funcs, + wpa_crypto_funcs : g_wifi_default_wpa_crypto_funcs, + static_rx_buf_num : CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM, + dynamic_rx_buf_num : CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM, + tx_buf_type : CONFIG_ESP32_WIFI_TX_BUFFER_TYPE, + static_tx_buf_num : WIFI_STATIC_TX_BUFFER_NUM, + dynamic_tx_buf_num : WIFI_DYNAMIC_TX_BUFFER_NUM, + rx_mgmt_buf_type : CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF, + rx_mgmt_buf_num : WIFI_RX_MGMT_BUF_NUM_DEF, + cache_tx_buf_num : WIFI_CACHE_TX_BUFFER_NUM, + csi_enable : WIFI_CSI_ENABLED, + ampdu_rx_enable : WIFI_AMPDU_RX_ENABLED, + ampdu_tx_enable : WIFI_AMPDU_TX_ENABLED, + amsdu_tx_enable : WIFI_AMSDU_TX_ENABLED, + nvs_enable : WIFI_NVS_ENABLED, + nano_enable : WIFI_NANO_FORMAT_ENABLED, + rx_ba_win : WIFI_DEFAULT_RX_BA_WIN, + wifi_task_core_id : WIFI_TASK_CORE_ID, + beacon_max_len : WIFI_SOFTAP_BEACON_MAX_LEN, + mgmt_sbuf_num : WIFI_MGMT_SBUF_NUM, + feature_caps : g_wifi_feature_caps, + sta_disconnected_pm : WIFI_STA_DISCONNECTED_PM_ENABLED, + espnow_max_encrypt_num : CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM, + magic : WIFI_INIT_CONFIG_MAGIC, + ); +} + +esp_err_t esp_wifi_init(const wifi_init_config_t* config); +esp_err_t esp_wifi_deinit(); +esp_err_t esp_wifi_set_mode(wifi_mode_t mode); +esp_err_t esp_wifi_get_mode(wifi_mode_t* mode); +esp_err_t esp_wifi_start(); +esp_err_t esp_wifi_stop(); +esp_err_t esp_wifi_restore(); +esp_err_t esp_wifi_connect(); +esp_err_t esp_wifi_disconnect(); +esp_err_t esp_wifi_clear_fast_connect(); +esp_err_t esp_wifi_deauth_sta(ushort aid); +esp_err_t esp_wifi_scan_start(const wifi_scan_config_t* config, bool block); +esp_err_t esp_wifi_scan_stop(); +esp_err_t esp_wifi_scan_get_ap_num(ushort* number); +esp_err_t esp_wifi_scan_get_ap_records(ushort* number, wifi_ap_record_t* ap_records); +esp_err_t esp_wifi_clear_ap_list(); +esp_err_t esp_wifi_sta_get_ap_info(wifi_ap_record_t* ap_info); +esp_err_t esp_wifi_set_ps(wifi_ps_type_t type); +esp_err_t esp_wifi_get_ps(wifi_ps_type_t* type); +esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, ubyte protocol_bitmap); +esp_err_t esp_wifi_get_protocol(wifi_interface_t ifx, ubyte* protocol_bitmap); +esp_err_t esp_wifi_set_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t bw); +esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t* bw); +esp_err_t esp_wifi_set_channel(ubyte primary, wifi_second_chan_t second); +esp_err_t esp_wifi_get_channel(ubyte* primary, wifi_second_chan_t* second); +esp_err_t esp_wifi_set_country(const wifi_country_t* country); +esp_err_t esp_wifi_get_country(wifi_country_t* country); +esp_err_t esp_wifi_set_mac(wifi_interface_t ifx, const ubyte[6] mac); +esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, ubyte[6] mac); +esp_err_t esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); +esp_err_t esp_wifi_set_promiscuous(bool en); +esp_err_t esp_wifi_get_promiscuous(bool* en); +esp_err_t esp_wifi_set_promiscuous_filter(const wifi_promiscuous_filter_t* filter); +esp_err_t esp_wifi_get_promiscuous_filter(wifi_promiscuous_filter_t* filter); +esp_err_t esp_wifi_set_promiscuous_ctrl_filter(const wifi_promiscuous_filter_t* filter); +esp_err_t esp_wifi_get_promiscuous_ctrl_filter(wifi_promiscuous_filter_t* filter); +esp_err_t esp_wifi_set_config(wifi_interface_t iface, wifi_config_t* conf); +esp_err_t esp_wifi_get_config(wifi_interface_t iface, wifi_config_t* conf); +esp_err_t esp_wifi_ap_get_sta_list(wifi_sta_list_t* sta); +esp_err_t esp_wifi_ap_get_sta_aid(const ubyte[6] mac, ushort* aid); +esp_err_t esp_wifi_set_storage(wifi_storage_t storage); +esp_err_t esp_wifi_set_vendor_ie(bool enable, wifi_vendor_ie_type_t type, wifi_vendor_ie_id_t idx, const void* vnd_ie); +esp_err_t esp_wifi_set_vendor_ie_cb(esp_vendor_ie_cb_t cb, void* ctx); +esp_err_t esp_wifi_set_max_tx_power(byte power); +esp_err_t esp_wifi_get_max_tx_power(byte* power); +esp_err_t esp_wifi_set_event_mask(uint mask); +esp_err_t esp_wifi_get_event_mask(uint* mask); +esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void* buffer, int len, bool en_sys_seq); +esp_err_t esp_wifi_set_csi_rx_cb(wifi_csi_cb_t cb, void* ctx); +esp_err_t esp_wifi_set_csi_config(const wifi_csi_config_t* config); +esp_err_t esp_wifi_set_csi(bool en); +esp_err_t esp_wifi_set_ant_gpio(const wifi_ant_gpio_config_t* config); +esp_err_t esp_wifi_get_ant_gpio(wifi_ant_gpio_config_t* config); +esp_err_t esp_wifi_set_ant(const wifi_ant_config_t* config); +esp_err_t esp_wifi_get_ant(wifi_ant_config_t* config); +long esp_wifi_get_tsf_time(wifi_interface_t iface); +esp_err_t esp_wifi_set_inactive_time(wifi_interface_t ifx, ushort sec); +esp_err_t esp_wifi_get_inactive_time(wifi_interface_t ifx, ushort* sec); +esp_err_t esp_wifi_statis_dump(uint modules); +esp_err_t esp_wifi_set_rssi_threshold(int rssi); +esp_err_t esp_wifi_ftm_initiate_session(wifi_ftm_initiator_cfg_t* cfg); +esp_err_t esp_wifi_ftm_end_session(); +esp_err_t esp_wifi_ftm_resp_set_offset(short offset_cm); +esp_err_t esp_wifi_ftm_get_report(wifi_ftm_report_entry_t* report, ubyte num_entries); +esp_err_t esp_wifi_config_11b_rate(wifi_interface_t ifx, bool disable); +esp_err_t esp_wifi_set_connectionless_wake_interval(ushort interval); +esp_err_t esp_wifi_force_wakeup_acquire(); +esp_err_t esp_wifi_force_wakeup_release(); +esp_err_t esp_wifi_set_country_code(const char* country, bool ieee80211d_enabled); +esp_err_t esp_wifi_get_country_code(char* country); +esp_err_t esp_wifi_config_80211_tx_rate(wifi_interface_t ifx, wifi_phy_rate_t rate); +esp_err_t esp_wifi_disable_pmf_config(wifi_interface_t ifx); +esp_err_t esp_wifi_sta_get_aid(ushort* aid); +esp_err_t esp_wifi_sta_get_negotiated_phymode(wifi_phy_mode_t* phymode); +esp_err_t esp_wifi_sta_get_rssi(int* rssi); \ No newline at end of file diff --git a/source/idf/esp_wifi/esp_wifi_crypto_types.d b/source/idf/esp_wifi/esp_wifi_crypto_types.d new file mode 100644 index 0000000..ab5cea9 --- /dev/null +++ b/source/idf/esp_wifi/esp_wifi_crypto_types.d @@ -0,0 +1,396 @@ +module idf.esp_wifi.esp_wifi_crypto_types; + +enum ESP_WIFI_CRYPTO_VERSION = 0x00000001; + +/* + * Enumeration for hash operations. + * When WPA2 is connecting, this enum is used to + * request a hash algorithm via crypto_hash_xxx functions. + */ +enum esp_crypto_hash_alg_t +{ + ESP_CRYPTO_HASH_ALG_MD5, ESP_CRYPTO_HASH_ALG_SHA1, + ESP_CRYPTO_HASH_ALG_HMAC_MD5, ESP_CRYPTO_HASH_ALG_HMAC_SHA1, + ESP_CRYPTO_HASH_ALG_SHA256, ESP_CRYPTO_HASH_ALG_HMAC_SHA256 +} + +/* + * Enumeration for block cipher operations. + * When WPA2 is connecting, this enum is used to request a block + * cipher algorithm via crypto_cipher_xxx functions. + */ +enum esp_crypto_cipher_alg_t +{ + ESP_CRYPTO_CIPHER_NULL, ESP_CRYPTO_CIPHER_ALG_AES, ESP_CRYPTO_CIPHER_ALG_3DES, + ESP_CRYPTO_CIPHER_ALG_DES, ESP_CRYPTO_CIPHER_ALG_RC2, ESP_CRYPTO_CIPHER_ALG_RC4 +} + +/* + * This structure is about the algorithm when do crypto_hash operation, for detail, + * please reference to the structure crypto_hash. + */ +// typedef struct crypto_hash esp_crypto_hash_t; + +/* + * This structure is about the algorithm when do crypto_cipher operation, for detail, + * please reference to the structure crypto_cipher. + */ +// typedef struct crypto_cipher esp_crypto_cipher_t; + +/** + * @brief The AES callback function when do WPS connect. + * + * @param key Encryption key. + * @param iv Encryption IV for CBC mode (16 bytes). + * @param data Data to encrypt in-place. + * @param data_len Length of data in bytes (must be divisible by 16) + */ +alias esp_aes_128_encrypt_t = int function(const ubyte* key, const ubyte* iv, ubyte* data, int data_len); + +/** + * @brief The AES callback function when do WPS connect. + * + * @param key Decryption key. + * @param iv Decryption IV for CBC mode (16 bytes). + * @param data Data to decrypt in-place. + * @param data_len Length of data in bytes (must be divisible by 16) + * + */ +alias esp_aes_128_decrypt_t = int function(const ubyte* key, const ubyte* iv, ubyte* data, int data_len); + +/** + * @brief The AES callback function when do STA connect. + * + * @param kek 16-octet Key encryption key (KEK). + * @param n Length of the plaintext key in 64-bit units; + * @param plain Plaintext key to be wrapped, n * 64 bits + * @param cipher Wrapped key, (n + 1) * 64 bits + * + */ +alias esp_aes_wrap_t = int function(const ubyte* kek, int n, const ubyte* plain, ubyte* cipher); + +/** + * @brief The AES callback function when do STA connect. + * + * @param kek 16-octet Key decryption key (KEK). + * @param n Length of the plaintext key in 64-bit units; + * @param cipher Wrapped key to be unwrapped, (n + 1) * 64 bits + * @param plain Plaintext key, n * 64 bits + * + */ +alias esp_aes_unwrap_t = int function(const ubyte* kek, int n, const ubyte* cipher, ubyte* plain); + +/** + * @brief The SHA256 callback function when do WPS connect. + * + * @param key Key for HMAC operations. + * @param key_len Length of the key in bytes. + * @param num_elem Number of elements in the data vector. + * @param addr Pointers to the data areas. + * @param len Lengths of the data blocks. + * @param mac Buffer for the hash (32 bytes). + * + */ +alias esp_hmac_sha256_vector_t = int function(const ubyte* key, int key_len, int num_elem, + const ubyte* addr, const int* len, ubyte* mac); + +/** + * @brief The AES callback function when do STA connect. + * + * @param key Key for PRF. + * @param key_len Length of the key in bytes. + * @param label A unique label for each purpose of the PRF. + * @param data Extra data to bind into the key. + * @param data_len Length of the data. + * @param buf Buffer for the generated pseudo-random key. + * @param buf_len Number of bytes of key to generate. + * + */ +alias esp_sha256_prf_t = int function(const ubyte* key, int key_len, const char* label, + const ubyte* data, int data_len, ubyte* buf, int buf_len); + +/** + * @brief HMAC-MD5 over data buffer (RFC 2104)' + * + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (16 bytes) + * Returns: 0 on success, -1 on failure + */ +alias esp_hmac_md5_t = int function(const ubyte* key, uint key_len, const ubyte* data, + uint data_len, ubyte* mac); + +/** + * @brief HMAC-MD5 over data vector (RFC 2104) + * + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (16 bytes) + * Returns: 0 on success, -1 on failure + */ +alias esp_hmac_md5_vector_t = int function(const ubyte* key, uint key_len, uint num_elem, + const ubyte* addr, const uint* len, ubyte* mac); + +/** + * @brief HMAC-SHA1 over data buffer (RFC 2104) + * + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @data: Pointers to the data area + * @data_len: Length of the data area + * @mac: Buffer for the hash (20 bytes) + * Returns: 0 on success, -1 of failure + */ +alias esp_hmac_sha1_t = int function(const ubyte* key, uint key_len, const ubyte* data, + uint data_len, ubyte* mac); + +/** + * @brief HMAC-SHA1 over data vector (RFC 2104) + * + * @key: Key for HMAC operations + * @key_len: Length of the key in bytes + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash (20 bytes) + * Returns: 0 on success, -1 on failure + */ +alias esp_hmac_sha1_vector_t = int function(const ubyte* key, uint key_len, uint num_elem, + const ubyte* addr, const uint* len, ubyte* mac); + +/** + * @brief SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) + * + * @key: Key for PRF + * @key_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @data: Extra data to bind into the key + * @data_len: Length of the data + * @buf: Buffer for the generated pseudo-random key + * @buf_len: Number of bytes of key to generate + * Returns: 0 on success, -1 of failure + * + * This function is used to derive new, cryptographically separate keys from a + * given key (e.g., PMK in IEEE 802.11i). + */ +alias esp_sha1_prf_t = int function(const ubyte* key, uint key_len, const char* label, + const ubyte* data, uint data_len, ubyte* buf, uint buf_len); + +/** + * @brief SHA-1 hash for data vector + * + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +alias esp_sha1_vector_t = int function(uint num_elem, const ubyte* addr, const uint* len, + ubyte* mac); + +/** + * @brief SHA1-based key derivation function (PBKDF2) for IEEE 802.11i + * + * @passphrase: ASCII passphrase + * @ssid: SSID + * @ssid_len: SSID length in bytes + * @iterations: Number of iterations to run + * @buf: Buffer for the generated key + * @buflen: Length of the buffer in bytes + * Returns: 0 on success, -1 of failure + * + * This function is used to derive PSK for WPA-PSK. For this protocol, + * iterations is set to 4096 and buflen to 32. This function is described in + * IEEE Std 802.11-2004, Clause H.4. The main construction is from PKCS#5 v2.0. + */ +alias esp_pbkdf2_sha1_t = int function(const char* passphrase, const char* ssid, uint ssid_len, + int iterations, ubyte* buf, uint buflen); + +/** + * @brief XOR RC4 stream to given data with skip-stream-start + * + * @key: RC4 key + * @keylen: RC4 key length + * @skip: number of bytes to skip from the beginning of the RC4 stream + * @data: data to be XOR'ed with RC4 stream + * @data_len: buf length + * Returns: 0 on success, -1 on failure + * + * Generate RC4 pseudo random stream for the given key, skip beginning of the + * stream, and XOR the end result with the data buffer to perform RC4 + * encryption/decryption. + */ +alias esp_rc4_skip_t = int function(const ubyte* key, uint keylen, uint skip, + ubyte* data, uint data_len); + +/** + * @brief MD5 hash for data vector + * + * @num_elem: Number of elements in the data vector + * @addr: Pointers to the data areas + * @len: Lengths of the data blocks + * @mac: Buffer for the hash + * Returns: 0 on success, -1 on failure + */ +alias esp_md5_vector_t = int function(uint num_elem, const ubyte* addr, const uint* len, + ubyte* mac); + +/** + * @brief Encrypt one AES block + * + * @ctx: Context pointer from aes_encrypt_init() + * @plain: Plaintext data to be encrypted (16 bytes) + * @crypt: Buffer for the encrypted data (16 bytes) + */ +alias esp_aes_encrypt_t = void function(void* ctx, const ubyte* plain, ubyte* crypt); + +/** + * @brief Initialize AES for encryption + * + * @key: Encryption key + * @len: Key length in bytes (usually 16, i.e., 128 bits) + * Returns: Pointer to context data or %NULL on failure + */ +alias esp_aes_encrypt_init_t = void* function(const ubyte* key, uint len); + +/** + * @brief Deinitialize AES encryption + * + * @ctx: Context pointer from aes_encrypt_init() + */ +alias esp_aes_encrypt_deinit_t = void function(void* ctx); + +/** + * @brief Decrypt one AES block + * + * @ctx: Context pointer from aes_encrypt_init() + * @crypt: Encrypted data (16 bytes) + * @plain: Buffer for the decrypted data (16 bytes) + */ +alias esp_aes_decrypt_t = void function(void* ctx, const ubyte* crypt, ubyte* plain); + +/** + * @brief Initialize AES for decryption + * + * @key: Decryption key + * @len: Key length in bytes (usually 16, i.e., 128 bits) + * Returns: Pointer to context data or %NULL on failure + */ +alias esp_aes_decrypt_init_t = void* function(const ubyte* key, uint len); + +/** + * @brief Deinitialize AES decryption + * + * @ctx: Context pointer from aes_encrypt_init() + */ +alias esp_aes_decrypt_deinit_t = void function(void* ctx); + +/** + * @brief One-Key CBC MAC (OMAC1) hash with AES-128 for MIC computation + * + * @key: 128-bit key for the hash operation + * @data: Data buffer for which a MIC is computed + * @data_len: Length of data buffer in bytes + * @mic: Buffer for MIC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + */ +alias esp_omac1_aes_128_t = int function(const ubyte* key, const ubyte* data, size_t data_len, + ubyte* mic); + +/** + * @brief Decrypt data using CCMP (Counter Mode CBC-MAC Protocol OR + * Counter Mode Cipher Block Chaining Message Authentication + * Code Protocol) which is used in IEEE 802.11i RSN standard. + * @tk: 128-bit Temporal Key for obtained during 4-way handshake + * @hdr: Pointer to IEEE802.11 frame headeri needed for AAD + * @data: Pointer to encrypted data buffer + * @data_len: Encrypted data length in bytes + * @decrypted_len: Length of decrypted data + * @espnow_pkt: Indicates if it's an ESPNOW packet + * Returns: Pointer to decrypted data on success, NULL on failure + */ +alias esp_ccmp_decrypt_t = ubyte* function(const ubyte* tk, const ubyte* ieee80211_hdr, + const ubyte* data, size_t data_len, + size_t* decrypted_len, bool espnow_pkt); + +/** + * @brief Encrypt data using CCMP (Counter Mode CBC-MAC Protocol OR + * Counter Mode Cipher Block Chaining Message Authentication + * Code Protocol) which is used in IEEE 802.11i RSN standard. + * @tk: 128-bit Temporal Key for obtained during 4-way handshake + * @frame: Pointer to IEEE802.11 frame including header + * @len: Length of the frame including header + * @hdrlen: Length of the header + * @pn: Packet Number counter + * @keyid: Key ID to be mentioned in CCMP Vector + * @encrypted_len: Length of the encrypted frame including header + */ +alias esp_ccmp_encrypt_t = ubyte* function(const ubyte* tk, ubyte* frame, size_t len, size_t hdrlen, + ubyte* pn, int keyid, size_t* encrypted_len); + +/** + * @brief One-Key GMAC hash with AES for MIC computation + * + * @key: key for the hash operation + * @keylen: key length + * @iv: initialization vector + * @iv_len: initialization vector length + * @aad: aad + * @aad_len: aad length + * @mic: Buffer for MIC (128 bits, i.e., 16 bytes) + * Returns: 0 on success, -1 on failure + */ +alias esp_aes_gmac_t = int function(const ubyte* key, size_t keylen, const ubyte* iv, size_t iv_len, + const ubyte* aad, size_t aad_len, ubyte* mic); + +/** + * @brief The crypto callback function structure used when do station security connect. + * The structure can be set as software crypto or the crypto optimized by ESP32 + * hardware. + */ +struct wpa_crypto_funcs_t +{ + uint size; + uint version_; + esp_aes_wrap_t aes_wrap; /**< station connect function used when send EAPOL frame */ + esp_aes_unwrap_t aes_unwrap; /**< station connect function used when decrypt key data */ + esp_hmac_sha256_vector_t hmac_sha256_vector; /**< station connect function used when check MIC */ + esp_sha256_prf_t sha256_prf; /**< station connect function used when check MIC */ + esp_hmac_md5_t hmac_md5; + esp_hmac_md5_vector_t hamc_md5_vector; + esp_hmac_sha1_t hmac_sha1; + esp_hmac_sha1_vector_t hmac_sha1_vector; + esp_sha1_prf_t sha1_prf; + esp_sha1_vector_t sha1_vector; + esp_pbkdf2_sha1_t pbkdf2_sha1; + esp_rc4_skip_t rc4_skip; + esp_md5_vector_t md5_vector; + esp_aes_encrypt_t aes_encrypt; + esp_aes_encrypt_init_t aes_encrypt_init; + esp_aes_encrypt_deinit_t aes_encrypt_deinit; + esp_aes_decrypt_t aes_decrypt; + esp_aes_decrypt_init_t aes_decrypt_init; + esp_aes_decrypt_deinit_t aes_decrypt_deinit; + esp_aes_128_encrypt_t aes_128_encrypt; + esp_aes_128_decrypt_t aes_128_decrypt; + esp_omac1_aes_128_t omac1_aes_128; + esp_ccmp_decrypt_t ccmp_decrypt; + esp_ccmp_encrypt_t ccmp_encrypt; + esp_aes_gmac_t aes_gmac; +} + +/** + * @brief The crypto callback function structure used in mesh vendor IE encryption. The + * structure can be set as software crypto or the crypto optimized by ESP32 + * hardware. + */ +struct mesh_crypto_funcs_t +{ + esp_aes_128_encrypt_t aes_128_encrypt; /**< function used in mesh vendor IE encryption */ + esp_aes_128_decrypt_t aes_128_decrypt; /**< function used in mesh vendor IE decryption */ +} \ No newline at end of file diff --git a/source/idf/esp_wifi/esp_wifi_default.d b/source/idf/esp_wifi/esp_wifi_default.d new file mode 100644 index 0000000..795f493 --- /dev/null +++ b/source/idf/esp_wifi/esp_wifi_default.d @@ -0,0 +1,114 @@ +module idf.esp_wifi.esp_wifi_default; + +import idf.esp_common.esp_err : esp_err_t; +import idf.esp_netif : esp_netif_t; + +@safe nothrow @nogc extern (C): + +/** + * @brief Attaches wifi station interface to supplied netif + * + * @param esp_netif instance to attach the wifi station to + * + * @return + * - ESP_OK on success + * - ESP_FAIL if attach failed + */ +esp_err_t esp_netif_attach_wifi_station(esp_netif_t* esp_netif); + +/** + * @brief Attaches wifi soft AP interface to supplied netif + * + * @param esp_netif instance to attach the wifi AP to + * + * @return + * - ESP_OK on success + * - ESP_FAIL if attach failed + */ +esp_err_t esp_netif_attach_wifi_ap(esp_netif_t* esp_netif); + +/** + * @brief Sets default wifi event handlers for STA interface + * + * @return + * - ESP_OK on success, error returned from esp_event_handler_register if failed + */ +esp_err_t esp_wifi_set_default_wifi_sta_handlers(); + +/** + * @brief Sets default wifi event handlers for AP interface + * + * @return + * - ESP_OK on success, error returned from esp_event_handler_register if failed + */ +esp_err_t esp_wifi_set_default_wifi_ap_handlers(); + +/** + * @brief Clears default wifi event handlers for supplied network interface + * + * @param esp_netif instance of corresponding if object + * + * @return + * - ESP_OK on success, error returned from esp_event_handler_register if failed + */ +esp_err_t esp_wifi_clear_default_wifi_driver_and_handlers(void* esp_netif); + +/** + * @brief Creates default WIFI AP. In case of any init error this API aborts. + * + * @note The API creates esp_netif object with default WiFi access point config, + * attaches the netif to wifi and registers default wifi handlers. + * + * @return pointer to esp-netif instance + */ +esp_netif_t* esp_netif_create_default_wifi_ap(); + +/** + * @brief Creates default WIFI STA. In case of any init error this API aborts. + * + * @note The API creates esp_netif object with default WiFi station config, + * attaches the netif to wifi and registers default wifi handlers. + * + * @return pointer to esp-netif instance + */ +esp_netif_t* esp_netif_create_default_wifi_sta(); + +/** + * @brief Destroys default WIFI netif created with esp_netif_create_default_wifi_...() API. + * + * @param[in] esp_netif object to detach from WiFi and destroy + * + * @note This API unregisters wifi handlers and detaches the created object from the wifi. + * (this function is a no-operation if esp_netif is NULL) + */ +void esp_netif_destroy_default_wifi(void* esp_netif); + +/** + * @brief Creates esp_netif WiFi object based on the custom configuration. + * + * @attention This API DOES NOT register default handlers! + * + * @param[in] wifi_if type of wifi interface + * @param[in] esp_netif_config inherent esp-netif configuration pointer + * + * @return pointer to esp-netif instance + */ +// esp_netif_t* esp_netif_create_wifi(wifi_interface_t wifi_if, esp_netif_inherent_config_t* esp_netif_config); + +/** + * @brief Creates default STA and AP network interfaces for esp-mesh. + * + * Both netifs are almost identical to the default station and softAP, but with + * DHCP client and server disabled. Please note that the DHCP client is typically + * enabled only if the device is promoted to a root node. + * + * Returns created interfaces which could be ignored setting parameters to NULL + * if an application code does not need to save the interface instances + * for further processing. + * + * @param[out] p_netif_sta pointer where the resultant STA interface is saved (if non NULL) + * @param[out] p_netif_ap pointer where the resultant AP interface is saved (if non NULL) + * + * @return ESP_OK on success + */ +esp_err_t esp_netif_create_default_wifi_mesh_netifs(esp_netif_t** p_netif_sta, esp_netif_t** p_netif_ap); diff --git a/source/idf/esp_wifi/esp_wifi_types.d b/source/idf/esp_wifi/esp_wifi_types.d new file mode 100644 index 0000000..c7fd418 --- /dev/null +++ b/source/idf/esp_wifi/esp_wifi_types.d @@ -0,0 +1,872 @@ +module idf.esp_wifi.esp_wifi_types; + +import idf.esp_event : esp_event_base_t; +import idf.esp_hw_support.esp_interface : esp_interface_t; + +@safe nothrow @nogc extern (C): +// dfmt off + +enum WIFI_OFFCHAN_TX_REQ = 1; +enum WIFI_OFFCHAN_TX_CANCEL = 0; + +enum WIFI_ROC_REQ = 1; +enum WIFI_ROC_CANCEL = 0; + +enum WIFI_STATIS_BUFFER = 1 << 0; +enum WIFI_STATIS_RXTX = 1 << 1; +enum WIFI_STATIS_HW = 1 << 2; +enum WIFI_STATIS_DIAG = 1 << 3; +enum WIFI_STATIS_PS = 1 << 4; +enum WIFI_STATIS_ALL = -1; + +enum WIFI_PROTOCOL_11B = 1; +enum WIFI_PROTOCOL_11G = 2; +enum WIFI_PROTOCOL_11N = 4; +enum WIFI_PROTOCOL_LR = 8; + +static if(is(typeof(CONFIG_IDF_TARGET_ESP32C3))) + enum ESP_WIFI_MAX_CONN_NUM = 10; /**< max number of stations which can connect to ESP32C3 soft-AP */ +else + enum ESP_WIFI_MAX_CONN_NUM = 15; /**< max number of stations which can connect to ESP32/ESP32S3/ESP32S2 soft-AP */ + +enum WIFI_VENDOR_IE_ELEMENT_ID = 0xDD; + +enum WIFI_PROMIS_FILTER_MASK_ALL = 0xFFFFFFFF; /**< filter all packets */ +enum WIFI_PROMIS_FILTER_MASK_MGMT = 1; /**< filter the packets with type of WIFI_PKT_MGMT */ +enum WIFI_PROMIS_FILTER_MASK_CTRL = 1 << 1; /**< filter the packets with type of WIFI_PKT_CTRL */ +enum WIFI_PROMIS_FILTER_MASK_DATA = 1 << 2; /**< filter the packets with type of WIFI_PKT_DATA */ +enum WIFI_PROMIS_FILTER_MASK_MISC = 1 << 3; /**< filter the packets with type of WIFI_PKT_MISC */ +enum WIFI_PROMIS_FILTER_MASK_DATA_MPDU = 1 << 4; /**< filter the MPDU which is a kind of WIFI_PKT_DATA */ +enum WIFI_PROMIS_FILTER_MASK_DATA_AMPDU = 1 << 5; /**< filter the AMPDU which is a kind of WIFI_PKT_DATA */ +enum WIFI_PROMIS_FILTER_MASK_FCSFAIL = 1 << 6; /**< filter the FCS failed packets, do not open it in general */ + +enum WIFI_PROMIS_CTRL_FILTER_MASK_ALL = 0xFF800000; /**< filter all control packets */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_WRAPPER = 1 << 23; /**< filter the control packets with subtype of Control Wrapper */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_BAR = 1 << 24; /**< filter the control packets with subtype of Block Ack Request */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_BA = 1 << 25; /**< filter the control packets with subtype of Block Ack */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_PSPOLL = 1 << 26; /**< filter the control packets with subtype of PS-Poll */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_RTS = 1 << 27; /**< filter the control packets with subtype of RTS */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_CTS = 1 << 28; /**< filter the control packets with subtype of CTS */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_ACK = 1 << 29; /**< filter the control packets with subtype of ACK */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_CFEND = 1 << 30; /**< filter the control packets with subtype of CF-END */ +enum WIFI_PROMIS_CTRL_FILTER_MASK_CFENDACK = 1 << 31; /**< filter the control packets with subtype of CF-END+CF-ACK */ + +enum WIFI_EVENT_MASK_ALL = 0xFFFFFFFF; /**< mask all WiFi events */ +enum WIFI_EVENT_MASK_NONE = 0; /**< mask none of the WiFi events */ +enum WIFI_EVENT_MASK_AP_PROBEREQRECVED = 1 << 0; /**< mask SYSTEM_EVENT_AP_PROBEREQRECVED event */ + +enum MAX_SSID_LEN = 32; +enum MAX_PASSPHRASE_LEN = 64; +enum MAX_WPS_AP_CRED = 3; + +enum wifi_mode_t +{ + WIFI_MODE_NULL = 0, /**< null mode */ + WIFI_MODE_STA, /**< WiFi station mode */ + WIFI_MODE_AP, /**< WiFi soft-AP mode */ + WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */ + WIFI_MODE_MAX +} + +enum wifi_interface_t +{ + WIFI_IF_STA = esp_interface_t.ESP_IF_WIFI_STA, + WIFI_IF_AP = esp_interface_t.ESP_IF_WIFI_AP, +} + +enum wifi_country_policy_t +{ + WIFI_COUNTRY_POLICY_AUTO, /**< Country policy is auto, use the country info of AP to which the station is connected */ + WIFI_COUNTRY_POLICY_MANUAL, /**< Country policy is manual, always use the configured country info */ +} + +/** @brief Structure describing WiFi country-based regional restrictions. */ +struct wifi_country_t +{ + char[3] cc; /**< country code string */ + ubyte schan; /**< start channel */ + ubyte nchan; /**< total channel number */ + byte max_tx_power; /**< This field is used for getting WiFi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. */ + wifi_country_policy_t policy; /**< country policy */ +} + +/* Strength of authmodes */ +/* OPEN < WEP < WPA_PSK < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK */ +enum wifi_auth_mode_t +{ + WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */ + WIFI_AUTH_WEP, /**< authenticate mode : WEP */ + WIFI_AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */ + WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */ + WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */ + WIFI_AUTH_ENTERPRISE, /**< authenticate mode : WiFi EAP security */ + WIFI_AUTH_WPA2_ENTERPRISE = WIFI_AUTH_ENTERPRISE, /**< authenticate mode : WiFi EAP security */ + WIFI_AUTH_WPA3_PSK, /**< authenticate mode : WPA3_PSK */ + WIFI_AUTH_WPA2_WPA3_PSK, /**< authenticate mode : WPA2_WPA3_PSK */ + WIFI_AUTH_WAPI_PSK, /**< authenticate mode : WAPI_PSK */ + WIFI_AUTH_WPA3_ENT_192, /**< authenticate mode : WPA3_ENT_SUITE_B_192_BIT */ + WIFI_AUTH_MAX +} + +enum wifi_err_reason_t +{ + WIFI_REASON_UNSPECIFIED = 1, + WIFI_REASON_AUTH_EXPIRE = 2, + WIFI_REASON_AUTH_LEAVE = 3, + WIFI_REASON_ASSOC_EXPIRE = 4, + WIFI_REASON_ASSOC_TOOMANY = 5, + WIFI_REASON_NOT_AUTHED = 6, + WIFI_REASON_NOT_ASSOCED = 7, + WIFI_REASON_ASSOC_LEAVE = 8, + WIFI_REASON_ASSOC_NOT_AUTHED = 9, + WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, + WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11, + WIFI_REASON_BSS_TRANSITION_DISASSOC = 12, + WIFI_REASON_IE_INVALID = 13, + WIFI_REASON_MIC_FAILURE = 14, + WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, + WIFI_REASON_IE_IN_4WAY_DIFFERS = 17, + WIFI_REASON_GROUP_CIPHER_INVALID = 18, + WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19, + WIFI_REASON_AKMP_INVALID = 20, + WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21, + WIFI_REASON_INVALID_RSN_IE_CAP = 22, + WIFI_REASON_802_1X_AUTH_FAILED = 23, + WIFI_REASON_CIPHER_SUITE_REJECTED = 24, + WIFI_REASON_TDLS_PEER_UNREACHABLE = 25, + WIFI_REASON_TDLS_UNSPECIFIED = 26, + WIFI_REASON_SSP_REQUESTED_DISASSOC = 27, + WIFI_REASON_NO_SSP_ROAMING_AGREEMENT = 28, + WIFI_REASON_BAD_CIPHER_OR_AKM = 29, + WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION = 30, + WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS = 31, + WIFI_REASON_UNSPECIFIED_QOS = 32, + WIFI_REASON_NOT_ENOUGH_BANDWIDTH = 33, + WIFI_REASON_MISSING_ACKS = 34, + WIFI_REASON_EXCEEDED_TXOP = 35, + WIFI_REASON_STA_LEAVING = 36, + WIFI_REASON_END_BA = 37, + WIFI_REASON_UNKNOWN_BA = 38, + WIFI_REASON_TIMEOUT = 39, + WIFI_REASON_PEER_INITIATED = 46, + WIFI_REASON_AP_INITIATED = 47, + WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT = 48, + WIFI_REASON_INVALID_PMKID = 49, + WIFI_REASON_INVALID_MDE = 50, + WIFI_REASON_INVALID_FTE = 51, + WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED = 67, + WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED = 68, + + WIFI_REASON_BEACON_TIMEOUT = 200, + WIFI_REASON_NO_AP_FOUND = 201, + WIFI_REASON_AUTH_FAIL = 202, + WIFI_REASON_ASSOC_FAIL = 203, + WIFI_REASON_HANDSHAKE_TIMEOUT = 204, + WIFI_REASON_CONNECTION_FAIL = 205, + WIFI_REASON_AP_TSF_RESET = 206, + WIFI_REASON_ROAMING = 207, + WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG = 208, + WIFI_REASON_SA_QUERY_TIMEOUT = 209, +} + +enum wifi_second_chan_t +{ + WIFI_SECOND_CHAN_NONE = 0, /**< the channel width is HT20 */ + WIFI_SECOND_CHAN_ABOVE, /**< the channel width is HT40 and the secondary channel is above the primary channel */ + WIFI_SECOND_CHAN_BELOW, /**< the channel width is HT40 and the secondary channel is below the primary channel */ +} + +enum wifi_scan_type_t +{ + WIFI_SCAN_TYPE_ACTIVE = 0, /**< active scan */ + WIFI_SCAN_TYPE_PASSIVE, /**< passive scan */ +} + +/** @brief Range of active scan times per channel */ +struct wifi_active_scan_time_t +{ + uint min; /**< minimum active scan time per channel, units: millisecond */ + uint max; /**< maximum active scan time per channel, units: millisecond, values above 1500ms may + cause station to disconnect from AP and are not recommended. */ +} + +/** @brief Aggregate of active & passive scan time per channel */ +struct wifi_scan_time_t +{ + wifi_active_scan_time_t active; /**< active scan time per channel, units: millisecond. */ + uint passive; /**< passive scan time per channel, units: millisecond, values above 1500ms may + cause station to disconnect from AP and are not recommended. */ +} + +/** @brief Parameters for an SSID scan. */ +struct wifi_scan_config_t +{ + ubyte* ssid; /**< SSID of AP */ + ubyte* bssid; /**< MAC address of AP */ + ubyte channel; /**< channel, scan the specific channel */ + bool show_hidden; /**< enable to scan AP whose SSID is hidden */ + wifi_scan_type_t scan_type; /**< scan type, active or passive */ + wifi_scan_time_t scan_time; /**< scan time per channel */ + ubyte home_chan_dwell_time;/**< time spent at home channel between scanning consecutive channels.*/ +} + +enum wifi_cipher_type_t +{ + WIFI_CIPHER_TYPE_NONE = 0, /**< the cipher type is none */ + WIFI_CIPHER_TYPE_WEP40, /**< the cipher type is WEP40 */ + WIFI_CIPHER_TYPE_WEP104, /**< the cipher type is WEP104 */ + WIFI_CIPHER_TYPE_TKIP, /**< the cipher type is TKIP */ + WIFI_CIPHER_TYPE_CCMP, /**< the cipher type is CCMP */ + WIFI_CIPHER_TYPE_TKIP_CCMP, /**< the cipher type is TKIP and CCMP */ + WIFI_CIPHER_TYPE_AES_CMAC128,/**< the cipher type is AES-CMAC-128 */ + WIFI_CIPHER_TYPE_SMS4, /**< the cipher type is SMS4 */ + WIFI_CIPHER_TYPE_GCMP, /**< the cipher type is GCMP */ + WIFI_CIPHER_TYPE_GCMP256, /**< the cipher type is GCMP-256 */ + WIFI_CIPHER_TYPE_AES_GMAC128,/**< the cipher type is AES-GMAC-128 */ + WIFI_CIPHER_TYPE_AES_GMAC256,/**< the cipher type is AES-GMAC-256 */ + WIFI_CIPHER_TYPE_UNKNOWN, /**< the cipher type is unknown */ +} + +/** + * @brief WiFi antenna + * + */ +enum wifi_ant_t +{ + WIFI_ANT_ANT0, /**< WiFi antenna 0 */ + WIFI_ANT_ANT1, /**< WiFi antenna 1 */ + WIFI_ANT_MAX, /**< Invalid WiFi antenna */ +} + +/** @brief Description of a WiFi AP */ +struct wifi_ap_record_t +{ + ubyte[6] bssid; /**< MAC address of AP */ + ubyte[33] ssid; /**< SSID of AP */ + ubyte primary; /**< channel of AP */ + wifi_second_chan_t second; /**< secondary channel of AP */ + byte rssi; /**< signal strength of AP. Note that in some rare cases where signal strength is very strong, rssi values can be slightly positive */ + wifi_auth_mode_t authmode; /**< authmode of AP */ + wifi_cipher_type_t pairwise_cipher; /**< pairwise cipher of AP */ + wifi_cipher_type_t group_cipher; /**< group cipher of AP */ + wifi_ant_t ant; /**< antenna used to receive beacon from AP */ + uint phy_11b:1; /**< bit: 0 flag to identify if 11b mode is enabled or not */ + uint phy_11g:1; /**< bit: 1 flag to identify if 11g mode is enabled or not */ + uint phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */ + uint phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */ + uint wps:1; /**< bit: 4 flag to identify if WPS is supported or not */ + uint ftm_responder:1; /**< bit: 5 flag to identify if FTM is supported in responder mode */ + uint ftm_initiator:1; /**< bit: 6 flag to identify if FTM is supported in initiator mode */ + uint reserved:25; /**< bit: 7..31 reserved */ + wifi_country_t country; /**< country information of AP */ +} + +enum wifi_scan_method_t +{ + WIFI_FAST_SCAN = 0, /**< Do fast scan, scan will end after find SSID match AP */ + WIFI_ALL_CHANNEL_SCAN, /**< All channel scan, scan will end after scan all the channel */ +} + +enum wifi_sort_method_t +{ + WIFI_CONNECT_AP_BY_SIGNAL = 0, /**< Sort match AP in scan list by RSSI */ + WIFI_CONNECT_AP_BY_SECURITY, /**< Sort match AP in scan list by security mode */ +} + +/** @brief Structure describing parameters for a WiFi fast scan */ +struct wifi_scan_threshold_t +{ + byte rssi; /**< The minimum rssi to accept in the fast scan mode */ + wifi_auth_mode_t authmode; /**< The weakest authmode to accept in the fast scan mode */ +} + +enum wifi_ps_type_t +{ + WIFI_PS_NONE, /**< No power save */ + WIFI_PS_MIN_MODEM, /**< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period */ + WIFI_PS_MAX_MODEM, /**< Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval parameter in wifi_sta_config_t */ +} + +enum wifi_bandwidth_t +{ + WIFI_BW_HT20 = 1, /* Bandwidth is HT20 */ + WIFI_BW_HT40, /* Bandwidth is HT40 */ +} + +/** Configuration structure for Protected Management Frame */ +struct wifi_pmf_config_t +{ + bool capable; /**< Deprecated variable. Device will always connect in PMF mode if other device also advertizes PMF capability. */ + bool required; /**< Advertizes that Protected Management Frame is required. Device will not associate to non-PMF capable devices. */ +} + +/** Configuration for SAE PWE derivation */ +enum wifi_sae_pwe_method_t +{ + WPA3_SAE_PWE_UNSPECIFIED, + WPA3_SAE_PWE_HUNT_AND_PECK, + WPA3_SAE_PWE_HASH_TO_ELEMENT, + WPA3_SAE_PWE_BOTH, +} + +/** @brief Soft-AP configuration settings for the ESP32 */ +struct wifi_ap_config_t +{ + ubyte[32] ssid; /**< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */ + ubyte[64] password; /**< Password of ESP32 soft-AP. */ + ubyte ssid_len; /**< Optional length of SSID field. */ + ubyte channel; /**< Channel of soft-AP */ + wifi_auth_mode_t authmode; /**< Auth mode of soft-AP. Do not support AUTH_WEP, AUTH_WAPI_PSK and AUTH_OWE in soft-AP mode. When the auth mode is set to WPA2_PSK, WPA2_WPA3_PSK or WPA3_PSK, the pairwise cipher will be overwritten with WIFI_CIPHER_TYPE_CCMP. */ + ubyte ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ + ubyte max_connection; /**< Max number of stations allowed to connect in */ + ushort beacon_interval; /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */ + wifi_cipher_type_t pairwise_cipher; /**< Pairwise cipher of SoftAP, group cipher will be derived using this. Cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP and WIFI_CIPHER_TYPE_TKIP_CCMP. */ + bool ftm_responder; /**< Enable FTM Responder mode */ +} + +/** @brief STA configuration settings for the ESP32 */ +struct wifi_sta_config_t +{ + ubyte[32] ssid; /**< SSID of target AP. */ + ubyte[64] password; /**< Password of target AP. */ + wifi_scan_method_t scan_method; /**< do all channel scan or fast scan */ + bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ + ubyte[6] bssid; /**< MAC address of target AP*/ + ubyte channel; /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/ + ushort listen_interval; /**< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. */ + wifi_sort_method_t sort_method; /**< sort the connect AP in the list by rssi or security mode */ + wifi_scan_threshold_t threshold; /**< When scan_threshold is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */ + wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertised in RSN Capabilities in RSN IE. */ + uint rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ + uint btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ + uint mbo_enabled:1; /**< Whether MBO is enabled for the connection */ + uint transition_disable:1; /**< Whether to enable transition disable feature */ + uint reserved:28; /**< Reserved for future feature set */ + wifi_sae_pwe_method_t sae_pwe_h2e; /**< Configuration for SAE PWE derivation method */ + ubyte failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. + Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. */ +} + +/** @brief Configuration data for ESP32 AP or STA. + * + * The usage of this union (for ap or sta configuration) is determined by the accompanying + * interface argument passed to esp_wifi_set_config() or esp_wifi_get_config() + * + */ +union wifi_config_t +{ + wifi_ap_config_t ap; /**< configuration of AP */ + wifi_sta_config_t sta; /**< configuration of STA */ +} + +/** @brief Description of STA associated with AP */ +struct wifi_sta_info_t +{ + ubyte[6] mac; /**< mac address */ + byte rssi; /**< current average rssi of sta connected */ + uint phy_11b:1; /**< bit: 0 flag to identify if 11b mode is enabled or not */ + uint phy_11g:1; /**< bit: 1 flag to identify if 11g mode is enabled or not */ + uint phy_11n:1; /**< bit: 2 flag to identify if 11n mode is enabled or not */ + uint phy_lr:1; /**< bit: 3 flag to identify if low rate is enabled or not */ + uint is_mesh_child:1;/**< bit: 4 flag to identify mesh child */ + uint reserved:27; /**< bit: 5..31 reserved */ +} + +/** @brief List of stations associated with the ESP32 Soft-AP */ +struct wifi_sta_list_t +{ + wifi_sta_info_t[ESP_WIFI_MAX_CONN_NUM] sta; /**< station list */ + int num; /**< number of stations in the list (other entries are invalid) */ +} + +enum wifi_storage_t +{ + WIFI_STORAGE_FLASH, /**< all configuration will store in both memory and flash */ + WIFI_STORAGE_RAM, /**< all configuration will only store in the memory */ +} + +/** + * @brief Vendor Information Element type + * + * Determines the frame type that the IE will be associated with. + */ +enum wifi_vendor_ie_type_t +{ + WIFI_VND_IE_TYPE_BEACON, + WIFI_VND_IE_TYPE_PROBE_REQ, + WIFI_VND_IE_TYPE_PROBE_RESP, + WIFI_VND_IE_TYPE_ASSOC_REQ, + WIFI_VND_IE_TYPE_ASSOC_RESP, +} + +/** + * @brief Vendor Information Element index + * + * Each IE type can have up to two associated vendor ID elements. + */ +enum wifi_vendor_ie_id_t +{ + WIFI_VND_IE_ID_0, + WIFI_VND_IE_ID_1, +} + +/** + * @brief Operation Phymode + */ +enum wifi_phy_mode_t +{ + WIFI_PHY_MODE_LR, /**< PHY mode for Low Rate */ + WIFI_PHY_MODE_11B, /**< PHY mode for 11b */ + WIFI_PHY_MODE_11G, /**< PHY mode for 11g */ + WIFI_PHY_MODE_HT20, /**< PHY mode for Bandwidth HT20 */ + WIFI_PHY_MODE_HT40, /**< PHY mode for Bandwidth HT40 */ + WIFI_PHY_MODE_HE20, /**< PHY mode for Bandwidth HE20 */ +} + +/** + * @brief Vendor Information Element header + * + * The first bytes of the Information Element will match this header. Payload follows. + */ +struct vendor_ie_data_t +{ + ubyte element_id; /**< Should be set to WIFI_VENDOR_IE_ELEMENT_ID (0xDD) */ + ubyte length; /**< Length of all bytes in the element data following this field. Minimum 4. */ + ubyte[3] vendor_oui; /**< Vendor identifier (OUI). */ + ubyte vendor_oui_type; /**< Vendor-specific OUI type. */ + ubyte[0] payload; /**< Payload. Length is equal to value in 'length' field, minus 4. */ +} + +/** @brief Received packet radio metadata header, this is the common header at the beginning of all promiscuous mode RX callback buffers */ +struct wifi_pkt_rx_ctrl_t +{ + int rssi:8; /**< Received Signal Strength Indicator(RSSI) of packet. unit: dBm */ + uint rate:5; /**< PHY rate encoding of the packet. Only valid for non HT(11bg) packet */ + uint :1; /**< reserved */ + uint sig_mode:2; /**< 0: non HT(11bg) packet; 1: HT(11n) packet; 3: VHT(11ac) packet */ + uint :16; /**< reserved */ + uint mcs:7; /**< Modulation Coding Scheme. If is HT(11n) packet, shows the modulation, range from 0 to 76(MSC0 ~ MCS76) */ + uint cwb:1; /**< Channel Bandwidth of the packet. 0: 20MHz; 1: 40MHz */ + uint :16; /**< reserved */ + uint smoothing:1; /**< reserved */ + uint not_sounding:1; /**< reserved */ + uint :1; /**< reserved */ + uint aggregation:1; /**< Aggregation. 0: MPDU packet; 1: AMPDU packet */ + uint stbc:2; /**< Space Time Block Code(STBC). 0: non STBC packet; 1: STBC packet */ + uint fec_coding:1; /**< Flag is set for 11n packets which are LDPC */ + uint sgi:1; /**< Short Guide Interval(SGI). 0: Long GI; 1: Short GI */ + + static if (is(typeof(CONFIG_IDF_TARGET_ESP32))) + { + int noise_floor:8; /**< noise floor of Radio Frequency Module(RF). unit: dBm*/ + } + else static if (is(typeof(CONFIG_IDF_TARGET_ESP32S2)) || is(typeof(CONFIG_IDF_TARGET_ESP32S3)) || is(typeof(CONFIG_IDF_TARGET_ESP32C3))) + { + uint :8; /**< reserved */ + } + + uint ampdu_cnt:8; /**< ampdu cnt */ + uint channel:4; /**< primary channel on which this packet is received */ + uint secondary_channel:4; /**< secondary channel on which this packet is received. 0: none; 1: above; 2: below */ + uint :8; /**< reserved */ + uint timestamp:32; /**< timestamp. The local time when this packet is received. It is precise only if modem sleep or light sleep is not enabled. unit: microsecond */ + uint :32; /**< reserved */ + + static if (is(typeof(CONFIG_IDF_TARGET_ESP32S2))) + { + uint :32; /**< reserved */ + } + else static if (is(typeof(CONFIG_IDF_TARGET_ESP32S3)) || is(typeof(CONFIG_IDF_TARGET_ESP32C3))) + { + int noise_floor:8; /**< noise floor of Radio Frequency Module(RF). unit: dBm*/ + uint :24; /**< reserved */ + uint :32; /**< reserved */ + } + + uint :31; /**< reserved */ + uint ant:1; /**< antenna number from which this packet is received. 0: WiFi antenna 0; 1: WiFi antenna 1 */ + + static if (is(typeof(CONFIG_IDF_TARGET_ESP32S2))) + { + int noise_floor:8; /**< noise floor of Radio Frequency Module(RF). unit: dBm*/ + uint :24; /**< reserved */ + } + else static if (is(typeof(CONFIG_IDF_TARGET_ESP32S3)) || is(typeof(CONFIG_IDF_TARGET_ESP32C3))) + { + uint :32; /**< reserved */ + uint :32; /**< reserved */ + uint :32; /**< reserved */ + } + + uint sig_len:12; /**< length of packet including Frame Check Sequence(FCS) */ + uint :12; /**< reserved */ + uint rx_state:8; /**< state of the packet. 0: no error; others: error numbers which are not public */ +} + +/** @brief Payload passed to 'buf' parameter of promiscuous mode RX callback. + */ +struct wifi_promiscuous_pkt_t +{ + wifi_pkt_rx_ctrl_t rx_ctrl; /**< metadata header */ + ubyte[0] payload; /**< Data or management payload. Length of payload is described by rx_ctrl.sig_len. Type of content determined by packet type argument of callback. */ +} + +/** + * @brief Promiscuous frame type + * + * Passed to promiscuous mode RX callback to indicate the type of parameter in the buffer. + * + */ +enum wifi_promiscuous_pkt_type_t +{ + WIFI_PKT_MGMT, /**< Management frame, indicates 'buf' argument is wifi_promiscuous_pkt_t */ + WIFI_PKT_CTRL, /**< Control frame, indicates 'buf' argument is wifi_promiscuous_pkt_t */ + WIFI_PKT_DATA, /**< Data frame, indiciates 'buf' argument is wifi_promiscuous_pkt_t */ + WIFI_PKT_MISC, /**< Other type, such as MIMO etc. 'buf' argument is wifi_promiscuous_pkt_t but the payload is zero length. */ +} + +/** @brief Mask for filtering different packet types in promiscuous mode. */ +struct wifi_promiscuous_filter_t +{ + uint filter_mask; /**< OR of one or more filter values WIFI_PROMIS_FILTER_* */ +} + +/** + * @brief Channel state information(CSI) configuration type + * + */ +struct wifi_csi_config_t +{ + bool lltf_en; /**< enable to receive legacy long training field(lltf) data. Default enabled */ + bool htltf_en; /**< enable to receive HT long training field(htltf) data. Default enabled */ + bool stbc_htltf2_en; /**< enable to receive space time block code HT long training field(stbc-htltf2) data. Default enabled */ + bool ltf_merge_en; /**< enable to generate htlft data by averaging lltf and ht_ltf data when receiving HT packet. Otherwise, use ht_ltf data directly. Default enabled */ + bool channel_filter_en; /**< enable to turn on channel filter to smooth adjacent sub-carrier. Disable it to keep independence of adjacent sub-carrier. Default enabled */ + bool manu_scale; /**< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false */ + ubyte shift; /**< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 */ +} + +/** + * @brief CSI data type + * + */ +struct wifi_csi_info_t +{ + wifi_pkt_rx_ctrl_t rx_ctrl;/**< received packet radio metadata header of the CSI data */ + ubyte[6] mac; /**< source MAC address of the CSI data */ + bool first_word_invalid; /**< first four bytes of the CSI data is invalid or not */ + byte *buf; /**< buffer of CSI data */ + ushort len; /**< length of CSI data */ +} + +/** + * @brief WiFi GPIO configuration for antenna selection + * + */ +struct wifi_ant_gpio_t +{ + ubyte gpio_select: 1, /**< Whether this GPIO is connected to external antenna switch */ + gpio_num: 7; /**< The GPIO number that connects to external antenna switch */ +} + +/** + * @brief WiFi GPIOs configuration for antenna selection + * + */ +struct wifi_ant_gpio_config_t +{ + wifi_ant_gpio_t[4] gpio_cfg; /**< The configurations of GPIOs that connect to external antenna switch */ +} + +/** + * @brief WiFi antenna mode + * + */ +enum wifi_ant_mode_t +{ + WIFI_ANT_MODE_ANT0, /**< Enable WiFi antenna 0 only */ + WIFI_ANT_MODE_ANT1, /**< Enable WiFi antenna 1 only */ + WIFI_ANT_MODE_AUTO, /**< Enable WiFi antenna 0 and 1, automatically select an antenna */ + WIFI_ANT_MODE_MAX, /**< Invalid WiFi enabled antenna */ +} + +/** + * @brief WiFi antenna configuration + * + */ +struct wifi_ant_config_t +{ + wifi_ant_mode_t rx_ant_mode; /**< WiFi antenna mode for receiving */ + wifi_ant_t rx_ant_default; /**< Default antenna mode for receiving, it's ignored if rx_ant_mode is not WIFI_ANT_MODE_AUTO */ + wifi_ant_mode_t tx_ant_mode; /**< WiFi antenna mode for transmission, it can be set to WIFI_ANT_MODE_AUTO only if rx_ant_mode is set to WIFI_ANT_MODE_AUTO */ + ubyte enabled_ant0: 4, /**< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT0 */ + enabled_ant1: 4; /**< Index (in antenna GPIO configuration) of enabled WIFI_ANT_MODE_ANT1 */ +} + +/** + * @brief The Rx callback function of Action Tx operations + * + * @param hdr pointer to the IEEE 802.11 Header structure + * @param payload pointer to the Payload following 802.11 Header + * @param len length of the Payload + * @param channel channel number the frame is received on + * + */ +alias wifi_action_rx_cb_t = int function(ubyte* hdr, ubyte* payload, + size_t len, ubyte channel); + +/** + * @brief Action Frame Tx Request + * + * + */ +struct wifi_action_tx_req_t +{ + wifi_interface_t ifx; /**< WiFi interface to send request to */ + ubyte[6] dest_mac; /**< Destination MAC address */ + bool no_ack; /**< Indicates no ack required */ + wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive any response */ + uint data_len; /**< Length of the appended Data */ + ubyte[0] data; /**< Appended Data payload */ +} + +/** + * @brief FTM Initiator configuration + * + */ +struct wifi_ftm_initiator_cfg_t +{ + ubyte[6] resp_mac; /**< MAC address of the FTM Responder */ + ubyte channel; /**< Primary channel of the FTM Responder */ + ubyte frm_count; /**< No. of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64) */ + ushort burst_period; /**< Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) */ + bool use_get_report_api; /**< True - Using esp_wifi_ftm_get_report to get FTM report, False - Using ftm_report_data from + WIFI_EVENT_FTM_REPORT to get FTM report */ +} + +/** + * @brief WiFi PHY rate encodings + * + */ +enum wifi_phy_rate_t +{ + WIFI_PHY_RATE_1M_L = 0x00, /**< 1 Mbps with long preamble */ + WIFI_PHY_RATE_2M_L = 0x01, /**< 2 Mbps with long preamble */ + WIFI_PHY_RATE_5M_L = 0x02, /**< 5.5 Mbps with long preamble */ + WIFI_PHY_RATE_11M_L = 0x03, /**< 11 Mbps with long preamble */ + WIFI_PHY_RATE_2M_S = 0x05, /**< 2 Mbps with short preamble */ + WIFI_PHY_RATE_5M_S = 0x06, /**< 5.5 Mbps with short preamble */ + WIFI_PHY_RATE_11M_S = 0x07, /**< 11 Mbps with short preamble */ + WIFI_PHY_RATE_48M = 0x08, /**< 48 Mbps */ + WIFI_PHY_RATE_24M = 0x09, /**< 24 Mbps */ + WIFI_PHY_RATE_12M = 0x0A, /**< 12 Mbps */ + WIFI_PHY_RATE_6M = 0x0B, /**< 6 Mbps */ + WIFI_PHY_RATE_54M = 0x0C, /**< 54 Mbps */ + WIFI_PHY_RATE_36M = 0x0D, /**< 36 Mbps */ + WIFI_PHY_RATE_18M = 0x0E, /**< 18 Mbps */ + WIFI_PHY_RATE_9M = 0x0F, /**< 9 Mbps */ + WIFI_PHY_RATE_MCS0_LGI = 0x10, /**< MCS0 with long GI, 6.5 Mbps for 20MHz, 13.5 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS1_LGI = 0x11, /**< MCS1 with long GI, 13 Mbps for 20MHz, 27 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS2_LGI = 0x12, /**< MCS2 with long GI, 19.5 Mbps for 20MHz, 40.5 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS3_LGI = 0x13, /**< MCS3 with long GI, 26 Mbps for 20MHz, 54 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS4_LGI = 0x14, /**< MCS4 with long GI, 39 Mbps for 20MHz, 81 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS5_LGI = 0x15, /**< MCS5 with long GI, 52 Mbps for 20MHz, 108 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS6_LGI = 0x16, /**< MCS6 with long GI, 58.5 Mbps for 20MHz, 121.5 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS7_LGI = 0x17, /**< MCS7 with long GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS0_SGI = 0x18, /**< MCS0 with short GI, 7.2 Mbps for 20MHz, 15 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS1_SGI = 0x19, /**< MCS1 with short GI, 14.4 Mbps for 20MHz, 30 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS2_SGI = 0x1A, /**< MCS2 with short GI, 21.7 Mbps for 20MHz, 45 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS3_SGI = 0x1B, /**< MCS3 with short GI, 28.9 Mbps for 20MHz, 60 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS4_SGI = 0x1C, /**< MCS4 with short GI, 43.3 Mbps for 20MHz, 90 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS5_SGI = 0x1D, /**< MCS5 with short GI, 57.8 Mbps for 20MHz, 120 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS6_SGI = 0x1E, /**< MCS6 with short GI, 65 Mbps for 20MHz, 135 Mbps for 40MHz */ + WIFI_PHY_RATE_MCS7_SGI = 0x1F, /**< MCS7 with short GI, 72.2 Mbps for 20MHz, 150 Mbps for 40MHz */ + WIFI_PHY_RATE_LORA_250K = 0x29, /**< 250 Kbps */ + WIFI_PHY_RATE_LORA_500K = 0x2A, /**< 500 Kbps */ + WIFI_PHY_RATE_MAX, +} + +/** WiFi event declarations */ +enum wifi_event_t +{ + WIFI_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */ + WIFI_EVENT_SCAN_DONE, /**< ESP32 finish scanning AP */ + WIFI_EVENT_STA_START, /**< ESP32 station start */ + WIFI_EVENT_STA_STOP, /**< ESP32 station stop */ + WIFI_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */ + WIFI_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */ + WIFI_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */ + + WIFI_EVENT_STA_WPS_ER_SUCCESS, /**< ESP32 station wps succeeds in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_FAILED, /**< ESP32 station wps fails in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP32 station wps timeout in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_PIN, /**< ESP32 station wps pin code in enrollee mode */ + WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, /**< ESP32 station wps overlap in enrollee mode */ + + WIFI_EVENT_AP_START, /**< ESP32 soft-AP start */ + WIFI_EVENT_AP_STOP, /**< ESP32 soft-AP stop */ + WIFI_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */ + WIFI_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */ + WIFI_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ + + WIFI_EVENT_FTM_REPORT, /**< Receive report of FTM procedure */ + + /* Add next events after this only */ + WIFI_EVENT_STA_BSS_RSSI_LOW, /**< AP's RSSI crossed configured threshold */ + WIFI_EVENT_ACTION_TX_STATUS, /**< Status indication of Action Tx operation */ + WIFI_EVENT_ROC_DONE, /**< Remain-on-Channel operation complete */ + + WIFI_EVENT_STA_BEACON_TIMEOUT, /**< ESP32 station beacon timeout */ + + WIFI_EVENT_MAX, /**< Invalid WiFi event ID */ +} + +/** Argument structure for WIFI_EVENT_SCAN_DONE event */ +struct wifi_event_sta_scan_done_t +{ + uint status; /**< status of scanning APs: 0 — success, 1 - failure */ + ubyte number; /**< number of scan results */ + ubyte scan_id; /**< scan sequence number, used for block scan */ +} + +/** Argument structure for WIFI_EVENT_STA_CONNECTED event */ +struct wifi_event_sta_connected_t +{ + ubyte[32] ssid; /**< SSID of connected AP */ + ubyte ssid_len; /**< SSID length of connected AP */ + ubyte[6] bssid; /**< BSSID of connected AP*/ + ubyte channel; /**< channel of connected AP*/ + wifi_auth_mode_t authmode;/**< authentication mode used by AP*/ +} + +/** Argument structure for WIFI_EVENT_STA_DISCONNECTED event */ +struct wifi_event_sta_disconnected_t +{ + ubyte[32] ssid; /**< SSID of disconnected AP */ + ubyte ssid_len; /**< SSID length of disconnected AP */ + ubyte[6] bssid; /**< BSSID of disconnected AP */ + ubyte reason; /**< reason of disconnection */ + byte rssi; /**< rssi of disconnection */ +} + +/** Argument structure for WIFI_EVENT_STA_AUTHMODE_CHANGE event */ +struct wifi_event_sta_authmode_change_t +{ + wifi_auth_mode_t old_mode; /**< the old auth mode of AP */ + wifi_auth_mode_t new_mode; /**< the new auth mode of AP */ +} + +/** Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event */ +struct wifi_event_sta_wps_er_pin_t +{ + ubyte[8] pin_code; /**< PIN code of station in enrollee mode */ +} + +/** Argument structure for WIFI_EVENT_STA_WPS_ER_FAILED event */ +enum wifi_event_sta_wps_fail_reason_t +{ + WPS_FAIL_REASON_NORMAL = 0, /**< ESP32 WPS normal fail reason */ + WPS_FAIL_REASON_RECV_M2D, /**< ESP32 WPS receive M2D frame */ + WPS_FAIL_REASON_MAX +} + +/** Argument structure for WIFI_EVENT_STA_WPS_ER_SUCCESS event */ +struct wifi_event_sta_wps_er_success_t +{ + struct Credential + { + ubyte[MAX_SSID_LEN] ssid; /**< SSID of AP */ + ubyte[MAX_PASSPHRASE_LEN] passphrase; /**< Passphrase for the AP */ + } + + ubyte ap_cred_cnt; /**< Number of AP credentials received */ + Credential[MAX_WPS_AP_CRED] ap_cred; /**< All AP credentials received from WPS handshake */ +} + +/** Argument structure for WIFI_EVENT_AP_STACONNECTED event */ +struct wifi_event_ap_staconnected_t +{ + ubyte[6] mac; /**< MAC address of the station connected to ESP32 soft-AP */ + ubyte aid; /**< the aid that ESP32 soft-AP gives to the station connected to */ + bool is_mesh_child; /**< flag to identify mesh child */ +} + +/** Argument structure for WIFI_EVENT_AP_STADISCONNECTED event */ +struct wifi_event_ap_stadisconnected_t +{ + ubyte[6] mac; /**< MAC address of the station disconnects to ESP32 soft-AP */ + ubyte aid; /**< the aid that ESP32 soft-AP gave to the station disconnects to */ + bool is_mesh_child; /**< flag to identify mesh child */ +} + +/** Argument structure for WIFI_EVENT_AP_PROBEREQRECVED event */ +struct wifi_event_ap_probe_req_rx_t +{ + int rssi; /**< Received probe request signal strength */ + ubyte[6] mac; /**< MAC address of the station which send probe request */ +} + +/** Argument structure for WIFI_EVENT_STA_BSS_RSSI_LOW event */ +struct wifi_event_bss_rssi_low_t +{ + int rssi; /**< RSSI value of bss */ +} + +/** + * @brief FTM operation status types + * + */ +enum wifi_ftm_status_t +{ + FTM_STATUS_SUCCESS = 0, /**< FTM exchange is successful */ + FTM_STATUS_UNSUPPORTED, /**< Peer does not support FTM */ + FTM_STATUS_CONF_REJECTED, /**< Peer rejected FTM configuration in FTM Request */ + FTM_STATUS_NO_RESPONSE, /**< Peer did not respond to FTM Requests */ + FTM_STATUS_FAIL, /**< Unknown error during FTM exchange */ + FTM_STATUS_NO_VALID_MSMT, /**< FTM session did not result in any valid measurements */ + FTM_STATUS_USER_TERM, /**< User triggered termination */ +} + +/** Argument structure for */ +struct wifi_ftm_report_entry_t +{ + ubyte dlog_token; /**< Dialog Token of the FTM frame */ + byte rssi; /**< RSSI of the FTM frame received */ + uint rtt; /**< Round Trip Time in pSec with a peer */ + ulong t1; /**< Time of departure of FTM frame from FTM Responder in pSec */ + ulong t2; /**< Time of arrival of FTM frame at FTM Initiator in pSec */ + ulong t3; /**< Time of departure of ACK from FTM Initiator in pSec */ + ulong t4; /**< Time of arrival of ACK at FTM Responder in pSec */ +} + +/** Argument structure for WIFI_EVENT_FTM_REPORT event */ +struct wifi_event_ftm_report_t +{ + ubyte[6] peer_mac; /**< MAC address of the FTM Peer */ + wifi_ftm_status_t status; /**< Status of the FTM operation */ + uint rtt_raw; /**< Raw average Round-Trip-Time with peer in Nano-Seconds */ + uint rtt_est; /**< Estimated Round-Trip-Time with peer in Nano-Seconds */ + uint dist_est; /**< Estimated one-way distance in Centi-Meters */ + wifi_ftm_report_entry_t *ftm_report_data; /**< Pointer to FTM Report, should be freed after use. Note: Highly recommended + to use API esp_wifi_ftm_get_report to get the report instead of using this */ + ubyte ftm_report_num_entries; /**< Number of entries in the FTM Report data */ +} + +/** Argument structure for WIFI_EVENT_ACTION_TX_STATUS event */ +struct wifi_event_action_tx_status_t +{ + wifi_interface_t ifx; /**< WiFi interface to send request to */ + uint context; /**< Context to identify the request */ + ubyte[6] da; /**< Destination MAC address */ + ubyte status; /**< Status of the operation */ +} + +/** Argument structure for WIFI_EVENT_ROC_DONE event */ +struct wifi_event_roc_done_t +{ + uint context; /**< Context to identify the request */ +} + +/** @brief WiFi event base declaration */ +extern __gshared esp_event_base_t WIFI_EVENT; diff --git a/source/idf/esp_wifi/idf_esp_wifi_c_code.c b/source/idf/esp_wifi/idf_esp_wifi_c_code.c index a88c5c4..054d1cb 100644 --- a/source/idf/esp_wifi/idf_esp_wifi_c_code.c +++ b/source/idf/esp_wifi/idf_esp_wifi_c_code.c @@ -1,7 +1 @@ #include "esp_wifi.h" - -wifi_init_config_t WIFI_INIT_CONFIG_DEFAULT_CFunc() -{ - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - return cfg; -} diff --git a/source/idf/esp_wifi/package.d b/source/idf/esp_wifi/package.d index 383bd60..ec0d309 100644 --- a/source/idf/esp_wifi/package.d +++ b/source/idf/esp_wifi/package.d @@ -1,7 +1,8 @@ module idf.esp_wifi; -public import idf.esp_wifi.idf_esp_wifi_c_code; +public import idf.esp_wifi.esp_wifi; +public import idf.esp_wifi.esp_wifi_crypto_types; +public import idf.esp_wifi.esp_wifi_default; +public import idf.esp_wifi.esp_wifi_types; -@safe: - -wifi_init_config_t WIFI_INIT_CONFIG_DEFAULT() @trusted => WIFI_INIT_CONFIG_DEFAULT_CFunc; +@safe nothrow @nogc extern (C): diff --git a/source/idf/freertos/package.d b/source/idf/freertos/package.d index c1fadfe..35d3e80 100644 --- a/source/idf/freertos/package.d +++ b/source/idf/freertos/package.d @@ -4,4 +4,4 @@ public import idf.freertos.idf_freertos_c_code; @safe nothrow @nogc: -enum portMAX_DELAY = TickType_t.max; \ No newline at end of file +enum portMAX_DELAY = TickType_t.max; diff --git a/source/idfd/net/wifi_client.d b/source/idfd/net/wifi_client.d index 64420ed..481c6bb 100644 --- a/source/idfd/net/wifi_client.d +++ b/source/idfd/net/wifi_client.d @@ -9,18 +9,18 @@ import idf.esp_event : esp_event_base_t, esp_event_handler_instance_t, ESP_EVENT import idf.freertos : EventGroupHandle_t, pdFALSE, portMAX_DELAY, xEventGroupCreate, xEventGroupSetBits, xEventGroupWaitBits; -import idf.esp_wifi : esp_wifi_connect, esp_wifi_start, - WIFI_EVENT, WIFI_EVENT_STA_START, WIFI_EVENT_STA_DISCONNECTED, - esp_netif_init, esp_netif_create_default_wifi_sta, - IP_EVENT, IP_EVENT_STA_GOT_IP, ip_event_got_ip_t, - esp_wifi_init, wifi_init_config_t, WIFI_INIT_CONFIG_DEFAULT, - esp_wifi_set_mode, esp_wifi_set_config, wifi_config_t, wifi_sta_config_t, - WIFI_AUTH_OPEN, WIFI_AUTH_WEP, WIFI_MODE_STA, WIFI_IF_STA; +import idf.esp_netif : esp_netif_init, IP_EVENT, ip_event_got_ip_t, ip_event_t; +import idf.esp_wifi : esp_netif_create_default_wifi_sta, esp_wifi_connect, esp_wifi_init, + esp_wifi_set_config, esp_wifi_set_mode, esp_wifi_start, wifi_auth_mode_t, + wifi_config_t, WIFI_EVENT, wifi_event_t, WIFI_INIT_CONFIG_DEFAULT, wifi_init_config_t, + wifi_interface_t, wifi_mode_t, wifi_sta_config_t; import ministd.string : setStringz; @safe nothrow @nogc: +__gshared wifi_init_config_t initCfg; + struct WiFiClient { private enum log = Logger!"WifiClient"(); @@ -61,6 +61,7 @@ struct WiFiClient if (!nvsFlashInitialized) initNvsFlash!true; + m_eventGroup = xEventGroupCreate; ESP_ERROR_CHECK(esp_netif_init); @@ -68,7 +69,8 @@ struct WiFiClient ESP_ERROR_CHECK(esp_event_loop_create_default); esp_netif_create_default_wifi_sta; - wifi_init_config_t initCfg = WIFI_INIT_CONFIG_DEFAULT; + initCfg = WIFI_INIT_CONFIG_DEFAULT; + log.info!"tx: %d"(initCfg.dynamic_tx_buf_num); ESP_ERROR_CHECK(esp_wifi_init(&initCfg)); esp_event_handler_instance_t instance_any_id; @@ -77,7 +79,7 @@ struct WiFiClient WIFI_EVENT, ESP_EVENT_ANY_ID, &wifiEventHandler, &this, &instance_any_id )); ESP_ERROR_CHECK(esp_event_handler_instance_register( - IP_EVENT, IP_EVENT_STA_GOT_IP, &wifiEventHandler, &this, &instance_got_ip + IP_EVENT, ip_event_t.IP_EVENT_STA_GOT_IP, &wifiEventHandler, &this, &instance_got_ip )); wifi_config_t wifi_config; @@ -85,10 +87,11 @@ struct WiFiClient wifi_config.sta.ssid[].setStringz(m_ssid); wifi_config.sta.password[].setStringz(m_password); // Set minimum accepted network security - wifi_config.sta.threshold.authmode = m_password.length ? WIFI_AUTH_WEP : WIFI_AUTH_OPEN; + wifi_config.sta.threshold.authmode = m_password.length + ? wifi_auth_mode_t.WIFI_AUTH_WEP : wifi_auth_mode_t.WIFI_AUTH_OPEN; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_set_mode(wifi_mode_t.WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(wifi_interface_t.WIFI_IF_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start); } @@ -101,12 +104,12 @@ struct WiFiClient { if (eventBase == WIFI_EVENT) { - if (eventId == WIFI_EVENT_STA_START) + if (eventId == wifi_event_t.WIFI_EVENT_STA_START) { log.info!"Connecting to AP..."; esp_wifi_connect; } - else if (eventId == WIFI_EVENT_STA_DISCONNECTED) + else if (eventId == wifi_event_t.WIFI_EVENT_STA_DISCONNECTED) { log.warn!"Failed to connect to AP, retrying..."; esp_wifi_connect; @@ -114,7 +117,7 @@ struct WiFiClient } else if (eventBase == IP_EVENT) { - if (eventId == IP_EVENT_STA_GOT_IP) + if (eventId == ip_event_t.IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t* event = cast(ip_event_got_ip_t*) eventData; uint* ipPtr = &event.ip_info.ip.addr; diff --git a/source/ministd/heap_caps.d b/source/ministd/heap_caps.d index f537f47..d33607a 100644 --- a/source/ministd/heap_caps.d +++ b/source/ministd/heap_caps.d @@ -6,7 +6,7 @@ import core.lifetime : emplace; import idf.heap.caps : heap_caps_malloc; -@safe nothrow: +@safe nothrow @nogc: @trusted void[] mallocCapsWrapper(size_t size, uint capabilities = 0)