diff --git a/.devcontainer/All/Dockerfile.All.SRC b/.devcontainer/All/Dockerfile.All.SRC index e8b49e1125..5b3fdb3f2b 100644 --- a/.devcontainer/All/Dockerfile.All.SRC +++ b/.devcontainer/All/Dockerfile.All.SRC @@ -55,7 +55,8 @@ RUN apt-get update \ ninja-build \ srecord \ nodejs \ - libffi-dev + libffi-dev \ + libusb-1.0 # Create needed directories RUN mkdir -p /usr/local/bin/gcc \ @@ -92,7 +93,7 @@ RUN git clone --branch V10.4.1-kernel-only https://github.com/FreeRTOS/FreeRTOS- RUN git clone --branch STABLE-2_1_3_RELEASE https://github.com/lwip-tcpip/lwip.git --depth 1 ./sources/lwip # Clone ESP-IDF -RUN git clone --branch v5.2.3 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf +RUN git clone --branch v5.4.1 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf # Clone what is needed for TI RUN git clone --branch 4.10.00.07 https://github.com/nanoframework/SimpleLink_CC32xx_SDK.git --depth 1 ./sources/SimpleLinkCC32 \ @@ -127,12 +128,12 @@ RUN ln -fs /usr/bin/python3 /usr/bin/python \ # Install ESP-IDF ENV IDF_PATH=/sources/esp-idf -ENV ESP_PATCH_VER=esp-13.2.0_20230928 +ENV ESP_PATCH_VER=esp-14.2.0_20241119 # This is now taking care in the following line # RUN python -m pip install -r $IDF_PATH/requirements.txt RUN $IDF_PATH/install.sh -ENV PATH=/root/.espressif/python_env/idf5.2_py3.11_env/bin:$PATH:\ +ENV PATH=/root/.espressif/python_env/idf5.4_py3.11_env/bin:$PATH:\ $IDF_PATH/components/esptool_py/esptool:\ $IDF_PATH/components/espcoredump:\ $IDF_PATH/components/partition_table/:\ diff --git a/.devcontainer/ESP32/Dockerfile.ESP32.SRC b/.devcontainer/ESP32/Dockerfile.ESP32.SRC index a7f0ced160..c6006a75ee 100644 --- a/.devcontainer/ESP32/Dockerfile.ESP32.SRC +++ b/.devcontainer/ESP32/Dockerfile.ESP32.SRC @@ -39,7 +39,8 @@ RUN apt-get update \ ninja-build \ srecord \ nodejs \ - libffi-dev + libffi-dev \ + libusb-1.0 # Create needed directories RUN mkdir -p /usr/local/bin/gcc @@ -48,7 +49,7 @@ RUN mkdir -p /usr/local/bin/gcc RUN git clone --branch R0.15a https://github.com/abbrev/fatfs.git --depth 1 ./sources/fatfs # Clone ESP-IDF -RUN git clone --branch v5.2.3 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf +RUN git clone --branch v5.4.1 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf # Creating static link python for pyhton3 RUN ln -fs /usr/bin/python3 /usr/bin/python \ @@ -61,12 +62,12 @@ ENV PATH=/usr/bin/cmake/bin:${PATH} # Install ESP-IDF ENV IDF_PATH=/sources/esp-idf -ENV ESP_PATCH_VER=esp-13.2.0_20230928 +ENV ESP_PATCH_VER=esp-14.2.0_20241119 # This is now taking care in the following line # RUN python -m pip install -r $IDF_PATH/requirements.txt RUN $IDF_PATH/install.sh -ENV PATH=/root/.espressif/python_env/idf5.2_py3.11_env/bin:$PATH:\ +ENV PATH=/root/.espressif/python_env/idf5.4_py3.11_env/bin:$PATH:\ $IDF_PATH/components/esptool_py/esptool:\ $IDF_PATH/components/espcoredump:\ $IDF_PATH/components/partition_table/:\ diff --git a/CMake/Modules/ESP32_P4_GCC_options.cmake b/CMake/Modules/ESP32_P4_GCC_options.cmake new file mode 100644 index 0000000000..c4821f1843 --- /dev/null +++ b/CMake/Modules/ESP32_P4_GCC_options.cmake @@ -0,0 +1,53 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# need to specify linker flags here +set(CMAKE_EXE_LINKER_FLAGS " -Wl,--print-memory-usage " CACHE INTERNAL "executable linker flags") + +# TARGET parameter to set the target that's setting them for +# optional EXTRA_COMPILE_OPTIONS with compile options to be added +macro(nf_set_compile_options) + + # parse arguments + cmake_parse_arguments(NFSCO "" "TARGET" "EXTRA_COMPILE_OPTIONS" ${ARGN}) + + if(NOT NFSCO_TARGET OR "${NFSCO_TARGET}" STREQUAL "") + message(FATAL_ERROR "Need to set TARGET argument when calling nf_set_compile_options()") + endif() + + # include any extra options coming from any extra args? + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) + + # this series has FPU + target_compile_definitions(${NFSCO_TARGET} PUBLIC -DTARGET=esp32p4 -DUSE_FPU=TRUE -DPLATFORM_ESP32 -DESP_PLATFORM) + +endmacro() + +# TARGET parameter to set the target that's setting them for +# optional EXTRA_LINK_FLAGS with link flags to be added +macro(nf_set_link_options) + + # parse arguments + cmake_parse_arguments(NFSLO "" "TARGET;EXTRA_LINK_FLAGS" "" ${ARGN}) + + if(NOT NFSLO_TARGET OR "${NFSLO_TARGET}" STREQUAL "") + message(FATAL_ERROR "Need to set TARGET argument when calling nf_set_link_options()") + endif() + + # set optimization linker flags for RELEASE and MinSizeRel + if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Os ") + endif() + + # include libraries in build + nf_include_libraries_in_build(${NFSLO_TARGET}) + + # set extra linker flags + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") + + # set optimization flags + nf_set_optimization_options(${NFSLO_TARGET}) + +endmacro() diff --git a/CMake/Modules/ESP32_P4_sources.cmake b/CMake/Modules/ESP32_P4_sources.cmake new file mode 100644 index 0000000000..0aa4fd139b --- /dev/null +++ b/CMake/Modules/ESP32_P4_sources.cmake @@ -0,0 +1,4 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# diff --git a/CMake/Modules/FindESP32_IDF.cmake b/CMake/Modules/FindESP32_IDF.cmake index 732ba96630..2b46f64c74 100644 --- a/CMake/Modules/FindESP32_IDF.cmake +++ b/CMake/Modules/FindESP32_IDF.cmake @@ -9,8 +9,6 @@ FetchContent_GetProperties(esp32_idf) include(binutils.ESP32) list(APPEND ESP32_IDF_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/config) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${TARGET_SERIES_SHORT}) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${TARGET_SERIES_SHORT}/esp_rom/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${ESP32_CPU_TYPE}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${ESP32_CPU_TYPE}/${TARGET_SERIES_SHORT}/include) @@ -21,21 +19,22 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/hal/includ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/hal/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/soc/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/soc/${TARGET_SERIES_SHORT}/include/soc) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/soc/${TARGET_SERIES_SHORT}/register) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_hw_support/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_hw_support/dma/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_hw_support/include/soc) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/gptimer/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/uart/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/gpio/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/spi/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_gptimer/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_uart/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_gpio/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_spi/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/i2c/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/i2s/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/dac/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/ledc/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/pcnt/include) -#list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/rmt/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/sdmmc/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_i2s/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_dac/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_ledc/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_pcnt/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_sdmmc/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_sdspi/include) # Use depecated drivers for RMT, I2S etc list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/deprecated) @@ -58,6 +57,7 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_ringbu list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_timer/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_system/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_wifi/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_wifi/include/local) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_partition/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_pm/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/fatfs/diskio) @@ -86,11 +86,12 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/sdmmc/incl list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/soc/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/vfs/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/wear_levelling/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/usb_serial_jtag/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_driver_usb_serial_jtag/include) -list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/include/${TARGET_SERIES_SHORT}/rom) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/${TARGET_SERIES_SHORT}) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/${TARGET_SERIES_SHORT}/include) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/${TARGET_SERIES_SHORT}/include/${TARGET_SERIES_SHORT}/rom) # includes specific to ESP32S2 and ESP32S3 if(${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") diff --git a/CMake/binutils.ESP32.cmake b/CMake/binutils.ESP32.cmake index 5a0beab55c..6042479396 100644 --- a/CMake/binutils.ESP32.cmake +++ b/CMake/binutils.ESP32.cmake @@ -151,6 +151,43 @@ macro(nf_fix_esp32c3_rom_file) endmacro() +# Fixes an issue with IDF 5.4.1 where we get an error cause by ESP_ROM_ELF_DIR environment variable missing +# This patch removes need for variable. Offical patch added after IDF5.4.1 release +macro(nf_patch_idf5_4_1) + file(READ + ${esp32_idf_SOURCE_DIR}/tools/cmake/gdbinit.cmake + ESP32_GBBINIT_CONTENT) + + string(FIND ${ESP32_GBBINIT_CONTENT} "# set(gdbinit_rom_in_path " GBD_INIT_PATCH_INDEX) + message("-- Check IDF patch exists") + if(GBD_INIT_PATCH_INDEX EQUAL -1) + + message("-- Patching IDF 5.4.1 gdbinit.cmake") + + string(REPLACE + "set(gdbinit_rom_in_path " + "# set(gdbinit_rom_in_path " + ESP32_GBBINIT_NEW_CONTENT + "${ESP32_GBBINIT_CONTENT}") + + string(REPLACE + "set(gdbinit_rom_path " + "# set(gdbinit_rom_path " + ESP32_GBBINIT_NEW_CONTENT + "${ESP32_GBBINIT_NEW_CONTENT}") + + string(REPLACE + "file(TO_CMAKE_PATH " + "# file(TO_CMAKE_PATH " + ESP32_GBBINIT_NEW_CONTENT + "${ESP32_GBBINIT_NEW_CONTENT}") + + file(WRITE + ${esp32_idf_SOURCE_DIR}/tools/cmake/gdbinit.cmake + "${ESP32_GBBINIT_NEW_CONTENT}") + endif() +endmacro() + # setting compile definitions for a target based on general build options # TARGET parameter to set the target that's setting them for # optional EXTRA_COMPILE_DEFINITIONS with compiler definitions to be added to the library @@ -184,7 +221,7 @@ function(nf_set_esp32_target_series) set(TARGET_SERIES_SHORT ${TARGET_SERIES_2} CACHE INTERNAL "ESP32 target series lower case, short version") # set the CPU type - if(${TARGET_SERIES_SHORT} STREQUAL "esp32c3" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32c6" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32h2" ) + if(${TARGET_SERIES_SHORT} STREQUAL "esp32c3" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32c6" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32h2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32p4") set(ESP32_CPU_TYPE "riscv" CACHE INTERNAL "Setting CPU type") else() set(ESP32_CPU_TYPE "xtensa" CACHE INTERNAL "Setting CPU type") @@ -468,6 +505,7 @@ macro(nf_setup_partition_tables_generator) ${TARGET_SERIES_SHORT} STREQUAL "esp32c3" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32c6" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32h2" OR + ${TARGET_SERIES_SHORT} STREQUAL "esp32p4" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") @@ -482,6 +520,7 @@ macro(nf_setup_partition_tables_generator) if(${TARGET_SERIES_SHORT} STREQUAL "esp32" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32c6" OR + ${TARGET_SERIES_SHORT} STREQUAL "esp32p4" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") @@ -501,7 +540,8 @@ macro(nf_setup_partition_tables_generator) endif() - if(${TARGET_SERIES_SHORT} STREQUAL "esp32s3") + if(${TARGET_SERIES_SHORT} STREQUAL "esp32s3" OR + ${TARGET_SERIES_SHORT} STREQUAL "esp32p4") # 32MB partition table for ESP32_S3 add_custom_command( TARGET ${NANOCLR_PROJECT_NAME}.elf POST_BUILD @@ -594,11 +634,16 @@ macro(nf_add_idf_as_library) # Load any required Components from Component registry # Must be done before "tools/cmake/idf.cmake" if(ESP32_USB_CDC) - nf_install_idf_component_from_registry(tinyusb 55142eec-a3a4-47a5-ad01-4ba3ef44444b) - nf_install_idf_component_from_registry(esp_tinyusb 8115ffc9-366a-4340-94ab-e327aed20831) + nf_install_idf_component_from_registry(tinyusb c384401d-144d-453d-a821-20f1ba0a7be1) + nf_install_idf_component_from_registry(esp_tinyusb 47b2b1fc-fb7e-4acf-943b-a14125e0f1e7) endif() - nf_install_idf_component_from_registry(littlefs 4831aa41-8b72-48ac-a534-910a985a5519) + nf_install_idf_component_from_registry(littlefs 288ff2e7-dfd9-4833-9be5-6e9d37d29880) + + if(${TARGET_SERIES_SHORT} STREQUAL "esp32p4") + nf_install_idf_component_from_registry(esp_wifi_remote 3355c7e4-03ac-44a2-b100-1cbb29a05d03) + nf_install_idf_component_from_registry(esp_hosted 9fb39051-7a32-4fbf-83e9-a4b54ab6fae5) + endif() include(${IDF_PATH_CMAKED}/tools/cmake/idf.cmake) @@ -670,7 +715,6 @@ macro(nf_add_idf_as_library) freertos esptool_py fatfs - esp_wifi esp_event vfs esp_netif @@ -686,7 +730,6 @@ macro(nf_add_idf_as_library) idf::freertos idf::esptool_py idf::fatfs - idf::esp_wifi idf::esp_event idf::vfs idf::esp_netif @@ -695,6 +738,17 @@ macro(nf_add_idf_as_library) idf::littlefs ) + # Needed for remote Wifi module on P4 boards + if(${TARGET_SERIES_SHORT} STREQUAL "esp32p4") + list(APPEND IDF_COMPONENTS_TO_ADD esp_wifi_remote) + list(APPEND IDF_COMPONENTS_TO_ADD esp_hosted) + list(APPEND IDF_LIBRARIES_TO_ADD idf::esp_hosted) + list(APPEND IDF_LIBRARIES_TO_ADD idf::esp_wifi_remote) + else() + list(APPEND IDF_COMPONENTS_TO_ADD esp_wifi) + list(APPEND IDF_LIBRARIES_TO_ADD idf::esp_wifi) + endif() + if(HAL_USE_BLE_OPTION) list(APPEND IDF_COMPONENTS_TO_ADD bt) list(APPEND IDF_LIBRARIES_TO_ADD idf::bt) @@ -1004,6 +1058,9 @@ macro(nf_add_idf_as_library) nf_fix_esp32c3_rom_file() + # FIXME patch IDF 5.4.1 problem + nf_patch_idf5_4_1() + # find out if there is support for BLE string(FIND ${SDKCONFIG_DEFAULT_CONTENTS} "CONFIG_BT_ENABLED=y" CONFIG_BT_ENABLED_POS) @@ -1035,8 +1092,8 @@ macro(nf_add_idf_as_library) add_custom_command( TARGET ${NANOCLR_PROJECT_NAME}.elf POST_BUILD COMMAND ${output_idf_size} - --archives --target ${TARGET_SERIES_SHORT} ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map - COMMENT "Ouptut IDF size summary") + --archives ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map + COMMENT "Output IDF size summary") endmacro() diff --git a/CMake/xtensa-esp32c3.json b/CMake/riscv-esp32c3.json similarity index 96% rename from CMake/xtensa-esp32c3.json rename to CMake/riscv-esp32c3.json index 342f6a6fa4..9dfbb8f9b5 100644 --- a/CMake/xtensa-esp32c3.json +++ b/CMake/riscv-esp32c3.json @@ -5,14 +5,14 @@ ], "configurePresets": [ { - "name": "xtensa-esp32c3-preset", + "name": "riscv-esp32c3-preset", "description": "Preset for ESP32-C3 series", "inherits": "general-preset", "hidden": true, "cacheVariables": { "CMAKE_TOOLCHAIN_FILE": { "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.riscv32-esp-elf.cmake" + "value": "${sourceDir}/CMake/toolchain.riscv32-esp32c3-elf.cmake" }, "NF_INTEROP_ASSEMBLIES": null, "NF_TARGET_HAS_NANOBOOTER": "OFF", diff --git a/CMake/xtensa-esp32c6.json b/CMake/riscv-esp32c6.json similarity index 94% rename from CMake/xtensa-esp32c6.json rename to CMake/riscv-esp32c6.json index 5c9e2d116a..b6b7f7f3dc 100644 --- a/CMake/xtensa-esp32c6.json +++ b/CMake/riscv-esp32c6.json @@ -5,14 +5,14 @@ ], "configurePresets": [ { - "name": "xtensa-esp32c6-preset", + "name": "riscv-esp32c6-preset", "description": "Preset for ESP32-C6 series", "inherits": "general-preset", "hidden": true, "cacheVariables": { "CMAKE_TOOLCHAIN_FILE": { "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.riscv32-esp-elf.cmake" + "value": "${sourceDir}/CMake/toolchain.riscv32-esp32c6-elf.cmake" }, "NF_INTEROP_ASSEMBLIES": null, "NF_TARGET_HAS_NANOBOOTER": "OFF", @@ -25,7 +25,7 @@ "SUPPORT_ANY_BASE_CONVERSION": "ON", "API_System.Net": "ON", "API_System.Math": "ON", - "API_System.Device.Adc": "ON", + "API_System.Device.Adc": "OFF", "API_System.Device.Gpio": "ON", "API_System.Device.I2c": "ON", "API_System.Device.I2c.Slave": "ON", diff --git a/CMake/xtensa-esp32h2.json b/CMake/riscv-esp32h2.json similarity index 93% rename from CMake/xtensa-esp32h2.json rename to CMake/riscv-esp32h2.json index 5f8c255830..b538afd256 100644 --- a/CMake/xtensa-esp32h2.json +++ b/CMake/riscv-esp32h2.json @@ -5,14 +5,14 @@ ], "configurePresets": [ { - "name": "xtensa-esp32h2-preset", + "name": "riscv-esp32h2-preset", "description": "Preset for ESP32-H2 series", "inherits": "general-preset", "hidden": true, "cacheVariables": { "CMAKE_TOOLCHAIN_FILE": { "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.riscv32-esp-elf.cmake" + "value": "${sourceDir}/CMake/toolchain.riscv32-esp32h2-elf.cmake" }, "NF_INTEROP_ASSEMBLIES": null, "NF_TARGET_HAS_NANOBOOTER": "OFF", @@ -25,7 +25,7 @@ "SUPPORT_ANY_BASE_CONVERSION": "ON", "API_System.Net": "ON", "API_System.Math": "ON", - "API_System.Device.Adc": "ON", + "API_System.Device.Adc": "OFF", "API_System.Device.Gpio": "ON", "API_System.Device.I2c": "ON", "API_System.Device.I2c.Slave": "ON", diff --git a/CMake/riscv-esp32p4.json b/CMake/riscv-esp32p4.json new file mode 100644 index 0000000000..c6b2222807 --- /dev/null +++ b/CMake/riscv-esp32p4.json @@ -0,0 +1,47 @@ +{ + "version": 4, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "riscv-esp32p4-preset", + "description": "Preset for ESP32-P4 series", + "inherits": "general-preset", + "hidden": true, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMake/toolchain.riscv32-esp32p4-elf.cmake" + }, + "NF_INTEROP_ASSEMBLIES": null, + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "RTOS": "ESP32", + "TARGET_SERIES": "ESP32_P4", + "TARGET_BOARD": "ESP32_P4", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "NF_FEATURE_USE_LITTLEFS": "ON", + "NF_FEATURE_HAS_ACCESSIBLE_STORAGE": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "API_System.Net": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.I2c.Slave": "ON", + "API_System.Device.I2s": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.System.IO.Hashing": "ON", + "API_nanoFramework.System.Security.Cryptography": "ON", + "API_Hardware.Esp32": "ON", + "API_nanoFramework.Hardware.Esp32.Rmt": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON" + } + } + ] +} diff --git a/CMake/toolchain.riscv32-esp-elf.cmake b/CMake/toolchain.riscv32-esp-elf.cmake index 0573f8720b..7e3f87a613 100644 --- a/CMake/toolchain.riscv32-esp-elf.cmake +++ b/CMake/toolchain.riscv32-esp-elf.cmake @@ -44,8 +44,8 @@ find_program( riscv32-esp-elf-size CMAKE_FIND_ROOT_PATH_BOTH) -set(CMAKE_C_FLAGS " -march=rv32imc_zicsr_zifencei -Wno-frame-address" CACHE STRING "C Compiler Base Flags") -set(CMAKE_CXX_FLAGS " -march=rv32imc_zicsr_zifencei -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") +set(CMAKE_C_FLAGS " -march=rv32imafc_zicsr_zifencei_xesppie -Wno-frame-address" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS " -march=rv32imafc_zicsr_zifencei_xesppie -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") # root paths to search on the filesystem for cross-compiling get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) diff --git a/CMake/toolchain.riscv32-esp32c3-elf.cmake b/CMake/toolchain.riscv32-esp32c3-elf.cmake new file mode 100644 index 0000000000..fe3a4691fe --- /dev/null +++ b/CMake/toolchain.riscv32-esp32c3-elf.cmake @@ -0,0 +1,61 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(CMakeForceCompiler) + +# the name of the operating system for which CMake is to build +set(CMAKE_SYSTEM_NAME Generic) + +# macro to setup compilers +macro(nf_set_compiler_var var name) + find_program( + CMAKE_${var} + riscv32-esp-elf-${name} + CMAKE_FIND_ROOT_PATH_BOTH + REQUIRED) +endmacro() + +# safer to have these here as a check if the toolchain are accessible in the PATH + +# setup C compiler +nf_set_compiler_var(C_COMPILER gcc) + +# setup C++ compiler +nf_set_compiler_var(CXX_COMPILER g++) + +# setup Assembler compiler +nf_set_compiler_var(ASM_COMPILER gcc) + +# other toolchain configurations +find_program( + CMAKE_OBJCOPY + riscv32-esp-elf-objcopy + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_OBJDUMP + riscv32-esp-elf-objdump + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_SIZE + riscv32-esp-elf-size + CMAKE_FIND_ROOT_PATH_BOTH) + +set(CMAKE_C_FLAGS " -march=rv32imc_zicsr_zifencei -Wno-frame-address" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS " -march=rv32imc_zicsr_zifencei -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") + +# root paths to search on the filesystem for cross-compiling +get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# set required C and C++ standard for ALL targets +set(CMAKE_C_STANDARD 11 CACHE INTERNAL "C standard for all targets") +set(CMAKE_CXX_STANDARD 11 CACHE INTERNAL "C++ standard for all targets") + +# Perform compiler test with static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/CMake/toolchain.riscv32-esp32c6-elf.cmake b/CMake/toolchain.riscv32-esp32c6-elf.cmake new file mode 100644 index 0000000000..26d95055fa --- /dev/null +++ b/CMake/toolchain.riscv32-esp32c6-elf.cmake @@ -0,0 +1,61 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(CMakeForceCompiler) + +# the name of the operating system for which CMake is to build +set(CMAKE_SYSTEM_NAME Generic) + +# macro to setup compilers +macro(nf_set_compiler_var var name) + find_program( + CMAKE_${var} + riscv32-esp-elf-${name} + CMAKE_FIND_ROOT_PATH_BOTH + REQUIRED) +endmacro() + +# safer to have these here as a check if the toolchain are accessible in the PATH + +# setup C compiler +nf_set_compiler_var(C_COMPILER gcc) + +# setup C++ compiler +nf_set_compiler_var(CXX_COMPILER g++) + +# setup Assembler compiler +nf_set_compiler_var(ASM_COMPILER gcc) + +# other toolchain configurations +find_program( + CMAKE_OBJCOPY + riscv32-esp-elf-objcopy + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_OBJDUMP + riscv32-esp-elf-objdump + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_SIZE + riscv32-esp-elf-size + CMAKE_FIND_ROOT_PATH_BOTH) + +set(CMAKE_C_FLAGS " -march=rv32imac_zicsr_zifencei -Wno-frame-address" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS " -march=rv32imac_zicsr_zifencei -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") + +# root paths to search on the filesystem for cross-compiling +get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# set required C and C++ standard for ALL targets +set(CMAKE_C_STANDARD 11 CACHE INTERNAL "C standard for all targets") +set(CMAKE_CXX_STANDARD 11 CACHE INTERNAL "C++ standard for all targets") + +# Perform compiler test with static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/CMake/toolchain.riscv32-esp32h2-elf.cmake b/CMake/toolchain.riscv32-esp32h2-elf.cmake new file mode 100644 index 0000000000..3ffd487db7 --- /dev/null +++ b/CMake/toolchain.riscv32-esp32h2-elf.cmake @@ -0,0 +1,61 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(CMakeForceCompiler) + +# the name of the operating system for which CMake is to build +set(CMAKE_SYSTEM_NAME Generic) + +# macro to setup compilers +macro(nf_set_compiler_var var name) + find_program( + CMAKE_${var} + riscv32-esp-elf-${name} + CMAKE_FIND_ROOT_PATH_BOTH + REQUIRED) +endmacro() + +# safer to have these here as a check if the toolchain are accessible in the PATH + +# setup C compiler +nf_set_compiler_var(C_COMPILER gcc) + +# setup C++ compiler +nf_set_compiler_var(CXX_COMPILER g++) + +# setup Assembler compiler +nf_set_compiler_var(ASM_COMPILER gcc) + +# other toolchain configurations +find_program( + CMAKE_OBJCOPY + riscv32-esp-elf-objcopy + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_OBJDUMP + riscv32-esp-elf-objdump + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_SIZE + riscv32-esp-elf-size + CMAKE_FIND_ROOT_PATH_BOTH) + +set(CMAKE_C_FLAGS " -march=rv32imac_zicsr_zifencei -mabi=ilp32 -Wno-frame-address" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS " -march=rv32imac_zicsr_zifencei -mabi=ilp32 -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") + +# root paths to search on the filesystem for cross-compiling +get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# set required C and C++ standard for ALL targets +set(CMAKE_C_STANDARD 11 CACHE INTERNAL "C standard for all targets") +set(CMAKE_CXX_STANDARD 11 CACHE INTERNAL "C++ standard for all targets") + +# Perform compiler test with static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/CMake/toolchain.riscv32-esp32p4-elf.cmake b/CMake/toolchain.riscv32-esp32p4-elf.cmake new file mode 100644 index 0000000000..ef24974e6b --- /dev/null +++ b/CMake/toolchain.riscv32-esp32p4-elf.cmake @@ -0,0 +1,62 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(CMakeForceCompiler) + +# the name of the operating system for which CMake is to build +set(CMAKE_SYSTEM_NAME Generic) + +# macro to setup compilers +macro(nf_set_compiler_var var name) + find_program( + CMAKE_${var} + riscv32-esp-elf-${name} + CMAKE_FIND_ROOT_PATH_BOTH + REQUIRED) +endmacro() + +# safer to have these here as a check if the toolchain are accessible in the PATH + +# setup C compiler +nf_set_compiler_var(C_COMPILER gcc) + +# setup C++ compiler +nf_set_compiler_var(CXX_COMPILER g++) + +# setup Assembler compiler +nf_set_compiler_var(ASM_COMPILER gcc) + +# other toolchain configurations +find_program( + CMAKE_OBJCOPY + riscv32-esp-elf-objcopy + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_OBJDUMP + riscv32-esp-elf-objdump + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_SIZE + riscv32-esp-elf-size + CMAKE_FIND_ROOT_PATH_BOTH) + +set(CMAKE_C_FLAGS " -march=rv32imafc_zicsr_zifencei_xesppie -mabi=ilp32f -Wno-frame-address" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS " -march=rv32imafc_zicsr_zifencei_xesppie -mabi=ilp32f -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") +set(CMAKE_ASM_FLAGS "-march=rv32imafc_zicsr_zifencei_xesppie -mabi=ilp32f ${CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE) + +# root paths to search on the filesystem for cross-compiling +get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# set required C and C++ standard for ALL targets +set(CMAKE_C_STANDARD 11 CACHE INTERNAL "C standard for all targets") +set(CMAKE_CXX_STANDARD 11 CACHE INTERNAL "C++ standard for all targets") + +# Perform compiler test with static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/CMake/toolchain.xtensa-esp32-elf.cmake b/CMake/toolchain.xtensa-esp32-elf.cmake index 4ca6585cdd..925d7068c4 100644 --- a/CMake/toolchain.xtensa-esp32-elf.cmake +++ b/CMake/toolchain.xtensa-esp32-elf.cmake @@ -44,8 +44,8 @@ find_program( xtensa-esp32-elf-size CMAKE_FIND_ROOT_PATH_BOTH) -set(CMAKE_C_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C Compiler Base Flags") -set(CMAKE_CXX_FLAGS "-mlongcalls -Wno-frame-address -Wno-literal-suffix" CACHE STRING "C++ Compiler Base Flags") +set(CMAKE_C_FLAGS "-mlongcalls -Wno-frame-address -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS "-mlongcalls -Wno-frame-address -Wno-literal-suffix -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero -fno-builtin-stpcpy -fno-builtin-strncpy" CACHE STRING "C++ Compiler Base Flags") # root paths to search on the filesystem for cross-compiling get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) diff --git a/CMakePresets.json b/CMakePresets.json index babeb6dfc5..fe2f0eb2df 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -3,7 +3,7 @@ "include": [ "CMake/arm-gcc.json", "CMake/xtensa-esp32.json", - "CMake/xtensa-esp32c3.json", + "CMake/riscv-esp32c3.json", "CMake/xtensa-esp32s2.json", "CMake/xtensa-esp32s3.json", "targets/AzureRTOS/CMakePresets.json", diff --git a/README.md b/README.md index 8a7889e729..8eea0a33df 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ We also have a [Community Targets](https://github.com/nanoframework/nf-Community | XIAO_ESP32C3 | USB jtag -> VS| [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/XIAO_ESP32C3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/XIAO_ESP32C3/latest/) | | ESP32_C6_THREAD | USB jtag -> VS, OpenThread, Display | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C6_THREAD/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C6_THREAD/latest/) | | ESP32_H2_THREAD | USB jtag -> VS, OpenThread | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_H2_THREAD/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_H2_THREAD/latest/) | +| ESP32_P4_UART | Beta, Uart -> VS, wifi ESP32_C6, No Display | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_P4_UART/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_P4_UART/latest/) | ### M5Stack diff --git a/azure-pipelines-nightly.yml b/azure-pipelines-nightly.yml index 1baeeab991..f726155c2d 100644 --- a/azure-pipelines-nightly.yml +++ b/azure-pipelines-nightly.yml @@ -17,7 +17,7 @@ resources: type: github name: espressif/esp-idf endpoint: nanoframework - ref: refs/tags/v5.2.3 + ref: refs/tags/v5.4.1 # scheduled build # the schedule is defined at the AZDO web interface because of inconsistencies with time zones @@ -577,6 +577,15 @@ jobs: PackageName: ESP_WROVER_KIT CMakePreset: ESP_WROVER_KIT + ESP32_P4_USB: + TargetBoard: ESP32_P4 + TargetSeries: "esp32p4" + BuildOptions: + IDF_Target: esp32p4 + TargetName: ESP32_P4_USB + PackageName: ESP32_P4_USB + CMakePreset: ESP32_P4_USB + variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable @@ -584,7 +593,7 @@ jobs: IDF_PATH: "D:/a/1/s/esp-idf" PIP_CACHE_DIR: $(Pipeline.Workspace)/.pip TargetPlatform: "esp32" - IDF_TAG: "v5.2.3" + IDF_TAG: "v5.4.1" steps: - checkout: self diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5549dc240a..ade455003e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -44,7 +44,7 @@ resources: type: github name: espressif/esp-idf endpoint: nanoframework - ref: refs/tags/v5.2.3 + ref: refs/tags/v5.4.1 - repository: mscorlib type: github name: nanoframework/CoreLibrary @@ -519,6 +519,15 @@ jobs: PackageName: ESP32_ETHERNET_KIT_1.2 CMakePreset: ESP32_ETHERNET_KIT_1.2 + ESP32_P4_UART: + TargetBoard: ESP32_P4 + TargetSeries: "esp32p4" + BuildOptions: + IDF_Target: esp32p4 + TargetName: ESP32_P4_UART + PackageName: ESP32_P4_UART + CMakePreset: ESP32_P4_UART + variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable @@ -526,7 +535,7 @@ jobs: IDF_PATH: "D:/a/1/s/esp-idf" PIP_CACHE_DIR: $(Pipeline.Workspace)/.pip TargetPlatform: "esp32" - IDF_TAG: "v5.2.3" + IDF_TAG: "v5.4.1" steps: - checkout: self diff --git a/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_NetworkInformation_WirelessAPConfiguration.cpp b/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_NetworkInformation_WirelessAPConfiguration.cpp index e7ee608a9a..8ac4df9ed9 100644 --- a/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_NetworkInformation_WirelessAPConfiguration.cpp +++ b/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_NetworkInformation_WirelessAPConfiguration.cpp @@ -165,7 +165,7 @@ HRESULT Library_sys_net_native_System_Net_NetworkInformation_WirelessAPConfigura NativeGetConnectedClients___STATIC__SZARRAY_SystemNetNetworkInformationWirelessAPStation__I4( CLR_RT_StackFrame &stack) { -#if defined(PLATFORM_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32H2) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) NANOCLR_HEADER(); CLR_RT_TypeDef_Index apStationTypeDef; @@ -263,7 +263,7 @@ HRESULT Library_sys_net_native_System_Net_NetworkInformation_WirelessAPConfigura HRESULT Library_sys_net_native_System_Net_NetworkInformation_WirelessAPConfiguration:: NativeDeauthStation___STATIC__STRING__I4(CLR_RT_StackFrame &stack) { -#if defined(PLATFORM_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32H2) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) NANOCLR_HEADER(); uint16_t index = (uint16_t)stack.Arg0().NumericByRef().u4; diff --git a/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp index f2db6f340f..b1893e92a6 100644 --- a/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp @@ -46,11 +46,11 @@ void nf_debug(void *ctx, int level, const char *file, int line, const char *str) debug_printf("%s", str); } -int net_would_block(const mbedtls_net_context *ctx) +__nfweak int net_would_block(const mbedtls_net_context *ctx) { - /* - * Never return 'WOULD BLOCK' on a non-blocking socket - */ + // + // Never return 'WOULD BLOCK' on a non-blocking socket + // int val = 0; if ((fcntl(ctx->fd, F_GETFL, val) & O_NONBLOCK) != O_NONBLOCK) @@ -70,7 +70,7 @@ int net_would_block(const mbedtls_net_context *ctx) return (0); } -int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) +__nfweak int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) { int32_t ret; int32_t fd = ((mbedtls_net_context *)ctx)->fd; @@ -105,7 +105,7 @@ int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) return ret; } -int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len) +__nfweak int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len) { int32_t ret; int fd = ((mbedtls_net_context *)ctx)->fd; @@ -140,7 +140,7 @@ int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len) return ret; } -int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t timeout) +__nfweak int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t timeout) { int ret; struct timeval tv; @@ -158,7 +158,7 @@ int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t ret = select(fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv); - /* Zero fds ready means we timed out */ + // Zero fds ready means we timed out if (ret == 0) return (MBEDTLS_ERR_SSL_TIMEOUT); @@ -175,12 +175,12 @@ int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t return (MBEDTLS_ERR_NET_RECV_FAILED); } - /* This call will not block */ + // This call will not block return (mbedtls_net_recv(ctx, buf, len)); } // Gracefully closes the connection -void mbedtls_net_free(mbedtls_net_context *ctx) +__nfweak void mbedtls_net_free(mbedtls_net_context *ctx) { if (ctx->fd == -1) return; diff --git a/targets/ESP32/CMakeLists.txt b/targets/ESP32/CMakeLists.txt index 9fda07e5ad..aeba706532 100644 --- a/targets/ESP32/CMakeLists.txt +++ b/targets/ESP32/CMakeLists.txt @@ -64,7 +64,7 @@ endif() # 3. cache tag in build and download AZDO yaml templates # ################################################################################# ################################################################################# -set(ESP32_IDF_TAG "5.2.3" CACHE INTERNAL "ESP32 IDF tag") +set(ESP32_IDF_TAG "5.4.1" CACHE INTERNAL "ESP32 IDF tag") ################################################################################# ################################################################################# diff --git a/targets/ESP32/CMakePresets.json b/targets/ESP32/CMakePresets.json index 4372534551..685fcb2f92 100644 --- a/targets/ESP32/CMakePresets.json +++ b/targets/ESP32/CMakePresets.json @@ -2,9 +2,10 @@ "version": 4, "include": [ "../../CMake/xtensa-esp32.json", - "../../CMake/xtensa-esp32c3.json", - "../../CMake/xtensa-esp32c6.json", - "../../CMake/xtensa-esp32h2.json", + "../../CMake/riscv-esp32c3.json", + "../../CMake/riscv-esp32c6.json", + "../../CMake/riscv-esp32h2.json", + "../../CMake/riscv-esp32p4.json", "../../CMake/xtensa-esp32s2.json", "../../CMake/xtensa-esp32s3.json", "../../config/user-tools-repos.json", @@ -240,7 +241,7 @@ { "name": "ESP32_C3", "inherits": [ - "xtensa-esp32c3-preset", + "riscv-esp32c3-preset", "user-tools-repos", "user-prefs" ], @@ -258,7 +259,7 @@ { "name": "ESP32_C3_REV3", "inherits": [ - "xtensa-esp32c3-preset", + "riscv-esp32c3-preset", "user-tools-repos", "user-prefs" ], @@ -277,7 +278,7 @@ { "name": "ESP32_C6_THREAD", "inherits": [ - "xtensa-esp32c6-preset", + "riscv-esp32c6-preset", "user-tools-repos", "user-prefs" ], @@ -304,7 +305,7 @@ { "name": "ESP32_H2_THREAD", "inherits": [ - "xtensa-esp32h2-preset", + "riscv-esp32h2-preset", "user-tools-repos", "user-prefs" ], @@ -323,6 +324,58 @@ "THREAD_DEVICE_TYPE": "FTD" } }, + { + "name": "ESP32_P4_UART", + "inherits": [ + "riscv-esp32p4-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default.esp32p4", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "TARGET_SERIAL_BAUDRATE": "921600", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.Device.Wifi": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "ESP32_ETHERNET_SUPPORT": "ON", + "ESP32_ETHERNET_INTERFACE": "IP101", + "ETH_MDC_GPIO" : "31", + "ETH_MDIO_GPIO": "52", + "ETH_PHY_RST_GPIO": "51", + "ETH_PHY_ADDR": "1" + } + }, + { + "name": "ESP32_P4_USB", + "inherits": [ + "riscv-esp32p4-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default.esp32p4", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "HAL_WP_USE_USB_CDC": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.Device.Wifi": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "ESP32_ETHERNET_SUPPORT": "ON", + "ESP32_ETHERNET_INTERFACE": "IP101", + "ETH_MDC_GPIO" : "31", + "ETH_MDIO_GPIO": "52", + "ETH_PHY_RST_GPIO": "51", + "ETH_PHY_ADDR": "1" + } + }, { "name": "ESP32_S3", "inherits": [ @@ -404,7 +457,7 @@ { "name": "XIAO_ESP32C3", "inherits": [ - "xtensa-esp32c3-preset", + "riscv-esp32c3-preset", "user-tools-repos", "user-prefs" ], @@ -1069,6 +1122,18 @@ "name": "ESP32_S2_UART", "displayName": "ESP32_S2_UART", "configurePreset": "ESP32_S2_UART" + }, + { + "inherits": "base-user", + "name": "ESP32_P4_UART", + "displayName": "ESP32_P4_UART", + "configurePreset": "ESP32_P4_UART" + }, + { + "inherits": "base-user", + "name": "ESP32_P4_USB", + "displayName": "ESP32_P4_USB", + "configurePreset": "ESP32_P4_USB" } ] } diff --git a/targets/ESP32/ESP32_C6/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp b/targets/ESP32/ESP32_C6/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp index 06f08993c5..b55a150453 100644 --- a/targets/ESP32/ESP32_C6/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp +++ b/targets/ESP32/ESP32_C6/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp @@ -32,8 +32,7 @@ bool GraphicsMemory::GraphicsHeapLocation( CLR_UINT8 *&graphicsStartingAddress, CLR_UINT8 *&graphicsEndingAddress) { - // requesting 2MB - CLR_INT32 graphicsMemoryBlockSize = 2 * 1024 * 1024; + CLR_UINT32 graphicsMemoryBlockSize = requested; CLR_INT32 memoryCaps = MALLOC_CAP_8BIT | MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM; @@ -45,14 +44,15 @@ bool GraphicsMemory::GraphicsHeapLocation( } // We don't want to allocate upfront - if (requested == 0) + if (graphicsMemoryBlockSize == 0) { // We don't allocate anything here return false; } // Get Largest free block in SPIRam - CLR_INT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + CLR_UINT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + if (spiramMaxSize == 0) { // No SPIRAM, try and allocate small block in normal ram to keep allocator happy for @@ -60,14 +60,16 @@ bool GraphicsMemory::GraphicsHeapLocation( // Should be able to use with small screens memoryCaps ^= MALLOC_CAP_SPIRAM; - spiramMaxSize = requested; + spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); } if (spiramMaxSize < graphicsMemoryBlockSize) // limit the size to what is available { graphicsMemoryBlockSize = spiramMaxSize; } + graphicsStartingAddress = (CLR_UINT8 *)heap_caps_malloc(graphicsMemoryBlockSize, memoryCaps); + ASSERT(graphicsStartingAddress != NULL); graphicsEndingAddress = (CLR_UINT8 *)(graphicsStartingAddress + graphicsMemoryBlockSize); diff --git a/targets/ESP32/ESP32_C6/target_common.c b/targets/ESP32/ESP32_C6/target_common.c index 0ca5bb663b..e7c7f9f3b5 100644 --- a/targets/ESP32/ESP32_C6/target_common.c +++ b/targets/ESP32/ESP32_C6/target_common.c @@ -8,7 +8,7 @@ #include "target_board.h" #include "target_common.h" -#include +#include HAL_SYSTEM_CONFIG HalSystemConfig = { {true}, // HAL_DRIVER_CONFIG_HEADER Header; diff --git a/targets/ESP32/ESP32_H2/target_common.c b/targets/ESP32/ESP32_H2/target_common.c index 0ca5bb663b..b6ef0fd508 100644 --- a/targets/ESP32/ESP32_H2/target_common.c +++ b/targets/ESP32/ESP32_H2/target_common.c @@ -8,7 +8,7 @@ #include "target_board.h" #include "target_common.h" -#include +#include HAL_SYSTEM_CONFIG HalSystemConfig = { {true}, // HAL_DRIVER_CONFIG_HEADER Header; diff --git a/targets/ESP32/ESP32_P4/CMakeLists.txt b/targets/ESP32/ESP32_P4/CMakeLists.txt new file mode 100644 index 0000000000..2bffbbbc64 --- /dev/null +++ b/targets/ESP32/ESP32_P4/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(binutils.ESP32) + +############################## + +nf_setup_target_build() diff --git a/targets/ESP32/ESP32_P4/README.md b/targets/ESP32/ESP32_P4/README.md new file mode 100644 index 0000000000..2b7a6d37c1 --- /dev/null +++ b/targets/ESP32/ESP32_P4/README.md @@ -0,0 +1,10 @@ +# ESP32-P4 + +This reference target _fits_ all ESP32 boards carrying an ESP32-P4 chip. + +Check the details at the documentation website [here](http://docs.nanoframework.net/content/reference-targets/esp32-p4.html) + +Getting started guides and build instructions can also be found at the documentation website: + +- [Build instructions](https://docs.nanoframework.net/content/building/build-esp32.html) +- [Getting started with managed code (C#)](https://docs.nanoframework.net/content/getting-started-guides/getting-started-managed.html) diff --git a/targets/ESP32/ESP32_P4/common/CMakeLists.txt b/targets/ESP32/ESP32_P4/common/CMakeLists.txt new file mode 100644 index 0000000000..0aa4fd139b --- /dev/null +++ b/targets/ESP32/ESP32_P4/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# diff --git a/targets/ESP32/ESP32_P4/ffconf.h b/targets/ESP32/ESP32_P4/ffconf.h new file mode 100644 index 0000000000..c6821be003 --- /dev/null +++ b/targets/ESP32/ESP32_P4/ffconf.h @@ -0,0 +1,349 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) 2018, ChaN, all right reserved. +// See LICENSE file in the project root for full license information. +// + +// clang-format off + +#include +#include +#include + +#if (HAL_USE_SDC != TRUE) +// need this include here when not using SDCARD so it can load the one from IDF +#include +#endif + +/*---------------------------------------------------------------------------/ +/ Configurations of FatFs Module +/---------------------------------------------------------------------------*/ + +#define FFCONF_DEF 80286 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + + +#define FF_FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: Basic functions are fully enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define FF_USE_FIND 1 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + + +#define FF_USE_MKFS 1 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + + +#define FF_USE_FASTSEEK CONFIG_FATFS_USE_FASTSEEK +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + + +#define FF_USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + + +#define FF_USE_CHMOD 1 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ + + +#define FF_USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + + +#define FF_USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) */ + + +#define FF_USE_STRFUNC 0 +#define FF_PRINT_LLI 0 +#define FF_PRINT_FLOAT 0 +#define FF_STRF_ENCODE 3 +/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and +/ f_printf(). +/ +/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. +/ +/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2 +/ makes f_printf() support floating point argument. These features want C99 or later. +/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character +/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE +/ to be read/written via those functions. +/ +/ 0: ANSI/OEM in current CP +/ 1: Unicode in UTF-16LE +/ 2: Unicode in UTF-16BE +/ 3: Unicode in UTF-8 +*/ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define FF_CODE_PAGE CONFIG_FATFS_CODEPAGE +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect code page setting can cause a file open failure. +/ +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +/ 0 - Include all code pages above and configured by f_setcp() +*/ + + +#if defined(CONFIG_FATFS_LFN_STACK) +#define FF_USE_LFN 2 +#elif defined(CONFIG_FATFS_LFN_HEAP) +#define FF_USE_LFN 3 +#else /* CONFIG_FATFS_LFN_NONE */ +#define FF_USE_LFN 0 +#endif + +#ifdef CONFIG_FATFS_MAX_LFN +#define FF_MAX_LFN CONFIG_FATFS_MAX_LFN +#endif + +/* The FF_USE_LFN switches the support for LFN (long file name). +/ +/ 0: Disable LFN. FF_MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function +/ requires certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and +/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. +/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can +/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN +/ specification. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */ + + +#ifdef CONFIG_FATFS_API_ENCODING_UTF_8 +#define FF_LFN_UNICODE 2 +#else /* CONFIG_FATFS_API_ENCODING_ANSI_OEM */ +#define FF_LFN_UNICODE 0 +#endif +/* This option switches the character encoding on the API when LFN is enabled. +/ +/ 0: ANSI/OEM in current CP (TCHAR = char) +/ 1: Unicode in UTF-16 (TCHAR = WCHAR) +/ 2: Unicode in UTF-8 (TCHAR = char) +/ 3: Unicode in UTF-32 (TCHAR = DWORD) +/ +/ Also behavior of string I/O functions will be affected by this option. +/ When LFN is not enabled, this option has no effect. */ + + +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 +/* This set of options defines size of file name members in the FILINFO structure +/ which is used to read out directory items. These values should be suffcient for +/ the file names to read. The maximum possible length of the read file name depends +/ on character encoding. When LFN is not enabled, these options have no effect. */ + + +#define FF_FS_RPATH 2 +/* This option configures support for relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define FF_VOLUMES 3 +/* Number of volumes (logical drives) to be used. (1-10) */ + + +#define FF_STR_VOLUME_ID 1 +#define FF_VOLUME_STRS "D", "E", "F" +/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. +/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive +/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each +/ logical drives. Number of items must not be less than FF_VOLUMES. Valid +/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are +/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is +/ not defined, a user defined volume string table is needed as: +/ +/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... +*/ + + +#define FF_MULTI_PARTITION 1 +/* This option switches support for multiple volumes on the physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When this function is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ function will be available. */ + +/* SD card sector size */ +#define FF_SS_SDCARD 512 +/* wear_levelling library sector size */ +#define FF_SS_WL CONFIG_WL_SECTOR_SIZE + +#define FF_MIN_SS MIN(FF_SS_SDCARD, FF_SS_WL) +#define FF_MAX_SS MAX(FF_SS_SDCARD, FF_SS_WL) +/* This set of options configures the range of sector size to be supported. (512, +/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and +/ harddisk, but a larger value may be required for on-board flash memory and some +/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured +/ for variable sector size mode and disk_ioctl() function needs to implement +/ GET_SECTOR_SIZE command. */ + + +#define FF_LBA64 0 +/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable) +/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ + + +#define FF_MIN_GPT 0x10000000 +/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and +/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */ + + +#define FF_USE_TRIM 0 +/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_TINY (!CONFIG_FATFS_PER_FILE_CACHE) +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ + + +#define FF_FS_EXFAT 0 +/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) +/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ + + +#define FF_FS_NORTC 0 +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2022 +/* The option FF_FS_NORTC switches timestamp feature. If the system does not have +/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the +/ timestamp feature. Every object modified by FatFs will have a fixed timestamp +/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. +/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to read current time form real-time clock. FF_NORTC_MON, +/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. +/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */ + + +#define FF_FS_NOFSINFO 0 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at the first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + +#define FF_FS_LOCK CONFIG_FATFS_FS_LOCK +/* The option FF_FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + + +#define FF_FS_REENTRANT 1 +#define FF_FS_TIMEOUT (CONFIG_FATFS_TIMEOUT_MS / portTICK_PERIOD_MS) +/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this featuer. +/ +/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give() +/ function, must be added to the project. Samples are available in ffsystem.c. +/ +/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick. +*/ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +/* Some memory allocation functions are declared here in addition to ff.h, so that + they can be used also by external code when LFN feature is disabled. + */ +void* ff_memalloc (unsigned msize); +void ff_memfree(void*); + + +/*--- End of configuration options ---*/ + +/* Redefine names of disk IO functions to prevent name collisions */ +#define disk_initialize ff_disk_initialize +#define disk_status ff_disk_status +#define disk_read ff_disk_read +#define disk_write ff_disk_write +#define disk_ioctl ff_disk_ioctl + +// clang-format on diff --git a/targets/ESP32/ESP32_P4/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp b/targets/ESP32/ESP32_P4/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp new file mode 100644 index 0000000000..b55a150453 --- /dev/null +++ b/targets/ESP32/ESP32_P4/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef GRAPHICS_MEMORY_SETUP_ +#define GRAPHICS_MEMORY_SETUP_ + +#include +#include +#include +#include +#include + +struct GraphicsMemory g_GraphicsMemory; + +// Choosing Integrate RAM into ESP32 memory map from CONFIG_SPIRAM_USE. +// This is the most basic option for external SPI RAM integration +// During the ESP IDF start-up, external RAM is mapped into the data address space, +// starting at address 0x3F800000 (byte - accessible). +// The length of this region is the same as the SPI RAM size(up to the limit of 4 MB). + +// Applications can manually place data in external memory by creating pointers to this region. +// So if an application uses external memory, it is responsible for all management of the external SPI RAM. +// coordinating buffer usage, preventing corruption, etc. + +static CLR_UINT8 *heapStartingAddress = 0; +static CLR_UINT8 *heapEndingAddress = 0; + +bool GraphicsMemory::GraphicsHeapLocation( + CLR_UINT32 requested, + CLR_UINT8 *&graphicsStartingAddress, + CLR_UINT8 *&graphicsEndingAddress) +{ + CLR_UINT32 graphicsMemoryBlockSize = requested; + + CLR_INT32 memoryCaps = MALLOC_CAP_8BIT | MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM; + + if (heapStartingAddress != 0) + { + graphicsStartingAddress = heapStartingAddress; + graphicsEndingAddress = heapEndingAddress; + return true; + } + + // We don't want to allocate upfront + if (graphicsMemoryBlockSize == 0) + { + // We don't allocate anything here + return false; + } + + // Get Largest free block in SPIRam + CLR_UINT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + + if (spiramMaxSize == 0) + { + // No SPIRAM, try and allocate small block in normal ram to keep allocator happy for + // people trying to run graphics on boards without SPIRAM + // Should be able to use with small screens + memoryCaps ^= MALLOC_CAP_SPIRAM; + + spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + } + + if (spiramMaxSize < graphicsMemoryBlockSize) // limit the size to what is available + { + graphicsMemoryBlockSize = spiramMaxSize; + } + + graphicsStartingAddress = (CLR_UINT8 *)heap_caps_malloc(graphicsMemoryBlockSize, memoryCaps); + + ASSERT(graphicsStartingAddress != NULL); + graphicsEndingAddress = (CLR_UINT8 *)(graphicsStartingAddress + graphicsMemoryBlockSize); + + // Save where we allocated it for restarts + heapStartingAddress = graphicsStartingAddress; + heapEndingAddress = graphicsEndingAddress; + + return true; +} + +#endif // GRAPHICS_MEMORY_SETUP_ diff --git a/targets/ESP32/ESP32_P4/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp b/targets/ESP32/ESP32_P4/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp new file mode 100644 index 0000000000..7b21023fd4 --- /dev/null +++ b/targets/ESP32/ESP32_P4/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2017 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#define UNUSED(x) (void)x + +#ifndef SPI_TO_TOUCHPANEL_CPP +#define SPI_TO_TOUCHPANEL_CPP + +#include "nanoCLR_Types.h" +#include +#include +#include + +#include "TouchInterface.h" + +bool TouchInterface::Initialize() +{ + // Setup SPI configuration + + return true; +} + +CLR_UINT8 *TouchInterface::Write_Read( + CLR_UINT8 *valuesToSend, + CLR_UINT16 numberOfValuesToSend, + CLR_UINT16 numberValuesExpected) +{ + + UNUSED(valuesToSend); + UNUSED(numberOfValuesToSend); + UNUSED(numberValuesExpected); + + return 0; +} + +#endif // SPI_TO_TOUCHPANEL_CPP diff --git a/targets/ESP32/ESP32_S2/target_windows_storage_config.h b/targets/ESP32/ESP32_P4/nanoCLR/nanoHAL.cpp similarity index 64% rename from targets/ESP32/ESP32_S2/target_windows_storage_config.h rename to targets/ESP32/ESP32_P4/nanoCLR/nanoHAL.cpp index b2d2dec961..e754dd5f80 100644 --- a/targets/ESP32/ESP32_S2/target_windows_storage_config.h +++ b/targets/ESP32/ESP32_P4/nanoCLR/nanoHAL.cpp @@ -3,3 +3,6 @@ // See LICENSE file in the project root for full license information. // +#include + +bool g_fDoNotUninitializeDebuggerPort = false; diff --git a/targets/ESP32/ESP32_P4/nanoCLR/target_board.h.in b/targets/ESP32/ESP32_P4/nanoCLR/target_board.h.in new file mode 100644 index 0000000000..4d14660a1b --- /dev/null +++ b/targets/ESP32/ESP32_P4/nanoCLR/target_board.h.in @@ -0,0 +1,18 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef TARGET_BOARD_NANOCLR_H +#define TARGET_BOARD_NANOCLR_H + +#include + +#define OEMSYSTEMINFOSTRING "nanoCLR running @ @TARGET_BOARD@ built with ESP-IDF @IDF_VER@" + +#endif // TARGET_BOARD_NANOCLR_H diff --git a/targets/ESP32/ESP32_P4/target_BlockStorage.c b/targets/ESP32/ESP32_P4/target_BlockStorage.c new file mode 100644 index 0000000000..6a930352f5 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_BlockStorage.c @@ -0,0 +1,22 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +extern struct BlockStorageDevice Device_BlockStorage; +extern struct MEMORY_MAPPED_NOR_BLOCK_CONFIG Device_BlockStorageConfig; +extern IBlockStorageDevice ESP32Flash_BlockStorageInterface; + +void BlockStorage_AddDevices() +{ + // add device + BlockStorageList_AddDevice( + (BlockStorageDevice *)&Device_BlockStorage, + &ESP32Flash_BlockStorageInterface, + &Device_BlockStorageConfig, + false); +} diff --git a/targets/ESP32/ESP32_P4/target_BlockStorage.h b/targets/ESP32/ESP32_P4/target_BlockStorage.h new file mode 100644 index 0000000000..927aa237ed --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_BlockStorage.h @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef TARGETPAL_BLOCKSTORAGE_H +#define TARGETPAL_BLOCKSTORAGE_H + +// this device has 1 block storage device +#define TARGET_BLOCKSTORAGE_COUNT 1 + +#endif // TARGETPAL_BLOCKSTORAGE_H diff --git a/targets/ESP32/ESP32_P4/target_FileSystem.cpp b/targets/ESP32/ESP32_P4/target_FileSystem.cpp new file mode 100644 index 0000000000..33430d84c1 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_FileSystem.cpp @@ -0,0 +1,61 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include + +#if (HAL_USE_SDC == TRUE) +#include +#endif + +#include "Target_System_IO_FileSystem.h" + +extern FILESYSTEM_DRIVER_INTERFACE g_LITTLEFS_FILE_SYSTEM_DriverInterface; +extern STREAM_DRIVER_INTERFACE g_LITTLEFS_STREAM_DriverInterface; + +#if (HAL_USE_SDC == TRUE) +extern FILESYSTEM_DRIVER_INTERFACE g_FATFS_FILE_SYSTEM_DriverInterface; +extern STREAM_DRIVER_INTERFACE g_FATFS_STREAM_DriverInterface; +#endif + +FILESYSTEM_INTERFACES g_AvailableFSInterfaces[] = { + {&g_LITTLEFS_FILE_SYSTEM_DriverInterface, &g_LITTLEFS_STREAM_DriverInterface}, +#if (HAL_USE_SDC == TRUE) + {&g_FATFS_FILE_SYSTEM_DriverInterface, &g_FATFS_STREAM_DriverInterface}, +#endif +}; + +const size_t g_InstalledFSCount = ARRAYSIZE(g_AvailableFSInterfaces); + +uint32_t g_FS_NumVolumes; +STREAM_DRIVER_DETAILS *g_FS_DriverDetails; +FileSystemVolume *g_FS_Volumes; + +void FS_AddVolumes() +{ + // one internal storage in littlefs partition + g_FS_NumVolumes = 1; + + g_FS_Volumes = new FileSystemVolume[g_FS_NumVolumes]; + g_FS_DriverDetails = new STREAM_DRIVER_DETAILS[g_FS_NumVolumes]; + + // littlefs partition + FileSystemVolumeList::AddVolume( + &g_FS_Volumes[0], + "I:", + 0, + g_AvailableFSInterfaces[0].streamDriver, + g_AvailableFSInterfaces[0].fsDriver, + 0, + FALSE); +} + +void FS_MountRemovableVolumes() +{ + // nothing to do here +} diff --git a/targets/ESP32/ESP32_P4/target_common.c b/targets/ESP32/ESP32_P4/target_common.c new file mode 100644 index 0000000000..0d44223504 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_common.c @@ -0,0 +1,29 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include "target_board.h" +#include "target_common.h" + +#include + +HAL_SYSTEM_CONFIG HalSystemConfig = { + {true}, // HAL_DRIVER_CONFIG_HEADER Header; + + 1, // ConvertCOM_DebugHandle(1), + 0, // ConvertCOM_DebugHandle(0), + 921600, + 0, // STDIO = COM2 or COM1 + + {RAM1_MEMORY_StartAddress, RAM1_MEMORY_Size}, + {FLASH1_MEMORY_StartAddress, FLASH1_MEMORY_Size}}; + +HAL_TARGET_CONFIGURATION g_TargetConfiguration; + +void FixUpHalSystemConfig() +{ + HalSystemConfig.FLASH1.Size = g_rom_flashchip.chip_size; +} diff --git a/targets/ESP32/ESP32_P4/target_common.h.in b/targets/ESP32/ESP32_P4/target_common.h.in new file mode 100644 index 0000000000..6794119b58 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_common.h.in @@ -0,0 +1,49 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef TARGET_COMMON_H +#define TARGET_COMMON_H + +#include + +/////////////////////////////////////////////////////////////////////// +// RAM start address and size is filled @ HeapLocation() during boot // +/////////////////////////////////////////////////////////////////////// + +// RAM base address +#define RAM1_MEMORY_StartAddress (0x0) +// RAM size +#define RAM1_MEMORY_Size (0x0) + +///////////////////////////////////////////////////////////////////////////////// +// FLASH start address and size is filled @ FixUpHalSystemConfig() during boot // +///////////////////////////////////////////////////////////////////////////////// + +// FLASH base address +#define FLASH1_MEMORY_StartAddress (0x0) +// FLASH size +#define FLASH1_MEMORY_Size (0x0) + +///////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////// +#define TARGETNAMESTRING "@TARGET_NAME@" +#define PLATFORMNAMESTRING "ESP32" +////////////////////////////////////////////// + +///////////////////////////////////// +#define PLATFORM_HAS_RNG TRUE +///////////////////////////////////// + +///////////////////////////////////// +// #define EVENTS_HEART_BEAT +///////////////////////////////////// + +#endif // TARGET_COMMON_H diff --git a/targets/ESP32/ESP32_P4/target_lwip_sntp_opts.h b/targets/ESP32/ESP32_P4/target_lwip_sntp_opts.h new file mode 100644 index 0000000000..c4d09f1f1a --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_lwip_sntp_opts.h @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T OVERRIDE ANY lwIP SNTP OPTIONS // +////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_P4/target_lwipopts.h b/targets/ESP32/ESP32_P4/target_lwipopts.h new file mode 100644 index 0000000000..ca1a0b4465 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_lwipopts.h @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +///////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T OVERRIDE ANY lwIP OPTIONS // +///////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_C3/target_windows_storage_config.h b/targets/ESP32/ESP32_P4/target_nf_dev_onewire_config.cpp similarity index 100% rename from targets/ESP32/ESP32_C3/target_windows_storage_config.h rename to targets/ESP32/ESP32_P4/target_nf_dev_onewire_config.cpp diff --git a/targets/ESP32/ESP32_P4/target_nf_dev_onewire_config.h b/targets/ESP32/ESP32_P4/target_nf_dev_onewire_config.h new file mode 100644 index 0000000000..167ba490d6 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_nf_dev_onewire_config.h @@ -0,0 +1,10 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +// use UART 2 for the 1-wire interface +#define NF_ONEWIRE_ESP32_UART_NUM UART_NUM_2 +// use GPIO port 16 for RX and 17 for TX +#define NF_ONEWIRE_ESP32_UART_RX_PIN UART_NUM_2_RXD_DIRECT_GPIO_NUM +#define NF_ONEWIRE_ESP32_UART_TX_PIN UART_NUM_2_TXD_DIRECT_GPIO_NUM diff --git a/targets/ESP32/ESP32_C6/target_windows_storage_config.h b/targets/ESP32/ESP32_P4/target_system_device_adc_config.cpp similarity index 100% rename from targets/ESP32/ESP32_C6/target_windows_storage_config.h rename to targets/ESP32/ESP32_P4/target_system_device_adc_config.cpp diff --git a/targets/ESP32/ESP32_H2/target_windows_storage_config.h b/targets/ESP32/ESP32_P4/target_system_device_dac_config.cpp similarity index 100% rename from targets/ESP32/ESP32_H2/target_windows_storage_config.h rename to targets/ESP32/ESP32_P4/target_system_device_dac_config.cpp diff --git a/targets/ESP32/ESP32_P4/target_system_device_i2c_config.cpp b/targets/ESP32/ESP32_P4/target_system_device_i2c_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_system_device_i2c_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32/target_windows_storage_config.h b/targets/ESP32/ESP32_P4/target_system_device_i2c_slave_config.h similarity index 51% rename from targets/ESP32/ESP32/target_windows_storage_config.h rename to targets/ESP32/ESP32_P4/target_system_device_i2c_slave_config.h index b2d2dec961..314f5e7213 100644 --- a/targets/ESP32/ESP32/target_windows_storage_config.h +++ b/targets/ESP32/ESP32_P4/target_system_device_i2c_slave_config.h @@ -3,3 +3,7 @@ // See LICENSE file in the project root for full license information. // +// I2C slave TX buffer size +#define I2C_SLAVE_TX_BUF_LEN 16 +// I2C slave RX buffer size +#define I2C_SLAVE_RX_BUF_LEN 16 diff --git a/targets/ESP32/ESP32_P4/target_system_device_i2s_config.cpp b/targets/ESP32/ESP32_P4/target_system_device_i2s_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_system_device_i2s_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_P4/target_system_device_pwm_config.cpp b/targets/ESP32/ESP32_P4/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_P4/target_system_device_spi_config.cpp b/targets/ESP32/ESP32_P4/target_system_device_spi_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_system_device_spi_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_P4/target_system_devices_dac_config.cpp b/targets/ESP32/ESP32_P4/target_system_devices_dac_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_system_devices_dac_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_P4/target_system_io_ports_config.cpp b/targets/ESP32/ESP32_P4/target_system_io_ports_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_P4/target_system_io_ports_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S2/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp b/targets/ESP32/ESP32_S2/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp index 06f08993c5..b55a150453 100644 --- a/targets/ESP32/ESP32_S2/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp +++ b/targets/ESP32/ESP32_S2/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp @@ -32,8 +32,7 @@ bool GraphicsMemory::GraphicsHeapLocation( CLR_UINT8 *&graphicsStartingAddress, CLR_UINT8 *&graphicsEndingAddress) { - // requesting 2MB - CLR_INT32 graphicsMemoryBlockSize = 2 * 1024 * 1024; + CLR_UINT32 graphicsMemoryBlockSize = requested; CLR_INT32 memoryCaps = MALLOC_CAP_8BIT | MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM; @@ -45,14 +44,15 @@ bool GraphicsMemory::GraphicsHeapLocation( } // We don't want to allocate upfront - if (requested == 0) + if (graphicsMemoryBlockSize == 0) { // We don't allocate anything here return false; } // Get Largest free block in SPIRam - CLR_INT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + CLR_UINT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + if (spiramMaxSize == 0) { // No SPIRAM, try and allocate small block in normal ram to keep allocator happy for @@ -60,14 +60,16 @@ bool GraphicsMemory::GraphicsHeapLocation( // Should be able to use with small screens memoryCaps ^= MALLOC_CAP_SPIRAM; - spiramMaxSize = requested; + spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); } if (spiramMaxSize < graphicsMemoryBlockSize) // limit the size to what is available { graphicsMemoryBlockSize = spiramMaxSize; } + graphicsStartingAddress = (CLR_UINT8 *)heap_caps_malloc(graphicsMemoryBlockSize, memoryCaps); + ASSERT(graphicsStartingAddress != NULL); graphicsEndingAddress = (CLR_UINT8 *)(graphicsStartingAddress + graphicsMemoryBlockSize); diff --git a/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp b/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp index 06f08993c5..b55a150453 100644 --- a/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp +++ b/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp @@ -32,8 +32,7 @@ bool GraphicsMemory::GraphicsHeapLocation( CLR_UINT8 *&graphicsStartingAddress, CLR_UINT8 *&graphicsEndingAddress) { - // requesting 2MB - CLR_INT32 graphicsMemoryBlockSize = 2 * 1024 * 1024; + CLR_UINT32 graphicsMemoryBlockSize = requested; CLR_INT32 memoryCaps = MALLOC_CAP_8BIT | MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM; @@ -45,14 +44,15 @@ bool GraphicsMemory::GraphicsHeapLocation( } // We don't want to allocate upfront - if (requested == 0) + if (graphicsMemoryBlockSize == 0) { // We don't allocate anything here return false; } // Get Largest free block in SPIRam - CLR_INT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + CLR_UINT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + if (spiramMaxSize == 0) { // No SPIRAM, try and allocate small block in normal ram to keep allocator happy for @@ -60,14 +60,16 @@ bool GraphicsMemory::GraphicsHeapLocation( // Should be able to use with small screens memoryCaps ^= MALLOC_CAP_SPIRAM; - spiramMaxSize = requested; + spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); } if (spiramMaxSize < graphicsMemoryBlockSize) // limit the size to what is available { graphicsMemoryBlockSize = spiramMaxSize; } + graphicsStartingAddress = (CLR_UINT8 *)heap_caps_malloc(graphicsMemoryBlockSize, memoryCaps); + ASSERT(graphicsStartingAddress != NULL); graphicsEndingAddress = (CLR_UINT8 *)(graphicsStartingAddress + graphicsMemoryBlockSize); diff --git a/targets/ESP32/_IDF/esp32/app_main.c b/targets/ESP32/_IDF/esp32/app_main.c index 7cda78e1ba..b0d2dfc892 100644 --- a/targets/ESP32/_IDF/esp32/app_main.c +++ b/targets/ESP32/_IDF/esp32/app_main.c @@ -60,9 +60,9 @@ void app_main() ESP_ERROR_CHECK(nvs_flash_init()); - // start receiver task pinned to core 1 + // start receiver task pinned to core 0 xTaskCreatePinnedToCore(&receiver_task, "ReceiverThread", 3072, NULL, 5, NULL, 0); - // start the CLR main task pinned to core 0 + // start the CLR main task pinned to core 1 xTaskCreatePinnedToCore(&main_task, "main_task", 15000, NULL, 5, NULL, 1); } diff --git a/targets/ESP32/_IDF/esp32/partitions_nanoclr_16mb.csv b/targets/ESP32/_IDF/esp32/partitions_nanoclr_16mb.csv index 7d9da584dd..eb986550ca 100644 --- a/targets/ESP32/_IDF/esp32/partitions_nanoclr_16mb.csv +++ b/targets/ESP32/_IDF/esp32/partitions_nanoclr_16mb.csv @@ -7,9 +7,9 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, # Factory area for nanoCLR - 1728k -factory, app, factory, 0x10000, 0x1B0000, -# Deployment area for Managed code 2880K, Mapping issues with deployment areas over 3.5Mb, see issue #691 -deploy, data, 0x84, 0x1C0000, 0x2D0000, +factory, app, factory, 0x10000, 0x1C0000, +# Deployment area for Managed code 2816K, Mapping issues with deployment areas over 3.5Mb, see issue #691 +deploy, data, 0x84, 0x1D0000, 0x2C0000, # Config data for Network, Wireless, certificates, user data 3MB config, data, littlefs, 0x490000, 0x300000, ########################################## diff --git a/targets/ESP32/_IDF/esp32/partitions_nanoclr_4mb.csv b/targets/ESP32/_IDF/esp32/partitions_nanoclr_4mb.csv index 1c6f9affe4..6598c849e6 100644 --- a/targets/ESP32/_IDF/esp32/partitions_nanoclr_4mb.csv +++ b/targets/ESP32/_IDF/esp32/partitions_nanoclr_4mb.csv @@ -7,9 +7,9 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, # Factory area for nanoCLR - 1728k -factory, app, factory, 0x10000, 0x1B0000, -# Deployment area for Managed code 1964k -deploy, data, 0x84, 0x1C0000, 0x1E0000, +factory, app, factory, 0x10000, 0x1C0000, +# Deployment area for Managed code 1856k +deploy, data, 0x84, 0x1D0000, 0x1D0000, # Config data for Network, Wireless, certificates, user data 256k config, data, littlefs, 0x3C0000, 0x40000, ################################# diff --git a/targets/ESP32/_IDF/esp32/partitions_nanoclr_8mb.csv b/targets/ESP32/_IDF/esp32/partitions_nanoclr_8mb.csv index 572716a8c9..607a4560bf 100644 --- a/targets/ESP32/_IDF/esp32/partitions_nanoclr_8mb.csv +++ b/targets/ESP32/_IDF/esp32/partitions_nanoclr_8mb.csv @@ -7,9 +7,9 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, # Factory area for nanoCLR - 1728k -factory, app, factory, 0x10000, 0x1B0000, -# Deployment area for Managed code 2880K, Mapping issues with deployment areas over 3.5Mb, see issue #691 -deploy, data, 0x84, 0x1C0000, 0x2D0000, +factory, app, factory, 0x10000, 0x1C0000, +# Deployment area for Managed code 2816K, Mapping issues with deployment areas over 3.5Mb, see issue #691 +deploy, data, 0x84, 0x1D0000, 0x2C0000, # Config data for Network, Wireless, certificates, user data 2Mb config, data, littlefs, 0x490000, 0x200000, ########################################## diff --git a/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_16mb.csv b/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_16mb.csv index 9e3be7e32c..926e81c383 100644 --- a/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_16mb.csv +++ b/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_16mb.csv @@ -7,9 +7,9 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, # Factory area for NanoCLR - 2240k -factory, app, factory, 0x10000, 0x230000, -# Deployment area for Managed code 2368k -deploy, data, 0x84, 0x240000, 0x250000, +factory, app, factory, 0x10000, 0x240000, +# Deployment area for Managed code 2304k +deploy, data, 0x84, 0x250000, 0x240000, # Config data for Network, Wireless, certificates, user data 3MB config, data, littlefs, 0x490000, 0x300000, ########################################## diff --git a/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_4mb.csv b/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_4mb.csv index 535fec9fe1..cb1cd1e423 100644 --- a/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_4mb.csv +++ b/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_4mb.csv @@ -7,9 +7,9 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, # Factory area for nanoCLR - 2240k -factory, app, factory, 0x10000, 0x230000, -# Deployment area for Managed code 1536k -deploy, data, 0x84, 0x240000, 0x180000, +factory, app, factory, 0x10000, 0x240000, +# Deployment area for Managed code 1472k +deploy, data, 0x84, 0x250000, 0x170000, # Config data for Network, Wireless, certificates, user data 256k config, data, littlefs, 0x3C0000, 0x40000, ################################# diff --git a/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_8mb.csv b/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_8mb.csv index 8c042a018e..46c2d65377 100644 --- a/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_8mb.csv +++ b/targets/ESP32/_IDF/esp32c6/partitions_nanoclr_8mb.csv @@ -7,9 +7,9 @@ nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, # Factory area for NanoCLR - 2240k -factory, app, factory, 0x10000, 0x230000, -# Deployment area for Managed code 2368k -deploy, data, 0x84, 0x240000, 0x250000, +factory, app, factory, 0x10000, 0x240000, +# Deployment area for Managed code 2304k +deploy, data, 0x84, 0x250000, 0x240000, # Config data for Network, Wireless, certificates, user data 2Mb config, data, littlefs, 0x490000, 0x200000, ########################################## diff --git a/targets/ESP32/_IDF/esp32p4/app_main.c b/targets/ESP32/_IDF/esp32p4/app_main.c new file mode 100644 index 0000000000..cc26e1adee --- /dev/null +++ b/targets/ESP32/_IDF/esp32p4/app_main.c @@ -0,0 +1,57 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include +#include + +extern void CLRStartupThread(void const *argument); +TaskHandle_t ReceiverTask; + +void receiver_task(void *pvParameter) +{ + (void)pvParameter; + + ReceiverThread(0); + + vTaskDelete(NULL); +} + +// Main task start point +void main_task(void *pvParameter) +{ + (void)pvParameter; + + // CLR settings to launch CLR thread + CLR_SETTINGS clrSettings; + (void)memset(&clrSettings, 0, sizeof(CLR_SETTINGS)); + + clrSettings.MaxContextSwitches = 50; + clrSettings.WaitForDebugger = false; + clrSettings.EnterDebuggerLoopAfterExit = true; + + CLRStartupThread(&clrSettings); + + vTaskDelete(NULL); +} + +// App_main +// Called from Esp32 IDF start up code before scheduler starts +void app_main() +{ + // Switch off logging so as not to interfere with WireProtocol over Uart0 + esp_log_level_set("*", ESP_LOG_NONE); + + ESP_ERROR_CHECK(nvs_flash_init()); + + // start receiver task pinned to core 0 + xTaskCreatePinnedToCore(&receiver_task, "ReceiverThread", 3072, NULL, 5, NULL, 0); + + // start the CLR main task pinned to core 1 + xTaskCreatePinnedToCore(&main_task, "main_task", 15000, NULL, 5, NULL, 1); +} diff --git a/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_16mb.csv b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_16mb.csv new file mode 100644 index 0000000000..9701499b14 --- /dev/null +++ b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_16mb.csv @@ -0,0 +1,18 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for nanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 2944k +deploy, data, 0x84, 0x1B0000, 0x2E0000, +# Config data for Network, Wireless, certificates, user data 3MB +config, data, littlefs, 0x490000, 0x300000, +########################################## +# spare from 0x790000 (8Mb free) # +# total size has to be 0x1000000 or less # +########################################## diff --git a/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_32mb.csv b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_32mb.csv new file mode 100644 index 0000000000..3bd082dbb6 --- /dev/null +++ b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_32mb.csv @@ -0,0 +1,18 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for nanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 2944k +deploy, data, 0x84, 0x1B0000, 0x2E0000, +# Config data for Network, Wireless, certificates, user data 8MB +config, data, littlefs, 0x490000, 0x800000, +########################################## +# spare from 0xC90000 (19Mb free) # +# total size has to be 0x2000000 or less # +########################################## diff --git a/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_4mb.csv b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_4mb.csv new file mode 100644 index 0000000000..6a48cd309e --- /dev/null +++ b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_4mb.csv @@ -0,0 +1,17 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for nanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 1984k +deploy, data, 0x84, 0x1B0000, 0x1F0000, +# Config data for Network, Wireless, certificates, user data 256k +config, data, littlefs, 0x3C0000, 0x40000, +################################# +# total size has to be 0x400000 # +################################# diff --git a/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_8mb.csv b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_8mb.csv new file mode 100644 index 0000000000..ffe2a98d93 --- /dev/null +++ b/targets/ESP32/_IDF/esp32p4/partitions_nanoclr_8mb.csv @@ -0,0 +1,18 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for nanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 2944k +deploy, data, 0x84, 0x1B0000, 0x2E0000, +# Config data for Network, Wireless, certificates, user data 2MB +config, data, littlefs, 0x490000, 0x200000, +########################################## +# spare from 0x690000 (1.4MB free) # +# total size has to be 0x800000 or less # +########################################## diff --git a/targets/ESP32/ESP32_S3/target_windows_storage_config.h b/targets/ESP32/_IDF/project_elf_src_esp32p4.c similarity index 54% rename from targets/ESP32/ESP32_S3/target_windows_storage_config.h rename to targets/ESP32/_IDF/project_elf_src_esp32p4.c index b2d2dec961..c19b2ff9b4 100644 --- a/targets/ESP32/ESP32_S3/target_windows_storage_config.h +++ b/targets/ESP32/_IDF/project_elf_src_esp32p4.c @@ -3,3 +3,6 @@ // See LICENSE file in the project root for full license information. // +/////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE // +/////////////////////////////////// diff --git a/targets/ESP32/_IDF/sdkconfig.default b/targets/ESP32/_IDF/sdkconfig.default index 42ff894764..55a2022c86 100644 --- a/targets/ESP32/_IDF/sdkconfig.default +++ b/targets/ESP32/_IDF/sdkconfig.default @@ -4,7 +4,6 @@ CONFIG_IDF_TARGET="esp32" CONFIG_IDF_TARGET_ESP32=y CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 - CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y diff --git a/targets/ESP32/_IDF/sdkconfig.default.esp32p4 b/targets/ESP32/_IDF/sdkconfig.default.esp32p4 new file mode 100644 index 0000000000..48a1c38ad4 --- /dev/null +++ b/targets/ESP32/_IDF/sdkconfig.default.esp32p4 @@ -0,0 +1,97 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32p4" + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y + +CONFIG_IDF_EXPERIMENTAL_FEATURES=y + +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_200M=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="targets/ESP32/_IDF/${TARGET_SERIES_SHORT}/partitions_nanoclr_4mb.csv" + +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y + +# Bluetooth currently not building with hosted/remote config +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nanoBLE" +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=10 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT=20 + +CONFIG_ADC_SUPPRESS_DEPRECATE_WARN=y +CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN=y + +CONFIG_UART_ISR_IN_IRAM=y + +CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN=y + +CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y + +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y + +CONFIG_ETH_SPI_ETHERNET_DM9051=y +CONFIG_ETH_SPI_ETHERNET_W5500=y +CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y + +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y +CONFIG_PM_ENABLE=y + +CONFIG_ESP_TASK_WDT_INIT=n +CONFIG_FATFS_LFN_HEAP=y + +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=5 +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y + +#### Add Wi-Fi Remote config for better performance: +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=16 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=64 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=64 +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=32 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=32 + +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=65534 +CONFIG_LWIP_TCP_WND_DEFAULT=65534 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=64 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=64 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64 + +CONFIG_LWIP_TCP_SACK_OUT=y + +CONFIG_LWIP_LOCAL_HOSTNAME="nanodevice" +CONFIG_LWIP_MAX_SOCKETS=16 +CONFIG_LWIP_SO_LINGER=y +CONFIG_LWIP_SO_RCVBUF=y +CONFIG_LWIP_DHCP_OPTIONS_LEN=80 +CONFIG_LWIP_DHCPS=n +CONFIG_LWIP_MAX_LISTENING_TCP=8 +CONFIG_LWIP_SNTP_MAX_SERVERS=2 + +CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y +CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_HAVE_TIME_DATE=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_DES_C=y +CONFIG_MBEDTLS_XTEA_C=n +CONFIG_MBEDTLS_PEM_WRITE_C=n +CONFIG_MBEDTLS_X509_CSR_PARSE_C=n +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y + +CONFIG_LITTLEFS_MAX_PARTITIONS=1 +CONFIG_LITTLEFS_OBJ_NAME_LEN=256 +CONFIG_LITTLEFS_OPEN_DIR=y +CONFIG_LITTLEFS_FCNTL_GET_PATH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default.esp32s2 b/targets/ESP32/_IDF/sdkconfig.default.esp32s2 index 9dc929efa0..b2dcb86732 100644 --- a/targets/ESP32/_IDF/sdkconfig.default.esp32s2 +++ b/targets/ESP32/_IDF/sdkconfig.default.esp32s2 @@ -1,1804 +1,77 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration # CONFIG_IDF_CMAKE=y CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET_ARCH="xtensa" CONFIG_IDF_TARGET="esp32s2" -CONFIG_IDF_TARGET_ESP32S2=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0002 - -CONFIG_SOC_ADC_SUPPORTED=y -CONFIG_SOC_DAC_SUPPORTED=y -CONFIG_SOC_UART_SUPPORTED=y -CONFIG_SOC_TWAI_SUPPORTED=y -CONFIG_SOC_CP_DMA_SUPPORTED=y -CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y -CONFIG_SOC_GPTIMER_SUPPORTED=y -CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y -CONFIG_SOC_ULP_FSM_SUPPORTED=y -CONFIG_SOC_RISCV_COPROC_SUPPORTED=y -CONFIG_SOC_USB_OTG_SUPPORTED=y -CONFIG_SOC_PCNT_SUPPORTED=y -CONFIG_SOC_WIFI_SUPPORTED=y -CONFIG_SOC_ULP_SUPPORTED=y -CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y -CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y -CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD=y -CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y -CONFIG_SOC_CACHE_SUPPORT_WRAP=y -CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y -CONFIG_SOC_RTC_MEM_SUPPORTED=y -CONFIG_SOC_PSRAM_DMA_CAPABLE=y -CONFIG_SOC_XT_WDT_SUPPORTED=y -CONFIG_SOC_I2S_SUPPORTED=y -CONFIG_SOC_RMT_SUPPORTED=y -CONFIG_SOC_SDM_SUPPORTED=y -CONFIG_SOC_GPSPI_SUPPORTED=y -CONFIG_SOC_LEDC_SUPPORTED=y -CONFIG_SOC_I2C_SUPPORTED=y -CONFIG_SOC_SYSTIMER_SUPPORTED=y -CONFIG_SOC_AES_SUPPORTED=y -CONFIG_SOC_MPI_SUPPORTED=y -CONFIG_SOC_SHA_SUPPORTED=y -CONFIG_SOC_HMAC_SUPPORTED=y -CONFIG_SOC_DIG_SIGN_SUPPORTED=y -CONFIG_SOC_FLASH_ENC_SUPPORTED=y -CONFIG_SOC_SECURE_BOOT_SUPPORTED=y -CONFIG_SOC_MEMPROT_SUPPORTED=y -CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y -CONFIG_SOC_BOD_SUPPORTED=y -CONFIG_SOC_XTAL_SUPPORT_40M=y -CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y -CONFIG_SOC_ADC_ARBITER_SUPPORTED=y -CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y -CONFIG_SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED=y -CONFIG_SOC_ADC_MONITOR_SUPPORTED=y -CONFIG_SOC_ADC_DMA_SUPPORTED=y -CONFIG_SOC_ADC_PERIPH_NUM=2 -CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 -CONFIG_SOC_ADC_ATTEN_NUM=4 -CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 -CONFIG_SOC_ADC_PATT_LEN_MAX=32 -CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12 -CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 -CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2 -CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 -CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=2 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333 -CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611 -CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=13 -CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=13 -CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y -CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y -CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y -CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y -CONFIG_SOC_CP_DMA_MAX_BUFFER_SIZE=4095 -CONFIG_SOC_CPU_CORES_NUM=1 -CONFIG_SOC_CPU_INTR_NUM=32 -CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 -CONFIG_SOC_CPU_WATCHPOINT_SIZE=64 -CONFIG_SOC_DAC_CHAN_NUM=2 -CONFIG_SOC_DAC_RESOLUTION=8 -CONFIG_SOC_GPIO_PORT=1 -CONFIG_SOC_GPIO_PIN_COUNT=47 -CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y -CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y -CONFIG_SOC_GPIO_SUPPORT_RTC_INDEPENDENT=y -CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y -CONFIG_SOC_GPIO_VALID_GPIO_MASK=0x7FFFFFFFFFFF -CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00007FFFFC000000 -CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 -CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 -CONFIG_SOC_DEDIC_GPIO_ALLOW_REG_ACCESS=y -CONFIG_SOC_DEDIC_GPIO_HAS_INTERRUPT=y -CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y -CONFIG_SOC_I2C_NUM=2 -CONFIG_SOC_I2C_FIFO_LEN=32 -CONFIG_SOC_I2C_CMD_REG_NUM=16 -CONFIG_SOC_I2C_SUPPORT_SLAVE=y -CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y -CONFIG_SOC_I2C_SUPPORT_REF_TICK=y -CONFIG_SOC_I2C_SUPPORT_APB=y -CONFIG_SOC_I2S_NUM=1 -CONFIG_SOC_I2S_HW_VERSION_1=y -CONFIG_SOC_I2S_SUPPORTS_APLL=y -CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y -CONFIG_SOC_I2S_SUPPORTS_DMA_EQUAL=y -CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y -CONFIG_SOC_I2S_APLL_MIN_FREQ=250000000 -CONFIG_SOC_I2S_APLL_MAX_FREQ=500000000 -CONFIG_SOC_I2S_APLL_MIN_RATE=10675 -CONFIG_SOC_I2S_LCD_I80_VARIANT=y -CONFIG_SOC_LCD_I80_SUPPORTED=y -CONFIG_SOC_LCD_I80_BUSES=1 -CONFIG_SOC_LCD_I80_BUS_WIDTH=24 -CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y -CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y -CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y -CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y -CONFIG_SOC_LEDC_CHANNEL_NUM=8 -CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 -CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y -CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=5 -CONFIG_SOC_MMU_PERIPH_NUM=1 -CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 -CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 -CONFIG_SOC_PCNT_GROUPS=1 -CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 -CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 -CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 -CONFIG_SOC_RMT_GROUPS=1 -CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=4 -CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=4 -CONFIG_SOC_RMT_CHANNELS_PER_GROUP=4 -CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 -CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y -CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y -CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y -CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y -CONFIG_SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY=y -CONFIG_SOC_RMT_SUPPORT_REF_TICK=y -CONFIG_SOC_RMT_SUPPORT_APB=y -CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y -CONFIG_SOC_RTCIO_PIN_COUNT=22 -CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y -CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y -CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y -CONFIG_SOC_SDM_GROUPS=1 -CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 -CONFIG_SOC_SDM_CLK_SUPPORT_APB=y -CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y -CONFIG_SOC_SPI_PERIPH_NUM=3 -CONFIG_SOC_SPI_DMA_CHAN_NUM=3 -CONFIG_SOC_SPI_MAX_CS_NUM=6 -CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=72 -CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 -CONFIG_SOC_SPI_SUPPORT_DDRCLK=y -CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y -CONFIG_SOC_SPI_SUPPORT_CD_SIG=y -CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y -CONFIG_SOC_SPI_SUPPORT_CLK_APB=y -CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y -CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y -CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y -CONFIG_SOC_SPI_SUPPORT_OCT=y -CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y -CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y -CONFIG_SOC_SYSTIMER_COUNTER_NUM=y -CONFIG_SOC_SYSTIMER_ALARM_NUM=3 -CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32 -CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=32 -CONFIG_SOC_TIMER_GROUPS=2 -CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 -CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 -CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y -CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y -CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 -CONFIG_SOC_TOUCH_VERSION_2=y -CONFIG_SOC_TOUCH_SENSOR_NUM=15 -CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 -CONFIG_SOC_TOUCH_PAD_THRESHOLD_MAX=0x1FFFFF -CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF -CONFIG_SOC_TWAI_CONTROLLER_NUM=1 -CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y -CONFIG_SOC_TWAI_BRP_MIN=2 -CONFIG_SOC_TWAI_BRP_MAX=32768 -CONFIG_SOC_TWAI_SUPPORTS_RX_STATUS=y -CONFIG_SOC_UART_NUM=2 -CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y -CONFIG_SOC_UART_SUPPORT_APB_CLK=y -CONFIG_SOC_UART_SUPPORT_REF_TICK=y -CONFIG_SOC_UART_FIFO_LEN=128 -CONFIG_SOC_UART_BITRATE_MAX=5000000 -CONFIG_SOC_SPIRAM_SUPPORTED=y -CONFIG_SOC_SPIRAM_XIP_SUPPORTED=y -CONFIG_SOC_USB_PERIPH_NUM=y -CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 -CONFIG_SOC_SHA_SUPPORT_DMA=y -CONFIG_SOC_SHA_SUPPORT_RESUME=y -CONFIG_SOC_SHA_CRYPTO_DMA=y -CONFIG_SOC_SHA_SUPPORT_SHA1=y -CONFIG_SOC_SHA_SUPPORT_SHA224=y -CONFIG_SOC_SHA_SUPPORT_SHA256=y -CONFIG_SOC_SHA_SUPPORT_SHA384=y -CONFIG_SOC_SHA_SUPPORT_SHA512=y -CONFIG_SOC_SHA_SUPPORT_SHA512_224=y -CONFIG_SOC_SHA_SUPPORT_SHA512_256=y -CONFIG_SOC_SHA_SUPPORT_SHA512_T=y -CONFIG_SOC_RSA_MAX_BIT_LEN=4096 -CONFIG_SOC_AES_SUPPORT_DMA=y -CONFIG_SOC_AES_SUPPORT_GCM=y -CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y -CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y -CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y -CONFIG_SOC_EFUSE_SOFT_DIS_JTAG=y -CONFIG_SOC_EFUSE_DIS_BOOT_REMAP=y -CONFIG_SOC_EFUSE_DIS_LEGACY_SPI_BOOT=y -CONFIG_SOC_EFUSE_DIS_ICACHE=y -CONFIG_SOC_SECURE_BOOT_V2_RSA=y -CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=3 -CONFIG_SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS=y -CONFIG_SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY=y -CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=64 -CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y -CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y -CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y -CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_256=y -CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 -CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE=4 -CONFIG_SOC_AES_CRYPTO_DMA=y -CONFIG_SOC_AES_SUPPORT_AES_128=y -CONFIG_SOC_AES_SUPPORT_AES_192=y -CONFIG_SOC_AES_SUPPORT_AES_256=y -CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 -CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12 -CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y -CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND=y -CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y -CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y -CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y -CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y -CONFIG_SOC_PM_SUPPORT_WIFI_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y -CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y -CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y -CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y -CONFIG_SOC_CLK_APLL_SUPPORTED=y -CONFIG_SOC_APLL_MULTIPLIER_OUT_MIN_HZ=350000000 -CONFIG_SOC_APLL_MULTIPLIER_OUT_MAX_HZ=500000000 -CONFIG_SOC_APLL_MIN_HZ=5303031 -CONFIG_SOC_APLL_MAX_HZ=125000000 -CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y -CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y -CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y -CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y -CONFIG_SOC_COEX_HW_PTI=y -CONFIG_SOC_EXTERNAL_COEX_LEADER_TX_LINE=y -CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC=y -CONFIG_SOC_WIFI_HW_TSF=y -CONFIG_SOC_WIFI_FTM_SUPPORT=y -CONFIG_SOC_WIFI_WAPI_SUPPORT=y -CONFIG_SOC_WIFI_CSI_SUPPORT=y -CONFIG_SOC_WIFI_MESH_SUPPORT=y -CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y -CONFIG_SOC_WIFI_NAN_SUPPORT=y -CONFIG_SOC_ULP_HAS_ADC=y - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# CONFIG_APP_REPRODUCIBLE_BUILD is not set -# CONFIG_APP_NO_BLOBS is not set -# end of Build type - -# -# Bootloader config -# -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=3 -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y -CONFIG_SECURE_BOOT_V2_PREFERRED=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -CONFIG_SECURE_ROM_DL_MODE_ENABLED=y -# end of Security features -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 -# end of Application manager - -CONFIG_ESP_ROM_HAS_CRC_LE=y -CONFIG_ESP_ROM_HAS_MZ_CRC32=y -CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y -CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y -CONFIG_ESP_ROM_HAS_REGI2C_BUG=y -CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y -CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y - -# -# Boot ROM Behavior -# -CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y -# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set -# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set -# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set -# end of Boot ROM Behavior +# Deprecated drivers, disable warnings on build +CONFIG_ADC_SUPPRESS_DEPRECATE_WARN=y +CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN=y +CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN=y +CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y -# -# Serial flasher config -# -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y -CONFIG_ESPTOOLPY_FLASHFREQ="80m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="4MB" CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config -# -# Partition Table -# -# CONFIG_PARTITION_TABLE_SINGLE_APP is not set -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="targets/ESP32/_IDF/${TARGET_SERIES_SHORT}/partitions_nanoclr_4mb.csv" -CONFIG_PARTITION_TABLE_FILENAME="targets/ESP32/_IDF/${TARGET_SERIES_SHORT}/partitions_nanoclr_4mb.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="targets/ESP32/_IDF/esp32s3/partitions_nanoclr_4mb.csv" -# -# Compiler options -# -# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set CONFIG_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y -CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=0 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -# CONFIG_APPTRACE_DEST_UART1 is not set -CONFIG_APPTRACE_DEST_UART_NONE=y -CONFIG_APPTRACE_UART_TASK_PRIO=1 -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# Driver Configurations -# - -# -# Legacy ADC Configuration -# -CONFIG_ADC_DISABLE_DAC=y -CONFIG_ADC_SUPPRESS_DEPRECATE_WARN=y - -# -# Legacy ADC Calibration Configuration -# -CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN=y -# end of Legacy ADC Calibration Configuration -# end of Legacy ADC Configuration - -# -# SPI Configuration -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of SPI Configuration -# -# TWAI Configuration -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y -# end of TWAI Configuration - -# -# Temperature sensor Configuration -# -# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set -# end of Temperature sensor Configuration - -# -# UART Configuration -# CONFIG_UART_ISR_IN_IRAM=y -# end of UART Configuration - -# -# GPIO Configuration -# -# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set -# end of GPIO Configuration - -# -# Sigma Delta Modulator Configuration -# -# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set -# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_SDM_ENABLE_DEBUG_LOG is not set -# end of Sigma Delta Modulator Configuration - -# -# GPTimer Configuration -# -# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set -# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set -# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set -# end of GPTimer Configuration - -# -# PCNT Configuration -# -# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_PCNT_ISR_IRAM_SAFE is not set -CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN=y -# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set -# end of PCNT Configuration - -# -# RMT Configuration -# -# CONFIG_RMT_ISR_IRAM_SAFE is not set -CONFIG_RMT_SUPPRESS_DEPRECATE_WARN=y -# CONFIG_RMT_ENABLE_DEBUG_LOG is not set -# end of RMT Configuration - -# -# I2S Configuration -# -# CONFIG_I2S_ISR_IRAM_SAFE is not set -CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y -# CONFIG_I2S_ENABLE_DEBUG_LOG is not set -# end of I2S Configuration -# -# DAC Configuration -# -# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set -# CONFIG_DAC_ISR_IRAM_SAFE is not set -CONFIG_DAC_SUPPRESS_DEPRECATE_WARN=y -# CONFIG_DAC_ENABLE_DEBUG_LOG is not set -# end of DAC Configuration -# end of Driver Configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -CONFIG_EFUSE_MAX_BLK_LEN=256 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y -# CONFIG_ESP_TLS_SERVER is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -# end of ESP-TLS - -# -# ADC and ADC Calibration -# -# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set -# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set -CONFIG_ADC_DISABLE_DAC_OUTPUT=y -# end of ADC and ADC Calibration - -# -# Wireless Coexistence -# -# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set -# end of Wireless Coexistence - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# Ethernet -# -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_SPI_ETHERNET=y -CONFIG_ETH_SPI_ETHERNET_DM9051=y -CONFIG_ETH_SPI_ETHERNET_W5500=y -CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y -# CONFIG_ETH_USE_OPENETH is not set -# CONFIG_ETH_TRANSMIT_MUTEX is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -# end of GDB Stub - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set -# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# Chip revision -# -CONFIG_ESP32S2_REV_MIN_0=y -# CONFIG_ESP32S2_REV_MIN_1 is not set -CONFIG_ESP32S2_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 - -# -# Maximum Supported ESP32-S2 Revision (Rev v1.99) -# -CONFIG_ESP32S2_REV_MAX_FULL=199 -CONFIG_ESP_REV_MAX_FULL=199 -# end of Chip revision - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO=y -# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set -CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y -CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 -# end of MAC Config - -# -# Sleep Config -# -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y -# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLK_SRC_INT_RC=y -# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_RTC_CLK_CAL_CYCLES=576 -# end of RTC Clock Config - -# -# Peripheral Control -# -CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y -# end of Peripheral Control - -# -# Main XTAL Config -# -CONFIG_XTAL_FREQ_40=y -CONFIG_XTAL_FREQ=40 -# end of Main XTAL Config -# end of Hardware Settings - -# -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration -# -CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 -# CONFIG_LCD_ENABLE_DEBUG_LOG is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y -# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set -# CONFIG_ESP_NETIF_L2_TAP is not set -# CONFIG_ESP_NETIF_BRIDGE_EN is not set -# end of ESP NETIF Adapter - -# -# Partition API Configuration -# -# end of Partition API Configuration - -# -# PHY -# -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -# CONFIG_ESP_PHY_ENABLE_USB is not set -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# end of PHY - -# -# Power Management -# CONFIG_PM_ENABLE=y -# CONFIG_PM_DFS_INIT_AUTO is not set -# CONFIG_PM_PROFILING is not set -# CONFIG_PM_TRACE is not set -# CONFIG_PM_SLP_IRAM_OPT is not set -# CONFIG_PM_RTOS_IDLE_OPT is not set -# CONFIG_PM_SLP_DISABLE_GPIO is not set -# end of Power Management -# -# ESP PSRAM -# CONFIG_SPIRAM=y - -# -# SPI RAM config -# -CONFIG_SPIRAM_MODE_QUAD=y -CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -# CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set -CONFIG_SPIRAM_CLK_IO=30 -CONFIG_SPIRAM_CS_IO=26 -# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set -# CONFIG_SPIRAM_RODATA is not set -# CONFIG_SPIRAM_SPEED_80M is not set -CONFIG_SPIRAM_SPEED_40M=y -# CONFIG_SPIRAM_SPEED_26M is not set -# CONFIG_SPIRAM_SPEED_20M is not set -CONFIG_SPIRAM_SPEED=40 CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_IGNORE_NOTFOUND=y -# CONFIG_SPIRAM_USE_MEMMAP is not set -# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set -CONFIG_SPIRAM_USE_MALLOC=y -# CONFIG_SPIRAM_MEMTEST is not set -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 -CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 -# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set -# end of SPI RAM config -# end of ESP PSRAM +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_TYPE_AUTO=y -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf -# -# ESP System Settings -# -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set -# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y -CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 - -# -# Cache config -# -CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y -# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set -# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set -CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y -CONFIG_ESP32S2_DATA_CACHE_8KB=y -# CONFIG_ESP32S2_DATA_CACHE_16KB is not set -# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set -CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y -# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set -# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set -# end of Cache config - -# -# Memory -# -# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set -# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set -# end of Memory - -# -# Trace memory -# -# CONFIG_ESP32S2_TRAX is not set -CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 -# end of Trace memory - -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 -CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y -CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y -CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y - -# -# Memory protection -# -CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y -CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y -# end of Memory protection -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_USB_CDC is not set -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_MULTIPLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_TASK_WDT_EN=y -# CONFIG_ESP_TASK_WDT_INIT is not set -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP_DEBUG_OCDAWARE=y -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y +CONFIG_ESP_TASK_WDT_INIT=n -# -# Brownout Detector -# -CONFIG_ESP_BROWNOUT_DET=y -CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_ESP_BROWNOUT_DET_LVL=7 -# end of Brownout Detector - -# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set -CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y -# end of ESP System Settings - -# -# IPC (Inter-Processor Call) -# CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 -# end of IPC (Inter-Processor Call) -# -# High resolution timer (esp_timer) -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set -CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 -CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y -CONFIG_ESP_TIMER_ISR_AFFINITY=0x1 -CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_SYSTIMER=y -# end of High resolution timer (esp_timer) - -# -# Wi-Fi -# -CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y -CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 -CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 -# CONFIG_ESP_WIFI_CSI_ENABLED is not set -CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP_WIFI_TX_BA_WIN=6 -CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=6 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set -CONFIG_ESP_WIFI_NVS_ENABLED=y -CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP_WIFI_IRAM_OPT=y -CONFIG_ESP_WIFI_RX_IRAM_OPT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP_WIFI_ENABLE_SAE_PK=y -CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y -CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -# CONFIG_ESP_WIFI_FTM_ENABLE is not set -# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set -# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# CONFIG_ESP_WIFI_NAN_ENABLE is not set -CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y -CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y -# CONFIG_ESP_WIFI_WAPI_PSK is not set -# CONFIG_ESP_WIFI_SUITE_B_192 is not set -# CONFIG_ESP_WIFI_11KV_SUPPORT is not set -# CONFIG_ESP_WIFI_MBO_SUPPORT is not set -# CONFIG_ESP_WIFI_DPP_SUPPORT is not set -# CONFIG_ESP_WIFI_11R_SUPPORT is not set -# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set -# -# WPS Configuration Options -# -# CONFIG_ESP_WIFI_WPS_STRICT is not set -# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set -# end of WPS Configuration Options - -# CONFIG_ESP_WIFI_DEBUG_PRINT is not set -# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set -# end of Wi-Fi - -# -# Core dump -# -# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -CONFIG_FATFS_VOLUME_COUNT=2 -# CONFIG_FATFS_LFN_NONE is not set CONFIG_FATFS_LFN_HEAP=y -# CONFIG_FATFS_LFN_STACK is not set -# CONFIG_FATFS_SECTOR_512 is not set -CONFIG_FATFS_SECTOR_4096=y -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_MAX_LFN=255 -CONFIG_FATFS_API_ENCODING_ANSI_OEM=y -# CONFIG_FATFS_API_ENCODING_UTF_8 is not set -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y -# CONFIG_FATFS_USE_FASTSEEK is not set -CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 -# end of FAT Filesystem support - -# -# FreeRTOS -# -# -# Kernel -# -# CONFIG_FREERTOS_SMP is not set -CONFIG_FREERTOS_UNICORE=y -CONFIG_FREERTOS_HZ=100 -CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 -# CONFIG_FREERTOS_USE_IDLE_HOOK is not set -# CONFIG_FREERTOS_USE_TICK_HOOK is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set CONFIG_FREERTOS_TIMER_TASK_PRIORITY=5 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set CONFIG_FREERTOS_USE_TICKLESS_IDLE=y -CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=3 -# end of Kernel - -# -# Port -# -# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set -CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y -CONFIG_FREERTOS_CORETIMER_0=y -# CONFIG_FREERTOS_CORETIMER_1 is not set -CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -# end of Port - -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=0 -CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y -CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -# CONFIG_HEAP_POISONING_LIGHT is not set -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_USE_HOOKS is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set -# end of Heap memory debugging - -CONFIG_IEEE802154_CCA_THRESHOLD=-60 -CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 -# -# Log output -# -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_LOG_DEFAULT_LEVEL_INFO=y -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=3 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=3 -CONFIG_LOG_COLORS=y -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output +CONFIG_LOG_DEFAULT_LEVEL_NONE=y -# -# LWIP -# CONFIG_LWIP_LOCAL_HOSTNAME="nanodevice" -# CONFIG_LWIP_NETIF_API is not set -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y CONFIG_LWIP_MAX_SOCKETS=16 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set CONFIG_LWIP_SO_LINGER=y -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y CONFIG_LWIP_SO_RCVBUF=y -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP4_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set CONFIG_LWIP_DHCP_OPTIONS_LEN=80 -CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -# CONFIG_LWIP_DHCPS is not set -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV4=y -# CONFIG_LWIP_IPV6 is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_DHCPS=n +CONFIG_LWIP_IPV6=n CONFIG_LWIP_MAX_LISTENING_TCP=8 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 -CONFIG_LWIP_TCP_WND_DEFAULT=5744 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -# CONFIG_LWIP_TCP_SACK_OUT is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# CONFIG_LWIP_WND_SCALE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_LWIP_PPP_SUPPORT is not set -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# CONFIG_LWIP_SNTP_MAX_SERVERS=2 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -# end of SNTP - -CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP -# -# mbedTLS -# -# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set -# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v3.x related -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set -CONFIG_MBEDTLS_PKCS7_C=y - -# -# DTLS-based configurations -# -# CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID is not set -# CONFIG_MBEDTLS_SSL_DTLS_SRTP is not set -# end of DTLS-based configurations -# end of mbedTLS v3.x related - -# -# Certificate Bundle -# -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set -# end of Certificate Bundle - -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -CONFIG_MBEDTLS_CMAC_C=y -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_AES_USE_INTERRUPT=y -CONFIG_MBEDTLS_HARDWARE_GCM=y -CONFIG_MBEDTLS_HARDWARE_MPI=y -CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n CONFIG_MBEDTLS_HAVE_TIME_DATE=y -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA512_C=y -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -# CONFIG_MBEDTLS_PSK_MODES is not set -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y CONFIG_MBEDTLS_SSL_PROTO_DTLS=y -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_DES_C=y +CONFIG_MBEDTLS_XTEA_C=n +CONFIG_MBEDTLS_PEM_WRITE_C=n CONFIG_MBEDTLS_X509_CSR_PARSE_C=n CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -CONFIG_MBEDTLS_DES_C=y -# CONFIG_MBEDTLS_BLOWFISH_C is not set -CONFIG_MBEDTLS_XTEA_C=n -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -# CONFIG_MBEDTLS_PEM_WRITE_C is not set -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -# CONFIG_MBEDTLS_DHM_C is not set -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set -# CONFIG_MBEDTLS_SECURITY_RISKS is not set -# end of mbedTLS - -# -# ESP-MQTT Configurations -# -CONFIG_MQTT_PROTOCOL_311=y -# CONFIG_MQTT_PROTOCOL_5 is not set -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -# CONFIG_NEWLIB_NANO_FORMAT is not set -CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y -# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set -# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set -# end of Newlib - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# end of NVS - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set - -# -# Thread Operational Dataset -# -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" -CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 -CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" -CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" -CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" -# end of Thread Operational Dataset -# end of OpenThread - -# -# Protocomm -# -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y -CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y -# end of Protocomm - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# MMU Config -# -CONFIG_MMU_PAGE_SIZE_64KB=y -CONFIG_MMU_PAGE_MODE="64KB" -CONFIG_MMU_PAGE_SIZE=0x10000 -# end of MMU Config - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# SPI Flash behavior when brownout -# -CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y -CONFIG_SPI_FLASH_BROWNOUT_RESET=y -# end of SPI Flash behavior when brownout - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y -CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# CONFIG_WS_DYNAMIC_BUFFER is not set -# end of Websocket -# end of TCP Transport - -# -# Ultra Low Power (ULP) Co-processor -# -# CONFIG_ULP_COPROC_ENABLED is not set -# end of Ultra Low Power (ULP) Co-processor - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# USB-OTG -# -CONFIG_USB_OTG_SUPPORTED=y -CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 -CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y -# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set -# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set - -# -# Root Hub configuration -# -CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 -CONFIG_USB_HOST_RESET_HOLD_MS=30 -CONFIG_USB_HOST_RESET_RECOVERY_MS=30 -CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 -# end of Root Hub configuration -# end of USB-OTG - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_VFS_SUPPORT_TERMIOS=y -CONFIG_VFS_MAX_COUNT=8 - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y -# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set -# end of Wi-Fi Provisioning Manager -# end of Component config - -# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set - -# Deprecated options for backward compatibility -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -# CONFIG_NO_BLOBS is not set -# CONFIG_ESP32S2_NO_BLOBS is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y -# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=3 -# CONFIG_APP_ROLLBACK_ENABLE is not set -# CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set -# CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y -# CONFIG_FLASHMODE_DOUT is not set -CONFIG_MONITOR_BAUD=115200 -# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set -CONFIG_OPTIMIZATION_LEVEL_RELEASE=y -CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y -# CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED is not set -# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set -CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED=y -CONFIG_OPTIMIZATION_ASSERTION_LEVEL=0 -# CONFIG_CXX_EXCEPTIONS is not set -CONFIG_STACK_CHECK_NONE=y -# CONFIG_STACK_CHECK_NORM is not set -# CONFIG_STACK_CHECK_STRONG is not set -# CONFIG_STACK_CHECK_ALL is not set -# CONFIG_WARN_WRITE_STRINGS is not set -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -CONFIG_ADC2_DISABLE_DAC=y -# CONFIG_EXTERNAL_COEX_ENABLE is not set -# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -# CONFIG_OTA_ALLOW_HTTP is not set -CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# CONFIG_REDUCE_PHY_TX_POWER is not set -# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -CONFIG_ESP32S2_SPIRAM_SUPPORT=y -CONFIG_DEFAULT_PSRAM_CLK_IO=30 -CONFIG_DEFAULT_PSRAM_CS_IO=26 -# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80 is not set -# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_160 is not set -CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240=y -CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=240 -# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set -CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32S2_PANIC_GDBSTUB is not set -CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y -CONFIG_ESP32S2_MEMPROT_FEATURE=y -CONFIG_ESP32S2_MEMPROT_FEATURE_LOCK=y -CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y -# CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_CONSOLE_UART_NONE is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 -# CONFIG_TASK_WDT is not set -# CONFIG_ESP_TASK_WDT is not set -# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP32S2_DEBUG_OCDAWARE=y -CONFIG_BROWNOUT_DET=y -CONFIG_ESP32S2_BROWNOUT_DET=y -CONFIG_ESP32S2_BROWNOUT_DET=y -CONFIG_BROWNOUT_DET_LVL_SEL_7=y -CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_BROWNOUT_DET_LVL=7 -CONFIG_ESP32S2_BROWNOUT_DET_LVL=7 -CONFIG_IPC_TASK_STACK_SIZE=1024 -CONFIG_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP32_WIFI_ENABLED=y -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y -CONFIG_WPA_MBEDTLS_CRYPTO=y -CONFIG_WPA_MBEDTLS_TLS_CLIENT=y -# CONFIG_WPA_WAPI_PSK is not set -# CONFIG_WPA_SUITE_B_192 is not set -# CONFIG_WPA_11KV_SUPPORT is not set -# CONFIG_WPA_MBO_SUPPORT is not set -# CONFIG_WPA_DPP_SUPPORT is not set -# CONFIG_WPA_11R_SUPPORT is not set -# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set -# CONFIG_WPA_WPS_STRICT is not set -# CONFIG_WPA_DEBUG_PRINT is not set -# CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -CONFIG_TIMER_TASK_PRIORITY=5 -CONFIG_TIMER_TASK_STACK_DEPTH=2048 -CONFIG_TIMER_QUEUE_LENGTH=10 -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -# CONFIG_L2_TO_L3_COPY is not set -CONFIG_ESP_GRATUITOUS_ARP=y -CONFIG_GARP_TMR_INTERVAL=60 -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=12 -CONFIG_TCP_MSS=1440 -CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5744 -CONFIG_TCP_WND_DEFAULT=5744 -CONFIG_TCP_RECVMBOX_SIZE=6 -CONFIG_TCP_QUEUE_OOSEQ=y -CONFIG_TCP_OVERSIZE_MSS=y -# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_TCP_OVERSIZE_DISABLE is not set -CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_PPP_SUPPORT is not set -CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_SYSTIMER=y -CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32S2_TIME_SYSCALL_USE_SYSTIMER is not set -# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_ESP32_PTHREAD_STACK_MIN=768 -CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_ESP32S2_ULP_COPROC_ENABLED is not set -CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options - CONFIG_LITTLEFS_MAX_PARTITIONS=1 CONFIG_LITTLEFS_OBJ_NAME_LEN=256 CONFIG_LITTLEFS_OPEN_DIR=y diff --git a/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp b/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp index b16214fab7..508ec086a0 100644 --- a/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp +++ b/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp @@ -29,15 +29,68 @@ esp_eth_handle_t eth_handle = NULL; #define ETH_PHY_ADDR 0 #endif -#ifndef ETH_MDC_GPIO -// GPIO number used by SMI MDC -#define ETH_MDC_GPIO 23 -#endif +#if CONFIG_IDF_TARGET_ESP32 +#define NANO_ETH_ESP32_EMAC_DEFAULT_CONFIG() \ + { \ + .smi_gpio = \ + { \ + .mdc_num = 23, \ + .mdio_num = 18 \ + }, \ + .interface = EMAC_DATA_INTERFACE_RMII, \ + .clock_config = \ + { \ + .rmii = \ + { \ + .clock_mode = DEFAULT_RMII_CLK_MODE, \ + .clock_gpio = (emac_rmii_clock_gpio_t)DEFAULT_RMII_CLK_GPIO \ + } \ + }, \ + .dma_burst_len = ETH_DMA_BURST_LEN_32, \ + .intr_priority = 0, \ + } +#elif CONFIG_IDF_TARGET_ESP32P4 +#define NANO_ETH_ESP32_EMAC_DEFAULT_CONFIG() \ + { \ + .smi_gpio = \ + { \ + .mdc_num = 31, \ + .mdio_num = 27 \ + }, \ + .interface = EMAC_DATA_INTERFACE_RMII, \ + .clock_config = \ + { \ + .rmii = \ + { \ + .clock_mode = EMAC_CLK_EXT_IN, \ + .clock_gpio = 50 \ + } \ + }, \ + .dma_burst_len = ETH_DMA_BURST_LEN_32, \ + .intr_priority = 0, \ + .emac_dataif_gpio = \ + { \ + .rmii = \ + { \ + .tx_en_num = 49, \ + .txd0_num = 34, \ + .txd1_num = 35, \ + .crs_dv_num = 28, \ + .rxd0_num = 29, \ + .rxd1_num = 30 \ + } \ + }, \ + .clock_config_out_in = \ + { \ + .rmii = \ + { \ + .clock_mode = EMAC_CLK_EXT_IN, \ + .clock_gpio = -1 \ + } \ + }, \ + } +#endif // CONFIG_IDF_TARGET_ESP32P4 -#ifndef ETH_MDIO_GPIO -// GPIO number used by SMI MDIO -#define ETH_MDIO_GPIO 18 -#endif esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) { @@ -55,7 +108,7 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) // now MAC and PHY configs eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); - eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); + eth_esp32_emac_config_t esp32_emac_config = NANO_ETH_ESP32_EMAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); phy_config.phy_addr = ETH_PHY_ADDR; @@ -87,32 +140,50 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) CPU_GPIO_ReservePin(EMAC_CLK_OUT, true); // REF_CLK OUT CPU_GPIO_ReservePin(ETH_RMII_CLK_OUT_GPIO, true); // REF_CLK OUT #else - esp32_emac_config.clock_config.rmii.clock_mode = EMAC_CLK_EXT_IN; - esp32_emac_config.clock_config.rmii.clock_gpio = EMAC_CLK_IN_GPIO; // always 0 - ESP_LOGI(TAG, "Ethernet clock_config IN gpio 0\n"); + ESP_LOGI(TAG, "Ethernet clock_config IN gpio %d\n", esp32_emac_config.clock_config.rmii.clock_gpio); CPU_GPIO_ReservePin(EMAC_CLK_EXT_IN, true); // REF_CLK EXT - CPU_GPIO_ReservePin(EMAC_CLK_IN_GPIO, true); // REF_CLK IN + CPU_GPIO_ReservePin(esp32_emac_config.clock_config.rmii.clock_gpio, true); // REF_CLK IN #endif - esp32_emac_config.smi_mdc_gpio_num = ETH_MDC_GPIO; - esp32_emac_config.smi_mdio_gpio_num = ETH_MDIO_GPIO; - esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); +// If ETH_MDC_GPIO or ETH_MDIO_GPIO defined then use new values +#ifdef ETH_MDC_GPIO + esp32_emac_config.smi_gpio.mdc_num = ETH_MDC_GPIO; +#endif - ESP_LOGI(TAG, "Ethernet mdio %d mdc %d\n", ETH_MDIO_GPIO, ETH_MDC_GPIO); +#ifdef ETH_MDIO_GPIO + esp32_emac_config.smi_gpio.mdio_num = ETH_MDIO_GPIO; +#endif + + ESP_LOGI(TAG, "Ethernet pins for MDC %d MDIO %d\n", esp32_emac_config.smi_gpio.mdc_num, esp32_emac_config.smi_gpio.mdio_num); + + esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); // Reserve all pins used by ethernet interface - CPU_GPIO_ReservePin(ETH_MDIO_GPIO, true); // MDIO (18) + CPU_GPIO_ReservePin(esp32_emac_config.smi_gpio.mdio_num, true); // MDIO + CPU_GPIO_ReservePin(esp32_emac_config.smi_gpio.mdc_num, true); // MDC + +#if SOC_EMAC_USE_MULTI_IO_MUX || SOC_EMAC_MII_USE_GPIO_MATRIX + // ESP32_P4 with Ethernet + const eth_mac_rmii_gpio_config_t &rmii = esp32_emac_config.emac_dataif_gpio.rmii; + CPU_GPIO_ReservePin(rmii.txd0_num, true); + CPU_GPIO_ReservePin(rmii.tx_en_num, true); + CPU_GPIO_ReservePin(rmii.txd1_num, true); + CPU_GPIO_ReservePin(rmii.rxd0_num, true); + CPU_GPIO_ReservePin(rmii.rxd1_num, true); + CPU_GPIO_ReservePin(rmii.crs_dv_num,true); +#else + // ESP32 with Ethernet CPU_GPIO_ReservePin(19, true); // TXD0 CPU_GPIO_ReservePin(21, true); // TX_EN CPU_GPIO_ReservePin(22, true); // TXD1 - CPU_GPIO_ReservePin(ETH_MDC_GPIO, true); // MDC (23) CPU_GPIO_ReservePin(25, true); // RXD0 CPU_GPIO_ReservePin(26, true); // RXD1 CPU_GPIO_ReservePin(27, true); // CRS_DV +#endif // Define PHY to use with internal Ethernet -#ifdef ESP32_ETHERNET_PHY_IP101 +#if defined(ESP32_ETHERNET_PHY_IP101) ESP_LOGI(TAG, "Ethernet IP101 phy\n"); esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config); #elif defined(ESP32_ETHERNET_PHY_RTL8201) diff --git a/targets/ESP32/_Network/NF_ESP32_SmartConfig.cpp b/targets/ESP32/_Network/NF_ESP32_SmartConfig.cpp index 29335577b4..c78bab3412 100644 --- a/targets/ESP32/_Network/NF_ESP32_SmartConfig.cpp +++ b/targets/ESP32/_Network/NF_ESP32_SmartConfig.cpp @@ -3,6 +3,9 @@ // See LICENSE file in the project root for full license information. // +// ESP32-P4 doesn't currently have smartconfig support +#if !defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) + #include #include @@ -101,3 +104,5 @@ void NF_ESP32_Start_wifi_smart_config(void) { xTaskCreate(smartconfig_task, "smartconfig_task", 4096, NULL, 3, NULL); } + +#endif diff --git a/targets/ESP32/_Network/NF_ESP32_Wireless.cpp b/targets/ESP32/_Network/NF_ESP32_Wireless.cpp index 6954849512..f3228696dc 100644 --- a/targets/ESP32/_Network/NF_ESP32_Wireless.cpp +++ b/targets/ESP32/_Network/NF_ESP32_Wireless.cpp @@ -8,7 +8,7 @@ #include "NF_ESP32_Network.h" #include "esp_netif_net_stack.h" -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) static const char *TAG = "wifi"; @@ -128,6 +128,8 @@ void NF_ESP32_DeinitWifi() esp_wifi_deinit(); } +extern "C" esp_err_t esp_hosted_init(void); + esp_err_t NF_ESP32_InitaliseWifi() { esp_err_t ec = ESP_OK; @@ -152,6 +154,9 @@ esp_err_t NF_ESP32_InitaliseWifi() if (!IsWifiInitialised) { +#if defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) + esp_hosted_init(); +#endif // create Wi-Fi STA (ignoring return) wifiStaNetif = esp_netif_create_default_wifi_sta(); @@ -340,6 +345,8 @@ int NF_ESP32_Wireless_Open(HAL_Configuration_NetworkInterface *config) NF_ESP32_IsToConnect = false; } +// ESP32-P4 doesn't currently have smartconfig support so disable +#if !defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) if (okToStartSmartConnect && (wirelessConfig->Options & Wireless80211Configuration_ConfigurationOptions_SmartConfig)) { @@ -349,6 +356,7 @@ int NF_ESP32_Wireless_Open(HAL_Configuration_NetworkInterface *config) // clear flag NF_ESP32_IsToConnect = false; } +#endif return NF_ESP32_Wait_NetNumber(IDF_WIFI_STA_DEF); } diff --git a/targets/ESP32/_common/ESP32_C3_DeviceMapping.cpp b/targets/ESP32/_common/ESP32_C3_DeviceMapping.cpp index 79eac188d8..7472d27386 100644 --- a/targets/ESP32/_common/ESP32_C3_DeviceMapping.cpp +++ b/targets/ESP32/_common/ESP32_C3_DeviceMapping.cpp @@ -12,7 +12,7 @@ // int8_t Esp32_SPI_DevicePinMap[MAX_SPI_DEVICES][Esp32SpiPin_Max] = { // SPI1 - use defaults from IDF sample - {SPI_IOMUX_PIN_NUM_MOSI, SPI_IOMUX_PIN_NUM_MISO, SPI_IOMUX_PIN_NUM_CLK}, + {MSPI_IOMUX_PIN_NUM_MOSI, MSPI_IOMUX_PIN_NUM_MISO, MSPI_IOMUX_PIN_NUM_CLK}, // SPI2 - no pins assigned {-1, -1, -1}}; diff --git a/targets/ESP32/_common/ESP32_C6_DeviceMapping.cpp b/targets/ESP32/_common/ESP32_C6_DeviceMapping.cpp index ceb85aff19..a318d6eec6 100644 --- a/targets/ESP32/_common/ESP32_C6_DeviceMapping.cpp +++ b/targets/ESP32/_common/ESP32_C6_DeviceMapping.cpp @@ -11,8 +11,8 @@ // Map pins mosi, miso, clock // int8_t Esp32_SPI_DevicePinMap[MAX_SPI_DEVICES][Esp32SpiPin_Max] = { - // SPI1 - use defaults from IDF sample - {SPI_IOMUX_PIN_NUM_MOSI, SPI_IOMUX_PIN_NUM_MISO, SPI_IOMUX_PIN_NUM_CLK}, + // SPI1 - use defaults + {MSPI_IOMUX_PIN_NUM_MOSI, MSPI_IOMUX_PIN_NUM_MISO, MSPI_IOMUX_PIN_NUM_CLK}, // SPI2 - no pins assigned {-1, -1, -1}}; diff --git a/targets/ESP32/_common/ESP32_H2_DeviceMapping.cpp b/targets/ESP32/_common/ESP32_H2_DeviceMapping.cpp index abed74a7d0..b1413c95e0 100644 --- a/targets/ESP32/_common/ESP32_H2_DeviceMapping.cpp +++ b/targets/ESP32/_common/ESP32_H2_DeviceMapping.cpp @@ -12,7 +12,7 @@ // int8_t Esp32_SPI_DevicePinMap[MAX_SPI_DEVICES][Esp32SpiPin_Max] = { // SPI1 - use defaults from IDF sample - {SPI_IOMUX_PIN_NUM_MOSI, SPI_IOMUX_PIN_NUM_MISO, SPI_IOMUX_PIN_NUM_CLK}, + {MSPI_IOMUX_PIN_NUM_MOSI, MSPI_IOMUX_PIN_NUM_MISO, MSPI_IOMUX_PIN_NUM_CLK}, // SPI2 - no pins assigned {-1, -1, -1}}; diff --git a/targets/ESP32/_common/ESP32_P4_DeviceMapping.cpp b/targets/ESP32/_common/ESP32_P4_DeviceMapping.cpp new file mode 100644 index 0000000000..d214a22663 --- /dev/null +++ b/targets/ESP32/_common/ESP32_P4_DeviceMapping.cpp @@ -0,0 +1,85 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +// SPI +// 2 devices +// Map pins mosi, miso, clock +// +int8_t Esp32_SPI_DevicePinMap[MAX_SPI_DEVICES][Esp32SpiPin_Max] = { + // SPI1 - no pins assigned + {-1, -1, -1}, + // SPI2 - use defaults from IDF sample + {SPI2_IOMUX_PIN_NUM_MOSI, SPI2_IOMUX_PIN_NUM_MISO, SPI2_IOMUX_PIN_NUM_CLK}}; + +// Serial +// 2 devices COM1,COM2 ( UART_NUM_0, UART_NUM_1 ) +// Map pins Tx, RX, RTS, CTS +// Set pins to default for UART_NUM_0 +// others assign as NONE because the default pins can be shared with serial flash and PSRAM +int8_t Esp32_SERIAL_DevicePinMap[UART_NUM_MAX][Esp32SerialPin_Max] = { + // COM 1 - pins 21, 20 + {UART_NUM_0_TXD_DIRECT_GPIO_NUM, + UART_NUM_0_RXD_DIRECT_GPIO_NUM, + UART_PIN_NO_CHANGE, + UART_PIN_NO_CHANGE}, + +#if defined(UART_NUM_2) + // COM 2 - all set to UART_PIN_NO_CHANGE + {UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE}, +#endif +}; + +// ============================================= +// I2C +// 1 devices I2C1 +// Map pins Data & Clock +int8_t Esp32_I2C_DevicePinMap[I2C_NUM_MAX][2] = { + // I2C1 - pins 18, 19, + {I2C1_DATA, I2C1_CLOCK}}; + +// ============================================= +// LED PWM +// 16 channels LED1 to LED16 or PWM1 to PWM16 +// Map pins Data & Clock +int8_t Esp32_LED_DevicePinMap[8] = { + // Channels ( non assigned ) + -1, // 1 + -1, // 2 + -1, // 3 + -1, // 4 + -1, // 5 + -1, // 6 + -1, // 7 + -1 // 8 +}; + +// ESP32P4 ADC1 channels 0 - 9 +// ADC2 channels 10 - 19 +int8_t Esp32_ADC_DevicePinMap[TARGET_ADC_NUM_PINS] = { + // ADC1 + ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, + ADC1_CHANNEL_4_GPIO_NUM, ADC1_CHANNEL_5_GPIO_NUM, ADC1_CHANNEL_6_GPIO_NUM, ADC1_CHANNEL_7_GPIO_NUM, + // ADC2 + ADC2_CHANNEL_0_GPIO_NUM, ADC2_CHANNEL_1_GPIO_NUM, ADC2_CHANNEL_2_GPIO_NUM, ADC2_CHANNEL_3_GPIO_NUM, + ADC2_CHANNEL_4_GPIO_NUM, ADC2_CHANNEL_5_GPIO_NUM}; + +// I2S +// 1 device I2S1 +// Map pins various pins. If not used, I2S_PIN_NO_CHANGE is used +int8_t Esp32_I2S_DevicePinMap[I2S_NUM_MAX][5] = { + // No pin pre configured + {I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE}}; + +// SDMMC +// ESP32_P4 allows 2 sdmmc devices, allow for 4 data pins +// Set SDMMC1 to default pins and SDMMC2 to not configured +int8_t Esp32_SDMMC_DevicePinMap[CONFIG_SOC_SDMMC_NUM_SLOTS][6] = { + // Clock, Command, D0, D1, D2, D3, D4, D5, D6, D7, D8 + {GPIO_NUM_14, GPIO_NUM_15, GPIO_NUM_2, GPIO_NUM_4, GPIO_NUM_12, GPIO_NUM_13}, + {GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC, GPIO_NUM_NC}}; diff --git a/targets/ESP32/_common/Target_Network.cpp b/targets/ESP32/_common/Target_Network.cpp index 52a4e1e73c..02d9453813 100644 --- a/targets/ESP32/_common/Target_Network.cpp +++ b/targets/ESP32/_common/Target_Network.cpp @@ -6,7 +6,7 @@ #include "NF_ESP32_Network.h" #include - +#include // // Works with the Target_NetworkConfig to map the Network_Interface_XXXXX calls to the correct driver @@ -45,7 +45,7 @@ int Network_Interface_Open(int index) switch (networkConfiguration.InterfaceType) { -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) // Wi-Fi (STA) case NetworkInterfaceType_Wireless80211: return NF_ESP32_Wireless_Open(&networkConfiguration); @@ -90,7 +90,7 @@ bool Network_Interface_Close(int index) switch (networkConfiguration.InterfaceType) { -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) // Wireless case NetworkInterfaceType_Wireless80211: return NF_ESP32_Wireless_Close(); @@ -116,7 +116,7 @@ bool Network_Interface_Close(int index) return false; } -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) int Network_Interface_Start_Scan(int index) { HAL_Configuration_NetworkInterface networkConfiguration; diff --git a/targets/ESP32/_common/Target_System_IO_FileSystem.c b/targets/ESP32/_common/Target_System_IO_FileSystem.c index baa128af58..9e1292700f 100644 --- a/targets/ESP32/_common/Target_System_IO_FileSystem.c +++ b/targets/ESP32/_common/Target_System_IO_FileSystem.c @@ -210,8 +210,8 @@ bool Storage_MountSpi(int spiBus, uint32_t csPin, int driveIndex) sdmmc_host_t host = SDSPI_HOST_DEFAULT(); #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) - // First available bus on ESP32_C3/S3/C6/H2 is SPI2_HOST + defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) + // First available bus on ESP32_C3/S3/C6/H2/P4 is SPI2_HOST host.slot = spiBus + SPI2_HOST; #else // First available bus on ESP32 is HSPI_HOST(1) diff --git a/targets/ESP32/_common/WireProtocol_HAL_Interface.c b/targets/ESP32/_common/WireProtocol_HAL_Interface.c index bbe2180338..d2ada2c930 100644 --- a/targets/ESP32/_common/WireProtocol_HAL_Interface.c +++ b/targets/ESP32/_common/WireProtocol_HAL_Interface.c @@ -102,9 +102,20 @@ static uart_port_t ESP32_WP_UART = UART_NUM_0; #define ESP32_WP_RX_PIN UART_NUM_0_RXD_DIRECT_GPIO_NUM #define ESP32_WP_TX_PIN UART_NUM_0_TXD_DIRECT_GPIO_NUM +#elif CONFIG_IDF_TARGET_ESP32P4 + +// WP uses UART0 +static uart_port_t ESP32_WP_UART = UART_NUM_0; + +// UART pins for ESP32-P4 +// U0RXD 23 +// U0TXD 24 + +#define ESP32_WP_RX_PIN UART_NUM_0_RXD_DIRECT_GPIO_NUM +#define ESP32_WP_TX_PIN UART_NUM_0_TXD_DIRECT_GPIO_NUM #endif -#if (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2) && HAL_WP_USE_USB_CDC +#if (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4) && HAL_WP_USE_USB_CDC #include diff --git a/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp b/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp index c45c8d8c16..87004612e3 100644 --- a/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp +++ b/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp @@ -16,6 +16,8 @@ bool ethernetEnabled = false; // NVS parameters for Interface config #define NVS_NAMESPACE "nanoF" +static const char *TAG = "cm"; + // #define DEBUG_CONFIG 1 #ifdef DEBUG_CONFIG @@ -151,7 +153,7 @@ bool AppendConfigBlock( void ConfigurationManager_EnumerateConfigurationBlocks() { HAL_CONFIGURATION_NETWORK *networkConfigs = ConfigStorage_FindNetworkConfigurationBlocks(); - +ESP_LOGI(TAG, "ConfigurationManager_EnumerateConfigurationBlocks %d",networkConfigs->Count); // check network configs count if (networkConfigs->Count == 0) { @@ -162,7 +164,7 @@ void ConfigurationManager_EnumerateConfigurationBlocks() // ESP32 can have have up to 4 network interfaces: Wireless Station, Wireless AP, Ethernet and OpenThread // Allocate count & types of network interfaces -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) // Wireless Support netTypes[networkCount++] = NetworkInterfaceType_Wireless80211; netTypes[networkCount++] = NetworkInterfaceType_WirelessAP; @@ -176,6 +178,8 @@ void ConfigurationManager_EnumerateConfigurationBlocks() #if HAL_USE_THREAD == TRUE netTypes[networkCount++] = NetworkInterfaceType_Thread; #endif +ESP_LOGI(TAG, "networkCount %d", networkCount); + // allocate memory for ONE network configuration HAL_Configuration_NetworkInterface *networkConfig = (HAL_Configuration_NetworkInterface *)platform_malloc(sizeof(HAL_Configuration_NetworkInterface)); @@ -203,6 +207,7 @@ void ConfigurationManager_EnumerateConfigurationBlocks() // have to enumerate again to pick it up networkConfigs = ConfigStorage_FindNetworkConfigurationBlocks(); +ESP_LOGI(TAG, "networkCount %d/%d", networkCount, networkConfigs->Count); } // find wireless 80211 network configuration blocks diff --git a/targets/ESP32/_common/targetHAL_Network.cpp b/targets/ESP32/_common/targetHAL_Network.cpp index cb49b025d7..db879a8dca 100644 --- a/targets/ESP32/_common/targetHAL_Network.cpp +++ b/targets/ESP32/_common/targetHAL_Network.cpp @@ -152,7 +152,7 @@ static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_ ets_printf("Event %d, ID: %d\n", event_base, event_id); #endif -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) if (event_base == WIFI_EVENT) { switch (event_id) @@ -373,6 +373,15 @@ static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_ #ifdef PRINT_NET_EVENT ets_printf("ETHERNET_EVENT_CONNECTED\n"); #endif + +#if LWIP_IPV6 + { + // Create IPV6 link local address for ETH interface + struct netif *netif = esp_netif_get_handle_from_ifkey("ETH_DEF")->lwip_netif; + netif_create_ip6_linklocal_address(netif, 1); + } +#endif + PostAvailabilityOn(IDF_ETH_DEF); break; @@ -514,7 +523,7 @@ void nanoHAL_Network_Initialize() { ESP_ERROR_CHECK(result); -#if defined(CONFIG_SOC_WIFI_SUPPORTED) +#if defined(CONFIG_SOC_WIFI_SUPPORTED) || defined(CONFIG_SOC_WIRELESS_HOST_SUPPORTED) // register the handler for WIFI events ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL)); #endif diff --git a/targets/ESP32/_include/Esp32_DeviceMapping.h b/targets/ESP32/_include/Esp32_DeviceMapping.h index 6a3e7c50f5..7b8bad3cae 100644 --- a/targets/ESP32/_include/Esp32_DeviceMapping.h +++ b/targets/ESP32/_include/Esp32_DeviceMapping.h @@ -85,6 +85,9 @@ extern int8_t Esp32_SERIAL_DevicePinMap[UART_NUM_MAX][Esp32SerialPin_Max]; #elif defined(CONFIG_IDF_TARGET_ESP32S3) #define TARGET_ADC_NUM_PINS (CONFIG_SOC_ADC_MAX_CHANNEL_NUM * CONFIG_SOC_ADC_PERIPH_NUM) #define TARGET_LED_NUM_PINS 8 +#elif defined(CONFIG_IDF_TARGET_ESP32P4) +#define TARGET_ADC_NUM_PINS (CONFIG_SOC_ADC_MAX_CHANNEL_NUM * CONFIG_SOC_ADC_PERIPH_NUM) +#define TARGET_LED_NUM_PINS 8 #else #define TARGET_ADC_NUM_PINS (CONFIG_SOC_ADC_MAX_CHANNEL_NUM * CONFIG_SOC_ADC_PERIPH_NUM) #define TARGET_LED_NUM_PINS 16 diff --git a/targets/ESP32/_include/lwipopts.h b/targets/ESP32/_include/lwipopts.h index fd83eb6dde..b2c6cadebe 100644 --- a/targets/ESP32/_include/lwipopts.h +++ b/targets/ESP32/_include/lwipopts.h @@ -360,12 +360,13 @@ extern "C" { #define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID #define DHCP_DEFINE_CUSTOM_TIMEOUTS 1 + #define DHCP_COARSE_TIMER_SECS CONFIG_LWIP_DHCP_COARSE_TIMER_SECS #define DHCP_NEXT_TIMEOUT_THRESHOLD (3) /* Since for embedded devices it's not that hard to miss a discover packet, so lower * the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s. */ -#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) ((uint16_t)(((tries) < 5 ? 1 << (tries) : 16) * 250)) +#define DHCP_REQUEST_BACKOFF_SEQUENCE(state, tries) ((uint16_t)(((tries) < 5 ? 1 << (tries) : 16) * 250)) static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) { @@ -377,13 +378,13 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) return timeout; } -#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp) \ - timeout_from_offered((dhcp)->offered_t0_lease, 120) -#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp) \ - timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ ) -#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) \ - timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ ) - +#define DHCP_SET_TIMEOUT_FROM_OFFERED_T0_LEASE(tout, dhcp) do { \ + (tout) = timeout_from_offered((dhcp)->offered_t0_lease, 120); } while(0) +#define DHCP_SET_TIMEOUT_FROM_OFFERED_T1_RENEW(tout, dhcp) do { \ + (tout) = timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ ); } while(0) +#define DHCP_SET_TIMEOUT_FROM_OFFERED_T2_REBIND(tout, dhcp) do { \ + (tout) = timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ ); } while(0) + #define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \ do { LWIP_UNUSED_ARG(msg); \ dhcp_parse_extra_opts(dhcp, state, option, len, pbuf, offset); \ diff --git a/targets/ESP32/_include/nf_sockets_priv.h b/targets/ESP32/_include/nf_sockets_priv.h new file mode 100644 index 0000000000..709b52e815 --- /dev/null +++ b/targets/ESP32/_include/nf_sockets_priv.h @@ -0,0 +1,182 @@ +/** + * @file + * Sockets API internal implementations (do not use in application code) + */ + +/* + * Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Joel Cunningham + * + */ +#ifndef NF_LWIP_HDR_SOCKETS_PRIV_H +#define NF_LWIP_HDR_SOCKETS_PRIV_H + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NUM_SOCKETS MEMP_NUM_NETCONN + +/** This is overridable for the rare case where more than 255 threads + * select on the same socket... + */ +#ifndef SELWAIT_T +#define SELWAIT_T u8_t +#endif + +union lwip_sock_lastdata { + struct netbuf *netbuf; + struct pbuf *pbuf; +}; + +/** Contains all internal pointers and states used for a socket */ +struct lwip_sock { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + union lwip_sock_lastdata lastdata; +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was ACKed (free send buffer), set by event_callback(), + tested by select */ + u16_t sendevent; + /** error happened for this socket, set by event_callback(), tested by select */ + u16_t errevent; + /** counter of how many threads are waiting for this socket using select */ + SELWAIT_T select_waiting; + + // [NF_CHANGE] + // need this to store the last error that occurred in the socket + // last error that occurred on this socket (in fact, all our errnos fit into an u8_t) + u8_t err; + // [END_NF_CHANGE] + +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ +#if LWIP_NETCONN_FULLDUPLEX + /* counter of how many threads are using a struct lwip_sock (not the 'int') */ + u8_t fd_used; + /* status of pending close/delete actions */ + u8_t fd_free_pending; +#define LWIP_SOCK_FD_FREE_TCP 1 +#define LWIP_SOCK_FD_FREE_FREE 2 +#endif +}; + +#ifndef set_errno +#define set_errno(err) do { if (err) { errno = (err); } } while(0) +#endif + +#if !LWIP_TCPIP_CORE_LOCKING +/** Maximum optlen used by setsockopt/getsockopt */ +#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq)) + +/** This struct is used to pass data to the set/getsockopt_impl + * functions running in tcpip_thread context (only a void* is allowed) */ +struct lwip_setgetsockopt_data { + /** socket index for which to change options */ + int s; + /** level of the option to process */ + int level; + /** name of the option to process */ + int optname; + /** set: value to set the option to + * get: value of the option is stored here */ +#if LWIP_MPU_COMPATIBLE + u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN]; +#else + union { + void *p; + const void *pc; + } optval; +#endif + /** size of *optval */ + socklen_t optlen; + /** if an error occurs, it is temporarily stored here */ + int err; + /** semaphore to wake up the calling task */ + void* completed_sem; +}; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + +#ifdef __cplusplus +} +#endif + +struct lwip_sock* lwip_socket_dbg_get_socket(int fd); + +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL + +#if LWIP_NETCONN_SEM_PER_THREAD +#define SELECT_SEM_T sys_sem_t* +#define SELECT_SEM_PTR(sem) (sem) +#else /* LWIP_NETCONN_SEM_PER_THREAD */ +#define SELECT_SEM_T sys_sem_t +#define SELECT_SEM_PTR(sem) (&(sem)) +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +/** Description for a task waiting in select */ +struct lwip_select_cb { + /** Pointer to the next waiting task */ + struct lwip_select_cb *next; + /** Pointer to the previous waiting task */ + struct lwip_select_cb *prev; +#if LWIP_SOCKET_SELECT + /** readset passed to select */ + fd_set *readset; + /** writeset passed to select */ + fd_set *writeset; + /** unimplemented: exceptset passed to select */ + fd_set *exceptset; +#endif /* LWIP_SOCKET_SELECT */ +#if LWIP_SOCKET_POLL + /** fds passed to poll; NULL if select */ + struct pollfd *poll_fds; + /** nfds passed to poll; 0 if select */ + nfds_t poll_nfds; +#endif /* LWIP_SOCKET_POLL */ + /** don't signal the same semaphore twice: set to 1 when signalled */ + int sem_signalled; + /** semaphore to wake up a task waiting for select */ + SELECT_SEM_T sem; +}; +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ + +#endif /* LWIP_SOCKET */ + +#endif /* NF_LWIP_HDR_SOCKETS_PRIV_H */ diff --git a/targets/ESP32/_lwIP/nf_api_msg.c b/targets/ESP32/_lwIP/nf_api_msg.c index 0dd26104a1..6eaddf07f1 100644 --- a/targets/ESP32/_lwIP/nf_api_msg.c +++ b/targets/ESP32/_lwIP/nf_api_msg.c @@ -1,10 +1,48 @@ // // Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) 2001-2004 Swedish Institute of Computer Science. All rights reserved. -// See LICENSE file in the project root for full license information. // +/** + * @file + * Sequential API Internal module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +// [NF_CHANGE] #include +// [END_NF_CHANGE] #include "lwip/opt.h" #if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ @@ -28,18 +66,10 @@ /* netconns are polled once per second (e.g. continue write on memory error) */ #define NETCONN_TCP_POLL_INTERVAL 2 -#define SET_NONBLOCKING_CONNECT(conn, val) \ - do \ - { \ - if (val) \ - { \ - netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \ - } \ - else \ - { \ - netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \ - } \ - } while (0) +#define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \ + netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \ +} else { \ + netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0) #define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT) #if LWIP_NETCONN_FULLDUPLEX @@ -51,14 +81,14 @@ /* forward declarations */ #if LWIP_TCP #if LWIP_TCPIP_CORE_LOCKING -#define WRITE_DELAYED , 1 -#define WRITE_DELAYED_PARAM , u8_t delayed +#define WRITE_DELAYED , 1 +#define WRITE_DELAYED_PARAM , u8_t delayed #else /* LWIP_TCPIP_CORE_LOCKING */ #define WRITE_DELAYED #define WRITE_DELAYED_PARAM #endif /* LWIP_TCPIP_CORE_LOCKING */ -static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM); -static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM); +static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM); +static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM); #endif static void netconn_drain(struct netconn *conn); @@ -66,71 +96,64 @@ static void netconn_drain(struct netconn *conn); #if LWIP_TCPIP_CORE_LOCKING #define TCPIP_APIMSG_ACK(m) #else /* LWIP_TCPIP_CORE_LOCKING */ -#define TCPIP_APIMSG_ACK(m) \ - do \ - { \ - sys_sem_signal(LWIP_API_MSG_SEM(m)); \ - } while (0) +#define TCPIP_APIMSG_ACK(m) do { sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) #endif /* LWIP_TCPIP_CORE_LOCKING */ #if LWIP_NETCONN_FULLDUPLEX -const u8_t netconn_deleted = 0; +static const u8_t netconn_deleted = 0; -int lwip_netconn_is_deallocated_msg(void *msg) +int +lwip_netconn_is_deallocated_msg(void *msg) { - if (msg == &netconn_deleted) - { - return 1; - } - return 0; + if (msg == &netconn_deleted) { + return 1; + } + return 0; } #endif /* LWIP_NETCONN_FULLDUPLEX */ #if LWIP_TCP -const u8_t netconn_aborted = 0; -const u8_t netconn_reset = 0; -const u8_t netconn_closed = 0; +static const u8_t netconn_aborted = 0; +static const u8_t netconn_reset = 0; +static const u8_t netconn_closed = 0; /** Translate an error to a unique void* passed via an mbox */ -static void *lwip_netconn_err_to_msg(err_t err) +static void * +lwip_netconn_err_to_msg(err_t err) { - switch (err) - { - case ERR_ABRT: - return LWIP_CONST_CAST(void *, &netconn_aborted); - case ERR_RST: - return LWIP_CONST_CAST(void *, &netconn_reset); - case ERR_CLSD: - return LWIP_CONST_CAST(void *, &netconn_closed); - default: - LWIP_ASSERT("unhandled error", err == ERR_OK); - return NULL; - } + switch (err) { + case ERR_ABRT: + return LWIP_CONST_CAST(void *, &netconn_aborted); + case ERR_RST: + return LWIP_CONST_CAST(void *, &netconn_reset); + case ERR_CLSD: + return LWIP_CONST_CAST(void *, &netconn_closed); + default: + LWIP_ASSERT("unhandled error", err == ERR_OK); + return NULL; + } } -int lwip_netconn_is_err_msg(void *msg, err_t *err) +int +lwip_netconn_is_err_msg(void *msg, err_t *err) { - LWIP_ASSERT("err != NULL", err != NULL); - - if (msg == &netconn_aborted) - { - *err = ERR_ABRT; - return 1; - } - else if (msg == &netconn_reset) - { - *err = ERR_RST; - return 1; - } - else if (msg == &netconn_closed) - { - *err = ERR_CLSD; - return 1; - } - return 0; + LWIP_ASSERT("err != NULL", err != NULL); + + if (msg == &netconn_aborted) { + *err = ERR_ABRT; + return 1; + } else if (msg == &netconn_reset) { + *err = ERR_RST; + return 1; + } else if (msg == &netconn_closed) { + *err = ERR_CLSD; + return 1; + } + return 0; } #endif /* LWIP_TCP */ + #if LWIP_RAW /** * Receive callback function for RAW netconns. @@ -139,60 +162,55 @@ int lwip_netconn_is_err_msg(void *msg, err_t *err) * * @see raw.h (struct raw_pcb.recv) for parameters and return value */ -static u8_t recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) +static u8_t +recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, + const ip_addr_t *addr) { - struct pbuf *q; - struct netbuf *buf; - struct netconn *conn; + struct pbuf *q; + struct netbuf *buf; + struct netconn *conn; - LWIP_UNUSED_ARG(addr); - conn = (struct netconn *)arg; + LWIP_UNUSED_ARG(addr); + conn = (struct netconn *)arg; - if ((conn != NULL) && NETCONN_MBOX_VALID(conn, &conn->recvmbox)) - { + if ((conn != NULL) && NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { #if LWIP_SO_RCVBUF - int recv_avail; - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) - { - return 0; - } + int recv_avail; + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { + return 0; + } #endif /* LWIP_SO_RCVBUF */ - /* copy the whole packet into new pbufs */ - q = pbuf_clone(PBUF_RAW, PBUF_RAM, p); - if (q != NULL) - { - u16_t len; - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) - { - pbuf_free(q); - return 0; - } - - buf->p = q; - buf->ptr = q; - ip_addr_copy(buf->addr, *ip_current_src_addr()); - buf->port = pcb->protocol; - - len = q->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) - { - netbuf_delete(buf); - return 0; - } - else - { + /* copy the whole packet into new pbufs */ + q = pbuf_clone(PBUF_RAW, PBUF_RAM, p); + if (q != NULL) { + u16_t len; + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(q); + return 0; + } + + buf->p = q; + buf->ptr = q; + ip_addr_copy(buf->addr, *ip_current_src_addr()); + buf->port = pcb->protocol; + + len = q->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return 0; + } else { #if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); + SYS_ARCH_INC(conn->recv_avail, len); #endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - } + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } } + } - return 0; /* do not eat the packet */ + return 0; /* do not eat the packet */ } #endif /* LWIP_RAW*/ @@ -203,89 +221,84 @@ static u8_t recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_ad * * @see udp.h (struct udp_pcb.recv) for parameters */ -static void recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +static void +recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + const ip_addr_t *addr, u16_t port) { - struct netbuf *buf; - struct netconn *conn; - u16_t len; + struct netbuf *buf; + struct netconn *conn; + u16_t len; + err_t err; #if LWIP_SO_RCVBUF - int recv_avail; + int recv_avail; #endif /* LWIP_SO_RCVBUF */ - LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ - LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_udp must have an argument", arg != NULL); - conn = (struct netconn *)arg; + LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ + LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_udp must have an argument", arg != NULL); + conn = (struct netconn *)arg; - if (conn == NULL) - { - pbuf_free(p); - return; - } + if (conn == NULL) { + pbuf_free(p); + return; + } - LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); + LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); #if LWIP_SO_RCVBUF - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) || ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) - { + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) || + ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { #else /* LWIP_SO_RCVBUF */ - if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) - { + if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { #endif /* LWIP_SO_RCVBUF */ - pbuf_free(p); - return; - } + pbuf_free(p); + return; + } #if ESP_LWIP && LWIP_IPV6 - /* This should be eventually moved to a flag on the UDP PCB, and this drop can happen - more correctly in udp_input(). This will also allow icmp_dest_unreach() to be called. */ - if (conn->flags & NETCONN_FLAG_IPV6_V6ONLY && !ip_current_is_v6()) - { - LWIP_DEBUGF(API_MSG_DEBUG, ("recv_udp: Dropping IPv4 UDP packet (IPv6-only socket)")); - pbuf_free(p); - return; - } + /* This should be eventually moved to a flag on the UDP PCB, and this drop can happen + more correctly in udp_input(). This will also allow icmp_dest_unreach() to be called. */ + if (conn->flags & NETCONN_FLAG_IPV6_V6ONLY && !ip_current_is_v6()) { + LWIP_DEBUGF(API_MSG_DEBUG, ("recv_udp: Dropping IPv4 UDP packet (IPv6-only socket)")); + pbuf_free(p); + return; + } #endif /* ESP_LWIP && LWIP_IPV6 */ - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) - { - pbuf_free(p); - return; - } - else - { - buf->p = p; - buf->ptr = p; - ip_addr_set(&buf->addr, addr); - buf->port = port; + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(p); + return; + } else { + buf->p = p; + buf->ptr = p; + ip_addr_set(&buf->addr, addr); + buf->port = port; #if LWIP_NETBUF_RECVINFO - if (conn->flags & NETCONN_FLAG_PKTINFO) - { - /* get the UDP header - always in the first pbuf, ensured by udp_input */ - const struct udp_hdr *udphdr = (const struct udp_hdr *)ip_next_header_ptr(); - buf->flags = NETBUF_FLAG_DESTADDR; - ip_addr_set(&buf->toaddr, ip_current_dest_addr()); - buf->toport_chksum = udphdr->dest; - } -#endif /* LWIP_NETBUF_RECVINFO */ - } - - len = p->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) - { - netbuf_delete(buf); - return; + if (conn->flags & NETCONN_FLAG_PKTINFO) { + /* get the UDP header - always in the first pbuf, ensured by udp_input */ + const struct udp_hdr *udphdr = (const struct udp_hdr *)ip_next_header_ptr(); + buf->flags = NETBUF_FLAG_DESTADDR; + ip_addr_set(&buf->toaddr, ip_current_dest_addr()); + buf->toport_chksum = udphdr->dest; } - else - { +#endif /* LWIP_NETBUF_RECVINFO */ + } + + len = p->tot_len; + err = sys_mbox_trypost(&conn->recvmbox, buf); + if (err != ERR_OK) { + netbuf_delete(buf); + LWIP_DEBUGF(API_MSG_DEBUG, ("recv_udp: sys_mbox_trypost failed, err=%d\n", err)); + return; + } else { #if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); + SYS_ARCH_INC(conn->recv_avail, len); #endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } } #endif /* LWIP_UDP */ @@ -296,65 +309,57 @@ static void recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_ad * * @see tcp.h (struct tcp_pcb.recv) for parameters and return value */ -static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +static err_t +recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { - struct netconn *conn; - u16_t len; - void *msg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); - LWIP_ASSERT("err != ERR_OK unhandled", err == ERR_OK); - LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ - conn = (struct netconn *)arg; - - if (conn == NULL) - { - return ERR_VAL; - } - LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); - - if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) - { - /* recvmbox already deleted */ - if (p != NULL) - { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } - return ERR_OK; - } - /* Unlike for UDP or RAW pcbs, don't check for available space - using recv_avail since that could break the connection - (data is already ACKed) */ - - if (p != NULL) - { - msg = p; - len = p->tot_len; - } - else - { - msg = LWIP_CONST_CAST(void *, &netconn_closed); - len = 0; + struct netconn *conn; + u16_t len; + void *msg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); + LWIP_ASSERT("err != ERR_OK unhandled", err == ERR_OK); + LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ + conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); + + if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { + /* recvmbox already deleted */ + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); } + return ERR_OK; + } + /* Unlike for UDP or RAW pcbs, don't check for available space + using recv_avail since that could break the connection + (data is already ACKed) */ - if (sys_mbox_trypost(&conn->recvmbox, msg) != ERR_OK) - { - /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ - return ERR_MEM; - } - else - { + if (p != NULL) { + msg = p; + len = p->tot_len; + } else { + msg = LWIP_CONST_CAST(void *, &netconn_closed); + len = 0; + } + + if (sys_mbox_trypost(&conn->recvmbox, msg) != ERR_OK) { + /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ + return ERR_MEM; + } else { #if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); + SYS_ARCH_INC(conn->recv_avail, len); #endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } - return ERR_OK; + return ERR_OK; } /** @@ -368,43 +373,38 @@ static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) * * @see tcp.h (struct tcp_pcb.poll) for parameters and return value */ -static err_t poll_tcp(void *arg, struct tcp_pcb *pcb) +static err_t +poll_tcp(void *arg, struct tcp_pcb *pcb) { - struct netconn *conn = (struct netconn *)arg; + struct netconn *conn = (struct netconn *)arg; - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); - if (conn->state == NETCONN_WRITE) - { - lwip_netconn_do_writemore(conn WRITE_DELAYED); - } - else if (conn->state == NETCONN_CLOSE) - { + if (conn->state == NETCONN_WRITE) { + lwip_netconn_do_writemore(conn WRITE_DELAYED); + } else if (conn->state == NETCONN_CLOSE) { #if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER - if (conn->current_msg && conn->current_msg->msg.sd.polls_left) - { - conn->current_msg->msg.sd.polls_left--; - } -#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */ - lwip_netconn_do_close_internal(conn WRITE_DELAYED); - } - /* @todo: implement connect timeout here? */ - - /* Did a nonblocking write fail before? Then check available write-space. */ - if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) - { - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) - { - netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } + if (conn->current_msg && conn->current_msg->msg.sd.polls_left) { + conn->current_msg->msg.sd.polls_left--; } - - return ERR_OK; +#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */ + lwip_netconn_do_close_internal(conn WRITE_DELAYED); + } + /* @todo: implement connect timeout here? */ + + /* Did a nonblocking write fail before? Then check available write-space. */ + if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + } + + return ERR_OK; } /** @@ -414,35 +414,31 @@ static err_t poll_tcp(void *arg, struct tcp_pcb *pcb) * * @see tcp.h (struct tcp_pcb.sent) for parameters and return value */ -static err_t sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) +static err_t +sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) { - struct netconn *conn = (struct netconn *)arg; + struct netconn *conn = (struct netconn *)arg; - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); - if (conn) - { - if (conn->state == NETCONN_WRITE) - { - lwip_netconn_do_writemore(conn WRITE_DELAYED); - } - else if (conn->state == NETCONN_CLOSE) - { - lwip_netconn_do_close_internal(conn WRITE_DELAYED); - } + if (conn) { + if (conn->state == NETCONN_WRITE) { + lwip_netconn_do_writemore(conn WRITE_DELAYED); + } else if (conn->state == NETCONN_CLOSE) { + lwip_netconn_do_close_internal(conn WRITE_DELAYED); + } - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) - { - netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); - } + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); } + } - return ERR_OK; + return ERR_OK; } /** @@ -452,89 +448,80 @@ static err_t sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) * * @see tcp.h (struct tcp_pcb.err) for parameters */ -static void err_tcp(void *arg, err_t err) +static void +err_tcp(void *arg, err_t err) { - struct netconn *conn; - enum netconn_state old_state; - void *mbox_msg; - SYS_ARCH_DECL_PROTECT(lev); - - conn = (struct netconn *)arg; - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - SYS_ARCH_PROTECT(lev); - - /* when err is called, the pcb is deallocated, so delete the reference */ - conn->pcb.tcp = NULL; - /* store pending error */ - conn->pending_err = err; - /* prevent application threads from blocking on 'recvmbox'/'acceptmbox' */ - conn->flags |= NETCONN_FLAG_MBOXCLOSED; - - /* reset conn->state now before waking up other threads */ - old_state = conn->state; - conn->state = NETCONN_NONE; - - SYS_ARCH_UNPROTECT(lev); - - /* Notify the user layer about a connection error. Used to signal select. */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - /* Try to release selects pending on 'read' or 'write', too. - They will get an error if they actually try to read or write. */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - mbox_msg = lwip_netconn_err_to_msg(err); - /* pass error message to recvmbox to wake up pending recv */ - if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) - { - /* use trypost to prevent deadlock */ - sys_mbox_trypost(&conn->recvmbox, mbox_msg); - } - /* pass error message to acceptmbox to wake up pending accept */ - if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) - { - /* use trypost to preven deadlock */ - sys_mbox_trypost(&conn->acceptmbox, mbox_msg); - } - - if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || (old_state == NETCONN_CONNECT)) - { - /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary - since the pcb has already been deleted! */ - int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); + struct netconn *conn; + enum netconn_state old_state; + void *mbox_msg; + SYS_ARCH_DECL_PROTECT(lev); + + conn = (struct netconn *)arg; + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + SYS_ARCH_PROTECT(lev); + + /* when err is called, the pcb is deallocated, so delete the reference */ + conn->pcb.tcp = NULL; + /* store pending error */ + conn->pending_err = err; + /* prevent application threads from blocking on 'recvmbox'/'acceptmbox' */ + conn->flags |= NETCONN_FLAG_MBOXCLOSED; + + /* reset conn->state now before waking up other threads */ + old_state = conn->state; + conn->state = NETCONN_NONE; + + SYS_ARCH_UNPROTECT(lev); + + /* Notify the user layer about a connection error. Used to signal select. */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + /* Try to release selects pending on 'read' or 'write', too. + They will get an error if they actually try to read or write. */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + mbox_msg = lwip_netconn_err_to_msg(err); + /* pass error message to recvmbox to wake up pending recv */ + if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { + /* use trypost to prevent deadlock */ + sys_mbox_trypost(&conn->recvmbox, mbox_msg); + } + /* pass error message to acceptmbox to wake up pending accept */ + if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) { + /* use trypost to prevent deadlock */ + sys_mbox_trypost(&conn->acceptmbox, mbox_msg); + } + + if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || + (old_state == NETCONN_CONNECT)) { + /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary + since the pcb has already been deleted! */ + int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); - if (!was_nonblocking_connect) - { - sys_sem_t *op_completed_sem; - /* set error return code */ - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - if (old_state == NETCONN_CLOSE) - { - /* let close succeed: the connection is closed after all... */ - conn->current_msg->err = ERR_OK; - } - else - { - /* Write and connect fail */ - conn->current_msg->err = err; - } - op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - LWIP_ASSERT("inavlid op_completed_sem", sys_sem_valid(op_completed_sem)); - conn->current_msg = NULL; - /* wake up the waiting task */ - sys_sem_signal(op_completed_sem); - } - else - { - /* @todo: test what happens for error on nonblocking connect */ - } - } - else - { - LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); - } + if (!was_nonblocking_connect) { + sys_sem_t *op_completed_sem; + /* set error return code */ + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + if (old_state == NETCONN_CLOSE) { + /* let close succeed: the connection is closed after all... */ + conn->current_msg->err = ERR_OK; + } else { + /* Write and connect fail */ + conn->current_msg->err = err; + } + op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + LWIP_ASSERT("invalid op_completed_sem", sys_sem_valid(op_completed_sem)); + conn->current_msg = NULL; + /* wake up the waiting task */ + sys_sem_signal(op_completed_sem); + } else { + /* @todo: test what happens for error on nonblocking connect */ + } + } else { + LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); + } } /** @@ -543,16 +530,17 @@ static void err_tcp(void *arg, err_t err) * * @param conn the TCP netconn to setup */ -static void setup_tcp(struct netconn *conn) +static void +setup_tcp(struct netconn *conn) { - struct tcp_pcb *pcb; - - pcb = conn->pcb.tcp; - tcp_arg(pcb, conn); - tcp_recv(pcb, recv_tcp); - tcp_sent(pcb, sent_tcp); - tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL); - tcp_err(pcb, err_tcp); + struct tcp_pcb *pcb; + + pcb = conn->pcb.tcp; + tcp_arg(pcb, conn); + tcp_recv(pcb, recv_tcp); + tcp_sent(pcb, sent_tcp); + tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL); + tcp_err(pcb, err_tcp); } /** @@ -561,84 +549,76 @@ static void setup_tcp(struct netconn *conn) * * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value */ -static err_t accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +static err_t +accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) { - struct netconn *newconn; - struct netconn *conn = (struct netconn *)arg; - - if (conn == NULL) - { - return ERR_VAL; - } - if (!NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) - { - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); - return ERR_VAL; - } - - if (newpcb == NULL) - { - /* out-of-pcbs during connect: pass on this error to the application */ - if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) - { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - return ERR_VAL; - } - LWIP_ASSERT("expect newpcb == NULL or err == ERR_OK", err == ERR_OK); - LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ - - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->state: %s\n", tcp_debug_state_str(newpcb->state))); - - /* We have to set the callback here even though - * the new socket is unknown. newconn->socket is marked as -1. */ - newconn = netconn_alloc(conn->type, conn->callback); - if (newconn == NULL) - { - /* outof netconns: pass on this error to the application */ - if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) - { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - return ERR_MEM; - } - newconn->pcb.tcp = newpcb; - setup_tcp(newconn); - - /* handle backlog counter */ - tcp_backlog_delayed(newpcb); - - if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) - { - /* When returning != ERR_OK, the pcb is aborted in tcp_process(), - so do nothing here! */ - /* remove all references to this netconn from the pcb */ - struct tcp_pcb *pcb = newconn->pcb.tcp; - tcp_arg(pcb, NULL); - tcp_recv(pcb, NULL); - tcp_sent(pcb, NULL); - tcp_poll(pcb, NULL, 0); - tcp_err(pcb, NULL); - /* remove reference from to the pcb from this netconn */ - newconn->pcb.tcp = NULL; + struct netconn *newconn; + struct netconn *conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + if (!NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) { + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); + return ERR_VAL; + } + + if (newpcb == NULL) { + /* out-of-pcbs during connect: pass on this error to the application */ + if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + return ERR_VAL; + } + LWIP_ASSERT("expect newpcb == NULL or err == ERR_OK", err == ERR_OK); + LWIP_UNUSED_ARG(err); /* for LWIP_NOASSERT */ + + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->state: %s\n", tcp_debug_state_str(newpcb->state))); + + /* We have to set the callback here even though + * the new socket is unknown. newconn->socket is marked as -1. */ + newconn = netconn_alloc(conn->type, conn->callback); + if (newconn == NULL) { + /* outof netconns: pass on this error to the application */ + if (sys_mbox_trypost(&conn->acceptmbox, lwip_netconn_err_to_msg(ERR_ABRT)) == ERR_OK) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + return ERR_MEM; + } + newconn->pcb.tcp = newpcb; + setup_tcp(newconn); + + /* handle backlog counter */ + tcp_backlog_delayed(newpcb); + + if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { + /* When returning != ERR_OK, the pcb is aborted in tcp_process(), + so do nothing here! */ + /* remove all references to this netconn from the pcb */ + struct tcp_pcb *pcb = newconn->pcb.tcp; + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_poll(pcb, NULL, 0); + tcp_err(pcb, NULL); + /* remove reference from to the pcb from this netconn */ + newconn->pcb.tcp = NULL; #if ESP_LWIP && LWIP_NETCONN_FULLDUPLEX - newconn->flags |= NETCONN_FLAG_MBOXINVALID; + newconn->flags |= NETCONN_FLAG_MBOXINVALID; #endif /* ESP_LWIP && LWIP_NETCONN_FULLDUPLEX */ - /* no need to drain since we know the recvmbox is empty. */ - sys_mbox_free(&newconn->recvmbox); - sys_mbox_set_invalid(&newconn->recvmbox); - netconn_free(newconn); - return ERR_MEM; - } - else - { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } + /* no need to drain since we know the recvmbox is empty. */ + sys_mbox_free(&newconn->recvmbox); + sys_mbox_set_invalid(&newconn->recvmbox); + netconn_free(newconn); + return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } - return ERR_OK; + return ERR_OK; } #endif /* LWIP_TCP */ @@ -648,87 +628,77 @@ static err_t accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) * * @param msg the api_msg describing the connection type */ -static void pcb_new(struct api_msg *msg) +static void +pcb_new(struct api_msg *msg) { - enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4; + enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4; - LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); + LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); #if LWIP_IPV6 && LWIP_IPV4 - /* IPv6: Dual-stack by default, unless netconn_set_ipv6only() is called */ - if (NETCONNTYPE_ISIPV6(netconn_type(msg->conn))) - { - iptype = IPADDR_TYPE_ANY; - } + /* IPv6: Dual-stack by default, unless netconn_set_ipv6only() is called */ + if (NETCONNTYPE_ISIPV6(netconn_type(msg->conn))) { + iptype = IPADDR_TYPE_ANY; + } #endif - /* Allocate a PCB for this connection */ - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + /* Allocate a PCB for this connection */ + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto); - if (msg->conn->pcb.raw != NULL) - { + case NETCONN_RAW: + msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto); + if (msg->conn->pcb.raw != NULL) { #if LWIP_IPV6 - /* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */ - if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) - { - msg->conn->pcb.raw->chksum_reqd = 1; - msg->conn->pcb.raw->chksum_offset = 2; - } + /* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */ + if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) { + msg->conn->pcb.raw->chksum_reqd = 1; + msg->conn->pcb.raw->chksum_offset = 2; + } #endif /* LWIP_IPV6 */ - raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); - } - break; + raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); + } + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp = udp_new_ip_type(iptype); - if (msg->conn->pcb.udp != NULL) - { + case NETCONN_UDP: + msg->conn->pcb.udp = udp_new_ip_type(iptype); + if (msg->conn->pcb.udp != NULL) { #if LWIP_UDPLITE - if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) - { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); - } + if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); + } #endif /* LWIP_UDPLITE */ - if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) - { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); - } - break; + if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); + } + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - msg->conn->pcb.tcp = tcp_new_ip_type(iptype); - if (msg->conn->pcb.tcp != NULL) - { - setup_tcp(msg->conn); - } - break; + case NETCONN_TCP: + msg->conn->pcb.tcp = tcp_new_ip_type(iptype); + if (msg->conn->pcb.tcp != NULL) { + setup_tcp(msg->conn); + } + break; #endif /* LWIP_TCP */ - default: - /* Unsupported netconn type, e.g. protocol disabled */ - msg->err = ERR_VAL; - return; - } - if (msg->conn->pcb.ip == NULL) - { - msg->err = ERR_MEM; - } + default: + /* Unsupported netconn type, e.g. protocol disabled */ + msg->err = ERR_VAL; + return; + } + if (msg->conn->pcb.ip == NULL) { + msg->err = ERR_MEM; + } #if ESP_LWIP && LWIP_IPV4 && LWIP_IPV6 - else - { - if (NETCONNTYPE_ISIPV6(msg->conn->type)) - { - /* Convert IPv4 PCB manually to an IPv6 PCB */ - IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_V6); - IP_SET_TYPE_VAL(msg->conn->pcb.ip->remote_ip, IPADDR_TYPE_V6); - } + else { + if (NETCONNTYPE_ISIPV6(msg->conn->type)) { + /* Convert IPv4 PCB manually to an IPv6 PCB */ + IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_V6); + IP_SET_TYPE_VAL(msg->conn->pcb.ip->remote_ip, IPADDR_TYPE_V6); } + } #endif /* ESP_LWIP && LWIP_IPV4 && LWIP_IPV6 */ } @@ -738,20 +708,20 @@ static void pcb_new(struct api_msg *msg) * * @param m the api_msg describing the connection type */ -void lwip_netconn_do_newconn(void *m) +void +lwip_netconn_do_newconn(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - msg->err = ERR_OK; - if (msg->conn->pcb.tcp == NULL) - { - pcb_new(msg); - } - /* Else? This "new" connection already has a PCB allocated. */ - /* Is this an error condition? Should it be deleted? */ - /* We currently just are happy and return. */ + msg->err = ERR_OK; + if (msg->conn->pcb.tcp == NULL) { + pcb_new(msg); + } + /* Else? This "new" connection already has a PCB allocated. */ + /* Is this an error condition? Should it be deleted? */ + /* We currently just are happy and return. */ - TCPIP_APIMSG_ACK(msg); + TCPIP_APIMSG_ACK(msg); } /** @@ -763,93 +733,88 @@ void lwip_netconn_do_newconn(void *m) * @return a newly allocated struct netconn or * NULL on memory error */ -struct netconn *netconn_alloc(enum netconn_type t, netconn_callback callback) +struct netconn * +netconn_alloc(enum netconn_type t, netconn_callback callback) { - struct netconn *conn; - int size; - u8_t init_flags = 0; + struct netconn *conn; + int size; + u8_t init_flags = 0; - conn = (struct netconn *)memp_malloc(MEMP_NETCONN); - if (conn == NULL) - { - return NULL; - } + conn = (struct netconn *)memp_malloc(MEMP_NETCONN); + if (conn == NULL) { + return NULL; + } - conn->pending_err = ERR_OK; - conn->type = t; - conn->pcb.tcp = NULL; + conn->pending_err = ERR_OK; + conn->type = t; + conn->pcb.tcp = NULL; #if LWIP_NETCONN_FULLDUPLEX - conn->mbox_threads_waiting = 0; + conn->mbox_threads_waiting = 0; #endif - /* If all sizes are the same, every compiler should optimize this switch to nothing */ - switch (NETCONNTYPE_GROUP(t)) - { + /* If all sizes are the same, every compiler should optimize this switch to nothing */ + switch (NETCONNTYPE_GROUP(t)) { #if LWIP_RAW - case NETCONN_RAW: - size = DEFAULT_RAW_RECVMBOX_SIZE; - break; + case NETCONN_RAW: + size = DEFAULT_RAW_RECVMBOX_SIZE; + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - size = DEFAULT_UDP_RECVMBOX_SIZE; + case NETCONN_UDP: + size = DEFAULT_UDP_RECVMBOX_SIZE; #if LWIP_NETBUF_RECVINFO - init_flags |= NETCONN_FLAG_PKTINFO; + init_flags |= NETCONN_FLAG_PKTINFO; #endif /* LWIP_NETBUF_RECVINFO */ - break; + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - size = DEFAULT_TCP_RECVMBOX_SIZE; - break; + case NETCONN_TCP: + size = DEFAULT_TCP_RECVMBOX_SIZE; + break; #endif /* LWIP_TCP */ - default: - LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); - goto free_and_return; - } - - if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) - { - goto free_and_return; - } + default: + LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); + goto free_and_return; + } + + if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { + goto free_and_return; + } #if !LWIP_NETCONN_SEM_PER_THREAD - if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) - { - sys_mbox_free(&conn->recvmbox); - goto free_and_return; - } + if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { + sys_mbox_free(&conn->recvmbox); + goto free_and_return; + } #endif #if LWIP_TCP - sys_mbox_set_invalid(&conn->acceptmbox); + sys_mbox_set_invalid(&conn->acceptmbox); #endif - conn->state = NETCONN_NONE; -#if LWIP_SOCKET - /* initialize socket to -1 since 0 is a valid socket */ - conn->socket = -1; -#endif /* LWIP_SOCKET */ - conn->callback = callback; + conn->state = NETCONN_NONE; + /* initialize socket to -1 since 0 is a valid socket */ + conn->callback_arg.socket = -1; + conn->callback = callback; #if LWIP_TCP - conn->current_msg = NULL; + conn->current_msg = NULL; #endif /* LWIP_TCP */ #if LWIP_SO_SNDTIMEO - conn->send_timeout = 0; + conn->send_timeout = 0; #endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO - conn->recv_timeout = 0; + conn->recv_timeout = 0; #endif /* LWIP_SO_RCVTIMEO */ #if LWIP_SO_RCVBUF - conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; - conn->recv_avail = 0; + conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; + conn->recv_avail = 0; #endif /* LWIP_SO_RCVBUF */ #if LWIP_SO_LINGER - conn->linger = -1; + conn->linger = -1; #endif /* LWIP_SO_LINGER */ - conn->flags = init_flags; - return conn; + conn->flags = init_flags; + return conn; free_and_return: - memp_free(MEMP_NETCONN, conn); - return NULL; + memp_free(MEMP_NETCONN, conn); + return NULL; } /** @@ -858,40 +823,42 @@ struct netconn *netconn_alloc(enum netconn_type t, netconn_callback callback) * * @param conn the netconn to free */ -void netconn_free(struct netconn *conn) +void +netconn_free(struct netconn *conn) { - LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); + LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); #if LWIP_NETCONN_FULLDUPLEX - /* in fullduplex, netconn is drained here */ - netconn_drain(conn); + /* in fullduplex, netconn is drained here */ + netconn_drain(conn); #endif /* LWIP_NETCONN_FULLDUPLEX */ - LWIP_ASSERT("recvmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->recvmbox)); + LWIP_ASSERT("recvmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->recvmbox)); #if LWIP_TCP - LWIP_ASSERT("acceptmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->acceptmbox)); + LWIP_ASSERT("acceptmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->acceptmbox)); #endif /* LWIP_TCP */ #if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(&conn->op_completed); - sys_sem_set_invalid(&conn->op_completed); + sys_sem_free(&conn->op_completed); + sys_sem_set_invalid(&conn->op_completed); #endif - memp_free(MEMP_NETCONN, conn); + memp_free(MEMP_NETCONN, conn); } #if ESP_LWIP -struct tcp_psb_msg -{ - struct tcpip_api_call_data call; - struct tcp_pcb *pcb; +struct tcp_psb_msg { + struct tcpip_api_call_data call; + struct tcp_pcb *pcb; }; static err_t tcp_do_abort(struct tcpip_api_call_data *msg) { - struct tcp_psb_msg *pcb_msg = __containerof(msg, struct tcp_psb_msg, call); - tcp_abort(pcb_msg->pcb); - return ERR_OK; + struct tcp_psb_msg *pcb_msg = __containerof(msg, struct tcp_psb_msg, call); + tcp_abort(pcb_msg->pcb); + return ERR_OK; } #endif /* ESP_LWIP */ @@ -903,108 +870,97 @@ static err_t tcp_do_abort(struct tcpip_api_call_data *msg) * @bytes_drained bytes drained from recvmbox * @accepts_drained pending connections drained from acceptmbox */ -static void netconn_drain(struct netconn *conn) +static void +netconn_drain(struct netconn *conn) { - void *mem; + void *mem; - /* This runs when mbox and netconn are marked as closed, - so we don't need to lock against rx packets */ + /* This runs when mbox and netconn are marked as closed, + so we don't need to lock against rx packets */ #if LWIP_NETCONN_FULLDUPLEX - LWIP_ASSERT("netconn marked closed", conn->flags & NETCONN_FLAG_MBOXINVALID); + LWIP_ASSERT("netconn marked closed", conn->flags & NETCONN_FLAG_MBOXINVALID); #endif /* LWIP_NETCONN_FULLDUPLEX */ - /* Delete and drain the recvmbox. */ - if (sys_mbox_valid(&conn->recvmbox)) - { - while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) - { + /* Delete and drain the recvmbox. */ + if (sys_mbox_valid(&conn->recvmbox)) { + while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { #if LWIP_NETCONN_FULLDUPLEX - if (!lwip_netconn_is_deallocated_msg(mem)) + if (!lwip_netconn_is_deallocated_msg(mem)) #endif /* LWIP_NETCONN_FULLDUPLEX */ - { + { #if LWIP_TCP - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) - { - err_t err; - if (!lwip_netconn_is_err_msg(mem, &err)) - { - pbuf_free((struct pbuf *)mem); - } - } - else + if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) { + err_t err; + if (!lwip_netconn_is_err_msg(mem, &err)) { + pbuf_free((struct pbuf *)mem); + } + } else #endif /* LWIP_TCP */ - { - netbuf_delete((struct netbuf *)mem); - } - } + { + netbuf_delete((struct netbuf *)mem); } - sys_mbox_free(&conn->recvmbox); - sys_mbox_set_invalid(&conn->recvmbox); + } } + sys_mbox_free(&conn->recvmbox); + sys_mbox_set_invalid(&conn->recvmbox); + } - /* Delete and drain the acceptmbox. */ + /* Delete and drain the acceptmbox. */ #if LWIP_TCP - if (sys_mbox_valid(&conn->acceptmbox)) - { - while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) - { + if (sys_mbox_valid(&conn->acceptmbox)) { + while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { #if LWIP_NETCONN_FULLDUPLEX - if (!lwip_netconn_is_deallocated_msg(mem)) + if (!lwip_netconn_is_deallocated_msg(mem)) #endif /* LWIP_NETCONN_FULLDUPLEX */ - { - err_t err; - if (!lwip_netconn_is_err_msg(mem, &err)) - { - struct netconn *newconn = (struct netconn *)mem; - /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ - /* pcb might be set to NULL already by err_tcp() */ - /* drain recvmbox */ + { + err_t err; + if (!lwip_netconn_is_err_msg(mem, &err)) { + struct netconn *newconn = (struct netconn *)mem; + /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ + /* pcb might be set to NULL already by err_tcp() */ + /* drain recvmbox */ #if ESP_LWIP && LWIP_NETCONN_FULLDUPLEX - newconn->flags |= NETCONN_FLAG_MBOXINVALID; + newconn->flags |= NETCONN_FLAG_MBOXINVALID; #endif /* ESP_LWIP */ - netconn_drain(newconn); - if (newconn->pcb.tcp != NULL) - { + netconn_drain(newconn); + if (newconn->pcb.tcp != NULL) { #if ESP_LWIP - struct tcp_psb_msg pcb_msg = {0}; - pcb_msg.pcb = newconn->pcb.tcp; - tcpip_api_call(tcp_do_abort, &pcb_msg.call); + struct tcp_psb_msg pcb_msg = { 0 }; + pcb_msg.pcb = newconn->pcb.tcp; + tcpip_api_call(tcp_do_abort, &pcb_msg.call); #else - tcp_abort(newconn->pcb.tcp); + tcp_abort(newconn->pcb.tcp); #endif /* ESP_LWIP */ - newconn->pcb.tcp = NULL; - } - netconn_free(newconn); - } - } + newconn->pcb.tcp = NULL; + } + netconn_free(newconn); } - sys_mbox_free(&conn->acceptmbox); - sys_mbox_set_invalid(&conn->acceptmbox); + } } + sys_mbox_free(&conn->acceptmbox); + sys_mbox_set_invalid(&conn->acceptmbox); + } #endif /* LWIP_TCP */ } #if LWIP_NETCONN_FULLDUPLEX -static void netconn_mark_mbox_invalid(struct netconn *conn) +static void +netconn_mark_mbox_invalid(struct netconn *conn) { - int i, num_waiting; - void *msg = LWIP_CONST_CAST(void *, &netconn_deleted); + int i, num_waiting; + void *msg = LWIP_CONST_CAST(void *, &netconn_deleted); - /* Prevent new calls/threads from reading from the mbox */ - conn->flags |= NETCONN_FLAG_MBOXINVALID; + /* Prevent new calls/threads from reading from the mbox */ + conn->flags |= NETCONN_FLAG_MBOXINVALID; - SYS_ARCH_LOCKED(num_waiting = conn->mbox_threads_waiting); - for (i = 0; i < num_waiting; i++) - { - if (sys_mbox_valid_val(conn->recvmbox)) - { - sys_mbox_trypost(&conn->recvmbox, msg); - } - else - { - sys_mbox_trypost(&conn->acceptmbox, msg); - } + SYS_ARCH_LOCKED(num_waiting = conn->mbox_threads_waiting); + for (i = 0; i < num_waiting; i++) { + if (sys_mbox_valid_val(conn->recvmbox)) { + sys_mbox_trypost(&conn->recvmbox, msg); + } else { + sys_mbox_trypost(&conn->acceptmbox, msg); } + } } #endif /* LWIP_NETCONN_FULLDUPLEX */ @@ -1016,235 +972,194 @@ static void netconn_mark_mbox_invalid(struct netconn *conn) * * @param conn the TCP netconn to close */ -static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM) +static err_t +lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM) { - err_t err; - u8_t shut, shut_rx, shut_tx, shut_close; - u8_t close_finished = 0; - struct tcp_pcb *tpcb; + err_t err; + u8_t shut, shut_rx, shut_tx, shut_close; + u8_t close_finished = 0; + struct tcp_pcb *tpcb; #if LWIP_SO_LINGER - u8_t linger_wait_required = 0; + u8_t linger_wait_required = 0; #endif /* LWIP_SO_LINGER */ - LWIP_ASSERT("invalid conn", (conn != NULL)); - LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)); - LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); - LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - - tpcb = conn->pcb.tcp; - shut = conn->current_msg->msg.sd.shut; - shut_rx = shut & NETCONN_SHUT_RD; - shut_tx = shut & NETCONN_SHUT_WR; - /* shutting down both ends is the same as closing - (also if RD or WR side was shut down before already) */ - if (shut == NETCONN_SHUT_RDWR) - { - shut_close = 1; - } - else if (shut_rx && ((tpcb->state == FIN_WAIT_1) || (tpcb->state == FIN_WAIT_2) || (tpcb->state == CLOSING))) - { - shut_close = 1; + LWIP_ASSERT("invalid conn", (conn != NULL)); + LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)); + LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); + LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + + tpcb = conn->pcb.tcp; + shut = conn->current_msg->msg.sd.shut; + shut_rx = shut & NETCONN_SHUT_RD; + shut_tx = shut & NETCONN_SHUT_WR; + /* shutting down both ends is the same as closing + (also if RD or WR side was shut down before already) */ + if (shut == NETCONN_SHUT_RDWR) { + shut_close = 1; + } else if (shut_rx && + ((tpcb->state == FIN_WAIT_1) || + (tpcb->state == FIN_WAIT_2) || + (tpcb->state == CLOSING))) { + shut_close = 1; + } else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) { + shut_close = 1; + } else { + shut_close = 0; + } + + /* Set back some callback pointers */ + if (shut_close) { + tcp_arg(tpcb, NULL); + } + if (tpcb->state == LISTEN) { + tcp_accept(tpcb, NULL); + } else { + /* some callbacks have to be reset if tcp_close is not successful */ + if (shut_rx) { + tcp_recv(tpcb, NULL); + tcp_accept(tpcb, NULL); + } + if (shut_tx) { + tcp_sent(tpcb, NULL); + } + if (shut_close) { + tcp_poll(tpcb, NULL, 0); + tcp_err(tpcb, NULL); + } + } + /* Try to close the connection */ + if (shut_close) { +#if LWIP_SO_LINGER + /* check linger possibilities before calling tcp_close */ + err = ERR_OK; + /* linger enabled/required at all? (i.e. is there untransmitted data left?) */ + if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) { + if (conn->linger == 0) { + /* data left but linger prevents waiting */ + tcp_abort(tpcb); + tpcb = NULL; + } else if (conn->linger > 0) { + /* data left and linger says we should wait */ + if (netconn_is_nonblocking(conn)) { + /* data left on a nonblocking netconn -> cannot linger */ + err = ERR_WOULDBLOCK; + } else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= + (conn->linger * 1000)) { + /* data left but linger timeout has expired (this happens on further + calls to this function through poll_tcp */ + tcp_abort(tpcb); + tpcb = NULL; + } else { + /* data left -> need to wait for ACK after successful close */ + linger_wait_required = 1; + } + } } - else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) + if ((err == ERR_OK) && (tpcb != NULL)) +#endif /* LWIP_SO_LINGER */ { - shut_close = 1; + err = tcp_close_ext(tpcb, +#if LWIP_SO_LINGER + /* don't send RST yet if linger-wait-required */ linger_wait_required ? 0 : +#endif + 1); } - else - { - shut_close = 0; + } else { + err = tcp_shutdown(tpcb, shut_rx, shut_tx); + } + if (err == ERR_OK) { + close_finished = 1; +#if LWIP_SO_LINGER + if (linger_wait_required) { + /* wait for ACK of all unsent/unacked data by just getting called again */ + close_finished = 0; + err = ERR_INPROGRESS; } - - /* Set back some callback pointers */ - if (shut_close) - { - tcp_arg(tpcb, NULL); +#endif /* LWIP_SO_LINGER */ + } else { + if (err == ERR_MEM) { + /* Closing failed because of memory shortage, try again later. Even for + nonblocking netconns, we have to wait since no standard socket application + is prepared for close failing because of resource shortage. + Check the timeout: this is kind of an lwip addition to the standard sockets: + we wait for some time when failing to allocate a segment for the FIN */ +#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER + s32_t close_timeout = LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT; +#if LWIP_SO_SNDTIMEO + if (conn->send_timeout > 0) { + close_timeout = conn->send_timeout; + } +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_LINGER + if (conn->linger >= 0) { + /* use linger timeout (seconds) */ + close_timeout = conn->linger * 1000U; + } +#endif + if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) { +#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ + if (conn->current_msg->msg.sd.polls_left == 0) { +#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ + close_finished = 1; + if (shut_close) { + /* in this case, we want to RST the connection */ + tcp_abort(tpcb); + err = ERR_OK; + } + } + } else { + /* Closing failed for a non-memory error: give up */ + close_finished = 1; + } + } + if (close_finished) { + /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */ + sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + conn->current_msg->err = err; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (err == ERR_OK) { + if (shut_close) { + /* Set back some callback pointers as conn is going away */ + conn->pcb.tcp = NULL; + /* Trigger select() in socket layer. Make sure everybody notices activity + on the connection, error first! */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + } + if (shut_rx) { + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + if (shut_tx) { + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } } - if (tpcb->state == LISTEN) +#if LWIP_TCPIP_CORE_LOCKING + if (delayed) +#endif { - tcp_accept(tpcb, NULL); + /* wake up the application task */ + sys_sem_signal(op_completed_sem); } - else - { - /* some callbacks have to be reset if tcp_close is not successful */ - if (shut_rx) - { - tcp_recv(tpcb, NULL); - tcp_accept(tpcb, NULL); - } - if (shut_tx) - { - tcp_sent(tpcb, NULL); - } - if (shut_close) - { - tcp_poll(tpcb, NULL, 0); - tcp_err(tpcb, NULL); - } - } - /* Try to close the connection */ - if (shut_close) - { -#if LWIP_SO_LINGER - /* check linger possibilites before calling tcp_close */ - err = ERR_OK; - /* linger enabled/required at all? (i.e. is there untransmitted data left?) */ - if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) - { - if (conn->linger == 0) - { - /* data left but linger prevents waiting */ - tcp_abort(tpcb); - tpcb = NULL; - } - else if (conn->linger > 0) - { - /* data left and linger says we should wait */ - if (netconn_is_nonblocking(conn)) - { - /* data left on a nonblocking netconn -> cannot linger */ - err = ERR_WOULDBLOCK; - } - else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= (conn->linger * 1000)) - { - /* data left but linger timeout has expired (this happens on further - calls to this function through poll_tcp */ - tcp_abort(tpcb); - tpcb = NULL; - } - else - { - /* data left -> need to wait for ACK after successful close */ - linger_wait_required = 1; - } - } - } - if ((err == ERR_OK) && (tpcb != NULL)) -#endif /* LWIP_SO_LINGER */ - { - err = tcp_close_ext( - tpcb, -#if LWIP_SO_LINGER - /* don't send RST yet if linger-wait-required */ linger_wait_required ? 0 : -#endif - 1); - } - } - else - { - err = tcp_shutdown(tpcb, shut_rx, shut_tx); - } - if (err == ERR_OK) - { - close_finished = 1; -#if LWIP_SO_LINGER - if (linger_wait_required) - { - /* wait for ACK of all unsent/unacked data by just getting called again */ - close_finished = 0; - err = ERR_INPROGRESS; - } -#endif /* LWIP_SO_LINGER */ - } - else - { - if (err == ERR_MEM) - { - /* Closing failed because of memory shortage, try again later. Even for - nonblocking netconns, we have to wait since no standard socket application - is prepared for close failing because of resource shortage. - Check the timeout: this is kind of an lwip addition to the standard sockets: - we wait for some time when failing to allocate a segment for the FIN */ -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - s32_t close_timeout = LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT; -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout > 0) - { - close_timeout = conn->send_timeout; - } -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_LINGER - if (conn->linger >= 0) - { - /* use linger timeout (seconds) */ - close_timeout = conn->linger * 1000U; - } -#endif - if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) - { -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - if (conn->current_msg->msg.sd.polls_left == 0) - { -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - close_finished = 1; - if (shut_close) - { - /* in this case, we want to RST the connection */ - tcp_abort(tpcb); - err = ERR_OK; - } - } - } - else - { - /* Closing failed for a non-memory error: give up */ - close_finished = 1; - } - } - if (close_finished) - { - /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */ - sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - if (err == ERR_OK) - { - if (shut_close) - { - /* Set back some callback pointers as conn is going away */ - conn->pcb.tcp = NULL; - /* Trigger select() in socket layer. Make sure everybody notices activity - on the connection, error first! */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - } - if (shut_rx) - { - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - if (shut_tx) - { - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - } -#if LWIP_TCPIP_CORE_LOCKING - if (delayed) -#endif - { - /* wake up the application task */ - sys_sem_signal(op_completed_sem); - } - return ERR_OK; - } - if (!close_finished) - { - /* Closing failed and we want to wait: restore some of the callbacks */ - /* Closing of listen pcb will never fail! */ - LWIP_ASSERT("Closing a listen pcb may not fail!", (tpcb->state != LISTEN)); - if (shut_tx) - { - tcp_sent(tpcb, sent_tcp); - } - /* when waiting for close, set up poll interval to 500ms */ - tcp_poll(tpcb, poll_tcp, 1); - tcp_err(tpcb, err_tcp); - tcp_arg(tpcb, conn); - /* don't restore recv callback: we don't want to receive any more data */ - } - /* If closing didn't succeed, we get called again either - from poll_tcp or from sent_tcp */ - LWIP_ASSERT("err != ERR_OK", err != ERR_OK); - return err; + return ERR_OK; + } + if (!close_finished) { + /* Closing failed and we want to wait: restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + LWIP_ASSERT("Closing a listen pcb may not fail!", (tpcb->state != LISTEN)); + if (shut_tx) { + tcp_sent(tpcb, sent_tcp); + } + /* when waiting for close, set up poll interval to 500ms */ + tcp_poll(tpcb, poll_tcp, 1); + tcp_err(tpcb, err_tcp); + tcp_arg(tpcb, conn); + /* don't restore recv callback: we don't want to receive any more data */ + } + /* If closing didn't succeed, we get called again either + from poll_tcp or from sent_tcp */ + LWIP_ASSERT("err != ERR_OK", err != ERR_OK); + return err; } #endif /* LWIP_TCP */ @@ -1254,112 +1169,108 @@ static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_P * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_delconn(void *m) +void +lwip_netconn_do_delconn(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - enum netconn_state state = msg->conn->state; - LWIP_ASSERT( - "netconn state error", /* this only happens for TCP netconns */ - (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)); + enum netconn_state state = msg->conn->state; + LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */ + (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)); #if ESP_LWIP - msg->err = ERR_OK; + msg->err = ERR_OK; #endif #if LWIP_NETCONN_FULLDUPLEX - /* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */ - if (state != NETCONN_NONE) - { - if ((state == NETCONN_WRITE) || ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) - { - /* close requested, abort running write/connect */ - sys_sem_t *op_completed_sem; - LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); - op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); - msg->conn->current_msg->err = ERR_CLSD; - msg->conn->current_msg = NULL; - msg->conn->state = NETCONN_NONE; + /* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */ + if (state != NETCONN_NONE) { + if ((state == NETCONN_WRITE) || + ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { + /* close requested, abort running write/connect */ + sys_sem_t *op_completed_sem; + LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); + op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); + msg->conn->current_msg->err = ERR_CLSD; + msg->conn->current_msg = NULL; + msg->conn->state = NETCONN_NONE; #if ESP_LWIP - msg->err = ERR_INPROGRESS; + msg->err = ERR_INPROGRESS; #endif - sys_sem_signal(op_completed_sem); - } - } -#else /* LWIP_NETCONN_FULLDUPLEX */ - if (((state != NETCONN_NONE) && (state != NETCONN_LISTEN) && (state != NETCONN_CONNECT)) || - ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) - { - /* This means either a blocking write or blocking connect is running - (nonblocking write returns and sets state to NONE) */ - msg->err = ERR_INPROGRESS; - } - else + sys_sem_signal(op_completed_sem); + } + } +#else /* LWIP_NETCONN_FULLDUPLEX */ + if (((state != NETCONN_NONE) && + (state != NETCONN_LISTEN) && + (state != NETCONN_CONNECT)) || + ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { + /* This means either a blocking write or blocking connect is running + (nonblocking write returns and sets state to NONE) */ + msg->err = ERR_INPROGRESS; + } else #endif /* LWIP_NETCONN_FULLDUPLEX */ - { + { #if !ESP_LWIP - LWIP_ASSERT("blocking connect in progress", (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); - msg->err = ERR_OK; + LWIP_ASSERT("blocking connect in progress", + (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); + msg->err = ERR_OK; #endif /* ESP_LWIP */ #if LWIP_NETCONN_FULLDUPLEX - /* Mark mboxes invalid */ - netconn_mark_mbox_invalid(msg->conn); -#else /* LWIP_NETCONN_FULLDUPLEX */ - netconn_drain(msg->conn); + /* Mark mboxes invalid */ + netconn_mark_mbox_invalid(msg->conn); +#else /* LWIP_NETCONN_FULLDUPLEX */ + netconn_drain(msg->conn); #endif /* LWIP_NETCONN_FULLDUPLEX */ - if (msg->conn->pcb.tcp != NULL) - { + if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - raw_remove(msg->conn->pcb.raw); - break; + case NETCONN_RAW: + raw_remove(msg->conn->pcb.raw); + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp->recv_arg = NULL; - udp_remove(msg->conn->pcb.udp); - break; + case NETCONN_UDP: + msg->conn->pcb.udp->recv_arg = NULL; + udp_remove(msg->conn->pcb.udp); + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); - msg->conn->state = NETCONN_CLOSE; - msg->msg.sd.shut = NETCONN_SHUT_RDWR; - msg->conn->current_msg = msg; + case NETCONN_TCP: + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); + msg->conn->state = NETCONN_CLOSE; + msg->msg.sd.shut = NETCONN_SHUT_RDWR; + msg->conn->current_msg = msg; #if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) - { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_close_internal(msg->conn); + if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + lwip_netconn_do_close_internal(msg->conn); #endif /* LWIP_TCPIP_CORE_LOCKING */ - /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing - the application thread, so we can return at this point! */ - return; + /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing + the application thread, so we can return at this point! */ + return; #endif /* LWIP_TCP */ - default: - break; - } - msg->conn->pcb.tcp = NULL; - } - /* tcp netconns don't come here! */ - - /* @todo: this lets select make the socket readable and writable, - which is wrong! errfd instead? */ - API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); - } - if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) - { - TCPIP_APIMSG_ACK(msg); - } + default: + break; + } + msg->conn->pcb.tcp = NULL; + } + /* tcp netconns don't come here! */ + + /* @todo: this lets select make the socket readable and writable, + which is wrong! errfd instead? */ + API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); + } + if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) { + TCPIP_APIMSG_ACK(msg); + } } /** @@ -1369,55 +1280,52 @@ void lwip_netconn_do_delconn(void *m) * @param m the api_msg pointing to the connection and containing * the IP address and port to bind to */ -void lwip_netconn_do_bind(void *m) +void +lwip_netconn_do_bind(void *m) { - struct api_msg *msg = (struct api_msg *)m; - err_t err; + struct api_msg *msg = (struct api_msg *)m; + err_t err; - if (msg->conn->pcb.tcp != NULL) - { + if (msg->conn->pcb.tcp != NULL) { #if ESP_LWIP && LWIP_IPV4 && LWIP_IPV6 - /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY, - * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to bind - */ - if (ip_addr_cmp(API_EXPR_REF(msg->msg.bc.ipaddr), IP6_ADDR_ANY) && (netconn_get_ipv6only(msg->conn) == 0)) - { - /* change PCB type to IPADDR_TYPE_ANY */ - IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_ANY); - IP_SET_TYPE_VAL(msg->conn->pcb.ip->remote_ip, IPADDR_TYPE_ANY); - - /* bind to IPADDR_TYPE_ANY */ - API_EXPR_REF(msg->msg.bc.ipaddr) = IP_ANY_TYPE; - } + /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY, + * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to bind + */ + if (ip_addr_cmp(API_EXPR_REF(msg->msg.bc.ipaddr), IP6_ADDR_ANY) && + (netconn_get_ipv6only(msg->conn) == 0)) { + /* change PCB type to IPADDR_TYPE_ANY */ + IP_SET_TYPE_VAL(msg->conn->pcb.ip->local_ip, IPADDR_TYPE_ANY); + IP_SET_TYPE_VAL(msg->conn->pcb.ip->remote_ip, IPADDR_TYPE_ANY); + + /* bind to IPADDR_TYPE_ANY */ + API_EXPR_REF(msg->msg.bc.ipaddr) = IP_ANY_TYPE; + } #endif /* ESP_LWIP && LWIP_IPV4 && LWIP_IPV6 */ - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); - break; + case NETCONN_RAW: + err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; + case NETCONN_UDP: + err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; + case NETCONN_TCP: + err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + break; #endif /* LWIP_TCP */ - default: - err = ERR_VAL; - break; - } - } - else - { + default: err = ERR_VAL; + break; } - msg->err = err; - TCPIP_APIMSG_ACK(msg); + } else { + err = ERR_VAL; + } + msg->err = err; + TCPIP_APIMSG_ACK(msg); } /** * Bind a pcb contained in a netconn to an interface @@ -1426,45 +1334,42 @@ void lwip_netconn_do_bind(void *m) * @param m the api_msg pointing to the connection and containing * the IP address and port to bind to */ -void lwip_netconn_do_bind_if(void *m) +void +lwip_netconn_do_bind_if(void *m) { - struct netif *netif; - struct api_msg *msg = (struct api_msg *)m; - err_t err; + struct netif *netif; + struct api_msg *msg = (struct api_msg *)m; + err_t err; - netif = netif_get_by_index(msg->msg.bc.if_idx); + netif = netif_get_by_index(msg->msg.bc.if_idx); - if ((netif != NULL) && (msg->conn->pcb.tcp != NULL)) - { - err = ERR_OK; - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + if ((netif != NULL) && (msg->conn->pcb.tcp != NULL)) { + err = ERR_OK; + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - raw_bind_netif(msg->conn->pcb.raw, netif); - break; + case NETCONN_RAW: + raw_bind_netif(msg->conn->pcb.raw, netif); + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - udp_bind_netif(msg->conn->pcb.udp, netif); - break; + case NETCONN_UDP: + udp_bind_netif(msg->conn->pcb.udp, netif); + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - tcp_bind_netif(msg->conn->pcb.tcp, netif); - break; + case NETCONN_TCP: + tcp_bind_netif(msg->conn->pcb.tcp, netif); + break; #endif /* LWIP_TCP */ - default: - err = ERR_VAL; - break; - } - } - else - { + default: err = ERR_VAL; + break; } - msg->err = err; - TCPIP_APIMSG_ACK(msg); + } else { + err = ERR_VAL; + } + msg->err = err; + TCPIP_APIMSG_ACK(msg); } #if LWIP_TCP @@ -1474,49 +1379,45 @@ void lwip_netconn_do_bind_if(void *m) * * @see tcp.h (struct tcp_pcb.connected) for parameters and return values */ -static err_t lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +static err_t +lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) { - struct netconn *conn; - int was_blocking; - sys_sem_t *op_completed_sem = NULL; - - LWIP_UNUSED_ARG(pcb); - - conn = (struct netconn *)arg; - - if (conn == NULL) - { - return ERR_VAL; - } - - LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); - LWIP_ASSERT( - "(conn->current_msg != NULL) || conn->in_non_blocking_connect", - (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); - - if (conn->current_msg != NULL) - { - conn->current_msg->err = err; - op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - } - if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) - { - setup_tcp(conn); - } - was_blocking = !IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - LWIP_ASSERT( - "blocking connect state error", - (was_blocking && op_completed_sem != NULL) || (!was_blocking && op_completed_sem == NULL)); - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - if (was_blocking) - { - sys_sem_signal(op_completed_sem); - } - return ERR_OK; + struct netconn *conn; + int was_blocking; + sys_sem_t *op_completed_sem = NULL; + + LWIP_UNUSED_ARG(pcb); + + conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + + LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); + LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", + (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); + + if (conn->current_msg != NULL) { + conn->current_msg->err = err; + op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + } + if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) { + setup_tcp(conn); + } + was_blocking = !IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + LWIP_ASSERT("blocking connect state error", + (was_blocking && op_completed_sem != NULL) || + (!was_blocking && op_completed_sem == NULL)); + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + if (was_blocking) { + sys_sem_signal(op_completed_sem); + } + return ERR_OK; } #endif /* LWIP_TCP */ @@ -1527,88 +1428,72 @@ static err_t lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err * @param m the api_msg pointing to the connection and containing * the IP address and port to connect to */ -void lwip_netconn_do_connect(void *m) +void +lwip_netconn_do_connect(void *m) { - struct api_msg *msg = (struct api_msg *)m; - err_t err; - - if (msg->conn->pcb.tcp == NULL) - { - /* This may happen when calling netconn_connect() a second time */ - err = ERR_CLSD; - } - else - { - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + struct api_msg *msg = (struct api_msg *)m; + err_t err; + + if (msg->conn->pcb.tcp == NULL) { + /* This may happen when calling netconn_connect() a second time */ + err = ERR_CLSD; + } else { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); - break; + case NETCONN_RAW: + err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; + case NETCONN_UDP: + err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - /* Prevent connect while doing any other action. */ - if (msg->conn->state == NETCONN_CONNECT) - { - err = ERR_ALREADY; - } - else if (msg->conn->state != NETCONN_NONE) - { - err = ERR_ISCONN; - } - else - { - setup_tcp(msg->conn); - err = tcp_connect( - msg->conn->pcb.tcp, - API_EXPR_REF(msg->msg.bc.ipaddr), - msg->msg.bc.port, - lwip_netconn_do_connected); - if (err == ERR_OK) - { - u8_t non_blocking = netconn_is_nonblocking(msg->conn); - msg->conn->state = NETCONN_CONNECT; - SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); - if (non_blocking) - { - err = ERR_INPROGRESS; - } - else - { - msg->conn->current_msg = msg; - /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), - when the connection is established! */ + case NETCONN_TCP: + /* Prevent connect while doing any other action. */ + if (msg->conn->state == NETCONN_CONNECT) { + err = ERR_ALREADY; + } else if (msg->conn->state != NETCONN_NONE) { + err = ERR_ISCONN; + } else { + setup_tcp(msg->conn); + err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), + msg->msg.bc.port, lwip_netconn_do_connected); + if (err == ERR_OK) { + u8_t non_blocking = netconn_is_nonblocking(msg->conn); + msg->conn->state = NETCONN_CONNECT; + SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); + if (non_blocking) { + err = ERR_INPROGRESS; + } else { + msg->conn->current_msg = msg; + /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), + when the connection is established! */ #if LWIP_TCPIP_CORE_LOCKING - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CONNECT); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state != NETCONN_CONNECT); + LWIP_ASSERT("state!", msg->conn->state == NETCONN_CONNECT); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state != NETCONN_CONNECT); #endif /* LWIP_TCPIP_CORE_LOCKING */ - return; - } - } - } - break; -#endif /* LWIP_TCP */ - default: - LWIP_ERROR( - "Invalid netconn type", - 0, - do { err = ERR_VAL; } while (0)); - break; + return; + } + } } - } - msg->err = err; - /* For all other protocols, netconn_connect() calls netconn_apimsg(), - so use TCPIP_APIMSG_ACK() here. */ - TCPIP_APIMSG_ACK(msg); + break; +#endif /* LWIP_TCP */ + default: + LWIP_ERROR("Invalid netconn type", 0, do { + err = ERR_VAL; + } while (0)); + break; + } + } + msg->err = err; + /* For all other protocols, netconn_connect() calls netconn_apimsg(), + so use TCPIP_APIMSG_ACK() here. */ + TCPIP_APIMSG_ACK(msg); } /** @@ -1618,22 +1503,21 @@ void lwip_netconn_do_connect(void *m) * * @param m the api_msg pointing to the connection to disconnect */ -void lwip_netconn_do_disconnect(void *m) +void +lwip_netconn_do_disconnect(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; #if LWIP_UDP - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) - { - udp_disconnect(msg->conn->pcb.udp); - msg->err = ERR_OK; - } - else + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + udp_disconnect(msg->conn->pcb.udp); + msg->err = ERR_OK; + } else #endif /* LWIP_UDP */ - { - msg->err = ERR_VAL; - } - TCPIP_APIMSG_ACK(msg); + { + msg->err = ERR_VAL; + } + TCPIP_APIMSG_ACK(msg); } #if LWIP_TCP @@ -1643,102 +1527,80 @@ void lwip_netconn_do_disconnect(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_listen(void *m) +void +lwip_netconn_do_listen(void *m) { - struct api_msg *msg = (struct api_msg *)m; - err_t err; - - if (msg->conn->pcb.tcp != NULL) - { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) - { - if (msg->conn->state == NETCONN_NONE) - { - struct tcp_pcb *lpcb; - if (msg->conn->pcb.tcp->state != CLOSED) - { - /* connection is not closed, cannot listen */ - err = ERR_VAL; - } - else - { - u8_t backlog; + struct api_msg *msg = (struct api_msg *)m; + err_t err; + + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { + if (msg->conn->state == NETCONN_NONE) { + struct tcp_pcb *lpcb; + if (msg->conn->pcb.tcp->state != CLOSED) { + /* connection is not closed, cannot listen */ + err = ERR_VAL; + } else { + u8_t backlog; #if TCP_LISTEN_BACKLOG - backlog = msg->msg.lb.backlog; + backlog = msg->msg.lb.backlog; #else /* TCP_LISTEN_BACKLOG */ - backlog = TCP_DEFAULT_LISTEN_BACKLOG; + backlog = TCP_DEFAULT_LISTEN_BACKLOG; #endif /* TCP_LISTEN_BACKLOG */ #if LWIP_IPV4 && LWIP_IPV6 - /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY, - * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen - */ - if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && - (netconn_get_ipv6only(msg->conn) == 0)) - { - /* change PCB type to IPADDR_TYPE_ANY */ - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY); - } + /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY, + * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen + */ + if (ip_addr_eq(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && + (netconn_get_ipv6only(msg->conn) == 0)) { + /* change PCB type to IPADDR_TYPE_ANY */ + IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); + IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY); + } #endif /* LWIP_IPV4 && LWIP_IPV6 */ - lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err); - - if (lpcb == NULL) - { - /* in this case, the old pcb is still allocated */ - } - else - { - /* delete the recvmbox and allocate the acceptmbox */ - if (sys_mbox_valid(&msg->conn->recvmbox)) - { - /** @todo: should we drain the recvmbox here? */ - sys_mbox_free(&msg->conn->recvmbox); - sys_mbox_set_invalid(&msg->conn->recvmbox); - } - err = ERR_OK; - if (!sys_mbox_valid(&msg->conn->acceptmbox)) - { - err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); - } - if (err == ERR_OK) - { - msg->conn->state = NETCONN_LISTEN; - msg->conn->pcb.tcp = lpcb; - tcp_arg(msg->conn->pcb.tcp, msg->conn); - tcp_accept(msg->conn->pcb.tcp, accept_function); - } - else - { - /* since the old pcb is already deallocated, free lpcb now */ - tcp_close(lpcb); - msg->conn->pcb.tcp = NULL; - } - } - } + lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err); + + if (lpcb == NULL) { + /* in this case, the old pcb is still allocated */ + } else { + /* delete the recvmbox and allocate the acceptmbox */ + if (sys_mbox_valid(&msg->conn->recvmbox)) { + /** @todo: should we drain the recvmbox here? */ + sys_mbox_free(&msg->conn->recvmbox); + sys_mbox_set_invalid(&msg->conn->recvmbox); } - else if (msg->conn->state == NETCONN_LISTEN) - { - /* already listening, allow updating of the backlog */ - err = ERR_OK; - tcp_backlog_set(msg->conn->pcb.tcp, msg->msg.lb.backlog); + err = ERR_OK; + if (!sys_mbox_valid(&msg->conn->acceptmbox)) { + err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); } - else - { - err = ERR_CONN; + if (err == ERR_OK) { + msg->conn->state = NETCONN_LISTEN; + msg->conn->pcb.tcp = lpcb; + tcp_arg(msg->conn->pcb.tcp, msg->conn); + tcp_accept(msg->conn->pcb.tcp, accept_function); + } else { + /* since the old pcb is already deallocated, free lpcb now */ + tcp_close(lpcb); + msg->conn->pcb.tcp = NULL; } + } } - else - { - err = ERR_ARG; - } - } - else - { + } else if (msg->conn->state == NETCONN_LISTEN) { + /* already listening, allow updating of the backlog */ + err = ERR_OK; + tcp_backlog_set(msg->conn->pcb.tcp, msg->msg.lb.backlog); + } else { err = ERR_CONN; - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); + } + } else { + err = ERR_ARG; + } + } else { + err = ERR_CONN; + } + msg->err = err; + TCPIP_APIMSG_ACK(msg); } #endif /* LWIP_TCP */ @@ -1748,83 +1610,62 @@ void lwip_netconn_do_listen(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_send(void *m) +void +lwip_netconn_do_send(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - err_t err = netconn_err(msg->conn); + err_t err = netconn_err(msg->conn); #if ESP_LWIP && LWIP_IPV4 && LWIP_IPV6 - if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) && IP_IS_V4MAPPEDV6(&msg->msg.b->addr)) - { - LWIP_DEBUGF(API_MSG_DEBUG, ("lwip_netconn_do_send: Dropping IPv4 packet on IPv6-only socket")); - msg->err = ERR_VAL; - } + if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) &&IP_IS_V4MAPPEDV6(&msg->msg.b->addr)) { + LWIP_DEBUGF(API_MSG_DEBUG, ("lwip_netconn_do_send: Dropping IPv4 packet on IPv6-only socket")); + msg->err = ERR_VAL; + } #endif /* ESP_LWIP && LWIP_IPV4 && LWIP_IPV6 */ - if (err == ERR_OK) - { - if (msg->conn->pcb.tcp != NULL) - { - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + if (err == ERR_OK) { + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) - { - err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); - } - else - { - err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); - } - break; + case NETCONN_RAW: + if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { + err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); + } else { + err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); + } + break; #endif #if LWIP_UDP - case NETCONN_UDP: + case NETCONN_UDP: #if LWIP_CHECKSUM_ON_COPY - if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) - { - err = udp_send_chksum( - msg->conn->pcb.udp, - msg->msg.b->p, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, - msg->msg.b->toport_chksum); - } - else - { - err = udp_sendto_chksum( - msg->conn->pcb.udp, - msg->msg.b->p, - &msg->msg.b->addr, - msg->msg.b->port, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, - msg->msg.b->toport_chksum); - } -#else /* LWIP_CHECKSUM_ON_COPY */ - if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) - { - err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); - } - else - { - err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); - } + if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { + err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } else { + err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, + &msg->msg.b->addr, msg->msg.b->port, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } +#else /* LWIP_CHECKSUM_ON_COPY */ + if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { + err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); + } else { + err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); + } #endif /* LWIP_CHECKSUM_ON_COPY */ - break; + break; #endif /* LWIP_UDP */ - default: - err = ERR_CONN; - break; - } - } - else - { - err = ERR_CONN; - } - } - msg->err = err; - TCPIP_APIMSG_ACK(msg); + default: + err = ERR_CONN; + break; + } + } else { + err = ERR_CONN; + } + } + msg->err = err; + TCPIP_APIMSG_ACK(msg); } #if LWIP_TCP @@ -1834,25 +1675,23 @@ void lwip_netconn_do_send(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_recv(void *m) +void +lwip_netconn_do_recv(void *m) { - struct api_msg *msg = (struct api_msg *)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) - { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) - { - size_t remaining = msg->msg.r.len; - do - { - u16_t recved = (u16_t)((remaining > 0xffff) ? 0xffff : remaining); - tcp_recved(msg->conn->pcb.tcp, recved); - remaining -= recved; - } while (remaining != 0); - } - } - TCPIP_APIMSG_ACK(msg); + struct api_msg *msg = (struct api_msg *)m; + + msg->err = ERR_OK; + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { + size_t remaining = msg->msg.r.len; + do { + u16_t recved = (u16_t)((remaining > 0xffff) ? 0xffff : remaining); + tcp_recved(msg->conn->pcb.tcp, recved); + remaining -= recved; + } while (remaining != 0); + } + } + TCPIP_APIMSG_ACK(msg); } #if TCP_LISTEN_BACKLOG @@ -1861,19 +1700,18 @@ void lwip_netconn_do_recv(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_accepted(void *m) +void +lwip_netconn_do_accepted(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) - { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) - { - tcp_backlog_accepted(msg->conn->pcb.tcp); - } + msg->err = ERR_OK; + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { + tcp_backlog_accepted(msg->conn->pcb.tcp); } - TCPIP_APIMSG_ACK(msg); + } + TCPIP_APIMSG_ACK(msg); } #endif /* TCP_LISTEN_BACKLOG */ @@ -1888,205 +1726,170 @@ void lwip_netconn_do_accepted(void *m) * @return ERR_OK * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished */ -static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) +static err_t +lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) { - err_t err; - const void *dataptr; - u16_t len, available; - u8_t write_finished = 0; - size_t diff; - u8_t dontblock; - u8_t apiflags; - u8_t write_more; - - LWIP_ASSERT("conn != NULL", conn != NULL); - LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); - LWIP_ASSERT( - "conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len", - conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len); - LWIP_ASSERT("conn->current_msg->msg.w.vector_cnt > 0", conn->current_msg->msg.w.vector_cnt > 0); - - apiflags = conn->current_msg->msg.w.apiflags; - dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); + err_t err; + const void *dataptr; + u16_t len, available; + u8_t write_finished = 0; + size_t diff; + u8_t dontblock; + u8_t apiflags; + u8_t write_more; + + LWIP_ASSERT("conn != NULL", conn != NULL); + LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); + LWIP_ASSERT("conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len", + conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len); + LWIP_ASSERT("conn->current_msg->msg.w.vector_cnt > 0", conn->current_msg->msg.w.vector_cnt > 0); + + apiflags = conn->current_msg->msg.w.apiflags; + dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); #if LWIP_SO_SNDTIMEO - if ((conn->send_timeout != 0) && ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) - { - write_finished = 1; - if (conn->current_msg->msg.w.offset == 0) - { - /* nothing has been written */ - err = ERR_WOULDBLOCK; - } - else - { - /* partial write */ - err = ERR_OK; - } - } - else + if ((conn->send_timeout != 0) && + ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { + write_finished = 1; + if (conn->current_msg->msg.w.offset == 0) { + /* nothing has been written */ + err = ERR_WOULDBLOCK; + } else { + /* partial write */ + err = ERR_OK; + } + } else #endif /* LWIP_SO_SNDTIMEO */ - { - do - { - dataptr = (const u8_t *)conn->current_msg->msg.w.vector->ptr + conn->current_msg->msg.w.vector_off; - diff = conn->current_msg->msg.w.vector->len - conn->current_msg->msg.w.vector_off; - if (diff > 0xffffUL) - { /* max_u16_t */ - len = 0xffff; - apiflags |= TCP_WRITE_FLAG_MORE; - } - else - { - len = (u16_t)diff; - } - available = tcp_sndbuf(conn->pcb.tcp); - if (available < len) - { - /* don't try to write more than sendbuf */ - len = available; - if (dontblock) - { - if (!len) - { - /* set error according to partial write or not */ - err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK; - goto err_mem; - } - } - else - { - apiflags |= TCP_WRITE_FLAG_MORE; - } - } - LWIP_ASSERT( - "lwip_netconn_do_writemore: invalid length!", - ((conn->current_msg->msg.w.vector_off + len) <= conn->current_msg->msg.w.vector->len)); - /* we should loop around for more sending in the following cases: - 1) We couldn't finish the current vector because of 16-bit size limitations. - tcp_write() and tcp_sndbuf() both are limited to 16-bit sizes - 2) We are sending the remainder of the current vector and have more */ - if ((len == 0xffff && diff > 0xffffUL) || (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) - { - write_more = 1; - apiflags |= TCP_WRITE_FLAG_MORE; - } - else - { - write_more = 0; - } - err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); - if (err == ERR_OK) - { - conn->current_msg->msg.w.offset += len; - conn->current_msg->msg.w.vector_off += len; - /* check if current vector is finished */ - if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) - { - conn->current_msg->msg.w.vector_cnt--; - /* if we have additional vectors, move on to them */ - if (conn->current_msg->msg.w.vector_cnt > 0) - { - conn->current_msg->msg.w.vector++; - conn->current_msg->msg.w.vector_off = 0; - } - } - } - } while (write_more && err == ERR_OK); - /* if OK or memory error, check available space */ - if ((err == ERR_OK) || (err == ERR_MEM)) - { - err_mem: - if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) - { - /* non-blocking write did not write everything: mark the pcb non-writable - and let poll_tcp check writable space to mark the pcb writable again */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); - conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; - } - else if ( - (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) - { - /* The queued byte- or pbuf-count exceeds the configured low-water limit, - let select mark this pcb as non-writable. */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); - } + { + do { + dataptr = (const u8_t *)conn->current_msg->msg.w.vector->ptr + conn->current_msg->msg.w.vector_off; + diff = conn->current_msg->msg.w.vector->len - conn->current_msg->msg.w.vector_off; + if (diff > 0xffffUL) { /* max_u16_t */ + len = 0xffff; + apiflags |= TCP_WRITE_FLAG_MORE; + } else { + len = (u16_t)diff; + } + available = tcp_sndbuf(conn->pcb.tcp); + if (available < len) { + /* don't try to write more than sendbuf */ + len = available; + if (dontblock) { + if (!len) { + /* set error according to partial write or not */ + err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK; + goto err_mem; + } + } else { + apiflags |= TCP_WRITE_FLAG_MORE; } - - if (err == ERR_OK) - { - err_t out_err; - if ((conn->current_msg->msg.w.offset == conn->current_msg->msg.w.len) || dontblock) - { - /* return sent length (caller reads length from msg.w.offset) */ - write_finished = 1; - } - out_err = tcp_output(conn->pcb.tcp); - if (out_err == ERR_RTE) - { - /* If tcp_output fails because no route is found, - don't try writing any more but return the error - to the application thread. */ - err = out_err; - write_finished = 1; - } - } - else if (err == ERR_MEM) - { - /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called. - For blocking sockets, we do NOT return to the application - thread, since ERR_MEM is only a temporary error! Non-blocking - will remain non-writable until sent_tcp/poll_tcp is called */ - - /* tcp_write returned ERR_MEM, try tcp_output anyway */ - err_t out_err = tcp_output(conn->pcb.tcp); - if (out_err == ERR_RTE) - { - /* If tcp_output fails because no route is found, - don't try writing any more but return the error - to the application thread. */ - err = out_err; - write_finished = 1; - } - else if (dontblock) - { - /* non-blocking write is done on ERR_MEM, set error according - to partial write or not */ - err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK; - write_finished = 1; - } + } + LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", + ((conn->current_msg->msg.w.vector_off + len) <= conn->current_msg->msg.w.vector->len)); + /* we should loop around for more sending in the following cases: + 1) We couldn't finish the current vector because of 16-bit size limitations. + tcp_write() and tcp_sndbuf() both are limited to 16-bit sizes + 2) We are sending the remainder of the current vector and have more */ + if ((len == 0xffff && diff > 0xffffUL) || + (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) { + write_more = 1; + apiflags |= TCP_WRITE_FLAG_MORE; + } else { + write_more = 0; + } + err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); + if (err == ERR_OK) { + conn->current_msg->msg.w.offset += len; + conn->current_msg->msg.w.vector_off += len; + /* check if current vector is finished */ + if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) { + conn->current_msg->msg.w.vector_cnt--; + /* if we have additional vectors, move on to them */ + if (conn->current_msg->msg.w.vector_cnt > 0) { + conn->current_msg->msg.w.vector++; + conn->current_msg->msg.w.vector_off = 0; + } } - else - { - /* On errors != ERR_MEM, we don't try writing any more but return - the error to the application thread. */ - write_finished = 1; - } - } - if (write_finished) - { - /* everything was written: set back connection state - and back to application task */ - sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; + } + } while (write_more && err == ERR_OK); + /* if OK or memory error, check available space */ + if ((err == ERR_OK) || (err == ERR_MEM)) { +err_mem: + if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) { + /* non-blocking write did not write everything: mark the pcb non-writable + and let poll_tcp check writable space to mark the pcb writable again */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); + conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; + } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || + (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { + /* The queued byte- or pbuf-count exceeds the configured low-water limit, + let select mark this pcb as non-writable. */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); + } + } + + if (err == ERR_OK) { + err_t out_err; + if ((conn->current_msg->msg.w.offset == conn->current_msg->msg.w.len) || dontblock) { + /* return sent length (caller reads length from msg.w.offset) */ + write_finished = 1; + } + out_err = tcp_output(conn->pcb.tcp); + if (out_err == ERR_RTE) { + /* If tcp_output fails because no route is found, + don't try writing any more but return the error + to the application thread. */ + err = out_err; + write_finished = 1; + } + } else if (err == ERR_MEM) { + /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called. + For blocking sockets, we do NOT return to the application + thread, since ERR_MEM is only a temporary error! Non-blocking + will remain non-writable until sent_tcp/poll_tcp is called */ + + /* tcp_write returned ERR_MEM, try tcp_output anyway */ + err_t out_err = tcp_output(conn->pcb.tcp); + if (out_err == ERR_RTE) { + /* If tcp_output fails because no route is found, + don't try writing any more but return the error + to the application thread. */ + err = out_err; + write_finished = 1; + } else if (dontblock) { + /* non-blocking write is done on ERR_MEM, set error according + to partial write or not */ + err = (conn->current_msg->msg.w.offset == 0) ? ERR_WOULDBLOCK : ERR_OK; + write_finished = 1; + } + } else { + /* On errors != ERR_MEM, we don't try writing any more but return + the error to the application thread. */ + write_finished = 1; + } + } + if (write_finished) { + /* everything was written: set back connection state + and back to application task */ + sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + conn->current_msg->err = err; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; #if LWIP_TCPIP_CORE_LOCKING - if (delayed) + if (delayed) #endif - { - sys_sem_signal(op_completed_sem); - } - } -#if LWIP_TCPIP_CORE_LOCKING - else { - return ERR_MEM; + sys_sem_signal(op_completed_sem); } + } +#if LWIP_TCPIP_CORE_LOCKING + else { + return ERR_MEM; + } #endif - return ERR_OK; + return ERR_OK; } #endif /* LWIP_TCP */ @@ -2096,61 +1899,52 @@ static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_write(void *m) +void +lwip_netconn_do_write(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - err_t err = netconn_err(msg->conn); - if (err == ERR_OK) - { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) - { + err_t err = netconn_err(msg->conn); + if (err == ERR_OK) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { #if LWIP_TCP - if (msg->conn->state != NETCONN_NONE) - { - /* netconn is connecting, closing or in blocking write */ - err = ERR_INPROGRESS; - } - else if (msg->conn->pcb.tcp != NULL) - { - msg->conn->state = NETCONN_WRITE; - /* set all the variables used by lwip_netconn_do_writemore */ - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); - LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); - msg->conn->current_msg = msg; + if (msg->conn->state != NETCONN_NONE) { + /* netconn is connecting, closing or in blocking write */ + err = ERR_INPROGRESS; + } else if (msg->conn->pcb.tcp != NULL) { + msg->conn->state = NETCONN_WRITE; + /* set all the variables used by lwip_netconn_do_writemore */ + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); + LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); + msg->conn->current_msg = msg; #if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) - { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_writemore(msg->conn); + if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + lwip_netconn_do_writemore(msg->conn); #endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG - since lwip_netconn_do_writemore ACKs it! */ - return; - } - else - { - err = ERR_CONN; - } -#else /* LWIP_TCP */ - err = ERR_VAL; + /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG + since lwip_netconn_do_writemore ACKs it! */ + return; + } else { + err = ERR_CONN; + } +#else /* LWIP_TCP */ + err = ERR_VAL; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) - } - else - { - err = ERR_VAL; + } else { + err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ - } } - msg->err = err; - TCPIP_APIMSG_ACK(msg); + } + msg->err = err; + TCPIP_APIMSG_ACK(msg); } /** @@ -2159,81 +1953,64 @@ void lwip_netconn_do_write(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_getaddr(void *m) +void +lwip_netconn_do_getaddr(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - if (msg->conn->pcb.ip != NULL) - { - if (msg->msg.ad.local) - { - ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->local_ip); - } - else - { - ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->remote_ip); - } + if (msg->conn->pcb.ip != NULL) { + if (msg->msg.ad.local) { + ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), + msg->conn->pcb.ip->local_ip); + } else { + ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), + msg->conn->pcb.ip->remote_ip); + } - msg->err = ERR_OK; - switch (NETCONNTYPE_GROUP(msg->conn->type)) - { + msg->err = ERR_OK; + switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW - case NETCONN_RAW: - if (msg->msg.ad.local) - { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; - } - else - { - /* return an error as connecting is only a helper for upper layers */ - msg->err = ERR_CONN; - } - break; + case NETCONN_RAW: + if (msg->msg.ad.local) { + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; + } else { + /* return an error as connecting is only a helper for upper layers */ + msg->err = ERR_CONN; + } + break; #endif /* LWIP_RAW */ #if LWIP_UDP - case NETCONN_UDP: - if (msg->msg.ad.local) - { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; - } - else - { - if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) - { - msg->err = ERR_CONN; - } - else - { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; - } - } - break; + case NETCONN_UDP: + if (msg->msg.ad.local) { + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; + } else { + if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { + msg->err = ERR_CONN; + } else { + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; + } + } + break; #endif /* LWIP_UDP */ #if LWIP_TCP - case NETCONN_TCP: - if ((msg->msg.ad.local == 0) && - ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) - { - /* pcb is not connected and remote name is requested */ - msg->err = ERR_CONN; - } - else - { - API_EXPR_DEREF(msg->msg.ad.port) = - (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); - } - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("invalid netconn_type", 0); - break; + case NETCONN_TCP: + if ((msg->msg.ad.local == 0) && + ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) { + /* pcb is not connected and remote name is requested */ + msg->err = ERR_CONN; + } else { + API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); } + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("invalid netconn_type", 0); + break; } - else - { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); + } else { + msg->err = ERR_CONN; + } + TCPIP_APIMSG_ACK(msg); } /** @@ -2243,88 +2020,77 @@ void lwip_netconn_do_getaddr(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_close(void *m) +void +lwip_netconn_do_close(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; #if LWIP_TCP - enum netconn_state state = msg->conn->state; - /* First check if this is a TCP netconn and if it is in a correct state - (LISTEN doesn't support half shutdown) */ - if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) && - ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) - { - /* Check if we are in a connected state */ - if (state == NETCONN_CONNECT) - { - /* TCP connect in progress: cannot shutdown */ - msg->err = ERR_CONN; - } - else if (state == NETCONN_WRITE) - { + enum netconn_state state = msg->conn->state; + /* First check if this is a TCP netconn and if it is in a correct state + (LISTEN doesn't support half shutdown) */ + if ((msg->conn->pcb.tcp != NULL) && + (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) && + ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) { + /* Check if we are in a connected state */ + if (state == NETCONN_CONNECT) { + /* TCP connect in progress: cannot shutdown */ + msg->err = ERR_CONN; + } else if (state == NETCONN_WRITE) { #if LWIP_NETCONN_FULLDUPLEX - if (msg->msg.sd.shut & NETCONN_SHUT_WR) - { - /* close requested, abort running write */ - sys_sem_t *write_completed_sem; - LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); - write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); - msg->conn->current_msg->err = ERR_CLSD; - msg->conn->current_msg = NULL; - msg->conn->state = NETCONN_NONE; - state = NETCONN_NONE; - sys_sem_signal(write_completed_sem); - } - else - { - LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD); - /* In this case, let the write continue and do not interfere with - conn->current_msg or conn->state! */ - msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0); - } - } - if (state == NETCONN_NONE) - { -#else /* LWIP_NETCONN_FULLDUPLEX */ - msg->err = ERR_INPROGRESS; - } - else - { + if (msg->msg.sd.shut & NETCONN_SHUT_WR) { + /* close requested, abort running write */ + sys_sem_t *write_completed_sem; + LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); + write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); + msg->conn->current_msg->err = ERR_CLSD; + msg->conn->current_msg = NULL; + msg->conn->state = NETCONN_NONE; + state = NETCONN_NONE; + sys_sem_signal(write_completed_sem); + } else { + LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD); + /* In this case, let the write continue and do not interfere with + conn->current_msg or conn->state! */ + msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0); + } + } + if (state == NETCONN_NONE) { +#else /* LWIP_NETCONN_FULLDUPLEX */ + msg->err = ERR_INPROGRESS; + } else { #endif /* LWIP_NETCONN_FULLDUPLEX */ - if (msg->msg.sd.shut & NETCONN_SHUT_RD) - { + if (msg->msg.sd.shut & NETCONN_SHUT_RD) { #if LWIP_NETCONN_FULLDUPLEX - /* Mark mboxes invalid */ - netconn_mark_mbox_invalid(msg->conn); -#else /* LWIP_NETCONN_FULLDUPLEX */ - netconn_drain(msg->conn); + /* Mark mboxes invalid */ + netconn_mark_mbox_invalid(msg->conn); +#else /* LWIP_NETCONN_FULLDUPLEX */ + netconn_drain(msg->conn); #endif /* LWIP_NETCONN_FULLDUPLEX */ - } - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); - msg->conn->state = NETCONN_CLOSE; - msg->conn->current_msg = msg; + } + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL); + msg->conn->state = NETCONN_CLOSE; + msg->conn->current_msg = msg; #if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) - { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_close_internal(msg->conn); + if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + lwip_netconn_do_close_internal(msg->conn); #endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ - return; - } + /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ + return; } - else + } else #endif /* LWIP_TCP */ - { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); + { + msg->err = ERR_CONN; + } + TCPIP_APIMSG_ACK(msg); } #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) @@ -2334,60 +2100,45 @@ void lwip_netconn_do_close(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_join_leave_group(void *m) +void +lwip_netconn_do_join_leave_group(void *m) { - struct api_msg *msg = (struct api_msg *)m; + struct api_msg *msg = (struct api_msg *)m; - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) - { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) - { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP #if LWIP_IPV6 && LWIP_IPV6_MLD - if (NETCONNTYPE_ISIPV6(msg->conn->type)) - { - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) - { - msg->err = mld6_joingroup( - ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - else - { - msg->err = mld6_leavegroup( - ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - } - else + if (NETCONNTYPE_ISIPV6(msg->conn->type)) { + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = mld6_joingroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } else { + msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } + } else #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - { + { #if LWIP_IGMP - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) - { - msg->err = igmp_joingroup( - ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - else - { - msg->err = igmp_leavegroup( - ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = igmp_joingroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), + ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); + } else { + msg->err = igmp_leavegroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), + ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); + } #endif /* LWIP_IGMP */ - } + } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) - } - else - { - msg->err = ERR_VAL; + } else { + msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ - } } - TCPIP_APIMSG_ACK(msg); + } + TCPIP_APIMSG_ACK(msg); } /** * Join multicast groups for UDP netconns. @@ -2395,62 +2146,54 @@ void lwip_netconn_do_join_leave_group(void *m) * * @param m the api_msg pointing to the connection */ -void lwip_netconn_do_join_leave_group_netif(void *m) +void +lwip_netconn_do_join_leave_group_netif(void *m) { - struct api_msg *msg = (struct api_msg *)m; - struct netif *netif; - - netif = netif_get_by_index(msg->msg.jl.if_idx); - if (netif == NULL) - { - msg->err = ERR_IF; - goto done; - } - - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) - { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) - { + struct api_msg *msg = (struct api_msg *)m; + struct netif *netif; + + netif = netif_get_by_index(msg->msg.jl.if_idx); + if (netif == NULL) { + msg->err = ERR_IF; + goto done; + } + + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP #if LWIP_IPV6 && LWIP_IPV6_MLD - if (NETCONNTYPE_ISIPV6(msg->conn->type)) - { - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) - { - msg->err = mld6_joingroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - else - { - msg->err = mld6_leavegroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - } - else + if (NETCONNTYPE_ISIPV6(msg->conn->type)) { + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = mld6_joingroup_netif(netif, + ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } else { + msg->err = mld6_leavegroup_netif(netif, + ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } + } else #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - { + { #if LWIP_IGMP - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) - { - msg->err = igmp_joingroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - else - { - msg->err = igmp_leavegroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = igmp_joingroup_netif(netif, + ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); + } else { + msg->err = igmp_leavegroup_netif(netif, + ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); + } #endif /* LWIP_IGMP */ - } + } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) - } - else - { - msg->err = ERR_VAL; + } else { + msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ - } } + } done: - TCPIP_APIMSG_ACK(msg); + TCPIP_APIMSG_ACK(msg); } #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ @@ -2460,30 +2203,32 @@ void lwip_netconn_do_join_leave_group_netif(void *m) * (or on timeout). A waiting application thread is waked up by * signaling the semaphore. */ -static void lwip_netconn_do_dns_found(const char *name, const ip_addr_t *ipaddr, void *arg) +static void +lwip_netconn_do_dns_found(const char *name, const ip_addr_t *ipaddr, void *arg) { - struct dns_api_msg *msg = (struct dns_api_msg *)arg; + u8_t i; + struct dns_api_msg *msg = (struct dns_api_msg *)arg; - /* we trust the internal implementation to be correct :-) */ - LWIP_UNUSED_ARG(name); + /* we trust the internal implementation to be correct :-) */ + LWIP_UNUSED_ARG(name); - if (ipaddr == NULL) - { - /* timeout or memory error */ - API_EXPR_DEREF(msg->err) = ERR_VAL; - } - else - { - /* address was resolved */ - API_EXPR_DEREF(msg->err) = ERR_OK; - API_EXPR_DEREF(msg->addr) = *ipaddr; + if (ipaddr == NULL) { + /* timeout or memory error */ + API_EXPR_DEREF(msg->err) = ERR_VAL; + } else { + /* address was resolved */ + API_EXPR_DEREF(msg->err) = ERR_OK; + + for (i=0; iaddr+i) = *(ipaddr+i); } - /* wake up the application task waiting in netconn_gethostbyname */ - sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); + } + /* wake up the application task waiting in netconn_gethostbyname */ + sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); - // [NF_CHANGE] - sys_signal_sock_event(); - // [END_NF_CHANGE] + // [NF_CHANGE] + sys_signal_sock_event(); + // [END_NF_CHANGE] } /** @@ -2492,34 +2237,33 @@ static void lwip_netconn_do_dns_found(const char *name, const ip_addr_t *ipaddr, * * @param arg the dns_api_msg pointing to the query */ -void lwip_netconn_do_gethostbyname(void *arg) +void +lwip_netconn_do_gethostbyname(void *arg) { - struct dns_api_msg *msg = (struct dns_api_msg *)arg; - u8_t addrtype = + struct dns_api_msg *msg = (struct dns_api_msg *)arg; + u8_t addrtype = #if LWIP_IPV4 && LWIP_IPV6 - msg->dns_addrtype; + msg->dns_addrtype; #else - LWIP_DNS_ADDRTYPE_DEFAULT; + LWIP_DNS_ADDRTYPE_DEFAULT; #endif - API_EXPR_DEREF(msg->err) = - dns_gethostbyname_addrtype(msg->name, API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype); + API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name, + API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype); #if LWIP_TCPIP_CORE_LOCKING - /* For core locking, only block if we need to wait for answer/timeout */ - if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) - { - UNLOCK_TCPIP_CORE(); - sys_sem_wait(API_EXPR_REF_SEM(msg->sem)); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) - { - /* on error or immediate success, wake up the application - * task waiting in netconn_gethostbyname */ - sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); - } + /* For core locking, only block if we need to wait for answer/timeout */ + if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) { + UNLOCK_TCPIP_CORE(); + sys_sem_wait(API_EXPR_REF_SEM(msg->sem)); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { + /* on error or immediate success, wake up the application + * task waiting in netconn_gethostbyname */ + sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); + } #endif /* LWIP_TCPIP_CORE_LOCKING */ } #endif /* LWIP_DNS */ diff --git a/targets/ESP32/_lwIP/nf_sockets.c b/targets/ESP32/_lwIP/nf_sockets.c index aa39123e22..d59962a328 100644 --- a/targets/ESP32/_lwIP/nf_sockets.c +++ b/targets/ESP32/_lwIP/nf_sockets.c @@ -1,19 +1,59 @@ // // Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) 2001-2004 Swedish Institute of Computer Science. All rights reserved. -// See LICENSE file in the project root for full license information. // -#include +/** + * @file + * Sockets BSD-Like API module + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * Improved by Marc Boucher and David Haas + * + */ + #include "lwip/opt.h" #if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ #include "lwip/sockets.h" + // [NF_CHANGE] -// can't include this because we have to tweak -// #include "lwip/priv/sockets_priv.h" +// can't include this because we have to tweak it for err nuumber +//#include "lwip/priv/sockets_priv.h" +#include +#include "nf_sockets_priv.h" // [END_NF_CHANGE] + #include "lwip/api.h" #include "lwip/igmp.h" #include "lwip/inet.h" @@ -29,151 +69,6 @@ #include "lwip/inet_chksum.h" #endif -// [NF_CHANGE] -////////////////////// -// from sockets_priv.h - -#define NUM_SOCKETS MEMP_NUM_NETCONN - -/** This is overridable for the rare case where more than 255 threads - * select on the same socket... - */ -#ifndef SELWAIT_T -#define SELWAIT_T u8_t -#endif - -union lwip_sock_lastdata { - struct netbuf *netbuf; - struct pbuf *pbuf; -}; - -/** Contains all internal pointers and states used for a socket */ -struct lwip_sock -{ - /** sockets currently are built on netconns, each socket has one netconn */ - struct netconn *conn; - /** data that was left from the previous read */ - union lwip_sock_lastdata lastdata; -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL - /** number of times data was received, set by event_callback(), - tested by the receive and select functions */ - s16_t rcvevent; - /** number of times data was ACKed (free send buffer), set by event_callback(), - tested by select */ - u16_t sendevent; - /** error happened for this socket, set by event_callback(), tested by select */ - u16_t errevent; - /** counter of how many threads are waiting for this socket using select */ - SELWAIT_T select_waiting; - - // [NF_CHANGE] - // need this to store the last error that occurred in the socket - // last error that occurred on this socket (in fact, all our errnos fit into an u8_t) - u8_t err; - // [END_NF_CHANGE] - -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ -#if LWIP_NETCONN_FULLDUPLEX - /* counter of how many threads are using a struct lwip_sock (not the 'int') */ - u8_t fd_used; - /* status of pending close/delete actions */ - u8_t fd_free_pending; -#define LWIP_SOCK_FD_FREE_TCP 1 -#define LWIP_SOCK_FD_FREE_FREE 2 -#endif -}; - -#ifndef set_errno -#define set_errno(err) \ - do \ - { \ - if (err) \ - { \ - errno = (err); \ - } \ - } while (0) -#endif - -#if !LWIP_TCPIP_CORE_LOCKING -/** Maximum optlen used by setsockopt/getsockopt */ -#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq)) - -/** This struct is used to pass data to the set/getsockopt_internal - * functions running in tcpip_thread context (only a void* is allowed) */ -struct lwip_setgetsockopt_data -{ - /** socket index for which to change options */ - int s; - /** level of the option to process */ - int level; - /** name of the option to process */ - int optname; - /** set: value to set the option to - * get: value of the option is stored here */ -#if LWIP_MPU_COMPATIBLE - u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN]; -#else - union { - void *p; - const void *pc; - } optval; -#endif - /** size of *optval */ - socklen_t optlen; - /** if an error occurs, it is temporarily stored here */ - int err; - /** semaphore to wake up the calling task */ - void *completed_sem; -}; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - -#ifdef __cplusplus -} -#endif - -struct lwip_sock *lwip_socket_dbg_get_socket(int fd); - -#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL - -#if LWIP_NETCONN_SEM_PER_THREAD -#define SELECT_SEM_T sys_sem_t * -#define SELECT_SEM_PTR(sem) (sem) -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define SELECT_SEM_T sys_sem_t -#define SELECT_SEM_PTR(sem) (&(sem)) -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -/** Description for a task waiting in select */ -struct lwip_select_cb -{ - /** Pointer to the next waiting task */ - struct lwip_select_cb *next; - /** Pointer to the previous waiting task */ - struct lwip_select_cb *prev; -#if LWIP_SOCKET_SELECT - /** readset passed to select */ - fd_set *readset; - /** writeset passed to select */ - fd_set *writeset; - /** unimplemented: exceptset passed to select */ - fd_set *exceptset; -#endif /* LWIP_SOCKET_SELECT */ -#if LWIP_SOCKET_POLL - /** fds passed to poll; NULL if select */ - struct pollfd *poll_fds; - /** nfds passed to poll; 0 if select */ - nfds_t poll_nfds; -#endif /* LWIP_SOCKET_POLL */ - /** don't signal the same semaphore twice: set to 1 when signalled */ - int sem_signalled; - /** semaphore to wake up a task waiting for select */ - SELECT_SEM_T sem; -}; -#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - -/////////////////////// -// [END_NF_CHANGE] - #if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES #include #endif @@ -196,187 +91,180 @@ struct lwip_select_cb #define LWIP_NETCONN 0 #endif -#define API_SELECT_CB_VAR_REF(name) API_VAR_REF(name) -#define API_SELECT_CB_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_select_cb, name) -#define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock) -#define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) +#define API_SELECT_CB_VAR_REF(name) API_VAR_REF(name) +#define API_SELECT_CB_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_select_cb, name) +#define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock) +#define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) + +#ifndef LWIP_SOCKET_HAVE_SA_LEN +#define LWIP_SOCKET_HAVE_SA_LEN 0 +#endif /* LWIP_SOCKET_HAVE_SA_LEN */ + +/* Address length safe read and write */ +#if LWIP_SOCKET_HAVE_SA_LEN #if LWIP_IPV4 -#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) \ - do \ - { \ - (sin)->sin_len = sizeof(struct sockaddr_in); \ - (sin)->sin_family = AF_INET; \ - (sin)->sin_port = lwip_htons((port)); \ - inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ - memset((sin)->sin_zero, 0, SIN_ZERO_LEN); \ - } while (0) -#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) \ - do \ - { \ - inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ - (port) = lwip_ntohs((sin)->sin_port); \ - } while (0) +#define IP4ADDR_SOCKADDR_SET_LEN(sin) \ + (sin)->sin_len = sizeof(struct sockaddr_in) #endif /* LWIP_IPV4 */ #if LWIP_IPV6 -#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) \ - do \ - { \ - (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ - (sin6)->sin6_family = AF_INET6; \ - (sin6)->sin6_port = lwip_htons((port)); \ - (sin6)->sin6_flowinfo = 0; \ - inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ - (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); \ - } while (0) -#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) \ - do \ - { \ - inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ - if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) \ - { \ - ip6_addr_set_zone(ip_2_ip6(ipaddr), (u8_t)((sin6)->sin6_scope_id)); \ - } \ - (port) = lwip_ntohs((sin6)->sin6_port); \ - } while (0) +#define IP6ADDR_SOCKADDR_SET_LEN(sin6) \ + (sin6)->sin6_len = sizeof(struct sockaddr_in6) +#endif /* LWIP_IPV6 */ + +#define IPADDR_SOCKADDR_GET_LEN(addr) \ + (addr)->sa.sa_len + +#else + +#if LWIP_IPV4 +#define IP4ADDR_SOCKADDR_SET_LEN(addr) +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 +#define IP6ADDR_SOCKADDR_SET_LEN(addr) +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV4 && LWIP_IPV6 +#define IPADDR_SOCKADDR_GET_LEN(addr) \ + ((addr)->sa.sa_family == AF_INET ? sizeof(struct sockaddr_in) \ + : ((addr)->sa.sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : 0)) +#elif LWIP_IPV4 +#define IPADDR_SOCKADDR_GET_LEN(addr) sizeof(struct sockaddr_in) +#elif LWIP_IPV6 +#define IPADDR_SOCKADDR_GET_LEN(addr) sizeof(struct sockaddr_in6) +#else +#define IPADDR_SOCKADDR_GET_LEN(addr) sizeof(struct sockaddr) +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + +#endif /* LWIP_SOCKET_HAVE_SA_LEN */ + +#if LWIP_IPV4 +#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ + IP4ADDR_SOCKADDR_SET_LEN(sin); \ + (sin)->sin_family = AF_INET; \ + (sin)->sin_port = lwip_htons((port)); \ + inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ + memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) +#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ + inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ + (port) = lwip_ntohs((sin)->sin_port); }while(0) +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 +#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \ + IP6ADDR_SOCKADDR_SET_LEN(sin6); \ + (sin6)->sin6_family = AF_INET6; \ + (sin6)->sin6_port = lwip_htons((port)); \ + (sin6)->sin6_flowinfo = 0; \ + inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ + (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0) +#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \ + inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ + if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { \ + ip6_addr_set_zone(ip_2_ip6(ipaddr), (u8_t)((sin6)->sin6_scope_id)); \ + } \ + (port) = lwip_ntohs((sin6)->sin6_port); }while(0) #endif /* LWIP_IPV6 */ #if LWIP_IPV4 && LWIP_IPV6 static void sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port); -#define IS_SOCK_ADDR_LEN_VALID(namelen) \ - (((namelen) == sizeof(struct sockaddr_in)) || ((namelen) == sizeof(struct sockaddr_in6))) -#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || ((name)->sa_family == AF_INET6)) -#define SOCK_ADDR_TYPE_MATCH(name, sock) \ - ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ - (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - do \ - { \ - if (IP_IS_ANY_TYPE_VAL(*ipaddr) || IP_IS_V6_VAL(*ipaddr)) \ - { \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6 *)(void *)(sockaddr), ip_2_ip6(ipaddr), port); \ - } \ - else \ - { \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in *)(void *)(sockaddr), ip_2_ip4(ipaddr), port); \ - } \ - } while (0) +#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ + ((namelen) == sizeof(struct sockaddr_in6))) +#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ + ((name)->sa_family == AF_INET6)) +#define SOCK_ADDR_TYPE_MATCH(name, sock) \ + ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ + (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) +#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) do { \ + if (IP_IS_ANY_TYPE_VAL(*ipaddr) || IP_IS_V6_VAL(*ipaddr)) { \ + IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port); \ + } else { \ + IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port); \ + } } while(0) #define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port)) -#define DOMAIN_TO_NETCONN_TYPE(domain, type) \ - (((domain) == AF_INET) ? (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) +#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ + (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ #define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in6)) #define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET6) #define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6 *)(void *)(sockaddr), ip_2_ip6(ipaddr), port) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ - SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6 *)(const void *)(sockaddr), ipaddr, port) -#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) +#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ + IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port) +#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ + SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, port) +#define DOMAIN_TO_NETCONN_TYPE(domain, type) ((enum netconn_type)((type) | NETCONN_TYPE_IPV6)) #else /*-> LWIP_IPV4: LWIP_IPV4 && LWIP_IPV6 */ #define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) #define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) #define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in *)(void *)(sockaddr), ip_2_ip4(ipaddr), port) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ - SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in *)(const void *)(sockaddr), ipaddr, port) +#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ + IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port) +#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ + SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port) #define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) #endif /* LWIP_IPV6 */ -#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || IS_SOCK_ADDR_TYPE_VALID(name)) -#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) \ - (((name)->sa_family == AF_UNSPEC) || SOCK_ADDR_TYPE_MATCH(name, sock)) -#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) +#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ + IS_SOCK_ADDR_TYPE_VALID(name)) +#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ + SOCK_ADDR_TYPE_MATCH(name, sock)) +#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % LWIP_MIN(4, MEM_ALIGNMENT)) == 0) + + +#define LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype) do { if ((optlen) < sizeof(opttype)) { done_socket(sock); return EINVAL; }}while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ + if ((sock)->conn == NULL) { done_socket(sock); return EINVAL; } }while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ + if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { done_socket(sock); return EINVAL; } }while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ + if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { done_socket(sock); return ENOPROTOOPT; } }while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype) \ - do \ - { \ - if ((optlen) < sizeof(opttype)) \ - { \ - done_socket(sock); \ - return EINVAL; \ - } \ - } while (0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) \ - do \ - { \ - LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ - if ((sock)->conn == NULL) \ - { \ - done_socket(sock); \ - return EINVAL; \ - } \ - } while (0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) \ - do \ - { \ - LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ - if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) \ - { \ - done_socket(sock); \ - return EINVAL; \ - } \ - } while (0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) \ - do \ - { \ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ - if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) \ - { \ - done_socket(sock); \ - return ENOPROTOOPT; \ - } \ - } while (0) #define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) #define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) #define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) #if LWIP_MPU_COMPATIBLE -#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) \ - do \ - { \ - name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ - if (name == NULL) \ - { \ - sock_set_errno(sock, ENOMEM); \ - done_socket(sock); \ - return -1; \ - } \ - } while (0) +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ + name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ + if (name == NULL) { \ + set_errno(ENOMEM); \ + done_socket(sock); \ + return -1; \ + } }while(0) #else /* LWIP_MPU_COMPATIBLE */ #define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) #endif /* LWIP_MPU_COMPATIBLE */ #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD -#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int +#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int #define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val)) -#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((long)*(const int *)(optval)) +#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((long)*(const int*)(optval)) #else #define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval -#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) \ - do \ - { \ - u32_t loc = (val); \ - ((struct timeval *)(optval))->tv_sec = (long)((loc) / 1000U); \ - ((struct timeval *)(optval))->tv_usec = (long)(((loc) % 1000U) * 1000U); \ - } while (0) -#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) \ - ((((const struct timeval *)(optval))->tv_sec * 1000) + (((const struct timeval *)(optval))->tv_usec / 1000)) +#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) do { \ + u32_t loc = (val); \ + ((struct timeval *)(optval))->tv_sec = (long)((loc) / 1000U); \ + ((struct timeval *)(optval))->tv_usec = (long)(((loc) % 1000U) * 1000U); }while(0) +#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000) + (((const struct timeval *)(optval))->tv_usec / 1000)) #endif + /** A struct sockaddr replacement that has the same alignment as sockaddr_in/ * sockaddr_in6 if instantiated. */ union sockaddr_aligned { - struct sockaddr sa; + struct sockaddr sa; #if LWIP_IPV6 - struct sockaddr_in6 sin6; + struct sockaddr_in6 sin6; #endif /* LWIP_IPV6 */ #if LWIP_IPV4 - struct sockaddr_in sin; + struct sockaddr_in sin; #endif /* LWIP_IPV4 */ }; @@ -388,19 +276,18 @@ union sockaddr_aligned { #if LWIP_IGMP /* This is to keep track of IP_ADD_MEMBERSHIP calls to drop the membership when a socket is closed */ -struct lwip_socket_multicast_pair -{ - /** the socket */ - struct lwip_sock *sock; - /** the interface address */ - ip4_addr_t if_addr; - /** the group address */ - ip4_addr_t multi_addr; +struct lwip_socket_multicast_pair { + /** the socket */ + struct lwip_sock *sock; + /** the interface address */ + ip4_addr_t if_addr; + /** the group address */ + ip4_addr_t multi_addr; }; static struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; -static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); +static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ @@ -408,19 +295,18 @@ static void lwip_socket_drop_registered_memberships(int s); #if LWIP_IPV6_MLD /* This is to keep track of IP_JOIN_GROUP calls to drop the membership when a socket is closed */ -struct lwip_socket_multicast_mld6_pair -{ - /** the socket */ - struct lwip_sock *sock; - /** the interface index */ - u8_t if_idx; - /** the group address */ - ip6_addr_t multi_addr; +struct lwip_socket_multicast_mld6_pair { + /** the socket */ + struct lwip_sock *sock; + /** the interface index */ + u8_t if_idx; + /** the group address */ + ip6_addr_t multi_addr; }; static struct lwip_socket_multicast_mld6_pair socket_ipv6_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; -static int lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); +static int lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); static void lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); static void lwip_socket_drop_registered_mld6_memberships(int s); #endif /* LWIP_IPV6_MLD */ @@ -436,9 +322,9 @@ static struct lwip_sock sockets[NUM_SOCKETS]; #define LWIP_SOCKET_SELECT_UNPROTECT(lev) UNLOCK_TCPIP_CORE() #else /* LWIP_TCPIP_CORE_LOCKING */ /* protect the select_cb_list using SYS_LIGHTWEIGHT_PROT */ -#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) -#define LWIP_SOCKET_SELECT_PROTECT(lev) SYS_ARCH_PROTECT(lev) -#define LWIP_SOCKET_SELECT_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) +#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) +#define LWIP_SOCKET_SELECT_PROTECT(lev) SYS_ARCH_PROTECT(lev) +#define LWIP_SOCKET_SELECT_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) /** This counter is increased from lwip_select when the list is changed and checked in select_check_waiters to see if it has changed. */ static volatile int select_cb_ctr; @@ -458,6 +344,7 @@ static struct lwip_select_cb *select_cb_list; } while (0) // [END_NF_CHANGE] + /* Forward declaration of some functions */ #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); @@ -472,80 +359,75 @@ static void lwip_setsockopt_callback(void *arg); #endif static int lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen); static int lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen); -static int free_socket_locked( - struct lwip_sock *sock, - int is_tcp, - struct netconn **conn, - union lwip_sock_lastdata *lastdata); +static int free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn, + union lwip_sock_lastdata *lastdata); static void free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata); #if LWIP_IPV4 && LWIP_IPV6 -static void sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port) +static void +sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port) { - if ((sockaddr->sa_family) == AF_INET6) - { - SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6 *)(const void *)(sockaddr), ipaddr, *port); - ipaddr->type = IPADDR_TYPE_V6; - } - else - { - SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in *)(const void *)(sockaddr), ipaddr, *port); - ipaddr->type = IPADDR_TYPE_V4; - } + if ((sockaddr->sa_family) == AF_INET6) { + SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6 *)(const void *)(sockaddr), ipaddr, *port); + ipaddr->type = IPADDR_TYPE_V6; + } else { + SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in *)(const void *)(sockaddr), ipaddr, *port); + ipaddr->type = IPADDR_TYPE_V4; + } } #endif /* LWIP_IPV4 && LWIP_IPV6 */ /** LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */ -void lwip_socket_thread_init(void) +void +lwip_socket_thread_init(void) { - netconn_thread_init(); + netconn_thread_init(); } /** LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */ -void lwip_socket_thread_cleanup(void) +void +lwip_socket_thread_cleanup(void) { - netconn_thread_cleanup(); + netconn_thread_cleanup(); } #if LWIP_NETCONN_FULLDUPLEX /* Thread-safe increment of sock->fd_used, with overflow check */ -static int sock_inc_used(struct lwip_sock *sock) +static int +sock_inc_used(struct lwip_sock *sock) { - int ret; - SYS_ARCH_DECL_PROTECT(lev); + int ret; + SYS_ARCH_DECL_PROTECT(lev); - LWIP_ASSERT("sock != NULL", sock != NULL); + LWIP_ASSERT("sock != NULL", sock != NULL); - SYS_ARCH_PROTECT(lev); - if (sock->fd_free_pending) - { - /* prevent new usage of this socket if free is pending */ - ret = 0; - } - else - { - ++sock->fd_used; - ret = 1; - LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); - } - SYS_ARCH_UNPROTECT(lev); - return ret; + SYS_ARCH_PROTECT(lev); + if (sock->fd_free_pending) { + /* prevent new usage of this socket if free is pending */ + ret = 0; + } else { + ++sock->fd_used; + ret = 1; + LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); + } + SYS_ARCH_UNPROTECT(lev); + return ret; } /* Like sock_inc_used(), but called under SYS_ARCH_PROTECT lock. */ -static int sock_inc_used_locked(struct lwip_sock *sock) +static int +sock_inc_used_locked(struct lwip_sock *sock) { - LWIP_ASSERT("sock != NULL", sock != NULL); - - if (sock->fd_free_pending) - { - LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); - return 0; - } + LWIP_ASSERT("sock != NULL", sock != NULL); - ++sock->fd_used; + if (sock->fd_free_pending) { LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); - return 1; + return 0; + } + + ++sock->fd_used; + LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); + return 1; } /* In full-duplex mode,sock->fd_used != 0 prevents a socket descriptor from being @@ -553,88 +435,85 @@ static int sock_inc_used_locked(struct lwip_sock *sock) * (e.g. read-while-write or close-while-write, etc) * This function is called at the end of functions using (try)get_socket*(). */ -static void done_socket(struct lwip_sock *sock) +static void +done_socket(struct lwip_sock *sock) { - int freed = 0; - int is_tcp = 0; - struct netconn *conn = NULL; - union lwip_sock_lastdata lastdata; - SYS_ARCH_DECL_PROTECT(lev); - LWIP_ASSERT("sock != NULL", sock != NULL); - - SYS_ARCH_PROTECT(lev); - LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); - if (--sock->fd_used == 0) - { - if (sock->fd_free_pending) - { - /* free the socket */ - sock->fd_used = 1; - is_tcp = sock->fd_free_pending & LWIP_SOCK_FD_FREE_TCP; - freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); - } - } - SYS_ARCH_UNPROTECT(lev); - - if (freed) - { - free_socket_free_elements(is_tcp, conn, &lastdata); - } + int freed = 0; + int is_tcp = 0; + struct netconn *conn = NULL; + union lwip_sock_lastdata lastdata; + SYS_ARCH_DECL_PROTECT(lev); + LWIP_ASSERT("sock != NULL", sock != NULL); + + SYS_ARCH_PROTECT(lev); + LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); + if (--sock->fd_used == 0) { + if (sock->fd_free_pending) { + /* free the socket */ + sock->fd_used = 1; + is_tcp = sock->fd_free_pending & LWIP_SOCK_FD_FREE_TCP; + freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); + } + } + SYS_ARCH_UNPROTECT(lev); + + if (freed) { + free_socket_free_elements(is_tcp, conn, &lastdata); + } } #else /* LWIP_NETCONN_FULLDUPLEX */ -#define sock_inc_used(sock) 1 -#define sock_inc_used_locked(sock) 1 +#define sock_inc_used(sock) 1 +#define sock_inc_used_locked(sock) 1 #define done_socket(sock) #endif /* LWIP_NETCONN_FULLDUPLEX */ /* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ -static struct lwip_sock *tryget_socket_unconn_nouse(int fd) +static struct lwip_sock * +tryget_socket_unconn_nouse(int fd) { - int s = fd - LWIP_SOCKET_OFFSET; - if ((s < 0) || (s >= NUM_SOCKETS)) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); - return NULL; - } - return &sockets[s]; + int s = fd - LWIP_SOCKET_OFFSET; + if ((s < 0) || (s >= NUM_SOCKETS)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); + return NULL; + } + return &sockets[s]; } -struct lwip_sock *lwip_socket_dbg_get_socket(int fd) +struct lwip_sock * +lwip_socket_dbg_get_socket(int fd) { - return tryget_socket_unconn_nouse(fd); + return tryget_socket_unconn_nouse(fd); } /* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ -static struct lwip_sock *tryget_socket_unconn(int fd) +static struct lwip_sock * +tryget_socket_unconn(int fd) { - struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); - if (ret != NULL) - { - if (!sock_inc_used(ret)) - { - return NULL; - } + struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); + if (ret != NULL) { + if (!sock_inc_used(ret)) { + return NULL; } - return ret; + } + return ret; } /* Like tryget_socket_unconn(), but called under SYS_ARCH_PROTECT lock. */ -static struct lwip_sock *tryget_socket_unconn_locked(int fd) +static struct lwip_sock * +tryget_socket_unconn_locked(int fd) { - struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); - if (ret != NULL) - { -#if ESP_LWIP - if (ret->conn == NULL) - return NULL; -#endif /* ESP_LWIP */ - if (!sock_inc_used_locked(ret)) - { - return NULL; - } - } - return ret; + struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); + if (ret != NULL) { +#if ESP_LWIP + if (ret->conn == NULL) + return NULL; +#endif /* ESP_LWIP */ + if (!sock_inc_used_locked(ret)) { + return NULL; + } + } + return ret; } /** @@ -643,18 +522,17 @@ static struct lwip_sock *tryget_socket_unconn_locked(int fd) * @param fd externally used socket index * @return struct lwip_sock for the socket or NULL if not found */ -static struct lwip_sock *tryget_socket(int fd) +static struct lwip_sock * +tryget_socket(int fd) { - struct lwip_sock *sock = tryget_socket_unconn(fd); - if (sock != NULL) - { - if (sock->conn) - { - return sock; - } - done_socket(sock); + struct lwip_sock *sock = tryget_socket_unconn(fd); + if (sock != NULL) { + if (sock->conn) { + return sock; } - return NULL; + done_socket(sock); + } + return NULL; } /** @@ -663,19 +541,18 @@ static struct lwip_sock *tryget_socket(int fd) * @param fd externally used socket index * @return struct lwip_sock for the socket or NULL if not found */ -static struct lwip_sock *get_socket(int fd) +static struct lwip_sock * +get_socket(int fd) { - struct lwip_sock *sock = tryget_socket(fd); - if (!sock) - { - if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", fd)); - } - set_errno(EBADF); - return NULL; + struct lwip_sock *sock = tryget_socket(fd); + if (!sock) { + if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", fd)); } - return sock; + set_errno(EBADF); + return NULL; + } + return sock; } /** @@ -686,46 +563,44 @@ static struct lwip_sock *get_socket(int fd) * 0 if socket has been created by socket() * @return the index of the new socket; -1 on error */ -static int alloc_socket(struct netconn *newconn, int accepted) +static int +alloc_socket(struct netconn *newconn, int accepted) { - int i; - SYS_ARCH_DECL_PROTECT(lev); - LWIP_UNUSED_ARG(accepted); + int i; + SYS_ARCH_DECL_PROTECT(lev); + LWIP_UNUSED_ARG(accepted); - /* allocate a new socket identifier */ - for (i = 0; i < NUM_SOCKETS; ++i) - { - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - if (!sockets[i].conn) - { + /* allocate a new socket identifier */ + for (i = 0; i < NUM_SOCKETS; ++i) { + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + if (!sockets[i].conn) { #if LWIP_NETCONN_FULLDUPLEX - if (sockets[i].fd_used) - { - SYS_ARCH_UNPROTECT(lev); - continue; - } - sockets[i].fd_used = 1; - sockets[i].fd_free_pending = 0; + if (sockets[i].fd_used) { + SYS_ARCH_UNPROTECT(lev); + continue; + } + sockets[i].fd_used = 1; + sockets[i].fd_free_pending = 0; #endif - sockets[i].conn = newconn; - /* The socket is not yet known to anyone, so no need to protect - after having marked it as used. */ - SYS_ARCH_UNPROTECT(lev); - sockets[i].lastdata.pbuf = NULL; + sockets[i].conn = newconn; + /* The socket is not yet known to anyone, so no need to protect + after having marked it as used. */ + SYS_ARCH_UNPROTECT(lev); + sockets[i].lastdata.pbuf = NULL; #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL - LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0); - sockets[i].rcvevent = 0; - /* TCP sendbuf is empty, but the socket is not yet writable until connected - * (unless it has been created by accept()). */ - sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); - sockets[i].errevent = 0; + LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0); + sockets[i].rcvevent = 0; + /* TCP sendbuf is empty, but the socket is not yet writable until connected + * (unless it has been created by accept()). */ + sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); + sockets[i].errevent = 0; #endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ - return i + LWIP_SOCKET_OFFSET; - } - SYS_ARCH_UNPROTECT(lev); + return i + LWIP_SOCKET_OFFSET; } - return -1; + SYS_ARCH_UNPROTECT(lev); + } + return -1; } /** Free a socket (under lock) @@ -735,54 +610,47 @@ static int alloc_socket(struct netconn *newconn, int accepted) * @param conn the socekt's netconn is stored here, must be freed externally * @param lastdata lastdata is stored here, must be freed externally */ -static int free_socket_locked( - struct lwip_sock *sock, - int is_tcp, - struct netconn **conn, - union lwip_sock_lastdata *lastdata) +static int +free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn, + union lwip_sock_lastdata *lastdata) { #if LWIP_NETCONN_FULLDUPLEX - LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); - sock->fd_used--; - if (sock->fd_used > 0) - { - sock->fd_free_pending = LWIP_SOCK_FD_FREE_FREE | (is_tcp ? LWIP_SOCK_FD_FREE_TCP : 0); - return 0; - } -#else /* LWIP_NETCONN_FULLDUPLEX */ - LWIP_UNUSED_ARG(is_tcp); + LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); + sock->fd_used--; + if (sock->fd_used > 0) { + sock->fd_free_pending = LWIP_SOCK_FD_FREE_FREE | (is_tcp ? LWIP_SOCK_FD_FREE_TCP : 0); + return 0; + } +#else /* LWIP_NETCONN_FULLDUPLEX */ + LWIP_UNUSED_ARG(is_tcp); #endif /* LWIP_NETCONN_FULLDUPLEX */ - *lastdata = sock->lastdata; - sock->lastdata.pbuf = NULL; + *lastdata = sock->lastdata; + sock->lastdata.pbuf = NULL; #if ESP_LWIP - sock->select_waiting = 0; + sock->select_waiting = 0; #endif /* ESP_LWIP */ - *conn = sock->conn; - sock->conn = NULL; - return 1; + *conn = sock->conn; + sock->conn = NULL; + return 1; } /** Free a socket's leftover members. */ -static void free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata) +static void +free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata) { - if (lastdata->pbuf != NULL) - { - if (is_tcp) - { - pbuf_free(lastdata->pbuf); - } - else - { - netbuf_delete(lastdata->netbuf); - } - } - if (conn != NULL) - { - /* netconn_prepare_delete() has already been called, here we only free the conn */ - netconn_delete(conn); - } + if (lastdata->pbuf != NULL) { + if (is_tcp) { + pbuf_free(lastdata->pbuf); + } else { + netbuf_delete(lastdata->netbuf); + } + } + if (conn != NULL) { + /* netconn_prepare_delete() has already been called, here we only free the conn */ + netconn_delete(conn); + } } /** Free a socket. The socket's netconn must have been @@ -791,24 +659,24 @@ static void free_socket_free_elements(int is_tcp, struct netconn *conn, union lw * @param sock the socket to free * @param is_tcp != 0 for TCP sockets, used to free lastdata */ -static void free_socket(struct lwip_sock *sock, int is_tcp) +static void +free_socket(struct lwip_sock *sock, int is_tcp) { - int freed; - struct netconn *conn; - union lwip_sock_lastdata lastdata; - SYS_ARCH_DECL_PROTECT(lev); + int freed; + struct netconn *conn; + union lwip_sock_lastdata lastdata; + SYS_ARCH_DECL_PROTECT(lev); - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); - freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); - SYS_ARCH_UNPROTECT(lev); - /* don't use 'sock' after this line, as another task might have allocated it */ + freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); + SYS_ARCH_UNPROTECT(lev); + /* don't use 'sock' after this line, as another task might have allocated it */ - if (freed) - { - free_socket_free_elements(is_tcp, conn, &lastdata); - } + if (freed) { + free_socket_free_elements(is_tcp, conn, &lastdata); + } } /* Below this, the well-known socket functions are implemented. @@ -817,311 +685,277 @@ static void free_socket(struct lwip_sock *sock, int is_tcp) * Exceptions are documented! */ -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +int +lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - struct lwip_sock *sock, *nsock; - struct netconn *newconn; - ip_addr_t naddr; - u16_t port = 0; - int newsock; - err_t err; - int recvevent; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); - sock = get_socket(s); - if (!sock) - { - return -1; + struct lwip_sock *sock, *nsock; + struct netconn *newconn; + ip_addr_t naddr; + u16_t port = 0; + int newsock; + err_t err; + int recvevent; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + set_errno(EOPNOTSUPP); + } else if (err == ERR_CLSD) { + set_errno(EINVAL); + } else { + set_errno(err_to_errno(err)); } + done_socket(sock); + return -1; + } + LWIP_ASSERT("newconn != NULL", newconn != NULL); - /* wait for a new connection */ - err = netconn_accept(sock->conn, &newconn); - if (err != ERR_OK) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - { - sock_set_errno(sock, EOPNOTSUPP); - } - else if (err == ERR_CLSD) - { - sock_set_errno(sock, EINVAL); - } - else - { - sock_set_errno(sock, err_to_errno(err)); - } - done_socket(sock); - return -1; + newsock = alloc_socket(newconn, 1); + if (newsock == -1) { + netconn_delete(newconn); + set_errno(ENFILE); + done_socket(sock); + return -1; + } + LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); + nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; + + /* See event_callback: If data comes in right away after an accept, even + * though the server task might not have created a new socket yet. + * In that case, newconn->socket is counted down (newconn->socket--), + * so nsock->rcvevent is >= 1 here! + */ + SYS_ARCH_PROTECT(lev); + recvevent = (s16_t)(-1 - newconn->callback_arg.socket); + newconn->callback_arg.socket = newsock; + SYS_ARCH_UNPROTECT(lev); + + if (newconn->callback) { + LOCK_TCPIP_CORE(); + while (recvevent > 0) { + recvevent--; + newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0); } - LWIP_ASSERT("newconn != NULL", newconn != NULL); + UNLOCK_TCPIP_CORE(); + } + + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if ((addr != NULL) && (addrlen != NULL)) { + union sockaddr_aligned tempaddr; + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + free_socket(nsock, 1); + set_errno(err_to_errno(err)); + done_socket(sock); + return -1; + } + + IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); + if (*addrlen > IPADDR_SOCKADDR_GET_LEN(&tempaddr)) { + *addrlen = IPADDR_SOCKADDR_GET_LEN(&tempaddr); + } + MEMCPY(addr, &tempaddr, *addrlen); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); + ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); + } else { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d\n", s, newsock)); + } + + // [NF_CHANGE] - Signal the CLR that a socket event has occured + // TODO: We may want to investigate other ways to signal + // the CLR (maybe based on which socket received the + // event). + if (nsock->rcvevent > 0) + { + sys_signal_sock_event(); + } + //[END_NF_CHANGE] - newsock = alloc_socket(newconn, 1); - if (newsock == -1) - { - netconn_delete(newconn); - sock_set_errno(sock, ENFILE); - done_socket(sock); - return -1; - } - LWIP_ASSERT( - "invalid socket index", - (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); - nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; - - /* See event_callback: If data comes in right away after an accept, even - * though the server task might not have created a new socket yet. - * In that case, newconn->socket is counted down (newconn->socket--), - * so nsock->rcvevent is >= 1 here! - */ - SYS_ARCH_PROTECT(lev); - recvevent = (s16_t)(-1 - newconn->socket); - newconn->socket = newsock; - SYS_ARCH_UNPROTECT(lev); + set_errno(0); + done_socket(sock); + done_socket(nsock); + return newsock; +} - if (newconn->callback) - { - LOCK_TCPIP_CORE(); - while (recvevent > 0) - { - recvevent--; - newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0); - } - UNLOCK_TCPIP_CORE(); - } +int +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + ip_addr_t local_addr; + u16_t local_port; + err_t err; - /* Note that POSIX only requires us to check addr is non-NULL. addrlen must - * not be NULL if addr is valid. - */ - if ((addr != NULL) && (addrlen != NULL)) - { - union sockaddr_aligned tempaddr; - /* get the IP address and port of the remote host */ - err = netconn_peer(newconn, &naddr, &port); - if (err != ERR_OK) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); - free_socket(nsock, 1); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } + sock = get_socket(s); + if (!sock) { + return -1; + } - IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); - if (*addrlen > tempaddr.sa.sa_len) - { - *addrlen = tempaddr.sa.sa_len; - } - MEMCPY(addr, &tempaddr, *addrlen); + if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + set_errno(err_to_errno(ERR_VAL)); + done_socket(sock); + return -1; + } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); - ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F "\n", port)); - } - else - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); - } + /* check size, family and alignment of 'name' */ + LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), + set_errno(err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_UNUSED_ARG(namelen); - // [NF_CHANGE] - Signal the CLR that a socket event has occured - // TODO: We may want to investigate other ways to signal - // the CLR (maybe based on which socket received the - // event). - if (nsock->rcvevent > 0) - { - sys_signal_sock_event(); - } - //[END_NF_CHANGE] + SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); - sock_set_errno(sock, 0); - done_socket(sock); - done_socket(nsock); - return newsock; -} +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr)); + IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - ip_addr_t local_addr; - u16_t local_port; - err_t err; - - sock = get_socket(s); - if (!sock) - { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH(name, sock)) - { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - done_socket(sock); - return -1; - } - - /* check size, family and alignment of 'name' */ - LWIP_ERROR("lwip_bind: invalid address", - (IS_SOCK_ADDR_LEN_VALID(namelen) && IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1;); - LWIP_UNUSED_ARG(namelen); - - SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F ")\n", local_port)); + err = netconn_bind(sock->conn, &local_addr, local_port); -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) - { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr)); - IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - err = netconn_bind(sock->conn, &local_addr, local_port); - - if (err != ERR_OK) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); - sock_set_errno(sock, 0); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); + set_errno(err_to_errno(err)); done_socket(sock); - return 0; + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); + set_errno(0); + done_socket(sock); + return 0; } -int lwip_close(int s) +int +lwip_close(int s) { - struct lwip_sock *sock; - int is_tcp = 0; - err_t err; + struct lwip_sock *sock; + int is_tcp = 0; + err_t err; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); - sock = get_socket(s); - if (!sock) - { - return -1; - } + sock = get_socket(s); + if (!sock) { + return -1; + } - if (sock->conn != NULL) - { - is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; - } - else - { - LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata.pbuf == NULL); - } + if (sock->conn != NULL) { + is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; + } else { + LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata.pbuf == NULL); + } #if LWIP_IGMP - /* drop all possibly joined IGMP memberships */ - lwip_socket_drop_registered_memberships(s); + /* drop all possibly joined IGMP memberships */ + lwip_socket_drop_registered_memberships(s); #endif /* LWIP_IGMP */ #if LWIP_IPV6_MLD - /* drop all possibly joined MLD6 memberships */ - lwip_socket_drop_registered_mld6_memberships(s); + /* drop all possibly joined MLD6 memberships */ + lwip_socket_drop_registered_mld6_memberships(s); #endif /* LWIP_IPV6_MLD */ - err = netconn_prepare_delete(sock->conn); - if (err != ERR_OK) - { - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } + err = netconn_prepare_delete(sock->conn); + if (err != ERR_OK) { + set_errno(err_to_errno(err)); + done_socket(sock); + return -1; + } - free_socket(sock, is_tcp); - set_errno(0); - return 0; + free_socket(sock, is_tcp); + set_errno(0); + return 0; } -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +int +lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) { - struct lwip_sock *sock; - err_t err; + struct lwip_sock *sock; + err_t err; - sock = get_socket(s); - if (!sock) - { - return -1; - } + sock = get_socket(s); + if (!sock) { + return -1; + } - if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) - { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - done_socket(sock); - return -1; - } + if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + set_errno(err_to_errno(ERR_VAL)); + done_socket(sock); + return -1; + } + + LWIP_UNUSED_ARG(namelen); + if (name->sa_family == AF_UNSPEC) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); + err = netconn_disconnect(sock->conn); + } else { + ip_addr_t remote_addr; + u16_t remote_port; - LWIP_UNUSED_ARG(namelen); - if (name->sa_family == AF_UNSPEC) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); - err = netconn_disconnect(sock->conn); - } - else - { - ip_addr_t remote_addr; - u16_t remote_port; - - /* check size, family and alignment of 'name' */ - LWIP_ERROR("lwip_connect: invalid address", - IS_SOCK_ADDR_LEN_VALID(namelen) && IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && - IS_SOCK_ADDR_ALIGNED(name), - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1;); - - SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F ")\n", remote_port)); + /* check size, family and alignment of 'name' */ + LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), + set_errno(err_to_errno(ERR_ARG)); done_socket(sock); return -1;); -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) - { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr)); - IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ + SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); - err = netconn_connect(sock->conn, &remote_addr, remote_port); +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr)); + IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4); } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ - // [NF_CHANGE] We are using async calls to lwIP API - // the code in lwIP isn't handling this properly - if (err == ERR_INPROGRESS) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) operation in progress\n", s)); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - // [END_NF_CHANGE] + err = netconn_connect(sock->conn, &remote_addr, remote_port); + } - if (err != ERR_OK) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } +// [NF_CHANGE] We are using async calls to lwIP API +// the code in lwIP isn't handling this properly, this just reports correct debug pront + if (err == ERR_INPROGRESS) + { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) operation in progress\n", s)); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } +// [END_NF_CHANGE] - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); + set_errno(err_to_errno(err)); done_socket(sock); - return 0; + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); + set_errno(0); + done_socket(sock); + return 0; } /** @@ -1132,42 +966,38 @@ int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) * @return 0 on success, non-zero on failure */ -int lwip_listen(int s, int backlog) +int +lwip_listen(int s, int backlog) { - struct lwip_sock *sock; - err_t err; + struct lwip_sock *sock; + err_t err; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); - sock = get_socket(s); - if (!sock) - { - return -1; - } + sock = get_socket(s); + if (!sock) { + return -1; + } - /* limit the "backlog" parameter to fit in an u8_t */ - backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); + /* limit the "backlog" parameter to fit in an u8_t */ + backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); - err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); + err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); - if (err != ERR_OK) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - { - sock_set_errno(sock, EOPNOTSUPP); - } - else - { - sock_set_errno(sock, err_to_errno(err)); - } - done_socket(sock); - return -1; + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + set_errno(EOPNOTSUPP); + } else { + set_errno(err_to_errno(err)); } - - sock_set_errno(sock, 0); done_socket(sock); - return 0; + return -1; + } + + set_errno(0); + done_socket(sock); + return 0; } #if LWIP_TCP @@ -1175,1031 +1005,903 @@ int lwip_listen(int s, int backlog) * until "len" bytes are received or we're otherwise done. * Keeps sock->lastdata for peeking or partly copying. */ -static ssize_t lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +static ssize_t +lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) { - u8_t apiflags = NETCONN_NOAUTORCVD; - ssize_t recvd = 0; - ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX; + u8_t apiflags = NETCONN_NOAUTORCVD; + ssize_t recvd = 0; + ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX; - LWIP_ASSERT("no socket given", sock != NULL); - LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP); - - if (flags & MSG_DONTWAIT) - { - apiflags |= NETCONN_DONTBLOCK; - } + LWIP_ASSERT("no socket given", sock != NULL); + LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP); - do - { - struct pbuf *p; - err_t err; - u16_t copylen; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: top while sock->lastdata=%p\n", (void *)sock->lastdata.pbuf)); - /* Check if there is data left from the last recv operation. */ - if (sock->lastdata.pbuf) - { - p = sock->lastdata.pbuf; - } - else - { - /* No data was left from the previous operation, so we try to get - some from the network. */ - err = netconn_recv_tcp_pbuf_flags(sock->conn, &p, apiflags); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: netconn_recv err=%d, pbuf=%p\n", err, (void *)p)); - - if (err != ERR_OK) - { - if (recvd > 0) - { - /* already received data, return that (this trusts in getting the same error from - netconn layer again next time netconn_recv is called) */ - goto lwip_recv_tcp_done; - } - /* We should really do some error checking here. */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: p == NULL, error is \"%s\"!\n", lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - if (err == ERR_CLSD) - { - return 0; - } - else - { - return -1; - } - } - LWIP_ASSERT("p != NULL", p != NULL); - sock->lastdata.pbuf = p; - } + if (flags & MSG_DONTWAIT) { + apiflags |= NETCONN_DONTBLOCK; + } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_recv_tcp: buflen=%" U16_F " recv_left=%d off=%d\n", p->tot_len, (int)recv_left, (int)recvd)); + do { + struct pbuf *p; + err_t err; + u16_t copylen; - if (recv_left > p->tot_len) - { - copylen = p->tot_len; - } - else - { - copylen = (u16_t)recv_left; - } - if (recvd + copylen < recvd) - { - /* overflow */ - copylen = (u16_t)(SSIZE_MAX - recvd); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: top while sock->lastdata=%p\n", (void *)sock->lastdata.pbuf)); + /* Check if there is data left from the last recv operation. */ + if (sock->lastdata.pbuf) { + p = sock->lastdata.pbuf; + } else { + /* No data was left from the previous operation, so we try to get + some from the network. */ + err = netconn_recv_tcp_pbuf_flags(sock->conn, &p, apiflags); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: netconn_recv err=%d, pbuf=%p\n", + err, (void *)p)); + + if (err != ERR_OK) { + if (recvd > 0) { + /* already received data, return that (this trusts in getting the same error from + netconn layer again next time netconn_recv is called) */ + goto lwip_recv_tcp_done; } - - /* copy the contents of the received buffer into - the supplied memory pointer mem */ - pbuf_copy_partial(p, (u8_t *)mem + recvd, copylen, 0); - - recvd += copylen; - - /* TCP combines multiple pbufs for one recv */ - LWIP_ASSERT("invalid copylen, len would underflow", recv_left >= copylen); - recv_left -= copylen; - - /* Unless we peek the incoming message... */ - if ((flags & MSG_PEEK) == 0) - { - /* ... check if there is data left in the pbuf */ - LWIP_ASSERT("invalid copylen", p->tot_len >= copylen); - if (p->tot_len - copylen > 0) - { - /* If so, it should be saved in the sock structure for the next recv call. - We store the pbuf but hide/free the consumed data: */ - sock->lastdata.pbuf = pbuf_free_header(p, copylen); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: lastdata now pbuf=%p\n", (void *)sock->lastdata.pbuf)); - } - else - { - sock->lastdata.pbuf = NULL; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: deleting pbuf=%p\n", (void *)p)); - pbuf_free(p); - } + /* We should really do some error checking here. */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: p == NULL, error is \"%s\"!\n", + lwip_strerr(err))); + set_errno(err_to_errno(err)); + if (err == ERR_CLSD) { + return 0; + } else { + return -1; } - /* once we have some data to return, only add more if we don't need to wait */ - apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; - /* @todo: do we need to support peeking more than one pbuf? */ - } while ((recv_left > 0) && !(flags & MSG_PEEK)); + } + LWIP_ASSERT("p != NULL", p != NULL); + sock->lastdata.pbuf = p; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: buflen=%"U16_F" recv_left=%d off=%d\n", + p->tot_len, (int)recv_left, (int)recvd)); + + if (recv_left > p->tot_len) { + copylen = p->tot_len; + } else { + copylen = (u16_t)recv_left; + } + if (recvd > SSIZE_MAX - copylen) { + /* overflow */ + copylen = (u16_t)(SSIZE_MAX - recvd); + } + + /* copy the contents of the received buffer into + the supplied memory pointer mem */ + pbuf_copy_partial(p, (u8_t *)mem + recvd, copylen, 0); + + recvd += copylen; + + /* TCP combines multiple pbufs for one recv */ + LWIP_ASSERT("invalid copylen, len would underflow", recv_left >= copylen); + recv_left -= copylen; + + /* Unless we peek the incoming message... */ + if ((flags & MSG_PEEK) == 0) { + /* ... check if there is data left in the pbuf */ + LWIP_ASSERT("invalid copylen", p->tot_len >= copylen); + if (p->tot_len - copylen > 0) { + /* If so, it should be saved in the sock structure for the next recv call. + We store the pbuf but hide/free the consumed data: */ + sock->lastdata.pbuf = pbuf_free_header(p, copylen); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: lastdata now pbuf=%p\n", (void *)sock->lastdata.pbuf)); + } else { + sock->lastdata.pbuf = NULL; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: deleting pbuf=%p\n", (void *)p)); + pbuf_free(p); + } + } + /* once we have some data to return, only add more if we don't need to wait */ + apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; + /* @todo: do we need to support peeking more than one pbuf? */ + } while ((recv_left > 0) && !(flags & MSG_PEEK)); lwip_recv_tcp_done: - if ((recvd > 0) && !(flags & MSG_PEEK)) - { - /* ensure window update after copying all data */ - netconn_tcp_recvd(sock->conn, (size_t)recvd); - } - sock_set_errno(sock, 0); - return recvd; + if ((recvd > 0) && !(flags & MSG_PEEK)) { + /* ensure window update after copying all data */ + netconn_tcp_recvd(sock->conn, (size_t)recvd); + } + set_errno(0); + return recvd; } #endif /* Convert a netbuf's address data to struct sockaddr */ -static int lwip_sock_make_addr( - struct netconn *conn, - ip_addr_t *fromaddr, - u16_t port, - struct sockaddr *from, - socklen_t *fromlen) +static int +lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, + struct sockaddr *from, socklen_t *fromlen) { - int truncated = 0; - union sockaddr_aligned saddr; + int truncated = 0; + union sockaddr_aligned saddr; - LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(conn); - LWIP_ASSERT("fromaddr != NULL", fromaddr != NULL); - LWIP_ASSERT("from != NULL", from != NULL); - LWIP_ASSERT("fromlen != NULL", fromlen != NULL); + LWIP_ASSERT("fromaddr != NULL", fromaddr != NULL); + LWIP_ASSERT("from != NULL", from != NULL); + LWIP_ASSERT("fromlen != NULL", fromlen != NULL); #if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ - if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4(fromaddr)) - { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr)); - IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6); - } + /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ + if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4(fromaddr)) { + ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr)); + IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6); + } #endif /* LWIP_IPV4 && LWIP_IPV6 */ - IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); - if (*fromlen < saddr.sa.sa_len) - { - truncated = 1; - } - else if (*fromlen > saddr.sa.sa_len) - { - *fromlen = saddr.sa.sa_len; - } - MEMCPY(from, &saddr, *fromlen); - return truncated; + IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); + if (*fromlen < IPADDR_SOCKADDR_GET_LEN(&saddr)) { + truncated = 1; + } else if (*fromlen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { + *fromlen = IPADDR_SOCKADDR_GET_LEN(&saddr); + } + MEMCPY(from, &saddr, *fromlen); + return truncated; } #if LWIP_TCP /* Helper function to get a tcp socket's remote address info */ -static int lwip_recv_tcp_from( - struct lwip_sock *sock, - struct sockaddr *from, - socklen_t *fromlen, - const char *dbg_fn, - int dbg_s, - ssize_t dbg_ret) +static int +lwip_recv_tcp_from(struct lwip_sock *sock, struct sockaddr *from, socklen_t *fromlen, const char *dbg_fn, int dbg_s, ssize_t dbg_ret) { - if (sock == NULL) - { - return 0; - } - LWIP_UNUSED_ARG(dbg_fn); - LWIP_UNUSED_ARG(dbg_s); - LWIP_UNUSED_ARG(dbg_ret); + if (sock == NULL) { + return 0; + } + LWIP_UNUSED_ARG(dbg_fn); + LWIP_UNUSED_ARG(dbg_s); + LWIP_UNUSED_ARG(dbg_ret); #if !SOCKETS_DEBUG - if (from && fromlen) + if (from && fromlen) #endif /* !SOCKETS_DEBUG */ - { - /* get remote addr/port from tcp_pcb */ - u16_t port; - ip_addr_t tmpaddr; - netconn_getaddr(sock->conn, &tmpaddr, &port, 0); - LWIP_DEBUGF(SOCKETS_DEBUG, ("%s(%d): addr=", dbg_fn, dbg_s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, tmpaddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F " len=%d\n", port, (int)dbg_ret)); - if (from && fromlen) - { - return lwip_sock_make_addr(sock->conn, &tmpaddr, port, from, fromlen); - } - } - return 0; + { + /* get remote addr/port from tcp_pcb */ + u16_t port; + ip_addr_t tmpaddr; + netconn_getaddr(sock->conn, &tmpaddr, &port, 0); + LWIP_DEBUGF(SOCKETS_DEBUG, ("%s(%d): addr=", dbg_fn, dbg_s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, tmpaddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, (int)dbg_ret)); + if (from && fromlen) { + return lwip_sock_make_addr(sock->conn, &tmpaddr, port, from, fromlen); + } + } + return 0; } #endif /* Helper function to receive a netbuf from a udp or raw netconn. * Keeps sock->lastdata for peeking. */ -static err_t lwip_recvfrom_udp_raw( - struct lwip_sock *sock, - int flags, - struct msghdr *msg, - u16_t *datagram_len, - int dbg_s) +static err_t +lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16_t *datagram_len, int dbg_s) { - struct netbuf *buf; - u8_t apiflags; - err_t err; - u16_t buflen, copylen, copied; - int i; - - LWIP_UNUSED_ARG(dbg_s); - LWIP_ERROR( - "lwip_recvfrom_udp_raw: invalid arguments", (msg->msg_iov != NULL) || (msg->msg_iovlen <= 0), return ERR_ARG;); - - if (flags & MSG_DONTWAIT) - { - apiflags = NETCONN_DONTBLOCK; - } - else - { - apiflags = 0; - } - - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); - /* Check if there is data left from the last recv operation. */ - buf = sock->lastdata.netbuf; - if (buf == NULL) - { - /* No data was left from the previous operation, so we try to get - some from the network. */ - err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &buf, apiflags); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_recvfrom_udp_raw[UDP/RAW]: netconn_recv err=%d, netbuf=%p\n", err, (void *)buf)); - - if (err != ERR_OK) - { - return err; - } - LWIP_ASSERT("buf != NULL", buf != NULL); - sock->lastdata.netbuf = buf; - } - buflen = buf->p->tot_len; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw: buflen=%" U16_F "\n", buflen)); - - copied = 0; - /* copy the pbuf payload into the iovs */ - for (i = 0; (i < msg->msg_iovlen) && (copied < buflen); i++) - { - u16_t len_left = (u16_t)(buflen - copied); - if (msg->msg_iov[i].iov_len > len_left) - { - copylen = len_left; - } - else - { - copylen = (u16_t)msg->msg_iov[i].iov_len; - } - - /* copy the contents of the received buffer into - the supplied memory buffer */ - pbuf_copy_partial(buf->p, (u8_t *)msg->msg_iov[i].iov_base, copylen, copied); - copied = (u16_t)(copied + copylen); - } - - /* Check to see from where the data was.*/ + struct netbuf *buf; + u8_t apiflags; + err_t err; + u16_t buflen, copylen, copied; + msg_iovlen_t i; + + LWIP_UNUSED_ARG(dbg_s); + LWIP_ERROR("lwip_recvfrom_udp_raw: invalid arguments", (msg->msg_iov != NULL) || (msg->msg_iovlen <= 0), return ERR_ARG;); + + if (flags & MSG_DONTWAIT) { + apiflags = NETCONN_DONTBLOCK; + } else { + apiflags = 0; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); + /* Check if there is data left from the last recv operation. */ + buf = sock->lastdata.netbuf; + if (buf == NULL) { + /* No data was left from the previous operation, so we try to get + some from the network. */ + err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &buf, apiflags); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: netconn_recv err=%d, netbuf=%p\n", + err, (void *)buf)); + + if (err != ERR_OK) { + return err; + } + LWIP_ASSERT("buf != NULL", buf != NULL); + sock->lastdata.netbuf = buf; + } + buflen = buf->p->tot_len; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw: buflen=%"U16_F"\n", buflen)); + + copied = 0; + /* copy the pbuf payload into the iovs */ + for (i = 0; (i < msg->msg_iovlen) && (copied < buflen); i++) { + u16_t len_left = (u16_t)(buflen - copied); + if (msg->msg_iov[i].iov_len > len_left) { + copylen = len_left; + } else { + copylen = (u16_t)msg->msg_iov[i].iov_len; + } + + /* copy the contents of the received buffer into + the supplied memory buffer */ + pbuf_copy_partial(buf->p, (u8_t *)msg->msg_iov[i].iov_base, copylen, copied); + copied = (u16_t)(copied + copylen); + } + + /* Check to see from where the data was.*/ #if !SOCKETS_DEBUG - if (msg->msg_name && msg->msg_namelen) + if (msg->msg_name && msg->msg_namelen) #endif /* !SOCKETS_DEBUG */ - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw(%d): addr=", dbg_s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, *netbuf_fromaddr(buf)); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F " len=%d\n", netbuf_fromport(buf), copied)); - if (msg->msg_name && msg->msg_namelen) - { - lwip_sock_make_addr( - sock->conn, - netbuf_fromaddr(buf), - netbuf_fromport(buf), - (struct sockaddr *)msg->msg_name, - &msg->msg_namelen); - } + { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw(%d): addr=", dbg_s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, *netbuf_fromaddr(buf)); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", netbuf_fromport(buf), copied)); + if (msg->msg_name && msg->msg_namelen) { + lwip_sock_make_addr(sock->conn, netbuf_fromaddr(buf), netbuf_fromport(buf), + (struct sockaddr *)msg->msg_name, &msg->msg_namelen); } + } - /* Initialize flag output */ - msg->msg_flags = 0; + /* Initialize flag output */ + msg->msg_flags = 0; - if (msg->msg_control) - { - u8_t wrote_msg = 0; + if (msg->msg_control) { + u8_t wrote_msg = 0; #if LWIP_NETBUF_RECVINFO - /* Check if packet info was recorded */ - if (buf->flags & NETBUF_FLAG_DESTADDR) - { - if (IP_IS_V4(&buf->toaddr)) - { + /* Check if packet info was recorded */ + if (buf->flags & NETBUF_FLAG_DESTADDR) { + if (IP_IS_V4(&buf->toaddr)) { #if LWIP_IPV4 - if (msg->msg_controllen >= CMSG_SPACE(sizeof(struct in_pktinfo))) - { - struct cmsghdr *chdr = CMSG_FIRSTHDR(msg); /* This will always return a header!! */ - struct in_pktinfo *pkti = (struct in_pktinfo *)CMSG_DATA(chdr); - chdr->cmsg_level = IPPROTO_IP; - chdr->cmsg_type = IP_PKTINFO; - chdr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); - pkti->ipi_ifindex = buf->p->if_idx; - inet_addr_from_ip4addr(&pkti->ipi_addr, ip_2_ip4(netbuf_destaddr(buf))); - msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); - wrote_msg = 1; - } - else - { - msg->msg_flags |= MSG_CTRUNC; - } -#endif /* LWIP_IPV4 */ - } + if (msg->msg_controllen >= CMSG_SPACE(sizeof(struct in_pktinfo))) { + struct cmsghdr *chdr = CMSG_FIRSTHDR(msg); /* This will always return a header!! */ + struct in_pktinfo *pkti = (struct in_pktinfo *)CMSG_DATA(chdr); + chdr->cmsg_level = IPPROTO_IP; + chdr->cmsg_type = IP_PKTINFO; + chdr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + pkti->ipi_ifindex = buf->p->if_idx; + inet_addr_from_ip4addr(&pkti->ipi_addr, ip_2_ip4(netbuf_destaddr(buf))); + msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); + wrote_msg = 1; + } else { + msg->msg_flags |= MSG_CTRUNC; } +#endif /* LWIP_IPV4 */ + } + } #endif /* LWIP_NETBUF_RECVINFO */ - if (!wrote_msg) - { - msg->msg_controllen = 0; - } + if (!wrote_msg) { + msg->msg_controllen = 0; } + } - /* If we don't peek the incoming message: zero lastdata pointer and free the netbuf */ - if ((flags & MSG_PEEK) == 0) - { - sock->lastdata.netbuf = NULL; - netbuf_delete(buf); - } - if (datagram_len) - { - *datagram_len = buflen; - } - return ERR_OK; + /* If we don't peek the incoming message: zero lastdata pointer and free the netbuf */ + if ((flags & MSG_PEEK) == 0) { + sock->lastdata.netbuf = NULL; + netbuf_delete(buf); + } + if (datagram_len) { + *datagram_len = buflen; + } + return ERR_OK; } -ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) +ssize_t +lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) { - struct lwip_sock *sock; - ssize_t ret; + struct lwip_sock *sock; + ssize_t ret; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %" SZT_F ", 0x%x, ..)\n", s, mem, len, flags)); - sock = get_socket(s); - if (!sock) - { - return -1; - } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); + sock = get_socket(s); + if (!sock) { + return -1; + } #if LWIP_TCP - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) - { - ret = lwip_recv_tcp(sock, mem, len, flags); - lwip_recv_tcp_from(sock, from, fromlen, "lwip_recvfrom", s, ret); - done_socket(sock); - return ret; - } - else -#endif - { - u16_t datagram_len = 0; - struct iovec vec; - struct msghdr msg; - err_t err; - vec.iov_base = mem; - vec.iov_len = len; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - msg.msg_iov = &vec; - msg.msg_iovlen = 1; - msg.msg_name = from; - msg.msg_namelen = (fromlen ? *fromlen : 0); - err = lwip_recvfrom_udp_raw(sock, flags, &msg, &datagram_len, s); - if (err != ERR_OK) - { - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX); - if (fromlen) - { - *fromlen = msg.msg_namelen; - } - } - - sock_set_errno(sock, 0); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + ret = lwip_recv_tcp(sock, mem, len, flags); + lwip_recv_tcp_from(sock, from, fromlen, "lwip_recvfrom", s, ret); done_socket(sock); return ret; + } else +#endif + { + u16_t datagram_len = 0; + struct iovec vec; + struct msghdr msg; + err_t err; + vec.iov_base = mem; + vec.iov_len = len; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + msg.msg_name = from; + msg.msg_namelen = (fromlen ? *fromlen : 0); + err = lwip_recvfrom_udp_raw(sock, flags, &msg, &datagram_len, s); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + set_errno(err_to_errno(err)); + done_socket(sock); + return -1; + } + ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX); + if (fromlen) { + *fromlen = msg.msg_namelen; + } + } + + set_errno(0); + done_socket(sock); + return ret; } -ssize_t lwip_read(int s, void *mem, size_t len) +ssize_t +lwip_read(int s, void *mem, size_t len) { - return lwip_recvfrom(s, mem, len, 0, NULL, NULL); + return lwip_recvfrom(s, mem, len, 0, NULL, NULL); } -ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt) +ssize_t +lwip_readv(int s, const struct iovec *iov, int iovcnt) { - struct msghdr msg; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Hack: we have to cast via number to cast from 'const' pointer to non-const. - Blame the opengroup standard for this inconsistency. */ - msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); - msg.msg_iovlen = iovcnt; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - return lwip_recvmsg(s, &msg, 0); + struct msghdr msg; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + /* Hack: we have to cast via number to cast from 'const' pointer to non-const. + Blame the opengroup standard for this inconsistency. */ + msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); + msg.msg_iovlen = iovcnt; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + return lwip_recvmsg(s, &msg, 0); } -ssize_t lwip_recv(int s, void *mem, size_t len, int flags) +ssize_t +lwip_recv(int s, void *mem, size_t len, int flags) { - return lwip_recvfrom(s, mem, len, flags, NULL, NULL); + return lwip_recvfrom(s, mem, len, flags, NULL, NULL); } -ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags) +ssize_t +lwip_recvmsg(int s, struct msghdr *message, int flags) { - struct lwip_sock *sock; - int i; - ssize_t buflen; + struct lwip_sock *sock; + msg_iovlen_t i; + ssize_t buflen; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags)); - LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;); - LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK | MSG_DONTWAIT)) == 0, set_errno(EOPNOTSUPP); - return -1;); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags)); + LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;); + LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0, + set_errno(EOPNOTSUPP); return -1;); - if ((message->msg_iovlen <= 0) || (message->msg_iovlen > IOV_MAX)) - { - set_errno(EMSGSIZE); - return -1; - } - - sock = get_socket(s); - if (!sock) - { - return -1; - } + if ((message->msg_iovlen <= 0) || (message->msg_iovlen > IOV_MAX)) { + set_errno(EMSGSIZE); + return -1; + } - /* check for valid vectors */ + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* check for valid vectors */ + buflen = 0; + for (i = 0; i < message->msg_iovlen; i++) { + if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) || + ((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) || + ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) { + set_errno(err_to_errno(ERR_VAL)); + done_socket(sock); + return -1; + } + buflen = (ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len); + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { +#if LWIP_TCP + int recv_flags = flags; + message->msg_flags = 0; + /* recv the data */ buflen = 0; - for (i = 0; i < message->msg_iovlen; i++) - { - if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) || - ((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) || - ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) - { - sock_set_errno(sock, err_to_errno(ERR_VAL)); - done_socket(sock); - return -1; + for (i = 0; i < message->msg_iovlen; i++) { + /* try to receive into this vector's buffer */ + ssize_t recvd_local = lwip_recv_tcp(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, recv_flags); + if (recvd_local > 0) { + /* sum up received bytes */ + buflen += recvd_local; + } + if ((recvd_local < 0) || (recvd_local < (int)message->msg_iov[i].iov_len) || + (flags & MSG_PEEK)) { + /* returned prematurely (or peeking, which might actually be limitated to the first iov) */ + if (buflen <= 0) { + /* nothing received at all, propagate the error */ + buflen = recvd_local; } - buflen = (ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len); + break; + } + /* pass MSG_DONTWAIT to lwip_recv_tcp() to prevent waiting for more data */ + recv_flags |= MSG_DONTWAIT; } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) - { -#if LWIP_TCP - int recv_flags = flags; - message->msg_flags = 0; - /* recv the data */ - buflen = 0; - for (i = 0; i < message->msg_iovlen; i++) - { - /* try to receive into this vector's buffer */ - ssize_t recvd_local = - lwip_recv_tcp(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, recv_flags); - if (recvd_local > 0) - { - /* sum up received bytes */ - buflen += recvd_local; - } - if ((recvd_local < 0) || (recvd_local < (int)message->msg_iov[i].iov_len) || (flags & MSG_PEEK)) - { - /* returned prematurely (or peeking, which might actually be limitated to the first iov) */ - if (buflen <= 0) - { - /* nothing received at all, propagate the error */ - buflen = recvd_local; - } - break; - } - /* pass MSG_DONTWAIT to lwip_recv_tcp() to prevent waiting for more data */ - recv_flags |= MSG_DONTWAIT; - } - if (buflen > 0) - { - /* reset socket error since we have received something */ - sock_set_errno(sock, 0); - } - /* " If the socket is connected, the msg_name and msg_namelen members shall be ignored." */ - done_socket(sock); - return buflen; -#else /* LWIP_TCP */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* LWIP_TCP */ + if (buflen > 0) { + /* reset socket error since we have received something */ + set_errno(0); } - /* else, UDP and RAW NETCONNs */ + /* " If the socket is connected, the msg_name and msg_namelen members shall be ignored." */ + done_socket(sock); + return buflen; +#else /* LWIP_TCP */ + set_errno(err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* LWIP_TCP */ + } + /* else, UDP and RAW NETCONNs */ #if LWIP_UDP || LWIP_RAW - { - u16_t datagram_len = 0; - err_t err; - err = lwip_recvfrom_udp_raw(sock, flags, message, &datagram_len, s); - if (err != ERR_OK) - { - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_recvmsg[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } - if (datagram_len > buflen) - { - message->msg_flags |= MSG_TRUNC; - } - - sock_set_errno(sock, 0); - done_socket(sock); - return (int)datagram_len; + { + u16_t datagram_len = 0; + err_t err; + err = lwip_recvfrom_udp_raw(sock, flags, message, &datagram_len, s); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + set_errno(err_to_errno(err)); + done_socket(sock); + return -1; } -#else /* LWIP_UDP || LWIP_RAW */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); + if (datagram_len > buflen) { + message->msg_flags |= MSG_TRUNC; + } + + set_errno(0); done_socket(sock); - return -1; + return (int)datagram_len; + } +#else /* LWIP_UDP || LWIP_RAW */ + set_errno(err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; #endif /* LWIP_UDP || LWIP_RAW */ } -ssize_t lwip_send(int s, const void *data, size_t size, int flags) +ssize_t +lwip_send(int s, const void *data, size_t size, int flags) { - struct lwip_sock *sock; - err_t err; - u8_t write_flags; - size_t written; + struct lwip_sock *sock; + err_t err; + u8_t write_flags; + size_t written; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%" SZT_F ", flags=0x%x)\n", s, data, size, flags)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", + s, data, size, flags)); - sock = get_socket(s); - if (!sock) - { - return -1; - } + sock = get_socket(s); + if (!sock) { + return -1; + } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { #if (LWIP_UDP || LWIP_RAW) - done_socket(sock); - return lwip_sendto(s, data, size, flags, NULL, 0); -#else /* (LWIP_UDP || LWIP_RAW) */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - - write_flags = - (u8_t)(NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); - written = 0; - err = netconn_write_partly(sock->conn, data, size, write_flags, &written); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%" SZT_F "\n", s, err, written)); - sock_set_errno(sock, err_to_errno(err)); done_socket(sock); - /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ - return (err == ERR_OK ? (ssize_t)written : -1); + return lwip_sendto(s, data, size, flags, NULL, 0); +#else /* (LWIP_UDP || LWIP_RAW) */ + set_errno(err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + write_flags = (u8_t)(NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); + written = 0; + err = netconn_write_partly(sock->conn, data, size, write_flags, &written); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); + set_errno(err_to_errno(err)); + done_socket(sock); + /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ + return (err == ERR_OK ? (ssize_t)written : -1); } -ssize_t lwip_sendmsg(int s, const struct msghdr *msg, int flags) +ssize_t +lwip_sendmsg(int s, const struct msghdr *msg, int flags) { - struct lwip_sock *sock; + struct lwip_sock *sock; #if LWIP_TCP - u8_t write_flags; - size_t written; + u8_t write_flags; + size_t written; #endif - err_t err = ERR_OK; - - sock = get_socket(s); - if (!sock) - { - return -1; - } - - LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL, sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1;); - LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", msg->msg_iov != NULL, sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1;); - LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", - (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX), - sock_set_errno(sock, EMSGSIZE); - done_socket(sock); - return -1;); - LWIP_ERROR( - "lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0, sock_set_errno(sock, EOPNOTSUPP); - done_socket(sock); - return -1;); - - LWIP_UNUSED_ARG(msg->msg_control); - LWIP_UNUSED_ARG(msg->msg_controllen); - LWIP_UNUSED_ARG(msg->msg_flags); + err_t err = ERR_OK; - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) - { + sock = get_socket(s); + if (!sock) { + return -1; + } + + LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL, + set_errno(err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", msg->msg_iov != NULL, + set_errno(err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX), + set_errno(EMSGSIZE); done_socket(sock); return -1;); + LWIP_ERROR("lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0, + set_errno(EOPNOTSUPP); done_socket(sock); return -1;); + + LWIP_UNUSED_ARG(msg->msg_control); + LWIP_UNUSED_ARG(msg->msg_controllen); + LWIP_UNUSED_ARG(msg->msg_flags); + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { #if LWIP_TCP - write_flags = - (u8_t)(NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); - - written = 0; - err = netconn_write_vectors_partly( - sock->conn, - (struct netvector *)msg->msg_iov, - (u16_t)msg->msg_iovlen, - write_flags, - &written); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ - return (err == ERR_OK ? (ssize_t)written : -1); -#else /* LWIP_TCP */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; + write_flags = (u8_t)(NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); + + written = 0; + err = netconn_write_vectors_partly(sock->conn, (struct netvector *)msg->msg_iov, (u16_t)msg->msg_iovlen, write_flags, &written); + set_errno(err_to_errno(err)); + done_socket(sock); + /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ + return (err == ERR_OK ? (ssize_t)written : -1); +#else /* LWIP_TCP */ + set_errno(err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; #endif /* LWIP_TCP */ - } - /* else, UDP and RAW NETCONNs */ + } + /* else, UDP and RAW NETCONNs */ #if LWIP_UDP || LWIP_RAW - { - struct netbuf chain_buf; - int i; - ssize_t size = 0; - - LWIP_UNUSED_ARG(flags); - LWIP_ERROR("lwip_sendmsg: invalid msghdr name", - (((msg->msg_name == NULL) && (msg->msg_namelen == 0)) || IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1;); - - /* initialize chain buffer with destination */ - memset(&chain_buf, 0, sizeof(struct netbuf)); - if (msg->msg_name) - { - u16_t remote_port; - SOCKADDR_TO_IPADDR_PORT((const struct sockaddr *)msg->msg_name, &chain_buf.addr, remote_port); - netbuf_fromport(&chain_buf) = remote_port; - } + { + struct netbuf chain_buf; + msg_iovlen_t i; + ssize_t size = 0; + + LWIP_UNUSED_ARG(flags); + LWIP_ERROR("lwip_sendmsg: invalid msghdr name", (((msg->msg_name == NULL) && (msg->msg_namelen == 0)) || + IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)), + set_errno(err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + + /* initialize chain buffer with destination */ + memset(&chain_buf, 0, sizeof(struct netbuf)); + if (msg->msg_name) { + u16_t remote_port; + SOCKADDR_TO_IPADDR_PORT((const struct sockaddr *)msg->msg_name, &chain_buf.addr, remote_port); + netbuf_fromport(&chain_buf) = remote_port; + } #if LWIP_NETIF_TX_SINGLE_PBUF - for (i = 0; i < msg->msg_iovlen; i++) - { - size += msg->msg_iov[i].iov_len; - if ((msg->msg_iov[i].iov_len > INT_MAX) || (size < (int)msg->msg_iov[i].iov_len)) - { - /* overflow */ - goto sendmsg_emsgsize; - } - } - if (size > 0xFFFF) - { - /* overflow */ - goto sendmsg_emsgsize; - } - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&chain_buf, (u16_t)size) == NULL) - { - err = ERR_MEM; - } - else - { - /* flatten the IO vectors */ - size_t offset = 0; - for (i = 0; i < msg->msg_iovlen; i++) - { - MEMCPY(&((u8_t *)chain_buf.p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); - offset += msg->msg_iov[i].iov_len; - } + for (i = 0; i < msg->msg_iovlen; i++) { + size += msg->msg_iov[i].iov_len; + if ((msg->msg_iov[i].iov_len > INT_MAX) || (size < (int)msg->msg_iov[i].iov_len)) { + /* overflow */ + goto sendmsg_emsgsize; + } + } + if (size > 0xFFFF) { + /* overflow */ + goto sendmsg_emsgsize; + } + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&chain_buf, (u16_t)size) == NULL) { + err = ERR_MEM; + } else { + /* flatten the IO vectors */ + size_t offset = 0; + for (i = 0; i < msg->msg_iovlen; i++) { + MEMCPY(&((u8_t *)chain_buf.p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); + offset += msg->msg_iov[i].iov_len; + } #if LWIP_CHECKSUM_ON_COPY - { - /* This can be improved by using LWIP_CHKSUM_COPY() and aggregating the checksum for each IO vector */ - u16_t chksum = ~inet_chksum_pbuf(chain_buf.p); - netbuf_set_chksum(&chain_buf, chksum); - } + { + /* This can be improved by using LWIP_CHKSUM_COPY() and aggregating the checksum for each IO vector */ + u16_t chksum = ~inet_chksum_pbuf(chain_buf.p); + netbuf_set_chksum(&chain_buf, chksum); + } #endif /* LWIP_CHECKSUM_ON_COPY */ - err = ERR_OK; - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - /* create a chained netbuf from the IO vectors. NOTE: we assemble a pbuf chain - manually to avoid having to allocate, chain, and delete a netbuf for each iov */ - for (i = 0; i < msg->msg_iovlen; i++) - { - struct pbuf *p; - if (msg->msg_iov[i].iov_len > 0xFFFF) - { - /* overflow */ - goto sendmsg_emsgsize; - } - p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); - if (p == NULL) - { - err = ERR_MEM; /* let netbuf_delete() cleanup chain_buf */ - break; - } - p->payload = msg->msg_iov[i].iov_base; - p->len = p->tot_len = (u16_t)msg->msg_iov[i].iov_len; - /* netbuf empty, add new pbuf */ - if (chain_buf.p == NULL) - { - chain_buf.p = chain_buf.ptr = p; - /* add pbuf to existing pbuf chain */ - } - else - { - if (chain_buf.p->tot_len + p->len > 0xffff) - { - /* overflow */ - pbuf_free(p); - goto sendmsg_emsgsize; - } - pbuf_cat(chain_buf.p, p); - } - } - /* save size of total chain */ - if (err == ERR_OK) - { - size = netbuf_len(&chain_buf); + err = ERR_OK; + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + /* create a chained netbuf from the IO vectors. NOTE: we assemble a pbuf chain + manually to avoid having to allocate, chain, and delete a netbuf for each iov */ + for (i = 0; i < msg->msg_iovlen; i++) { + struct pbuf *p; + if (msg->msg_iov[i].iov_len > 0xFFFF) { + /* overflow */ + goto sendmsg_emsgsize; + } + p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (p == NULL) { + err = ERR_MEM; /* let netbuf_delete() cleanup chain_buf */ + break; + } + p->payload = msg->msg_iov[i].iov_base; + p->len = p->tot_len = (u16_t)msg->msg_iov[i].iov_len; + /* netbuf empty, add new pbuf */ + if (chain_buf.p == NULL) { + chain_buf.p = chain_buf.ptr = p; + /* add pbuf to existing pbuf chain */ + } else { + if (chain_buf.p->tot_len + p->len > 0xffff) { + /* overflow */ + pbuf_free(p); + goto sendmsg_emsgsize; } + pbuf_cat(chain_buf.p, p); + } + } + /* save size of total chain */ + if (err == ERR_OK) { + size = netbuf_len(&chain_buf); + } #endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (err == ERR_OK) - { + if (err == ERR_OK) { #if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(chain_buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf.addr))) - { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf.addr), ip_2_ip6(&chain_buf.addr)); - IP_SET_TYPE_VAL(chain_buf.addr, IPADDR_TYPE_V4); - } + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(chain_buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf.addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf.addr), ip_2_ip6(&chain_buf.addr)); + IP_SET_TYPE_VAL(chain_buf.addr, IPADDR_TYPE_V4); + } #endif /* LWIP_IPV4 && LWIP_IPV6 */ - /* send the data */ - err = netconn_send(sock->conn, &chain_buf); - } + /* send the data */ + err = netconn_send(sock->conn, &chain_buf); + } - /* deallocated the buffer */ - netbuf_free(&chain_buf); + /* deallocated the buffer */ + netbuf_free(&chain_buf); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return (err == ERR_OK ? size : -1); - sendmsg_emsgsize: - sock_set_errno(sock, EMSGSIZE); - netbuf_free(&chain_buf); - done_socket(sock); - return -1; - } -#else /* LWIP_UDP || LWIP_RAW */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); + set_errno(err_to_errno(err)); + done_socket(sock); + return (err == ERR_OK ? size : -1); +sendmsg_emsgsize: + set_errno(EMSGSIZE); + netbuf_free(&chain_buf); done_socket(sock); return -1; + } +#else /* LWIP_UDP || LWIP_RAW */ + set_errno(err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; #endif /* LWIP_UDP || LWIP_RAW */ } -ssize_t lwip_sendto(int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) +ssize_t +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) { - struct lwip_sock *sock; - err_t err; - u16_t short_size; - u16_t remote_port; - struct netbuf buf; - - sock = get_socket(s); - if (!sock) - { - return -1; - } + struct lwip_sock *sock; + err_t err; + u16_t short_size; + u16_t remote_port; + struct netbuf buf; + + sock = get_socket(s); + if (!sock) { + return -1; + } - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) - { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { #if LWIP_TCP - done_socket(sock); - return lwip_send(s, data, size, flags); -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(flags); - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1; + done_socket(sock); + return lwip_send(s, data, size, flags); +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(flags); + set_errno(err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; #endif /* LWIP_TCP */ - } + } - if (size > LWIP_MIN(0xFFFF, SSIZE_MAX)) - { - /* cannot fit into one datagram (at least for us) */ - sock_set_errno(sock, EMSGSIZE); - done_socket(sock); - return -1; - } - short_size = (u16_t)size; - LWIP_ERROR("lwip_sendto: invalid address", - (((to == NULL) && (tolen == 0)) || - (IS_SOCK_ADDR_LEN_VALID(tolen) && - ((to != NULL) && (IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))))), - sock_set_errno(sock, err_to_errno(ERR_ARG)); - done_socket(sock); - return -1;); - LWIP_UNUSED_ARG(tolen); - - /* initialize a buffer */ - buf.p = buf.ptr = NULL; + if (size > LWIP_MIN(0xFFFF, SSIZE_MAX)) { + /* cannot fit into one datagram (at least for us) */ + set_errno(EMSGSIZE); + done_socket(sock); + return -1; + } + short_size = (u16_t)size; + LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || + (IS_SOCK_ADDR_LEN_VALID(tolen) && + ((to != NULL) && (IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))))), + set_errno(err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_UNUSED_ARG(tolen); + + /* initialize a buffer */ + buf.p = buf.ptr = NULL; #if LWIP_CHECKSUM_ON_COPY - buf.flags = 0; + buf.flags = 0; #endif /* LWIP_CHECKSUM_ON_COPY */ - if (to) - { - SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port); - } - else - { - remote_port = 0; - ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); - } - netbuf_fromport(&buf) = remote_port; + if (to) { + SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port); + } else { + remote_port = 0; + ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); + } + netbuf_fromport(&buf) = remote_port; + - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_sendto(%d, data=%p, short_size=%" U16_F ", flags=0x%x to=", s, data, short_size, flags)); - ip_addr_debug_print_val(SOCKETS_DEBUG, buf.addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F "\n", remote_port)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", + s, data, short_size, flags)); + ip_addr_debug_print_val(SOCKETS_DEBUG, buf.addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); - /* make the buffer point to the data that should be sent */ + /* make the buffer point to the data that should be sent */ #if LWIP_NETIF_TX_SINGLE_PBUF - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&buf, short_size) == NULL) - { - err = ERR_MEM; - } - else - { + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { #if LWIP_CHECKSUM_ON_COPY - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) - { - u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); - netbuf_set_chksum(&buf, chksum); - } - else + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { + u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); + netbuf_set_chksum(&buf, chksum); + } else #endif /* LWIP_CHECKSUM_ON_COPY */ - { - MEMCPY(buf.p->payload, data, short_size); - } - err = ERR_OK; + { + MEMCPY(buf.p->payload, data, short_size); } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - err = netbuf_ref(&buf, data, short_size); + err = ERR_OK; + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); #endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (err == ERR_OK) - { + if (err == ERR_OK) { #if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) - { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr)); - IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4); - } + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr)); + IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4); + } #endif /* LWIP_IPV4 && LWIP_IPV6 */ - /* send the data */ - err = netconn_send(sock->conn, &buf); - } + /* send the data */ + err = netconn_send(sock->conn, &buf); + } - /* deallocated the buffer */ - netbuf_free(&buf); + /* deallocated the buffer */ + netbuf_free(&buf); - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return (err == ERR_OK ? short_size : -1); + set_errno(err_to_errno(err)); + done_socket(sock); + return (err == ERR_OK ? short_size : -1); } -int lwip_socket(int domain, int type, int protocol) +int +lwip_socket(int domain, int type, int protocol) { - struct netconn *conn; - int i; - - LWIP_UNUSED_ARG(domain); /* @todo: check this */ - - /* create a netconn */ - switch (type) - { - case SOCK_RAW: - conn = netconn_new_with_proto_and_callback( - DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), - (u8_t)protocol, - DEFAULT_SOCKET_EVENTCB); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_socket(%s, SOCK_RAW, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_DGRAM: - conn = netconn_new_with_callback( - DOMAIN_TO_NETCONN_TYPE(domain, ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)), - DEFAULT_SOCKET_EVENTCB); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_socket(%s, SOCK_DGRAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + struct netconn *conn; + int i; + + LWIP_UNUSED_ARG(domain); /* @todo: check this */ + + /* create a netconn */ + switch (type) { + case SOCK_RAW: + conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), + (u8_t)protocol, DEFAULT_SOCKET_EVENTCB); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_DGRAM: + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, + ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)), + DEFAULT_SOCKET_EVENTCB); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); #if LWIP_NETBUF_RECVINFO - if (conn) - { - /* netconn layer enables pktinfo by default, sockets default to off */ - conn->flags &= ~NETCONN_FLAG_PKTINFO; - } + if (conn) { + /* netconn layer enables pktinfo by default, sockets default to off */ + conn->flags &= ~NETCONN_FLAG_PKTINFO; + } #endif /* LWIP_NETBUF_RECVINFO */ - break; - case SOCK_STREAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), DEFAULT_SOCKET_EVENTCB); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_socket(%s, SOCK_STREAM, %d) = ", domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", domain, type, protocol)); - set_errno(EINVAL); - return -1; - } - - if (!conn) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); - set_errno(ENOBUFS); - return -1; - } + break; + case SOCK_STREAM: + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), DEFAULT_SOCKET_EVENTCB); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", + domain, type, protocol)); + set_errno(EINVAL); + return -1; + } + + if (!conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); + set_errno(ENOBUFS); + return -1; + } - i = alloc_socket(conn, 0); + i = alloc_socket(conn, 0); - if (i == -1) - { - netconn_delete(conn); - set_errno(ENFILE); - return -1; - } - conn->socket = i; - done_socket(&sockets[i - LWIP_SOCKET_OFFSET]); - LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); - set_errno(0); - return i; + if (i == -1) { + netconn_delete(conn); + set_errno(ENFILE); + return -1; + } + conn->callback_arg.socket = i; + done_socket(&sockets[i - LWIP_SOCKET_OFFSET]); + LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); + set_errno(0); + return i; } -ssize_t lwip_write(int s, const void *data, size_t size) +ssize_t +lwip_write(int s, const void *data, size_t size) { - return lwip_send(s, data, size, 0); + return lwip_send(s, data, size, 0); } -ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt) +ssize_t +lwip_writev(int s, const struct iovec *iov, int iovcnt) { - struct msghdr msg; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Hack: we have to cast via number to cast from 'const' pointer to non-const. - Blame the opengroup standard for this inconsistency. */ - msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); - msg.msg_iovlen = iovcnt; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - return lwip_sendmsg(s, &msg, 0); + struct msghdr msg; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + /* Hack: we have to cast via number to cast from 'const' pointer to non-const. + Blame the opengroup standard for this inconsistency. */ + msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); + msg.msg_iovlen = iovcnt; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + return lwip_sendmsg(s, &msg, 0); } #if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL /* Add select_cb to select_cb_list. */ -static void lwip_link_select_cb(struct lwip_select_cb *select_cb) +static void +lwip_link_select_cb(struct lwip_select_cb *select_cb) { - LWIP_SOCKET_SELECT_DECL_PROTECT(lev); + LWIP_SOCKET_SELECT_DECL_PROTECT(lev); - /* Protect the select_cb_list */ - LWIP_SOCKET_SELECT_PROTECT(lev); + /* Protect the select_cb_list */ + LWIP_SOCKET_SELECT_PROTECT(lev); - /* Put this select_cb on top of list */ - select_cb->next = select_cb_list; - if (select_cb_list != NULL) - { - select_cb_list->prev = select_cb; - } - select_cb_list = select_cb; + /* Put this select_cb on top of list */ + select_cb->next = select_cb_list; + if (select_cb_list != NULL) { + select_cb_list->prev = select_cb; + } + select_cb_list = select_cb; #if !LWIP_TCPIP_CORE_LOCKING - /* Increasing this counter tells select_check_waiters that the list has changed. */ - select_cb_ctr++; + /* Increasing this counter tells select_check_waiters that the list has changed. */ + select_cb_ctr++; #endif - /* Now we can safely unprotect */ - LWIP_SOCKET_SELECT_UNPROTECT(lev); + /* Now we can safely unprotect */ + LWIP_SOCKET_SELECT_UNPROTECT(lev); } /* Remove select_cb from select_cb_list. */ -static void lwip_unlink_select_cb(struct lwip_select_cb *select_cb) +static void +lwip_unlink_select_cb(struct lwip_select_cb *select_cb) { - LWIP_SOCKET_SELECT_DECL_PROTECT(lev); - - /* Take us off the list */ - LWIP_SOCKET_SELECT_PROTECT(lev); - if (select_cb->next != NULL) - { - select_cb->next->prev = select_cb->prev; - } - if (select_cb_list == select_cb) - { - LWIP_ASSERT("select_cb->prev == NULL", select_cb->prev == NULL); - select_cb_list = select_cb->next; - } - else - { - LWIP_ASSERT("select_cb->prev != NULL", select_cb->prev != NULL); - select_cb->prev->next = select_cb->next; - } + LWIP_SOCKET_SELECT_DECL_PROTECT(lev); + + /* Take us off the list */ + LWIP_SOCKET_SELECT_PROTECT(lev); + if (select_cb->next != NULL) { + select_cb->next->prev = select_cb->prev; + } + if (select_cb_list == select_cb) { + LWIP_ASSERT("select_cb->prev == NULL", select_cb->prev == NULL); + select_cb_list = select_cb->next; + } else { + LWIP_ASSERT("select_cb->prev != NULL", select_cb->prev != NULL); + select_cb->prev->next = select_cb->next; + } #if !LWIP_TCPIP_CORE_LOCKING - /* Increasing this counter tells select_check_waiters that the list has changed. */ - select_cb_ctr++; + /* Increasing this counter tells select_check_waiters that the list has changed. */ + select_cb_ctr++; #endif - LWIP_SOCKET_SELECT_UNPROTECT(lev); + LWIP_SOCKET_SELECT_UNPROTECT(lev); } #endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ @@ -2218,83 +1920,71 @@ static void lwip_unlink_select_cb(struct lwip_select_cb *select_cb) * @param exceptset_out set os sockets that had error events * @return number of sockets that had events (read/write/exception) (>= 0) */ -static int lwip_selscan( - int maxfdp1, - fd_set *readset_in, - fd_set *writeset_in, - fd_set *exceptset_in, - fd_set *readset_out, - fd_set *writeset_out, - fd_set *exceptset_out) +static int +lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, + fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) { - int i, nready = 0; - fd_set lreadset, lwriteset, lexceptset; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - FD_ZERO(&lreadset); - FD_ZERO(&lwriteset); - FD_ZERO(&lexceptset); - - /* Go through each socket in each list to count number of sockets which - currently match */ - for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) - { - /* if this FD is not in the set, continue */ - if (!(readset_in && FD_ISSET(i, readset_in)) && !(writeset_in && FD_ISSET(i, writeset_in)) && - !(exceptset_in && FD_ISSET(i, exceptset_in))) - { - continue; - } - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) - { - void *lastdata = sock->lastdata.pbuf; - s16_t rcvevent = sock->rcvevent; - u16_t sendevent = sock->sendevent; - u16_t errevent = sock->errevent; - SYS_ARCH_UNPROTECT(lev); - - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) - { - FD_SET(i, &lreadset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); - nready++; - } - /* See if netconn of this socket is ready for write */ - if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) - { - FD_SET(i, &lwriteset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); - nready++; - } - /* See if netconn of this socket had an error */ - if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) - { - FD_SET(i, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); - nready++; - } - done_socket(sock); - } - else - { - SYS_ARCH_UNPROTECT(lev); - /* no a valid open socket */ - return -1; - } - } - /* copy local sets to the ones provided as arguments */ - *readset_out = lreadset; - *writeset_out = lwriteset; - *exceptset_out = lexceptset; - - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; + int i, nready = 0; + fd_set lreadset, lwriteset, lexceptset; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + FD_ZERO(&lreadset); + FD_ZERO(&lwriteset); + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { + /* if this FD is not in the set, continue */ + if (!(readset_in && FD_ISSET(i, readset_in)) && + !(writeset_in && FD_ISSET(i, writeset_in)) && + !(exceptset_in && FD_ISSET(i, exceptset_in))) { + continue; + } + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + void *lastdata = sock->lastdata.pbuf; + s16_t rcvevent = sock->rcvevent; + u16_t sendevent = sock->sendevent; + u16_t errevent = sock->errevent; + SYS_ARCH_UNPROTECT(lev); + + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { + FD_SET(i, &lreadset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); + nready++; + } + /* See if netconn of this socket is ready for write */ + if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { + FD_SET(i, &lwriteset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); + nready++; + } + /* See if netconn of this socket had an error */ + if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { + FD_SET(i, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); + nready++; + } + done_socket(sock); + } else { + SYS_ARCH_UNPROTECT(lev); + /* no a valid open socket */ + return -1; + } + } + /* copy local sets to the ones provided as arguments */ + *readset_out = lreadset; + *writeset_out = lwriteset; + *exceptset_out = lexceptset; + + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; } #if LWIP_NETCONN_FULLDUPLEX @@ -2302,29 +1992,26 @@ static int lwip_selscan( * All sockets are marked (and later unmarked), whether they are open or not. * This is OK as lwip_selscan aborts select when non-open sockets are found. */ -static void lwip_select_inc_sockets_used_set(int maxfdp, fd_set *fdset, fd_set *used_sockets) +static void +lwip_select_inc_sockets_used_set(int maxfdp, fd_set *fdset, fd_set *used_sockets) { - SYS_ARCH_DECL_PROTECT(lev); - if (fdset) - { - int i; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) - { - /* if this FD is in the set, lock it (unless already done) */ - if (FD_ISSET(i, fdset) && !FD_ISSET(i, used_sockets)) - { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) - { - /* leave the socket used until released by lwip_select_dec_sockets_used */ - FD_SET(i, used_sockets); - } - SYS_ARCH_UNPROTECT(lev); - } + SYS_ARCH_DECL_PROTECT(lev); + if (fdset) { + int i; + for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) { + /* if this FD is in the set, lock it (unless already done) */ + if (FD_ISSET(i, fdset) && !FD_ISSET(i, used_sockets)) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + /* leave the socket used until released by lwip_select_dec_sockets_used */ + FD_SET(i, used_sockets); } + SYS_ARCH_UNPROTECT(lev); + } } + } } /* Mark all sockets passed to select as used to prevent them from being freed @@ -2332,295 +2019,250 @@ static void lwip_select_inc_sockets_used_set(int maxfdp, fd_set *fdset, fd_set * * Marked sockets are added to 'used_sockets' to mark them only once an be able * to unmark them correctly. */ -static void lwip_select_inc_sockets_used( - int maxfdp, - fd_set *fdset1, - fd_set *fdset2, - fd_set *fdset3, - fd_set *used_sockets) +static void +lwip_select_inc_sockets_used(int maxfdp, fd_set *fdset1, fd_set *fdset2, fd_set *fdset3, fd_set *used_sockets) { - FD_ZERO(used_sockets); - lwip_select_inc_sockets_used_set(maxfdp, fdset1, used_sockets); - lwip_select_inc_sockets_used_set(maxfdp, fdset2, used_sockets); - lwip_select_inc_sockets_used_set(maxfdp, fdset3, used_sockets); + FD_ZERO(used_sockets); + lwip_select_inc_sockets_used_set(maxfdp, fdset1, used_sockets); + lwip_select_inc_sockets_used_set(maxfdp, fdset2, used_sockets); + lwip_select_inc_sockets_used_set(maxfdp, fdset3, used_sockets); } /* Let go all sockets that were marked as used when starting select */ -static void lwip_select_dec_sockets_used(int maxfdp, fd_set *used_sockets) +static void +lwip_select_dec_sockets_used(int maxfdp, fd_set *used_sockets) { - int i; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) - { - /* if this FD is not in the set, continue */ - if (FD_ISSET(i, used_sockets)) - { - struct lwip_sock *sock = tryget_socket_unconn_nouse(i); - LWIP_ASSERT("socket gone at the end of select", sock != NULL); - if (sock != NULL) - { - done_socket(sock); - } - } + int i; + for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) { + /* if this FD is not in the set, continue */ + if (FD_ISSET(i, used_sockets)) { + struct lwip_sock *sock = tryget_socket_unconn_nouse(i); + LWIP_ASSERT("socket gone at the end of select", sock != NULL); + if (sock != NULL) { + done_socket(sock); + } } + } } #else /* LWIP_NETCONN_FULLDUPLEX */ #define lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, used_sockets) #define lwip_select_dec_sockets_used(maxfdp1, used_sockets) #endif /* LWIP_NETCONN_FULLDUPLEX */ -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) +int +lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout) { - u32_t waitres = 0; - int nready; - fd_set lreadset, lwriteset, lexceptset; - u32_t msectimeout; - int i; - int maxfdp2; + u32_t waitres = 0; + int nready; + fd_set lreadset, lwriteset, lexceptset; + u32_t msectimeout; + int i; + int maxfdp2; #if LWIP_NETCONN_SEM_PER_THREAD - int waited = 0; + int waited = 0; #endif #if LWIP_NETCONN_FULLDUPLEX - fd_set used_sockets; -#endif - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_select(%d, %p, %p, %p, tvsec=%" S32_F " tvusec=%" S32_F ")\n", - maxfdp1, - (void *)readset, - (void *)writeset, - (void *)exceptset, - timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, - timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); - - if ((maxfdp1 < 0) || (maxfdp1 > LWIP_SELECT_MAXNFDS)) - { - set_errno(EINVAL); - return -1; - } + fd_set used_sockets; +#endif + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", + maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, + timeout ? (s32_t)timeout->tv_sec : (s32_t) - 1, + timeout ? (s32_t)timeout->tv_usec : (s32_t) - 1)); - lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, &used_sockets); + if ((maxfdp1 < 0) || (maxfdp1 > LWIP_SELECT_MAXNFDS)) { + set_errno(EINVAL); + return -1; + } - /* Go through each socket in each list to count number of sockets which - currently match */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, &used_sockets); - if (nready < 0) - { - /* one of the sockets in one of the fd_sets was invalid */ - set_errno(EBADF); + /* Go through each socket in each list to count number of sockets which + currently match */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + + if (nready < 0) { + /* one of the sockets in one of the fd_sets was invalid */ + set_errno(EBADF); + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + return -1; + } else if (nready > 0) { + /* one or more sockets are set, no need to wait */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); + } else { + /* If we don't have any current events, then suspend if we are supposed to */ + if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + } else { + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables (unless we're running in MPU compatible + mode). */ + API_SELECT_CB_VAR_DECLARE(select_cb); + API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); return -1); + memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); + + API_SELECT_CB_VAR_REF(select_cb).readset = readset; + API_SELECT_CB_VAR_REF(select_cb).writeset = writeset; + API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset; +#if LWIP_NETCONN_SEM_PER_THREAD + API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); + if (!sys_sem_valid(API_SELECT_CB_VAR_REF(select_cb).sem)) { + set_errno(ENOMEM); + return -1; + } +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { + /* failed to create semaphore */ + set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + API_SELECT_CB_VAR_FREE(select_cb); return -1; - } - else if (nready > 0) - { - /* one or more sockets are set, no need to wait */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); - } - else - { - /* If we don't have any current events, then suspend if we are supposed to */ - if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - } - else - { - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables (unless we're running in MPU compatible - mode). */ - API_SELECT_CB_VAR_DECLARE(select_cb); - API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - return -1); - memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); - - API_SELECT_CB_VAR_REF(select_cb).readset = readset; - API_SELECT_CB_VAR_REF(select_cb).writeset = writeset; - API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset; -#if LWIP_NETCONN_SEM_PER_THREAD - API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) - { - /* failed to create semaphore */ - set_errno(ENOMEM); - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - API_SELECT_CB_VAR_FREE(select_cb); - return -1; - } + } #endif /* LWIP_NETCONN_SEM_PER_THREAD */ - lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); - - /* Increase select_waiting for each socket we are interested in */ - maxfdp2 = maxfdp1; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) - { - if ((readset && FD_ISSET(i, readset)) || (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) - { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(i); - if (sock != NULL) - { - sock->select_waiting++; - if (sock->select_waiting == 0) - { - /* overflow - too many threads waiting */ - sock->select_waiting--; - nready = -1; - maxfdp2 = i; - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - set_errno(EBUSY); - break; - } - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - } - else - { - /* Not a valid socket */ - nready = -1; - maxfdp2 = i; - SYS_ARCH_UNPROTECT(lev); - set_errno(EBADF); - break; - } - } + lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + + /* Increase select_waiting for each socket we are interested in */ + maxfdp2 = maxfdp1; + for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + sock->select_waiting++; + if (sock->select_waiting == 0) { + /* overflow - too many threads waiting */ + sock->select_waiting--; + nready = -1; + maxfdp2 = i; + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + set_errno(EBUSY); + break; + } + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } else { + /* Not a valid socket */ + nready = -1; + maxfdp2 = i; + SYS_ARCH_UNPROTECT(lev); + set_errno(EBADF); + break; + } + } + } + + if (nready >= 0) { + /* Call lwip_selscan again: there could have been events between + the last scan (without us on the list) and putting us on the list! */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + if (nready < 0) { + set_errno(EBADF); + } else if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout == NULL) { + /* Wait forever */ + msectimeout = 0; + } else { + long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500) / 1000)); + if (msecs_long <= 0) { + /* Wait 1ms at least (0 means wait forever) */ + msectimeout = 1; + } else { + msectimeout = (u32_t)msecs_long; } + } - if (nready >= 0) - { - /* Call lwip_selscan again: there could have been events between - the last scan (without us on the list) and putting us on the list! */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - if (nready < 0) - { - set_errno(EBADF); - } - else if (!nready) - { - /* Still none ready, just wait to be woken */ - if (timeout == 0) - { - /* Wait forever */ - msectimeout = 0; - } - else - { - long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500) / 1000)); - if (msecs_long <= 0) - { - /* Wait 1ms at least (0 means wait forever) */ - msectimeout = 1; - } - else - { - msectimeout = (u32_t)msecs_long; - } - } - - waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); + waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); #if LWIP_NETCONN_SEM_PER_THREAD - waited = 1; + waited = 1; #endif - } - } - - /* Decrease select_waiting for each socket we are interested in */ - for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) - { - if ((readset && FD_ISSET(i, readset)) || (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) - { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_nouse(i); - LWIP_ASSERT("socket gone at the end of select", sock != NULL); - if (sock != NULL) - { - /* for now, handle select_waiting==0... */ - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - if (sock->select_waiting > 0) - { - sock->select_waiting--; - } - SYS_ARCH_UNPROTECT(lev); - } - else - { - SYS_ARCH_UNPROTECT(lev); - /* Not a valid socket */ - nready = -1; - set_errno(EBADF); - } - } + } + } + + /* Decrease select_waiting for each socket we are interested in */ + for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_nouse(i); + LWIP_ASSERT("socket gone at the end of select", sock != NULL); + if (sock != NULL) { + /* for now, handle select_waiting==0... */ + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + if (sock->select_waiting > 0) { + sock->select_waiting--; } + SYS_ARCH_UNPROTECT(lev); + } else { + SYS_ARCH_UNPROTECT(lev); + /* Not a valid socket */ + nready = -1; + set_errno(EBADF); + } + } + } - lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); #if LWIP_NETCONN_SEM_PER_THREAD - if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) - { - /* don't leave the thread-local semaphore signalled */ - sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); - } -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); + if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { + /* don't leave the thread-local semaphore signalled */ + sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); + } +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); #endif /* LWIP_NETCONN_SEM_PER_THREAD */ - API_SELECT_CB_VAR_FREE(select_cb); + API_SELECT_CB_VAR_FREE(select_cb); - if (nready < 0) - { - /* This happens when a socket got closed while waiting */ - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - return -1; - } - - if (waitres == SYS_ARCH_TIMEOUT) - { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - } - else - { - /* See what's set now after waiting */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); - if (nready < 0) - { - set_errno(EBADF); - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - return -1; - } - } + if (nready < 0) { + /* This happens when a socket got closed while waiting */ + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + return -1; + } + + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + } else { + /* See what's set now after waiting */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); + if (nready < 0) { + set_errno(EBADF); + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + return -1; } - } - - lwip_select_dec_sockets_used(maxfdp1, &used_sockets); - set_errno(0); - if (readset) - { - *readset = lreadset; - } - if (writeset) - { - *writeset = lwriteset; - } - if (exceptset) - { - *exceptset = lexceptset; - } - return nready; + } + } + } + + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + set_errno(0); + if (readset) { + *readset = lreadset; + } + if (writeset) { + *writeset = lwriteset; + } + if (exceptset) { + *exceptset = lexceptset; + } + return nready; } #endif /* LWIP_SOCKET_SELECT */ @@ -2628,14 +2270,14 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse /** Options for the lwip_pollscan function. */ enum lwip_pollscan_opts { - /** Clear revents in each struct pollfd. */ - LWIP_POLLSCAN_CLEAR = 1, + /** Clear revents in each struct pollfd. */ + LWIP_POLLSCAN_CLEAR = 1, - /** Increment select_waiting in each struct lwip_sock. */ - LWIP_POLLSCAN_INC_WAIT = 2, + /** Increment select_waiting in each struct lwip_sock. */ + LWIP_POLLSCAN_INC_WAIT = 2, - /** Decrement select_waiting in each struct lwip_sock. */ - LWIP_POLLSCAN_DEC_WAIT = 4 + /** Decrement select_waiting in each struct lwip_sock. */ + LWIP_POLLSCAN_DEC_WAIT = 4 }; /** @@ -2647,103 +2289,89 @@ enum lwip_pollscan_opts * @param opts what to update and how * @return number of structures that have revents != 0 */ -static int lwip_pollscan(struct pollfd *fds, nfds_t nfds, enum lwip_pollscan_opts opts) +static int +lwip_pollscan(struct pollfd *fds, nfds_t nfds, enum lwip_pollscan_opts opts) { - int nready = 0; - nfds_t fdi; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - /* Go through each struct pollfd in the array. */ - for (fdi = 0; fdi < nfds; fdi++) - { - if ((opts & LWIP_POLLSCAN_CLEAR) != 0) - { - fds[fdi].revents = 0; + int nready = 0; + nfds_t fdi; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + /* Go through each struct pollfd in the array. */ + for (fdi = 0; fdi < nfds; fdi++) { + if ((opts & LWIP_POLLSCAN_CLEAR) != 0) { + fds[fdi].revents = 0; + } + + /* Negative fd means the caller wants us to ignore this struct. + POLLNVAL means we already detected that the fd is invalid; + if another thread has since opened a new socket with that fd, + we must not use that socket. */ + if (fds[fdi].fd >= 0 && (fds[fdi].revents & POLLNVAL) == 0) { + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(fds[fdi].fd); + if (sock != NULL) { + void* lastdata = sock->lastdata.pbuf; + s16_t rcvevent = sock->rcvevent; + u16_t sendevent = sock->sendevent; + u16_t errevent = sock->errevent; + + if ((opts & LWIP_POLLSCAN_INC_WAIT) != 0) { + sock->select_waiting++; + if (sock->select_waiting == 0) { + /* overflow - too many threads waiting */ + sock->select_waiting--; + nready = -1; + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + break; + } + } else if ((opts & LWIP_POLLSCAN_DEC_WAIT) != 0) { + /* for now, handle select_waiting==0... */ + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + if (sock->select_waiting > 0) { + sock->select_waiting--; + } } + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); - /* Negative fd means the caller wants us to ignore this struct. - POLLNVAL means we already detected that the fd is invalid; - if another thread has since opened a new socket with that fd, - we must not use that socket. */ - if (fds[fdi].fd >= 0 && (fds[fdi].revents & POLLNVAL) == 0) - { - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket_unconn_locked(fds[fdi].fd); - if (sock != NULL) - { - void *lastdata = sock->lastdata.pbuf; - s16_t rcvevent = sock->rcvevent; - u16_t sendevent = sock->sendevent; - u16_t errevent = sock->errevent; - - if ((opts & LWIP_POLLSCAN_INC_WAIT) != 0) - { - sock->select_waiting++; - if (sock->select_waiting == 0) - { - /* overflow - too many threads waiting */ - sock->select_waiting--; - nready = -1; - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - break; - } - } - else if ((opts & LWIP_POLLSCAN_DEC_WAIT) != 0) - { - /* for now, handle select_waiting==0... */ - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - if (sock->select_waiting > 0) - { - sock->select_waiting--; - } - } - SYS_ARCH_UNPROTECT(lev); - done_socket(sock); - - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if ((fds[fdi].events & POLLIN) != 0 && ((lastdata != NULL) || (rcvevent > 0))) - { - fds[fdi].revents |= POLLIN; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for reading\n", fds[fdi].fd)); - } - /* See if netconn of this socket is ready for write */ - if ((fds[fdi].events & POLLOUT) != 0 && (sendevent != 0)) - { - fds[fdi].revents |= POLLOUT; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for writing\n", fds[fdi].fd)); - } - /* See if netconn of this socket had an error */ - if (errevent != 0) - { - /* POLLERR is output only. */ - fds[fdi].revents |= POLLERR; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for exception\n", fds[fdi].fd)); - } - } - else - { - /* Not a valid socket */ - SYS_ARCH_UNPROTECT(lev); - /* POLLNVAL is output only. */ - fds[fdi].revents |= POLLNVAL; - return -1; - } + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if ((fds[fdi].events & POLLIN) != 0 && ((lastdata != NULL) || (rcvevent > 0))) { + fds[fdi].revents |= POLLIN; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for reading\n", fds[fdi].fd)); } - - /* Will return the number of structures that have events, - not the number of events. */ - if (fds[fdi].revents != 0) - { - nready++; + /* See if netconn of this socket is ready for write */ + if ((fds[fdi].events & POLLOUT) != 0 && (sendevent != 0)) { + fds[fdi].revents |= POLLOUT; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for writing\n", fds[fdi].fd)); } + /* See if netconn of this socket had an error */ + if (errevent != 0) { + /* POLLERR is output only. */ + fds[fdi].revents |= POLLERR; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for exception\n", fds[fdi].fd)); + } + } else { + /* Not a valid socket */ + SYS_ARCH_UNPROTECT(lev); + /* POLLNVAL is output only. */ + fds[fdi].revents |= POLLNVAL; + return -1; + } + } + + /* Will return the number of structures that have events, + not the number of events. */ + if (fds[fdi].revents != 0) { + nready++; } + } - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; } #if LWIP_NETCONN_FULLDUPLEX @@ -2752,204 +2380,188 @@ static int lwip_pollscan(struct pollfd *fds, nfds_t nfds, enum lwip_pollscan_opt * All sockets are marked (and later unmarked), whether they are open or not. * This is OK as lwip_pollscan aborts select when non-open sockets are found. */ -static void lwip_poll_inc_sockets_used(struct pollfd *fds, nfds_t nfds) +static void +lwip_poll_inc_sockets_used(struct pollfd *fds, nfds_t nfds) { - nfds_t fdi; + nfds_t fdi; - if (fds) - { - /* Go through each struct pollfd in the array. */ - for (fdi = 0; fdi < nfds; fdi++) - { - /* Increase the reference counter */ - tryget_socket_unconn(fds[fdi].fd); - } + if(fds) { + /* Go through each struct pollfd in the array. */ + for (fdi = 0; fdi < nfds; fdi++) { + /* Increase the reference counter */ + tryget_socket_unconn(fds[fdi].fd); } + } } /* Let go all sockets that were marked as used when starting poll */ -static void lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds) +static void +lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds) { - nfds_t fdi; + nfds_t fdi; - if (fds) - { - /* Go through each struct pollfd in the array. */ - for (fdi = 0; fdi < nfds; fdi++) - { - struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd); - if (sock != NULL) - { - done_socket(sock); - } - } + if(fds) { + /* Go through each struct pollfd in the array. */ + for (fdi = 0; fdi < nfds; fdi++) { + struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd); + if (sock != NULL) { + done_socket(sock); + } } + } } #else /* LWIP_NETCONN_FULLDUPLEX */ #define lwip_poll_inc_sockets_used(fds, nfds) #define lwip_poll_dec_sockets_used(fds, nfds) #endif /* LWIP_NETCONN_FULLDUPLEX */ -int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) +int +lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) { - u32_t waitres = 0; - int nready; - u32_t msectimeout; + u32_t waitres = 0; + int nready; + u32_t msectimeout; #if LWIP_NETCONN_SEM_PER_THREAD - int waited = 0; + int waited = 0; #endif - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll(%p, %d, %d)\n", (void *)fds, (int)nfds, timeout)); - LWIP_ERROR("lwip_poll: invalid fds", ((fds != NULL && nfds > 0) || (fds == NULL && nfds == 0)), set_errno(EINVAL); - return -1;); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll(%p, %d, %d)\n", + (void*)fds, (int)nfds, timeout)); + LWIP_ERROR("lwip_poll: invalid fds", ((fds != NULL && nfds > 0) || (fds == NULL && nfds == 0)), + set_errno(EINVAL); return -1;); - lwip_poll_inc_sockets_used(fds, nfds); + lwip_poll_inc_sockets_used(fds, nfds); - /* Go through each struct pollfd to count number of structures - which currently match */ - nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_CLEAR); + /* Go through each struct pollfd to count number of structures + which currently match */ + nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_CLEAR); - if (nready < 0) - { - lwip_poll_dec_sockets_used(fds, nfds); - return -1; - } + if (nready < 0) { + lwip_poll_dec_sockets_used(fds, nfds); + return -1; + } - /* If we don't have any current events, then suspend if we are supposed to */ - if (!nready) - { - API_SELECT_CB_VAR_DECLARE(select_cb); + /* If we don't have any current events, then suspend if we are supposed to */ + if (!nready) { + API_SELECT_CB_VAR_DECLARE(select_cb); - if (timeout == 0) - { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n")); - goto return_success; - } - API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1); - memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); + if (timeout == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n")); + goto return_success; + } + API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1); + memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables. */ + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables. */ - API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds; - API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds; + API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds; + API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds; #if LWIP_NETCONN_SEM_PER_THREAD - API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) - { - /* failed to create semaphore */ - set_errno(EAGAIN); - lwip_poll_dec_sockets_used(fds, nfds); - API_SELECT_CB_VAR_FREE(select_cb); - return -1; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); + if (!sys_sem_valid(API_SELECT_CB_VAR_REF(select_cb).sem)) { + set_errno(ENOMEM); + return -1; + } - lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { + /* failed to create semaphore */ + set_errno(EAGAIN); + lwip_poll_dec_sockets_used(fds, nfds); + API_SELECT_CB_VAR_FREE(select_cb); + return -1; + } +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - /* Increase select_waiting for each socket we are interested in. - Also, check for events again: there could have been events between - the last scan (without us on the list) and putting us on the list! */ - nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_INC_WAIT); - - if (!nready) - { - /* Still none ready, just wait to be woken */ - if (timeout < 0) - { - /* Wait forever */ - msectimeout = 0; - } - else - { - /* timeout == 0 would have been handled earlier. */ - LWIP_ASSERT("timeout > 0", timeout > 0); - msectimeout = timeout; - } - waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); + lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + + /* Increase select_waiting for each socket we are interested in. + Also, check for events again: there could have been events between + the last scan (without us on the list) and putting us on the list! */ + nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_INC_WAIT); + + if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout < 0) { + /* Wait forever */ + msectimeout = 0; + } else { + /* timeout == 0 would have been handled earlier. */ + LWIP_ASSERT("timeout > 0", timeout > 0); + msectimeout = timeout; + } + waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); #if LWIP_NETCONN_SEM_PER_THREAD - waited = 1; + waited = 1; #endif - } + } - /* Decrease select_waiting for each socket we are interested in, - and check which events occurred while we waited. */ - nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_DEC_WAIT); + /* Decrease select_waiting for each socket we are interested in, + and check which events occurred while we waited. */ + nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_DEC_WAIT); - lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); #if LWIP_NETCONN_SEM_PER_THREAD - if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) - { - /* don't leave the thread-local semaphore signalled */ - sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); - } -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); + if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { + /* don't leave the thread-local semaphore signalled */ + sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); + } +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); #endif /* LWIP_NETCONN_SEM_PER_THREAD */ - API_SELECT_CB_VAR_FREE(select_cb); + API_SELECT_CB_VAR_FREE(select_cb); - if (nready < 0) - { - /* This happens when a socket got closed while waiting */ - lwip_poll_dec_sockets_used(fds, nfds); - return -1; - } + if (nready < 0) { + /* This happens when a socket got closed while waiting */ + lwip_poll_dec_sockets_used(fds, nfds); + return -1; + } - if (waitres == SYS_ARCH_TIMEOUT) - { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n")); - goto return_success; - } + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n")); + goto return_success; } + } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready)); return_success: - lwip_poll_dec_sockets_used(fds, nfds); - set_errno(0); - return nready; + lwip_poll_dec_sockets_used(fds, nfds); + set_errno(0); + return nready; } /** * Check whether event_callback should wake up a thread waiting in * lwip_poll. */ -static int lwip_poll_should_wake( - const struct lwip_select_cb *scb, - int fd, - int has_recvevent, - int has_sendevent, - int has_errevent) +static int +lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recvevent, int has_sendevent, int has_errevent) { - nfds_t fdi; - for (fdi = 0; fdi < scb->poll_nfds; fdi++) - { - const struct pollfd *pollfd = &scb->poll_fds[fdi]; - if (pollfd->fd == fd) - { - /* Do not update pollfd->revents right here; - that would be a data race because lwip_pollscan - accesses revents without protecting. */ - if (has_recvevent && (pollfd->events & POLLIN) != 0) - { - return 1; - } - if (has_sendevent && (pollfd->events & POLLOUT) != 0) - { - return 1; - } - if (has_errevent) - { - /* POLLERR is output only. */ - return 1; - } - } - } - return 0; + nfds_t fdi; + for (fdi = 0; fdi < scb->poll_nfds; fdi++) { + const struct pollfd *pollfd = &scb->poll_fds[fdi]; + if (pollfd->fd == fd) { + /* Do not update pollfd->revents right here; + that would be a data race because lwip_pollscan + accesses revents without protecting. */ + if (has_recvevent && (pollfd->events & POLLIN) != 0) { + return 1; + } + if (has_sendevent && (pollfd->events & POLLOUT) != 0) { + return 1; + } + if (has_errevent) { + /* POLLERR is output only. */ + return 1; + } + } + } + return 0; } #endif /* LWIP_SOCKET_POLL */ @@ -2966,111 +2578,99 @@ static int lwip_poll_should_wake( * NETCONN_EVT_ERROR * This requirement will be asserted in select_check_waiters() */ -static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) { - int s, check_waiters; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(len); - - /* Get socket */ - if (conn) - { - s = conn->socket; - if (s < 0) - { - /* Data comes in right away after an accept, even though - * the server task might not have created a new socket yet. - * Just count down (or up) if that's the case and we - * will use the data later. Note that only receive events - * can happen before the new socket is set up. */ - SYS_ARCH_PROTECT(lev); - if (conn->socket < 0) - { - if (evt == NETCONN_EVT_RCVPLUS) - { - /* conn->socket is -1 on initialization - lwip_accept adjusts sock->recvevent if conn->socket < -1 */ - conn->socket--; - } - SYS_ARCH_UNPROTECT(lev); - return; - } - s = conn->socket; - SYS_ARCH_UNPROTECT(lev); - } - - sock = get_socket(s); - if (!sock) - { - return; + int s, check_waiters; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) { + s = conn->callback_arg.socket; + if (s < 0) { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + SYS_ARCH_PROTECT(lev); + if (conn->callback_arg.socket < 0) { + if (evt == NETCONN_EVT_RCVPLUS) { + /* conn->socket is -1 on initialization + lwip_accept adjusts sock->recvevent if conn->socket < -1 */ + conn->callback_arg.socket--; } - } - else - { + SYS_ARCH_UNPROTECT(lev); return; + } + s = conn->callback_arg.socket; + SYS_ARCH_UNPROTECT(lev); } - check_waiters = 1; - SYS_ARCH_PROTECT(lev); - /* Set event as required */ - switch (evt) - { - case NETCONN_EVT_RCVPLUS: - sock->rcvevent++; - if (sock->rcvevent > 1) - { - check_waiters = 0; - } - break; - case NETCONN_EVT_RCVMINUS: - sock->rcvevent--; - check_waiters = 0; - break; - case NETCONN_EVT_SENDPLUS: - if (sock->sendevent) - { - check_waiters = 0; - } - sock->sendevent = 1; - break; - case NETCONN_EVT_SENDMINUS: - sock->sendevent = 0; - check_waiters = 0; - break; - case NETCONN_EVT_ERROR: - sock->errevent = 1; - break; - default: - LWIP_ASSERT("unknown event", 0); - break; - } - - if (sock->select_waiting && check_waiters) - { - /* Save which events are active */ - int has_recvevent, has_sendevent, has_errevent; - has_recvevent = sock->rcvevent > 0; - has_sendevent = sock->sendevent != 0; - has_errevent = sock->errevent != 0; - SYS_ARCH_UNPROTECT(lev); - /* Check any select calls waiting on this socket */ - select_check_waiters(s, has_recvevent, has_sendevent, has_errevent); - } - else - { - SYS_ARCH_UNPROTECT(lev); - } + sock = get_socket(s); + if (!sock) { + return; + } + } else { + return; + } + + check_waiters = 1; + SYS_ARCH_PROTECT(lev); + /* Set event as required */ + switch (evt) { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + if (sock->rcvevent > 1) { + check_waiters = 0; + } + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + check_waiters = 0; + break; + case NETCONN_EVT_SENDPLUS: + if (sock->sendevent) { + check_waiters = 0; + } + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + check_waiters = 0; + break; + case NETCONN_EVT_ERROR: + sock->errevent = 1; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + + if (sock->select_waiting && check_waiters) { + /* Save which events are active */ + int has_recvevent, has_sendevent, has_errevent; + has_recvevent = sock->rcvevent > 0; + has_sendevent = sock->sendevent != 0; + has_errevent = sock->errevent != 0; + SYS_ARCH_UNPROTECT(lev); + /* Check any select calls waiting on this socket */ + select_check_waiters(s, has_recvevent, has_sendevent, has_errevent); + } else { + SYS_ARCH_UNPROTECT(lev); + } - // [NF_CHANGE] - Signal the CLR that a socket event has occured - // TODO: We may want to investigate other ways to signal - // the CLR (maybe based on which socket received the - // event). - sys_signal_sock_event(); - //[END_NF_CHANGE] + // [NF_CHANGE] - Signal the CLR that a socket event has occured + // TODO: We may want to investigate other ways to signal + // the CLR (maybe based on which socket received the + // event). + sys_signal_sock_event(); + //[END_NF_CHANGE] - done_socket(sock); + done_socket(sock); } /** @@ -3088,110 +2688,96 @@ static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len */ static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent) { - struct lwip_select_cb *scb; + struct lwip_select_cb *scb; #if ESP_LWIP - struct lwip_sock *sock; + struct lwip_sock *sock; #endif /* ESP_LWIP */ #if !LWIP_TCPIP_CORE_LOCKING - int last_select_cb_ctr; - SYS_ARCH_DECL_PROTECT(lev); + int last_select_cb_ctr; + SYS_ARCH_DECL_PROTECT(lev); #endif /* !LWIP_TCPIP_CORE_LOCKING */ - LWIP_ASSERT_CORE_LOCKED(); + LWIP_ASSERT_CORE_LOCKED(); #if ESP_LWIP - sock = tryget_socket_unconn(s); + sock = tryget_socket_unconn(s); #endif /* ESP_LWIP */ #if !LWIP_TCPIP_CORE_LOCKING - SYS_ARCH_PROTECT(lev); + SYS_ARCH_PROTECT(lev); again: - /* remember the state of select_cb_list to detect changes */ - last_select_cb_ctr = select_cb_ctr; + /* remember the state of select_cb_list to detect changes */ + last_select_cb_ctr = select_cb_ctr; #endif /* !LWIP_TCPIP_CORE_LOCKING */ - for (scb = select_cb_list; scb != NULL; scb = scb->next) - { - if (scb->sem_signalled == 0) - { - /* semaphore not signalled yet */ - int do_signal = 0; + for (scb = select_cb_list; scb != NULL; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* semaphore not signalled yet */ + int do_signal = 0; #if LWIP_SOCKET_POLL - if (scb->poll_fds != NULL) - { - do_signal = lwip_poll_should_wake(scb, s, has_recvevent, has_sendevent, has_errevent); - } + if (scb->poll_fds != NULL) { + do_signal = lwip_poll_should_wake(scb, s, has_recvevent, has_sendevent, has_errevent); + } #endif /* LWIP_SOCKET_POLL */ #if LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL - else + else #endif /* LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL */ #if LWIP_SOCKET_SELECT - { - /* Test this select call for our socket */ + { + /* Test this select call for our socket */ #if ESP_LWIP - if (sock->rcvevent) - { + if (sock->rcvevent) { #else - if (has_recvevent) - { + if (has_recvevent) { #endif /* ESP_LWIP */ - if (scb->readset && FD_ISSET(s, scb->readset)) - { - do_signal = 1; - } - } + if (scb->readset && FD_ISSET(s, scb->readset)) { + do_signal = 1; + } + } #if ESP_LWIP - if (sock->sendevent) - { + if (sock->sendevent) { #else - if (has_sendevent) - { + if (has_sendevent) { #endif /* ESP_LWIP */ - if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) - { - do_signal = 1; - } - } + if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { + do_signal = 1; + } + } #if ESP_LWIP - if (sock->errevent) - { + if (sock->errevent) { #else - if (has_errevent) - { + if (has_errevent) { #endif /* ESP_LWIP */ - if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) - { - do_signal = 1; - } - } - } -#endif /* LWIP_SOCKET_SELECT */ - if (do_signal) - { - scb->sem_signalled = 1; - /* For !LWIP_TCPIP_CORE_LOCKING, we don't call SYS_ARCH_UNPROTECT() before signaling - the semaphore, as this might lead to the select thread taking itself off the list, - invalidating the semaphore. */ - sys_sem_signal(SELECT_SEM_PTR(scb->sem)); - } + if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { + do_signal = 1; + } } -#if LWIP_TCPIP_CORE_LOCKING + } +#endif /* LWIP_SOCKET_SELECT */ + if (do_signal) { + scb->sem_signalled = 1; + /* For !LWIP_TCPIP_CORE_LOCKING, we don't call SYS_ARCH_UNPROTECT() before signaling + the semaphore, as this might lead to the select thread taking itself off the list, + invalidating the semaphore. */ + sys_sem_signal(SELECT_SEM_PTR(scb->sem)); + } } +#if LWIP_TCPIP_CORE_LOCKING + } #else - /* unlock interrupts with each step */ - SYS_ARCH_UNPROTECT(lev); - /* this makes sure interrupt protection time is short */ - SYS_ARCH_PROTECT(lev); - if (last_select_cb_ctr != select_cb_ctr) - { - /* someone has changed select_cb_list, restart at the beginning */ - goto again; - } - /* remember the state of select_cb_list to detect changes */ - last_select_cb_ctr = select_cb_ctr; - } + /* unlock interrupts with each step */ SYS_ARCH_UNPROTECT(lev); + /* this makes sure interrupt protection time is short */ + SYS_ARCH_PROTECT(lev); + if (last_select_cb_ctr != select_cb_ctr) { + /* someone has changed select_cb_list, restart at the beginning */ + goto again; + } + /* remember the state of select_cb_list to detect changes */ + last_select_cb_ctr = select_cb_ctr; + } + SYS_ARCH_UNPROTECT(lev); #endif /* LWIP_TCPIP_CORE_LOCKING */ #if ESP_LWIP - done_socket(sock); + done_socket(sock); #endif /* ESP_LWIP */ } #endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ @@ -3199,1377 +2785,1180 @@ static void select_check_waiters(int s, int has_recvevent, int has_sendevent, in /** * Close one end of a full-duplex connection. */ -int lwip_shutdown(int s, int how) +int +lwip_shutdown(int s, int how) { - struct lwip_sock *sock; - err_t err; - u8_t shut_rx = 0, shut_tx = 0; + struct lwip_sock *sock; + err_t err; + u8_t shut_rx = 0, shut_tx = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); - - sock = get_socket(s); - if (!sock) - { - return -1; - } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); - if (sock->conn != NULL) - { - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - { - sock_set_errno(sock, EOPNOTSUPP); - done_socket(sock); - return -1; - } - } - else - { - sock_set_errno(sock, ENOTCONN); - done_socket(sock); - return -1; - } + sock = get_socket(s); + if (!sock) { + return -1; + } - if (how == SHUT_RD) - { - shut_rx = 1; - } - else if (how == SHUT_WR) - { - shut_tx = 1; - } - else if (how == SHUT_RDWR) - { - shut_rx = 1; - shut_tx = 1; - } - else - { - sock_set_errno(sock, EINVAL); - done_socket(sock); - return -1; + if (sock->conn != NULL) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + set_errno(EOPNOTSUPP); + done_socket(sock); + return -1; } - err = netconn_shutdown(sock->conn, shut_rx, shut_tx); - - sock_set_errno(sock, err_to_errno(err)); + } else { + set_errno(ENOTCONN); + done_socket(sock); + return -1; + } + + if (how == SHUT_RD) { + shut_rx = 1; + } else if (how == SHUT_WR) { + shut_tx = 1; + } else if (how == SHUT_RDWR) { + shut_rx = 1; + shut_tx = 1; + } else { + set_errno(EINVAL); done_socket(sock); - return (err == ERR_OK ? 0 : -1); + return -1; + } + err = netconn_shutdown(sock->conn, shut_rx, shut_tx); + + set_errno(err_to_errno(err)); + done_socket(sock); + return (err == ERR_OK ? 0 : -1); } -static int lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +static int +lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) { - struct lwip_sock *sock; - union sockaddr_aligned saddr; - ip_addr_t naddr; - u16_t port; - err_t err; - - sock = get_socket(s); - if (!sock) - { - return -1; - } + struct lwip_sock *sock; + union sockaddr_aligned saddr; + ip_addr_t naddr; + u16_t port; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } - /* get the IP address and port */ - err = netconn_getaddr(sock->conn, &naddr, &port, local); - if (err != ERR_OK) - { - sock_set_errno(sock, err_to_errno(err)); - done_socket(sock); - return -1; - } + /* get the IP address and port */ + err = netconn_getaddr(sock->conn, &naddr, &port, local); + if (err != ERR_OK) { + set_errno(err_to_errno(err)); + done_socket(sock); + return -1; + } #if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ - if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && IP_IS_V4_VAL(naddr)) - { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr)); - IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6); - } + /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ + if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && + IP_IS_V4_VAL(naddr)) { + ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr)); + IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6); + } #endif /* LWIP_IPV4 && LWIP_IPV6 */ - IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port); + IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%" U16_F ")\n", port)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); - if (*namelen > saddr.sa.sa_len) - { - *namelen = saddr.sa.sa_len; - } - MEMCPY(name, &saddr, *namelen); + if (*namelen > IPADDR_SOCKADDR_GET_LEN(&saddr)) { + *namelen = IPADDR_SOCKADDR_GET_LEN(&saddr); + } + MEMCPY(name, &saddr, *namelen); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; + set_errno(0); + done_socket(sock); + return 0; } -int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) +int +lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) { - return lwip_getaddrname(s, name, namelen, 0); + return lwip_getaddrname(s, name, namelen, 0); } -int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) +int +lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) { - return lwip_getaddrname(s, name, namelen, 1); + return lwip_getaddrname(s, name, namelen, 1); } -int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +int +lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { - int err; - struct lwip_sock *sock = get_socket(s); + int err; + struct lwip_sock *sock = get_socket(s); #if !LWIP_TCPIP_CORE_LOCKING - err_t cberr; - LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); + err_t cberr; + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); #endif /* !LWIP_TCPIP_CORE_LOCKING */ - if (!sock) - { - return -1; - } + if (!sock) { + return -1; + } - if ((NULL == optval) || (NULL == optlen)) - { - sock_set_errno(sock, EFAULT); - done_socket(sock); - return -1; - } + if ((NULL == optval) || (NULL == optlen)) { + set_errno(EFAULT); + done_socket(sock); + return -1; + } #if LWIP_TCPIP_CORE_LOCKING - /* core-locking can just call the -impl function */ - LOCK_TCPIP_CORE(); - err = lwip_getsockopt_impl(s, level, optname, optval, optlen); - UNLOCK_TCPIP_CORE(); + /* core-locking can just call the -impl function */ + LOCK_TCPIP_CORE(); + err = lwip_getsockopt_impl(s, level, optname, optval, optlen); + UNLOCK_TCPIP_CORE(); #else /* LWIP_TCPIP_CORE_LOCKING */ #if LWIP_MPU_COMPATIBLE - /* MPU_COMPATIBLE copies the optval data, so check for max size here */ - if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) - { - sock_set_errno(sock, ENOBUFS); - done_socket(sock); - return -1; - } + /* MPU_COMPATIBLE copies the optval data, so check for max size here */ + if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { + set_errno(ENOBUFS); + done_socket(sock); + return -1; + } #endif /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen; + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen; #if !LWIP_MPU_COMPATIBLE - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval; #endif /* !LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; #if LWIP_NETCONN_SEM_PER_THREAD - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); #else - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; #endif - cberr = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); - if (cberr != ERR_OK) - { - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); - sock_set_errno(sock, err_to_errno(cberr)); - done_socket(sock); - return -1; - } - sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); + cberr = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); + if (cberr != ERR_OK) { + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); + set_errno(err_to_errno(cberr)); + done_socket(sock); + return -1; + } + sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); - /* write back optlen and optval */ - *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen; + /* write back optlen and optval */ + *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen; #if LWIP_MPU_COMPATIBLE - MEMCPY(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen); + MEMCPY(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen); #endif /* LWIP_MPU_COMPATIBLE */ - /* maybe lwip_getsockopt_internal has changed err */ - err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); + /* maybe lwip_getsockopt_impl has changed err */ + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); #endif /* LWIP_TCPIP_CORE_LOCKING */ - sock_set_errno(sock, err); - done_socket(sock); - return err ? -1 : 0; + set_errno(err); + done_socket(sock); + return err ? -1 : 0; } #if !LWIP_TCPIP_CORE_LOCKING /** lwip_getsockopt_callback: only used without CORE_LOCKING * to get into the tcpip_thread */ -static void lwip_getsockopt_callback(void *arg) +static void +lwip_getsockopt_callback(void *arg) { - struct lwip_setgetsockopt_data *data; - LWIP_ASSERT("arg != NULL", arg != NULL); - data = (struct lwip_setgetsockopt_data *)arg; - - data->err = lwip_getsockopt_impl( - data->s, - data->level, - data->optname, + struct lwip_setgetsockopt_data *data; + LWIP_ASSERT("arg != NULL", arg != NULL); + data = (struct lwip_setgetsockopt_data *)arg; + + data->err = lwip_getsockopt_impl(data->s, data->level, data->optname, #if LWIP_MPU_COMPATIBLE - data->optval, -#else /* LWIP_MPU_COMPATIBLE */ - data->optval.p, + data->optval, +#else /* LWIP_MPU_COMPATIBLE */ + data->optval.p, #endif /* LWIP_MPU_COMPATIBLE */ - &data->optlen); + &data->optlen); - sys_sem_signal((sys_sem_t *)(data->completed_sem)); + sys_sem_signal((sys_sem_t *)(data->completed_sem)); } -#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_TCPIP_CORE_LOCKING */ -static int lwip_sockopt_to_ipopt(int optname) +static int +lwip_sockopt_to_ipopt(int optname) { - /* Map SO_* values to our internal SOF_* values - * We should not rely on #defines in socket.h - * being in sync with ip.h. - */ - switch (optname) - { - case SO_BROADCAST: - return SOF_BROADCAST; - case SO_KEEPALIVE: - return SOF_KEEPALIVE; - case SO_REUSEADDR: - return SOF_REUSEADDR; - default: - LWIP_ASSERT("Unknown socket option", 0); - return 0; - } + /* Map SO_* values to our internal SOF_* values + * We should not rely on #defines in socket.h + * being in sync with ip.h. + */ + switch (optname) { + case SO_BROADCAST: + return SOF_BROADCAST; + case SO_KEEPALIVE: + return SOF_KEEPALIVE; + case SO_REUSEADDR: + return SOF_REUSEADDR; + default: + LWIP_ASSERT("Unknown socket option", 0); + return 0; + } } /** lwip_getsockopt_impl: the actual implementation of getsockopt: * same argument as lwip_getsockopt, either called directly or through callback */ -static int lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen) +static int +lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen) { - int err = 0; - struct lwip_sock *sock = tryget_socket(s); - if (!sock) - { - return EBADF; - } + int err = 0; + struct lwip_sock *sock = tryget_socket(s); + if (!sock) { + return EBADF; + } #ifdef LWIP_HOOK_SOCKETS_GETSOCKOPT - if (LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) - { - return err; - } + if (LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) { + return err; + } #endif - switch (level) - { + switch (level) { - /* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) - { + /* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { #if LWIP_TCP - case SO_ACCEPTCONN: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) - { - done_socket(sock); - return ENOPROTOOPT; - } - if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) - { - *(int *)optval = 1; - } - else - { - *(int *)optval = 0; - } - break; + case SO_ACCEPTCONN: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) { + done_socket(sock); + return ENOPROTOOPT; + } + if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) { + *(int *)optval = 1; + } else { + *(int *)optval = 0; + } + break; #endif /* LWIP_TCP */ - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: #if SO_REUSE - case SO_REUSEADDR: + case SO_REUSEADDR: #endif /* SO_REUSE */ - if ((optname == SO_BROADCAST) && (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) - { - done_socket(sock); - return ENOPROTOOPT; - } - - optname = lwip_sockopt_to_ipopt(optname); - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int *)optval = ip_get_option(sock->conn->pcb.ip, optname); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", - s, - optname, - (*(int *)optval ? "on" : "off"))); - break; - - case SO_TYPE: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) - { - case NETCONN_RAW: - *(int *)optval = SOCK_RAW; - break; - case NETCONN_TCP: - *(int *)optval = SOCK_STREAM; - break; - case NETCONN_UDP: - *(int *)optval = SOCK_DGRAM; - break; - default: /* unrecognized socket type */ - *(int *)optval = netconn_type(sock->conn); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", - s, - *(int *)optval)); - } /* switch (netconn_type(sock->conn)) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", s, *(int *)optval)); - break; - - case SO_ERROR: - LWIP_SOCKOPT_CHECK_OPTLEN(sock, *optlen, int); - *(int *)optval = err_to_errno(netconn_err(sock->conn)); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", s, *(int *)optval)); - break; + if ((optname == SO_BROADCAST) && + (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { + done_socket(sock); + return ENOPROTOOPT; + } + + optname = lwip_sockopt_to_ipopt(optname); + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int *)optval = ip_get_option(sock->conn->pcb.ip, optname); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", + s, optname, (*(int *)optval ? "on" : "off"))); + break; + + case SO_TYPE: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { + case NETCONN_RAW: + *(int *)optval = SOCK_RAW; + break; + case NETCONN_TCP: + *(int *)optval = SOCK_STREAM; + break; + case NETCONN_UDP: + *(int *)optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int *)optval = netconn_type(sock->conn); + LWIP_DEBUGF(SOCKETS_DEBUG, + ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", + s, *(int *)optval)); + } /* switch (netconn_type(sock->conn)) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", + s, *(int *)optval)); + break; + + case SO_ERROR: + LWIP_SOCKOPT_CHECK_OPTLEN(sock, *optlen, int); + *(int *)optval = err_to_errno(netconn_err(sock->conn)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", + s, *(int *)optval)); + break; #if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn)); - break; + case SO_SNDTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn)); + break; #endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn)); - break; + case SO_RCVTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn)); + break; #endif /* LWIP_SO_RCVTIMEO */ #if LWIP_SO_RCVBUF - case SO_RCVBUF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - *(int *)optval = netconn_get_recvbufsize(sock->conn); - break; + case SO_RCVBUF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + *(int *)optval = netconn_get_recvbufsize(sock->conn); + break; #endif /* LWIP_SO_RCVBUF */ #if LWIP_SO_LINGER - case SO_LINGER: - { - s16_t conn_linger; - struct linger *linger = (struct linger *)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, struct linger); - conn_linger = sock->conn->linger; - if (conn_linger >= 0) - { - linger->l_onoff = 1; - linger->l_linger = (int)conn_linger; - } - else - { - linger->l_onoff = 0; - linger->l_linger = 0; - } - } - break; + case SO_LINGER: { + s16_t conn_linger; + struct linger *linger = (struct linger *)optval; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, struct linger); + conn_linger = sock->conn->linger; + if (conn_linger >= 0) { + linger->l_onoff = 1; + linger->l_linger = (int)conn_linger; + } else { + linger->l_onoff = 0; + linger->l_linger = 0; + } + } + break; #endif /* LWIP_SO_LINGER */ #if LWIP_UDP - case SO_NO_CHECK: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP); + case SO_NO_CHECK: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP); #if LWIP_UDPLITE - if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) - { - /* this flag is only available for UDP, not for UDP lite */ - done_socket(sock); - return EAFNOSUPPORT; - } + if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) { + /* this flag is only available for UDP, not for UDP lite */ + done_socket(sock); + return EAFNOSUPPORT; + } #endif /* LWIP_UDPLITE */ - *(int *)optval = udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM) ? 1 : 0; - break; + *(int *)optval = udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM) ? 1 : 0; + break; #endif /* LWIP_UDP*/ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - - /* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) - { - case IP_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int *)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", s, *(int *)optval)); - break; - case IP_TOS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int *)optval = sock->conn->pcb.ip->tos; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", s, *(int *)optval)); - break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + + /* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int *)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_TOS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int *)optval = sock->conn->pcb.ip->tos; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", + s, *(int *)optval)); + break; #if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP - case IP_MULTICAST_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) - { - done_socket(sock); - return ENOPROTOOPT; - } - *(u8_t *)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", s, *(int *)optval)); - break; - case IP_MULTICAST_IF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) - { - done_socket(sock); - return ENOPROTOOPT; - } - inet_addr_from_ip4addr((struct in_addr *)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp)); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%" X32_F "\n", s, *(u32_t *)optval)); - break; - case IP_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) - { - *(u8_t *)optval = 1; - } - else - { - *(u8_t *)optval = 0; - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", s, *(int *)optval)); - break; + case IP_MULTICAST_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + done_socket(sock); + return ENOPROTOOPT; + } + *(u8_t *)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_MULTICAST_IF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + done_socket(sock); + return ENOPROTOOPT; + } + inet_addr_from_ip4addr((struct in_addr *)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", + s, *(u32_t *)optval)); + break; + case IP_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { + *(u8_t *)optval = 1; + } else { + *(u8_t *)optval = 0; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", + s, *(int *)optval)); + break; #endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #if LWIP_TCP - /* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* Special case: all IPPROTO_TCP option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP); - if (sock->conn->pcb.tcp->state == LISTEN) - { - done_socket(sock); - return EINVAL; - } - switch (optname) - { - case TCP_NODELAY: - *(int *)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", s, (*(int *)optval) ? "on" : "off")); - break; - case TCP_KEEPALIVE: - *(int *)optval = (int)sock->conn->pcb.tcp->keep_idle; - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n", s, *(int *)optval)); - break; + /* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* Special case: all IPPROTO_TCP option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP); + if (sock->conn->pcb.tcp->state == LISTEN) { + done_socket(sock); + return EINVAL; + } + switch (optname) { + case TCP_NODELAY: + *(int *)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", + s, (*(int *)optval) ? "on" : "off") ); + break; + case TCP_KEEPALIVE: + *(int *)optval = (int)sock->conn->pcb.tcp->keep_idle; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n", + s, *(int *)optval)); + break; #if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - *(int *)optval = (int)(sock->conn->pcb.tcp->keep_idle / 1000); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n", s, *(int *)optval)); - break; - case TCP_KEEPINTVL: - *(int *)optval = (int)(sock->conn->pcb.tcp->keep_intvl / 1000); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n", s, *(int *)optval)); - break; - case TCP_KEEPCNT: - *(int *)optval = (int)sock->conn->pcb.tcp->keep_cnt; - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n", s, *(int *)optval)); - break; + case TCP_KEEPIDLE: + *(int *)optval = (int)(sock->conn->pcb.tcp->keep_idle / 1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPINTVL: + *(int *)optval = (int)(sock->conn->pcb.tcp->keep_intvl / 1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPCNT: + *(int *)optval = (int)sock->conn->pcb.tcp->keep_cnt; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n", + s, *(int *)optval)); + break; #endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #endif /* LWIP_TCP */ #if LWIP_IPV6 - /* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) - { - case IPV6_V6ONLY: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - *(int *)optval = (netconn_get_ipv6only(sock->conn) ? 1 : 0); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", s, *(int *)optval)); - break; - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + /* Level: IPPROTO_IPV6 */ + case IPPROTO_IPV6: + switch (optname) { + case IPV6_V6ONLY: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + *(int *)optval = (netconn_get_ipv6only(sock->conn) ? 1 : 0); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", + s, *(int *)optval)); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #endif /* LWIP_IPV6 */ #if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - /* Special case: all IPPROTO_UDPLITE option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) - { - done_socket(sock); - return ENOPROTOOPT; - } - switch (optname) - { - case UDPLITE_SEND_CSCOV: - *(int *)optval = sock->conn->pcb.udp->chksum_len_tx; - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", s, (*(int *)optval))); - break; - case UDPLITE_RECV_CSCOV: - *(int *)optval = sock->conn->pcb.udp->chksum_len_rx; - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", s, (*(int *)optval))); - break; - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + /* Special case: all IPPROTO_UDPLITE option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + /* If this is no UDP lite socket, ignore any options. */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { + done_socket(sock); + return ENOPROTOOPT; + } + switch (optname) { + case UDPLITE_SEND_CSCOV: + *(int *)optval = sock->conn->pcb.udp->chksum_len_tx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", + s, (*(int *)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + *(int *)optval = sock->conn->pcb.udp->chksum_len_rx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", + s, (*(int *)optval)) ); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #endif /* LWIP_UDP */ - /* Level: IPPROTO_RAW */ - case IPPROTO_RAW: - switch (optname) - { + /* Level: IPPROTO_RAW */ + case IPPROTO_RAW: + switch (optname) { #if LWIP_IPV6 && LWIP_RAW - case IPV6_CHECKSUM: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW); - if (sock->conn->pcb.raw->chksum_reqd == 0) - { - *(int *)optval = -1; - } - else - { - *(int *)optval = sock->conn->pcb.raw->chksum_offset; - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n", s, (*(int *)optval))); - break; + case IPV6_CHECKSUM: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW); + if (sock->conn->pcb.raw->chksum_reqd == 0) { + *(int *)optval = -1; + } else { + *(int *)optval = sock->conn->pcb.raw->chksum_offset; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n", + s, (*(int *)optval)) ); + break; #endif /* LWIP_IPV6 && LWIP_RAW */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); - err = ENOPROTOOPT; - break; - } /* switch (level) */ - - done_socket(sock); - return err; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + break; + } /* switch (level) */ + + done_socket(sock); + return err; } -int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +int +lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) { - int err = 0; - struct lwip_sock *sock = get_socket(s); + int err = 0; + struct lwip_sock *sock = get_socket(s); #if !LWIP_TCPIP_CORE_LOCKING - err_t cberr; - LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); + err_t cberr; + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); #endif /* !LWIP_TCPIP_CORE_LOCKING */ - if (!sock) - { - return -1; - } + if (!sock) { + return -1; + } - if (NULL == optval) - { - sock_set_errno(sock, EFAULT); - done_socket(sock); - return -1; - } + if (NULL == optval) { + set_errno(EFAULT); + done_socket(sock); + return -1; + } #if LWIP_TCPIP_CORE_LOCKING - /* core-locking can just call the -impl function */ - LOCK_TCPIP_CORE(); - err = lwip_setsockopt_impl(s, level, optname, optval, optlen); - UNLOCK_TCPIP_CORE(); + /* core-locking can just call the -impl function */ + LOCK_TCPIP_CORE(); + err = lwip_setsockopt_impl(s, level, optname, optval, optlen); + UNLOCK_TCPIP_CORE(); #else /* LWIP_TCPIP_CORE_LOCKING */ #if LWIP_MPU_COMPATIBLE - /* MPU_COMPATIBLE copies the optval data, so check for max size here */ - if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) - { - sock_set_errno(sock, ENOBUFS); - done_socket(sock); - return -1; - } + /* MPU_COMPATIBLE copies the optval data, so check for max size here */ + if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { + set_errno(ENOBUFS); + done_socket(sock); + return -1; + } #endif /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; #if LWIP_MPU_COMPATIBLE - MEMCPY(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen); -#else /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (const void *)optval; + MEMCPY(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen); +#else /* LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (const void *)optval; #endif /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; #if LWIP_NETCONN_SEM_PER_THREAD - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); #else - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; #endif - cberr = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); - if (cberr != ERR_OK) - { - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); - sock_set_errno(sock, err_to_errno(cberr)); - done_socket(sock); - return -1; - } - sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); - - /* maybe lwip_getsockopt_internal has changed err */ - err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + cberr = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); + if (cberr != ERR_OK) { LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sock_set_errno(sock, err); + set_errno(err_to_errno(cberr)); done_socket(sock); - return err ? -1 : 0; + return -1; + } + sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); + + /* maybe lwip_setsockopt_impl has changed err */ + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + set_errno(err); + done_socket(sock); + return err ? -1 : 0; } #if !LWIP_TCPIP_CORE_LOCKING /** lwip_setsockopt_callback: only used without CORE_LOCKING * to get into the tcpip_thread */ -static void lwip_setsockopt_callback(void *arg) +static void +lwip_setsockopt_callback(void *arg) { - struct lwip_setgetsockopt_data *data; - LWIP_ASSERT("arg != NULL", arg != NULL); - data = (struct lwip_setgetsockopt_data *)arg; - - data->err = lwip_setsockopt_impl( - data->s, - data->level, - data->optname, + struct lwip_setgetsockopt_data *data; + LWIP_ASSERT("arg != NULL", arg != NULL); + data = (struct lwip_setgetsockopt_data *)arg; + + data->err = lwip_setsockopt_impl(data->s, data->level, data->optname, #if LWIP_MPU_COMPATIBLE - data->optval, -#else /* LWIP_MPU_COMPATIBLE */ - data->optval.pc, + data->optval, +#else /* LWIP_MPU_COMPATIBLE */ + data->optval.pc, #endif /* LWIP_MPU_COMPATIBLE */ - data->optlen); + data->optlen); - sys_sem_signal((sys_sem_t *)(data->completed_sem)); + sys_sem_signal((sys_sem_t *)(data->completed_sem)); } -#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_TCPIP_CORE_LOCKING */ /** lwip_setsockopt_impl: the actual implementation of setsockopt: * same argument as lwip_setsockopt, either called directly or through callback */ -static int lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen) +static int +lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen) { - int err = 0; - struct lwip_sock *sock = tryget_socket(s); - if (!sock) - { - return EBADF; - } + int err = 0; + struct lwip_sock *sock = tryget_socket(s); + if (!sock) { + return EBADF; + } #ifdef LWIP_HOOK_SOCKETS_SETSOCKOPT - if (LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) - { - return err; - } + if (LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) { + return err; + } #endif - switch (level) - { + switch (level) { - /* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) - { + /* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { - /* SO_ACCEPTCONN is get-only */ + /* SO_ACCEPTCONN is get-only */ - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: #if SO_REUSE - case SO_REUSEADDR: + case SO_REUSEADDR: #endif /* SO_REUSE */ - if ((optname == SO_BROADCAST) && (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) - { - done_socket(sock); - return ENOPROTOOPT; - } - - optname = lwip_sockopt_to_ipopt(optname); - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - if (*(const int *)optval) - { - ip_set_option(sock->conn->pcb.ip, optname); - } - else - { - ip_reset_option(sock->conn->pcb.ip, optname); - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", - s, - optname, - (*(const int *)optval ? "on" : "off"))); - break; - - /* SO_TYPE is get-only */ - /* SO_ERROR is get-only */ + if ((optname == SO_BROADCAST) && + (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { + done_socket(sock); + return ENOPROTOOPT; + } + + optname = lwip_sockopt_to_ipopt(optname); + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + if (*(const int *)optval) { + ip_set_option(sock->conn->pcb.ip, optname); + } else { + ip_reset_option(sock->conn->pcb.ip, optname); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", + s, optname, (*(const int *)optval ? "on" : "off"))); + break; + + /* SO_TYPE is get-only */ + /* SO_ERROR is get-only */ #if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - { - long ms_long; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); - if (ms_long < 0) - { - done_socket(sock); - return EINVAL; - } - netconn_set_sendtimeout(sock->conn, ms_long); - break; - } + case SO_SNDTIMEO: { + long ms_long; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); + if (ms_long < 0) { + done_socket(sock); + return EINVAL; + } + netconn_set_sendtimeout(sock->conn, ms_long); + break; + } #endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - { - long ms_long; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); - if (ms_long < 0) - { - done_socket(sock); - return EINVAL; - } - netconn_set_recvtimeout(sock->conn, (u32_t)ms_long); - break; - } + case SO_RCVTIMEO: { + long ms_long; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); + if (ms_long < 0) { + done_socket(sock); + return EINVAL; + } + netconn_set_recvtimeout(sock->conn, (u32_t)ms_long); + break; + } #endif /* LWIP_SO_RCVTIMEO */ #if LWIP_SO_RCVBUF - case SO_RCVBUF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int); - netconn_set_recvbufsize(sock->conn, *(const int *)optval); - break; + case SO_RCVBUF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int); + netconn_set_recvbufsize(sock->conn, *(const int *)optval); + break; #endif /* LWIP_SO_RCVBUF */ #if LWIP_SO_LINGER - case SO_LINGER: - { - const struct linger *linger = (const struct linger *)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct linger); - if (linger->l_onoff) - { - int lingersec = linger->l_linger; - if (lingersec < 0) - { - done_socket(sock); - return EINVAL; - } - if (lingersec > 0xFFFF) - { - lingersec = 0xFFFF; - } - sock->conn->linger = (s16_t)lingersec; - } - else - { - sock->conn->linger = -1; - } - } - break; + case SO_LINGER: { + const struct linger *linger = (const struct linger *)optval; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct linger); + if (linger->l_onoff) { + int lingersec = linger->l_linger; + if (lingersec < 0) { + done_socket(sock); + return EINVAL; + } + if (lingersec > 0xFFFF) { + lingersec = 0xFFFF; + } + sock->conn->linger = (s16_t)lingersec; + } else { + sock->conn->linger = -1; + } + } + break; #endif /* LWIP_SO_LINGER */ #if LWIP_UDP - case SO_NO_CHECK: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); + case SO_NO_CHECK: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); #if LWIP_UDPLITE - if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) - { - /* this flag is only available for UDP, not for UDP lite */ - done_socket(sock); - return EAFNOSUPPORT; - } + if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) { + /* this flag is only available for UDP, not for UDP lite */ + done_socket(sock); + return EAFNOSUPPORT; + } #endif /* LWIP_UDPLITE */ - if (*(const int *)optval) - { - udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - else - { - udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - break; + if (*(const int *)optval) { + udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } else { + udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + break; #endif /* LWIP_UDP */ - case SO_BINDTODEVICE: - { - const struct ifreq *iface; - struct netif *n = NULL; - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct ifreq); - - iface = (const struct ifreq *)optval; - if (iface->ifr_name[0] != 0) - { - n = netif_find(iface->ifr_name); - if (n == NULL) - { - done_socket(sock); - return ENODEV; - } - } - - switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) - { + case SO_BINDTODEVICE: { + const struct ifreq *iface; + struct netif *n = NULL; + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct ifreq); + + iface = (const struct ifreq *)optval; + if (iface->ifr_name[0] != 0) { + n = netif_find(iface->ifr_name); + if (n == NULL) { + done_socket(sock); + return ENODEV; + } + } + + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { #if LWIP_TCP - case NETCONN_TCP: - tcp_bind_netif(sock->conn->pcb.tcp, n); - break; + case NETCONN_TCP: + tcp_bind_netif(sock->conn->pcb.tcp, n); + break; #endif #if LWIP_UDP - case NETCONN_UDP: - udp_bind_netif(sock->conn->pcb.udp, n); - break; + case NETCONN_UDP: + udp_bind_netif(sock->conn->pcb.udp, n); + break; #endif #if LWIP_RAW - case NETCONN_RAW: - raw_bind_netif(sock->conn->pcb.raw, n); - break; + case NETCONN_RAW: + raw_bind_netif(sock->conn->pcb.raw, n); + break; #endif - default: - LWIP_ASSERT("Unhandled netconn type in SO_BINDTODEVICE", 0); - break; - } - } - break; - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - - /* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) - { - case IP_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - sock->conn->pcb.ip->ttl = (u8_t)(*(const int *)optval); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", s, sock->conn->pcb.ip->ttl)); - break; - case IP_TOS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - sock->conn->pcb.ip->tos = (u8_t)(*(const int *)optval); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", s, sock->conn->pcb.ip->tos)); - break; + default: + LWIP_ASSERT("Unhandled netconn type in SO_BINDTODEVICE", 0); + break; + } + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + + /* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + sock->conn->pcb.ip->ttl = (u8_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", + s, sock->conn->pcb.ip->ttl)); + break; + case IP_TOS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + sock->conn->pcb.ip->tos = (u8_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", + s, sock->conn->pcb.ip->tos)); + break; #if LWIP_NETBUF_RECVINFO - case IP_PKTINFO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); - if (*(const int *)optval) - { - sock->conn->flags |= NETCONN_FLAG_PKTINFO; - } - else - { - sock->conn->flags &= ~NETCONN_FLAG_PKTINFO; - } - break; + case IP_PKTINFO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); + if (*(const int *)optval) { + sock->conn->flags |= NETCONN_FLAG_PKTINFO; + } else { + sock->conn->flags &= ~NETCONN_FLAG_PKTINFO; + } + break; #endif /* LWIP_NETBUF_RECVINFO */ #if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP - case IP_MULTICAST_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t *)optval)); - break; - case IP_MULTICAST_IF: - { - ip4_addr_t if_addr; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP); - inet_addr_to_ip4addr(&if_addr, (const struct in_addr *)optval); - udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr); - } - break; - case IP_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - if (*(const u8_t *)optval) - { - udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); - } - else - { - udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); - } - break; + case IP_MULTICAST_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t *)optval)); + break; + case IP_MULTICAST_IF: { + ip4_addr_t if_addr; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP); + inet_addr_to_ip4addr(&if_addr, (const struct in_addr *)optval); + udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr); + } + break; + case IP_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + if (*(const u8_t *)optval) { + udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); + } else { + udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); + } + break; #endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ #if LWIP_IGMP - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - /* If this is a TCP or a RAW socket, ignore these options. */ - err_t igmp_err; - const struct ip_mreq *imr = (const struct ip_mreq *)optval; - ip4_addr_t if_addr; - ip4_addr_t multi_addr; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); - inet_addr_to_ip4addr(&if_addr, &imr->imr_interface); - inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr); - if (optname == IP_ADD_MEMBERSHIP) - { - if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) - { - /* cannot track membership (out of memory) */ - err = ENOMEM; - igmp_err = ERR_OK; - } - else - { - igmp_err = igmp_joingroup(&if_addr, &multi_addr); - } - } - else - { - igmp_err = igmp_leavegroup(&if_addr, &multi_addr); - lwip_socket_unregister_membership(s, &if_addr, &multi_addr); - } - if (igmp_err != ERR_OK) - { - err = EADDRNOTAVAIL; - } - } - break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: { + /* If this is a TCP or a RAW socket, ignore these options. */ + err_t igmp_err; + const struct ip_mreq *imr = (const struct ip_mreq *)optval; + ip4_addr_t if_addr; + ip4_addr_t multi_addr; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); + inet_addr_to_ip4addr(&if_addr, &imr->imr_interface); + inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr); + if (optname == IP_ADD_MEMBERSHIP) { + if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) { + /* cannot track membership (out of memory) */ + err = ENOMEM; + igmp_err = ERR_OK; + } else { + igmp_err = igmp_joingroup(&if_addr, &multi_addr); + } + } else { + igmp_err = igmp_leavegroup(&if_addr, &multi_addr); + lwip_socket_unregister_membership(s, &if_addr, &multi_addr); + } + if (igmp_err != ERR_OK) { + err = EADDRNOTAVAIL; + } + } + break; #endif /* LWIP_IGMP */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #if LWIP_TCP - /* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* Special case: all IPPROTO_TCP option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); - if (sock->conn->pcb.tcp->state == LISTEN) - { - done_socket(sock); - return EINVAL; - } - switch (optname) - { - case TCP_NODELAY: - if (*(const int *)optval) - { - tcp_nagle_disable(sock->conn->pcb.tcp); - } - else - { - tcp_nagle_enable(sock->conn->pcb.tcp); - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", - s, - (*(const int *)optval) ? "on" : "off")); - break; - case TCP_KEEPALIVE: - sock->conn->pcb.tcp->keep_idle = (u32_t)(*(const int *)optval); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %" U32_F "\n", - s, - sock->conn->pcb.tcp->keep_idle)); - break; + /* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* Special case: all IPPROTO_TCP option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); + if (sock->conn->pcb.tcp->state == LISTEN) { + done_socket(sock); + return EINVAL; + } + switch (optname) { + case TCP_NODELAY: + if (*(const int *)optval) { + tcp_nagle_disable(sock->conn->pcb.tcp); + } else { + tcp_nagle_enable(sock->conn->pcb.tcp); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", + s, (*(const int *)optval) ? "on" : "off") ); + break; + case TCP_KEEPALIVE: + sock->conn->pcb.tcp->keep_idle = (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; #if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - sock->conn->pcb.tcp->keep_idle = 1000 * (u32_t)(*(const int *)optval); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %" U32_F "\n", - s, - sock->conn->pcb.tcp->keep_idle)); - break; - case TCP_KEEPINTVL: - sock->conn->pcb.tcp->keep_intvl = 1000 * (u32_t)(*(const int *)optval); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %" U32_F "\n", - s, - sock->conn->pcb.tcp->keep_intvl)); - break; - case TCP_KEEPCNT: - sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(const int *)optval); - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %" U32_F "\n", - s, - sock->conn->pcb.tcp->keep_cnt)); - break; + case TCP_KEEPIDLE: + sock->conn->pcb.tcp->keep_idle = 1000 * (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + case TCP_KEEPINTVL: + sock->conn->pcb.tcp->keep_intvl = 1000 * (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_intvl)); + break; + case TCP_KEEPCNT: + sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_cnt)); + break; #endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #endif /* LWIP_TCP*/ #if LWIP_IPV6 - /* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) - { - case IPV6_V6ONLY: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - if (*(const int *)optval) - { - netconn_set_ipv6only(sock->conn, 1); - } - else - { - netconn_set_ipv6only(sock->conn, 0); - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", - s, - (netconn_get_ipv6only(sock->conn) ? 1 : 0))); - break; + /* Level: IPPROTO_IPV6 */ + case IPPROTO_IPV6: + switch (optname) { + case IPV6_V6ONLY: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + if (*(const int *)optval) { + netconn_set_ipv6only(sock->conn, 1); + } else { + netconn_set_ipv6only(sock->conn, 0); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", + s, (netconn_get_ipv6only(sock->conn) ? 1 : 0))); + break; #if LWIP_IPV6_MLD - case IPV6_JOIN_GROUP: - case IPV6_LEAVE_GROUP: - { - /* If this is a TCP or a RAW socket, ignore these options. */ - err_t mld6_err; - struct netif *netif; - ip6_addr_t multi_addr; - const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP); - inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); - LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); - netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); - if (netif == NULL) - { - err = EADDRNOTAVAIL; - break; - } - - if (optname == IPV6_JOIN_GROUP) - { - if (!lwip_socket_register_mld6_membership(s, imr->ipv6mr_interface, &multi_addr)) - { - /* cannot track membership (out of memory) */ - err = ENOMEM; - mld6_err = ERR_OK; - } - else - { - mld6_err = mld6_joingroup_netif(netif, &multi_addr); - } - } - else - { - mld6_err = mld6_leavegroup_netif(netif, &multi_addr); - lwip_socket_unregister_mld6_membership(s, imr->ipv6mr_interface, &multi_addr); - } - if (mld6_err != ERR_OK) - { - err = EADDRNOTAVAIL; - } - } - break; -#endif /* LWIP_IPV6_MLD */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ + case IPV6_JOIN_GROUP: + case IPV6_LEAVE_GROUP: { + /* If this is a TCP or a RAW socket, ignore these options. */ + err_t mld6_err; + struct netif *netif; + ip6_addr_t multi_addr; + const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP); + inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); + LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); + netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); + if (netif == NULL) { + err = EADDRNOTAVAIL; break; + } + + if (optname == IPV6_JOIN_GROUP) { + if (!lwip_socket_register_mld6_membership(s, imr->ipv6mr_interface, &multi_addr)) { + /* cannot track membership (out of memory) */ + err = ENOMEM; + mld6_err = ERR_OK; + } else { + mld6_err = mld6_joingroup_netif(netif, &multi_addr); + } + } else { + mld6_err = mld6_leavegroup_netif(netif, &multi_addr); + lwip_socket_unregister_mld6_membership(s, imr->ipv6mr_interface, &multi_addr); + } + if (mld6_err != ERR_OK) { + err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IPV6_MLD */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #endif /* LWIP_IPV6 */ #if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - /* Special case: all IPPROTO_UDPLITE option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) - { - done_socket(sock); - return ENOPROTOOPT; - } - switch (optname) - { - case UDPLITE_SEND_CSCOV: - if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) - { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_tx = 8; - } - else - { - sock->conn->pcb.udp->chksum_len_tx = (u16_t) * (const int *)optval; - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", - s, - (*(const int *)optval))); - break; - case UDPLITE_RECV_CSCOV: - if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) - { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_rx = 8; - } - else - { - sock->conn->pcb.udp->chksum_len_rx = (u16_t) * (const int *)optval; - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", - s, - (*(const int *)optval))); - break; - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + /* Special case: all IPPROTO_UDPLITE option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + /* If this is no UDP lite socket, ignore any options. */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { + done_socket(sock); + return ENOPROTOOPT; + } + switch (optname) { + case UDPLITE_SEND_CSCOV: + if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_tx = 8; + } else { + sock->conn->pcb.udp->chksum_len_tx = (u16_t) * (const int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", + s, (*(const int *)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_rx = 8; + } else { + sock->conn->pcb.udp->chksum_len_rx = (u16_t) * (const int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", + s, (*(const int *)optval)) ); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; #endif /* LWIP_UDP */ - /* Level: IPPROTO_RAW */ - case IPPROTO_RAW: - switch (optname) - { + /* Level: IPPROTO_RAW */ + case IPPROTO_RAW: + switch (optname) { #if LWIP_IPV6 && LWIP_RAW - case IPV6_CHECKSUM: - /* It should not be possible to disable the checksum generation with ICMPv6 - * as per RFC 3542 chapter 3.1 */ - if (sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) - { - done_socket(sock); - return EINVAL; - } - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); - if (*(const int *)optval < 0) - { - sock->conn->pcb.raw->chksum_reqd = 0; - } - else if (*(const int *)optval & 1) - { - /* Per RFC3542, odd offsets are not allowed */ - done_socket(sock); - return EINVAL; - } - else - { - sock->conn->pcb.raw->chksum_reqd = 1; - sock->conn->pcb.raw->chksum_offset = (u16_t) * (const int *)optval; - } - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n", - s, - sock->conn->pcb.raw->chksum_reqd)); - break; + case IPV6_CHECKSUM: + /* It should not be possible to disable the checksum generation with ICMPv6 + * as per RFC 3542 chapter 3.1 */ + if (sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) { + done_socket(sock); + return EINVAL; + } + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); + if (*(const int *)optval < 0) { + sock->conn->pcb.raw->chksum_reqd = 0; + } else if (*(const int *)optval & 1) { + /* Per RFC3542, odd offsets are not allowed */ + done_socket(sock); + return EINVAL; + } else { + sock->conn->pcb.raw->chksum_reqd = 1; + sock->conn->pcb.raw->chksum_offset = (u16_t) * (const int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n", + s, sock->conn->pcb.raw->chksum_reqd)); + break; #endif /* LWIP_IPV6 && LWIP_RAW */ - default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; default: - LWIP_DEBUGF( - SOCKETS_DEBUG, - ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname)); - err = ENOPROTOOPT; - break; - } /* switch (level) */ - - done_socket(sock); - return err; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + break; + } /* switch (level) */ + + done_socket(sock); + return err; } -int lwip_ioctl(int s, long cmd, void *argp) +int +lwip_ioctl(int s, long cmd, void *argp) { - struct lwip_sock *sock = get_socket(s); - u8_t val; + struct lwip_sock *sock = get_socket(s); + u8_t val; #if LWIP_SO_RCVBUF - int recv_avail; + int recv_avail; #endif /* LWIP_SO_RCVBUF */ - if (!sock) - { - return -1; - } + if (!sock) { + return -1; + } - switch (cmd) - { + switch (cmd) { #if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE - case FIONREAD: - if (!argp) - { - sock_set_errno(sock, EINVAL); - done_socket(sock); - return -1; - } + case FIONREAD: + if (!argp) { + set_errno(EINVAL); + done_socket(sock); + return -1; + } #if LWIP_FIONREAD_LINUXMODE - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) - { - struct netbuf *nb; - if (sock->lastdata.netbuf) - { - nb = sock->lastdata.netbuf; - *((int *)argp) = nb->p->tot_len; - } - else - { - struct netbuf *rxbuf; - err_t err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &rxbuf, NETCONN_DONTBLOCK); - if (err != ERR_OK) - { - *((int *)argp) = 0; - } - else - { - sock->lastdata.netbuf = rxbuf; - *((int *)argp) = rxbuf->p->tot_len; - } - } - done_socket(sock); - return 0; - } + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + struct netbuf *nb; + if (sock->lastdata.netbuf) { + nb = sock->lastdata.netbuf; + *((int *)argp) = nb->p->tot_len; + } else { + struct netbuf *rxbuf; + err_t err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &rxbuf, NETCONN_DONTBLOCK); + if (err != ERR_OK) { + *((int *)argp) = 0; + } else { + sock->lastdata.netbuf = rxbuf; + *((int *)argp) = rxbuf->p->tot_len; + } + } + done_socket(sock); + return 0; + } #endif /* LWIP_FIONREAD_LINUXMODE */ #if LWIP_SO_RCVBUF - /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ - SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); - if (recv_avail < 0) - { - recv_avail = 0; - } - - /* Check if there is data left from the last recv operation. /maq 041215 */ - if (sock->lastdata.netbuf) - { - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) - { - recv_avail += sock->lastdata.pbuf->tot_len; - } - else - { - recv_avail += sock->lastdata.netbuf->p->tot_len; - } - } - *((int *)argp) = recv_avail; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %" U16_F "\n", s, argp, *((u16_t *)argp))); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; -#else /* LWIP_SO_RCVBUF */ - break; + /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) { + recv_avail = 0; + } + + /* Check if there is data left from the last recv operation. /maq 041215 */ + if (sock->lastdata.netbuf) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + recv_avail += sock->lastdata.pbuf->tot_len; + } else { + recv_avail += sock->lastdata.netbuf->p->tot_len; + } + } + *((int *)argp) = recv_avail; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t *)argp))); + set_errno(0); + done_socket(sock); + return 0; +#else /* LWIP_SO_RCVBUF */ + break; #endif /* LWIP_SO_RCVBUF */ #endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ - case (long)FIONBIO: - val = 0; - if (argp && *(int *)argp) - { - val = 1; - } - netconn_set_nonblocking(sock->conn, val); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); - sock_set_errno(sock, 0); - done_socket(sock); - return 0; - - default: - break; - } /* switch (cmd) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - done_socket(sock); - return -1; + case (long)FIONBIO: + val = 0; + if (argp && *(int *)argp) { + val = 1; + } + netconn_set_nonblocking(sock->conn, val); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); + set_errno(0); + done_socket(sock); + return 0; + + default: + break; + } /* switch (cmd) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + set_errno(ENOSYS); /* not yet implemented */ + done_socket(sock); + return -1; } /** A minimal implementation of fcntl. @@ -4577,165 +3966,150 @@ int lwip_ioctl(int s, long cmd, void *argp) * The flag O_NONBLOCK and access modes are supported for F_GETFL, only * the flag O_NONBLOCK is implemented for F_SETFL. */ -int lwip_fcntl(int s, int cmd, int val) +int +lwip_fcntl(int s, int cmd, int val) { - struct lwip_sock *sock = get_socket(s); - int ret = -1; - int op_mode = 0; + struct lwip_sock *sock = get_socket(s); + int ret = -1; + int op_mode = 0; - if (!sock) - { - return -1; - } + if (!sock) { + return -1; + } - switch (cmd) - { - case F_GETFL: - ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; - sock_set_errno(sock, 0); + switch (cmd) { + case F_GETFL: + ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; + set_errno(0); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) - { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { #if LWIP_TCPIP_CORE_LOCKING - LOCK_TCPIP_CORE(); + LOCK_TCPIP_CORE(); #else - SYS_ARCH_DECL_PROTECT(lev); - /* the proper thing to do here would be to get into the tcpip_thread, - but locking should be OK as well since we only *read* some flags */ - SYS_ARCH_PROTECT(lev); + SYS_ARCH_DECL_PROTECT(lev); + /* the proper thing to do here would be to get into the tcpip_thread, + but locking should be OK as well since we only *read* some flags */ + SYS_ARCH_PROTECT(lev); #endif #if LWIP_TCP - if (sock->conn->pcb.tcp) - { - if (!(sock->conn->pcb.tcp->flags & TF_RXCLOSED)) - { - op_mode |= O_RDONLY; - } - if (!(sock->conn->pcb.tcp->flags & TF_FIN)) - { - op_mode |= O_WRONLY; - } - } + if (sock->conn->pcb.tcp) { + if (!(sock->conn->pcb.tcp->flags & TF_RXCLOSED)) { + op_mode |= O_RDONLY; + } + if (!(sock->conn->pcb.tcp->flags & TF_FIN)) { + op_mode |= O_WRONLY; + } + } #endif #if LWIP_TCPIP_CORE_LOCKING - UNLOCK_TCPIP_CORE(); + UNLOCK_TCPIP_CORE(); #else - SYS_ARCH_UNPROTECT(lev); + SYS_ARCH_UNPROTECT(lev); #endif - } - else - { - op_mode |= O_RDWR; - } - - /* ensure O_RDWR for (O_RDONLY|O_WRONLY) != O_RDWR cases */ - ret |= (op_mode == (O_RDONLY | O_WRONLY)) ? O_RDWR : op_mode; - - break; - case F_SETFL: - /* Bits corresponding to the file access mode and the file creation flags [..] that are set in arg shall be - * ignored */ - val &= ~(O_RDONLY | O_WRONLY | O_RDWR); - if ((val & ~O_NONBLOCK) == 0) - { - /* only O_NONBLOCK, all other bits are zero */ - netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); - ret = 0; - sock_set_errno(sock, 0); - } - else - { - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - break; - } - done_socket(sock); - return ret; + } else { + op_mode |= O_RDWR; + } + + /* ensure O_RDWR for (O_RDONLY|O_WRONLY) != O_RDWR cases */ + ret |= (op_mode == (O_RDONLY | O_WRONLY)) ? O_RDWR : op_mode; + + break; + case F_SETFL: + /* Bits corresponding to the file access mode and the file creation flags [..] that are set in arg shall be ignored */ + val &= ~(O_RDONLY | O_WRONLY | O_RDWR); + if ((val & ~O_NONBLOCK) == 0) { + /* only O_NONBLOCK, all other bits are zero */ + netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); + ret = 0; + set_errno(0); + } else { + set_errno(ENOSYS); /* not yet implemented */ + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); + set_errno(ENOSYS); /* not yet implemented */ + break; + } + done_socket(sock); + return ret; } #if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES -int fcntl(int s, int cmd, ...) +int +fcntl(int s, int cmd, ...) { - va_list ap; - int val; + va_list ap; + int val; - va_start(ap, cmd); - val = va_arg(ap, int); - va_end(ap); - return lwip_fcntl(s, cmd, val); + va_start(ap, cmd); + val = va_arg(ap, int); + va_end(ap); + return lwip_fcntl(s, cmd, val); } #endif -const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size) +const char * +lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size) { - const char *ret = NULL; - int size_int = (int)size; - if (size_int < 0) - { - set_errno(ENOSPC); - return NULL; - } - switch (af) - { + const char *ret = NULL; + int size_int = (int)size; + if (size_int < 0) { + set_errno(ENOSPC); + return NULL; + } + switch (af) { #if LWIP_IPV4 - case AF_INET: - ret = ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int); - if (ret == NULL) - { - set_errno(ENOSPC); - } - break; + case AF_INET: + ret = ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int); + if (ret == NULL) { + set_errno(ENOSPC); + } + break; #endif #if LWIP_IPV6 - case AF_INET6: - ret = ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int); - if (ret == NULL) - { - set_errno(ENOSPC); - } - break; + case AF_INET6: + ret = ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int); + if (ret == NULL) { + set_errno(ENOSPC); + } + break; #endif - default: - set_errno(EAFNOSUPPORT); - break; - } - return ret; + default: + set_errno(EAFNOSUPPORT); + break; + } + return ret; } -int lwip_inet_pton(int af, const char *src, void *dst) +int +lwip_inet_pton(int af, const char *src, void *dst) { - int err; - switch (af) - { + int err; + switch (af) { #if LWIP_IPV4 - case AF_INET: - err = ip4addr_aton(src, (ip4_addr_t *)dst); - break; + case AF_INET: + err = ip4addr_aton(src, (ip4_addr_t *)dst); + break; #endif #if LWIP_IPV6 - case AF_INET6: - { - /* convert into temporary variable since ip6_addr_t might be larger - than in6_addr when scopes are enabled */ - ip6_addr_t addr; - err = ip6addr_aton(src, &addr); - if (err) - { - memcpy(dst, &addr.addr, sizeof(addr.addr)); - } - break; - } -#endif - default: - err = -1; - set_errno(EAFNOSUPPORT); - break; + case AF_INET6: { + /* convert into temporary variable since ip6_addr_t might be larger + than in6_addr when scopes are enabled */ + ip6_addr_t addr; + err = ip6addr_aton(src, &addr); + if (err) { + memcpy(dst, &addr.addr, sizeof(addr.addr)); + } + break; } - return err; +#endif + default: + err = -1; + set_errno(EAFNOSUPPORT); + break; + } + return err; } #if LWIP_IGMP @@ -4745,29 +4119,27 @@ int lwip_inet_pton(int af, const char *src, void *dst) * * @return 1 on success, 0 on failure */ -static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) +static int +lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) { - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) - { - return 0; - } + struct lwip_sock *sock = get_socket(s); + int i; - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) - { - if (socket_ipv4_multicast_memberships[i].sock == NULL) - { - socket_ipv4_multicast_memberships[i].sock = sock; - ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); - ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); - done_socket(sock); - return 1; - } - } - done_socket(sock); + if (!sock) { return 0; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv4_multicast_memberships[i].sock == NULL) { + socket_ipv4_multicast_memberships[i].sock = sock; + ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); + ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); + done_socket(sock); + return 1; + } + } + done_socket(sock); + return 0; } /** Unregister a previously registered membership. This prevents dropping the membership @@ -4775,60 +4147,56 @@ static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, con * * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). */ -static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) +static void +lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) { - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) - { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) - { - if ((socket_ipv4_multicast_memberships[i].sock == sock) && - ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && - ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) - { - socket_ipv4_multicast_memberships[i].sock = NULL; - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); - break; - } - } - done_socket(sock); + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if ((socket_ipv4_multicast_memberships[i].sock == sock) && + ip4_addr_eq(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && + ip4_addr_eq(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv4_multicast_memberships[i].sock = NULL; + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); + break; + } + } + done_socket(sock); } /** Drop all memberships of a socket that were not dropped explicitly via setsockopt. * * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). */ -static void lwip_socket_drop_registered_memberships(int s) +static void +lwip_socket_drop_registered_memberships(int s) { - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) - { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) - { - if (socket_ipv4_multicast_memberships[i].sock == sock) - { - ip_addr_t multi_addr, if_addr; - ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); - ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr); - socket_ipv4_multicast_memberships[i].sock = NULL; - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); - - netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); - } - } - done_socket(sock); + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv4_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr, if_addr; + ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); + ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr); + socket_ipv4_multicast_memberships[i].sock = NULL; + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); + + netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); + } + } + done_socket(sock); } #endif /* LWIP_IGMP */ @@ -4839,29 +4207,27 @@ static void lwip_socket_drop_registered_memberships(int s) * * @return 1 on success, 0 on failure */ -static int lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) +static int +lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) { - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) - { - return 0; - } + struct lwip_sock *sock = get_socket(s); + int i; - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) - { - if (socket_ipv6_multicast_memberships[i].sock == NULL) - { - socket_ipv6_multicast_memberships[i].sock = sock; - socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; - ip6_addr_copy(socket_ipv6_multicast_memberships[i].multi_addr, *multi_addr); - done_socket(sock); - return 1; - } - } - done_socket(sock); + if (!sock) { return 0; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv6_multicast_memberships[i].sock == NULL) { + socket_ipv6_multicast_memberships[i].sock = sock; + socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; + ip6_addr_copy(socket_ipv6_multicast_memberships[i].multi_addr, *multi_addr); + done_socket(sock); + return 1; + } + } + done_socket(sock); + return 0; } /** Unregister a previously registered MLD6 membership. This prevents dropping the membership @@ -4869,63 +4235,59 @@ static int lwip_socket_register_mld6_membership(int s, unsigned int if_idx, cons * * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). */ -static void lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) +static void +lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) { - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) - { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) - { - if ((socket_ipv6_multicast_memberships[i].sock == sock) && - (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && - ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) - { - socket_ipv6_multicast_memberships[i].sock = NULL; - socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; - ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); - break; - } - } - done_socket(sock); + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if ((socket_ipv6_multicast_memberships[i].sock == sock) && + (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && + ip6_addr_eq(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv6_multicast_memberships[i].sock = NULL; + socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); + break; + } + } + done_socket(sock); } /** Drop all MLD6 memberships of a socket that were not dropped explicitly via setsockopt. * * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). */ -static void lwip_socket_drop_registered_mld6_memberships(int s) +static void +lwip_socket_drop_registered_mld6_memberships(int s) { - struct lwip_sock *sock = get_socket(s); - int i; + struct lwip_sock *sock = get_socket(s); + int i; - if (!sock) - { - return; - } + if (!sock) { + return; + } - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) - { - if (socket_ipv6_multicast_memberships[i].sock == sock) - { - ip_addr_t multi_addr; - u8_t if_idx; + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv6_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr; + u8_t if_idx; - ip_addr_copy_from_ip6(multi_addr, socket_ipv6_multicast_memberships[i].multi_addr); - if_idx = socket_ipv6_multicast_memberships[i].if_idx; + ip_addr_copy_from_ip6(multi_addr, socket_ipv6_multicast_memberships[i].multi_addr); + if_idx = socket_ipv6_multicast_memberships[i].if_idx; - socket_ipv6_multicast_memberships[i].sock = NULL; - socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; - ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); + socket_ipv6_multicast_memberships[i].sock = NULL; + socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); - netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); - } + netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); } - done_socket(sock); + } + done_socket(sock); } #endif /* LWIP_IPV6_MLD */ @@ -4934,9 +4296,9 @@ static void lwip_socket_drop_registered_mld6_memberships(int s) // lwIP is clearly missing an API to get the last error from a socket uint32_t lwip_socket_get_err(int s) { - struct lwip_sock *sock = get_socket(s); - done_socket(sock); - return sock->err; + struct lwip_sock *sock = get_socket(s); + done_socket(sock); + return sock->err; } // [END_NF_CHANGE] diff --git a/targets/ESP32/_lwIP/nf_sys_arch.c b/targets/ESP32/_lwIP/nf_sys_arch.c index 1208f669fe..f33ea980fb 100644 --- a/targets/ESP32/_lwIP/nf_sys_arch.c +++ b/targets/ESP32/_lwIP/nf_sys_arch.c @@ -1,9 +1,12 @@ // // Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) 2001-2004 Swedish Institute of Computer Science. All rights reserved. -// Portions Copyright (c) 2006..2015 Giovanni Di Sirio. All rights reserved. -// See LICENSE file in the project root for full license information. // +// SPDX-FileCopyrightText: 2001-2003 Swedish Institute of Computer Science +// SPDX-License-Identifier: BSD-3-Clause +// SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD +// + +/* lwIP includes. */ #include #include "freertos/FreeRTOS.h" @@ -218,10 +221,6 @@ sys_mbox_new(sys_mbox_t *mbox, int size) return ERR_MEM; } -#if ESP_THREAD_SAFE - (*mbox)->owner = NULL; -#endif - LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("new *mbox ok mbox=%p os_mbox=%p\n", *mbox, (*mbox)->os_mbox)); return ERR_OK; } @@ -351,15 +350,6 @@ sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) return 0; } -void -sys_mbox_set_owner(sys_mbox_t *mbox, void* owner) -{ - if (mbox && *mbox) { - (*mbox)->owner = owner; - LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("set mbox=%p owner=%p", *mbox, owner)); - } -} - /** * @brief Delete a mailbox * @@ -402,7 +392,7 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize ret = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &rtos_task, CONFIG_LWIP_TCPIP_TASK_AFFINITY); - LWIP_DEBUGF(TCPIP_DEBUG, ("new lwip task : %x, prio:%d,stack:%d\n", + LWIP_DEBUGF(TCPIP_DEBUG, ("new lwip task : %" U32_F ", prio:%d,stack:%d\n", (u32_t)rtos_task, prio, stacksize)); if (ret != pdTRUE) { @@ -421,7 +411,7 @@ sys_init(void) { if (!g_lwip_protect_mutex) { if (ERR_OK != sys_mutex_new(&g_lwip_protect_mutex)) { - ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n"); + ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex"); } } @@ -443,7 +433,7 @@ sys_jiffies(void) } /** - * @brief Get current time, in miliseconds + * @brief Get current time, in milliseconds * * @return current time */ diff --git a/targets/ESP32/_nanoCLR/System.Device.I2c.Slave/sys_dev_i2c_slave_native_System_Device_I2c_I2cSlaveDevice.cpp b/targets/ESP32/_nanoCLR/System.Device.I2c.Slave/sys_dev_i2c_slave_native_System_Device_I2c_I2cSlaveDevice.cpp index 66fcb9c749..1035dff3af 100644 --- a/targets/ESP32/_nanoCLR/System.Device.I2c.Slave/sys_dev_i2c_slave_native_System_Device_I2c_I2cSlaveDevice.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.I2c.Slave/sys_dev_i2c_slave_native_System_Device_I2c_I2cSlaveDevice.cpp @@ -31,7 +31,7 @@ NF_PAL_I2CSLAVE *GetPalI2cSlaveFromBusIndex(int busIndex) return &I2cSlave0_PAL; #endif -#if SOC_I2C_NUM > 1 +#if SOC_HP_I2C_NUM > 1 case I2C_NUM_1: // set UART PAL return &I2cSlave1_PAL; diff --git a/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp b/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp index 6d7a39af43..10546422b6 100644 --- a/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp @@ -323,7 +323,7 @@ HRESULT SetI2sConfig(i2s_port_t bus, CLR_RT_HeapBlock *config) // apply low-level workaround for bug in some ESP-IDF versions that swap // the left and right channels // https://github.com/espressif/esp-idf/issues/6625 -#if CONFIG_IDF_TARGET_ESP32S3 +#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4) REG_SET_BIT(I2S_TX_CONF_REG(bus), I2S_TX_MSB_SHIFT); REG_SET_BIT(I2S_TX_CONF_REG(bus), I2S_RX_MSB_SHIFT); #else diff --git a/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp b/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp index c70b3d338e..bca9f42917 100644 --- a/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp @@ -172,7 +172,7 @@ HRESULT sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers::ConfigureAndStar // Work out the duty Cycle for the current duty resolution dutyCycle = CalculateDuty(timerId, dutyCycle); - ledc_conf = {pinNumber, mode, channel, LEDC_INTR_DISABLE, timer_sel, dutyCycle, 0, (unsigned int)polarity}; + ledc_conf = {pinNumber, mode, channel, LEDC_INTR_DISABLE, timer_sel, dutyCycle, 0, LEDC_SLEEP_MODE_NO_ALIVE_NO_PD, (unsigned int)polarity}; // Configure Channel which will also start it IDF_ERROR(ledc_channel_config(&ledc_conf)); diff --git a/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp b/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp index 7f1213960b..632e389141 100644 --- a/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp @@ -170,6 +170,8 @@ bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDev data6_io_num : -1, // GPIO pin for spi data7 signal in octal mode, //-1 if not used. data7_io_num : -1, + // Output data IO default level when no transaction + data_io_default_level : 0, // max transfer size max_transfer_sz : 16384, // SPICOMMON_BUSFLAG_* flags @@ -180,8 +182,8 @@ bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDev // Try with DMA first #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) - // First available bus on ESP32_C3/S3 is SPI2_HOST + defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) + // First available bus on ESP32_C3/S3/P4 is SPI2_HOST esp_err_t ret = spi_bus_initialize((spi_host_device_t)(busIndex + SPI2_HOST), &bus_config, SPI_DMA_CH_AUTO); #else // First available bus on ESP32 is HSPI_HOST(1) @@ -191,7 +193,7 @@ bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDev if (ret != ESP_OK) { #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) + defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) // First available bus on ESP32_C3/S3/C6/H2 is SPI2_HOST ESP_LOGE(TAG, "Unable to init SPI bus %d esp_err %d", busIndex + SPI2_HOST, ret); #else @@ -213,8 +215,8 @@ bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDev bool CPU_SPI_Uninitialize(uint8_t busIndex) { #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) - // First available bus on ESP32_C3/S3/C6/H2 is SPI2_HOST + defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) + // First available bus on ESP32_C3/S3/C6/H2/P4 is SPI2_HOST esp_err_t ret = spi_bus_free((spi_host_device_t)(busIndex + SPI2_HOST)); #else // First available bus on ESP32 is HSPI_HOST(1) @@ -224,8 +226,8 @@ bool CPU_SPI_Uninitialize(uint8_t busIndex) if (ret != ESP_OK) { #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) - // First available bus on ESP32_C3/S3/C6/H2 is SPI2_HOST + defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) + // First available bus on ESP32_C3/S3/C6/H2/P4 is SPI2_HOST ESP_LOGE(TAG, "spi_bus_free bus %d esp_err %d", busIndex + SPI2_HOST, ret); #else // First available bus on ESP32 is HSPI_HOST(1) @@ -317,6 +319,7 @@ spi_device_interface_config_t GetConfig(const SPI_DEVICE_CONFIGURATION &spiDevic 0, // cs_ena_posttrans clockHz, // Clock speed in Hz 0, // Input_delay_ns + SPI_SAMPLING_POINT_PHASE_0, // Sampling point -1, // Chip select, we will use manual chip select flags, // SPI_DEVICE flags 1, // Queue size @@ -362,8 +365,8 @@ HRESULT CPU_SPI_Add_Device(const SPI_DEVICE_CONFIGURATION &spiDeviceConfig, uint spi_device_handle_t deviceHandle; #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) - // First available bus on ESP32_C3/S3 is SPI2_HOST + defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) + // First available bus on ESP32_C3/S3/P4 is SPI2_HOST esp_err_t ret = spi_bus_add_device((spi_host_device_t)(spiDeviceConfig.Spi_Bus + SPI2_HOST), &dev_config, &deviceHandle); #else diff --git a/targets/ESP32/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/ESP32/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp index 0b91b4181e..fc323f7b83 100644 --- a/targets/ESP32/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp +++ b/targets/ESP32/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -26,6 +26,9 @@ NF_PAL_UART Uart2_PAL; #if SOC_UART_HP_NUM > 3 NF_PAL_UART Uart3_PAL; #endif +#if SOC_UART_HP_NUM > 4 +NF_PAL_UART Uart4_PAL; +#endif NF_PAL_UART *GetPalUartFromUartNum_sys(int uart_num) { @@ -46,11 +49,17 @@ NF_PAL_UART *GetPalUartFromUartNum_sys(int uart_num) #endif #if SOC_UART_HP_NUM > 3 - case UART_NUM_2: + case UART_NUM_3: // set UART PAL return &Uart3_PAL; #endif +#if SOC_UART_HP_NUM > 4 + case UART_NUM_4: + // set UART PAL + return &Uart4_PAL; +#endif + default: break; } diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp index 0ad6616519..aa5f5a96bf 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp @@ -109,10 +109,10 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 #if CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP esp_err_t err; - int pad1; - int coefficient; #if defined(CONFIG_IDF_TARGET_ESP32) + int pad1; + int coefficient; int pad2; // Setup the sleep mode touch_pad_init(); @@ -164,8 +164,12 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } } - +#elif defined(CONFIG_IDF_TARGET_ESP32P4) + //TODO + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); #else + int pad1; + int coefficient; touch_pad_denoise_t denoise; touch_filter_config_t filterInfo; uint32_t touchValue;