From 6133498ec86a28944750d3d7638e1acd591a2339 Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 08:18:03 +0000 Subject: [PATCH 1/8] Added missing include in file.c module --- LuaNode_Esp32/LuaNode32/components/modules/file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/LuaNode_Esp32/LuaNode32/components/modules/file.c b/LuaNode_Esp32/LuaNode32/components/modules/file.c index 2ecf59b..2a36f86 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/file.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/file.c @@ -2,6 +2,7 @@ #include "modules.h" #include "lauxlib.h" +#include "lualib.h" #include "platform.h" #include "c_types.h" From 086efa47cc1bb08e817008c6d169d7f5bfe247db Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 08:18:59 +0000 Subject: [PATCH 2/8] Removed redefinition of ip_addr --- LuaNode_Esp32/LuaNode32/components/modules/wifi.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/LuaNode_Esp32/LuaNode32/components/modules/wifi.c b/LuaNode_Esp32/LuaNode32/components/modules/wifi.c index 2fdec18..d4e931b 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/wifi.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/wifi.c @@ -25,10 +25,6 @@ #include "c_stdio.h" #include "ip_fmt.h" -struct ip_addr { - uint32 addr; -}; - typedef void (*fill_cb_arg_fn) (lua_State *L, const system_event_t *evt); typedef struct { From 1c4f8b7044a68b70c8e1bb39b53e83208114152b Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 08:24:39 +0000 Subject: [PATCH 3/8] New sdkconfig for ESP-IDF 2.1.1 --- LuaNode_Esp32/LuaNode32/sdkconfig | 479 ++++++++---------------------- 1 file changed, 124 insertions(+), 355 deletions(-) diff --git a/LuaNode_Esp32/LuaNode32/sdkconfig b/LuaNode_Esp32/LuaNode32/sdkconfig index 7fd65f1..5d9688d 100644 --- a/LuaNode_Esp32/LuaNode32/sdkconfig +++ b/LuaNode_Esp32/LuaNode32/sdkconfig @@ -8,250 +8,175 @@ # CONFIG_TOOLPREFIX="xtensa-esp32-elf-" CONFIG_PYTHON="python" -CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y # # Bootloader config # -CONFIG_LOG_BOOTLOADER_LEVEL_NONE= -CONFIG_LOG_BOOTLOADER_LEVEL_ERROR= +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y -CONFIG_LOG_BOOTLOADER_LEVEL_INFO= -CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= -CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set CONFIG_LOG_BOOTLOADER_LEVEL=2 -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V= -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +CONFIG_BOOTLOADER_VDDSDIO_BOOST=y # # Security features # -CONFIG_SECURE_BOOT_ENABLED= -CONFIG_FLASH_ENCRYPTION_ENABLED= +# CONFIG_SECURE_BOOT_ENABLED is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set # # Serial flasher config # CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" CONFIG_ESPTOOLPY_BAUD_115200B=y -CONFIG_ESPTOOLPY_BAUD_230400B= -CONFIG_ESPTOOLPY_BAUD_921600B= -CONFIG_ESPTOOLPY_BAUD_2MB= -CONFIG_ESPTOOLPY_BAUD_OTHER= +# CONFIG_ESPTOOLPY_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_BAUD_OTHER is not set CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_BAUD=115200 -CONFIG_ESPTOOLPY_COMPRESSED= -CONFIG_FLASHMODE_QIO= -CONFIG_FLASHMODE_QOUT= +CONFIG_ESPTOOLPY_COMPRESSED=y +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set CONFIG_FLASHMODE_DIO=y -CONFIG_FLASHMODE_DOUT= +# CONFIG_FLASHMODE_DOUT is not set CONFIG_ESPTOOLPY_FLASHMODE="dio" -CONFIG_ESPTOOLPY_FLASHFREQ_80M= +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -CONFIG_ESPTOOLPY_FLASHFREQ_26M= -CONFIG_ESPTOOLPY_FLASHFREQ_20M= +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set CONFIG_ESPTOOLPY_FLASHFREQ="40m" -CONFIG_ESPTOOLPY_FLASHSIZE_1MB= +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -CONFIG_ESPTOOLPY_FLASHSIZE_4MB= -CONFIG_ESPTOOLPY_FLASHSIZE_8MB= -CONFIG_ESPTOOLPY_FLASHSIZE_16MB= +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y CONFIG_ESPTOOLPY_BEFORE_RESET=y -CONFIG_ESPTOOLPY_BEFORE_NORESET= +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set CONFIG_ESPTOOLPY_BEFORE="default_reset" CONFIG_ESPTOOLPY_AFTER_RESET=y -CONFIG_ESPTOOLPY_AFTER_NORESET= +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_MONITOR_BAUD_9600B= -CONFIG_MONITOR_BAUD_57600B= +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set CONFIG_MONITOR_BAUD_115200B=y -CONFIG_MONITOR_BAUD_230400B= -CONFIG_MONITOR_BAUD_921600B= -CONFIG_MONITOR_BAUD_2MB= -CONFIG_MONITOR_BAUD_OTHER= +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set CONFIG_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_MONITOR_BAUD=115200 # # Partition Table # -CONFIG_PARTITION_TABLE_SINGLE_APP= -CONFIG_PARTITION_TABLE_TWO_OTA= +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-LuaNode.csv" CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000 CONFIG_PARTITION_TABLE_FILENAME="partitions-LuaNode.csv" CONFIG_APP_OFFSET=0x10000 -CONFIG_PARTITION_TABLE_MD5=y - -# -# Compiler options -# CONFIG_OPTIMIZATION_LEVEL_DEBUG=y -CONFIG_OPTIMIZATION_LEVEL_RELEASE= -CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= -CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= -CONFIG_CXX_EXCEPTIONS= -CONFIG_STACK_CHECK_NONE=y -CONFIG_STACK_CHECK_NORM= -CONFIG_STACK_CHECK_STRONG= -CONFIG_STACK_CHECK_ALL= -CONFIG_STACK_CHECK= -CONFIG_WARN_WRITE_STRINGS= +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set # # Component config # - -# -# Application Level Tracing -# -CONFIG_ESP32_APPTRACE_DEST_TRAX= -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_ENABLE= -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y - -# -# FreeRTOS SystemView Tracing -# -CONFIG_AWS_IOT_SDK= - -# -# Bluetooth -# -CONFIG_BT_ENABLED= -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +# CONFIG_AWS_IOT_SDK is not set +# CONFIG_BT_ENABLED is not set CONFIG_BT_RESERVE_DRAM=0 -# -# ADC configuration -# -CONFIG_ADC_FORCE_XPD_FSM= -CONFIG_ADC2_DISABLE_DAC=y - # # ESP32-specific # -CONFIG_ESP32_DEFAULT_CPU_FREQ_80= -CONFIG_ESP32_DEFAULT_CPU_FREQ_160= +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 -CONFIG_SPIRAM_SUPPORT= -CONFIG_MEMMAP_TRACEMEM= -CONFIG_MEMMAP_TRACEMEM_TWOBANKS= -CONFIG_ESP32_TRAX= +CONFIG_MEMMAP_SMP=y +# CONFIG_MEMMAP_TRACEMEM is not set +# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set +# CONFIG_ESP32_TRAX is not set CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE= +# CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE is not set CONFIG_ESP32_ENABLE_COREDUMP=y CONFIG_ESP32_CORE_DUMP_UART_DELAY=0 CONFIG_ESP32_CORE_DUMP_LOG_LEVEL=1 -CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +# CONFIG_ESP32_APPTRACE_DEST_UART is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +# CONFIG_ESP32_APPTRACE_ENABLE is not set +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 CONFIG_MAIN_TASK_STACK_SIZE=6144 CONFIG_IPC_TASK_STACK_SIZE=1024 -CONFIG_TIMER_TASK_STACK_SIZE=4096 -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= -CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= -CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -CONFIG_NEWLIB_NANO_FORMAT= +CONFIG_NEWLIB_STDOUT_ADDCR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set CONFIG_CONSOLE_UART_DEFAULT=y -CONFIG_CONSOLE_UART_CUSTOM= -CONFIG_CONSOLE_UART_NONE= +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ULP_COPROC_ENABLED= +# CONFIG_ULP_COPROC_ENABLED is not set CONFIG_ULP_COPROC_RESERVE_MEM=0 CONFIG_ESP32_PANIC_PRINT_HALT=y -CONFIG_ESP32_PANIC_PRINT_REBOOT= -CONFIG_ESP32_PANIC_SILENT_REBOOT= -CONFIG_ESP32_PANIC_GDBSTUB= +# CONFIG_ESP32_PANIC_PRINT_REBOOT is not set +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set CONFIG_ESP32_DEBUG_OCDAWARE=y CONFIG_INT_WDT=y CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_TASK_WDT=y -CONFIG_TASK_WDT_PANIC= +# CONFIG_TASK_WDT_PANIC is not set CONFIG_TASK_WDT_TIMEOUT_S=5 -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_BROWNOUT_DET=y -CONFIG_BROWNOUT_DET_LVL_SEL_0=y -CONFIG_BROWNOUT_DET_LVL_SEL_1= -CONFIG_BROWNOUT_DET_LVL_SEL_2= -CONFIG_BROWNOUT_DET_LVL_SEL_3= -CONFIG_BROWNOUT_DET_LVL_SEL_4= -CONFIG_BROWNOUT_DET_LVL_SEL_5= -CONFIG_BROWNOUT_DET_LVL_SEL_6= -CONFIG_BROWNOUT_DET_LVL_SEL_7= -CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_TASK_WDT_CHECK_IDLE_TASK=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC= -CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= -CONFIG_ESP32_TIME_SYSCALL_USE_NONE= +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 -CONFIG_ESP32_RTC_XTAL_BOOTSTRAP_CYCLES=100 CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=0 -CONFIG_ESP32_XTAL_FREQ_40= -CONFIG_ESP32_XTAL_FREQ_26= +# CONFIG_ESP32_XTAL_FREQ_40 is not set +# CONFIG_ESP32_XTAL_FREQ_26 is not set CONFIG_ESP32_XTAL_FREQ_AUTO=y CONFIG_ESP32_XTAL_FREQ=0 -CONFIG_DISABLE_BASIC_ROM_CONSOLE= -CONFIG_NO_BLOBS= -CONFIG_ESP_TIMER_PROFILING= -CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y - -# -# Wi-Fi -# +CONFIG_WIFI_ENABLED=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=0 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER= +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_ENABLED=y CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_PHY_ENABLED=y # # PHY # CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= +# 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 -# -# Power Management -# -CONFIG_PM_ENABLE= - -# -# ADC-Calibration -# -CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y -CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y -CONFIG_ADC_CAL_LUT_ENABLE=y - # # MQTT # CONFIG_MQTT_PROTOCOL_311=y -CONFIG_MQTT_SECURITY_ON= +# CONFIG_MQTT_SECURITY_ON is not set CONFIG_MQTT_PRIORITY=5 CONFIG_MQTT_LOG_ERROR_ON=y CONFIG_MQTT_LOG_WARN_ON=y @@ -265,99 +190,75 @@ CONFIG_MQTT_MAX_USERNAME_LEN=32 CONFIG_MQTT_MAX_PASSWORD_LEN=32 CONFIG_MQTT_MAX_LWT_TOPIC=32 CONFIG_MQTT_MAX_LWT_MSG=32 - -# -# Ethernet -# -CONFIG_DMA_RX_BUF_NUM=10 -CONFIG_DMA_TX_BUF_NUM=10 -CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE= -CONFIG_EMAC_TASK_PRIORITY=20 +# CONFIG_ETHERNET is not set # # FAT Filesystem support # -CONFIG_FATFS_CODEPAGE_DYNAMIC= +# CONFIG_FATFS_CODEPAGE_ASCII is not set CONFIG_FATFS_CODEPAGE_437=y -CONFIG_FATFS_CODEPAGE_720= -CONFIG_FATFS_CODEPAGE_737= -CONFIG_FATFS_CODEPAGE_771= -CONFIG_FATFS_CODEPAGE_775= -CONFIG_FATFS_CODEPAGE_850= -CONFIG_FATFS_CODEPAGE_852= -CONFIG_FATFS_CODEPAGE_855= -CONFIG_FATFS_CODEPAGE_857= -CONFIG_FATFS_CODEPAGE_860= -CONFIG_FATFS_CODEPAGE_861= -CONFIG_FATFS_CODEPAGE_862= -CONFIG_FATFS_CODEPAGE_863= -CONFIG_FATFS_CODEPAGE_864= -CONFIG_FATFS_CODEPAGE_865= -CONFIG_FATFS_CODEPAGE_866= -CONFIG_FATFS_CODEPAGE_869= -CONFIG_FATFS_CODEPAGE_932= -CONFIG_FATFS_CODEPAGE_936= -CONFIG_FATFS_CODEPAGE_949= -CONFIG_FATFS_CODEPAGE_950= +# 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_LFN_NONE=y -CONFIG_FATFS_LFN_HEAP= -CONFIG_FATFS_LFN_STACK= -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set # # FreeRTOS # CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_CORETIMER_0=y -CONFIG_FREERTOS_CORETIMER_1= +# CONFIG_FREERTOS_CORETIMER_1 is not set CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE= +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL=y -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY= -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY is not set +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3 CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y -CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= -CONFIG_FREERTOS_ASSERT_DISABLE= +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG=y +# CONFIG_ENABLE_MEMORY_DEBUG is not set CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024 CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_LEGACY_HOOKS= +# CONFIG_FREERTOS_LEGACY_HOOKS is not set CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -CONFIG_SUPPORT_STATIC_ALLOCATION= +# CONFIG_SUPPORT_STATIC_ALLOCATION is not set CONFIG_TIMER_TASK_PRIORITY=1 CONFIG_TIMER_TASK_STACK_DEPTH=2048 CONFIG_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -CONFIG_FREERTOS_USE_TRACE_FACILITY= -CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= -CONFIG_FREERTOS_DEBUG_INTERNALS= - -# -# Heap memory debugging -# -CONFIG_HEAP_POISONING_DISABLED=y -CONFIG_HEAP_POISONING_LIGHT= -CONFIG_HEAP_POISONING_COMPREHENSIVE= -CONFIG_HEAP_TRACING= - -# -# libsodium -# +# CONFIG_FREERTOS_DEBUG_INTERNALS is not set # # Log output # -CONFIG_LOG_DEFAULT_LEVEL_NONE= -CONFIG_LOG_DEFAULT_LEVEL_ERROR= -CONFIG_LOG_DEFAULT_LEVEL_WARN= +# 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= -CONFIG_LOG_DEFAULT_LEVEL_VERBOSE= +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_LOG_DEFAULT_LEVEL=3 CONFIG_LOG_COLORS=y @@ -374,141 +275,31 @@ CONFIG_LUA_ENABLE=y # # LWIP # -CONFIG_L2_TO_L3_COPY= -CONFIG_LWIP_IRAM_OPTIMIZATION= +# CONFIG_L2_TO_L3_COPY is not set CONFIG_LWIP_MAX_SOCKETS=4 -CONFIG_LWIP_SO_REUSE= -CONFIG_LWIP_SO_RCVBUF= +CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0 +# CONFIG_LWIP_SO_REUSE is not set +# CONFIG_LWIP_SO_RCVBUF is not set CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 -CONFIG_LWIP_IP_FRAG= -CONFIG_LWIP_IP_REASSEMBLY= -CONFIG_LWIP_STATS= -CONFIG_LWIP_ETHARP_TRUST_IP_MAC=y -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y - -# -# DHCP server -# -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -CONFIG_LWIP_AUTOIP= -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 +# CONFIG_LWIP_IP_FRAG is not set +# CONFIG_LWIP_IP_REASSEMBLY is not set CONFIG_TCP_MAXRTX=12 CONFIG_TCP_SYNMAXRTX=6 -CONFIG_TCP_MSS=1436 -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= -CONFIG_TCP_OVERSIZE_DISABLE= - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y CONFIG_TCPIP_TASK_STACK_SIZE=2048 -CONFIG_PPP_SUPPORT= - -# -# ICMP -# -CONFIG_LWIP_MULTICAST_PING= -CONFIG_LWIP_BROADCAST_PING= - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 +# CONFIG_PPP_SUPPORT is not set # # mbedTLS # CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 -CONFIG_MBEDTLS_DEBUG= +# CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_HARDWARE_MPI=y CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_HAVE_TIME=y -CONFIG_MBEDTLS_HAVE_TIME_DATE= -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -CONFIG_MBEDTLS_TLS_SERVER_ONLY= -CONFIG_MBEDTLS_TLS_CLIENT_ONLY= -CONFIG_MBEDTLS_TLS_DISABLED= -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -CONFIG_MBEDTLS_PSK_MODES= -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_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 -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_SSL3= -CONFIG_MBEDTLS_SSL_PROTO_TLS1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -CONFIG_MBEDTLS_SSL_PROTO_DTLS= -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -CONFIG_MBEDTLS_CAMELLIA_C= -CONFIG_MBEDTLS_DES_C= -CONFIG_MBEDTLS_RC4_DISABLED=y -CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= -CONFIG_MBEDTLS_RC4_ENABLED= -CONFIG_MBEDTLS_BLOWFISH_C= -CONFIG_MBEDTLS_XTEA_C= -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -CONFIG_MBEDTLS_RIPEMD160_C= - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -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_HAVE_TIME_DATE is not set # # MODULES @@ -528,35 +319,20 @@ CONFIG_MYLIBC_ENABLE=y # # OpenSSL # -CONFIG_OPENSSL_DEBUG= +# CONFIG_OPENSSL_DEBUG is not set CONFIG_OPENSSL_ASSERT_DO_NOTHING=y -CONFIG_OPENSSL_ASSERT_EXIT= +# CONFIG_OPENSSL_ASSERT_EXIT is not set # # PLATFORM # CONFIG_PLATFORM_ENABLE=y -# -# PThreads -# -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 - # # SPI Flash driver # -CONFIG_SPI_FLASH_VERIFY_WRITE= CONFIG_SPI_FLASH_ENABLE_COUNTERS=y CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS= -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED= - -# -# tcpip adapter -# -CONFIG_IP_LOST_TIMER_INTERVAL=120 # # UART @@ -567,10 +343,3 @@ CONFIG_UART_ENABLE=y # UTILS # CONFIG_UTILS_ENABLE=y - -# -# Wear Levelling -# -CONFIG_WL_SECTOR_SIZE_512= -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 From c08f355f5543698df6aa0548227eafad4118bd49 Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 08:33:09 +0000 Subject: [PATCH 4/8] Added instructions for setup, and lua example --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ae1883..7be5dc8 100755 --- a/README.md +++ b/README.md @@ -29,7 +29,8 @@ Download the DOIT dev-board schematic [here](https://www.dropbox.com/s/jefwxxtuf ### How To Build LuaNode32 * Download prebuild toolchain [Here](https://github.com/jmattsson/nodemcu-prebuilt-toolchains "toolchains"), you - can also build the tools from source, follow the steps [Here](http://esp-idf.readthedocs.io/en/latest/linux-setup.html "How to build toolchain") + can also build the tools from source, follow the steps [Here](https://docs.espressif.com/projects/esp-idf/en/v2.1.1/get-started/index.html#setup-toolchain "Setup toolchain (esp-idf v2.1.1)") +* Download the esp-idf framework ([official guide](https://docs.espressif.com/projects/esp-idf/en/v2.1.1/get-started/index.html#get-esp-idf)). However You will need to include the `-b v2.1.1` flag in the `git` command line to checkout the correct version (`git clone --recursive -b v2.1.1 https://github.com/espressif/esp-idf.git`) * Export build tools' directory by executing the following command on terminal, `export PATH=/your_path/toolchains/esp32/bin:$PATH`, where the `your_path` is the path the toolchains stored. @@ -48,6 +49,13 @@ file.open("myfile.lua", "w+"); file.write("hello world"); file.close(); +-- connect to wifi +wifi.setmode(wifi.STATION); +config = {} +config.ssid = "MYSSID" +config.pwd = "password" +wifi.sta.config(config) + -- read file from file system file.open("myfile.lua", "r"); -- read 1024 bytes from myfile.lua and save them From 096584af624caca67467f0eb75e99a05df98c5b7 Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 17:59:09 +0000 Subject: [PATCH 5/8] Removed dead and useless submodule --- LuaNode_Esp32/.gitmodules | 3 --- LuaNode_Esp32/esp-idf | 1 - 2 files changed, 4 deletions(-) delete mode 100644 LuaNode_Esp32/.gitmodules delete mode 160000 LuaNode_Esp32/esp-idf diff --git a/LuaNode_Esp32/.gitmodules b/LuaNode_Esp32/.gitmodules deleted file mode 100644 index 4ac6779..0000000 --- a/LuaNode_Esp32/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "esp-idf"] - path = esp-idf - url = https://github.com/espressif/esp-idf diff --git a/LuaNode_Esp32/esp-idf b/LuaNode_Esp32/esp-idf deleted file mode 160000 index 0865819..0000000 --- a/LuaNode_Esp32/esp-idf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0865819cf9de5e7e7a032003db121cc801a3addd From 4792b6616bdd9b0a8b427f1ae39af85fcdde9923 Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 19:58:15 +0000 Subject: [PATCH 6/8] Dos2Unix all the files --- .../LuaNode32/components/easy_mem/easy_heap.c | 330 +-- .../LuaNode32/components/easy_mem/easy_mem.c | 350 +-- .../components/easy_mem/include/chain.h | 132 +- .../components/easy_mem/include/easy_conf.h | 70 +- .../components/easy_mem/include/easy_heap.h | 92 +- .../components/easy_mem/include/easy_mem.h | 128 +- .../LuaNode32/components/espconn/dhcpserver.c | 2320 ++++++++--------- .../components/espconn/espconn_udp.c | 888 +++---- .../components/espconn/include/dhcpserver.h | 228 +- .../components/espconn/include/espconn_tcp.h | 158 +- .../components/espconn/include/espconn_udp.h | 128 +- .../LuaNode32/components/espconn/netio.c | 746 +++--- .../LuaNode32/components/lpeg/Kconfig | 18 +- .../LuaNode32/components/lua/Kconfig | 18 +- .../LuaNode32/components/modules/Kconfig | 18 +- .../LuaNode32/components/modules/nvs.c | 644 ++--- .../LuaNode32/components/modules/utils.c | 192 +- .../LuaNode32/components/modules/wifi.c | 1182 ++++----- .../LuaNode32/components/mydriver/Kconfig | 18 +- .../LuaNode32/components/mylibc/Kconfig | 18 +- .../LuaNode32/components/platform/Kconfig | 18 +- .../LuaNode32/components/uart/Kconfig | 18 +- .../components/uart/include/my_uart.h | 50 +- .../LuaNode32/components/uart/my_uart.c | 376 +-- .../LuaNode32/components/utils/Kconfig | 18 +- .../LuaNode32/components/utils/include/md5.h | 96 +- .../LuaNode32/components/utils/md5.c | 322 +-- .../alexa_esp32/main/include/user_config.h | 52 +- .../examples/alexa_esp32/main/main.c | 286 +- .../main/include/user_config.h | 54 +- .../examples/alexa_multi_esp32/main/main.c | 286 +- .../components/uart/my_uart.c | 608 ++--- .../components/utils/my_list.c | 136 +- .../examples/ble_to_udp_server/main/main.c | 690 ++--- .../bluetooth_scanner/main/component.mk | 16 +- .../examples/camera/components/camera/sccb.h | 32 +- .../examples/dns_resolver/app_main.c | 502 ++-- .../LuaNode32/examples/easy_mem/app_main.c | 64 +- .../LuaNode32/examples/json/main/component.mk | 16 +- .../LuaNode32/examples/json/main/main.c | 236 +- .../examples/lwip_raw_api/app_main.c | 292 +-- .../ota_tcp_update/client/main/main.c | 198 +- .../ota_tcp_update/server/ota_server.py | 144 +- .../examples/tcp_client_espconn/app_main.c | 324 +-- .../examples/tcp_server_espconn/app_main.c | 270 +- .../examples/telnet_server/app_main.c | 330 +-- .../LuaNode32/examples/test_spiffs/app_main.c | 108 +- .../examples/udp_broadcast/app_main.c | 228 +- .../examples/udp_server_espconn/app_main.c | 244 +- .../LuaNode32/lua_samples/file/file_write.lua | 42 +- .../LuaNode32/lua_samples/gpio/gpio_out.lua | 22 +- .../LuaNode32/lua_samples/i2c/i2c.lua | 50 +- .../LuaNode32/lua_samples/i2c/i2c_test.lua | 44 +- .../LuaNode32/lua_samples/mqtt/mqtt.lua | 60 +- .../LuaNode32/lua_samples/pwm/pwm.lua | 56 +- .../LuaNode32/lua_samples/timer/timer.lua | 28 +- .../LuaNode32/lua_samples/uart/uart.lua | 44 +- .../LuaNode32/lua_samples/utils/utils.lua | 10 +- .../main/include/extras/esp_intr_ext.h | 24 +- .../LuaNode32/main/include/extras/gpio_ext.h | 14 +- .../main/include/extras/gpio_reg_ext.h | 42 +- .../main/include/extras/gpio_sd_reg_ext.h | 14 +- LuaNode_Esp32/LuaNode32/main/include/mem.h | 54 +- .../LuaNode32/main/include/user_config.h | 142 +- 64 files changed, 7169 insertions(+), 7169 deletions(-) diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c index d314a17..0478dcd 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c @@ -1,165 +1,165 @@ -#include "easy_heap.h" -#include "easy_conf.h" -//#include "easy_os.h" - -uint8_t ram_heap[HEAP_SIZE + 2*sizeof(struct mem_heap) + HEAP_ALIGNMENT - 1]; -void *ram; -struct mem_heap *pfree; -struct mem_heap *heap_end; - -/** - * Fill hole - */ -static void -plug_hole(struct mem_heap *heap) -{ - struct mem_heap *nheap, *pheap; - nheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->next]); - if(heap != nheap && !nheap->used && nheap != heap_end) { - if(pfree == nheap) - pfree = heap; - heap->next = nheap->next; - ((struct mem_heap *)&(((uint8_t *)ram)[nheap->next]))->prev = (uint8_t *)heap - (uint8_t *)ram; - } - pheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->prev]); - if(heap != pheap && !pheap->used) { - if(pfree == heap) - pfree = pheap; - pheap->next = heap->next; - ((struct mem_heap *)&(((uint8_t *)ram)[heap->next]))->prev = (uint8_t *)pheap - (uint8_t *)ram; - } -} - -/** - * Heap initialization - */ -void -easy_heap_init(void) -{ - ram = heap_align(ram_heap); - struct mem_heap *start = (struct mem_heap *)ram; - pfree = start; - start->used = 0; - start->prev = 0; - start->next = HEAP_SIZE; - heap_end = (struct mem_heap *)(ram+HEAP_SIZE+sizeof(struct mem_heap)); - heap_end->prev = 0; - heap_end->next = 0; - heap_end->used = 1; -#ifdef ENABLE_DEBUG - easy_heap_statistics(); -#endif // ENABLE_DEBUG -} - -/** - * Heap alloc - */ -void * -easy_heap_alloc(uint16_t size) -{ -#ifdef ENABLE_DEBUG - easy_assert(size >= 0 && size <= HEAP_SIZE); -#endif // ENABLE_DEBUG - uint8_t ptr, ptr2; - struct mem_heap *mem, *mem2; - - if(ram == NULL) { - ERROR_PRINT("Heap is not initialized\n"); - return NULL; - } - - if(size <= 0) { - ERROR_PRINT("Invalid size of memory\n"); - return NULL; - } - - uint32_t aligned_size = ((size + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT-1)); - if(aligned_size > HEAP_SIZE) { - ERROR_PRINT("Require too much memory\n"); - return NULL; - } - - for(ptr=(uint8_t *)pfree-(uint8_t *)ram; ptrnext) { - mem = (struct mem_heap *)&(((uint8_t *)ram)[ptr]); - if (!(mem->used) && (uint32_t)(mem->next-(ptr+sizeof(struct mem_heap))) >= aligned_size) { - /** - * Now, can alloc memory - * If the remaining free memory after alloc is enough to construct - * a new heap, we split the current heap to two part. Otherwise, - * return the current heap. - */ - if((uint8_t *)(mem->next)-(ptr+sizeof(struct mem_heap)) >= aligned_size+MIN_SIZE_ALIGNED) { - ptr2 = ptr+sizeof(struct mem_heap)+aligned_size; - mem2 = (struct mem_heap *)&(((uint8_t *)ram)[ptr2]); - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - mem->next = ptr2; - if(mem2->next != HEAP_SIZE) - ((struct mem_heap *)&(((uint8_t *)ram)[mem2->next]))->prev = ptr2; - } - mem->used = 1; - - if(mem == pfree) { // update pfree - while(pfree->used && pfree != heap_end) - pfree = (struct mem_heap *)&(((uint8_t *)ram)[pfree->next]); - } - return ((void *)skip_heap_head(mem)); - } - } - - return NULL; -} - -/** - * Heap free - */ -void -easy_heap_free(void *heap) -{ -#ifdef ENABLE_DEBUG - easy_assert(heap != NULL && heap >= ram+sizeof(struct mem_heap) && heap <= sizeof(ram_heap)); -#endif // ENABLE_DEBUG - if(heap == NULL) - return; - - if(heap < ram || heap > ram + HEAP_SIZE) { - ERROR_PRINT("Invalid address\n"); - return; - } - - struct mem_heap *mem = get_heap_head(heap); - mem->used = 0; - if(mem < pfree) - pfree = mem; - - plug_hole(mem); -} - -/** - * Heap realloc - */ -void * -easy_heap_realloc(void *heap, uint16_t size) -{ - easy_heap_free(heap); - return easy_heap_alloc(size); -} - -/** - * Heap statistics - */ -void -easy_heap_statistics(void) -{ - uint32_t total = sizeof(ram_heap); - uint32_t used = 0; - uint32_t remaining = 0; - DEBUG_PRINT("+----- Easy heap memory -----\n"); - DEBUG_PRINT("| Total: %d bytes\n", total); - DEBUG_PRINT("| Can be used: %d bytes\n", HEAP_SIZE); - DEBUG_PRINT("| Used: %d bytes\n", used); - DEBUG_PRINT("| Remaining: %d bytes\n", total-used); - DEBUG_PRINT("| Memory start from: %p\n", ram); - DEBUG_PRINT("+-----------------------\n"); -} +#include "easy_heap.h" +#include "easy_conf.h" +//#include "easy_os.h" + +uint8_t ram_heap[HEAP_SIZE + 2*sizeof(struct mem_heap) + HEAP_ALIGNMENT - 1]; +void *ram; +struct mem_heap *pfree; +struct mem_heap *heap_end; + +/** + * Fill hole + */ +static void +plug_hole(struct mem_heap *heap) +{ + struct mem_heap *nheap, *pheap; + nheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->next]); + if(heap != nheap && !nheap->used && nheap != heap_end) { + if(pfree == nheap) + pfree = heap; + heap->next = nheap->next; + ((struct mem_heap *)&(((uint8_t *)ram)[nheap->next]))->prev = (uint8_t *)heap - (uint8_t *)ram; + } + pheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->prev]); + if(heap != pheap && !pheap->used) { + if(pfree == heap) + pfree = pheap; + pheap->next = heap->next; + ((struct mem_heap *)&(((uint8_t *)ram)[heap->next]))->prev = (uint8_t *)pheap - (uint8_t *)ram; + } +} + +/** + * Heap initialization + */ +void +easy_heap_init(void) +{ + ram = heap_align(ram_heap); + struct mem_heap *start = (struct mem_heap *)ram; + pfree = start; + start->used = 0; + start->prev = 0; + start->next = HEAP_SIZE; + heap_end = (struct mem_heap *)(ram+HEAP_SIZE+sizeof(struct mem_heap)); + heap_end->prev = 0; + heap_end->next = 0; + heap_end->used = 1; +#ifdef ENABLE_DEBUG + easy_heap_statistics(); +#endif // ENABLE_DEBUG +} + +/** + * Heap alloc + */ +void * +easy_heap_alloc(uint16_t size) +{ +#ifdef ENABLE_DEBUG + easy_assert(size >= 0 && size <= HEAP_SIZE); +#endif // ENABLE_DEBUG + uint8_t ptr, ptr2; + struct mem_heap *mem, *mem2; + + if(ram == NULL) { + ERROR_PRINT("Heap is not initialized\n"); + return NULL; + } + + if(size <= 0) { + ERROR_PRINT("Invalid size of memory\n"); + return NULL; + } + + uint32_t aligned_size = ((size + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT-1)); + if(aligned_size > HEAP_SIZE) { + ERROR_PRINT("Require too much memory\n"); + return NULL; + } + + for(ptr=(uint8_t *)pfree-(uint8_t *)ram; ptrnext) { + mem = (struct mem_heap *)&(((uint8_t *)ram)[ptr]); + if (!(mem->used) && (uint32_t)(mem->next-(ptr+sizeof(struct mem_heap))) >= aligned_size) { + /** + * Now, can alloc memory + * If the remaining free memory after alloc is enough to construct + * a new heap, we split the current heap to two part. Otherwise, + * return the current heap. + */ + if((uint8_t *)(mem->next)-(ptr+sizeof(struct mem_heap)) >= aligned_size+MIN_SIZE_ALIGNED) { + ptr2 = ptr+sizeof(struct mem_heap)+aligned_size; + mem2 = (struct mem_heap *)&(((uint8_t *)ram)[ptr2]); + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + mem->next = ptr2; + if(mem2->next != HEAP_SIZE) + ((struct mem_heap *)&(((uint8_t *)ram)[mem2->next]))->prev = ptr2; + } + mem->used = 1; + + if(mem == pfree) { // update pfree + while(pfree->used && pfree != heap_end) + pfree = (struct mem_heap *)&(((uint8_t *)ram)[pfree->next]); + } + return ((void *)skip_heap_head(mem)); + } + } + + return NULL; +} + +/** + * Heap free + */ +void +easy_heap_free(void *heap) +{ +#ifdef ENABLE_DEBUG + easy_assert(heap != NULL && heap >= ram+sizeof(struct mem_heap) && heap <= sizeof(ram_heap)); +#endif // ENABLE_DEBUG + if(heap == NULL) + return; + + if(heap < ram || heap > ram + HEAP_SIZE) { + ERROR_PRINT("Invalid address\n"); + return; + } + + struct mem_heap *mem = get_heap_head(heap); + mem->used = 0; + if(mem < pfree) + pfree = mem; + + plug_hole(mem); +} + +/** + * Heap realloc + */ +void * +easy_heap_realloc(void *heap, uint16_t size) +{ + easy_heap_free(heap); + return easy_heap_alloc(size); +} + +/** + * Heap statistics + */ +void +easy_heap_statistics(void) +{ + uint32_t total = sizeof(ram_heap); + uint32_t used = 0; + uint32_t remaining = 0; + DEBUG_PRINT("+----- Easy heap memory -----\n"); + DEBUG_PRINT("| Total: %d bytes\n", total); + DEBUG_PRINT("| Can be used: %d bytes\n", HEAP_SIZE); + DEBUG_PRINT("| Used: %d bytes\n", used); + DEBUG_PRINT("| Remaining: %d bytes\n", total-used); + DEBUG_PRINT("| Memory start from: %p\n", ram); + DEBUG_PRINT("+-----------------------\n"); +} diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c index 4f71659..8dffa1d 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c @@ -1,175 +1,175 @@ -#include "easy_mem.h" -#include "easy_conf.h" -//#include "easy_os.h" -#include "chain.h" - - -/** - * multiply to make sure there are (2<<(MAX_ORDER+1)-1) heads - */ -uint8_t mem_total[MAX_CHUNK_NUM*MAX_CHUNK_SIZE + layer_heads_size(MAX_ORDER+1) + MEM_ALIGNMENT - 1]; -void *mem_memory = NULL; //alignment memory -struct chunk *mem_heads[MAX_ORDER+1]; - -/** - * Split chunk recursively - */ -static struct chunk * -split(struct chunk *c, uint8_t cnt, uint8_t order) -{ - add_to_head(mem_heads[cnt], c); - c->curr_order = cnt; - struct chunk *buddy = (struct chunk *)((void *)c+layer_size(cnt)+layer_heads_size(cnt+1)); - buddy->next = NULL; - buddy->order = c->order; - buddy->curr_order = c->curr_order; - buddy->used = 0; - - if(cnt > order) { - adjust_head(buddy, 1); - return split(buddy, --cnt, order); - } - buddy->used = 1; - return buddy; -} - -/** - * Merge two free chunks to a larger one recursively - */ -static void -merge(struct chunk *mem_chunk, uint8_t order) -{ - // chunk list is empty, insert directly - if(mem_heads[order] == NULL) { - mem_chunk->used = 0; - mem_heads[order] = mem_chunk; - return; - } - - struct chunk *tmp = mem_heads[order]; - while(tmp != NULL) { - uint32_t length = layer_size(order)+layer_heads_size(order+1); - if(tmp->order == mem_chunk->order) { - // only those two neighboring buddies can be merged - if((void *)mem_chunk == (void *)tmp+length) { - adjust_head(tmp, -1); - merge((struct chunk *)tmp, ++order); - } else if((void *)mem_chunk+length == (void *)tmp) { - adjust_head(mem_chunk, -1); - merge(mem_chunk, ++order); - } else { // cannot merge, add to list head - mem_chunk->used = 0; - add_to_head(mem_heads[order], mem_chunk); - } - return; - } - tmp = tmp->next; - } -} - -/** - * Memory initialization - */ -void -easy_mem_init(void) -{ - mem_memory = (void *)mem_align(mem_total); - mem_heads[MAX_ORDER] = (struct chunk *)mem_memory; - struct chunk *head = mem_heads[MAX_ORDER]; - head->next = NULL; - head->order = MAX_ORDER; - head->curr_order = MAX_ORDER; - head->used = 0; -#ifdef ENABLE_DEBUG - easy_mem_statistics(); -#endif // ENABLE_DEBUG -} - -/** - * Memory alloc - */ -void * -easy_mem_alloc(uint32_t size) -{ -#ifdef ENABLE_DEBUG - easy_assert(size > 0 && size < MAX_CHUNK_NUM * MAX_CHUNK_SIZE && mem_memory != NULL); -#endif // ENABLE_DEBUG - struct chunk *res = NULL; - - if(size < 0 || size > MAX_CHUNK_NUM * MAX_CHUNK_SIZE) { - ERROR_PRINT("Invalid memory size\n"); - goto alloc_failed; - } - - if(mem_memory == NULL) { - ERROR_PRINT("Memory not init\n"); - goto alloc_failed; - } - - uint8_t order = 0; - while(1<used = 1; - remove_from_chain(mem_heads[order], struct chunk, res); - } - - return ((void *)skip_chunk_head(res)); -alloc_failed: - return NULL; -} - -/** - * Memory free - */ -void -easy_mem_free(void *mem) -{ -#ifdef ENABLE_DEBUG - easy_assert(mem != NULL && mem <= mem_memory+sizeof(mem_total) && mem >= mem_memory); -#endif // ENABLE_DEBUG - if(mem == NULL) - return; - - if(mem < mem_memory || mem > mem_memory+sizeof(mem_total)) { - ERROR_PRINT("Invalid memory address"); - return; - } - - struct chunk *head = (struct chunk *)get_chunk_head(mem); - uint8_t curr_order = head->curr_order; - merge(head, curr_order); -} - -/** - * Print system memory statistics - */ -void -easy_mem_statistics(void) -{ - uint32_t total = sizeof(mem_total); - uint32_t used = 0; - uint32_t remaining = 0; - DEBUG_PRINT("+---- Easy chunk memory -----\n"); - DEBUG_PRINT("| Total: %d bytes\n", total); - DEBUG_PRINT("| Can be used: %d bytes\n", MAX_CHUNK_NUM*MAX_CHUNK_SIZE); - DEBUG_PRINT("| Used: %d bytes\n", used); - DEBUG_PRINT("| Remaining: %d bytes\n", total-used); - DEBUG_PRINT("| Memory start from: %p\n", mem_memory); - DEBUG_PRINT("+-----------------------\n"); -} +#include "easy_mem.h" +#include "easy_conf.h" +//#include "easy_os.h" +#include "chain.h" + + +/** + * multiply to make sure there are (2<<(MAX_ORDER+1)-1) heads + */ +uint8_t mem_total[MAX_CHUNK_NUM*MAX_CHUNK_SIZE + layer_heads_size(MAX_ORDER+1) + MEM_ALIGNMENT - 1]; +void *mem_memory = NULL; //alignment memory +struct chunk *mem_heads[MAX_ORDER+1]; + +/** + * Split chunk recursively + */ +static struct chunk * +split(struct chunk *c, uint8_t cnt, uint8_t order) +{ + add_to_head(mem_heads[cnt], c); + c->curr_order = cnt; + struct chunk *buddy = (struct chunk *)((void *)c+layer_size(cnt)+layer_heads_size(cnt+1)); + buddy->next = NULL; + buddy->order = c->order; + buddy->curr_order = c->curr_order; + buddy->used = 0; + + if(cnt > order) { + adjust_head(buddy, 1); + return split(buddy, --cnt, order); + } + buddy->used = 1; + return buddy; +} + +/** + * Merge two free chunks to a larger one recursively + */ +static void +merge(struct chunk *mem_chunk, uint8_t order) +{ + // chunk list is empty, insert directly + if(mem_heads[order] == NULL) { + mem_chunk->used = 0; + mem_heads[order] = mem_chunk; + return; + } + + struct chunk *tmp = mem_heads[order]; + while(tmp != NULL) { + uint32_t length = layer_size(order)+layer_heads_size(order+1); + if(tmp->order == mem_chunk->order) { + // only those two neighboring buddies can be merged + if((void *)mem_chunk == (void *)tmp+length) { + adjust_head(tmp, -1); + merge((struct chunk *)tmp, ++order); + } else if((void *)mem_chunk+length == (void *)tmp) { + adjust_head(mem_chunk, -1); + merge(mem_chunk, ++order); + } else { // cannot merge, add to list head + mem_chunk->used = 0; + add_to_head(mem_heads[order], mem_chunk); + } + return; + } + tmp = tmp->next; + } +} + +/** + * Memory initialization + */ +void +easy_mem_init(void) +{ + mem_memory = (void *)mem_align(mem_total); + mem_heads[MAX_ORDER] = (struct chunk *)mem_memory; + struct chunk *head = mem_heads[MAX_ORDER]; + head->next = NULL; + head->order = MAX_ORDER; + head->curr_order = MAX_ORDER; + head->used = 0; +#ifdef ENABLE_DEBUG + easy_mem_statistics(); +#endif // ENABLE_DEBUG +} + +/** + * Memory alloc + */ +void * +easy_mem_alloc(uint32_t size) +{ +#ifdef ENABLE_DEBUG + easy_assert(size > 0 && size < MAX_CHUNK_NUM * MAX_CHUNK_SIZE && mem_memory != NULL); +#endif // ENABLE_DEBUG + struct chunk *res = NULL; + + if(size < 0 || size > MAX_CHUNK_NUM * MAX_CHUNK_SIZE) { + ERROR_PRINT("Invalid memory size\n"); + goto alloc_failed; + } + + if(mem_memory == NULL) { + ERROR_PRINT("Memory not init\n"); + goto alloc_failed; + } + + uint8_t order = 0; + while(1<used = 1; + remove_from_chain(mem_heads[order], struct chunk, res); + } + + return ((void *)skip_chunk_head(res)); +alloc_failed: + return NULL; +} + +/** + * Memory free + */ +void +easy_mem_free(void *mem) +{ +#ifdef ENABLE_DEBUG + easy_assert(mem != NULL && mem <= mem_memory+sizeof(mem_total) && mem >= mem_memory); +#endif // ENABLE_DEBUG + if(mem == NULL) + return; + + if(mem < mem_memory || mem > mem_memory+sizeof(mem_total)) { + ERROR_PRINT("Invalid memory address"); + return; + } + + struct chunk *head = (struct chunk *)get_chunk_head(mem); + uint8_t curr_order = head->curr_order; + merge(head, curr_order); +} + +/** + * Print system memory statistics + */ +void +easy_mem_statistics(void) +{ + uint32_t total = sizeof(mem_total); + uint32_t used = 0; + uint32_t remaining = 0; + DEBUG_PRINT("+---- Easy chunk memory -----\n"); + DEBUG_PRINT("| Total: %d bytes\n", total); + DEBUG_PRINT("| Can be used: %d bytes\n", MAX_CHUNK_NUM*MAX_CHUNK_SIZE); + DEBUG_PRINT("| Used: %d bytes\n", used); + DEBUG_PRINT("| Remaining: %d bytes\n", total-used); + DEBUG_PRINT("| Memory start from: %p\n", mem_memory); + DEBUG_PRINT("+-----------------------\n"); +} diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/chain.h b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/chain.h index 31bfb13..0c8fed6 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/chain.h +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/chain.h @@ -1,66 +1,66 @@ -/** - * Chain operation - * - * Nicholas3388 - */ - -#ifndef _CHAIN_H_ -#define _CHAIN_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define add_to_head(head, item) { \ - if (head == NULL) { \ - head = item; \ - item->next = NULL; \ - } else { \ - item->next = head; \ - head = item; \ - } \ -} - -#define add_to_tail(head, type, item) { \ - type *pos = head; \ - if(pos == NULL) { \ - head = item; \ - item->next = NULL; \ - } else { \ - while(pos->next != NULL) {pos = pos->next;} \ - pos->next = item; \ - item->next = NULL; \ - } \ -} - -#define chain_cat(chain1, chain2, type) { \ - type *pos = chain1; \ - if(chain1 == NULL) {chain1 = chain2;} \ - if(chain2 != NULL && chain1 != NULL) { \ - while(pos->next != NULL) {pos = pos->next;} \ - pos->next = chain2; \ - } \ -} - -#define remove_from_chain(head, type, item) { \ - type *pos = head; type *prev = NULL; \ - while(pos != NULL) { \ - if(pos == item) { \ - if(prev != NULL) {prev->next = pos->next;} \ - else {head = pos->next;} \ - item->next = NULL; \ - break; \ - } \ - prev = pos; pos = pos->next; \ - } \ -} - -#define is_chain_empty(head) (head == NULL) - -#define foreach(head, iterator) for(iterator=head; iterator!=NULL; iterator=iterator->next) - -#ifdef __cplusplus -} -#endif - -#endif // _CHAIN_H_ +/** + * Chain operation + * + * Nicholas3388 + */ + +#ifndef _CHAIN_H_ +#define _CHAIN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define add_to_head(head, item) { \ + if (head == NULL) { \ + head = item; \ + item->next = NULL; \ + } else { \ + item->next = head; \ + head = item; \ + } \ +} + +#define add_to_tail(head, type, item) { \ + type *pos = head; \ + if(pos == NULL) { \ + head = item; \ + item->next = NULL; \ + } else { \ + while(pos->next != NULL) {pos = pos->next;} \ + pos->next = item; \ + item->next = NULL; \ + } \ +} + +#define chain_cat(chain1, chain2, type) { \ + type *pos = chain1; \ + if(chain1 == NULL) {chain1 = chain2;} \ + if(chain2 != NULL && chain1 != NULL) { \ + while(pos->next != NULL) {pos = pos->next;} \ + pos->next = chain2; \ + } \ +} + +#define remove_from_chain(head, type, item) { \ + type *pos = head; type *prev = NULL; \ + while(pos != NULL) { \ + if(pos == item) { \ + if(prev != NULL) {prev->next = pos->next;} \ + else {head = pos->next;} \ + item->next = NULL; \ + break; \ + } \ + prev = pos; pos = pos->next; \ + } \ +} + +#define is_chain_empty(head) (head == NULL) + +#define foreach(head, iterator) for(iterator=head; iterator!=NULL; iterator=iterator->next) + +#ifdef __cplusplus +} +#endif + +#endif // _CHAIN_H_ diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_conf.h b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_conf.h index 46145d3..c2026e0 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_conf.h +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_conf.h @@ -1,35 +1,35 @@ -/** - * Config for easy_mem - * - * Nicholas3388 - */ - -#ifndef _EASY_CONF_H_ -#define _EASY_CONF_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define ENABLE_DEBUG -//#define HASH_TABLE_CAN_EXTEND -#ifdef HASH_TABLE_CAN_EXTEND -#define EXTEND_THRESHOLD 3 -#endif - -#define DEBUG_PRINT printf -#define ERROR_PRINT printf - -#define EASY_OS_VERSION "1.0.1" - -#define STR(x) VAL(x) -#define VAL(x) #x -#define easy_assert(x) /*((x) ? (void)0 : ERROR_PRINT(__FILE__ ":" STR(__LINE__) " " #x"\n"))*/ - -#ifdef __cplusplus -} -#endif - -#endif // _EASY_CONF_H_ +/** + * Config for easy_mem + * + * Nicholas3388 + */ + +#ifndef _EASY_CONF_H_ +#define _EASY_CONF_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ENABLE_DEBUG +//#define HASH_TABLE_CAN_EXTEND +#ifdef HASH_TABLE_CAN_EXTEND +#define EXTEND_THRESHOLD 3 +#endif + +#define DEBUG_PRINT printf +#define ERROR_PRINT printf + +#define EASY_OS_VERSION "1.0.1" + +#define STR(x) VAL(x) +#define VAL(x) #x +#define easy_assert(x) /*((x) ? (void)0 : ERROR_PRINT(__FILE__ ":" STR(__LINE__) " " #x"\n"))*/ + +#ifdef __cplusplus +} +#endif + +#endif // _EASY_CONF_H_ diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_heap.h b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_heap.h index 4d656e0..7a14c84 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_heap.h +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_heap.h @@ -1,46 +1,46 @@ -/** - * Heap manager like LwIP - * Modified HEAP_SIZE according to your APP - * - * Nicholas3388 - */ - -#ifndef _EASY_HEAP_H_ -#define _EASY_HEAP_H_ - -#include "c_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct mem_heap { - uint16_t prev; - uint16_t next; - uint8_t used; - uint8_t pad[3]; -}; - -#define HEAP_SIZE 1024 -#define HEAP_ALIGNMENT 4 -#define MIN_SIZE_ALIGNED 8 - -#define heap_align(heap) ( \ - (void *)((uint32_t)(heap+HEAP_ALIGNMENT-1) & ~(uint32_t)(HEAP_ALIGNMENT-1)) \ -) - -#define skip_heap_head(c) ((uint8_t *)c + sizeof(struct mem_heap)) -#define get_heap_head(addr) ((struct mem_heap *)((uint8_t *)addr-sizeof(struct mem_heap))) - - -void easy_heap_init(); -void *easy_heap_alloc(uint16_t size); -void easy_heap_free(void *heap); -void *easy_heap_realloc(void *heap, uint16_t size); -void easy_heap_statistics(void); - -#ifdef __cplusplus -} -#endif - -#endif // _EASY_HEAP_H_ +/** + * Heap manager like LwIP + * Modified HEAP_SIZE according to your APP + * + * Nicholas3388 + */ + +#ifndef _EASY_HEAP_H_ +#define _EASY_HEAP_H_ + +#include "c_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct mem_heap { + uint16_t prev; + uint16_t next; + uint8_t used; + uint8_t pad[3]; +}; + +#define HEAP_SIZE 1024 +#define HEAP_ALIGNMENT 4 +#define MIN_SIZE_ALIGNED 8 + +#define heap_align(heap) ( \ + (void *)((uint32_t)(heap+HEAP_ALIGNMENT-1) & ~(uint32_t)(HEAP_ALIGNMENT-1)) \ +) + +#define skip_heap_head(c) ((uint8_t *)c + sizeof(struct mem_heap)) +#define get_heap_head(addr) ((struct mem_heap *)((uint8_t *)addr-sizeof(struct mem_heap))) + + +void easy_heap_init(); +void *easy_heap_alloc(uint16_t size); +void easy_heap_free(void *heap); +void *easy_heap_realloc(void *heap, uint16_t size); +void easy_heap_statistics(void); + +#ifdef __cplusplus +} +#endif + +#endif // _EASY_HEAP_H_ diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_mem.h b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_mem.h index eec0bae..cdb6527 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_mem.h +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/include/easy_mem.h @@ -1,64 +1,64 @@ -/** - * Memory manager based on buddy algorithm - * Modified MAX_ORDER to change the memory used - * - * Nicholas3388 - */ - -#ifndef _EASY_MEM_H_ -#define _EASY_MEM_H_ - -#include "c_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct chunk { - struct chunk *next; - uint8_t order; - uint8_t curr_order; - uint8_t used; - uint8_t pad; -}; - -#define MAX_ORDER 3 -#define MIN_CHUNK_SIZE 8 -#define MAX_CHUNK_SIZE MIN_CHUNK_SIZE * (1<order = h->order; \ - new_head->used = h->used; \ - h = new_head; \ -} - - -void easy_mem_init(void); -void *easy_mem_alloc(uint32_t size); -void easy_mem_free(void *mem); -void easy_mem_statistics(void); - -#ifdef __cplusplus -} -#endif - -#endif // _EASY_MEM_H_ +/** + * Memory manager based on buddy algorithm + * Modified MAX_ORDER to change the memory used + * + * Nicholas3388 + */ + +#ifndef _EASY_MEM_H_ +#define _EASY_MEM_H_ + +#include "c_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct chunk { + struct chunk *next; + uint8_t order; + uint8_t curr_order; + uint8_t used; + uint8_t pad; +}; + +#define MAX_ORDER 3 +#define MIN_CHUNK_SIZE 8 +#define MAX_CHUNK_SIZE MIN_CHUNK_SIZE * (1<order = h->order; \ + new_head->used = h->used; \ + h = new_head; \ +} + + +void easy_mem_init(void); +void *easy_mem_alloc(uint32_t size); +void easy_mem_free(void *mem); +void easy_mem_statistics(void); + +#ifdef __cplusplus +} +#endif + +#endif // _EASY_MEM_H_ diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c b/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c index 109eaaa..1a8a54b 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c @@ -1,1160 +1,1160 @@ - -#include - -#include "lwip/inet.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "dhcpserver.h" - -#define LWIP_OPEN_SRC -#ifndef LWIP_OPEN_SRC -#include "net80211/ieee80211_var.h" -#endif - -#include "esp_wifi.h" -#include "dhcpserver.h" -#include "tcpip_adapter.h" -extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info* ipinfo); -// #include "user_interface.h" -#define NULL_MODE 0xFF -#define DHCP_STARTED 0xFF -#define DHCP_STOPPED 0xFF -extern bool wifi_softap_set_station_info(uint8_t* chaddr, ip_addr_t* ipaddr); -extern void* eagle_lwip_getif(uint8 type); -extern uint8 wifi_softap_dhcps_status(); - -#define ICACHE_FLASH_ATTR -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; -#endif - -//////////////////////////////////////////////////////////////////////////////////// -//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; -//static u8_t old_xid[4] = {0}; -static const uint32 magic_cookie ICACHE_FLASH_ATTR = 0x63538263; -static struct udp_pcb *pcb_dhcps = NULL; -static ip_addr_t broadcast_dhcps; -static ip_addr_t server_address; -static ip_addr_t client_address;//added -static ip_addr_t client_address_plus; - -static struct dhcps_lease dhcps_lease; -//static bool dhcps_lease_flag = true; -static list_node *plist = NULL; -static uint8 offer = 0xFF; -static bool renew = false; -#define DHCPS_LEASE_TIME_DEF (120) -uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute -/****************************************************************************** - * FunctionName : node_insert_to_list - * Description : insert the node to the list - * Parameters : arg -- Additional argument to pass to the callback function - * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert) -{ - list_node *plist = NULL; - struct dhcps_pool *pdhcps_pool = NULL; - struct dhcps_pool *pdhcps_node = NULL; - if (*phead == NULL) - *phead = pinsert; - else { - plist = *phead; - pdhcps_node = pinsert->pnode; - pdhcps_pool = plist->pnode; - - if(pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { - pinsert->pnext = plist; - *phead = pinsert; - } else { - while (plist->pnext != NULL) { - pdhcps_pool = plist->pnext->pnode; - if (pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { - pinsert->pnext = plist->pnext; - plist->pnext = pinsert; - break; - } - plist = plist->pnext; - } - - if(plist->pnext == NULL) { - plist->pnext = pinsert; - } - } - } -// pinsert->pnext = NULL; -} - -/****************************************************************************** - * FunctionName : node_delete_from_list - * Description : remove the node from list - * Parameters : arg -- Additional argument to pass to the callback function - * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR node_remove_from_list_0(list_node **phead, list_node* pdelete) -{ - list_node *plist = NULL; - - plist = *phead; - if (plist == NULL){ - *phead = NULL; - } else { - if (plist == pdelete){ - *phead = plist->pnext; - } else { - while (plist != NULL) { - if (plist->pnext == pdelete){ - plist->pnext = pdelete->pnext; - } - plist = plist->pnext; - } - } - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg��Ϣ�ṹ���������� - * - * @param optptr -- DHCP msg��Ϣλ�� - * @param type -- Ҫ��ӵ�����option - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) -{ - - *optptr++ = DHCP_OPTION_MSG_TYPE; - *optptr++ = 1; - *optptr++ = type; - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg�ṹ������offerӦ������ - * - * @param optptr -- DHCP msg��Ϣλ�� - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) -{ - ip_addr_t ipadd; - - ipadd.u_addr.ip4.addr = *( (uint32_t *) &server_address); - -#ifdef USE_CLASS_B_NET - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; //length - *optptr++ = 255; - *optptr++ = 240; - *optptr++ = 0; - *optptr++ = 0; -#else - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 0; -#endif - - *optptr++ = DHCP_OPTION_LEASE_TIME; - *optptr++ = 4; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; - - *optptr++ = DHCP_OPTION_SERVER_ID; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr4( &ipadd.u_addr.ip4); - - if (dhcps_router_enabled(offer)){ - struct ip_info if_ip; - bzero(&if_ip, sizeof(struct ip_info)); - wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &if_ip); - - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = 4; - *optptr++ = ip4_addr1( &if_ip.gw); - *optptr++ = ip4_addr2( &if_ip.gw); - *optptr++ = ip4_addr3( &if_ip.gw); - *optptr++ = ip4_addr4( &if_ip.gw); - } - -#ifdef USE_DNS - *optptr++ = DHCP_OPTION_DNS_SERVER; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr4( &ipadd.u_addr.ip4); -#endif - -#ifdef CLASS_B_NET - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd); - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 255; -#else - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); - *optptr++ = 255; -#endif - - *optptr++ = DHCP_OPTION_INTERFACE_MTU; - *optptr++ = 2; -#ifdef CLASS_B_NET - *optptr++ = 0x05; - *optptr++ = 0xdc; -#else - *optptr++ = 0x02; - *optptr++ = 0x40; -#endif - - *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; - *optptr++ = 1; - *optptr++ = 0x00; - - *optptr++ = 43; - *optptr++ = 6; - - *optptr++ = 0x01; - *optptr++ = 4; - *optptr++ = 0x00; - *optptr++ = 0x00; - *optptr++ = 0x00; - *optptr++ = 0x02; - - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ��DHCP msg�ṹ����ӽ����־���� - * - * @param optptr -- DHCP msg��Ϣλ�� - * - * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr) -{ - - *optptr++ = DHCP_OPTION_END; - return optptr; -} -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) -{ - ip_addr_t client; - - client.u_addr.ip4.addr = *( (uint32_t *) &client_address); - - m->op = DHCP_REPLY; - m->htype = DHCP_HTYPE_ETHERNET; - m->hlen = 6; - m->hops = 0; -// memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); - m->secs = 0; - m->flags = htons(BOOTP_BROADCAST); - - memcpy((char *) m->yiaddr, (char *) &client.u_addr.ip4.addr, sizeof(m->yiaddr)); - - memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); - memset((char *) m->siaddr, 0, sizeof(m->siaddr)); - memset((char *) m->giaddr, 0, sizeof(m->giaddr)); - memset((char *) m->sname, 0, sizeof(m->sname)); - memset((char *) m->file, 0, sizeof(m->file)); - - memset((char *) m->options, 0, sizeof(m->options)); - memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie)); -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��OFFER - * - * @param -- m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) -{ - uint8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendOffer_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPOFFER); - end = add_offer_options(end); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); -#if DHCPS_DEBUG - printf("udhcp: send_offer>>p->ref = %d\n", p->ref); -#endif - if(p != NULL){ - -#if DHCPS_DEBUG - printf("dhcps: send_offer>>pbuf_alloc succeed\n"); - printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_offer>>p->len = %d\n", p->len); -#endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } -#endif - } - - q = q->next; - } - }else{ - -#if DHCPS_DEBUG - printf("dhcps: send_offer>>pbuf_alloc failed\n"); -#endif - return; - } - SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); -#if DHCPS_DEBUG - printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); -#endif - if(p->ref != 0){ -#if DHCPS_DEBUG - printf("udhcp: send_offer>>free pbuf\n"); -#endif - pbuf_free(p); - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��NAK��Ϣ - * - * @param m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) -{ - - u8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendNak_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPNAK); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); -#if DHCPS_DEBUG - printf("udhcp: send_nak>>p->ref = %d\n", p->ref); -#endif - if(p != NULL){ - -#if DHCPS_DEBUG - printf("dhcps: send_nak>>pbuf_alloc succeed\n"); - printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_nak>>p->len = %d\n", p->len); -#endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } -#endif - } - - q = q->next; - } - }else{ - -#if DHCPS_DEBUG - printf("dhcps: send_nak>>pbuf_alloc failed\n"); -#endif - return; - } - SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); -#if DHCPS_DEBUG - printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); -#endif - if(p->ref != 0){ -#if DHCPS_DEBUG - printf("udhcp: send_nak>>free pbuf\n"); -#endif - pbuf_free(p); - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����һ��ACK��DHCP�ͻ��� - * - * @param m ָ����Ҫ���͵�DHCP msg���� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) -{ - - u8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendAck_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPACK); - end = add_offer_options(end); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); -#if DHCPS_DEBUG - printf("udhcp: send_ack>>p->ref = %d\n", p->ref); -#endif - if(p != NULL){ - -#if DHCPS_DEBUG - printf("dhcps: send_ack>>pbuf_alloc succeed\n"); - printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_ack>>p->len = %d\n", p->len); -#endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } -#endif - } - - q = q->next; - } - }else{ - -#if DHCPS_DEBUG - printf("dhcps: send_ack>>pbuf_alloc failed\n"); -#endif - return; - } - SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); -#if DHCPS_DEBUG - printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); -#endif - - if(p->ref != 0){ -#if DHCPS_DEBUG - printf("udhcp: send_ack>>free pbuf\n"); -#endif - pbuf_free(p); - } -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ�� - * - * @param optptr DHCP msg�е��������� - * @param len ��������Ĵ��?(byte) - * - * @return uint8_t ���ش�����DHCP Server״ֵ̬ - */ -/////////////////////////////////////////////////////////////////////////////////// -static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) -{ - ip_addr_t client; - bool is_dhcp_parse_end = false; - struct dhcps_state s; - - client.u_addr.ip4.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP - - u8_t *end = optptr + len; - u16_t type = 0; - - s.state = DHCPS_STATE_IDLE; - - while (optptr < end) { -#if DHCPS_DEBUG - printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); -#endif - switch ((sint16_t) *optptr) { - - case DHCP_OPTION_MSG_TYPE: //53 - type = *(optptr + 2); - break; - - case DHCP_OPTION_REQ_IPADDR://50 - if( memcmp( (char *) &client.u_addr.ip4.addr, (char *) optptr+2,4)==0 ) { -#if DHCPS_DEBUG - printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); -#endif - s.state = DHCPS_STATE_ACK; - }else { -#if DHCPS_DEBUG - printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); -#endif - s.state = DHCPS_STATE_NAK; - } - break; - case DHCP_OPTION_END: - { - is_dhcp_parse_end = true; - } - break; - } - - if(is_dhcp_parse_end){ - break; - } - - optptr += optptr[1] + 2; - } - - switch (type){ - - case DHCPDISCOVER://1 - s.state = DHCPS_STATE_OFFER; -#if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_OFFER\n"); -#endif - break; - - case DHCPREQUEST://3 - if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) { - if(renew == true) { - s.state = DHCPS_STATE_ACK; - } else { - s.state = DHCPS_STATE_NAK; - } -#if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_NAK\n"); -#endif - } - break; - - case DHCPDECLINE://4 - s.state = DHCPS_STATE_IDLE; -#if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_IDLE\n"); -#endif - break; - - case DHCPRELEASE://7 - s.state = DHCPS_STATE_RELEASE; -#if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_IDLE\n"); -#endif - break; - } -#if DHCPS_DEBUG - printf("dhcps: return s.state = %d\n", s.state); -#endif - return s.state; -} -/////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////// -static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) -{ - if(memcmp((char *)m->options, - &magic_cookie, - sizeof(magic_cookie)) == 0){ -#if DHCPS_DEBUG - printf("dhcps: len = %d\n", len); -#endif - /* - * ��¼��ǰ��xid���ﴦ���? - * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� - */ -// if((old_xid[0] == 0) && -// (old_xid[1] == 0) && -// (old_xid[2] == 0) && -// (old_xid[3] == 0)){ -// /* -// * old_xidδ��¼�κ����? -// * �϶��ǵ�һ��ʹ�� -// */ -// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); -// }else{ -// /* -// * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� -// * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP -// * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) -// * -// */ -// if(memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ - /* - * ��¼���ε�xid�ţ�ͬʱ�����IP���� - */ - ip_addr_t addr_tmp; -// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); - -// { - struct dhcps_pool *pdhcps_pool = NULL; - list_node *pnode = NULL; - list_node *pback_node = NULL; - ip_addr_t first_address; - bool flag = false; - -// POOL_START: - first_address.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; - renew = false; -// addr_tmp.addr = htonl(client_address_plus.addr); -// addr_tmp.addr++; -// client_address_plus.addr = htonl(addr_tmp.addr); - for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { - pdhcps_pool = pback_node->pnode; - if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){ -// printf("the same device request ip\n"); - if (memcmp(&pdhcps_pool->ip.u_addr.ip4.addr, m->ciaddr, sizeof(pdhcps_pool->ip.u_addr.ip4.addr)) == 0) { - renew = true; - } - client_address.u_addr.ip4.addr = pdhcps_pool->ip.u_addr.ip4.addr; - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; - pnode = pback_node; - goto POOL_CHECK; - } else if (pdhcps_pool->ip.u_addr.ip4.addr == client_address_plus.u_addr.ip4.addr){ -// client_address.addr = client_address_plus.addr; -// printf("the ip addr has been request\n"); - addr_tmp.u_addr.ip4.addr = htonl(client_address_plus.u_addr.ip4.addr); - addr_tmp.u_addr.ip4.addr++; - client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); - client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; - } - - if(flag == false) { // search the fisrt unused ip - if(first_address.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { - flag = true; - } else { - addr_tmp.u_addr.ip4.addr = htonl(first_address.u_addr.ip4.addr); - addr_tmp.u_addr.ip4.addr++; - first_address.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); - } - } - } - if (client_address_plus.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) { - client_address.u_addr.ip4.addr = first_address.u_addr.ip4.addr; - } - if (client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) { - client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - pdhcps_pool = NULL; - pnode = NULL; - } else { - pdhcps_pool = (struct dhcps_pool *)malloc(sizeof(struct dhcps_pool)); - pdhcps_pool->ip.u_addr.ip4.addr = client_address.u_addr.ip4.addr; - memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; - pnode = (list_node *)malloc(sizeof(list_node )); - pnode->pnode = pdhcps_pool; - pnode->pnext = NULL; - node_insert_to_list(&plist,pnode); - if (client_address.u_addr.ip4.addr == dhcps_lease.end_ip.u_addr.ip4.addr) { - client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - } else { - addr_tmp.u_addr.ip4.addr = htonl(client_address.u_addr.ip4.addr); - addr_tmp.u_addr.ip4.addr++; - client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); - } - } - - POOL_CHECK: - if ((client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) || (ip_addr_isany(&client_address))){ - printf("client_address_plus.addr %x\n", client_address_plus.u_addr.ip4.addr); - if(pnode != NULL) { - node_remove_from_list_0(&plist,pnode); - free(pnode); - pnode = NULL; - } - - if (pdhcps_pool != NULL) { - free(pdhcps_pool); - pdhcps_pool = NULL; - } -// client_address_plus.addr = dhcps_lease.start_ip.addr; - return 4; - } - - sint16_t ret = parse_options(&m->options[4], len);; - - if(ret == DHCPS_STATE_RELEASE) { - if(pnode != NULL) { - node_remove_from_list_0(&plist,pnode); - free(pnode); - pnode = NULL; - } - - if (pdhcps_pool != NULL) { - free(pdhcps_pool); - pdhcps_pool = NULL; - } - memset(&client_address,0x0,sizeof(client_address)); - } - - if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { - return 0; - } -// } - -#if DHCPS_DEBUG - printf("dhcps: xid changed\n"); - printf("dhcps: client_address.addr = %x\n", client_address.addr); -#endif - -// } - -// } - return ret; - } - return 0; -} -/////////////////////////////////////////////////////////////////////////////////// -/* - * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������ - * ��Ҫ����udp_recv()������LWIP����ע��. - * - * @param arg - * @param pcb ���յ�UDP��Ŀ��ƿ�? - * @param p ���յ���UDP�е��������? - * @param addr ���ʹ�UDP���Դ�����IP��ַ - * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� - */ -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, - struct udp_pcb *pcb, - struct pbuf *p, - const ip_addr_t *addr, - uint16_t port) -{ - struct dhcps_msg *pmsg_dhcps = NULL; - sint16_t tlen = 0; - u16_t i = 0; - u16_t dhcps_msg_cnt = 0; - u8_t *p_dhcps_msg = NULL; - u8_t *data = NULL; - -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> receive a packet\n"); -#endif - if (p==NULL) return; - - pmsg_dhcps = (struct dhcps_msg *)malloc(sizeof(struct dhcps_msg)); - if (NULL == pmsg_dhcps){ - pbuf_free(p); - return; - } - p_dhcps_msg = (u8_t *)pmsg_dhcps; - tlen = p->tot_len; - data = p->payload; - -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); - printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); -#endif - - for(i=0; ilen; i++){ - p_dhcps_msg[dhcps_msg_cnt++] = data[i]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } -#endif - } - - if(p->next != NULL) { -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> p->next != NULL\n"); - printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len); - printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); -#endif - - data = p->next->payload; - for(i=0; inext->len; i++){ - p_dhcps_msg[dhcps_msg_cnt++] = data[i]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } -#endif - } - } - - /* - * DHCP �ͻ���������Ϣ���� - */ -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> parse_msg(p)\n"); -#endif - - switch(parse_msg(pmsg_dhcps, tlen - 240)) { - - case DHCPS_STATE_OFFER://1 -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); -#endif - send_offer(pmsg_dhcps); - break; - case DHCPS_STATE_ACK://3 -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); -#endif - send_ack(pmsg_dhcps); - break; - case DHCPS_STATE_NAK://4 -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); -#endif - send_nak(pmsg_dhcps); - break; - default : - break; - } -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); -#endif - pbuf_free(p); - free(pmsg_dhcps); - pmsg_dhcps = NULL; -} -/////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip) -{ - uint32 softap_ip = 0,local_ip = 0; - uint32 start_ip = 0; - uint32 end_ip = 0; -// if (dhcps_lease_flag) { - if (dhcps_lease.enable == true) { - softap_ip = htonl(ip); - start_ip = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); - end_ip = htonl(dhcps_lease.end_ip.u_addr.ip4.addr); - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { - dhcps_lease.enable = false; - } else { - /*config ip information must be in the same segment as the local ip*/ - softap_ip >>= 8; - if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) - || (end_ip - start_ip > DHCPS_MAX_LEASE)) { - dhcps_lease.enable = false; - } - } - } - - if (dhcps_lease.enable == false) { - local_ip = softap_ip = htonl(ip); - softap_ip &= 0xFFFFFF00; - local_ip &= 0xFF; - if (local_ip >= 0x80) - local_ip -= DHCPS_MAX_LEASE; - else - local_ip ++; - - bzero(&dhcps_lease, sizeof(dhcps_lease)); - dhcps_lease.start_ip.u_addr.ip4.addr = softap_ip | local_ip; - dhcps_lease.end_ip.u_addr.ip4.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); - dhcps_lease.start_ip.u_addr.ip4.addr = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); - dhcps_lease.end_ip.u_addr.ip4.addr= htonl(dhcps_lease.end_ip.u_addr.ip4.addr); - } -// dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); -// dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); -// printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); -} -/////////////////////////////////////////////////////////////////////////////////// -void ICACHE_FLASH_ATTR espconn_dhcps_start(struct ip_info *info) -{ - struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); - - if(apnetif->dhcps_pcb != NULL) { - udp_remove(apnetif->dhcps_pcb); - } - - pcb_dhcps = udp_new(); - if (pcb_dhcps == NULL || info ==NULL) { - printf("dhcps_start(): could not obtain pcb\n"); - } - - apnetif->dhcps_pcb = pcb_dhcps; - - IP4_ADDR(&broadcast_dhcps.u_addr.ip4, 255, 255, 255, 255); - - server_address.u_addr.ip4.addr = info->ip.addr; - wifi_softap_init_dhcps_lease(server_address.u_addr.ip4.addr); - client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - - udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); - - udp_recv(pcb_dhcps, &handle_dhcp, NULL); -#if DHCPS_DEBUG - printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); -#endif - -} - -void ICACHE_FLASH_ATTR espconn_dhcps_stop(void) -{ - struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); - - udp_disconnect(pcb_dhcps); -// dhcps_lease_flag = true; - if(apnetif->dhcps_pcb != NULL) { - udp_remove(apnetif->dhcps_pcb); - apnetif->dhcps_pcb = NULL; - } - - //udp_remove(pcb_dhcps); - list_node *pnode = NULL; - list_node *pback_node = NULL; - pnode = plist; - while (pnode != NULL) { - pback_node = pnode; - pnode = pback_node->pnext; - node_remove_from_list_0(&plist, pback_node); - free(pback_node->pnode); - pback_node->pnode = NULL; - free(pback_node); - pback_node = NULL; - } -} - -/****************************************************************************** - * FunctionName : wifi_softap_set_dhcps_lease - * Description : set the lease information of DHCP server - * Parameters : please -- Additional argument to set the lease information, - * Little-Endian. - * Returns : true or false -*******************************************************************************/ -bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) -{ - struct ip_info info; - uint32 softap_ip = 0; - uint32 start_ip = 0; - uint32 end_ip = 0; - - uint8 opmode = esp_wifi_get_mode(NULL); - - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { - return false; - } - - if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) - return false; - - if(please->enable) { - bzero(&info, sizeof(struct ip_info)); - wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &info); - softap_ip = htonl(info.ip.addr); - start_ip = htonl(please->start_ip.u_addr.ip4.addr); - end_ip = htonl(please->end_ip.u_addr.ip4.addr); - - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) - return false; - - /*config ip information must be in the same segment as the local ip*/ - softap_ip >>= 8; - if ((start_ip >> 8 != softap_ip) - || (end_ip >> 8 != softap_ip)) { - return false; - } - - if (end_ip - start_ip > DHCPS_MAX_LEASE) - return false; - - bzero(&dhcps_lease, sizeof(dhcps_lease)); -// dhcps_lease.start_ip.addr = start_ip; -// dhcps_lease.end_ip.addr = end_ip; - dhcps_lease.start_ip.u_addr.ip4.addr = please->start_ip.u_addr.ip4.addr; - dhcps_lease.end_ip.u_addr.ip4.addr = please->end_ip.u_addr.ip4.addr; - } - dhcps_lease.enable = please->enable; -// dhcps_lease_flag = false; - return true; -} - -/****************************************************************************** - * FunctionName : wifi_softap_get_dhcps_lease - * Description : get the lease information of DHCP server - * Parameters : please -- Additional argument to get the lease information, - * Little-Endian. - * Returns : true or false -*******************************************************************************/ -bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please) -{ - uint8 opmode = esp_wifi_get_mode(NULL); - - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { - return false; - } - - if (NULL == please) - return false; - -// if (dhcps_lease_flag){ - if (dhcps_lease.enable == false){ - if (wifi_softap_dhcps_status() == DHCP_STOPPED) - return false; - } else { -// bzero(please, sizeof(dhcps_lease)); -// if (wifi_softap_dhcps_status() == DHCP_STOPPED){ -// please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); -// please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); -// } - } - -// if (wifi_softap_dhcps_status() == DHCP_STARTED){ -// bzero(please, sizeof(dhcps_lease)); -// please->start_ip.addr = dhcps_lease.start_ip.addr; -// please->end_ip.addr = dhcps_lease.end_ip.addr; -// } - please->start_ip.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - please->end_ip.u_addr.ip4.addr = dhcps_lease.end_ip.u_addr.ip4.addr; - return true; -} - -static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void) -{ - list_node *pre = NULL, *p = NULL; - list_node *minpre = NULL, *minp = NULL; - struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; - pre = plist; - p = pre->pnext; - minpre = pre; - minp = p; - while (p != NULL){ - pdhcps_pool = p->pnode; - pmin_pool = minp->pnode; - if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){ - minp = p; - minpre = pre; - } - pre = p; - p = p->pnext; - } - minpre->pnext = minp->pnext; - free(minp->pnode); - minp->pnode = NULL; - free(minp); - minp = NULL; -} - -void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) -{ - uint8 num_dhcps_pool = 0; - list_node *pback_node = NULL; - list_node *pnode = NULL; - struct dhcps_pool *pdhcps_pool = NULL; - pnode = plist; - while (pnode != NULL) { - pdhcps_pool = pnode->pnode; - pdhcps_pool->lease_timer --; - if (pdhcps_pool->lease_timer == 0){ - pback_node = pnode; - pnode = pback_node->pnext; - node_remove_from_list_0(&plist,pback_node); - free(pback_node->pnode); - pback_node->pnode = NULL; - free(pback_node); - pback_node = NULL; - } else { - pnode = pnode ->pnext; - num_dhcps_pool ++; - } - } - - if (num_dhcps_pool >= MAX_STATION_NUM) - kill_oldest_dhcps_pool(); -} - -bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) -{ - bool offer_flag = true; - uint8 option = 0; - if (optarg == NULL && wifi_softap_dhcps_status() == false) - return false; - - if (level <= OFFER_START || level >= OFFER_END) - return false; - - switch (level){ - case OFFER_ROUTER: - offer = (*(uint8 *)optarg) & 0x01; - offer_flag = true; - break; - default : - offer_flag = false; - break; - } - return offer_flag; -} - -bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute) -{ - uint8 opmode = esp_wifi_get_mode(NULL); - - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { - return false; - } - - if (wifi_softap_dhcps_status() == DHCP_STARTED) { - return false; - } - - if(minute == 0) { - return false; - } - dhcps_lease_time = minute; - return true; -} - -bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void) -{ - uint8 opmode = esp_wifi_get_mode(NULL); - - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { - return false; - } - - if (wifi_softap_dhcps_status() == DHCP_STARTED) { - return false; - } - dhcps_lease_time = DHCPS_LEASE_TIME_DEF; - return true; -} - -uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute -{ - return dhcps_lease_time; -} + +#include + +#include "lwip/inet.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "dhcpserver.h" + +#define LWIP_OPEN_SRC +#ifndef LWIP_OPEN_SRC +#include "net80211/ieee80211_var.h" +#endif + +#include "esp_wifi.h" +#include "dhcpserver.h" +#include "tcpip_adapter.h" +extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info* ipinfo); +// #include "user_interface.h" +#define NULL_MODE 0xFF +#define DHCP_STARTED 0xFF +#define DHCP_STOPPED 0xFF +extern bool wifi_softap_set_station_info(uint8_t* chaddr, ip_addr_t* ipaddr); +extern void* eagle_lwip_getif(uint8 type); +extern uint8 wifi_softap_dhcps_status(); + +#define ICACHE_FLASH_ATTR +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + +//////////////////////////////////////////////////////////////////////////////////// +//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; +//static u8_t old_xid[4] = {0}; +static const uint32 magic_cookie ICACHE_FLASH_ATTR = 0x63538263; +static struct udp_pcb *pcb_dhcps = NULL; +static ip_addr_t broadcast_dhcps; +static ip_addr_t server_address; +static ip_addr_t client_address;//added +static ip_addr_t client_address_plus; + +static struct dhcps_lease dhcps_lease; +//static bool dhcps_lease_flag = true; +static list_node *plist = NULL; +static uint8 offer = 0xFF; +static bool renew = false; +#define DHCPS_LEASE_TIME_DEF (120) +uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute +/****************************************************************************** + * FunctionName : node_insert_to_list + * Description : insert the node to the list + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert) +{ + list_node *plist = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + struct dhcps_pool *pdhcps_node = NULL; + if (*phead == NULL) + *phead = pinsert; + else { + plist = *phead; + pdhcps_node = pinsert->pnode; + pdhcps_pool = plist->pnode; + + if(pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { + pinsert->pnext = plist; + *phead = pinsert; + } else { + while (plist->pnext != NULL) { + pdhcps_pool = plist->pnext->pnode; + if (pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { + pinsert->pnext = plist->pnext; + plist->pnext = pinsert; + break; + } + plist = plist->pnext; + } + + if(plist->pnext == NULL) { + plist->pnext = pinsert; + } + } + } +// pinsert->pnext = NULL; +} + +/****************************************************************************** + * FunctionName : node_delete_from_list + * Description : remove the node from list + * Parameters : arg -- Additional argument to pass to the callback function + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR node_remove_from_list_0(list_node **phead, list_node* pdelete) +{ + list_node *plist = NULL; + + plist = *phead; + if (plist == NULL){ + *phead = NULL; + } else { + if (plist == pdelete){ + *phead = plist->pnext; + } else { + while (plist != NULL) { + if (plist->pnext == pdelete){ + plist->pnext = pdelete->pnext; + } + plist = plist->pnext; + } + } + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ��DHCP msg��Ϣ�ṹ���������� + * + * @param optptr -- DHCP msg��Ϣλ�� + * @param type -- Ҫ��ӵ�����option + * + * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) +{ + + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ��DHCP msg�ṹ������offerӦ������ + * + * @param optptr -- DHCP msg��Ϣλ�� + * + * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) +{ + ip_addr_t ipadd; + + ipadd.u_addr.ip4.addr = *( (uint32_t *) &server_address); + +#ifdef USE_CLASS_B_NET + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = 4; //length + *optptr++ = 255; + *optptr++ = 240; + *optptr++ = 0; + *optptr++ = 0; +#else + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = 4; + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 0; +#endif + + *optptr++ = DHCP_OPTION_LEASE_TIME; + *optptr++ = 4; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; + + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr4( &ipadd.u_addr.ip4); + + if (dhcps_router_enabled(offer)){ + struct ip_info if_ip; + bzero(&if_ip, sizeof(struct ip_info)); + wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &if_ip); + + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = 4; + *optptr++ = ip4_addr1( &if_ip.gw); + *optptr++ = ip4_addr2( &if_ip.gw); + *optptr++ = ip4_addr3( &if_ip.gw); + *optptr++ = ip4_addr4( &if_ip.gw); + } + +#ifdef USE_DNS + *optptr++ = DHCP_OPTION_DNS_SERVER; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr4( &ipadd.u_addr.ip4); +#endif + +#ifdef CLASS_B_NET + *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd); + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 255; +#else + *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; + *optptr++ = 4; + *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); + *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); + *optptr++ = 255; +#endif + + *optptr++ = DHCP_OPTION_INTERFACE_MTU; + *optptr++ = 2; +#ifdef CLASS_B_NET + *optptr++ = 0x05; + *optptr++ = 0xdc; +#else + *optptr++ = 0x02; + *optptr++ = 0x40; +#endif + + *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; + *optptr++ = 1; + *optptr++ = 0x00; + + *optptr++ = 43; + *optptr++ = 6; + + *optptr++ = 0x01; + *optptr++ = 4; + *optptr++ = 0x00; + *optptr++ = 0x00; + *optptr++ = 0x00; + *optptr++ = 0x02; + + return optptr; +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ��DHCP msg�ṹ����ӽ����־���� + * + * @param optptr -- DHCP msg��Ϣλ�� + * + * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr) +{ + + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) +{ + ip_addr_t client; + + client.u_addr.ip4.addr = *( (uint32_t *) &client_address); + + m->op = DHCP_REPLY; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = 6; + m->hops = 0; +// memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); + m->secs = 0; + m->flags = htons(BOOTP_BROADCAST); + + memcpy((char *) m->yiaddr, (char *) &client.u_addr.ip4.addr, sizeof(m->yiaddr)); + + memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); + memset((char *) m->siaddr, 0, sizeof(m->siaddr)); + memset((char *) m->giaddr, 0, sizeof(m->giaddr)); + memset((char *) m->sname, 0, sizeof(m->sname)); + memset((char *) m->file, 0, sizeof(m->file)); + + memset((char *) m->options, 0, sizeof(m->options)); + memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie)); +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����һ��OFFER + * + * @param -- m ָ����Ҫ���͵�DHCP msg���� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) +{ + uint8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt=0; + u16_t i; + err_t SendOffer_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPOFFER); + end = add_offer_options(end); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); +#if DHCPS_DEBUG + printf("udhcp: send_offer>>p->ref = %d\n", p->ref); +#endif + if(p != NULL){ + +#if DHCPS_DEBUG + printf("dhcps: send_offer>>pbuf_alloc succeed\n"); + printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); + printf("dhcps: send_offer>>p->len = %d\n", p->len); +#endif + q = p; + while(q != NULL){ + data = (u8_t *)q->payload; + for(i=0; ilen; i++) + { + data[i] = ((u8_t *) m)[cnt++]; +#if DHCPS_DEBUG + printf("%02x ",data[i]); + if((i+1)%16 == 0){ + printf("\n"); + } +#endif + } + + q = q->next; + } + }else{ + +#if DHCPS_DEBUG + printf("dhcps: send_offer>>pbuf_alloc failed\n"); +#endif + return; + } + SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); +#if DHCPS_DEBUG + printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); +#endif + if(p->ref != 0){ +#if DHCPS_DEBUG + printf("udhcp: send_offer>>free pbuf\n"); +#endif + pbuf_free(p); + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����һ��NAK��Ϣ + * + * @param m ָ����Ҫ���͵�DHCP msg���� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) +{ + + u8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt=0; + u16_t i; + err_t SendNak_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPNAK); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); +#if DHCPS_DEBUG + printf("udhcp: send_nak>>p->ref = %d\n", p->ref); +#endif + if(p != NULL){ + +#if DHCPS_DEBUG + printf("dhcps: send_nak>>pbuf_alloc succeed\n"); + printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); + printf("dhcps: send_nak>>p->len = %d\n", p->len); +#endif + q = p; + while(q != NULL){ + data = (u8_t *)q->payload; + for(i=0; ilen; i++) + { + data[i] = ((u8_t *) m)[cnt++]; +#if DHCPS_DEBUG + printf("%02x ",data[i]); + if((i+1)%16 == 0){ + printf("\n"); + } +#endif + } + + q = q->next; + } + }else{ + +#if DHCPS_DEBUG + printf("dhcps: send_nak>>pbuf_alloc failed\n"); +#endif + return; + } + SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); +#if DHCPS_DEBUG + printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); +#endif + if(p->ref != 0){ +#if DHCPS_DEBUG + printf("udhcp: send_nak>>free pbuf\n"); +#endif + pbuf_free(p); + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����һ��ACK��DHCP�ͻ��� + * + * @param m ָ����Ҫ���͵�DHCP msg���� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) +{ + + u8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt=0; + u16_t i; + err_t SendAck_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPACK); + end = add_offer_options(end); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); +#if DHCPS_DEBUG + printf("udhcp: send_ack>>p->ref = %d\n", p->ref); +#endif + if(p != NULL){ + +#if DHCPS_DEBUG + printf("dhcps: send_ack>>pbuf_alloc succeed\n"); + printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); + printf("dhcps: send_ack>>p->len = %d\n", p->len); +#endif + q = p; + while(q != NULL){ + data = (u8_t *)q->payload; + for(i=0; ilen; i++) + { + data[i] = ((u8_t *) m)[cnt++]; +#if DHCPS_DEBUG + printf("%02x ",data[i]); + if((i+1)%16 == 0){ + printf("\n"); + } +#endif + } + + q = q->next; + } + }else{ + +#if DHCPS_DEBUG + printf("dhcps: send_ack>>pbuf_alloc failed\n"); +#endif + return; + } + SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); +#if DHCPS_DEBUG + printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); +#endif + + if(p->ref != 0){ +#if DHCPS_DEBUG + printf("udhcp: send_ack>>free pbuf\n"); +#endif + pbuf_free(p); + } +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * ����DHCP�ͻ��˷�����DHCP����������Ϣ�����Բ�ͬ��DHCP��������������Ӧ��Ӧ�� + * + * @param optptr DHCP msg�е��������� + * @param len ��������Ĵ��?(byte) + * + * @return uint8_t ���ش�����DHCP Server״ֵ̬ + */ +/////////////////////////////////////////////////////////////////////////////////// +static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) +{ + ip_addr_t client; + bool is_dhcp_parse_end = false; + struct dhcps_state s; + + client.u_addr.ip4.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP + + u8_t *end = optptr + len; + u16_t type = 0; + + s.state = DHCPS_STATE_IDLE; + + while (optptr < end) { +#if DHCPS_DEBUG + printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); +#endif + switch ((sint16_t) *optptr) { + + case DHCP_OPTION_MSG_TYPE: //53 + type = *(optptr + 2); + break; + + case DHCP_OPTION_REQ_IPADDR://50 + if( memcmp( (char *) &client.u_addr.ip4.addr, (char *) optptr+2,4)==0 ) { +#if DHCPS_DEBUG + printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); +#endif + s.state = DHCPS_STATE_ACK; + }else { +#if DHCPS_DEBUG + printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); +#endif + s.state = DHCPS_STATE_NAK; + } + break; + case DHCP_OPTION_END: + { + is_dhcp_parse_end = true; + } + break; + } + + if(is_dhcp_parse_end){ + break; + } + + optptr += optptr[1] + 2; + } + + switch (type){ + + case DHCPDISCOVER://1 + s.state = DHCPS_STATE_OFFER; +#if DHCPS_DEBUG + printf("dhcps: DHCPD_STATE_OFFER\n"); +#endif + break; + + case DHCPREQUEST://3 + if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) { + if(renew == true) { + s.state = DHCPS_STATE_ACK; + } else { + s.state = DHCPS_STATE_NAK; + } +#if DHCPS_DEBUG + printf("dhcps: DHCPD_STATE_NAK\n"); +#endif + } + break; + + case DHCPDECLINE://4 + s.state = DHCPS_STATE_IDLE; +#if DHCPS_DEBUG + printf("dhcps: DHCPD_STATE_IDLE\n"); +#endif + break; + + case DHCPRELEASE://7 + s.state = DHCPS_STATE_RELEASE; +#if DHCPS_DEBUG + printf("dhcps: DHCPD_STATE_IDLE\n"); +#endif + break; + } +#if DHCPS_DEBUG + printf("dhcps: return s.state = %d\n", s.state); +#endif + return s.state; +} +/////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////// +static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) +{ + if(memcmp((char *)m->options, + &magic_cookie, + sizeof(magic_cookie)) == 0){ +#if DHCPS_DEBUG + printf("dhcps: len = %d\n", len); +#endif + /* + * ��¼��ǰ��xid���ﴦ���? + * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� + */ +// if((old_xid[0] == 0) && +// (old_xid[1] == 0) && +// (old_xid[2] == 0) && +// (old_xid[3] == 0)){ +// /* +// * old_xidδ��¼�κ����? +// * �϶��ǵ�һ��ʹ�� +// */ +// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); +// }else{ +// /* +// * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� +// * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP +// * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) +// * +// */ +// if(memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ + /* + * ��¼���ε�xid�ţ�ͬʱ�����IP���� + */ + ip_addr_t addr_tmp; +// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); + +// { + struct dhcps_pool *pdhcps_pool = NULL; + list_node *pnode = NULL; + list_node *pback_node = NULL; + ip_addr_t first_address; + bool flag = false; + +// POOL_START: + first_address.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; + renew = false; +// addr_tmp.addr = htonl(client_address_plus.addr); +// addr_tmp.addr++; +// client_address_plus.addr = htonl(addr_tmp.addr); + for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { + pdhcps_pool = pback_node->pnode; + if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){ +// printf("the same device request ip\n"); + if (memcmp(&pdhcps_pool->ip.u_addr.ip4.addr, m->ciaddr, sizeof(pdhcps_pool->ip.u_addr.ip4.addr)) == 0) { + renew = true; + } + client_address.u_addr.ip4.addr = pdhcps_pool->ip.u_addr.ip4.addr; + pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pnode = pback_node; + goto POOL_CHECK; + } else if (pdhcps_pool->ip.u_addr.ip4.addr == client_address_plus.u_addr.ip4.addr){ +// client_address.addr = client_address_plus.addr; +// printf("the ip addr has been request\n"); + addr_tmp.u_addr.ip4.addr = htonl(client_address_plus.u_addr.ip4.addr); + addr_tmp.u_addr.ip4.addr++; + client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); + client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; + } + + if(flag == false) { // search the fisrt unused ip + if(first_address.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { + flag = true; + } else { + addr_tmp.u_addr.ip4.addr = htonl(first_address.u_addr.ip4.addr); + addr_tmp.u_addr.ip4.addr++; + first_address.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); + } + } + } + if (client_address_plus.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) { + client_address.u_addr.ip4.addr = first_address.u_addr.ip4.addr; + } + if (client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) { + client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + pdhcps_pool = NULL; + pnode = NULL; + } else { + pdhcps_pool = (struct dhcps_pool *)malloc(sizeof(struct dhcps_pool)); + pdhcps_pool->ip.u_addr.ip4.addr = client_address.u_addr.ip4.addr; + memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); + pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pnode = (list_node *)malloc(sizeof(list_node )); + pnode->pnode = pdhcps_pool; + pnode->pnext = NULL; + node_insert_to_list(&plist,pnode); + if (client_address.u_addr.ip4.addr == dhcps_lease.end_ip.u_addr.ip4.addr) { + client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + } else { + addr_tmp.u_addr.ip4.addr = htonl(client_address.u_addr.ip4.addr); + addr_tmp.u_addr.ip4.addr++; + client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); + } + } + + POOL_CHECK: + if ((client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) || (ip_addr_isany(&client_address))){ + printf("client_address_plus.addr %x\n", client_address_plus.u_addr.ip4.addr); + if(pnode != NULL) { + node_remove_from_list_0(&plist,pnode); + free(pnode); + pnode = NULL; + } + + if (pdhcps_pool != NULL) { + free(pdhcps_pool); + pdhcps_pool = NULL; + } +// client_address_plus.addr = dhcps_lease.start_ip.addr; + return 4; + } + + sint16_t ret = parse_options(&m->options[4], len);; + + if(ret == DHCPS_STATE_RELEASE) { + if(pnode != NULL) { + node_remove_from_list_0(&plist,pnode); + free(pnode); + pnode = NULL; + } + + if (pdhcps_pool != NULL) { + free(pdhcps_pool); + pdhcps_pool = NULL; + } + memset(&client_address,0x0,sizeof(client_address)); + } + + if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { + return 0; + } +// } + +#if DHCPS_DEBUG + printf("dhcps: xid changed\n"); + printf("dhcps: client_address.addr = %x\n", client_address.addr); +#endif + +// } + +// } + return ret; + } + return 0; +} +/////////////////////////////////////////////////////////////////////////////////// +/* + * DHCP ��������ݰ���մ���ص�����˺�����LWIP UDPģ������ʱ������ + * ��Ҫ����udp_recv()������LWIP����ע��. + * + * @param arg + * @param pcb ���յ�UDP��Ŀ��ƿ�? + * @param p ���յ���UDP�е��������? + * @param addr ���ʹ�UDP���Դ�����IP��ַ + * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� + */ +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, + struct udp_pcb *pcb, + struct pbuf *p, + const ip_addr_t *addr, + uint16_t port) +{ + struct dhcps_msg *pmsg_dhcps = NULL; + sint16_t tlen = 0; + u16_t i = 0; + u16_t dhcps_msg_cnt = 0; + u8_t *p_dhcps_msg = NULL; + u8_t *data = NULL; + +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> receive a packet\n"); +#endif + if (p==NULL) return; + + pmsg_dhcps = (struct dhcps_msg *)malloc(sizeof(struct dhcps_msg)); + if (NULL == pmsg_dhcps){ + pbuf_free(p); + return; + } + p_dhcps_msg = (u8_t *)pmsg_dhcps; + tlen = p->tot_len; + data = p->payload; + +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); + printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); +#endif + + for(i=0; ilen; i++){ + p_dhcps_msg[dhcps_msg_cnt++] = data[i]; +#if DHCPS_DEBUG + printf("%02x ",data[i]); + if((i+1)%16 == 0){ + printf("\n"); + } +#endif + } + + if(p->next != NULL) { +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> p->next != NULL\n"); + printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len); + printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); +#endif + + data = p->next->payload; + for(i=0; inext->len; i++){ + p_dhcps_msg[dhcps_msg_cnt++] = data[i]; +#if DHCPS_DEBUG + printf("%02x ",data[i]); + if((i+1)%16 == 0){ + printf("\n"); + } +#endif + } + } + + /* + * DHCP �ͻ���������Ϣ���� + */ +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> parse_msg(p)\n"); +#endif + + switch(parse_msg(pmsg_dhcps, tlen - 240)) { + + case DHCPS_STATE_OFFER://1 +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); +#endif + send_offer(pmsg_dhcps); + break; + case DHCPS_STATE_ACK://3 +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); +#endif + send_ack(pmsg_dhcps); + break; + case DHCPS_STATE_NAK://4 +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); +#endif + send_nak(pmsg_dhcps); + break; + default : + break; + } +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); +#endif + pbuf_free(p); + free(pmsg_dhcps); + pmsg_dhcps = NULL; +} +/////////////////////////////////////////////////////////////////////////////////// +static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip) +{ + uint32 softap_ip = 0,local_ip = 0; + uint32 start_ip = 0; + uint32 end_ip = 0; +// if (dhcps_lease_flag) { + if (dhcps_lease.enable == true) { + softap_ip = htonl(ip); + start_ip = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); + end_ip = htonl(dhcps_lease.end_ip.u_addr.ip4.addr); + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { + dhcps_lease.enable = false; + } else { + /*config ip information must be in the same segment as the local ip*/ + softap_ip >>= 8; + if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) + || (end_ip - start_ip > DHCPS_MAX_LEASE)) { + dhcps_lease.enable = false; + } + } + } + + if (dhcps_lease.enable == false) { + local_ip = softap_ip = htonl(ip); + softap_ip &= 0xFFFFFF00; + local_ip &= 0xFF; + if (local_ip >= 0x80) + local_ip -= DHCPS_MAX_LEASE; + else + local_ip ++; + + bzero(&dhcps_lease, sizeof(dhcps_lease)); + dhcps_lease.start_ip.u_addr.ip4.addr = softap_ip | local_ip; + dhcps_lease.end_ip.u_addr.ip4.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); + dhcps_lease.start_ip.u_addr.ip4.addr = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); + dhcps_lease.end_ip.u_addr.ip4.addr= htonl(dhcps_lease.end_ip.u_addr.ip4.addr); + } +// dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); +// dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); +// printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); +} +/////////////////////////////////////////////////////////////////////////////////// +void ICACHE_FLASH_ATTR espconn_dhcps_start(struct ip_info *info) +{ + struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); + + if(apnetif->dhcps_pcb != NULL) { + udp_remove(apnetif->dhcps_pcb); + } + + pcb_dhcps = udp_new(); + if (pcb_dhcps == NULL || info ==NULL) { + printf("dhcps_start(): could not obtain pcb\n"); + } + + apnetif->dhcps_pcb = pcb_dhcps; + + IP4_ADDR(&broadcast_dhcps.u_addr.ip4, 255, 255, 255, 255); + + server_address.u_addr.ip4.addr = info->ip.addr; + wifi_softap_init_dhcps_lease(server_address.u_addr.ip4.addr); + client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + + udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); + + udp_recv(pcb_dhcps, &handle_dhcp, NULL); +#if DHCPS_DEBUG + printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); +#endif + +} + +void ICACHE_FLASH_ATTR espconn_dhcps_stop(void) +{ + struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); + + udp_disconnect(pcb_dhcps); +// dhcps_lease_flag = true; + if(apnetif->dhcps_pcb != NULL) { + udp_remove(apnetif->dhcps_pcb); + apnetif->dhcps_pcb = NULL; + } + + //udp_remove(pcb_dhcps); + list_node *pnode = NULL; + list_node *pback_node = NULL; + pnode = plist; + while (pnode != NULL) { + pback_node = pnode; + pnode = pback_node->pnext; + node_remove_from_list_0(&plist, pback_node); + free(pback_node->pnode); + pback_node->pnode = NULL; + free(pback_node); + pback_node = NULL; + } +} + +/****************************************************************************** + * FunctionName : wifi_softap_set_dhcps_lease + * Description : set the lease information of DHCP server + * Parameters : please -- Additional argument to set the lease information, + * Little-Endian. + * Returns : true or false +*******************************************************************************/ +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) +{ + struct ip_info info; + uint32 softap_ip = 0; + uint32 start_ip = 0; + uint32 end_ip = 0; + + uint8 opmode = esp_wifi_get_mode(NULL); + + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { + return false; + } + + if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) + return false; + + if(please->enable) { + bzero(&info, sizeof(struct ip_info)); + wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &info); + softap_ip = htonl(info.ip.addr); + start_ip = htonl(please->start_ip.u_addr.ip4.addr); + end_ip = htonl(please->end_ip.u_addr.ip4.addr); + + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) + return false; + + /*config ip information must be in the same segment as the local ip*/ + softap_ip >>= 8; + if ((start_ip >> 8 != softap_ip) + || (end_ip >> 8 != softap_ip)) { + return false; + } + + if (end_ip - start_ip > DHCPS_MAX_LEASE) + return false; + + bzero(&dhcps_lease, sizeof(dhcps_lease)); +// dhcps_lease.start_ip.addr = start_ip; +// dhcps_lease.end_ip.addr = end_ip; + dhcps_lease.start_ip.u_addr.ip4.addr = please->start_ip.u_addr.ip4.addr; + dhcps_lease.end_ip.u_addr.ip4.addr = please->end_ip.u_addr.ip4.addr; + } + dhcps_lease.enable = please->enable; +// dhcps_lease_flag = false; + return true; +} + +/****************************************************************************** + * FunctionName : wifi_softap_get_dhcps_lease + * Description : get the lease information of DHCP server + * Parameters : please -- Additional argument to get the lease information, + * Little-Endian. + * Returns : true or false +*******************************************************************************/ +bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please) +{ + uint8 opmode = esp_wifi_get_mode(NULL); + + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { + return false; + } + + if (NULL == please) + return false; + +// if (dhcps_lease_flag){ + if (dhcps_lease.enable == false){ + if (wifi_softap_dhcps_status() == DHCP_STOPPED) + return false; + } else { +// bzero(please, sizeof(dhcps_lease)); +// if (wifi_softap_dhcps_status() == DHCP_STOPPED){ +// please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); +// please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); +// } + } + +// if (wifi_softap_dhcps_status() == DHCP_STARTED){ +// bzero(please, sizeof(dhcps_lease)); +// please->start_ip.addr = dhcps_lease.start_ip.addr; +// please->end_ip.addr = dhcps_lease.end_ip.addr; +// } + please->start_ip.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + please->end_ip.u_addr.ip4.addr = dhcps_lease.end_ip.u_addr.ip4.addr; + return true; +} + +static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void) +{ + list_node *pre = NULL, *p = NULL; + list_node *minpre = NULL, *minp = NULL; + struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; + pre = plist; + p = pre->pnext; + minpre = pre; + minp = p; + while (p != NULL){ + pdhcps_pool = p->pnode; + pmin_pool = minp->pnode; + if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){ + minp = p; + minpre = pre; + } + pre = p; + p = p->pnext; + } + minpre->pnext = minp->pnext; + free(minp->pnode); + minp->pnode = NULL; + free(minp); + minp = NULL; +} + +void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) +{ + uint8 num_dhcps_pool = 0; + list_node *pback_node = NULL; + list_node *pnode = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + pnode = plist; + while (pnode != NULL) { + pdhcps_pool = pnode->pnode; + pdhcps_pool->lease_timer --; + if (pdhcps_pool->lease_timer == 0){ + pback_node = pnode; + pnode = pback_node->pnext; + node_remove_from_list_0(&plist,pback_node); + free(pback_node->pnode); + pback_node->pnode = NULL; + free(pback_node); + pback_node = NULL; + } else { + pnode = pnode ->pnext; + num_dhcps_pool ++; + } + } + + if (num_dhcps_pool >= MAX_STATION_NUM) + kill_oldest_dhcps_pool(); +} + +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) +{ + bool offer_flag = true; + uint8 option = 0; + if (optarg == NULL && wifi_softap_dhcps_status() == false) + return false; + + if (level <= OFFER_START || level >= OFFER_END) + return false; + + switch (level){ + case OFFER_ROUTER: + offer = (*(uint8 *)optarg) & 0x01; + offer_flag = true; + break; + default : + offer_flag = false; + break; + } + return offer_flag; +} + +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute) +{ + uint8 opmode = esp_wifi_get_mode(NULL); + + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { + return false; + } + + if (wifi_softap_dhcps_status() == DHCP_STARTED) { + return false; + } + + if(minute == 0) { + return false; + } + dhcps_lease_time = minute; + return true; +} + +bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void) +{ + uint8 opmode = esp_wifi_get_mode(NULL); + + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { + return false; + } + + if (wifi_softap_dhcps_status() == DHCP_STARTED) { + return false; + } + dhcps_lease_time = DHCPS_LEASE_TIME_DEF; + return true; +} + +uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute +{ + return dhcps_lease_time; +} diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c b/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c index 4801be9..65ca997 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c @@ -1,444 +1,444 @@ -/****************************************************************************** - * Copyright 2013-2014 Espressif Systems (Wuxi) - * - * FileName: espconn_udp.c - * - * Description: udp proto interface - * - * Modification history: - * 2014/3/31, v1.0 create this file. -*******************************************************************************/ - -// #include "ets_sys.h" -// #include "os_type.h" -#include - -#include "lwip/inet.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/mem.h" -// #include "lwip/tcp_impl.h" -#include "lwip/udp.h" -#include "esp_wifi.h" - -#include "espconn_udp.h" - -struct ip_info { - ip4_addr_t ip; - ip4_addr_t netmask; - ip4_addr_t gw; -}; - -////////未对以下函数进行实现 -#include "tcpip_adapter.h" -extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info* ipinfo); -extern uint8 igmp_leavegroup(ip_addr_t *host_ip, ip_addr_t *multicast_ip); -extern uint8 igmp_joingroup(ip_addr_t *host_ip, ip_addr_t *multicast_ip); -extern void* eagle_lwip_getif(uint8 type); - -#define ICACHE_FLASH_ATTR -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; -#endif - -extern espconn_msg *plink_active; - uint8 default_interface = ESPCONN_AP_STA; - -enum send_opt{ - ESPCONN_SENDTO, - ESPCONN_SEND -}; -static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn) -{ - if (pespconn == NULL) { - return; - } - - if (pespconn->sent_callback != NULL) { - pespconn->sent_callback(pespconn); - } -} - -static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt) -{ - espconn_msg *psent = arg; - - if (psent == NULL) { - return; - } - - if (psent->pcommon.cntr == 0) { - psent->pespconn->state = ESPCONN_CONNECT; -// sys_timeout(10, espconn_data_sentcb, psent->pespconn); - espconn_data_sentcb(psent->pespconn); - } else { - if (opt == ESPCONN_SEND){ - espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); - } else { - espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); - } - } -} - -/****************************************************************************** - * FunctionName : espconn_udp_sent - * Description : sent data for client or server - * Parameters : void *arg -- client or server to send - * uint8* psent -- Data to send - * uint16 length -- Length of data to send - * Returns : return espconn error code. - * - ESPCONN_OK. Successful. No error occured. - * - ESPCONN_MEM. Out of memory. - * - ESPCONN_RTE. Could not find route to destination address. - * - More errors could be returned by lower protocol layers. -*******************************************************************************/ -err_t ICACHE_FLASH_ATTR -espconn_udp_sent(void *arg, uint8 *psent, uint16 length) -{ - espconn_msg *pudp_sent = arg; - struct udp_pcb *upcb = pudp_sent->pcommon.pcb; - struct pbuf *p, *q ,*p_temp; - u8_t *data = NULL; - u16_t cnt = 0; - u16_t datalen = 0; - u16_t i = 0; - err_t err; - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); - - if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { - return ESPCONN_ARG; - } - - if (1470 < length) { - datalen = 1470; - } else { - datalen = length; - } - - p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); - - if (p != NULL) { - q = p; - - while (q != NULL) { - data = (u8_t *)q->payload; - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); - - for (i = 0; i < q->len; i++) { - data[i] = ((u8_t *) psent)[cnt++]; - } - - q = q->next; - } - } else { - return ESPCONN_MEM; - } - - upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port; - IP4_ADDR(&upcb->remote_ip.u_addr.ip4, pudp_sent->pespconn->proto.udp->remote_ip[0], - pudp_sent->pespconn->proto.udp->remote_ip[1], - pudp_sent->pespconn->proto.udp->remote_ip[2], - pudp_sent->pespconn->proto.udp->remote_ip[3]); - - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); - - struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); - struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); - - sint8 value = ESPCONN_OK; - esp_wifi_get_mode((wifi_mode_t*)&value); - if(value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) - { - if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { - - p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - if (pbuf_copy (p_temp,p) != ERR_OK) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n")); - return ESPCONN_ARG; - } - netif_set_default(sta_netif); - err = udp_send(upcb, p_temp); - pbuf_free(p_temp); - netif_set_default(ap_netif); - } - } - err = udp_send(upcb, p); - - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err)); - - if (p->ref != 0) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); - pbuf_free(p); - pudp_sent->pcommon.ptrbuf = psent + datalen; - pudp_sent->pcommon.cntr = length - datalen; - espconn_data_sent(pudp_sent, ESPCONN_SEND); - if (err > 0) - return ESPCONN_IF; - return err; - } else { - pbuf_free(p); - return ESPCONN_RTE; - } -} - -/****************************************************************************** - * FunctionName : espconn_udp_sendto - * Description : sent data for UDP - * Parameters : void *arg -- UDP to send - * uint8* psent -- Data to send - * uint16 length -- Length of data to send - * Returns : return espconn error code. - * - ESPCONN_OK. Successful. No error occured. - * - ESPCONN_MEM. Out of memory. - * - ESPCONN_RTE. Could not find route to destination address. - * - More errors could be returned by lower protocol layers. -*******************************************************************************/ -err_t ICACHE_FLASH_ATTR -espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) -{ - espconn_msg *pudp_sent = arg; - struct udp_pcb *upcb = pudp_sent->pcommon.pcb; - struct espconn *pespconn = pudp_sent->pespconn; - struct pbuf *p, *q ,*p_temp; - ip_addr_t dst_ip; - u16_t dst_port; - u8_t *data = NULL; - u16_t cnt = 0; - u16_t datalen = 0; - u16_t i = 0; - err_t err; - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); - - if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { - return ESPCONN_ARG; - } - - if (1470 < length) { - datalen = 1470; - } else { - datalen = length; - } - - p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); - - if (p != NULL) { - q = p; - - while (q != NULL) { - data = (u8_t *)q->payload; - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); - - for (i = 0; i < q->len; i++) { - data[i] = ((u8_t *) psent)[cnt++]; - } - - q = q->next; - } - } else { - return ESPCONN_MEM; - } - - dst_port = pespconn->proto.udp->remote_port; - IP4_ADDR(&dst_ip.u_addr.ip4, pespconn->proto.udp->remote_ip[0], - pespconn->proto.udp->remote_ip[1], pespconn->proto.udp->remote_ip[2], - pespconn->proto.udp->remote_ip[3]); - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); - - struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); - struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); - - sint8 value = ESPCONN_OK; - esp_wifi_get_mode((wifi_mode_t*)&value); - if(value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) - { - if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { - - p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - if (pbuf_copy (p_temp,p) != ERR_OK) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); - return ESPCONN_ARG; - } - netif_set_default(sta_netif); - err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); - pbuf_free(p_temp); - netif_set_default(ap_netif); - } - } - err = udp_sendto(upcb, p, &dst_ip, dst_port); - - if (p->ref != 0) { - pbuf_free(p); - pudp_sent->pcommon.ptrbuf = psent + datalen; - pudp_sent->pcommon.cntr = length - datalen; - if (err == ERR_OK) - espconn_data_sent(pudp_sent, ESPCONN_SENDTO); - - if (err > 0) - return ESPCONN_IF; - return err; - } else { - pbuf_free(p); - return ESPCONN_RTE; - } -} - -/****************************************************************************** - * FunctionName : espconn_udp_server_recv - * Description : This callback will be called when receiving a datagram. - * Parameters : arg -- user supplied argument - * upcb -- the udp_pcb which received data - * p -- the packet buffer that was received - * addr -- the remote IP address from which the packet was received - * port -- the remote port from which the packet was received - * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port) -{ - espconn_msg *precv = arg; - struct pbuf *q = NULL; - u8_t *pdata = NULL; - u16_t length = 0; - struct ip_info ipconfig; - - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb)); - - precv->pcommon.remote_ip[0] = ip4_addr1_16(&(addr->u_addr.ip4)); - precv->pcommon.remote_ip[1] = ip4_addr2_16(&(addr->u_addr.ip4)); - precv->pcommon.remote_ip[2] = ip4_addr3_16(&(addr->u_addr.ip4)); - precv->pcommon.remote_ip[3] = ip4_addr4_16(&(addr->u_addr.ip4)); - precv->pcommon.remote_port = port; - precv->pcommon.pcb = upcb; - - sint8 value = ESPCONN_OK; - esp_wifi_get_mode((wifi_mode_t*)&value); - if (value != 1) { - wifi_get_ip_info(1, &ipconfig); - - if (!ip4_addr_netcmp(&addr->u_addr.ip4, &ipconfig.ip, &ipconfig.netmask)) { - wifi_get_ip_info(0, &ipconfig); - } - } else { - wifi_get_ip_info(0, &ipconfig); - } - - precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip); - precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip); - precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip); - precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip); - - if (p != NULL) { - pdata = (u8_t *)malloc(p ->tot_len + 1); - length = pbuf_copy_partial(p, pdata, p ->tot_len, 0); - precv->pcommon.pcb = upcb; - pbuf_free(p); - if (length != 0) { - if (precv->pespconn->recv_callback != NULL) { - precv->pespconn->recv_callback(precv->pespconn, (char*)pdata, length); - } - } - free(pdata); - } else { - return; - } -} - -/****************************************************************************** - * FunctionName : espconn_udp_disconnect - * Description : A new incoming connection has been disconnected. - * Parameters : espconn -- the espconn used to disconnect with host - * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon) -{ - if (pdiscon == NULL) { - return; - } - - struct udp_pcb *upcb = pdiscon->pcommon.pcb; - - udp_disconnect(upcb); - - udp_remove(upcb); - - espconn_list_delete(&plink_active, pdiscon); - - free(pdiscon); - pdiscon = NULL; -} - -/****************************************************************************** - * FunctionName : espconn_udp_server - * Description : Initialize the server: set up a PCB and bind it to the port - * Parameters : pespconn -- the espconn used to build server - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_udp_server(struct espconn *pespconn) -{ - struct udp_pcb *upcb = NULL; - espconn_msg *pserver = NULL; - upcb = udp_new(); - - if (upcb == NULL) { - return ESPCONN_MEM; - } else { - pserver = (espconn_msg *)malloc(sizeof(espconn_msg)); - - if (pserver == NULL) { - udp_remove(upcb); - return ESPCONN_MEM; - } - - pserver->pcommon.pcb = upcb; - pserver->pespconn = pespconn; - espconn_list_creat(&plink_active, pserver); - udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port); - udp_recv(upcb, espconn_udp_recv, (void *)pserver); - return ESPCONN_OK; - } -} - -/****************************************************************************** - * FunctionName : espconn_igmp_leave - * Description : leave a multicast group - * Parameters : host_ip -- the ip address of udp server - * multicast_ip -- multicast ip given by user - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip) -{ - if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n")); - return -1; - }; - - return ESPCONN_OK; -} - -/****************************************************************************** - * FunctionName : espconn_igmp_join - * Description : join a multicast group - * Parameters : host_ip -- the ip address of udp server - * multicast_ip -- multicast ip given by user - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip) -{ - if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n")); - return -1; - }; - - /* join to any IP address at the port */ - return ESPCONN_OK; -} +/****************************************************************************** + * Copyright 2013-2014 Espressif Systems (Wuxi) + * + * FileName: espconn_udp.c + * + * Description: udp proto interface + * + * Modification history: + * 2014/3/31, v1.0 create this file. +*******************************************************************************/ + +// #include "ets_sys.h" +// #include "os_type.h" +#include + +#include "lwip/inet.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/mem.h" +// #include "lwip/tcp_impl.h" +#include "lwip/udp.h" +#include "esp_wifi.h" + +#include "espconn_udp.h" + +struct ip_info { + ip4_addr_t ip; + ip4_addr_t netmask; + ip4_addr_t gw; +}; + +////////未对以下函数进行实现 +#include "tcpip_adapter.h" +extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info* ipinfo); +extern uint8 igmp_leavegroup(ip_addr_t *host_ip, ip_addr_t *multicast_ip); +extern uint8 igmp_joingroup(ip_addr_t *host_ip, ip_addr_t *multicast_ip); +extern void* eagle_lwip_getif(uint8 type); + +#define ICACHE_FLASH_ATTR +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + +extern espconn_msg *plink_active; + uint8 default_interface = ESPCONN_AP_STA; + +enum send_opt{ + ESPCONN_SENDTO, + ESPCONN_SEND +}; +static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn) +{ + if (pespconn == NULL) { + return; + } + + if (pespconn->sent_callback != NULL) { + pespconn->sent_callback(pespconn); + } +} + +static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt) +{ + espconn_msg *psent = arg; + + if (psent == NULL) { + return; + } + + if (psent->pcommon.cntr == 0) { + psent->pespconn->state = ESPCONN_CONNECT; +// sys_timeout(10, espconn_data_sentcb, psent->pespconn); + espconn_data_sentcb(psent->pespconn); + } else { + if (opt == ESPCONN_SEND){ + espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + } else { + espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + } + } +} + +/****************************************************************************** + * FunctionName : espconn_udp_sent + * Description : sent data for client or server + * Parameters : void *arg -- client or server to send + * uint8* psent -- Data to send + * uint16 length -- Length of data to send + * Returns : return espconn error code. + * - ESPCONN_OK. Successful. No error occured. + * - ESPCONN_MEM. Out of memory. + * - ESPCONN_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. +*******************************************************************************/ +err_t ICACHE_FLASH_ATTR +espconn_udp_sent(void *arg, uint8 *psent, uint16 length) +{ + espconn_msg *pudp_sent = arg; + struct udp_pcb *upcb = pudp_sent->pcommon.pcb; + struct pbuf *p, *q ,*p_temp; + u8_t *data = NULL; + u16_t cnt = 0; + u16_t datalen = 0; + u16_t i = 0; + err_t err; + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); + + if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { + return ESPCONN_ARG; + } + + if (1470 < length) { + datalen = 1470; + } else { + datalen = length; + } + + p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); + + if (p != NULL) { + q = p; + + while (q != NULL) { + data = (u8_t *)q->payload; + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); + + for (i = 0; i < q->len; i++) { + data[i] = ((u8_t *) psent)[cnt++]; + } + + q = q->next; + } + } else { + return ESPCONN_MEM; + } + + upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port; + IP4_ADDR(&upcb->remote_ip.u_addr.ip4, pudp_sent->pespconn->proto.udp->remote_ip[0], + pudp_sent->pespconn->proto.udp->remote_ip[1], + pudp_sent->pespconn->proto.udp->remote_ip[2], + pudp_sent->pespconn->proto.udp->remote_ip[3]); + + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); + + struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); + struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); + + sint8 value = ESPCONN_OK; + esp_wifi_get_mode((wifi_mode_t*)&value); + if(value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) + { + if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ + ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ + ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { + + p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + if (pbuf_copy (p_temp,p) != ERR_OK) { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n")); + return ESPCONN_ARG; + } + netif_set_default(sta_netif); + err = udp_send(upcb, p_temp); + pbuf_free(p_temp); + netif_set_default(ap_netif); + } + } + err = udp_send(upcb, p); + + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err)); + + if (p->ref != 0) { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); + pbuf_free(p); + pudp_sent->pcommon.ptrbuf = psent + datalen; + pudp_sent->pcommon.cntr = length - datalen; + espconn_data_sent(pudp_sent, ESPCONN_SEND); + if (err > 0) + return ESPCONN_IF; + return err; + } else { + pbuf_free(p); + return ESPCONN_RTE; + } +} + +/****************************************************************************** + * FunctionName : espconn_udp_sendto + * Description : sent data for UDP + * Parameters : void *arg -- UDP to send + * uint8* psent -- Data to send + * uint16 length -- Length of data to send + * Returns : return espconn error code. + * - ESPCONN_OK. Successful. No error occured. + * - ESPCONN_MEM. Out of memory. + * - ESPCONN_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. +*******************************************************************************/ +err_t ICACHE_FLASH_ATTR +espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) +{ + espconn_msg *pudp_sent = arg; + struct udp_pcb *upcb = pudp_sent->pcommon.pcb; + struct espconn *pespconn = pudp_sent->pespconn; + struct pbuf *p, *q ,*p_temp; + ip_addr_t dst_ip; + u16_t dst_port; + u8_t *data = NULL; + u16_t cnt = 0; + u16_t datalen = 0; + u16_t i = 0; + err_t err; + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); + + if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { + return ESPCONN_ARG; + } + + if (1470 < length) { + datalen = 1470; + } else { + datalen = length; + } + + p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); + + if (p != NULL) { + q = p; + + while (q != NULL) { + data = (u8_t *)q->payload; + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); + + for (i = 0; i < q->len; i++) { + data[i] = ((u8_t *) psent)[cnt++]; + } + + q = q->next; + } + } else { + return ESPCONN_MEM; + } + + dst_port = pespconn->proto.udp->remote_port; + IP4_ADDR(&dst_ip.u_addr.ip4, pespconn->proto.udp->remote_ip[0], + pespconn->proto.udp->remote_ip[1], pespconn->proto.udp->remote_ip[2], + pespconn->proto.udp->remote_ip[3]); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); + + struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); + struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); + + sint8 value = ESPCONN_OK; + esp_wifi_get_mode((wifi_mode_t*)&value); + if(value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) + { + if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ + ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ + ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { + + p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + if (pbuf_copy (p_temp,p) != ERR_OK) { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); + return ESPCONN_ARG; + } + netif_set_default(sta_netif); + err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); + pbuf_free(p_temp); + netif_set_default(ap_netif); + } + } + err = udp_sendto(upcb, p, &dst_ip, dst_port); + + if (p->ref != 0) { + pbuf_free(p); + pudp_sent->pcommon.ptrbuf = psent + datalen; + pudp_sent->pcommon.cntr = length - datalen; + if (err == ERR_OK) + espconn_data_sent(pudp_sent, ESPCONN_SENDTO); + + if (err > 0) + return ESPCONN_IF; + return err; + } else { + pbuf_free(p); + return ESPCONN_RTE; + } +} + +/****************************************************************************** + * FunctionName : espconn_udp_server_recv + * Description : This callback will be called when receiving a datagram. + * Parameters : arg -- user supplied argument + * upcb -- the udp_pcb which received data + * p -- the packet buffer that was received + * addr -- the remote IP address from which the packet was received + * port -- the remote port from which the packet was received + * Returns : none +*******************************************************************************/ +static void ICACHE_FLASH_ATTR +espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, + const ip_addr_t *addr, u16_t port) +{ + espconn_msg *precv = arg; + struct pbuf *q = NULL; + u8_t *pdata = NULL; + u16_t length = 0; + struct ip_info ipconfig; + + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb)); + + precv->pcommon.remote_ip[0] = ip4_addr1_16(&(addr->u_addr.ip4)); + precv->pcommon.remote_ip[1] = ip4_addr2_16(&(addr->u_addr.ip4)); + precv->pcommon.remote_ip[2] = ip4_addr3_16(&(addr->u_addr.ip4)); + precv->pcommon.remote_ip[3] = ip4_addr4_16(&(addr->u_addr.ip4)); + precv->pcommon.remote_port = port; + precv->pcommon.pcb = upcb; + + sint8 value = ESPCONN_OK; + esp_wifi_get_mode((wifi_mode_t*)&value); + if (value != 1) { + wifi_get_ip_info(1, &ipconfig); + + if (!ip4_addr_netcmp(&addr->u_addr.ip4, &ipconfig.ip, &ipconfig.netmask)) { + wifi_get_ip_info(0, &ipconfig); + } + } else { + wifi_get_ip_info(0, &ipconfig); + } + + precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip); + precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip); + precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip); + precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip); + + if (p != NULL) { + pdata = (u8_t *)malloc(p ->tot_len + 1); + length = pbuf_copy_partial(p, pdata, p ->tot_len, 0); + precv->pcommon.pcb = upcb; + pbuf_free(p); + if (length != 0) { + if (precv->pespconn->recv_callback != NULL) { + precv->pespconn->recv_callback(precv->pespconn, (char*)pdata, length); + } + } + free(pdata); + } else { + return; + } +} + +/****************************************************************************** + * FunctionName : espconn_udp_disconnect + * Description : A new incoming connection has been disconnected. + * Parameters : espconn -- the espconn used to disconnect with host + * Returns : none +*******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon) +{ + if (pdiscon == NULL) { + return; + } + + struct udp_pcb *upcb = pdiscon->pcommon.pcb; + + udp_disconnect(upcb); + + udp_remove(upcb); + + espconn_list_delete(&plink_active, pdiscon); + + free(pdiscon); + pdiscon = NULL; +} + +/****************************************************************************** + * FunctionName : espconn_udp_server + * Description : Initialize the server: set up a PCB and bind it to the port + * Parameters : pespconn -- the espconn used to build server + * Returns : none +*******************************************************************************/ +sint8 ICACHE_FLASH_ATTR +espconn_udp_server(struct espconn *pespconn) +{ + struct udp_pcb *upcb = NULL; + espconn_msg *pserver = NULL; + upcb = udp_new(); + + if (upcb == NULL) { + return ESPCONN_MEM; + } else { + pserver = (espconn_msg *)malloc(sizeof(espconn_msg)); + + if (pserver == NULL) { + udp_remove(upcb); + return ESPCONN_MEM; + } + + pserver->pcommon.pcb = upcb; + pserver->pespconn = pespconn; + espconn_list_creat(&plink_active, pserver); + udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port); + udp_recv(upcb, espconn_udp_recv, (void *)pserver); + return ESPCONN_OK; + } +} + +/****************************************************************************** + * FunctionName : espconn_igmp_leave + * Description : leave a multicast group + * Parameters : host_ip -- the ip address of udp server + * multicast_ip -- multicast ip given by user + * Returns : none +*******************************************************************************/ +sint8 ICACHE_FLASH_ATTR +espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip) +{ + if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n")); + return -1; + }; + + return ESPCONN_OK; +} + +/****************************************************************************** + * FunctionName : espconn_igmp_join + * Description : join a multicast group + * Parameters : host_ip -- the ip address of udp server + * multicast_ip -- multicast ip given by user + * Returns : none +*******************************************************************************/ +sint8 ICACHE_FLASH_ATTR +espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip) +{ + if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n")); + return -1; + }; + + /* join to any IP address at the port */ + return ESPCONN_OK; +} diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/include/dhcpserver.h b/LuaNode_Esp32/LuaNode32/components/espconn/include/dhcpserver.h index 3e069b4..f2661d9 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/include/dhcpserver.h +++ b/LuaNode_Esp32/LuaNode32/components/espconn/include/dhcpserver.h @@ -1,114 +1,114 @@ -#ifndef __DHCPS_H__ -#define __DHCPS_H__ - -#define USE_DNS - -typedef int8_t sint8; -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef int16_t sint16_t; -typedef uint32_t uint32; -struct ip_info { - ip4_addr_t ip; - ip4_addr_t netmask; - ip4_addr_t gw; -}; - - -typedef struct dhcps_state{ - sint16_t state; -} dhcps_state; - -// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� -typedef struct dhcps_msg { - uint8_t op, htype, hlen, hops; - uint8_t xid[4]; - uint16_t secs, flags; - uint8_t ciaddr[4]; - uint8_t yiaddr[4]; - uint8_t siaddr[4]; - uint8_t giaddr[4]; - uint8_t chaddr[16]; - uint8_t sname[64]; - uint8_t file[128]; - uint8_t options[312]; -}dhcps_msg; - -#ifndef LWIP_OPEN_SRC -typedef struct dhcps_lease { - bool enable; - ip_addr_t start_ip; - ip_addr_t end_ip; -}dhcps_lease_t; - -enum dhcps_offer_option{ - OFFER_START = 0x00, - OFFER_ROUTER = 0x01, - OFFER_END -}; -#endif - -struct dhcps_pool{ - ip_addr_t ip; - uint8 mac[6]; - uint32 lease_timer; -}; - -typedef struct _list_node{ - void *pnode; - struct _list_node *pnext; -}list_node; - -extern uint32 dhcps_lease_time; -#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 -#define DHCPS_MAX_LEASE 0x64 -#define BOOTP_BROADCAST 0x8000 - -#define DHCP_REQUEST 1 -#define DHCP_REPLY 2 -#define DHCP_HTYPE_ETHERNET 1 -#define DHCP_HLEN_ETHERNET 6 -#define DHCP_MSG_LEN 236 - -#define DHCPS_SERVER_PORT 67 -#define DHCPS_CLIENT_PORT 68 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 - -#define DHCP_OPTION_SUBNET_MASK 1 -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_REQ_IPADDR 50 -#define DHCP_OPTION_LEASE_TIME 51 -#define DHCP_OPTION_MSG_TYPE 53 -#define DHCP_OPTION_SERVER_ID 54 -#define DHCP_OPTION_INTERFACE_MTU 26 -#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 -#define DHCP_OPTION_BROADCAST_ADDRESS 28 -#define DHCP_OPTION_REQ_LIST 55 -#define DHCP_OPTION_END 255 - -//#define USE_CLASS_B_NET 1 -#define DHCPS_DEBUG 0 -#define MAX_STATION_NUM 8 - -#define DHCPS_STATE_OFFER 1 -#define DHCPS_STATE_DECLINE 2 -#define DHCPS_STATE_ACK 3 -#define DHCPS_STATE_NAK 4 -#define DHCPS_STATE_IDLE 5 -#define DHCPS_STATE_RELEASE 6 - -#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) - -void espconn_dhcps_start(struct ip_info *info); -void espconn_dhcps_stop(void); - -#endif - +#ifndef __DHCPS_H__ +#define __DHCPS_H__ + +#define USE_DNS + +typedef int8_t sint8; +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef int16_t sint16_t; +typedef uint32_t uint32; +struct ip_info { + ip4_addr_t ip; + ip4_addr_t netmask; + ip4_addr_t gw; +}; + + +typedef struct dhcps_state{ + sint16_t state; +} dhcps_state; + +// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� +typedef struct dhcps_msg { + uint8_t op, htype, hlen, hops; + uint8_t xid[4]; + uint16_t secs, flags; + uint8_t ciaddr[4]; + uint8_t yiaddr[4]; + uint8_t siaddr[4]; + uint8_t giaddr[4]; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + uint8_t options[312]; +}dhcps_msg; + +#ifndef LWIP_OPEN_SRC +typedef struct dhcps_lease { + bool enable; + ip_addr_t start_ip; + ip_addr_t end_ip; +}dhcps_lease_t; + +enum dhcps_offer_option{ + OFFER_START = 0x00, + OFFER_ROUTER = 0x01, + OFFER_END +}; +#endif + +struct dhcps_pool{ + ip_addr_t ip; + uint8 mac[6]; + uint32 lease_timer; +}; + +typedef struct _list_node{ + void *pnode; + struct _list_node *pnext; +}list_node; + +extern uint32 dhcps_lease_time; +#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 +#define DHCPS_MAX_LEASE 0x64 +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPS_SERVER_PORT 67 +#define DHCPS_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_INTERFACE_MTU 26 +#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +//#define USE_CLASS_B_NET 1 +#define DHCPS_DEBUG 0 +#define MAX_STATION_NUM 8 + +#define DHCPS_STATE_OFFER 1 +#define DHCPS_STATE_DECLINE 2 +#define DHCPS_STATE_ACK 3 +#define DHCPS_STATE_NAK 4 +#define DHCPS_STATE_IDLE 5 +#define DHCPS_STATE_RELEASE 6 + +#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) + +void espconn_dhcps_start(struct ip_info *info); +void espconn_dhcps_stop(void); + +#endif + diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_tcp.h b/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_tcp.h index 67ce506..35f795e 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_tcp.h +++ b/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_tcp.h @@ -1,79 +1,79 @@ -#ifndef __ESPCONN_TCP_H__ -#define __ESPCONN_TCP_H__ - -#ifndef ESPCONN_TCP_DEBUG -#define ESPCONN_TCP_DEBUG LWIP_DBG_OFF -#endif -#include "espconn.h" - -typedef struct _espcon_event_{ - void* par; - uint8 sig; -}espcon_event_t; - -#ifndef ESPCONN_TCP_TIMER -#define ESPCONN_TCP_TIMER 40 -#endif - -#define espconn_keepalive_enable(pcb) ((pcb)->so_options |= SOF_KEEPALIVE) -#define espconn_keepalive_disable(pcb) ((pcb)->so_options &= ~SOF_KEEPALIVE) - -/****************************************************************************** - * FunctionName : espconn_kill_oldest_pcb - * Description : A oldest incoming connection has been killed. - * Parameters : none - * Returns : none -*******************************************************************************/ - -extern void espconn_kill_oldest_pcb(void); - -/****************************************************************************** - * FunctionName : espconn_tcp_disconnect - * Description : A new incoming connection has been disconnected. - * Parameters : espconn -- the espconn used to disconnect with host - * Returns : none -*******************************************************************************/ - -extern void espconn_tcp_disconnect(espconn_msg *pdiscon,uint8 type); - -/****************************************************************************** - * FunctionName : espconn_tcp_client - * Description : Initialize the client: set up a connect PCB and bind it to - * the defined port - * Parameters : espconn -- the espconn used to build client - * Returns : none -*******************************************************************************/ - -extern sint8 espconn_tcp_client(struct espconn* espconn); - -/****************************************************************************** - * FunctionName : espconn_tcp_server - * Description : Initialize the server: set up a listening PCB and bind it to - * the defined port - * Parameters : espconn -- the espconn used to build server - * Returns : none -*******************************************************************************/ - -extern sint8 espconn_tcp_server(struct espconn *espconn); - -/****************************************************************************** - * FunctionName : espconn_tcp_write - * Description : - * - * Parameters : - * Returns : -*******************************************************************************/ - -extern err_t espconn_tcp_write(void *arg); - -/****************************************************************************** - * FunctionName : espconn_tcp_delete - * Description : - * Parameters : - * Returns : -*******************************************************************************/ - -extern sint8 espconn_tcp_delete(struct espconn *pdeletecon); - -#endif /* __CLIENT_TCP_H__ */ - +#ifndef __ESPCONN_TCP_H__ +#define __ESPCONN_TCP_H__ + +#ifndef ESPCONN_TCP_DEBUG +#define ESPCONN_TCP_DEBUG LWIP_DBG_OFF +#endif +#include "espconn.h" + +typedef struct _espcon_event_{ + void* par; + uint8 sig; +}espcon_event_t; + +#ifndef ESPCONN_TCP_TIMER +#define ESPCONN_TCP_TIMER 40 +#endif + +#define espconn_keepalive_enable(pcb) ((pcb)->so_options |= SOF_KEEPALIVE) +#define espconn_keepalive_disable(pcb) ((pcb)->so_options &= ~SOF_KEEPALIVE) + +/****************************************************************************** + * FunctionName : espconn_kill_oldest_pcb + * Description : A oldest incoming connection has been killed. + * Parameters : none + * Returns : none +*******************************************************************************/ + +extern void espconn_kill_oldest_pcb(void); + +/****************************************************************************** + * FunctionName : espconn_tcp_disconnect + * Description : A new incoming connection has been disconnected. + * Parameters : espconn -- the espconn used to disconnect with host + * Returns : none +*******************************************************************************/ + +extern void espconn_tcp_disconnect(espconn_msg *pdiscon,uint8 type); + +/****************************************************************************** + * FunctionName : espconn_tcp_client + * Description : Initialize the client: set up a connect PCB and bind it to + * the defined port + * Parameters : espconn -- the espconn used to build client + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_tcp_client(struct espconn* espconn); + +/****************************************************************************** + * FunctionName : espconn_tcp_server + * Description : Initialize the server: set up a listening PCB and bind it to + * the defined port + * Parameters : espconn -- the espconn used to build server + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_tcp_server(struct espconn *espconn); + +/****************************************************************************** + * FunctionName : espconn_tcp_write + * Description : + * + * Parameters : + * Returns : +*******************************************************************************/ + +extern err_t espconn_tcp_write(void *arg); + +/****************************************************************************** + * FunctionName : espconn_tcp_delete + * Description : + * Parameters : + * Returns : +*******************************************************************************/ + +extern sint8 espconn_tcp_delete(struct espconn *pdeletecon); + +#endif /* __CLIENT_TCP_H__ */ + diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_udp.h b/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_udp.h index 5ab8095..c58a4b9 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_udp.h +++ b/LuaNode_Esp32/LuaNode32/components/espconn/include/espconn_udp.h @@ -1,64 +1,64 @@ -#ifndef __ESPCONN_UDP_H__ -#define __ESPCONN_UDP_H__ - -#ifndef ESPCONN_UDP_DEBUG -#define ESPCONN_UDP_DEBUG LWIP_DBG_OFF -#endif - -#include "espconn.h" - -/****************************************************************************** - * FunctionName : espconn_udp_client - * Description : Initialize the client: set up a PCB and bind it to the port - * Parameters : pespconn -- the espconn used to build client - * Returns : none -*******************************************************************************/ - -extern sint8 espconn_udp_client(struct espconn *pespconn); - -/****************************************************************************** - * FunctionName : espconn_udp_disconnect - * Description : A new incoming connection has been disconnected. - * Parameters : espconn -- the espconn used to disconnect with host - * Returns : none -*******************************************************************************/ - -extern void espconn_udp_disconnect(espconn_msg *pdiscon); - -/****************************************************************************** - * FunctionName : espconn_udp_server - * Description : Initialize the server: set up a PCB and bind it to the port - * Parameters : pespconn -- the espconn used to build server - * Returns : none -*******************************************************************************/ - -extern sint8 espconn_udp_server(struct espconn *espconn); - -/****************************************************************************** - * FunctionName : espconn_udp_sent - * Description : sent data for client or server - * Parameters : void *arg -- client or server to send - * uint8* psent -- Data to send - * uint16 length -- Length of data to send - * Returns : none -*******************************************************************************/ - -extern err_t espconn_udp_sent(void *arg, uint8 *psent, uint16 length); - -/****************************************************************************** - * FunctionName : espconn_udp_sendto - * Description : sent data for UDP - * Parameters : void *arg -- UDP to send - * uint8* psent -- Data to send - * uint16 length -- Length of data to send - * Returns : return espconn error code. - * - ESPCONN_OK. Successful. No error occured. - * - ESPCONN_MEM. Out of memory. - * - ESPCONN_RTE. Could not find route to destination address. - * - More errors could be returned by lower protocol layers. -*******************************************************************************/ -extern err_t espconn_udp_sendto(void *arg, uint8 *psent, uint16 length); - -#endif /* __ESPCONN_UDP_H__ */ - - +#ifndef __ESPCONN_UDP_H__ +#define __ESPCONN_UDP_H__ + +#ifndef ESPCONN_UDP_DEBUG +#define ESPCONN_UDP_DEBUG LWIP_DBG_OFF +#endif + +#include "espconn.h" + +/****************************************************************************** + * FunctionName : espconn_udp_client + * Description : Initialize the client: set up a PCB and bind it to the port + * Parameters : pespconn -- the espconn used to build client + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_udp_client(struct espconn *pespconn); + +/****************************************************************************** + * FunctionName : espconn_udp_disconnect + * Description : A new incoming connection has been disconnected. + * Parameters : espconn -- the espconn used to disconnect with host + * Returns : none +*******************************************************************************/ + +extern void espconn_udp_disconnect(espconn_msg *pdiscon); + +/****************************************************************************** + * FunctionName : espconn_udp_server + * Description : Initialize the server: set up a PCB and bind it to the port + * Parameters : pespconn -- the espconn used to build server + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_udp_server(struct espconn *espconn); + +/****************************************************************************** + * FunctionName : espconn_udp_sent + * Description : sent data for client or server + * Parameters : void *arg -- client or server to send + * uint8* psent -- Data to send + * uint16 length -- Length of data to send + * Returns : none +*******************************************************************************/ + +extern err_t espconn_udp_sent(void *arg, uint8 *psent, uint16 length); + +/****************************************************************************** + * FunctionName : espconn_udp_sendto + * Description : sent data for UDP + * Parameters : void *arg -- UDP to send + * uint8* psent -- Data to send + * uint16 length -- Length of data to send + * Returns : return espconn error code. + * - ESPCONN_OK. Successful. No error occured. + * - ESPCONN_MEM. Out of memory. + * - ESPCONN_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. +*******************************************************************************/ +extern err_t espconn_udp_sendto(void *arg, uint8 *psent, uint16 length); + +#endif /* __ESPCONN_UDP_H__ */ + + diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/netio.c b/LuaNode_Esp32/LuaNode32/components/espconn/netio.c index 48fe5fb..7eca28b 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/netio.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/netio.c @@ -1,373 +1,373 @@ -/** - * @file - * MetIO Server - * - */ - -/* - * 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. - * - */ -#include "lwip/opt.h" - extern u32_t sys_now(void); - -#if LWIP_TCP -#include "lwip/tcp.h" - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; -#endif - - -#define ICACHE_FLASH_ATTR - -/* - * This implements a netio server. - * The client sends a command word (4 bytes) then a data length word (4 bytes). - * If the command is "receive", the server is to consume "data length" bytes into - * a circular buffer until the first byte is non-zero, then it is to consume - * another command/data pair. - * If the command is "send", the server is to send "data length" bytes from a circular - * buffer with the first byte being zero, until "some time" (6 seconds in the - * current netio126.zip download) has passed and then send one final buffer with - * the first byte being non-zero. Then it is to consume another command/data pair. - */ - -/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */ - -/* implementation options */ -#define NETIO_BUF_SIZE (4 * 1024) -#define NETIO_USE_STATIC_BUF 0 - -/* NetIO server state definition */ -#define NETIO_STATE_WAIT_FOR_CMD 0 -#define NETIO_STATE_RECV_DATA 1 -#define NETIO_STATE_SEND_DATA 2 -#define NETIO_STATE_SEND_DATA_LAST 3 -#define NETIO_STATE_DONE 4 - -struct netio_state { - u32_t state; - u32_t cmd; - u32_t data_len; - u32_t cntr; - u8_t * buf_ptr; - u32_t buf_pos; - u32_t first_byte; - u32_t time_stamp; -}; - -/* NetIO command protocol definition */ -#define NETIO_CMD_QUIT 0 -#define NETIO_CMD_C2S 1 -#define NETIO_CMD_S2C 2 -#define NETIO_CMD_RES 3 - -static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); - -static void ICACHE_FLASH_ATTR -netio_close(void *arg, struct tcp_pcb *pcb) -{ - err_t err; - - struct netio_state *ns = arg; - ns->state = NETIO_STATE_DONE; - tcp_recv(pcb, NULL); - err = tcp_close(pcb); - - if (err != ERR_OK) { - /* closing failed, try again later */ - tcp_recv(pcb, netio_recv); - } else { - /* closing succeeded */ -#if NETIO_USE_STATIC_BUF != 1 - if(ns->buf_ptr != NULL){ - mem_free(ns->buf_ptr); - } -#endif - tcp_arg(pcb, NULL); - tcp_poll(pcb, NULL, 0); - tcp_sent(pcb, NULL); - if (arg != NULL) { - mem_free(arg); - } - } -} - -static err_t ICACHE_FLASH_ATTR -netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct netio_state *ns = arg; - u8_t * data_ptr; - u32_t data_cntr; - struct pbuf *q = p; - u16_t len; - - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - } - - if (err == ERR_OK && q != NULL) { - - while (q != NULL) { - data_cntr = q->len; - data_ptr = q->payload; - while (data_cntr--) { - if (ns->state == NETIO_STATE_DONE){ - netio_close(ns, pcb); - break; - } else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) { - if (ns->cntr < 4) { - /* build up the CMD field */ - ns->cmd <<= 8; - ns->cmd |= *data_ptr++; - ns->cntr++; - } else if (ns->cntr < 8) { - /* build up the DATA field */ - ns->data_len <<= 8; - ns->data_len |= *data_ptr++; - ns->cntr++; - - if (ns->cntr == 8) { - /* now we have full command and data words */ - ns->cntr = 0; - ns->buf_pos = 0; - ns->buf_ptr[0] = 0; - if (ns->cmd == NETIO_CMD_C2S) { - ns->state = NETIO_STATE_RECV_DATA; - } else if (ns->cmd == NETIO_CMD_S2C) { - ns->state = NETIO_STATE_SEND_DATA; - /* start timer */ - ns->time_stamp = sys_now(); - /* send first round of data */ - - len = tcp_sndbuf(pcb); - len = LWIP_MIN(len, ns->data_len - ns->cntr); - len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); - - do { - err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); - if (err == ERR_MEM) { - len /= 2; - } - } while ((err == ERR_MEM) && (len > 1)); - - ns->buf_pos += len; - ns->cntr += len; - - } else { - /* unrecognized command, punt */ - ns->cntr = 0; - ns->buf_pos = 0; - ns->buf_ptr[0] = 0; - netio_close(ns, pcb); - break; - } - } - } else { - /* in trouble... shouldn't be in this state! */ - } - - } else if (ns->state == NETIO_STATE_RECV_DATA) { - - if(ns->cntr == 0){ - /* save the first byte of this new round of data - * this will not match ns->buf_ptr[0] in the case that - * NETIO_BUF_SIZE is less than ns->data_len. - */ - ns->first_byte = *data_ptr; - } - - ns->buf_ptr[ns->buf_pos++] = *data_ptr++; - ns->cntr++; - - if (ns->buf_pos == NETIO_BUF_SIZE) { - /* circularize the buffer */ - ns->buf_pos = 0; - } - - if(ns->cntr == ns->data_len){ - ns->cntr = 0; - if (ns->first_byte != 0) { - /* if this last round did not start with 0, - * go look for another command */ - ns->state = NETIO_STATE_WAIT_FOR_CMD; - ns->data_len = 0; - ns->cmd = 0; - /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ - } else { - /* stay here and wait on more data */ - } - } - - } else if (ns->state == NETIO_STATE_SEND_DATA - || ns->state == NETIO_STATE_SEND_DATA_LAST) { - /* I don't think this should happen... */ - } else { - /* done / quit */ - netio_close(ns, pcb); - break; - } /* end of ns->state condition */ - } /* end of while data still in this pbuf */ - - q = q->next; - } - - pbuf_free(p); - - } else { - - /* error or closed by other side */ - if (p != NULL) { - pbuf_free(p); - } - - /* close the connection */ - netio_close(ns, pcb); - - } - return ERR_OK; - -} - -static err_t ICACHE_FLASH_ATTR -netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - struct netio_state *ns = arg; - err_t err = ERR_OK; - - if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) { - /* done with this round of sending */ - ns->buf_pos = 0; - ns->cntr = 0; - - /* check if timer expired */ - if (sys_now() - ns->time_stamp > 600) { - ns->buf_ptr[0] = 1; - ns->state = NETIO_STATE_SEND_DATA_LAST; - } else { - ns->buf_ptr[0] = 0; - } - } - - if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){ - len = tcp_sndbuf(pcb); - len = LWIP_MIN(len, ns->data_len - ns->cntr); - len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); - - if(ns->cntr < ns->data_len){ - do { - err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); - if (err == ERR_MEM) { - len /= 2; - } - } while ((err == ERR_MEM) && (len > 1)); - - ns->buf_pos += len; - if(ns->buf_pos >= NETIO_BUF_SIZE){ - ns->buf_pos = 0; - } - - ns->cntr += len; - } - } - - if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){ - /* we have buffered up all our data to send this last round, go look for a command */ - ns->state = NETIO_STATE_WAIT_FOR_CMD; - ns->cntr = 0; - /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ - } - - return ERR_OK; -} - -static err_t ICACHE_FLASH_ATTR -netio_poll(void *arg, struct tcp_pcb *pcb) -{ - struct netio_state * ns = arg; - if(ns->state == NETIO_STATE_SEND_DATA){ - - } else if(ns->state == NETIO_STATE_DONE){ - netio_close(ns, pcb); - } - - return ERR_OK; - -} - -#if NETIO_USE_STATIC_BUF == 1 -static u8_t netio_buf[NETIO_BUF_SIZE]; -#endif - -static err_t ICACHE_FLASH_ATTR -netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) -{ - struct netio_state * ns; - - LWIP_UNUSED_ARG(err); - - ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state)); - - if(ns == NULL){ - return ERR_MEM; - } - - ns->state = NETIO_STATE_WAIT_FOR_CMD; - ns->data_len = 0; - ns->cmd = 0; - ns->cntr = 0; - ns->buf_pos = 0; -#if NETIO_USE_STATIC_BUF == 1 - ns->buf_ptr = netio_buf; -#else - ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE); - - if(ns->buf_ptr == NULL){ - mem_free(ns); - return ERR_MEM; - } -#endif - - ns->buf_ptr[0] = 0; - - tcp_arg(pcb, ns); - tcp_sent(pcb, netio_sent); - tcp_recv(pcb, netio_recv); - tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */ - return ERR_OK; -} - -void ICACHE_FLASH_ATTR netio_init(void) -{ - struct tcp_pcb *pcb; - - pcb = tcp_new(); - tcp_bind(pcb, IP_ADDR_ANY, 18767); - pcb = tcp_listen(pcb); - tcp_accept(pcb, netio_accept); -} - -#endif /* LWIP_TCP */ +/** + * @file + * MetIO Server + * + */ + +/* + * 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. + * + */ +#include "lwip/opt.h" + extern u32_t sys_now(void); + +#if LWIP_TCP +#include "lwip/tcp.h" + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; +#endif + + +#define ICACHE_FLASH_ATTR + +/* + * This implements a netio server. + * The client sends a command word (4 bytes) then a data length word (4 bytes). + * If the command is "receive", the server is to consume "data length" bytes into + * a circular buffer until the first byte is non-zero, then it is to consume + * another command/data pair. + * If the command is "send", the server is to send "data length" bytes from a circular + * buffer with the first byte being zero, until "some time" (6 seconds in the + * current netio126.zip download) has passed and then send one final buffer with + * the first byte being non-zero. Then it is to consume another command/data pair. + */ + +/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */ + +/* implementation options */ +#define NETIO_BUF_SIZE (4 * 1024) +#define NETIO_USE_STATIC_BUF 0 + +/* NetIO server state definition */ +#define NETIO_STATE_WAIT_FOR_CMD 0 +#define NETIO_STATE_RECV_DATA 1 +#define NETIO_STATE_SEND_DATA 2 +#define NETIO_STATE_SEND_DATA_LAST 3 +#define NETIO_STATE_DONE 4 + +struct netio_state { + u32_t state; + u32_t cmd; + u32_t data_len; + u32_t cntr; + u8_t * buf_ptr; + u32_t buf_pos; + u32_t first_byte; + u32_t time_stamp; +}; + +/* NetIO command protocol definition */ +#define NETIO_CMD_QUIT 0 +#define NETIO_CMD_C2S 1 +#define NETIO_CMD_S2C 2 +#define NETIO_CMD_RES 3 + +static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); + +static void ICACHE_FLASH_ATTR +netio_close(void *arg, struct tcp_pcb *pcb) +{ + err_t err; + + struct netio_state *ns = arg; + ns->state = NETIO_STATE_DONE; + tcp_recv(pcb, NULL); + err = tcp_close(pcb); + + if (err != ERR_OK) { + /* closing failed, try again later */ + tcp_recv(pcb, netio_recv); + } else { + /* closing succeeded */ +#if NETIO_USE_STATIC_BUF != 1 + if(ns->buf_ptr != NULL){ + mem_free(ns->buf_ptr); + } +#endif + tcp_arg(pcb, NULL); + tcp_poll(pcb, NULL, 0); + tcp_sent(pcb, NULL); + if (arg != NULL) { + mem_free(arg); + } + } +} + +static err_t ICACHE_FLASH_ATTR +netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct netio_state *ns = arg; + u8_t * data_ptr; + u32_t data_cntr; + struct pbuf *q = p; + u16_t len; + + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + } + + if (err == ERR_OK && q != NULL) { + + while (q != NULL) { + data_cntr = q->len; + data_ptr = q->payload; + while (data_cntr--) { + if (ns->state == NETIO_STATE_DONE){ + netio_close(ns, pcb); + break; + } else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) { + if (ns->cntr < 4) { + /* build up the CMD field */ + ns->cmd <<= 8; + ns->cmd |= *data_ptr++; + ns->cntr++; + } else if (ns->cntr < 8) { + /* build up the DATA field */ + ns->data_len <<= 8; + ns->data_len |= *data_ptr++; + ns->cntr++; + + if (ns->cntr == 8) { + /* now we have full command and data words */ + ns->cntr = 0; + ns->buf_pos = 0; + ns->buf_ptr[0] = 0; + if (ns->cmd == NETIO_CMD_C2S) { + ns->state = NETIO_STATE_RECV_DATA; + } else if (ns->cmd == NETIO_CMD_S2C) { + ns->state = NETIO_STATE_SEND_DATA; + /* start timer */ + ns->time_stamp = sys_now(); + /* send first round of data */ + + len = tcp_sndbuf(pcb); + len = LWIP_MIN(len, ns->data_len - ns->cntr); + len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); + + do { + err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); + if (err == ERR_MEM) { + len /= 2; + } + } while ((err == ERR_MEM) && (len > 1)); + + ns->buf_pos += len; + ns->cntr += len; + + } else { + /* unrecognized command, punt */ + ns->cntr = 0; + ns->buf_pos = 0; + ns->buf_ptr[0] = 0; + netio_close(ns, pcb); + break; + } + } + } else { + /* in trouble... shouldn't be in this state! */ + } + + } else if (ns->state == NETIO_STATE_RECV_DATA) { + + if(ns->cntr == 0){ + /* save the first byte of this new round of data + * this will not match ns->buf_ptr[0] in the case that + * NETIO_BUF_SIZE is less than ns->data_len. + */ + ns->first_byte = *data_ptr; + } + + ns->buf_ptr[ns->buf_pos++] = *data_ptr++; + ns->cntr++; + + if (ns->buf_pos == NETIO_BUF_SIZE) { + /* circularize the buffer */ + ns->buf_pos = 0; + } + + if(ns->cntr == ns->data_len){ + ns->cntr = 0; + if (ns->first_byte != 0) { + /* if this last round did not start with 0, + * go look for another command */ + ns->state = NETIO_STATE_WAIT_FOR_CMD; + ns->data_len = 0; + ns->cmd = 0; + /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ + } else { + /* stay here and wait on more data */ + } + } + + } else if (ns->state == NETIO_STATE_SEND_DATA + || ns->state == NETIO_STATE_SEND_DATA_LAST) { + /* I don't think this should happen... */ + } else { + /* done / quit */ + netio_close(ns, pcb); + break; + } /* end of ns->state condition */ + } /* end of while data still in this pbuf */ + + q = q->next; + } + + pbuf_free(p); + + } else { + + /* error or closed by other side */ + if (p != NULL) { + pbuf_free(p); + } + + /* close the connection */ + netio_close(ns, pcb); + + } + return ERR_OK; + +} + +static err_t ICACHE_FLASH_ATTR +netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct netio_state *ns = arg; + err_t err = ERR_OK; + + if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) { + /* done with this round of sending */ + ns->buf_pos = 0; + ns->cntr = 0; + + /* check if timer expired */ + if (sys_now() - ns->time_stamp > 600) { + ns->buf_ptr[0] = 1; + ns->state = NETIO_STATE_SEND_DATA_LAST; + } else { + ns->buf_ptr[0] = 0; + } + } + + if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){ + len = tcp_sndbuf(pcb); + len = LWIP_MIN(len, ns->data_len - ns->cntr); + len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); + + if(ns->cntr < ns->data_len){ + do { + err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); + if (err == ERR_MEM) { + len /= 2; + } + } while ((err == ERR_MEM) && (len > 1)); + + ns->buf_pos += len; + if(ns->buf_pos >= NETIO_BUF_SIZE){ + ns->buf_pos = 0; + } + + ns->cntr += len; + } + } + + if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){ + /* we have buffered up all our data to send this last round, go look for a command */ + ns->state = NETIO_STATE_WAIT_FOR_CMD; + ns->cntr = 0; + /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ + } + + return ERR_OK; +} + +static err_t ICACHE_FLASH_ATTR +netio_poll(void *arg, struct tcp_pcb *pcb) +{ + struct netio_state * ns = arg; + if(ns->state == NETIO_STATE_SEND_DATA){ + + } else if(ns->state == NETIO_STATE_DONE){ + netio_close(ns, pcb); + } + + return ERR_OK; + +} + +#if NETIO_USE_STATIC_BUF == 1 +static u8_t netio_buf[NETIO_BUF_SIZE]; +#endif + +static err_t ICACHE_FLASH_ATTR +netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct netio_state * ns; + + LWIP_UNUSED_ARG(err); + + ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state)); + + if(ns == NULL){ + return ERR_MEM; + } + + ns->state = NETIO_STATE_WAIT_FOR_CMD; + ns->data_len = 0; + ns->cmd = 0; + ns->cntr = 0; + ns->buf_pos = 0; +#if NETIO_USE_STATIC_BUF == 1 + ns->buf_ptr = netio_buf; +#else + ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE); + + if(ns->buf_ptr == NULL){ + mem_free(ns); + return ERR_MEM; + } +#endif + + ns->buf_ptr[0] = 0; + + tcp_arg(pcb, ns); + tcp_sent(pcb, netio_sent); + tcp_recv(pcb, netio_recv); + tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */ + return ERR_OK; +} + +void ICACHE_FLASH_ATTR netio_init(void) +{ + struct tcp_pcb *pcb; + + pcb = tcp_new(); + tcp_bind(pcb, IP_ADDR_ANY, 18767); + pcb = tcp_listen(pcb); + tcp_accept(pcb, netio_accept); +} + +#endif /* LWIP_TCP */ diff --git a/LuaNode_Esp32/LuaNode32/components/lpeg/Kconfig b/LuaNode_Esp32/LuaNode32/components/lpeg/Kconfig index f37cebd..c7bec6d 100644 --- a/LuaNode_Esp32/LuaNode32/components/lpeg/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/lpeg/Kconfig @@ -1,9 +1,9 @@ -menu "lpeg" - -config LPEG_ENABLE - bool "Enable lpeg" - default "y" - help - For lpeg. - -endmenu +menu "lpeg" + +config LPEG_ENABLE + bool "Enable lpeg" + default "y" + help + For lpeg. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/lua/Kconfig b/LuaNode_Esp32/LuaNode32/components/lua/Kconfig index 0725764..d58dc2d 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/lua/Kconfig @@ -1,9 +1,9 @@ -menu "LUA" - -config LUA_ENABLE - bool "Enable lua" - default "y" - help - For lua script. - -endmenu +menu "LUA" + +config LUA_ENABLE + bool "Enable lua" + default "y" + help + For lua script. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/modules/Kconfig b/LuaNode_Esp32/LuaNode32/components/modules/Kconfig index 75d53b7..d1780fd 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/modules/Kconfig @@ -1,9 +1,9 @@ -menu "MODULES" - -config MODULES_ENABLE - bool "Enable modules" - default "y" - help - For modules. - -endmenu +menu "MODULES" + +config MODULES_ENABLE + bool "Enable modules" + default "y" + help + For modules. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/modules/nvs.c b/LuaNode_Esp32/LuaNode32/components/modules/nvs.c index 56e3d23..6ae5f36 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/nvs.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/nvs.c @@ -1,322 +1,322 @@ -/** - * NVS module for Lua - * - * function is not support now - * - * Nicholas3388 - * 2017. 04.10 - */ -#include "lua.h" -#include "lauxlib.h" -#include "lualib.h" -#include "lrotable.h" -#include "lualib.h" -#include "user_config.h" -#include "esp_system.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "nvs.h" - -static const char *TAG = "nvs_lua_mod"; -static nvs_handle handle; -static int is_open = 0; - -static bool key_exist( lua_State* L, const char *key ) -{ - bool res = false; - int32_t out_value = 4096; - esp_err_t err = nvs_get_i32(handle, key, &out_value); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - res = false; - break; - case ESP_OK: - res = true; - break; - default: - break; - } - - uint8_t out_str[128]; - size_t length = sizeof(out_str); - err = nvs_get_str(handle, key, out_str, &length); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - res = false; - break; - case ESP_OK: - res = true; - break; - default: - break; - } - return res; -} - -// ret = nvs.exist(key) -// ret=1 if key exist, otherwise, ret=0 -static int lnvs_key_exist( lua_State* L ) -{ - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 1) { - return luaL_error( L, "expected 1 args" ); - } - - const char *key = luaL_checklstring( L, 1, &sl ); - if (key == NULL) { - return luaL_error( L, "the key is null" ); - } - - if (key_exist(L, key)) { - lua_pushinteger(L, 1); - return 1; - } - - lua_pushinteger(L, 0); - return 1; -} - -// res = nvs.open() -// res=0 if open successfully, otherwise, failed -static int lnvs_open( lua_State* L ) -{ - int res = 0; - esp_err_t err = nvs_open("storage", NVS_READWRITE, &handle); - if (err != ESP_OK) { - res = 1; - is_open = 0; - } else { - res = 0; - is_open = 1; - } - lua_pushinteger(L, res); - return 1; -} - -// nvs.close() -static int lnvs_close( lua_State* L ) -{ - nvs_close(handle); - is_open = 0; - return 0; -} - -// res = nvs.put(key, value) -// key: string type -// value: table/string/data/boolean -static int lnvs_put( lua_State* L ) -{ - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 2) { - return luaL_error( L, "expected 2 args" ); - } - - const char *key = luaL_checklstring( L, 1, &sl ); - if (key == NULL) { - return luaL_error( L, "the key is null" ); - } - - if (key_exist(L, key)) { - return luaL_error( L, "key exist! call nvs.remove to remove it first" ); - } - - if (lua_type(L, 2) == LUA_TTABLE) { - ESP_LOGE(TAG, "param is table"); - goto ret_err; - } else if (lua_type(L, 2) == LUA_TSTRING) { - const char *val = luaL_checklstring( L, 2, &sl ); - esp_err_t err = nvs_set_str (handle, key, val); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs set error"); - goto ret_err; - } - err = nvs_commit(handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs commit error"); - goto ret_err; - } - } else if (lua_type(L, 2) == LUA_TNUMBER) { - int val = luaL_checknumber( L, 2 ); - esp_err_t err = nvs_set_i32 (handle, key, val); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs set error"); - goto ret_err; - } - err = nvs_commit(handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs commit error"); - goto ret_err; - } - } else if (lua_type(L, 2) == LUA_TBOOLEAN) { - ESP_LOGI(TAG, "param is boolean"); - bool val = (lua_toboolean(L, 2) ? true : false); - int saveVal = (val? 1:0); - esp_err_t err = nvs_set_i32 (handle, key, saveVal); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs set error"); - goto ret_err; - } - err = nvs_commit(handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs commit error"); - goto ret_err; - } - } else { - ESP_LOGI(TAG, "unknown param type"); - goto ret_err; - } - - lua_pushinteger(L, 0); - return 1; -ret_err: - lua_pushinteger(L, 1); - return 1; -} - -// value = nvs.get(key) -static int lnvs_get( lua_State* L ) -{ - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 1) { - return luaL_error( L, "expected at least 1 args" ); - } - - int32_t out_value = 4096; - const char *key = luaL_checklstring( L, 1, &sl ); - - - esp_err_t err = nvs_get_i32(handle, key, &out_value); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - //ESP_LOGE(TAG, "value not found"); - break; - case ESP_ERR_NVS_INVALID_HANDLE: - return luaL_error( L, "invalid nvs handle" ); - case ESP_ERR_NVS_INVALID_NAME: - return luaL_error( L, "invalid name" ); - case ESP_ERR_NVS_INVALID_LENGTH: - break; - case ESP_OK: - lua_pushinteger(L, out_value); - return 1; - default: - break; - } - - uint8_t out_str[128]; - size_t length = sizeof(out_str); - err = nvs_get_str(handle, key, out_str, &length); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - ESP_LOGE(TAG, "value not found"); - lua_pushnil(L); - break; - case ESP_ERR_NVS_INVALID_HANDLE: - return luaL_error( L, "invalid nvs handle" ); - case ESP_ERR_NVS_INVALID_NAME: - return luaL_error( L, "invalid name" ); - case ESP_ERR_NVS_INVALID_LENGTH: - break; - case ESP_OK: - lua_pushlstring(L, out_str, length); - return 1; - default: - break; - } - - return 1; -} - -// res = nvs.remove(key) -// res=0 if remove successfully, otherwise, res!=0 -static int lnvs_remove( lua_State* L ) -{ - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 1) { - return luaL_error( L, "expected 1 args" ); - } - - const char *key = luaL_checklstring( L, 1, &sl ); - if (key == NULL) { - return luaL_error( L, "the key is null" ); - } - - if (!key_exist(L, key)) { - return luaL_error( L, "key doesn't exist!" ); - } - - esp_err_t err = nvs_erase_key(handle, key); - - switch (err) - { - case ESP_OK: - break; - case ESP_ERR_NVS_INVALID_HANDLE: - return luaL_error( L, "invalid handle" ); - case ESP_ERR_NVS_READ_ONLY: - return luaL_error( L, "nvs is readonly" ); - default: - break; - } - - lua_pushinteger(L, 0); - return 1; -} - -// res = nvs.clearall() -static int lnvs_clearall( lua_State* L ) -{ - int res = 0; - esp_err_t err = nvs_erase_all(handle); - if (err != ESP_OK) { - res = 1; - } - lua_pushinteger(L, res); - return 1; -} - - -#include "lrodefs.h" - -const LUA_REG_TYPE nvs_map[] = -{ - { LSTRKEY( "open" ), LFUNCVAL( lnvs_open ) }, - { LSTRKEY( "close" ), LFUNCVAL( lnvs_close ) }, - { LSTRKEY( "put" ), LFUNCVAL( lnvs_put ) }, - { LSTRKEY( "get" ), LFUNCVAL( lnvs_get ) }, - { LSTRKEY( "remove" ), LFUNCVAL( lnvs_remove ) }, - { LSTRKEY( "clearall" ), LFUNCVAL( lnvs_clearall ) }, - { LSTRKEY( "exist" ), LFUNCVAL( lnvs_key_exist ) }, - {LNILKEY, LNILVAL} -}; - -int luaopen_nvs(lua_State *L) -{ - // pre-handle - return 0; -} - +/** + * NVS module for Lua + * + * function is not support now + * + * Nicholas3388 + * 2017. 04.10 + */ +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#include "lrotable.h" +#include "lualib.h" +#include "user_config.h" +#include "esp_system.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "nvs.h" + +static const char *TAG = "nvs_lua_mod"; +static nvs_handle handle; +static int is_open = 0; + +static bool key_exist( lua_State* L, const char *key ) +{ + bool res = false; + int32_t out_value = 4096; + esp_err_t err = nvs_get_i32(handle, key, &out_value); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + res = false; + break; + case ESP_OK: + res = true; + break; + default: + break; + } + + uint8_t out_str[128]; + size_t length = sizeof(out_str); + err = nvs_get_str(handle, key, out_str, &length); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + res = false; + break; + case ESP_OK: + res = true; + break; + default: + break; + } + return res; +} + +// ret = nvs.exist(key) +// ret=1 if key exist, otherwise, ret=0 +static int lnvs_key_exist( lua_State* L ) +{ + size_t sl = 0; + if (is_open != 1) { + return luaL_error( L, "call nvs.open first" ); + } + + int argc = lua_gettop(L); + if (argc < 1) { + return luaL_error( L, "expected 1 args" ); + } + + const char *key = luaL_checklstring( L, 1, &sl ); + if (key == NULL) { + return luaL_error( L, "the key is null" ); + } + + if (key_exist(L, key)) { + lua_pushinteger(L, 1); + return 1; + } + + lua_pushinteger(L, 0); + return 1; +} + +// res = nvs.open() +// res=0 if open successfully, otherwise, failed +static int lnvs_open( lua_State* L ) +{ + int res = 0; + esp_err_t err = nvs_open("storage", NVS_READWRITE, &handle); + if (err != ESP_OK) { + res = 1; + is_open = 0; + } else { + res = 0; + is_open = 1; + } + lua_pushinteger(L, res); + return 1; +} + +// nvs.close() +static int lnvs_close( lua_State* L ) +{ + nvs_close(handle); + is_open = 0; + return 0; +} + +// res = nvs.put(key, value) +// key: string type +// value: table/string/data/boolean +static int lnvs_put( lua_State* L ) +{ + size_t sl = 0; + if (is_open != 1) { + return luaL_error( L, "call nvs.open first" ); + } + + int argc = lua_gettop(L); + if (argc < 2) { + return luaL_error( L, "expected 2 args" ); + } + + const char *key = luaL_checklstring( L, 1, &sl ); + if (key == NULL) { + return luaL_error( L, "the key is null" ); + } + + if (key_exist(L, key)) { + return luaL_error( L, "key exist! call nvs.remove to remove it first" ); + } + + if (lua_type(L, 2) == LUA_TTABLE) { + ESP_LOGE(TAG, "param is table"); + goto ret_err; + } else if (lua_type(L, 2) == LUA_TSTRING) { + const char *val = luaL_checklstring( L, 2, &sl ); + esp_err_t err = nvs_set_str (handle, key, val); + if (err != ESP_OK) { + ESP_LOGE(TAG, "nvs set error"); + goto ret_err; + } + err = nvs_commit(handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "nvs commit error"); + goto ret_err; + } + } else if (lua_type(L, 2) == LUA_TNUMBER) { + int val = luaL_checknumber( L, 2 ); + esp_err_t err = nvs_set_i32 (handle, key, val); + if (err != ESP_OK) { + ESP_LOGE(TAG, "nvs set error"); + goto ret_err; + } + err = nvs_commit(handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "nvs commit error"); + goto ret_err; + } + } else if (lua_type(L, 2) == LUA_TBOOLEAN) { + ESP_LOGI(TAG, "param is boolean"); + bool val = (lua_toboolean(L, 2) ? true : false); + int saveVal = (val? 1:0); + esp_err_t err = nvs_set_i32 (handle, key, saveVal); + if (err != ESP_OK) { + ESP_LOGE(TAG, "nvs set error"); + goto ret_err; + } + err = nvs_commit(handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "nvs commit error"); + goto ret_err; + } + } else { + ESP_LOGI(TAG, "unknown param type"); + goto ret_err; + } + + lua_pushinteger(L, 0); + return 1; +ret_err: + lua_pushinteger(L, 1); + return 1; +} + +// value = nvs.get(key) +static int lnvs_get( lua_State* L ) +{ + size_t sl = 0; + if (is_open != 1) { + return luaL_error( L, "call nvs.open first" ); + } + + int argc = lua_gettop(L); + if (argc < 1) { + return luaL_error( L, "expected at least 1 args" ); + } + + int32_t out_value = 4096; + const char *key = luaL_checklstring( L, 1, &sl ); + + + esp_err_t err = nvs_get_i32(handle, key, &out_value); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + //ESP_LOGE(TAG, "value not found"); + break; + case ESP_ERR_NVS_INVALID_HANDLE: + return luaL_error( L, "invalid nvs handle" ); + case ESP_ERR_NVS_INVALID_NAME: + return luaL_error( L, "invalid name" ); + case ESP_ERR_NVS_INVALID_LENGTH: + break; + case ESP_OK: + lua_pushinteger(L, out_value); + return 1; + default: + break; + } + + uint8_t out_str[128]; + size_t length = sizeof(out_str); + err = nvs_get_str(handle, key, out_str, &length); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGE(TAG, "value not found"); + lua_pushnil(L); + break; + case ESP_ERR_NVS_INVALID_HANDLE: + return luaL_error( L, "invalid nvs handle" ); + case ESP_ERR_NVS_INVALID_NAME: + return luaL_error( L, "invalid name" ); + case ESP_ERR_NVS_INVALID_LENGTH: + break; + case ESP_OK: + lua_pushlstring(L, out_str, length); + return 1; + default: + break; + } + + return 1; +} + +// res = nvs.remove(key) +// res=0 if remove successfully, otherwise, res!=0 +static int lnvs_remove( lua_State* L ) +{ + size_t sl = 0; + if (is_open != 1) { + return luaL_error( L, "call nvs.open first" ); + } + + int argc = lua_gettop(L); + if (argc < 1) { + return luaL_error( L, "expected 1 args" ); + } + + const char *key = luaL_checklstring( L, 1, &sl ); + if (key == NULL) { + return luaL_error( L, "the key is null" ); + } + + if (!key_exist(L, key)) { + return luaL_error( L, "key doesn't exist!" ); + } + + esp_err_t err = nvs_erase_key(handle, key); + + switch (err) + { + case ESP_OK: + break; + case ESP_ERR_NVS_INVALID_HANDLE: + return luaL_error( L, "invalid handle" ); + case ESP_ERR_NVS_READ_ONLY: + return luaL_error( L, "nvs is readonly" ); + default: + break; + } + + lua_pushinteger(L, 0); + return 1; +} + +// res = nvs.clearall() +static int lnvs_clearall( lua_State* L ) +{ + int res = 0; + esp_err_t err = nvs_erase_all(handle); + if (err != ESP_OK) { + res = 1; + } + lua_pushinteger(L, res); + return 1; +} + + +#include "lrodefs.h" + +const LUA_REG_TYPE nvs_map[] = +{ + { LSTRKEY( "open" ), LFUNCVAL( lnvs_open ) }, + { LSTRKEY( "close" ), LFUNCVAL( lnvs_close ) }, + { LSTRKEY( "put" ), LFUNCVAL( lnvs_put ) }, + { LSTRKEY( "get" ), LFUNCVAL( lnvs_get ) }, + { LSTRKEY( "remove" ), LFUNCVAL( lnvs_remove ) }, + { LSTRKEY( "clearall" ), LFUNCVAL( lnvs_clearall ) }, + { LSTRKEY( "exist" ), LFUNCVAL( lnvs_key_exist ) }, + {LNILKEY, LNILVAL} +}; + +int luaopen_nvs(lua_State *L) +{ + // pre-handle + return 0; +} + diff --git a/LuaNode_Esp32/LuaNode32/components/modules/utils.c b/LuaNode_Esp32/LuaNode32/components/modules/utils.c index 1e467d5..49aee27 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/utils.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/utils.c @@ -1,96 +1,96 @@ -// libutils.a -#include -#include "modules.h" -#include "lauxlib.h" -#include "c_string.h" -#include "base64.h" -#include "datetime.h" -//#include "md5.h" -#include "lualib.h" - -/** - * translate Hex to String - * pbDest: the memory to stored encoding string - * pbSrc: the input hex - * nLen: the length of hex - */ -void HexToStr(unsigned char *pbDest, unsigned char *pbSrc, int nLen) -{ - char ddl,ddh; - int i; - - for (i=0; i 57) ddh = ddh + 7; - if (ddl > 57) ddl = ddl + 7; - pbDest[i*2] = ddh; - pbDest[i*2+1] = ddl; - } - - pbDest[nLen*2] = '\0'; -} - -// return the lenght of encoding string -static int base64_encode0( lua_State* L ) { - int argc = lua_gettop(L); - const char *str = lua_tostring(L, 1); - char *buff = malloc(strlen(str) * 2); - memset(buff, 0, strlen(str)*2); - int num = base64_encode(str, strlen(str), buff, 1); - lua_pushstring(L, buff); - return 1; -} - -// return the length of decoding string -static int base64_decode0( lua_State* L ) { - int argc = lua_gettop(L); - const char *str = lua_tostring(L, 1); - char *buff = malloc(strlen(str) * 2); - memset(buff, 0, strlen(str)*2); - int num = base64_decode(str, buff); - lua_pushstring(L, buff); - return 1; -} - -static int leapyear0( lua_State* L ) { - int year = lua_tointeger(L, 1); - int isLeap = isLeapyear(year); - lua_pushboolean(L, isLeap); - return 1; -} - -// md5 encode, return the encoding string -/*static int md5_encode( lua_State* L ) { - unsigned char *str = (unsigned char *)lua_tostring(L, 1); // string to be encoded - char digest[16]; - char ecrypt[32]; - memset(digest, 0, 16); - memset(ecrypt, 0, 32); - MD5_CTX md5; - MD5Init(&md5); - MD5Update(&md5, str, strlen(str)); - MD5Final(&md5, digest); - HexToStr(ecrypt, digest, strlen(digest)); - lua_pushstring(L, ecrypt); - return 1; -}*/ - -// Module function map -const LUA_REG_TYPE utils_map[] = { - { LSTRKEY( "base64_encode" ), LFUNCVAL( base64_encode0 ) }, - { LSTRKEY( "base64_decode" ), LFUNCVAL( base64_decode0 ) }, - //{ LSTRKEY( "md5_encode" ), LFUNCVAL( md5_encode ) }, - { LSTRKEY( "leapyear" ), LFUNCVAL( leapyear0 ) }, - { LNILKEY, LNILVAL } -}; - -LUALIB_API int luaopen_utils(lua_State *L) -{ -#if LUA_OPTIMIZE_MEMORY > 0 - return 0; -#else - luaL_register( L, LUA_UTILSLIBNAME, utils_map ); - return 1; -#endif -} +// libutils.a +#include +#include "modules.h" +#include "lauxlib.h" +#include "c_string.h" +#include "base64.h" +#include "datetime.h" +//#include "md5.h" +#include "lualib.h" + +/** + * translate Hex to String + * pbDest: the memory to stored encoding string + * pbSrc: the input hex + * nLen: the length of hex + */ +void HexToStr(unsigned char *pbDest, unsigned char *pbSrc, int nLen) +{ + char ddl,ddh; + int i; + + for (i=0; i 57) ddh = ddh + 7; + if (ddl > 57) ddl = ddl + 7; + pbDest[i*2] = ddh; + pbDest[i*2+1] = ddl; + } + + pbDest[nLen*2] = '\0'; +} + +// return the lenght of encoding string +static int base64_encode0( lua_State* L ) { + int argc = lua_gettop(L); + const char *str = lua_tostring(L, 1); + char *buff = malloc(strlen(str) * 2); + memset(buff, 0, strlen(str)*2); + int num = base64_encode(str, strlen(str), buff, 1); + lua_pushstring(L, buff); + return 1; +} + +// return the length of decoding string +static int base64_decode0( lua_State* L ) { + int argc = lua_gettop(L); + const char *str = lua_tostring(L, 1); + char *buff = malloc(strlen(str) * 2); + memset(buff, 0, strlen(str)*2); + int num = base64_decode(str, buff); + lua_pushstring(L, buff); + return 1; +} + +static int leapyear0( lua_State* L ) { + int year = lua_tointeger(L, 1); + int isLeap = isLeapyear(year); + lua_pushboolean(L, isLeap); + return 1; +} + +// md5 encode, return the encoding string +/*static int md5_encode( lua_State* L ) { + unsigned char *str = (unsigned char *)lua_tostring(L, 1); // string to be encoded + char digest[16]; + char ecrypt[32]; + memset(digest, 0, 16); + memset(ecrypt, 0, 32); + MD5_CTX md5; + MD5Init(&md5); + MD5Update(&md5, str, strlen(str)); + MD5Final(&md5, digest); + HexToStr(ecrypt, digest, strlen(digest)); + lua_pushstring(L, ecrypt); + return 1; +}*/ + +// Module function map +const LUA_REG_TYPE utils_map[] = { + { LSTRKEY( "base64_encode" ), LFUNCVAL( base64_encode0 ) }, + { LSTRKEY( "base64_decode" ), LFUNCVAL( base64_decode0 ) }, + //{ LSTRKEY( "md5_encode" ), LFUNCVAL( md5_encode ) }, + { LSTRKEY( "leapyear" ), LFUNCVAL( leapyear0 ) }, + { LNILKEY, LNILVAL } +}; + +LUALIB_API int luaopen_utils(lua_State *L) +{ +#if LUA_OPTIMIZE_MEMORY > 0 + return 0; +#else + luaL_register( L, LUA_UTILSLIBNAME, utils_map ); + return 1; +#endif +} diff --git a/LuaNode_Esp32/LuaNode32/components/modules/wifi.c b/LuaNode_Esp32/LuaNode32/components/modules/wifi.c index d4e931b..b7de8b4 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/wifi.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/wifi.c @@ -1,591 +1,591 @@ -// Module for interfacing with WIFI - -#include "modules.h" -#include "lauxlib.h" -#include "platform.h" -#include "lualib.h" -#include "lua.h" -#include "lrodefs.h" -#include "lrotable.h" - -#include "c_string.h" -#include "c_stdlib.h" - -#include "c_types.h" -#include "user_interface.h" -#include "user_config.h" -#include "esp_sta.h" -#include "esp_phy.h" -#include "esp_timer.h" -#include "esp_softap.h" -#include "esp_misc.h" -#include "nodemcu_esp_event.h" -//#include "smart.h" -//#include "smartconfig.h" -#include "c_stdio.h" -#include "ip_fmt.h" - -typedef void (*fill_cb_arg_fn) (lua_State *L, const system_event_t *evt); -typedef struct -{ - const char *name; - system_event_id_t event_id; - fill_cb_arg_fn fill_cb_arg; -} event_desc_t; - - -typedef enum _sta_status { - STA_IDLE = 0, - STA_CONNECTING, - STA_WRONGPWD, - STA_APNOTFOUND, - STA_FAIL, - STA_GOTIP -} STA_STATUS; - -typedef enum _phy_mode { - PHYMODE_B = 0, - PHYMODE_G, - PHYMODE_N -} PHY_MODE; - -#define NULL_MODE 0x00 -#define STATION_MODE 0x01 -#define SOFTAP_MODE 0x02 -#define STATIONAP_MODE 0x03 - -#define STATION_IF 0x00 -#define SOFTAP_IF 0x01 - -#define DEFAULT_AP_CHANNEL 11 -#define DEFAULT_AP_MAXCONNS 4 -#define DEFAULT_AP_BEACON 100 - -static int wifi_smart_succeed = LUA_NOREF; -static uint8 getap_output_format=0; - -//wifi.sleep variables -#define FPM_SLEEP_MAX_TIME 0xFFFFFFF -static bool FLAG_wifi_force_sleep_enabled=0; - - -//variables for wifi event monitor -static sint32_t wifi_status_cb_ref[6] = {LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF}; -//static os_timer_t wifi_sta_status_timer; -static uint8 prev_wifi_status=0; - -// Forward declarations -static void on_event (const system_event_t *evt); - -static void sta_conn (lua_State *L, const system_event_t *evt); -static void sta_disconn (lua_State *L, const system_event_t *evt); -static void sta_authmode (lua_State *L, const system_event_t *evt); -static void sta_got_ip (lua_State *L, const system_event_t *evt); -static void ap_staconn (lua_State *L, const system_event_t *evt); -static void ap_stadisconn (lua_State *L, const system_event_t *evt); -static void ap_probe_req (lua_State *L, const system_event_t *evt); - -static void empty_arg (lua_State *L, const system_event_t *evt) {} - -static const event_desc_t events[] = -{ - { "sta_start", SYSTEM_EVENT_STA_START, empty_arg }, - { "sta_stop", SYSTEM_EVENT_STA_STOP, empty_arg }, - { "sta_connected", SYSTEM_EVENT_STA_CONNECTED, sta_conn }, - { "sta_disconnected", SYSTEM_EVENT_STA_DISCONNECTED, sta_disconn }, - { "sta_authmode_changed", SYSTEM_EVENT_STA_AUTHMODE_CHANGE, sta_authmode }, - { "sta_got_ip", SYSTEM_EVENT_STA_GOT_IP, sta_got_ip }, - - { "ap_start", SYSTEM_EVENT_AP_START, empty_arg }, - { "ap_stop", SYSTEM_EVENT_AP_STOP, empty_arg }, - { "ap_sta_connected", SYSTEM_EVENT_AP_STACONNECTED, ap_staconn }, - { "ap_sta_disconnected", SYSTEM_EVENT_AP_STADISCONNECTED, ap_stadisconn }, - { "ap_probe_req", SYSTEM_EVENT_AP_PROBEREQRECVED, ap_probe_req } -}; - -#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) -static int event_cb[ARRAY_LEN(events)]; - -nodemcu_esp_event_reg_t esp_event_cb_table[] = { - {SYSTEM_EVENT_STA_START, on_event}, - {SYSTEM_EVENT_STA_STOP, on_event}, - {SYSTEM_EVENT_STA_CONNECTED, on_event}, - {SYSTEM_EVENT_STA_DISCONNECTED, on_event}, - {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, on_event}, - {SYSTEM_EVENT_STA_GOT_IP, on_event}, - - {SYSTEM_EVENT_AP_START, on_event}, - {SYSTEM_EVENT_AP_STOP, on_event}, - {SYSTEM_EVENT_AP_STACONNECTED, on_event}, - {SYSTEM_EVENT_AP_STADISCONNECTED, on_event}, - {SYSTEM_EVENT_AP_PROBEREQRECVED, on_event}, -}; - - -#define SET_SAVE_MODE(save) \ - do { esp_err_t storage_err = \ - esp_wifi_set_storage (save ? WIFI_STORAGE_FLASH : WIFI_STORAGE_RAM); \ - if (storage_err != ESP_OK) \ - return luaL_error (L, "failed to update wifi storage, code %d", \ - storage_err); \ - } while(0) - - -bool luaL_optbool (lua_State *L, int idx, bool def) -{ - if (lua_isboolean (L, idx)) - return lua_toboolean (L, idx); - else - return def; -} - - -static lua_State* gL = NULL; -static int scan_cb_ref = LUA_NOREF; - -// Lua: realmode = getmode() - -static int wifi_getmode( lua_State* L ) -{ - wifi_mode_t mode; - esp_err_t err = esp_wifi_get_mode (&mode); - if (err != ESP_OK) - return luaL_error (L, "failed to get mode, code %d", err); - lua_pushinteger (L, mode); - return 1; -} - -static int event_idx_by_name (const char *name) -{ - for (unsigned i = 0; i < ARRAY_LEN(events); ++i) - if (strcmp (events[i].name, name) == 0) - return i; - return -1; -} - - -static int event_idx_by_id (system_event_id_t id) -{ - for (unsigned i = 0; i < ARRAY_LEN(events); ++i) - if (events[i].event_id == id) - return i; - return -1; -} - - -static void sta_conn (lua_State *L, const system_event_t *evt) -{ - lua_pushlstring (L, - (const char *)evt->event_info.connected.ssid, - evt->event_info.connected.ssid_len); - lua_setfield (L, -2, "ssid"); - - char bssid_str[MAC_STR_SZ]; - macstr (bssid_str, evt->event_info.connected.bssid); - lua_pushstring (L, bssid_str); - lua_setfield (L, -2, "bssid"); - - lua_pushinteger (L, evt->event_info.connected.channel); - lua_setfield (L, -2, "channel"); - - lua_pushinteger (L, evt->event_info.connected.authmode); - lua_setfield (L, -2, "auth"); -} - -static void sta_disconn (lua_State *L, const system_event_t *evt) -{ - lua_pushlstring (L, - (const char *)evt->event_info.disconnected.ssid, - evt->event_info.disconnected.ssid_len); - lua_setfield (L, -2, "ssid"); - - char bssid_str[MAC_STR_SZ]; - macstr (bssid_str, evt->event_info.disconnected.bssid); - lua_pushstring (L, bssid_str); - lua_setfield (L, -2, "bssid"); - - lua_pushinteger (L, evt->event_info.disconnected.reason); - lua_setfield (L, -2, "reason"); -} - -static void sta_authmode (lua_State *L, const system_event_t *evt) -{ - lua_pushinteger (L, evt->event_info.auth_change.old_mode); - lua_setfield (L, -2, "old_mode"); - lua_pushinteger (L, evt->event_info.auth_change.new_mode); - lua_setfield (L, -2, "new_mode"); -} - -static void sta_got_ip (lua_State *L, const system_event_t *evt) -{ - char ipstr[IP_STR_SZ] = { 0 }; - ip4str (ipstr, &evt->event_info.got_ip.ip_info.ip); - lua_pushstring (L, ipstr); - lua_setfield (L, -2, "ip"); - - ip4str (ipstr, &evt->event_info.got_ip.ip_info.netmask); - lua_pushstring (L, ipstr); - lua_setfield (L, -2, "netmask"); - - ip4str (ipstr, &evt->event_info.got_ip.ip_info.gw); - lua_pushstring (L, ipstr); - lua_setfield (L, -2, "gw"); -} - -static void ap_staconn (lua_State *L, const system_event_t *evt) -{ - char mac[MAC_STR_SZ]; - macstr (mac, evt->event_info.sta_connected.mac); - lua_pushstring (L, mac); - lua_setfield (L, -2, "mac"); - - lua_pushinteger (L, evt->event_info.sta_connected.aid); - lua_setfield (L, -2, "id"); -} - -static void ap_stadisconn (lua_State *L, const system_event_t *evt) -{ - char mac[MAC_STR_SZ]; - macstr (mac, evt->event_info.sta_disconnected.mac); - lua_pushstring (L, mac); - lua_setfield (L, -2, "mac"); - - lua_pushinteger (L, evt->event_info.sta_disconnected.aid); - lua_setfield (L, -2, "id"); -} - -static void ap_probe_req (lua_State *L, const system_event_t *evt) -{ - char str[MAC_STR_SZ]; - macstr (str, evt->event_info.ap_probereqrecved.mac); - lua_pushstring (L, str); - lua_setfield (L, -2, "from"); - - lua_pushinteger (L, evt->event_info.ap_probereqrecved.rssi); - lua_setfield (L, -2, "rssi"); -} - -static void on_event (const system_event_t *evt) -{ - int idx = event_idx_by_id (evt->event_id); - if (idx < 0 || event_cb[idx] == LUA_NOREF) - return; - - lua_State *L = lua_getstate (); - lua_rawgeti (L, LUA_REGISTRYINDEX, event_cb[idx]); - lua_pushstring (L, events[idx].name); - lua_createtable (L, 0, 5); - events[idx].fill_cb_arg (L, evt); - lua_call (L, 2, 0); -} - - -static int wifi_eventmon (lua_State *L) -{ - const char *event_name = luaL_checkstring (L, 1); - if (!lua_isnoneornil (L, 2)) - luaL_checkanyfunction (L, 2); - lua_settop (L, 2); - - int idx = event_idx_by_name (event_name); - if (idx < 0) - return luaL_error (L, "unknown event: %s", event_name); - - luaL_unref (L, LUA_REGISTRYINDEX, event_cb[idx]); - event_cb[idx] = lua_isnoneornil (L, 2) ? - LUA_NOREF : luaL_ref (L, LUA_REGISTRYINDEX); - - return 0; -} - -static int wifi_setmode (lua_State *L) -{ - int mode = luaL_checkinteger (L, 1); - wifi_mode_t tmp_mode; - esp_err_t err = esp_wifi_get_mode (&tmp_mode); - if (err == ESP_OK) { - if (tmp_mode == mode) { return 0; } - } - bool save = luaL_optbool (L, 2, false); - SET_SAVE_MODE(save); - switch (mode) - { - case WIFI_MODE_NULL: - case WIFI_MODE_STA: - case WIFI_MODE_AP: - case WIFI_MODE_APSTA: - return ((err = esp_wifi_set_mode (mode)) == ESP_OK) ? - 0 : luaL_error (L, "failed to set mode, code %d", err); - default: - return luaL_error (L, "invalid wifi mode %d", mode); - } -} - -static int wifi_start (lua_State *L) -{ - esp_err_t err = esp_wifi_start (); - return (err == ESP_OK) ? - 0 : luaL_error(L, "failed to start wifi, code %d", err); -} - -static int wifi_stop (lua_State *L) -{ - esp_err_t err = esp_wifi_stop (); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to stop wifi, code %d", err); -} - - -static int wifi_sta_config (lua_State *L) -{ - luaL_checkanytable (L, 1); - bool save = luaL_optbool (L, 2, false); - lua_settop (L, 1); - - wifi_config_t cfg; - memset (&cfg, 0, sizeof (cfg)); - - lua_getfield (L, 1, "ssid"); - size_t len; - const char *str = luaL_checklstring (L, -1, &len); - if (len > sizeof (cfg.sta.ssid)) - len = sizeof (cfg.sta.ssid); - strncpy (cfg.sta.ssid, str, len); - - lua_getfield (L, 1, "pwd"); - str = luaL_optlstring (L, -1, "", &len); - if (len > sizeof (cfg.sta.password)) - len = sizeof (cfg.sta.password); - strncpy (cfg.sta.password, str, len); - - lua_getfield (L, 1, "bssid"); - cfg.sta.bssid_set = false; - if (lua_isstring (L, -1)) - { - const char *bssid = luaL_checklstring (L, -1, &len); - const char *fmts[] = { - "%hhx%hhx%hhx%hhx%hhx%hhx", - "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", - "%hhx %hhx %hhx %hhx %hhx %hhx", - NULL - }; - for (unsigned i = 0; fmts[i]; ++i) - { - if (sscanf (bssid, fmts[i], - &cfg.sta.bssid[0], &cfg.sta.bssid[1], &cfg.sta.bssid[2], - &cfg.sta.bssid[3], &cfg.sta.bssid[4], &cfg.sta.bssid[5]) == 6) - { - cfg.sta.bssid_set = true; - break; - } - } - if (!cfg.sta.bssid_set) - return luaL_error (L, "invalid BSSID: %s", bssid); - } - - lua_getfield (L, 1, "auto"); - bool auto_conn = luaL_optbool (L, -1, true); - - SET_SAVE_MODE(save); - esp_err_t err = esp_wifi_set_config (WIFI_IF_STA, &cfg); - if (err != ESP_OK) - return luaL_error (L, "failed to set wifi config, code %d", err); - - if (auto_conn) - err = esp_wifi_connect (); - if (err != ESP_OK) - return luaL_error (L, "failed to begin connect, code %d", err); - - err = esp_wifi_set_auto_connect (auto_conn); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to set wifi auto-connect, code %d", err); -} - -static int wifi_sta_connect (lua_State *L) -{ - esp_err_t err = esp_wifi_connect (); - return (err == ESP_OK) ? 0 : luaL_error (L, "connect failed, code %d", err); -} - - -static int wifi_sta_disconnect (lua_State *L) -{ - esp_err_t err = esp_wifi_disconnect (); - return (err == ESP_OK) ? 0 : luaL_error(L, "disconnect failed, code %d", err); -} - -static int wifi_sta_getconfig (lua_State *L) -{ - wifi_config_t cfg; - esp_err_t err = esp_wifi_get_config (WIFI_IF_STA, &cfg); - if (err != ESP_OK) - return luaL_error (L, "failed to get config, code %d", err); - - lua_createtable (L, 0, 3); - size_t ssid_len = strnlen (cfg.sta.ssid, sizeof (cfg.sta.ssid)); - lua_pushlstring (L, cfg.sta.ssid, ssid_len); - lua_setfield (L, -2, "ssid"); - - size_t pwd_len = strnlen (cfg.sta.password, sizeof (cfg.sta.password)); - lua_pushlstring (L, cfg.sta.password, pwd_len); - lua_setfield (L, -2, "pwd"); - - if (cfg.sta.bssid_set) - { - char bssid_str[MAC_STR_SZ]; - macstr (bssid_str, cfg.sta.bssid); - lua_pushstring (L, bssid_str); - lua_setfield (L, -2, "bssid"); - } - - bool auto_conn; - err = esp_wifi_get_auto_connect (&auto_conn); - if (err != ESP_OK) - return luaL_error (L, "failed to get auto-connect, code %d", err); - - lua_pushboolean (L, auto_conn); - lua_setfield (L, -2, "auto"); - - return 1; -} - -static int wifi_sta_scan (lua_State *L) -{ - if (scan_cb_ref != LUA_NOREF) - return luaL_error (L, "scan already in progress"); - - luaL_checkanytable (L, 1); - - wifi_scan_config_t scan_cfg; - memset (&scan_cfg, 0, sizeof (scan_cfg)); - - // TODO: support ssid/bssid/channel/hidden features of wifi_scan_config_t - - luaL_checkanyfunction (L, 2); - lua_settop (L, 2); - scan_cb_ref = luaL_ref (L, LUA_REGISTRYINDEX); - - esp_err_t err = esp_wifi_scan_start (&scan_cfg, false); - if (err != ESP_OK) - { - luaL_unref (L, LUA_REGISTRYINDEX, scan_cb_ref); - scan_cb_ref = LUA_NOREF; - return luaL_error (L, "failed to start scan, code %d", err); - } - else - return 0; -} - -static int wifi_ap_config (lua_State *L) -{ - luaL_checkanytable (L, 1); - bool save = luaL_optbool (L, 2, false); - - wifi_config_t cfg; - memset (&cfg, 0, sizeof (cfg)); - - lua_getfield (L, 1, "ssid"); - size_t len; - const char *str = luaL_checklstring (L, -1, &len); - if (len > sizeof (cfg.ap.ssid)) - len = sizeof (cfg.ap.ssid); - strncpy (cfg.ap.ssid, str, len); - cfg.ap.ssid_len = len; - - lua_getfield (L, 1, "pwd"); - str = luaL_optlstring (L, -1, "", &len); - if (len > sizeof (cfg.ap.password)) - len = sizeof (cfg.ap.password); - strncpy (cfg.ap.password, str, len); - - lua_getfield (L, 1, "auth"); - int authmode = luaL_optint (L, -1, WIFI_AUTH_WPA2_PSK); - if (authmode < 0 || authmode >= WIFI_AUTH_MAX) - return luaL_error (L, "unknown auth mode %d", authmode); - cfg.ap.authmode = authmode; - - lua_getfield (L, 1, "channel"); - cfg.ap.channel = luaL_optint (L, -1, DEFAULT_AP_CHANNEL); - - lua_getfield (L, 1, "hidden"); - cfg.ap.ssid_hidden = luaL_optbool (L, -1, false); - - lua_getfield (L, 1, "max"); - cfg.ap.max_connection = luaL_optint (L, -1, DEFAULT_AP_MAXCONNS); - - lua_getfield (L, 1, "beacon"); - cfg.ap.beacon_interval = luaL_optint (L, -1, DEFAULT_AP_BEACON); - - SET_SAVE_MODE(save); - esp_err_t err = esp_wifi_set_config (WIFI_IF_AP, &cfg); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to set wifi config, code %d", err); -} - -static int wifi_init (lua_State *L) -{ - for (unsigned i = 0; i < ARRAY_LEN(event_cb); ++i) - event_cb[i] = LUA_NOREF; - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - esp_err_t err = esp_wifi_init (&cfg); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to init wifi, code %d", err); -} - - -const LUA_REG_TYPE wifi_sta_map[] = { - { LSTRKEY( "config" ), LFUNCVAL( wifi_sta_config ) }, - { LSTRKEY( "connect" ), LFUNCVAL( wifi_sta_connect ) }, - { LSTRKEY( "disconnect" ), LFUNCVAL( wifi_sta_disconnect ) }, - { LSTRKEY( "getconfig" ), LFUNCVAL( wifi_sta_getconfig ) }, - { LSTRKEY( "scan" ), LFUNCVAL( wifi_sta_scan ) }, - - { LNILKEY, LNILVAL } -}; - -const LUA_REG_TYPE wifi_ap_map[] = { - { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) }, - - { LSTRKEY( "AUTH_OPEN" ), LNUMVAL( WIFI_AUTH_OPEN ) }, - { LSTRKEY( "AUTH_WEP" ), LNUMVAL( WIFI_AUTH_WEP ) }, - { LSTRKEY( "AUTH_WPA_PSK" ), LNUMVAL( WIFI_AUTH_WPA_PSK ) }, - { LSTRKEY( "AUTH_WPA2_PSK" ), LNUMVAL( WIFI_AUTH_WPA2_PSK ) }, - { LSTRKEY( "AUTH_WPA_WPA2_PSK" ), LNUMVAL( WIFI_AUTH_WPA_WPA2_PSK ) }, - - { LNILKEY, LNILVAL } -}; - - -const LUA_REG_TYPE wifi_map[] = { - { LSTRKEY( "getmode" ), LFUNCVAL( wifi_getmode ) }, - { LSTRKEY( "on" ), LFUNCVAL( wifi_eventmon ) }, - { LSTRKEY( "setmode" ), LFUNCVAL( wifi_setmode ) }, - { LSTRKEY( "start" ), LFUNCVAL( wifi_start ) }, - { LSTRKEY( "stop" ), LFUNCVAL( wifi_stop ) }, - - { LSTRKEY( "sta" ), LROVAL( wifi_sta_map ) }, - { LSTRKEY( "ap" ), LROVAL( wifi_ap_map ) }, - - - { LSTRKEY( "NULLMODE" ), LNUMVAL( WIFI_MODE_NULL ) }, - { LSTRKEY( "STATION" ), LNUMVAL( WIFI_MODE_STA ) }, - { LSTRKEY( "SOFTAP" ), LNUMVAL( WIFI_MODE_AP ) }, - { LSTRKEY( "STATIONAP" ), LNUMVAL( WIFI_MODE_APSTA ) }, - - { LNILKEY, LNILVAL } -}; - - -LUALIB_API int luaopen_wifi(lua_State *L) -{ - //printf("wifi init\n"); - wifi_init(L); -#if LUA_OPTIMIZE_MEMORY > 0 - return 0; -#else - luaL_register( L, LUA_WIFILIBNAME, wifi_map ); - return 1; -#endif -} +// Module for interfacing with WIFI + +#include "modules.h" +#include "lauxlib.h" +#include "platform.h" +#include "lualib.h" +#include "lua.h" +#include "lrodefs.h" +#include "lrotable.h" + +#include "c_string.h" +#include "c_stdlib.h" + +#include "c_types.h" +#include "user_interface.h" +#include "user_config.h" +#include "esp_sta.h" +#include "esp_phy.h" +#include "esp_timer.h" +#include "esp_softap.h" +#include "esp_misc.h" +#include "nodemcu_esp_event.h" +//#include "smart.h" +//#include "smartconfig.h" +#include "c_stdio.h" +#include "ip_fmt.h" + +typedef void (*fill_cb_arg_fn) (lua_State *L, const system_event_t *evt); +typedef struct +{ + const char *name; + system_event_id_t event_id; + fill_cb_arg_fn fill_cb_arg; +} event_desc_t; + + +typedef enum _sta_status { + STA_IDLE = 0, + STA_CONNECTING, + STA_WRONGPWD, + STA_APNOTFOUND, + STA_FAIL, + STA_GOTIP +} STA_STATUS; + +typedef enum _phy_mode { + PHYMODE_B = 0, + PHYMODE_G, + PHYMODE_N +} PHY_MODE; + +#define NULL_MODE 0x00 +#define STATION_MODE 0x01 +#define SOFTAP_MODE 0x02 +#define STATIONAP_MODE 0x03 + +#define STATION_IF 0x00 +#define SOFTAP_IF 0x01 + +#define DEFAULT_AP_CHANNEL 11 +#define DEFAULT_AP_MAXCONNS 4 +#define DEFAULT_AP_BEACON 100 + +static int wifi_smart_succeed = LUA_NOREF; +static uint8 getap_output_format=0; + +//wifi.sleep variables +#define FPM_SLEEP_MAX_TIME 0xFFFFFFF +static bool FLAG_wifi_force_sleep_enabled=0; + + +//variables for wifi event monitor +static sint32_t wifi_status_cb_ref[6] = {LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF}; +//static os_timer_t wifi_sta_status_timer; +static uint8 prev_wifi_status=0; + +// Forward declarations +static void on_event (const system_event_t *evt); + +static void sta_conn (lua_State *L, const system_event_t *evt); +static void sta_disconn (lua_State *L, const system_event_t *evt); +static void sta_authmode (lua_State *L, const system_event_t *evt); +static void sta_got_ip (lua_State *L, const system_event_t *evt); +static void ap_staconn (lua_State *L, const system_event_t *evt); +static void ap_stadisconn (lua_State *L, const system_event_t *evt); +static void ap_probe_req (lua_State *L, const system_event_t *evt); + +static void empty_arg (lua_State *L, const system_event_t *evt) {} + +static const event_desc_t events[] = +{ + { "sta_start", SYSTEM_EVENT_STA_START, empty_arg }, + { "sta_stop", SYSTEM_EVENT_STA_STOP, empty_arg }, + { "sta_connected", SYSTEM_EVENT_STA_CONNECTED, sta_conn }, + { "sta_disconnected", SYSTEM_EVENT_STA_DISCONNECTED, sta_disconn }, + { "sta_authmode_changed", SYSTEM_EVENT_STA_AUTHMODE_CHANGE, sta_authmode }, + { "sta_got_ip", SYSTEM_EVENT_STA_GOT_IP, sta_got_ip }, + + { "ap_start", SYSTEM_EVENT_AP_START, empty_arg }, + { "ap_stop", SYSTEM_EVENT_AP_STOP, empty_arg }, + { "ap_sta_connected", SYSTEM_EVENT_AP_STACONNECTED, ap_staconn }, + { "ap_sta_disconnected", SYSTEM_EVENT_AP_STADISCONNECTED, ap_stadisconn }, + { "ap_probe_req", SYSTEM_EVENT_AP_PROBEREQRECVED, ap_probe_req } +}; + +#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) +static int event_cb[ARRAY_LEN(events)]; + +nodemcu_esp_event_reg_t esp_event_cb_table[] = { + {SYSTEM_EVENT_STA_START, on_event}, + {SYSTEM_EVENT_STA_STOP, on_event}, + {SYSTEM_EVENT_STA_CONNECTED, on_event}, + {SYSTEM_EVENT_STA_DISCONNECTED, on_event}, + {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, on_event}, + {SYSTEM_EVENT_STA_GOT_IP, on_event}, + + {SYSTEM_EVENT_AP_START, on_event}, + {SYSTEM_EVENT_AP_STOP, on_event}, + {SYSTEM_EVENT_AP_STACONNECTED, on_event}, + {SYSTEM_EVENT_AP_STADISCONNECTED, on_event}, + {SYSTEM_EVENT_AP_PROBEREQRECVED, on_event}, +}; + + +#define SET_SAVE_MODE(save) \ + do { esp_err_t storage_err = \ + esp_wifi_set_storage (save ? WIFI_STORAGE_FLASH : WIFI_STORAGE_RAM); \ + if (storage_err != ESP_OK) \ + return luaL_error (L, "failed to update wifi storage, code %d", \ + storage_err); \ + } while(0) + + +bool luaL_optbool (lua_State *L, int idx, bool def) +{ + if (lua_isboolean (L, idx)) + return lua_toboolean (L, idx); + else + return def; +} + + +static lua_State* gL = NULL; +static int scan_cb_ref = LUA_NOREF; + +// Lua: realmode = getmode() + +static int wifi_getmode( lua_State* L ) +{ + wifi_mode_t mode; + esp_err_t err = esp_wifi_get_mode (&mode); + if (err != ESP_OK) + return luaL_error (L, "failed to get mode, code %d", err); + lua_pushinteger (L, mode); + return 1; +} + +static int event_idx_by_name (const char *name) +{ + for (unsigned i = 0; i < ARRAY_LEN(events); ++i) + if (strcmp (events[i].name, name) == 0) + return i; + return -1; +} + + +static int event_idx_by_id (system_event_id_t id) +{ + for (unsigned i = 0; i < ARRAY_LEN(events); ++i) + if (events[i].event_id == id) + return i; + return -1; +} + + +static void sta_conn (lua_State *L, const system_event_t *evt) +{ + lua_pushlstring (L, + (const char *)evt->event_info.connected.ssid, + evt->event_info.connected.ssid_len); + lua_setfield (L, -2, "ssid"); + + char bssid_str[MAC_STR_SZ]; + macstr (bssid_str, evt->event_info.connected.bssid); + lua_pushstring (L, bssid_str); + lua_setfield (L, -2, "bssid"); + + lua_pushinteger (L, evt->event_info.connected.channel); + lua_setfield (L, -2, "channel"); + + lua_pushinteger (L, evt->event_info.connected.authmode); + lua_setfield (L, -2, "auth"); +} + +static void sta_disconn (lua_State *L, const system_event_t *evt) +{ + lua_pushlstring (L, + (const char *)evt->event_info.disconnected.ssid, + evt->event_info.disconnected.ssid_len); + lua_setfield (L, -2, "ssid"); + + char bssid_str[MAC_STR_SZ]; + macstr (bssid_str, evt->event_info.disconnected.bssid); + lua_pushstring (L, bssid_str); + lua_setfield (L, -2, "bssid"); + + lua_pushinteger (L, evt->event_info.disconnected.reason); + lua_setfield (L, -2, "reason"); +} + +static void sta_authmode (lua_State *L, const system_event_t *evt) +{ + lua_pushinteger (L, evt->event_info.auth_change.old_mode); + lua_setfield (L, -2, "old_mode"); + lua_pushinteger (L, evt->event_info.auth_change.new_mode); + lua_setfield (L, -2, "new_mode"); +} + +static void sta_got_ip (lua_State *L, const system_event_t *evt) +{ + char ipstr[IP_STR_SZ] = { 0 }; + ip4str (ipstr, &evt->event_info.got_ip.ip_info.ip); + lua_pushstring (L, ipstr); + lua_setfield (L, -2, "ip"); + + ip4str (ipstr, &evt->event_info.got_ip.ip_info.netmask); + lua_pushstring (L, ipstr); + lua_setfield (L, -2, "netmask"); + + ip4str (ipstr, &evt->event_info.got_ip.ip_info.gw); + lua_pushstring (L, ipstr); + lua_setfield (L, -2, "gw"); +} + +static void ap_staconn (lua_State *L, const system_event_t *evt) +{ + char mac[MAC_STR_SZ]; + macstr (mac, evt->event_info.sta_connected.mac); + lua_pushstring (L, mac); + lua_setfield (L, -2, "mac"); + + lua_pushinteger (L, evt->event_info.sta_connected.aid); + lua_setfield (L, -2, "id"); +} + +static void ap_stadisconn (lua_State *L, const system_event_t *evt) +{ + char mac[MAC_STR_SZ]; + macstr (mac, evt->event_info.sta_disconnected.mac); + lua_pushstring (L, mac); + lua_setfield (L, -2, "mac"); + + lua_pushinteger (L, evt->event_info.sta_disconnected.aid); + lua_setfield (L, -2, "id"); +} + +static void ap_probe_req (lua_State *L, const system_event_t *evt) +{ + char str[MAC_STR_SZ]; + macstr (str, evt->event_info.ap_probereqrecved.mac); + lua_pushstring (L, str); + lua_setfield (L, -2, "from"); + + lua_pushinteger (L, evt->event_info.ap_probereqrecved.rssi); + lua_setfield (L, -2, "rssi"); +} + +static void on_event (const system_event_t *evt) +{ + int idx = event_idx_by_id (evt->event_id); + if (idx < 0 || event_cb[idx] == LUA_NOREF) + return; + + lua_State *L = lua_getstate (); + lua_rawgeti (L, LUA_REGISTRYINDEX, event_cb[idx]); + lua_pushstring (L, events[idx].name); + lua_createtable (L, 0, 5); + events[idx].fill_cb_arg (L, evt); + lua_call (L, 2, 0); +} + + +static int wifi_eventmon (lua_State *L) +{ + const char *event_name = luaL_checkstring (L, 1); + if (!lua_isnoneornil (L, 2)) + luaL_checkanyfunction (L, 2); + lua_settop (L, 2); + + int idx = event_idx_by_name (event_name); + if (idx < 0) + return luaL_error (L, "unknown event: %s", event_name); + + luaL_unref (L, LUA_REGISTRYINDEX, event_cb[idx]); + event_cb[idx] = lua_isnoneornil (L, 2) ? + LUA_NOREF : luaL_ref (L, LUA_REGISTRYINDEX); + + return 0; +} + +static int wifi_setmode (lua_State *L) +{ + int mode = luaL_checkinteger (L, 1); + wifi_mode_t tmp_mode; + esp_err_t err = esp_wifi_get_mode (&tmp_mode); + if (err == ESP_OK) { + if (tmp_mode == mode) { return 0; } + } + bool save = luaL_optbool (L, 2, false); + SET_SAVE_MODE(save); + switch (mode) + { + case WIFI_MODE_NULL: + case WIFI_MODE_STA: + case WIFI_MODE_AP: + case WIFI_MODE_APSTA: + return ((err = esp_wifi_set_mode (mode)) == ESP_OK) ? + 0 : luaL_error (L, "failed to set mode, code %d", err); + default: + return luaL_error (L, "invalid wifi mode %d", mode); + } +} + +static int wifi_start (lua_State *L) +{ + esp_err_t err = esp_wifi_start (); + return (err == ESP_OK) ? + 0 : luaL_error(L, "failed to start wifi, code %d", err); +} + +static int wifi_stop (lua_State *L) +{ + esp_err_t err = esp_wifi_stop (); + return (err == ESP_OK) ? + 0 : luaL_error (L, "failed to stop wifi, code %d", err); +} + + +static int wifi_sta_config (lua_State *L) +{ + luaL_checkanytable (L, 1); + bool save = luaL_optbool (L, 2, false); + lua_settop (L, 1); + + wifi_config_t cfg; + memset (&cfg, 0, sizeof (cfg)); + + lua_getfield (L, 1, "ssid"); + size_t len; + const char *str = luaL_checklstring (L, -1, &len); + if (len > sizeof (cfg.sta.ssid)) + len = sizeof (cfg.sta.ssid); + strncpy (cfg.sta.ssid, str, len); + + lua_getfield (L, 1, "pwd"); + str = luaL_optlstring (L, -1, "", &len); + if (len > sizeof (cfg.sta.password)) + len = sizeof (cfg.sta.password); + strncpy (cfg.sta.password, str, len); + + lua_getfield (L, 1, "bssid"); + cfg.sta.bssid_set = false; + if (lua_isstring (L, -1)) + { + const char *bssid = luaL_checklstring (L, -1, &len); + const char *fmts[] = { + "%hhx%hhx%hhx%hhx%hhx%hhx", + "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", + "%hhx %hhx %hhx %hhx %hhx %hhx", + NULL + }; + for (unsigned i = 0; fmts[i]; ++i) + { + if (sscanf (bssid, fmts[i], + &cfg.sta.bssid[0], &cfg.sta.bssid[1], &cfg.sta.bssid[2], + &cfg.sta.bssid[3], &cfg.sta.bssid[4], &cfg.sta.bssid[5]) == 6) + { + cfg.sta.bssid_set = true; + break; + } + } + if (!cfg.sta.bssid_set) + return luaL_error (L, "invalid BSSID: %s", bssid); + } + + lua_getfield (L, 1, "auto"); + bool auto_conn = luaL_optbool (L, -1, true); + + SET_SAVE_MODE(save); + esp_err_t err = esp_wifi_set_config (WIFI_IF_STA, &cfg); + if (err != ESP_OK) + return luaL_error (L, "failed to set wifi config, code %d", err); + + if (auto_conn) + err = esp_wifi_connect (); + if (err != ESP_OK) + return luaL_error (L, "failed to begin connect, code %d", err); + + err = esp_wifi_set_auto_connect (auto_conn); + return (err == ESP_OK) ? + 0 : luaL_error (L, "failed to set wifi auto-connect, code %d", err); +} + +static int wifi_sta_connect (lua_State *L) +{ + esp_err_t err = esp_wifi_connect (); + return (err == ESP_OK) ? 0 : luaL_error (L, "connect failed, code %d", err); +} + + +static int wifi_sta_disconnect (lua_State *L) +{ + esp_err_t err = esp_wifi_disconnect (); + return (err == ESP_OK) ? 0 : luaL_error(L, "disconnect failed, code %d", err); +} + +static int wifi_sta_getconfig (lua_State *L) +{ + wifi_config_t cfg; + esp_err_t err = esp_wifi_get_config (WIFI_IF_STA, &cfg); + if (err != ESP_OK) + return luaL_error (L, "failed to get config, code %d", err); + + lua_createtable (L, 0, 3); + size_t ssid_len = strnlen (cfg.sta.ssid, sizeof (cfg.sta.ssid)); + lua_pushlstring (L, cfg.sta.ssid, ssid_len); + lua_setfield (L, -2, "ssid"); + + size_t pwd_len = strnlen (cfg.sta.password, sizeof (cfg.sta.password)); + lua_pushlstring (L, cfg.sta.password, pwd_len); + lua_setfield (L, -2, "pwd"); + + if (cfg.sta.bssid_set) + { + char bssid_str[MAC_STR_SZ]; + macstr (bssid_str, cfg.sta.bssid); + lua_pushstring (L, bssid_str); + lua_setfield (L, -2, "bssid"); + } + + bool auto_conn; + err = esp_wifi_get_auto_connect (&auto_conn); + if (err != ESP_OK) + return luaL_error (L, "failed to get auto-connect, code %d", err); + + lua_pushboolean (L, auto_conn); + lua_setfield (L, -2, "auto"); + + return 1; +} + +static int wifi_sta_scan (lua_State *L) +{ + if (scan_cb_ref != LUA_NOREF) + return luaL_error (L, "scan already in progress"); + + luaL_checkanytable (L, 1); + + wifi_scan_config_t scan_cfg; + memset (&scan_cfg, 0, sizeof (scan_cfg)); + + // TODO: support ssid/bssid/channel/hidden features of wifi_scan_config_t + + luaL_checkanyfunction (L, 2); + lua_settop (L, 2); + scan_cb_ref = luaL_ref (L, LUA_REGISTRYINDEX); + + esp_err_t err = esp_wifi_scan_start (&scan_cfg, false); + if (err != ESP_OK) + { + luaL_unref (L, LUA_REGISTRYINDEX, scan_cb_ref); + scan_cb_ref = LUA_NOREF; + return luaL_error (L, "failed to start scan, code %d", err); + } + else + return 0; +} + +static int wifi_ap_config (lua_State *L) +{ + luaL_checkanytable (L, 1); + bool save = luaL_optbool (L, 2, false); + + wifi_config_t cfg; + memset (&cfg, 0, sizeof (cfg)); + + lua_getfield (L, 1, "ssid"); + size_t len; + const char *str = luaL_checklstring (L, -1, &len); + if (len > sizeof (cfg.ap.ssid)) + len = sizeof (cfg.ap.ssid); + strncpy (cfg.ap.ssid, str, len); + cfg.ap.ssid_len = len; + + lua_getfield (L, 1, "pwd"); + str = luaL_optlstring (L, -1, "", &len); + if (len > sizeof (cfg.ap.password)) + len = sizeof (cfg.ap.password); + strncpy (cfg.ap.password, str, len); + + lua_getfield (L, 1, "auth"); + int authmode = luaL_optint (L, -1, WIFI_AUTH_WPA2_PSK); + if (authmode < 0 || authmode >= WIFI_AUTH_MAX) + return luaL_error (L, "unknown auth mode %d", authmode); + cfg.ap.authmode = authmode; + + lua_getfield (L, 1, "channel"); + cfg.ap.channel = luaL_optint (L, -1, DEFAULT_AP_CHANNEL); + + lua_getfield (L, 1, "hidden"); + cfg.ap.ssid_hidden = luaL_optbool (L, -1, false); + + lua_getfield (L, 1, "max"); + cfg.ap.max_connection = luaL_optint (L, -1, DEFAULT_AP_MAXCONNS); + + lua_getfield (L, 1, "beacon"); + cfg.ap.beacon_interval = luaL_optint (L, -1, DEFAULT_AP_BEACON); + + SET_SAVE_MODE(save); + esp_err_t err = esp_wifi_set_config (WIFI_IF_AP, &cfg); + return (err == ESP_OK) ? + 0 : luaL_error (L, "failed to set wifi config, code %d", err); +} + +static int wifi_init (lua_State *L) +{ + for (unsigned i = 0; i < ARRAY_LEN(event_cb); ++i) + event_cb[i] = LUA_NOREF; + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t err = esp_wifi_init (&cfg); + return (err == ESP_OK) ? + 0 : luaL_error (L, "failed to init wifi, code %d", err); +} + + +const LUA_REG_TYPE wifi_sta_map[] = { + { LSTRKEY( "config" ), LFUNCVAL( wifi_sta_config ) }, + { LSTRKEY( "connect" ), LFUNCVAL( wifi_sta_connect ) }, + { LSTRKEY( "disconnect" ), LFUNCVAL( wifi_sta_disconnect ) }, + { LSTRKEY( "getconfig" ), LFUNCVAL( wifi_sta_getconfig ) }, + { LSTRKEY( "scan" ), LFUNCVAL( wifi_sta_scan ) }, + + { LNILKEY, LNILVAL } +}; + +const LUA_REG_TYPE wifi_ap_map[] = { + { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) }, + + { LSTRKEY( "AUTH_OPEN" ), LNUMVAL( WIFI_AUTH_OPEN ) }, + { LSTRKEY( "AUTH_WEP" ), LNUMVAL( WIFI_AUTH_WEP ) }, + { LSTRKEY( "AUTH_WPA_PSK" ), LNUMVAL( WIFI_AUTH_WPA_PSK ) }, + { LSTRKEY( "AUTH_WPA2_PSK" ), LNUMVAL( WIFI_AUTH_WPA2_PSK ) }, + { LSTRKEY( "AUTH_WPA_WPA2_PSK" ), LNUMVAL( WIFI_AUTH_WPA_WPA2_PSK ) }, + + { LNILKEY, LNILVAL } +}; + + +const LUA_REG_TYPE wifi_map[] = { + { LSTRKEY( "getmode" ), LFUNCVAL( wifi_getmode ) }, + { LSTRKEY( "on" ), LFUNCVAL( wifi_eventmon ) }, + { LSTRKEY( "setmode" ), LFUNCVAL( wifi_setmode ) }, + { LSTRKEY( "start" ), LFUNCVAL( wifi_start ) }, + { LSTRKEY( "stop" ), LFUNCVAL( wifi_stop ) }, + + { LSTRKEY( "sta" ), LROVAL( wifi_sta_map ) }, + { LSTRKEY( "ap" ), LROVAL( wifi_ap_map ) }, + + + { LSTRKEY( "NULLMODE" ), LNUMVAL( WIFI_MODE_NULL ) }, + { LSTRKEY( "STATION" ), LNUMVAL( WIFI_MODE_STA ) }, + { LSTRKEY( "SOFTAP" ), LNUMVAL( WIFI_MODE_AP ) }, + { LSTRKEY( "STATIONAP" ), LNUMVAL( WIFI_MODE_APSTA ) }, + + { LNILKEY, LNILVAL } +}; + + +LUALIB_API int luaopen_wifi(lua_State *L) +{ + //printf("wifi init\n"); + wifi_init(L); +#if LUA_OPTIMIZE_MEMORY > 0 + return 0; +#else + luaL_register( L, LUA_WIFILIBNAME, wifi_map ); + return 1; +#endif +} diff --git a/LuaNode_Esp32/LuaNode32/components/mydriver/Kconfig b/LuaNode_Esp32/LuaNode32/components/mydriver/Kconfig index e3f3142..71da94e 100644 --- a/LuaNode_Esp32/LuaNode32/components/mydriver/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/mydriver/Kconfig @@ -1,9 +1,9 @@ -menu "DRIVER" - -config DRIVER_ENABLE - bool "Enable driver" - default "y" - help - For driver. - -endmenu +menu "DRIVER" + +config DRIVER_ENABLE + bool "Enable driver" + default "y" + help + For driver. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/mylibc/Kconfig b/LuaNode_Esp32/LuaNode32/components/mylibc/Kconfig index 25ad716..43b5e0f 100644 --- a/LuaNode_Esp32/LuaNode32/components/mylibc/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/mylibc/Kconfig @@ -1,9 +1,9 @@ -menu "MYLIBC" - -config MYLIBC_ENABLE - bool "Enable mylibc" - default "y" - help - For mylibc. - -endmenu +menu "MYLIBC" + +config MYLIBC_ENABLE + bool "Enable mylibc" + default "y" + help + For mylibc. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/platform/Kconfig b/LuaNode_Esp32/LuaNode32/components/platform/Kconfig index 36d118a..58c0be2 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/platform/Kconfig @@ -1,9 +1,9 @@ -menu "PLATFORM" - -config PLATFORM_ENABLE - bool "Enable platform" - default "y" - help - For platform. - -endmenu +menu "PLATFORM" + +config PLATFORM_ENABLE + bool "Enable platform" + default "y" + help + For platform. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/uart/Kconfig b/LuaNode_Esp32/LuaNode32/components/uart/Kconfig index 4a4f381..225406f 100644 --- a/LuaNode_Esp32/LuaNode32/components/uart/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/uart/Kconfig @@ -1,9 +1,9 @@ -menu "UART" - -config UART_ENABLE - bool "Enable uart" - default "y" - help - For uart. - -endmenu +menu "UART" + +config UART_ENABLE + bool "Enable uart" + default "y" + help + For uart. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/uart/include/my_uart.h b/LuaNode_Esp32/LuaNode32/components/uart/include/my_uart.h index c9c6b28..9d266b4 100644 --- a/LuaNode_Esp32/LuaNode32/components/uart/include/my_uart.h +++ b/LuaNode_Esp32/LuaNode32/components/uart/include/my_uart.h @@ -1,26 +1,26 @@ -#ifndef MY_UART_H -#define MY_UART_H - -#include "c_types.h" - -//#define REG_UART_BASE( i ) (0x60000000+(i)*0x10000) -#define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) - -typedef enum { - UART_WordLength_5b = 0x0, - UART_WordLength_6b = 0x1, - UART_WordLength_7b = 0x2, - UART_WordLength_8b = 0x3 -} UART_WordLength; - -typedef enum { - USART_StopBits_1 = 0x1, - USART_StopBits_1_5 = 0x2, - USART_StopBits_2 = 0x3, -} UART_StopBits; - -void uart_init(void); -void uart_sendStr(const char *str); -void uart_putc(uint8_t TxChar); - +#ifndef MY_UART_H +#define MY_UART_H + +#include "c_types.h" + +//#define REG_UART_BASE( i ) (0x60000000+(i)*0x10000) +#define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) + +typedef enum { + UART_WordLength_5b = 0x0, + UART_WordLength_6b = 0x1, + UART_WordLength_7b = 0x2, + UART_WordLength_8b = 0x3 +} UART_WordLength; + +typedef enum { + USART_StopBits_1 = 0x1, + USART_StopBits_1_5 = 0x2, + USART_StopBits_2 = 0x3, +} UART_StopBits; + +void uart_init(void); +void uart_sendStr(const char *str); +void uart_putc(uint8_t TxChar); + #endif \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c b/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c index a6c84f7..985b084 100644 --- a/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c +++ b/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c @@ -1,188 +1,188 @@ -#include "my_uart.h" -#include "esp_intr.h" -#include "esp_log.h" -#include "c_types.h" -#include "rom/uart.h" -#include "driver/uart.h" -#include "soc/uart_register.h" -#include "extras/esp_intr_ext.h" -#include "c_string.h" -#include "lua.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" - -#include -#include - -#define UART_FRM_ERR_INT_ST (BIT(3)) -#define UART_FRM_ERR_INT_CLR (BIT(3)) -#define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) -#define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) -#define UART_RXFIFO_FULL_INT_ST (BIT(0)) -#define UART_RXFIFO_FULL_INT_CLR (BIT(0)) -#define UART_RXFIFO_TOUT_INT_ST (BIT(8)) -#define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) -#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) -#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) -#define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) -#define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) -#define UART_RXFIFO_OVF_INT_CLR (BIT(4)) -#define UART_RXFIFO_OVF_INT_ST (BIT(4)) - -#define EX_UART_NUM UART_NUM_0 - -#define TAG "my_uart" - -enum { - UART_EVENT_RX_CHAR, - //UART_EVENT_MAX -}; - -typedef struct _os_event_ { - uint32 event; - uint32 param; -} os_event_t; - -xTaskHandle xUartTaskHandle; -xQueueHandle xQueueUart; -RcvMsgBuff rcvMsgBuff; - -static uint8_t pbuff[RX_BUFF_SIZE] = {0}; - - -static void uart_event_task(void *pvParameters) -{ - uart_event_t event; - size_t buffered_size; - memset(pbuff, 0, RX_BUFF_SIZE); - while (1) { - /* Waiting for UART event. - If it happens then print out information what is it */ - if (xQueueReceive(xQueueUart, (void * )&event, (portTickType)portMAX_DELAY)) { - //ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM); - switch (event.type) { - case UART_DATA: { - /* Event of UART receiving data - * We'd better handler data event fast, there would be much more data events - * than other types of events. - * If we take too much time on data event, the queue might be full. - * In this example, we don't process data in event, but read data outside. - */ - uart_get_buffered_data_len(EX_UART_NUM, &buffered_size); - //ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); - int len = uart_read_bytes(EX_UART_NUM, pbuff, RX_BUFF_SIZE, 100 / portTICK_RATE_MS); - if (len > 0) { - //ESP_LOGI(TAG, "data: %s", pbuff); - uint8 RcvChar; - for (int i = 0; i < len; i++) { - RcvChar = pbuff[i]; - *(rcvMsgBuff.pWritePos) = RcvChar; - if (RcvChar == '\r' || RcvChar == '\n' ) { - rcvMsgBuff.BuffState = WRITE_OVER; - } - - if (rcvMsgBuff.pWritePos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) { - // overflow ...we may need more error handle here. - rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff ; - } else { - rcvMsgBuff.pWritePos++; - } - - if (rcvMsgBuff.pWritePos == rcvMsgBuff.pReadPos){ // overflow one byte, need push pReadPos one byte ahead - if (rcvMsgBuff.pReadPos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) { - rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff ; - } else { - rcvMsgBuff.pReadPos++; - } - } - } - - - lua_handle_input(false); - } - break; - } - case UART_FIFO_OVF: { - ESP_LOGE(TAG, "hw fifo overflow"); - // If fifo overflow happened, you should consider adding flow control for your application. - // We can read data out out the buffer, or directly flush the Rx buffer. - uart_flush(EX_UART_NUM); - break; - } - case UART_BUFFER_FULL: { - ESP_LOGE(TAG, "ring buffer full"); - // If buffer full happened, you should consider increasing your buffer size - // We can read data out out the buffer, or directly flush the Rx buffer. - uart_flush(EX_UART_NUM); - break; - } - case UART_BREAK: - ESP_LOGI(TAG, "uart rx break detected"); - break; - case UART_PARITY_ERR: - ESP_LOGE(TAG, "uart parity error"); - break; - case UART_FRAME_ERR: - ESP_LOGE(TAG, "uart frame error"); - break; - case UART_PATTERN_DET: - ESP_LOGI(TAG, "uart pattern detected"); - break; - default: - ESP_LOGE(TAG, "not serviced uart event type: %d\n", event.type); - break; - } - } - } - vTaskDelete(NULL); -} - -void uart_sendStr(const char *str) -{ - while(*str) { - uart_tx_one_char(*str++); - } -} - -void uart_putc(uint8_t TxChar) -{ - while (true) { - uint32 fifo_cnt = READ_PERI_REG(UART_STATUS_REG(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); - - if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { - break; - } - } - - WRITE_PERI_REG(UART_FIFO(0) , TxChar); -} - - -void uart_init(void) -{ - printf("UART init ...\r\n"); - rcvMsgBuff.pRcvMsgBuff = malloc(RX_BUFF_SIZE); - memset(rcvMsgBuff.pRcvMsgBuff, 0, RX_BUFF_SIZE); - rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff; - rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff; - - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE - }; - uart_param_config(EX_UART_NUM, &uart_config); - // Set UART pins using UART0 default pins i.e. no changes - uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - uart_driver_install(EX_UART_NUM, RX_BUFF_SIZE * 2, RX_BUFF_SIZE * 2, 10, &xQueueUart, 0); - - // Set uart pattern detection function - uart_enable_pattern_det_intr(EX_UART_NUM, '+', 3, 10000, 10, 10); - - // Create a task to handle uart event from ISR - xTaskCreate(uart_event_task, "uart_event_task", 8192, NULL, 12, &xUartTaskHandle); -} +#include "my_uart.h" +#include "esp_intr.h" +#include "esp_log.h" +#include "c_types.h" +#include "rom/uart.h" +#include "driver/uart.h" +#include "soc/uart_register.h" +#include "extras/esp_intr_ext.h" +#include "c_string.h" +#include "lua.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +#include +#include + +#define UART_FRM_ERR_INT_ST (BIT(3)) +#define UART_FRM_ERR_INT_CLR (BIT(3)) +#define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) +#define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) +#define UART_RXFIFO_FULL_INT_ST (BIT(0)) +#define UART_RXFIFO_FULL_INT_CLR (BIT(0)) +#define UART_RXFIFO_TOUT_INT_ST (BIT(8)) +#define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) +#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) +#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) +#define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) +#define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) +#define UART_RXFIFO_OVF_INT_CLR (BIT(4)) +#define UART_RXFIFO_OVF_INT_ST (BIT(4)) + +#define EX_UART_NUM UART_NUM_0 + +#define TAG "my_uart" + +enum { + UART_EVENT_RX_CHAR, + //UART_EVENT_MAX +}; + +typedef struct _os_event_ { + uint32 event; + uint32 param; +} os_event_t; + +xTaskHandle xUartTaskHandle; +xQueueHandle xQueueUart; +RcvMsgBuff rcvMsgBuff; + +static uint8_t pbuff[RX_BUFF_SIZE] = {0}; + + +static void uart_event_task(void *pvParameters) +{ + uart_event_t event; + size_t buffered_size; + memset(pbuff, 0, RX_BUFF_SIZE); + while (1) { + /* Waiting for UART event. + If it happens then print out information what is it */ + if (xQueueReceive(xQueueUart, (void * )&event, (portTickType)portMAX_DELAY)) { + //ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM); + switch (event.type) { + case UART_DATA: { + /* Event of UART receiving data + * We'd better handler data event fast, there would be much more data events + * than other types of events. + * If we take too much time on data event, the queue might be full. + * In this example, we don't process data in event, but read data outside. + */ + uart_get_buffered_data_len(EX_UART_NUM, &buffered_size); + //ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); + int len = uart_read_bytes(EX_UART_NUM, pbuff, RX_BUFF_SIZE, 100 / portTICK_RATE_MS); + if (len > 0) { + //ESP_LOGI(TAG, "data: %s", pbuff); + uint8 RcvChar; + for (int i = 0; i < len; i++) { + RcvChar = pbuff[i]; + *(rcvMsgBuff.pWritePos) = RcvChar; + if (RcvChar == '\r' || RcvChar == '\n' ) { + rcvMsgBuff.BuffState = WRITE_OVER; + } + + if (rcvMsgBuff.pWritePos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) { + // overflow ...we may need more error handle here. + rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff ; + } else { + rcvMsgBuff.pWritePos++; + } + + if (rcvMsgBuff.pWritePos == rcvMsgBuff.pReadPos){ // overflow one byte, need push pReadPos one byte ahead + if (rcvMsgBuff.pReadPos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) { + rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff ; + } else { + rcvMsgBuff.pReadPos++; + } + } + } + + + lua_handle_input(false); + } + break; + } + case UART_FIFO_OVF: { + ESP_LOGE(TAG, "hw fifo overflow"); + // If fifo overflow happened, you should consider adding flow control for your application. + // We can read data out out the buffer, or directly flush the Rx buffer. + uart_flush(EX_UART_NUM); + break; + } + case UART_BUFFER_FULL: { + ESP_LOGE(TAG, "ring buffer full"); + // If buffer full happened, you should consider increasing your buffer size + // We can read data out out the buffer, or directly flush the Rx buffer. + uart_flush(EX_UART_NUM); + break; + } + case UART_BREAK: + ESP_LOGI(TAG, "uart rx break detected"); + break; + case UART_PARITY_ERR: + ESP_LOGE(TAG, "uart parity error"); + break; + case UART_FRAME_ERR: + ESP_LOGE(TAG, "uart frame error"); + break; + case UART_PATTERN_DET: + ESP_LOGI(TAG, "uart pattern detected"); + break; + default: + ESP_LOGE(TAG, "not serviced uart event type: %d\n", event.type); + break; + } + } + } + vTaskDelete(NULL); +} + +void uart_sendStr(const char *str) +{ + while(*str) { + uart_tx_one_char(*str++); + } +} + +void uart_putc(uint8_t TxChar) +{ + while (true) { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS_REG(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); + + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { + break; + } + } + + WRITE_PERI_REG(UART_FIFO(0) , TxChar); +} + + +void uart_init(void) +{ + printf("UART init ...\r\n"); + rcvMsgBuff.pRcvMsgBuff = malloc(RX_BUFF_SIZE); + memset(rcvMsgBuff.pRcvMsgBuff, 0, RX_BUFF_SIZE); + rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff; + rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff; + + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE + }; + uart_param_config(EX_UART_NUM, &uart_config); + // Set UART pins using UART0 default pins i.e. no changes + uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + uart_driver_install(EX_UART_NUM, RX_BUFF_SIZE * 2, RX_BUFF_SIZE * 2, 10, &xQueueUart, 0); + + // Set uart pattern detection function + uart_enable_pattern_det_intr(EX_UART_NUM, '+', 3, 10000, 10, 10); + + // Create a task to handle uart event from ISR + xTaskCreate(uart_event_task, "uart_event_task", 8192, NULL, 12, &xUartTaskHandle); +} diff --git a/LuaNode_Esp32/LuaNode32/components/utils/Kconfig b/LuaNode_Esp32/LuaNode32/components/utils/Kconfig index 8903c74..65c30c6 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/Kconfig +++ b/LuaNode_Esp32/LuaNode32/components/utils/Kconfig @@ -1,9 +1,9 @@ -menu "UTILS" - -config UTILS_ENABLE - bool "Enable utils" - default "y" - help - For utils. - -endmenu +menu "UTILS" + +config UTILS_ENABLE + bool "Enable utils" + default "y" + help + For utils. + +endmenu diff --git a/LuaNode_Esp32/LuaNode32/components/utils/include/md5.h b/LuaNode_Esp32/LuaNode32/components/utils/include/md5.h index caf309d..6389b79 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/include/md5.h +++ b/LuaNode_Esp32/LuaNode32/components/utils/include/md5.h @@ -1,48 +1,48 @@ -#ifndef MD5_H -#define MD5_H - -typedef struct -{ - unsigned int count[2]; - unsigned int state[4]; - unsigned char buffer[64]; -}MD5_CTX; - - -#define F(x,y,z) ((x & y) | (~x & z)) -#define G(x,y,z) ((x & z) | (y & ~z)) -#define H(x,y,z) (x^y^z) -#define I(x,y,z) (y ^ (x | ~z)) -#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) -#define FF(a,b,c,d,x,s,ac) \ -{ \ - a += F(b,c,d) + x + ac; \ - a = ROTATE_LEFT(a,s); \ - a += b; \ -} -#define GG(a,b,c,d,x,s,ac) \ -{ \ - a += G(b,c,d) + x + ac; \ - a = ROTATE_LEFT(a,s); \ - a += b; \ -} -#define HH(a,b,c,d,x,s,ac) \ -{ \ - a += H(b,c,d) + x + ac; \ - a = ROTATE_LEFT(a,s); \ - a += b; \ -} -#define II(a,b,c,d,x,s,ac) \ -{ \ - a += I(b,c,d) + x + ac; \ - a = ROTATE_LEFT(a,s); \ - a += b; \ -} -void MD5Init(MD5_CTX *context); -void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen); -void MD5Final(MD5_CTX *context,unsigned char digest[16]); -void MD5Transform(unsigned int state[4],unsigned char block[64]); -void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len); -void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); - -#endif +#ifndef MD5_H +#define MD5_H + +typedef struct +{ + unsigned int count[2]; + unsigned int state[4]; + unsigned char buffer[64]; +}MD5_CTX; + + +#define F(x,y,z) ((x & y) | (~x & z)) +#define G(x,y,z) ((x & z) | (y & ~z)) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y ^ (x | ~z)) +#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) +#define FF(a,b,c,d,x,s,ac) \ +{ \ + a += F(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define GG(a,b,c,d,x,s,ac) \ +{ \ + a += G(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define HH(a,b,c,d,x,s,ac) \ +{ \ + a += H(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +#define II(a,b,c,d,x,s,ac) \ +{ \ + a += I(b,c,d) + x + ac; \ + a = ROTATE_LEFT(a,s); \ + a += b; \ +} +void MD5Init(MD5_CTX *context); +void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen); +void MD5Final(MD5_CTX *context,unsigned char digest[16]); +void MD5Transform(unsigned int state[4],unsigned char block[64]); +void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len); +void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); + +#endif diff --git a/LuaNode_Esp32/LuaNode32/components/utils/md5.c b/LuaNode_Esp32/LuaNode32/components/utils/md5.c index 188b756..20d7185 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/md5.c +++ b/LuaNode_Esp32/LuaNode32/components/utils/md5.c @@ -1,161 +1,161 @@ -#include -#include "md5.h" - -unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -void MD5Init(MD5_CTX *context) -{ - context->count[0] = 0; - context->count[1] = 0; - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; -} -void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) -{ - unsigned int i = 0,index = 0,partlen = 0; - index = (context->count[0] >> 3) & 0x3F; - partlen = 64 - index; - context->count[0] += inputlen << 3; - if(context->count[0] < (inputlen << 3)) - context->count[1]++; - context->count[1] += inputlen >> 29; - - if(inputlen >= partlen) - { - memcpy(&context->buffer[index],input,partlen); - MD5Transform(context->state,context->buffer); - for(i = partlen;i+64 <= inputlen;i+=64) - MD5Transform(context->state,&input[i]); - index = 0; - } - else - { - i = 0; - } - memcpy(&context->buffer[index],&input[i],inputlen-i); -} -void MD5Final(MD5_CTX *context,unsigned char digest[16]) -{ - unsigned int index = 0,padlen = 0; - unsigned char bits[8]; - index = (context->count[0] >> 3) & 0x3F; - padlen = (index < 56)?(56-index):(120-index); - MD5Encode(bits,context->count,8); - MD5Update(context,PADDING,padlen); - MD5Update(context,bits,8); - MD5Encode(digest,context->state,16); -} -void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) -{ - unsigned int i = 0,j = 0; - while(j < len) - { - output[j] = input[i] & 0xFF; - output[j+1] = (input[i] >> 8) & 0xFF; - output[j+2] = (input[i] >> 16) & 0xFF; - output[j+3] = (input[i] >> 24) & 0xFF; - i++; - j+=4; - } -} -void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) -{ - unsigned int i = 0,j = 0; - while(j < len) - { - output[i] = (input[j]) | - (input[j+1] << 8) | - (input[j+2] << 16) | - (input[j+3] << 24); - i++; - j+=4; - } -} -void MD5Transform(unsigned int state[4],unsigned char block[64]) -{ - unsigned int a = state[0]; - unsigned int b = state[1]; - unsigned int c = state[2]; - unsigned int d = state[3]; - unsigned int x[64]; - MD5Decode(x,block,64); - FF(a, b, c, d, x[ 0], 7, 0xd76aa478); - FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); - FF(c, d, a, b, x[ 2], 17, 0x242070db); - FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); - FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); - FF(d, a, b, c, x[ 5], 12, 0x4787c62a); - FF(c, d, a, b, x[ 6], 17, 0xa8304613); - FF(b, c, d, a, x[ 7], 22, 0xfd469501); - FF(a, b, c, d, x[ 8], 7, 0x698098d8); - FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); - FF(c, d, a, b, x[10], 17, 0xffff5bb1); - FF(b, c, d, a, x[11], 22, 0x895cd7be); - FF(a, b, c, d, x[12], 7, 0x6b901122); - FF(d, a, b, c, x[13], 12, 0xfd987193); - FF(c, d, a, b, x[14], 17, 0xa679438e); - FF(b, c, d, a, x[15], 22, 0x49b40821); - - - GG(a, b, c, d, x[ 1], 5, 0xf61e2562); - GG(d, a, b, c, x[ 6], 9, 0xc040b340); - GG(c, d, a, b, x[11], 14, 0x265e5a51); - GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); - GG(a, b, c, d, x[ 5], 5, 0xd62f105d); - GG(d, a, b, c, x[10], 9, 0x2441453); - GG(c, d, a, b, x[15], 14, 0xd8a1e681); - GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); - GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); - GG(d, a, b, c, x[14], 9, 0xc33707d6); - GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); - GG(b, c, d, a, x[ 8], 20, 0x455a14ed); - GG(a, b, c, d, x[13], 5, 0xa9e3e905); - GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); - GG(c, d, a, b, x[ 7], 14, 0x676f02d9); - GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); - - - HH(a, b, c, d, x[ 5], 4, 0xfffa3942); - HH(d, a, b, c, x[ 8], 11, 0x8771f681); - HH(c, d, a, b, x[11], 16, 0x6d9d6122); - HH(b, c, d, a, x[14], 23, 0xfde5380c); - HH(a, b, c, d, x[ 1], 4, 0xa4beea44); - HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); - HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); - HH(b, c, d, a, x[10], 23, 0xbebfbc70); - HH(a, b, c, d, x[13], 4, 0x289b7ec6); - HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); - HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); - HH(b, c, d, a, x[ 6], 23, 0x4881d05); - HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); - HH(d, a, b, c, x[12], 11, 0xe6db99e5); - HH(c, d, a, b, x[15], 16, 0x1fa27cf8); - HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); - - - II(a, b, c, d, x[ 0], 6, 0xf4292244); - II(d, a, b, c, x[ 7], 10, 0x432aff97); - II(c, d, a, b, x[14], 15, 0xab9423a7); - II(b, c, d, a, x[ 5], 21, 0xfc93a039); - II(a, b, c, d, x[12], 6, 0x655b59c3); - II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); - II(c, d, a, b, x[10], 15, 0xffeff47d); - II(b, c, d, a, x[ 1], 21, 0x85845dd1); - II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); - II(d, a, b, c, x[15], 10, 0xfe2ce6e0); - II(c, d, a, b, x[ 6], 15, 0xa3014314); - II(b, c, d, a, x[13], 21, 0x4e0811a1); - II(a, b, c, d, x[ 4], 6, 0xf7537e82); - II(d, a, b, c, x[11], 10, 0xbd3af235); - II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); - II(b, c, d, a, x[ 9], 21, 0xeb86d391); - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; -} +#include +#include "md5.h" + +unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +void MD5Init(MD5_CTX *context) +{ + context->count[0] = 0; + context->count[1] = 0; + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; +} +void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) +{ + unsigned int i = 0,index = 0,partlen = 0; + index = (context->count[0] >> 3) & 0x3F; + partlen = 64 - index; + context->count[0] += inputlen << 3; + if(context->count[0] < (inputlen << 3)) + context->count[1]++; + context->count[1] += inputlen >> 29; + + if(inputlen >= partlen) + { + memcpy(&context->buffer[index],input,partlen); + MD5Transform(context->state,context->buffer); + for(i = partlen;i+64 <= inputlen;i+=64) + MD5Transform(context->state,&input[i]); + index = 0; + } + else + { + i = 0; + } + memcpy(&context->buffer[index],&input[i],inputlen-i); +} +void MD5Final(MD5_CTX *context,unsigned char digest[16]) +{ + unsigned int index = 0,padlen = 0; + unsigned char bits[8]; + index = (context->count[0] >> 3) & 0x3F; + padlen = (index < 56)?(56-index):(120-index); + MD5Encode(bits,context->count,8); + MD5Update(context,PADDING,padlen); + MD5Update(context,bits,8); + MD5Encode(digest,context->state,16); +} +void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) +{ + unsigned int i = 0,j = 0; + while(j < len) + { + output[j] = input[i] & 0xFF; + output[j+1] = (input[i] >> 8) & 0xFF; + output[j+2] = (input[i] >> 16) & 0xFF; + output[j+3] = (input[i] >> 24) & 0xFF; + i++; + j+=4; + } +} +void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) +{ + unsigned int i = 0,j = 0; + while(j < len) + { + output[i] = (input[j]) | + (input[j+1] << 8) | + (input[j+2] << 16) | + (input[j+3] << 24); + i++; + j+=4; + } +} +void MD5Transform(unsigned int state[4],unsigned char block[64]) +{ + unsigned int a = state[0]; + unsigned int b = state[1]; + unsigned int c = state[2]; + unsigned int d = state[3]; + unsigned int x[64]; + MD5Decode(x,block,64); + FF(a, b, c, d, x[ 0], 7, 0xd76aa478); + FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); + FF(c, d, a, b, x[ 2], 17, 0x242070db); + FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); + FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); + FF(d, a, b, c, x[ 5], 12, 0x4787c62a); + FF(c, d, a, b, x[ 6], 17, 0xa8304613); + FF(b, c, d, a, x[ 7], 22, 0xfd469501); + FF(a, b, c, d, x[ 8], 7, 0x698098d8); + FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); + FF(c, d, a, b, x[10], 17, 0xffff5bb1); + FF(b, c, d, a, x[11], 22, 0x895cd7be); + FF(a, b, c, d, x[12], 7, 0x6b901122); + FF(d, a, b, c, x[13], 12, 0xfd987193); + FF(c, d, a, b, x[14], 17, 0xa679438e); + FF(b, c, d, a, x[15], 22, 0x49b40821); + + + GG(a, b, c, d, x[ 1], 5, 0xf61e2562); + GG(d, a, b, c, x[ 6], 9, 0xc040b340); + GG(c, d, a, b, x[11], 14, 0x265e5a51); + GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); + GG(a, b, c, d, x[ 5], 5, 0xd62f105d); + GG(d, a, b, c, x[10], 9, 0x2441453); + GG(c, d, a, b, x[15], 14, 0xd8a1e681); + GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); + GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); + GG(d, a, b, c, x[14], 9, 0xc33707d6); + GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); + GG(b, c, d, a, x[ 8], 20, 0x455a14ed); + GG(a, b, c, d, x[13], 5, 0xa9e3e905); + GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); + GG(c, d, a, b, x[ 7], 14, 0x676f02d9); + GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); + + + HH(a, b, c, d, x[ 5], 4, 0xfffa3942); + HH(d, a, b, c, x[ 8], 11, 0x8771f681); + HH(c, d, a, b, x[11], 16, 0x6d9d6122); + HH(b, c, d, a, x[14], 23, 0xfde5380c); + HH(a, b, c, d, x[ 1], 4, 0xa4beea44); + HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); + HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); + HH(b, c, d, a, x[10], 23, 0xbebfbc70); + HH(a, b, c, d, x[13], 4, 0x289b7ec6); + HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); + HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); + HH(b, c, d, a, x[ 6], 23, 0x4881d05); + HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); + HH(d, a, b, c, x[12], 11, 0xe6db99e5); + HH(c, d, a, b, x[15], 16, 0x1fa27cf8); + HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); + + + II(a, b, c, d, x[ 0], 6, 0xf4292244); + II(d, a, b, c, x[ 7], 10, 0x432aff97); + II(c, d, a, b, x[14], 15, 0xab9423a7); + II(b, c, d, a, x[ 5], 21, 0xfc93a039); + II(a, b, c, d, x[12], 6, 0x655b59c3); + II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); + II(c, d, a, b, x[10], 15, 0xffeff47d); + II(b, c, d, a, x[ 1], 21, 0x85845dd1); + II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); + II(d, a, b, c, x[15], 10, 0xfe2ce6e0); + II(c, d, a, b, x[ 6], 15, 0xa3014314); + II(b, c, d, a, x[13], 21, 0x4e0811a1); + II(a, b, c, d, x[ 4], 6, 0xf7537e82); + II(d, a, b, c, x[11], 10, 0xbd3af235); + II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); + II(b, c, d, a, x[ 9], 21, 0xeb86d391); + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/include/user_config.h b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/include/user_config.h index 349e52c..3b6e3dd 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/include/user_config.h +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/include/user_config.h @@ -1,27 +1,27 @@ -// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#define TMP_TASK_STACK_SIZE 2048 -#define TMP_TASK_PRIO 9 -#define ALEXA_TASK_STACK_SIZE 4096 -#define ALEXA_TASK_PRIO 4 -#define ALEXA_UDP_TASK_STACK_SIZE 4096 -#define ALEXA_UDP_TASK_PRIO 4 - -#define MY_WIFI_SSID "doit_newifi" -#define MY_WIFI_PASS "doit3305" - -#define HTTP_SRV_PORT 80 - +// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#define TMP_TASK_STACK_SIZE 2048 +#define TMP_TASK_PRIO 9 +#define ALEXA_TASK_STACK_SIZE 4096 +#define ALEXA_TASK_PRIO 4 +#define ALEXA_UDP_TASK_STACK_SIZE 4096 +#define ALEXA_UDP_TASK_PRIO 4 + +#define MY_WIFI_SSID "doit_newifi" +#define MY_WIFI_PASS "doit3305" + +#define HTTP_SRV_PORT 80 + #define GPIO_TEST 2 \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c index 8026741..26004b7 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c @@ -1,143 +1,143 @@ -// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/** - * Nicholas3388 - * 2017.06.02 - * email: wangwei@doit.am - * www.doit.am - */ - -#include "user_config.h" -#include "alexa.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "freertos/event_groups.h" -#include "driver/gpio.h" - -static const char *TAG = "main"; - -static const int CONNECTED_BIT = BIT0; -static EventGroupHandle_t wifi_event_group; -static uint8_t wifi_mac[6] = {0}; -static tcpip_adapter_ip_info_t ip_info; -static char local_ip[16] = {0}; -static unsigned char local_ip_num[4] = {0}; - -char *get_local_ip(void) -{ - return local_ip; -} - -unsigned char *get_ip_num(void) -{ - return local_ip_num; -} - -static void save_ip_num(uint32_t ip) -{ - local_ip_num[0] = (unsigned char)(ip & 0xFF); - local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); - local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); - local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); -} - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { - ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); - ESP_LOGI(TAG, "~~~~~~~~~~~"); - sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); - save_ip_num(ip_info.ip.addr); - } - - ESP_LOGI(TAG, "AP+STA started"); - alexa_init(); - } - vTaskDelete(NULL); -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - - wifi_config_t sta_config = { - .sta = { - .ssid = MY_WIFI_SSID, - .password = MY_WIFI_PASS, - .bssid_set = false - }, - }; - - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); - - esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); - if (er != ESP_OK) { - ESP_LOGE(TAG, "get wifi MAC failed"); - } else { - ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); - } - - ESP_ERROR_CHECK(esp_wifi_start()); - -} - -void gpio_init(void) -{ - gpio_pad_select_gpio(GPIO_TEST); - gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_TEST, 0); -} - -void app_main(void) -{ - ESP_LOGI(TAG, "enter main"); - initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); - gpio_init(); -} +// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * Nicholas3388 + * 2017.06.02 + * email: wangwei@doit.am + * www.doit.am + */ + +#include "user_config.h" +#include "alexa.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "freertos/event_groups.h" +#include "driver/gpio.h" + +static const char *TAG = "main"; + +static const int CONNECTED_BIT = BIT0; +static EventGroupHandle_t wifi_event_group; +static uint8_t wifi_mac[6] = {0}; +static tcpip_adapter_ip_info_t ip_info; +static char local_ip[16] = {0}; +static unsigned char local_ip_num[4] = {0}; + +char *get_local_ip(void) +{ + return local_ip; +} + +unsigned char *get_ip_num(void) +{ + return local_ip_num; +} + +static void save_ip_num(uint32_t ip) +{ + local_ip_num[0] = (unsigned char)(ip & 0xFF); + local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); + local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); + local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); +} + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + ESP_LOGI(TAG, "~~~~~~~~~~~"); + ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "~~~~~~~~~~~"); + sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); + save_ip_num(ip_info.ip.addr); + } + + ESP_LOGI(TAG, "AP+STA started"); + alexa_init(); + } + vTaskDelete(NULL); +} + +static void initialise_wifi(void) +{ + tcpip_adapter_init(); + + wifi_config_t sta_config = { + .sta = { + .ssid = MY_WIFI_SSID, + .password = MY_WIFI_PASS, + .bssid_set = false + }, + }; + + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + + esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); + if (er != ESP_OK) { + ESP_LOGE(TAG, "get wifi MAC failed"); + } else { + ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); + } + + ESP_ERROR_CHECK(esp_wifi_start()); + +} + +void gpio_init(void) +{ + gpio_pad_select_gpio(GPIO_TEST); + gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_TEST, 0); +} + +void app_main(void) +{ + ESP_LOGI(TAG, "enter main"); + initialise_wifi(); + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); + gpio_init(); +} diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/include/user_config.h b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/include/user_config.h index b807b2d..cfc0a75 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/include/user_config.h +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/include/user_config.h @@ -1,27 +1,27 @@ -// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#define TMP_TASK_STACK_SIZE 2048 -#define TMP_TASK_PRIO 9 -#define ALEXA_TASK_STACK_SIZE 4096 -#define ALEXA_TASK_PRIO 4 -#define ALEXA_UDP_TASK_STACK_SIZE 4096 -#define ALEXA_UDP_TASK_PRIO 4 - -#define MY_WIFI_SSID "MERCURY_CA7C" -#define MY_WIFI_PASS "wang11113388" - -#define HTTP_SRV_PORT 80 - -#define GPIO_TEST 2 +// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#define TMP_TASK_STACK_SIZE 2048 +#define TMP_TASK_PRIO 9 +#define ALEXA_TASK_STACK_SIZE 4096 +#define ALEXA_TASK_PRIO 4 +#define ALEXA_UDP_TASK_STACK_SIZE 4096 +#define ALEXA_UDP_TASK_PRIO 4 + +#define MY_WIFI_SSID "MERCURY_CA7C" +#define MY_WIFI_PASS "wang11113388" + +#define HTTP_SRV_PORT 80 + +#define GPIO_TEST 2 diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c index 8026741..26004b7 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c @@ -1,143 +1,143 @@ -// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -/** - * Nicholas3388 - * 2017.06.02 - * email: wangwei@doit.am - * www.doit.am - */ - -#include "user_config.h" -#include "alexa.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "freertos/event_groups.h" -#include "driver/gpio.h" - -static const char *TAG = "main"; - -static const int CONNECTED_BIT = BIT0; -static EventGroupHandle_t wifi_event_group; -static uint8_t wifi_mac[6] = {0}; -static tcpip_adapter_ip_info_t ip_info; -static char local_ip[16] = {0}; -static unsigned char local_ip_num[4] = {0}; - -char *get_local_ip(void) -{ - return local_ip; -} - -unsigned char *get_ip_num(void) -{ - return local_ip_num; -} - -static void save_ip_num(uint32_t ip) -{ - local_ip_num[0] = (unsigned char)(ip & 0xFF); - local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); - local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); - local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); -} - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { - ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); - ESP_LOGI(TAG, "~~~~~~~~~~~"); - sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); - save_ip_num(ip_info.ip.addr); - } - - ESP_LOGI(TAG, "AP+STA started"); - alexa_init(); - } - vTaskDelete(NULL); -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - - wifi_config_t sta_config = { - .sta = { - .ssid = MY_WIFI_SSID, - .password = MY_WIFI_PASS, - .bssid_set = false - }, - }; - - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); - - esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); - if (er != ESP_OK) { - ESP_LOGE(TAG, "get wifi MAC failed"); - } else { - ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); - } - - ESP_ERROR_CHECK(esp_wifi_start()); - -} - -void gpio_init(void) -{ - gpio_pad_select_gpio(GPIO_TEST); - gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_TEST, 0); -} - -void app_main(void) -{ - ESP_LOGI(TAG, "enter main"); - initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); - gpio_init(); -} +// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * Nicholas3388 + * 2017.06.02 + * email: wangwei@doit.am + * www.doit.am + */ + +#include "user_config.h" +#include "alexa.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "freertos/event_groups.h" +#include "driver/gpio.h" + +static const char *TAG = "main"; + +static const int CONNECTED_BIT = BIT0; +static EventGroupHandle_t wifi_event_group; +static uint8_t wifi_mac[6] = {0}; +static tcpip_adapter_ip_info_t ip_info; +static char local_ip[16] = {0}; +static unsigned char local_ip_num[4] = {0}; + +char *get_local_ip(void) +{ + return local_ip; +} + +unsigned char *get_ip_num(void) +{ + return local_ip_num; +} + +static void save_ip_num(uint32_t ip) +{ + local_ip_num[0] = (unsigned char)(ip & 0xFF); + local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); + local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); + local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); +} + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + ESP_LOGI(TAG, "~~~~~~~~~~~"); + ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "~~~~~~~~~~~"); + sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); + save_ip_num(ip_info.ip.addr); + } + + ESP_LOGI(TAG, "AP+STA started"); + alexa_init(); + } + vTaskDelete(NULL); +} + +static void initialise_wifi(void) +{ + tcpip_adapter_init(); + + wifi_config_t sta_config = { + .sta = { + .ssid = MY_WIFI_SSID, + .password = MY_WIFI_PASS, + .bssid_set = false + }, + }; + + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + + esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); + if (er != ESP_OK) { + ESP_LOGE(TAG, "get wifi MAC failed"); + } else { + ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); + } + + ESP_ERROR_CHECK(esp_wifi_start()); + +} + +void gpio_init(void) +{ + gpio_pad_select_gpio(GPIO_TEST); + gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_TEST, 0); +} + +void app_main(void) +{ + ESP_LOGI(TAG, "enter main"); + initialise_wifi(); + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); + gpio_init(); +} diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c index 41c61b8..aa1d462 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c @@ -1,305 +1,305 @@ -/** - * Nicholas3388 - * 2017.04.12 - */ - -#include -#include -#include -#include "my_uart.h" -#include "ble.h" -#include "utils.h" -#include "user_config.h" -#include "esp_log.h" -#include "esp_system.h" -#include "driver/uart.h" -#include "soc/uart_struct.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" - -static const char *TAG = "uart"; -QueueHandle_t uart0_queue; -RcvMsgBuff rcvMsg; -inputStatus status = NONE; - -extern unsigned char wifi_ssid[WIFI_SSID_MAX_LEN]; -extern unsigned char wifi_pass[WIFI_PASS_MAX_LEN]; -extern unsigned char srv_ip[SRV_IP_MAX_LEN]; -extern int srv_port; - -extern void initialise_wifi(void); -extern void clear_storage(void); -extern void close_nvs(void); -extern esp_err_t save_string(const char *key, const char *str); -extern esp_err_t save_int32(const char *key, int data); - -void show_help_info() -{ - ESP_LOGI(TAG, " "); - ESP_LOGI(TAG, "----------------------------------------"); - ESP_LOGI(TAG, "input the following command to setup:"); - ESP_LOGI(TAG, " ssid - set AP ssid"); - ESP_LOGI(TAG, " pass - set password"); - ESP_LOGI(TAG, " ip - set server ip"); - ESP_LOGI(TAG, " port - set server port"); - ESP_LOGI(TAG, " wifi - start connecting to wifi"); - ESP_LOGI(TAG, " quit - reset wifi parameters"); - ESP_LOGI(TAG, " help - show help info"); - ESP_LOGI(TAG, "----------------------------------------"); - ESP_LOGI(TAG, " "); -} - -static bool is_valid_port(const char *port, int len) -{ - int i; - if (len > 5) { - ESP_LOGE(TAG, "invalid port!"); - return false; - } - - if (str2num(port, len) > 65535) { - ESP_LOGE(TAG, "port > 65535"); - return false; - } - - for (i = 0; i < len; i++) { - if (port[i] < '0' || port[i] > '9') { - return false; - } - } - return true; -} - -static void uart_input_handler(const char *data, int len) -{ - int i; - if (len < 1) { - return; - } - - if (data[0] == 0x7f || data[0] == 0x08) { - if (rcvMsg.pWritePos != rcvMsg.pRcvMsgBuff) { - const char back = 0x08, space = ' '; - uart_write_bytes(UART_NUM_0, &back, 1); - uart_write_bytes(UART_NUM_0, &space, 1); - //uart_write_bytes(UART_NUM_0, &back, 1); - rcvMsg.pWritePos[0] = 0; - rcvMsg.pWritePos -= 1; - } else { - // nothing to delete - return; - } - } - - if (data[0] == '\r' || data[0] == '\n') { - // enter key press - rcvMsg.pWritePos[0] = 0; - - if (rcvMsg.pWritePos == rcvMsg.pRcvMsgBuff) { - uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); - } else { - int length = rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff; - uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); - if (status == INPUT_SSID) { - memset(wifi_ssid, 0, WIFI_SSID_MAX_LEN); - memcpy(wifi_ssid, rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set ssid: %s", wifi_ssid); - esp_err_t er = save_string(CMD_SSID, (char *)wifi_ssid); - if (er != ESP_OK) - ESP_LOGE(TAG, "save ssid error"); - goto set_end; - } else if (status == INPUT_PASS) { - memset(wifi_pass, 0, WIFI_PASS_MAX_LEN); - memcpy(wifi_pass, rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set password: %s", wifi_pass); - esp_err_t er = save_string(CMD_PASS, (char *)wifi_pass); - if (er != ESP_OK) - ESP_LOGE(TAG, "save pass error"); - goto set_end; - } else if (status == INPUT_IP) { - memset(srv_ip, 0, SRV_IP_MAX_LEN); - memcpy(srv_ip, rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set server ip: %s", srv_ip); - esp_err_t er = save_string(CMD_IP, (char *)srv_ip); - if (er != ESP_OK) - ESP_LOGE(TAG, "save ip error"); - goto set_end; - } else if (status == INPUT_PORT) { - if (!is_valid_port((const char *)rcvMsg.pRcvMsgBuff, length)) { - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; - ESP_LOGE(TAG, "invalid server port, please input again"); - return; - } - srv_port = str2num((const char *)rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set server port: %d", srv_port); - //esp_err_t er = save_int32(CMD_PORT, srv_port); - esp_err_t er = save_string(CMD_PORT, (char *)rcvMsg.pRcvMsgBuff); - if (er != ESP_OK) - ESP_LOGE(TAG, "save port error"); - goto set_end; - } - - if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_SSID, length) == 0) { - ESP_LOGI(TAG, "input your ssid [less than 32byte]:"); - status = INPUT_SSID; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PASS, length) == 0) { - ESP_LOGI(TAG, "input your password [less than 32byte]:"); - status = INPUT_PASS; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_IP, length) == 0) { - ESP_LOGI(TAG, "input server IP:"); - status = INPUT_IP; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PORT, length) == 0) { - ESP_LOGI(TAG, "input server port:"); - status = INPUT_PORT; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_HELP, length) == 0) { - show_help_info(); - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_WIFI, length) == 0) { - ESP_LOGI(TAG, "BLE scanning ......"); - close_nvs(); - ble_client_app_register(); - //initialise_wifi(); - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_QUIT, length) == 0) { - ESP_LOGI(TAG, "reset wifi info:"); - clear_storage(); - close_nvs(); - system_restart(); - } else { - ESP_LOGI(TAG, "invalid command %s", rcvMsg.pRcvMsgBuff); - show_help_info(); - } - } -set_end: - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; - memset(rcvMsg.pRcvMsgBuff, 0, RECV_BUF_SIZE); - return; - } - - *(rcvMsg.pWritePos) = data[0]; - uart_write_bytes(UART_NUM_0, &data[0], 1); - rcvMsg.pWritePos += 1; - - if (rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff >= RECV_BUF_SIZE - 1) { - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; // overflow, restart - ESP_LOGI(TAG, "overflow"); - } -} - -static void uart_task(void *pvParameters) -{ - int uart_num = UART_NUM_0; - uart_event_t event; - size_t buffered_size; - uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE); - for(;;) { - //Waiting for UART event. - if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - //ESP_LOGI(TAG, "uart[%d] event:", uart_num); - switch(event.type) { - //Event of UART receving data - /*We'd better handler data event fast, there would be much more data events than - other types of events. If we take too much time on data event, the queue might - be full. - in this example, we don't process data in event, but read data outside.*/ - case UART_DATA: - uart_get_buffered_data_len(uart_num, &buffered_size); - //ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); - break; - //Event of HW FIFO overflow detected - case UART_FIFO_OVF: - ESP_LOGI(TAG, "hw fifo overflow\n"); - //If fifo overflow happened, you should consider adding flow control for your application. - //We can read data out out the buffer, or directly flush the rx buffer. - uart_flush(uart_num); - break; - //Event of UART ring buffer full - case UART_BUFFER_FULL: - ESP_LOGI(TAG, "ring buffer full\n"); - //If buffer full happened, you should consider encreasing your buffer size - //We can read data out out the buffer, or directly flush the rx buffer. - uart_flush(uart_num); - break; - //Event of UART RX break detected - case UART_BREAK: - ESP_LOGI(TAG, "uart rx break\n"); - break; - //Event of UART parity check error - case UART_PARITY_ERR: - ESP_LOGI(TAG, "uart parity error\n"); - break; - //Event of UART frame error - case UART_FRAME_ERR: - ESP_LOGI(TAG, "uart frame error\n"); - break; - //UART_PATTERN_DET - case UART_PATTERN_DET: - ESP_LOGI(TAG, "uart pattern detected\n"); - break; - //Others - default: - ESP_LOGI(TAG, "uart event type: %d\n", event.type); - break; - } - } - } - free(dtmp); - dtmp = NULL; - vTaskDelete(NULL); -} - -static void uart_evt_task(void *pvParameters) -{ - int uart_num = UART_NUM_0; - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .rx_flow_ctrl_thresh = 122, - }; - //Set UART parameters - uart_param_config(uart_num, &uart_config); - //Set UART log level - esp_log_level_set(TAG, ESP_LOG_INFO); - //Install UART driver, and get the queue. - uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0); - //Set UART pins,(-1: default pin, no change.) - //For UART0, we can just use the default pins. - //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - //Set uart pattern detect function. - uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); - //Create a task to handler UART event from ISR - xTaskCreate(uart_task, "uart_task", UART_TASK_STACK_SIZE, NULL, UART_TASK_PRIO, NULL); - //process data - uint8_t* data = (uint8_t*) malloc(BUF_SIZE); - do { - int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); - if(len > 0) { - //ESP_LOGI(TAG, "uart read : %d", len); - //uart_write_bytes(uart_num, (const char*)data, len); - uart_input_handler((const char*)data, len); - } - } while(1); -} - -void uart_init(void) -{ - memset(&rcvMsg, 0, sizeof(rcvMsg)); - rcvMsg.RcvBuffSize = RECV_BUF_SIZE; - rcvMsg.pRcvMsgBuff = NULL; - rcvMsg.pRcvMsgBuff = (uint8_t *) malloc(RECV_BUF_SIZE); - if (rcvMsg.pRcvMsgBuff == NULL) { - ESP_LOGE(TAG, "receive buffer alloc failed"); - return; - } - rcvMsg.pReadPos = rcvMsg.pRcvMsgBuff; - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; - - xTaskCreate(uart_evt_task, "uart_evt_task", UART_EVT_TASK_STACK_SIZE, NULL, UART_EVT_TASK_PRIO, NULL); +/** + * Nicholas3388 + * 2017.04.12 + */ + +#include +#include +#include +#include "my_uart.h" +#include "ble.h" +#include "utils.h" +#include "user_config.h" +#include "esp_log.h" +#include "esp_system.h" +#include "driver/uart.h" +#include "soc/uart_struct.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +static const char *TAG = "uart"; +QueueHandle_t uart0_queue; +RcvMsgBuff rcvMsg; +inputStatus status = NONE; + +extern unsigned char wifi_ssid[WIFI_SSID_MAX_LEN]; +extern unsigned char wifi_pass[WIFI_PASS_MAX_LEN]; +extern unsigned char srv_ip[SRV_IP_MAX_LEN]; +extern int srv_port; + +extern void initialise_wifi(void); +extern void clear_storage(void); +extern void close_nvs(void); +extern esp_err_t save_string(const char *key, const char *str); +extern esp_err_t save_int32(const char *key, int data); + +void show_help_info() +{ + ESP_LOGI(TAG, " "); + ESP_LOGI(TAG, "----------------------------------------"); + ESP_LOGI(TAG, "input the following command to setup:"); + ESP_LOGI(TAG, " ssid - set AP ssid"); + ESP_LOGI(TAG, " pass - set password"); + ESP_LOGI(TAG, " ip - set server ip"); + ESP_LOGI(TAG, " port - set server port"); + ESP_LOGI(TAG, " wifi - start connecting to wifi"); + ESP_LOGI(TAG, " quit - reset wifi parameters"); + ESP_LOGI(TAG, " help - show help info"); + ESP_LOGI(TAG, "----------------------------------------"); + ESP_LOGI(TAG, " "); +} + +static bool is_valid_port(const char *port, int len) +{ + int i; + if (len > 5) { + ESP_LOGE(TAG, "invalid port!"); + return false; + } + + if (str2num(port, len) > 65535) { + ESP_LOGE(TAG, "port > 65535"); + return false; + } + + for (i = 0; i < len; i++) { + if (port[i] < '0' || port[i] > '9') { + return false; + } + } + return true; +} + +static void uart_input_handler(const char *data, int len) +{ + int i; + if (len < 1) { + return; + } + + if (data[0] == 0x7f || data[0] == 0x08) { + if (rcvMsg.pWritePos != rcvMsg.pRcvMsgBuff) { + const char back = 0x08, space = ' '; + uart_write_bytes(UART_NUM_0, &back, 1); + uart_write_bytes(UART_NUM_0, &space, 1); + //uart_write_bytes(UART_NUM_0, &back, 1); + rcvMsg.pWritePos[0] = 0; + rcvMsg.pWritePos -= 1; + } else { + // nothing to delete + return; + } + } + + if (data[0] == '\r' || data[0] == '\n') { + // enter key press + rcvMsg.pWritePos[0] = 0; + + if (rcvMsg.pWritePos == rcvMsg.pRcvMsgBuff) { + uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); + } else { + int length = rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff; + uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); + if (status == INPUT_SSID) { + memset(wifi_ssid, 0, WIFI_SSID_MAX_LEN); + memcpy(wifi_ssid, rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set ssid: %s", wifi_ssid); + esp_err_t er = save_string(CMD_SSID, (char *)wifi_ssid); + if (er != ESP_OK) + ESP_LOGE(TAG, "save ssid error"); + goto set_end; + } else if (status == INPUT_PASS) { + memset(wifi_pass, 0, WIFI_PASS_MAX_LEN); + memcpy(wifi_pass, rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set password: %s", wifi_pass); + esp_err_t er = save_string(CMD_PASS, (char *)wifi_pass); + if (er != ESP_OK) + ESP_LOGE(TAG, "save pass error"); + goto set_end; + } else if (status == INPUT_IP) { + memset(srv_ip, 0, SRV_IP_MAX_LEN); + memcpy(srv_ip, rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set server ip: %s", srv_ip); + esp_err_t er = save_string(CMD_IP, (char *)srv_ip); + if (er != ESP_OK) + ESP_LOGE(TAG, "save ip error"); + goto set_end; + } else if (status == INPUT_PORT) { + if (!is_valid_port((const char *)rcvMsg.pRcvMsgBuff, length)) { + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; + ESP_LOGE(TAG, "invalid server port, please input again"); + return; + } + srv_port = str2num((const char *)rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set server port: %d", srv_port); + //esp_err_t er = save_int32(CMD_PORT, srv_port); + esp_err_t er = save_string(CMD_PORT, (char *)rcvMsg.pRcvMsgBuff); + if (er != ESP_OK) + ESP_LOGE(TAG, "save port error"); + goto set_end; + } + + if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_SSID, length) == 0) { + ESP_LOGI(TAG, "input your ssid [less than 32byte]:"); + status = INPUT_SSID; + } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PASS, length) == 0) { + ESP_LOGI(TAG, "input your password [less than 32byte]:"); + status = INPUT_PASS; + } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_IP, length) == 0) { + ESP_LOGI(TAG, "input server IP:"); + status = INPUT_IP; + } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PORT, length) == 0) { + ESP_LOGI(TAG, "input server port:"); + status = INPUT_PORT; + } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_HELP, length) == 0) { + show_help_info(); + } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_WIFI, length) == 0) { + ESP_LOGI(TAG, "BLE scanning ......"); + close_nvs(); + ble_client_app_register(); + //initialise_wifi(); + } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_QUIT, length) == 0) { + ESP_LOGI(TAG, "reset wifi info:"); + clear_storage(); + close_nvs(); + system_restart(); + } else { + ESP_LOGI(TAG, "invalid command %s", rcvMsg.pRcvMsgBuff); + show_help_info(); + } + } +set_end: + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; + memset(rcvMsg.pRcvMsgBuff, 0, RECV_BUF_SIZE); + return; + } + + *(rcvMsg.pWritePos) = data[0]; + uart_write_bytes(UART_NUM_0, &data[0], 1); + rcvMsg.pWritePos += 1; + + if (rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff >= RECV_BUF_SIZE - 1) { + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; // overflow, restart + ESP_LOGI(TAG, "overflow"); + } +} + +static void uart_task(void *pvParameters) +{ + int uart_num = UART_NUM_0; + uart_event_t event; + size_t buffered_size; + uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE); + for(;;) { + //Waiting for UART event. + if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + //ESP_LOGI(TAG, "uart[%d] event:", uart_num); + switch(event.type) { + //Event of UART receving data + /*We'd better handler data event fast, there would be much more data events than + other types of events. If we take too much time on data event, the queue might + be full. + in this example, we don't process data in event, but read data outside.*/ + case UART_DATA: + uart_get_buffered_data_len(uart_num, &buffered_size); + //ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); + break; + //Event of HW FIFO overflow detected + case UART_FIFO_OVF: + ESP_LOGI(TAG, "hw fifo overflow\n"); + //If fifo overflow happened, you should consider adding flow control for your application. + //We can read data out out the buffer, or directly flush the rx buffer. + uart_flush(uart_num); + break; + //Event of UART ring buffer full + case UART_BUFFER_FULL: + ESP_LOGI(TAG, "ring buffer full\n"); + //If buffer full happened, you should consider encreasing your buffer size + //We can read data out out the buffer, or directly flush the rx buffer. + uart_flush(uart_num); + break; + //Event of UART RX break detected + case UART_BREAK: + ESP_LOGI(TAG, "uart rx break\n"); + break; + //Event of UART parity check error + case UART_PARITY_ERR: + ESP_LOGI(TAG, "uart parity error\n"); + break; + //Event of UART frame error + case UART_FRAME_ERR: + ESP_LOGI(TAG, "uart frame error\n"); + break; + //UART_PATTERN_DET + case UART_PATTERN_DET: + ESP_LOGI(TAG, "uart pattern detected\n"); + break; + //Others + default: + ESP_LOGI(TAG, "uart event type: %d\n", event.type); + break; + } + } + } + free(dtmp); + dtmp = NULL; + vTaskDelete(NULL); +} + +static void uart_evt_task(void *pvParameters) +{ + int uart_num = UART_NUM_0; + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 122, + }; + //Set UART parameters + uart_param_config(uart_num, &uart_config); + //Set UART log level + esp_log_level_set(TAG, ESP_LOG_INFO); + //Install UART driver, and get the queue. + uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0); + //Set UART pins,(-1: default pin, no change.) + //For UART0, we can just use the default pins. + //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + //Set uart pattern detect function. + uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); + //Create a task to handler UART event from ISR + xTaskCreate(uart_task, "uart_task", UART_TASK_STACK_SIZE, NULL, UART_TASK_PRIO, NULL); + //process data + uint8_t* data = (uint8_t*) malloc(BUF_SIZE); + do { + int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); + if(len > 0) { + //ESP_LOGI(TAG, "uart read : %d", len); + //uart_write_bytes(uart_num, (const char*)data, len); + uart_input_handler((const char*)data, len); + } + } while(1); +} + +void uart_init(void) +{ + memset(&rcvMsg, 0, sizeof(rcvMsg)); + rcvMsg.RcvBuffSize = RECV_BUF_SIZE; + rcvMsg.pRcvMsgBuff = NULL; + rcvMsg.pRcvMsgBuff = (uint8_t *) malloc(RECV_BUF_SIZE); + if (rcvMsg.pRcvMsgBuff == NULL) { + ESP_LOGE(TAG, "receive buffer alloc failed"); + return; + } + rcvMsg.pReadPos = rcvMsg.pRcvMsgBuff; + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; + + xTaskCreate(uart_evt_task, "uart_evt_task", UART_EVT_TASK_STACK_SIZE, NULL, UART_EVT_TASK_PRIO, NULL); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c index 8fda583..5b5b424 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c @@ -1,69 +1,69 @@ -#include -#include -#include "my_list.h" -#include "esp_log.h" -#include "user_config.h" - -static const char *TAG = "my_list"; - -static scan_list_t head; - -void list_init(void) -{ - head.bda = NULL; - head.uuid = NULL; - head.rssi = 0; - head.pNext = NULL; -} - -scan_list_t *list_new_item(void) -{ - scan_list_t *newItem = (scan_list_t *) malloc(sizeof(scan_list_t)); - if (newItem == NULL) { - ESP_LOGE(TAG, "malloc list item failed!"); - return NULL; - } - memset(newItem, 0, sizeof(scan_list_t)); - newItem->bda = (char *) malloc(BDA_SIZE); - - if (newItem->bda == NULL) { - ESP_LOGE(TAG, "alloc for BDA failed!"); - free(newItem); - return NULL; - } - - newItem->uuid = (char *)malloc(UUID_SIZE); - if (newItem->uuid == NULL) { - ESP_LOGE(TAG, "alloc for UUID failed!"); - free(newItem->bda); - free(newItem); - return NULL; - } - - return newItem; -} - -void list_insert_to_head(scan_list_t *item) -{ - scan_list_t *next = NULL; - next = head.pNext; - head.pNext = item; - item->pNext = next; -} - -void list_destroy(void) -{ - scan_list_t *next = NULL; - while (head.pNext != NULL) { - next = (head.pNext)->pNext; - free((head.pNext)->bda); - free((head.pNext)->uuid); - free(head.pNext); - head.pNext = next; - } -} - -scan_list_t *list_get_head(void) -{ - return &head; +#include +#include +#include "my_list.h" +#include "esp_log.h" +#include "user_config.h" + +static const char *TAG = "my_list"; + +static scan_list_t head; + +void list_init(void) +{ + head.bda = NULL; + head.uuid = NULL; + head.rssi = 0; + head.pNext = NULL; +} + +scan_list_t *list_new_item(void) +{ + scan_list_t *newItem = (scan_list_t *) malloc(sizeof(scan_list_t)); + if (newItem == NULL) { + ESP_LOGE(TAG, "malloc list item failed!"); + return NULL; + } + memset(newItem, 0, sizeof(scan_list_t)); + newItem->bda = (char *) malloc(BDA_SIZE); + + if (newItem->bda == NULL) { + ESP_LOGE(TAG, "alloc for BDA failed!"); + free(newItem); + return NULL; + } + + newItem->uuid = (char *)malloc(UUID_SIZE); + if (newItem->uuid == NULL) { + ESP_LOGE(TAG, "alloc for UUID failed!"); + free(newItem->bda); + free(newItem); + return NULL; + } + + return newItem; +} + +void list_insert_to_head(scan_list_t *item) +{ + scan_list_t *next = NULL; + next = head.pNext; + head.pNext = item; + item->pNext = next; +} + +void list_destroy(void) +{ + scan_list_t *next = NULL; + while (head.pNext != NULL) { + next = (head.pNext)->pNext; + free((head.pNext)->bda); + free((head.pNext)->uuid); + free(head.pNext); + head.pNext = next; + } +} + +scan_list_t *list_get_head(void) +{ + return &head; } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c index 1abc693..f3546b9 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c @@ -1,346 +1,346 @@ -/** - * ESP32 beacon scan and udp send demo - * - * Nicholas3388 - * 2017.4.12 - */ - -#include -#include "esp_log.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - -#include "nvs_flash.h" -#include "nvs.h" - -#include "driver/gpio.h" -#include "utils.h" -#include "ble.h" -#include "udp_task.h" -#include "user_config.h" -#include "my_uart.h" -#include "my_list.h" - -#define LED_GPIO 2 - -static const char *TAG = "main"; -static EventGroupHandle_t wifi_event_group; -const int CONNECTED_BIT = BIT0; -static tcpip_adapter_ip_info_t ip_info; - -static bool panic = false; -static bool wifi_check = false; -static int wifi_check_count = 0; -uint8_t wifi_mac[6] = {0}; -bool toggle = false; -unsigned char wifi_ssid[WIFI_SSID_MAX_LEN] = {0}; -unsigned char wifi_pass[WIFI_PASS_MAX_LEN] = {0}; -unsigned char srv_ip[SRV_IP_MAX_LEN] = {0}; -int srv_port = 0; -static bool is_task_running = false; -static nvs_handle my_nvs_handle; - -extern void connect_server(const char *ip, int port); - -static void show_copyright(void) -{ - ESP_LOGI(TAG, "################################"); - ESP_LOGI(TAG, "## Test app ##"); - ESP_LOGI(TAG, "## 2017.4.12 ##"); - ESP_LOGI(TAG, "################################"); -} - -void set_panic(void) -{ - panic = true; -} - -void clear_panic(void) -{ - panic = false; -} - -esp_err_t save_string(const char *key, char *str) -{ - esp_err_t err = nvs_set_str (my_nvs_handle, key, str); - nvs_commit(my_nvs_handle); - return err; -} - -esp_err_t save_int32(const char *key, int data) -{ - esp_err_t err = nvs_set_i32 (my_nvs_handle, key, data); - nvs_commit(my_nvs_handle); - return err; -} - -int get_int32(const char *key) -{ - int out_value; - nvs_get_i32 (my_nvs_handle, key, &out_value); - return out_value; -} - -void get_string(const char* key, char* out_value, size_t* length) -{ - nvs_get_str (my_nvs_handle, key, out_value, length); -} - -void clear_storage(void) -{ - nvs_erase_all(my_nvs_handle); - nvs_commit(my_nvs_handle); -} - -void close_nvs(void) -{ - nvs_close(my_nvs_handle); -} - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void initialise_wifi(void) -{ - if (is_task_running) { -#ifdef ENABLE_SCAN_OUTPUT - ESP_LOGE(TAG, "task was running, no need to init again"); -#endif - send_all_data(); - - //restart scanning -#ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "###############################################"); - ESP_LOGI(TAG, "restart scanning ......"); -#endif - vTaskDelay(1000 / portTICK_PERIOD_MS); - ble_start_scanning(); - return; - } - - if (strlen((const char *)wifi_ssid) == 0) { - ESP_LOGE(TAG, "expected ssid"); - } - - if (strlen((const char *)wifi_pass) == 0) { - ESP_LOGE(TAG, "expected password"); - } - - tcpip_adapter_init(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = {0}, - .password = {0}, - }, - }; - memcpy(wifi_config.sta.ssid, wifi_ssid, strlen((const char *)wifi_ssid)); - memcpy(wifi_config.sta.password, wifi_pass, strlen((const char *)wifi_pass)); - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...PASS %s", wifi_config.sta.ssid, wifi_config.sta.password); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - - esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); - if (er != ESP_OK) { - ESP_LOGE(TAG, "get wifi MAC failed"); - } else { - ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); - } - - ESP_ERROR_CHECK( esp_wifi_start() ); - - wifi_check = true; // start wifi checking -} - -static void tmp_task(void *pvParameters) -{ - is_task_running = true; - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { - ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); - ESP_LOGI(TAG, "~~~~~~~~~~~"); - } - wifi_check = false; // stop wifi checking - - if (strlen((const char *)srv_ip) == 0) { - ESP_LOGE(TAG, "expected server IP, reset board to setup again!"); - break; - } - - if (srv_port == 0) { - ESP_LOGE(TAG, "expected server port, reset board to setup again!"); - break; - } - - // start espconn - connect_server((const char *)srv_ip, srv_port); - - while(1) { - vTaskDelay(3000 / portTICK_RATE_MS); // prevent trigger watch dog - } - } - vTaskDelete(NULL); - is_task_running = false; -} - -void wifi_init_task(void) -{ - if (is_task_running) { -#ifdef ENABLE_SCAN_OUTPUT - ESP_LOGE(TAG, "task was running"); -#endif - return; - } - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); -} - -static void led_task(void *pvParameters) -{ - while(1) { - if (panic) { - if (toggle) { - gpio_set_level(LED_GPIO, 1); - } else { - gpio_set_level(LED_GPIO, 0); - } - toggle = !toggle; - vTaskDelay(1000 / portTICK_RATE_MS); - } else { - //ESP_LOGI(TAG, "tmp_task loop"); - vTaskDelay(1000 / portTICK_RATE_MS); // prevent trigger watch dog - } - - if (wifi_check) { - wifi_check_count++; - if (wifi_check_count >= WIFI_CHECK_TIMEOUT) { - set_panic(); - wifi_check_count = 0; - } - } - } - vTaskDelete(NULL); -} - -static void led_task_init(void) -{ - gpio_pad_select_gpio(LED_GPIO); - /* Set the GPIO as a push/pull output */ - gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT); - gpio_set_level(LED_GPIO, 1); - - xTaskCreate(&led_task, "led_task", LED_TASK_STACK_SIZE, NULL, LED_TASK_PRIO, NULL); -} - -static void nvs_init(void) -{ - nvs_flash_init(); - esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_nvs_handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Error (%d) opening NVS!\n", err); - } else { - ESP_LOGI(TAG, "NVS open OK"); - } - -} - -static void load_config(void) -{ - size_t length = WIFI_SSID_MAX_LEN; - esp_err_t er; - er = nvs_get_str (my_nvs_handle, CMD_SSID, (char*)wifi_ssid, &length); - ESP_LOGI(TAG, "load ssid: %s", wifi_ssid); - if (er != ESP_OK) { - ESP_LOGE(TAG, "SSID not saved before"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset SSID: %s", wifi_ssid); - } - - er = nvs_get_str (my_nvs_handle, CMD_PASS, (char*)wifi_pass, &length); - ESP_LOGI(TAG, "load password: %s", wifi_pass); - if (er != ESP_OK) { - ESP_LOGE(TAG, "password not saved before"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset password: %s", wifi_pass); - } - - length = SRV_IP_MAX_LEN; - er = nvs_get_str (my_nvs_handle, CMD_IP, (char*)srv_ip, &length); - ESP_LOGI(TAG, "load ip: %s", srv_ip); - if (length == 0 || er != ESP_OK) { - ESP_LOGE(TAG, "ip not saved before"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset IP: %s", srv_ip); - } - - char port[SRV_IP_MAX_LEN] = {0}; - er = nvs_get_str (my_nvs_handle, CMD_PORT, (char*)port, &length); - if (er != ESP_OK) { - ESP_LOGE(TAG, "port get failed"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset port: %s", port); - } - srv_port = str2num((const char *)port, strlen(port)); - ESP_LOGI(TAG, "preset port in num: %d", srv_port); - - // ble scan and connect to wifi directly - ESP_LOGI(TAG, "BLE scanning ......"); - ble_client_app_register(); - return; -load_config_err: - ESP_LOGE(TAG, "some parameters not set"); - //set_panic(); - return; -} - -void app_main() -{ - ESP_LOGI(TAG, "App started"); - nvs_init(); - - show_copyright(); - - list_init(); - ble_init(); - uart_init(); - - led_task_init(); - - wifi_event_group = xEventGroupCreate(); - - show_help_info(); - load_config(); +/** + * ESP32 beacon scan and udp send demo + * + * Nicholas3388 + * 2017.4.12 + */ + +#include +#include "esp_log.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" + +#include "nvs_flash.h" +#include "nvs.h" + +#include "driver/gpio.h" +#include "utils.h" +#include "ble.h" +#include "udp_task.h" +#include "user_config.h" +#include "my_uart.h" +#include "my_list.h" + +#define LED_GPIO 2 + +static const char *TAG = "main"; +static EventGroupHandle_t wifi_event_group; +const int CONNECTED_BIT = BIT0; +static tcpip_adapter_ip_info_t ip_info; + +static bool panic = false; +static bool wifi_check = false; +static int wifi_check_count = 0; +uint8_t wifi_mac[6] = {0}; +bool toggle = false; +unsigned char wifi_ssid[WIFI_SSID_MAX_LEN] = {0}; +unsigned char wifi_pass[WIFI_PASS_MAX_LEN] = {0}; +unsigned char srv_ip[SRV_IP_MAX_LEN] = {0}; +int srv_port = 0; +static bool is_task_running = false; +static nvs_handle my_nvs_handle; + +extern void connect_server(const char *ip, int port); + +static void show_copyright(void) +{ + ESP_LOGI(TAG, "################################"); + ESP_LOGI(TAG, "## Test app ##"); + ESP_LOGI(TAG, "## 2017.4.12 ##"); + ESP_LOGI(TAG, "################################"); +} + +void set_panic(void) +{ + panic = true; +} + +void clear_panic(void) +{ + panic = false; +} + +esp_err_t save_string(const char *key, char *str) +{ + esp_err_t err = nvs_set_str (my_nvs_handle, key, str); + nvs_commit(my_nvs_handle); + return err; +} + +esp_err_t save_int32(const char *key, int data) +{ + esp_err_t err = nvs_set_i32 (my_nvs_handle, key, data); + nvs_commit(my_nvs_handle); + return err; +} + +int get_int32(const char *key) +{ + int out_value; + nvs_get_i32 (my_nvs_handle, key, &out_value); + return out_value; +} + +void get_string(const char* key, char* out_value, size_t* length) +{ + nvs_get_str (my_nvs_handle, key, out_value, length); +} + +void clear_storage(void) +{ + nvs_erase_all(my_nvs_handle); + nvs_commit(my_nvs_handle); +} + +void close_nvs(void) +{ + nvs_close(my_nvs_handle); +} + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} + +void initialise_wifi(void) +{ + if (is_task_running) { +#ifdef ENABLE_SCAN_OUTPUT + ESP_LOGE(TAG, "task was running, no need to init again"); +#endif + send_all_data(); + + //restart scanning +#ifdef ENABLE_SCAN_OUTPUT + ESP_LOGI(TAG, "###############################################"); + ESP_LOGI(TAG, "restart scanning ......"); +#endif + vTaskDelay(1000 / portTICK_PERIOD_MS); + ble_start_scanning(); + return; + } + + if (strlen((const char *)wifi_ssid) == 0) { + ESP_LOGE(TAG, "expected ssid"); + } + + if (strlen((const char *)wifi_pass) == 0) { + ESP_LOGE(TAG, "expected password"); + } + + tcpip_adapter_init(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + wifi_config_t wifi_config = { + .sta = { + .ssid = {0}, + .password = {0}, + }, + }; + memcpy(wifi_config.sta.ssid, wifi_ssid, strlen((const char *)wifi_ssid)); + memcpy(wifi_config.sta.password, wifi_pass, strlen((const char *)wifi_pass)); + ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...PASS %s", wifi_config.sta.ssid, wifi_config.sta.password); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + + esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); + if (er != ESP_OK) { + ESP_LOGE(TAG, "get wifi MAC failed"); + } else { + ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); + } + + ESP_ERROR_CHECK( esp_wifi_start() ); + + wifi_check = true; // start wifi checking +} + +static void tmp_task(void *pvParameters) +{ + is_task_running = true; + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + ESP_LOGI(TAG, "~~~~~~~~~~~"); + ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "~~~~~~~~~~~"); + } + wifi_check = false; // stop wifi checking + + if (strlen((const char *)srv_ip) == 0) { + ESP_LOGE(TAG, "expected server IP, reset board to setup again!"); + break; + } + + if (srv_port == 0) { + ESP_LOGE(TAG, "expected server port, reset board to setup again!"); + break; + } + + // start espconn + connect_server((const char *)srv_ip, srv_port); + + while(1) { + vTaskDelay(3000 / portTICK_RATE_MS); // prevent trigger watch dog + } + } + vTaskDelete(NULL); + is_task_running = false; +} + +void wifi_init_task(void) +{ + if (is_task_running) { +#ifdef ENABLE_SCAN_OUTPUT + ESP_LOGE(TAG, "task was running"); +#endif + return; + } + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); +} + +static void led_task(void *pvParameters) +{ + while(1) { + if (panic) { + if (toggle) { + gpio_set_level(LED_GPIO, 1); + } else { + gpio_set_level(LED_GPIO, 0); + } + toggle = !toggle; + vTaskDelay(1000 / portTICK_RATE_MS); + } else { + //ESP_LOGI(TAG, "tmp_task loop"); + vTaskDelay(1000 / portTICK_RATE_MS); // prevent trigger watch dog + } + + if (wifi_check) { + wifi_check_count++; + if (wifi_check_count >= WIFI_CHECK_TIMEOUT) { + set_panic(); + wifi_check_count = 0; + } + } + } + vTaskDelete(NULL); +} + +static void led_task_init(void) +{ + gpio_pad_select_gpio(LED_GPIO); + /* Set the GPIO as a push/pull output */ + gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT); + gpio_set_level(LED_GPIO, 1); + + xTaskCreate(&led_task, "led_task", LED_TASK_STACK_SIZE, NULL, LED_TASK_PRIO, NULL); +} + +static void nvs_init(void) +{ + nvs_flash_init(); + esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_nvs_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error (%d) opening NVS!\n", err); + } else { + ESP_LOGI(TAG, "NVS open OK"); + } + +} + +static void load_config(void) +{ + size_t length = WIFI_SSID_MAX_LEN; + esp_err_t er; + er = nvs_get_str (my_nvs_handle, CMD_SSID, (char*)wifi_ssid, &length); + ESP_LOGI(TAG, "load ssid: %s", wifi_ssid); + if (er != ESP_OK) { + ESP_LOGE(TAG, "SSID not saved before"); + goto load_config_err; + } else { + ESP_LOGI(TAG, "preset SSID: %s", wifi_ssid); + } + + er = nvs_get_str (my_nvs_handle, CMD_PASS, (char*)wifi_pass, &length); + ESP_LOGI(TAG, "load password: %s", wifi_pass); + if (er != ESP_OK) { + ESP_LOGE(TAG, "password not saved before"); + goto load_config_err; + } else { + ESP_LOGI(TAG, "preset password: %s", wifi_pass); + } + + length = SRV_IP_MAX_LEN; + er = nvs_get_str (my_nvs_handle, CMD_IP, (char*)srv_ip, &length); + ESP_LOGI(TAG, "load ip: %s", srv_ip); + if (length == 0 || er != ESP_OK) { + ESP_LOGE(TAG, "ip not saved before"); + goto load_config_err; + } else { + ESP_LOGI(TAG, "preset IP: %s", srv_ip); + } + + char port[SRV_IP_MAX_LEN] = {0}; + er = nvs_get_str (my_nvs_handle, CMD_PORT, (char*)port, &length); + if (er != ESP_OK) { + ESP_LOGE(TAG, "port get failed"); + goto load_config_err; + } else { + ESP_LOGI(TAG, "preset port: %s", port); + } + srv_port = str2num((const char *)port, strlen(port)); + ESP_LOGI(TAG, "preset port in num: %d", srv_port); + + // ble scan and connect to wifi directly + ESP_LOGI(TAG, "BLE scanning ......"); + ble_client_app_register(); + return; +load_config_err: + ESP_LOGE(TAG, "some parameters not set"); + //set_panic(); + return; +} + +void app_main() +{ + ESP_LOGI(TAG, "App started"); + nvs_init(); + + show_copyright(); + + list_init(); + ble_init(); + uart_init(); + + led_task_init(); + + wifi_event_group = xEventGroupCreate(); + + show_help_info(); + load_config(); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/component.mk b/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/component.mk index d593215..61f8990 100644 --- a/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/component.mk +++ b/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/component.mk @@ -1,8 +1,8 @@ -# -# Main component makefile. -# -# This Makefile can be left empty. By default, it will take the sources in the -# src/ directory, compile them and link them into lib(subdirectory_name).a -# in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# +# +# Main component makefile. +# +# This Makefile can be left empty. By default, it will take the sources in the +# src/ directory, compile them and link them into lib(subdirectory_name).a +# in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# diff --git a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.h b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.h index 567e753..a2de218 100644 --- a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.h +++ b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.h @@ -1,16 +1,16 @@ -/* - * This file is part of the OpenMV project. - * Copyright (c) 2013/2014 Ibrahim Abdelkader - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * SCCB (I2C like) driver. - * - */ -#ifndef __SCCB_H__ -#define __SCCB_H__ -#include -int SCCB_Init(int pin_sda, int pin_scl); -uint8_t SCCB_Probe(); -uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg); -uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data); -#endif // __SCCB_H__ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013/2014 Ibrahim Abdelkader + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * SCCB (I2C like) driver. + * + */ +#ifndef __SCCB_H__ +#define __SCCB_H__ +#include +int SCCB_Init(int pin_sda, int pin_scl); +uint8_t SCCB_Probe(); +uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg); +uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data); +#endif // __SCCB_H__ diff --git a/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c b/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c index 7eb9047..5dffb77 100644 --- a/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c @@ -1,251 +1,251 @@ -#include - -#include "lwip/sockets.h" -#include "lwip/err.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" - -#include "platform.h" -#include "tmr.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "esp_system.h" -#include "nvs_flash.h" -#include "tcpip_adapter.h" - -#define UDP_DNS_PORT 53 -#define UDP_DATA_LEN 1024 -#define UDP_LOCAL_PORT 7 -#define SSID_AP "DOIT" -#define DNS_SERVER_TASK_PRIO 12 -#define TMP_TASK_PRIO 13 - -#define DNS_QR_QUERY 0 -#define DNS_QR_RESPONSE 1 -#define DNS_OPCODE_QUERY 0 - -struct DNSHeader { - unsigned short ID; // identification number - unsigned char RD : 1; // recursion desired - unsigned char TC : 1; // truncated message - unsigned char AA : 1; // authoritive answer - unsigned char OPCode : 4; // message_type - unsigned char QR : 1; // query/response flag - unsigned char RCode : 4; // response code - unsigned char Z : 3; // its z! reserved - unsigned char RA : 1; // recursion available - unsigned short QDCount; // number of question entries - unsigned short ANCount; // number of answer entries - unsigned short NSCount; // number of authority entries - unsigned short ARCount; // number of resource entries -}; - -static EventGroupHandle_t wifi_event_group; -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; - - -void led_blink(void) -{ - if(platform_gpio_mode(2, 2) < 0) { - ESP_LOGI(TAG, "Led lightup failed"); - return; - } - platform_gpio_write(2, 1); // led on - tmr_delay_msec(250); - platform_gpio_write(2, 0); // led off - tmr_delay_msec(250); - platform_gpio_write(2, 1); - tmr_delay_msec(250); - platform_gpio_write(2, 0); - tmr_delay_msec(250); - platform_gpio_write(2, 1); -} - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_AP_START: - ESP_LOGI(TAG, "AP start now"); - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STOP: - ESP_LOGI(TAG, "AP stop now"); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "Station connect"); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "Station disconnect"); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - wifi_config_t config = { - .ap = { - .ssid = SSID_AP, - .ssid_len = strlen(SSID_AP), - .authmode = WIFI_AUTH_OPEN, - .max_connection = 10, - //.ssid_hidden = 0, - //.beacon_interval = 100, - }, - }; - - // set SSID - uint8_t mac[6]; - esp_wifi_get_mac(WIFI_IF_AP, mac); - sprintf(config.ap.ssid, SSID_AP "_%02X%02X%02X", mac[3], mac[4], mac[5]); - config.ap.ssid_len = strlen(config.ap.ssid); - - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static bool req_includes_only_one_quest(struct DNSHeader *h) -{ - return (ntohs(h->QDCount) == 1 && h->ANCount == 0 && h->NSCount == 0 && h->ARCount == 0); -} - -static void reply_with_ip(int32 sock_fd, struct DNSHeader *h, uint32_t len, struct sockaddr *toaddr, socklen_t tolen) -{ - h->QR = DNS_QR_RESPONSE; - h->ANCount = h->QDCount; - uint32_t length = len + 16; - - uint8_t *pkg_buf = (uint8_t *)malloc(length); - if (pkg_buf == NULL) { - ESP_LOGI(TAG, "UDP packet alloc failed!\n"); - return; - } - memset(pkg_buf, 0, length); - memcpy(pkg_buf, (void *)h, len); - - pkg_buf[len] = 192; // answer name is a pointer - pkg_buf[len+1] = 12; // pointer to offset at 0x00c - pkg_buf[len+2] = 0; // 0x0001 answer is type A query (host address) - pkg_buf[len+3] = 1; - pkg_buf[len+4] = 0; //0x0001 answer is class IN (internet address) - pkg_buf[len+5] = 1; - - // write ttl - uint32_t _ttl = htonl(60); - uint8_t *pttl = (uint8_t *)(&_ttl); - pkg_buf[len+6] = pttl[0]; - pkg_buf[len+7] = pttl[1]; - pkg_buf[len+8] = pttl[2]; - pkg_buf[len+9] = pttl[3]; - pkg_buf[len+10] = 0; - pkg_buf[len+11] = 4; - - // ip - pkg_buf[len+12] = 192; - pkg_buf[len+13] = 168; - pkg_buf[len+14] = 4; - pkg_buf[len+15] = 1; - - uint32_t ret = sendto(sock_fd, pkg_buf, length, 0, toaddr, tolen); - free(pkg_buf); -} - -static void reply_with_custom_code(struct DNSHeader *h) -{ - ESP_LOGI(TAG, "reply_with_custom_code"); -} - -static void dns_server_task(void *pvParameters) -{ - int32 sock_fd; - int ret = 0; - struct sockaddr_in server_addr; - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_port = htons(UDP_DNS_PORT); - server_addr.sin_len = sizeof(server_addr); - - while ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - ESP_LOGI(TAG, "create socket failed"); - tmr_delay_msec(1000); - } - - while (bind(sock_fd, (struct sockaddr * )&server_addr, sizeof(server_addr)) != 0) { - ESP_LOGI(TAG, "socket bind failed"); - tmr_delay_msec(1000); - } - - char *udp_msg = (char *) malloc(UDP_DATA_LEN); - struct sockaddr_in from; - int fromlen = 0; - int nNetTimeout = 5; - memset(udp_msg, 0, UDP_DATA_LEN); - memset(&from, 0, sizeof(from)); - setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, sizeof(int)); //non-block - fromlen = sizeof(struct sockaddr_in); - - ESP_LOGI(TAG, "udp server at port:%d\r\n", UDP_DNS_PORT); - while (1) { - ret = recvfrom(sock_fd, (uint8 * )udp_msg, UDP_DATA_LEN, 0, (struct sockaddr * )&from, (socklen_t * )&fromlen); - if (ret > 0) { - struct DNSHeader *dns_header = (struct DNSHeader *)udp_msg; - - if (dns_header->QR == DNS_QR_QUERY && dns_header->OPCode == DNS_OPCODE_QUERY && req_includes_only_one_quest(dns_header)) { - reply_with_ip(sock_fd, dns_header, ret, (struct sockaddr *)&from, fromlen); - } else if (dns_header->QR == DNS_QR_QUERY) { - reply_with_custom_code(dns_header); - } - - memset(udp_msg, 0, UDP_DATA_LEN); - } else if (ret == 0) { - ESP_LOGI(TAG, "recvfrom error!"); - break; - } - } - - if (udp_msg) { - free(udp_msg); - udp_msg = NULL; - } - - close(sock_fd); - vTaskDelete(NULL); -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "AP started"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - xTaskCreate(dns_server_task, "dns_server_task", 2048, NULL, DNS_SERVER_TASK_PRIO, NULL); - break; - } - vTaskDelete(NULL); -} - -void app_main() -{ - led_blink(); // led flashing - nvs_flash_init(); - initialise_wifi(); - - xTaskCreate(tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIO, NULL); - - return 0; -} +#include + +#include "lwip/sockets.h" +#include "lwip/err.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" + +#include "platform.h" +#include "tmr.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "tcpip_adapter.h" + +#define UDP_DNS_PORT 53 +#define UDP_DATA_LEN 1024 +#define UDP_LOCAL_PORT 7 +#define SSID_AP "DOIT" +#define DNS_SERVER_TASK_PRIO 12 +#define TMP_TASK_PRIO 13 + +#define DNS_QR_QUERY 0 +#define DNS_QR_RESPONSE 1 +#define DNS_OPCODE_QUERY 0 + +struct DNSHeader { + unsigned short ID; // identification number + unsigned char RD : 1; // recursion desired + unsigned char TC : 1; // truncated message + unsigned char AA : 1; // authoritive answer + unsigned char OPCode : 4; // message_type + unsigned char QR : 1; // query/response flag + unsigned char RCode : 4; // response code + unsigned char Z : 3; // its z! reserved + unsigned char RA : 1; // recursion available + unsigned short QDCount; // number of question entries + unsigned short ANCount; // number of answer entries + unsigned short NSCount; // number of authority entries + unsigned short ARCount; // number of resource entries +}; + +static EventGroupHandle_t wifi_event_group; +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; + + +void led_blink(void) +{ + if(platform_gpio_mode(2, 2) < 0) { + ESP_LOGI(TAG, "Led lightup failed"); + return; + } + platform_gpio_write(2, 1); // led on + tmr_delay_msec(250); + platform_gpio_write(2, 0); // led off + tmr_delay_msec(250); + platform_gpio_write(2, 1); + tmr_delay_msec(250); + platform_gpio_write(2, 0); + tmr_delay_msec(250); + platform_gpio_write(2, 1); +} + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_AP_START: + ESP_LOGI(TAG, "AP start now"); + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_AP_STOP: + ESP_LOGI(TAG, "AP stop now"); + break; + case SYSTEM_EVENT_AP_STACONNECTED: + ESP_LOGI(TAG, "Station connect"); + break; + case SYSTEM_EVENT_AP_STADISCONNECTED: + ESP_LOGI(TAG, "Station disconnect"); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + wifi_config_t config = { + .ap = { + .ssid = SSID_AP, + .ssid_len = strlen(SSID_AP), + .authmode = WIFI_AUTH_OPEN, + .max_connection = 10, + //.ssid_hidden = 0, + //.beacon_interval = 100, + }, + }; + + // set SSID + uint8_t mac[6]; + esp_wifi_get_mac(WIFI_IF_AP, mac); + sprintf(config.ap.ssid, SSID_AP "_%02X%02X%02X", mac[3], mac[4], mac[5]); + config.ap.ssid_len = strlen(config.ap.ssid); + + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static bool req_includes_only_one_quest(struct DNSHeader *h) +{ + return (ntohs(h->QDCount) == 1 && h->ANCount == 0 && h->NSCount == 0 && h->ARCount == 0); +} + +static void reply_with_ip(int32 sock_fd, struct DNSHeader *h, uint32_t len, struct sockaddr *toaddr, socklen_t tolen) +{ + h->QR = DNS_QR_RESPONSE; + h->ANCount = h->QDCount; + uint32_t length = len + 16; + + uint8_t *pkg_buf = (uint8_t *)malloc(length); + if (pkg_buf == NULL) { + ESP_LOGI(TAG, "UDP packet alloc failed!\n"); + return; + } + memset(pkg_buf, 0, length); + memcpy(pkg_buf, (void *)h, len); + + pkg_buf[len] = 192; // answer name is a pointer + pkg_buf[len+1] = 12; // pointer to offset at 0x00c + pkg_buf[len+2] = 0; // 0x0001 answer is type A query (host address) + pkg_buf[len+3] = 1; + pkg_buf[len+4] = 0; //0x0001 answer is class IN (internet address) + pkg_buf[len+5] = 1; + + // write ttl + uint32_t _ttl = htonl(60); + uint8_t *pttl = (uint8_t *)(&_ttl); + pkg_buf[len+6] = pttl[0]; + pkg_buf[len+7] = pttl[1]; + pkg_buf[len+8] = pttl[2]; + pkg_buf[len+9] = pttl[3]; + pkg_buf[len+10] = 0; + pkg_buf[len+11] = 4; + + // ip + pkg_buf[len+12] = 192; + pkg_buf[len+13] = 168; + pkg_buf[len+14] = 4; + pkg_buf[len+15] = 1; + + uint32_t ret = sendto(sock_fd, pkg_buf, length, 0, toaddr, tolen); + free(pkg_buf); +} + +static void reply_with_custom_code(struct DNSHeader *h) +{ + ESP_LOGI(TAG, "reply_with_custom_code"); +} + +static void dns_server_task(void *pvParameters) +{ + int32 sock_fd; + int ret = 0; + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(UDP_DNS_PORT); + server_addr.sin_len = sizeof(server_addr); + + while ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + ESP_LOGI(TAG, "create socket failed"); + tmr_delay_msec(1000); + } + + while (bind(sock_fd, (struct sockaddr * )&server_addr, sizeof(server_addr)) != 0) { + ESP_LOGI(TAG, "socket bind failed"); + tmr_delay_msec(1000); + } + + char *udp_msg = (char *) malloc(UDP_DATA_LEN); + struct sockaddr_in from; + int fromlen = 0; + int nNetTimeout = 5; + memset(udp_msg, 0, UDP_DATA_LEN); + memset(&from, 0, sizeof(from)); + setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, sizeof(int)); //non-block + fromlen = sizeof(struct sockaddr_in); + + ESP_LOGI(TAG, "udp server at port:%d\r\n", UDP_DNS_PORT); + while (1) { + ret = recvfrom(sock_fd, (uint8 * )udp_msg, UDP_DATA_LEN, 0, (struct sockaddr * )&from, (socklen_t * )&fromlen); + if (ret > 0) { + struct DNSHeader *dns_header = (struct DNSHeader *)udp_msg; + + if (dns_header->QR == DNS_QR_QUERY && dns_header->OPCode == DNS_OPCODE_QUERY && req_includes_only_one_quest(dns_header)) { + reply_with_ip(sock_fd, dns_header, ret, (struct sockaddr *)&from, fromlen); + } else if (dns_header->QR == DNS_QR_QUERY) { + reply_with_custom_code(dns_header); + } + + memset(udp_msg, 0, UDP_DATA_LEN); + } else if (ret == 0) { + ESP_LOGI(TAG, "recvfrom error!"); + break; + } + } + + if (udp_msg) { + free(udp_msg); + udp_msg = NULL; + } + + close(sock_fd); + vTaskDelete(NULL); +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "AP started"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + xTaskCreate(dns_server_task, "dns_server_task", 2048, NULL, DNS_SERVER_TASK_PRIO, NULL); + break; + } + vTaskDelete(NULL); +} + +void app_main() +{ + led_blink(); // led flashing + nvs_flash_init(); + initialise_wifi(); + + xTaskCreate(tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIO, NULL); + + return 0; +} diff --git a/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c b/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c index b553241..af5f20f 100644 --- a/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c @@ -1,32 +1,32 @@ -#include -#include -#include "esp_log.h" -#include "esp_system.h" -#include "easy_heap.h" -#include "easy_mem.h" - -#define BUF_SIZE 10 - -static const char *TAG = "main"; - -void app_main() -{ - easy_heap_init(); - easy_mem_init(); - - unsigned char *addr1 = (unsigned char*)easy_heap_alloc(BUF_SIZE); - memset(addr1, 0, BUF_SIZE); - memcpy(addr1, "hello", 5); - printf("%s\n", addr1); - easy_heap_free(addr1); - - unsigned char *addr2 = (unsigned char*)easy_mem_alloc(BUF_SIZE); - memset(addr2, 0, BUF_SIZE); - memcpy(addr2, "world", 5); - printf("%s\n", addr2); - easy_mem_free(addr2); - - // print statistics - easy_heap_statistics(); - easy_mem_statistics(); -} +#include +#include +#include "esp_log.h" +#include "esp_system.h" +#include "easy_heap.h" +#include "easy_mem.h" + +#define BUF_SIZE 10 + +static const char *TAG = "main"; + +void app_main() +{ + easy_heap_init(); + easy_mem_init(); + + unsigned char *addr1 = (unsigned char*)easy_heap_alloc(BUF_SIZE); + memset(addr1, 0, BUF_SIZE); + memcpy(addr1, "hello", 5); + printf("%s\n", addr1); + easy_heap_free(addr1); + + unsigned char *addr2 = (unsigned char*)easy_mem_alloc(BUF_SIZE); + memset(addr2, 0, BUF_SIZE); + memcpy(addr2, "world", 5); + printf("%s\n", addr2); + easy_mem_free(addr2); + + // print statistics + easy_heap_statistics(); + easy_mem_statistics(); +} diff --git a/LuaNode_Esp32/LuaNode32/examples/json/main/component.mk b/LuaNode_Esp32/LuaNode32/examples/json/main/component.mk index d593215..61f8990 100644 --- a/LuaNode_Esp32/LuaNode32/examples/json/main/component.mk +++ b/LuaNode_Esp32/LuaNode32/examples/json/main/component.mk @@ -1,8 +1,8 @@ -# -# Main component makefile. -# -# This Makefile can be left empty. By default, it will take the sources in the -# src/ directory, compile them and link them into lib(subdirectory_name).a -# in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# +# +# Main component makefile. +# +# This Makefile can be left empty. By default, it will take the sources in the +# src/ directory, compile them and link them into lib(subdirectory_name).a +# in the build directory. This behaviour is entirely configurable, +# please read the ESP-IDF documents if you need to do this. +# diff --git a/LuaNode_Esp32/LuaNode32/examples/json/main/main.c b/LuaNode_Esp32/LuaNode32/examples/json/main/main.c index ac7a20f..d491545 100644 --- a/LuaNode_Esp32/LuaNode32/examples/json/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/json/main/main.c @@ -1,119 +1,119 @@ -/** - * Nicholas3388 - * 2017.05.21 - */ - -#include -#include -#include "esp_log.h" -#include "cJSON.h" - - -static const char *TAG = "main"; - -// return unformated json string -static char *json_encode(void) -{ - cJSON *json = cJSON_CreateObject(); - cJSON_AddStringToObject(json, "name", "Jack"); - - cJSON *subArray = cJSON_CreateArray(); - - cJSON *subItem1 = cJSON_CreateObject(); - cJSON_AddStringToObject(subItem1, "sex", "male"); - cJSON *subItem2 = cJSON_CreateObject(); - cJSON_AddStringToObject(subItem2, "address", "Beijing"); - cJSON *subItem3 = cJSON_CreateObject(); - cJSON_AddBoolToObject(subItem3, "has_children", true); - cJSON *subItem4 = cJSON_CreateObject(); - cJSON_AddItemToObject(subItem4, "weight", cJSON_CreateNumber(62)); // or cJSON_AddNumberToObject(subItem4, 62) - cJSON *subItem5 = cJSON_CreateObject(); - cJSON_AddItemToObject(subItem5, "height", cJSON_CreateDouble(1.80, 2)); - - cJSON_AddItemToArray(subArray, subItem1); - cJSON_AddItemToArray(subArray, subItem2); - cJSON_AddItemToArray(subArray, subItem3); - cJSON_AddItemToArray(subArray, subItem4); - cJSON_AddItemToArray(subArray, subItem5); - - cJSON_AddItemToObject(json, "subArray", subArray); - - char *formated_str = cJSON_Print(json); - char *unformated_str = cJSON_PrintUnformatted(json); - ESP_LOGI(TAG, "----------- formated -----------"); - ESP_LOGI(TAG, "%s", formated_str); - ESP_LOGI(TAG, "----------- unformated -----------"); - ESP_LOGI(TAG, "%s", unformated_str); - - free(formated_str); // do not forget to free string buffer - - if ( NULL != json ) { - cJSON_Delete(json); - json = NULL; - } - - return unformated_str; -} - -static void json_decode(char *unformated_string) -{ - int i; - cJSON *json = cJSON_Parse(unformated_string); - if ( NULL != json ) { - cJSON *temp = cJSON_GetObjectItem(json, "name"); - if (NULL != temp) { - ESP_LOGI(TAG, "name : %s", temp->valuestring); - } - - temp = cJSON_GetObjectItem(json, "subArray"); - if (NULL != temp) { - ESP_LOGI(TAG, "subArray : ["); - int len = cJSON_GetArraySize(temp); - for (i = 0; i < len; i++) { - cJSON *subItem = cJSON_GetArrayItem(temp, i); - if (NULL != subItem) { - cJSON *sex = cJSON_GetObjectItem(subItem, "sex"); - if (NULL != sex) { - ESP_LOGI(TAG, "\tsex : %s", sex->valuestring); - } - cJSON *addr = cJSON_GetObjectItem(subItem, "address"); - if (NULL != addr) { - ESP_LOGI(TAG, "\taddress : %s", addr->valuestring); - } - cJSON *child = cJSON_GetObjectItem(subItem, "has_children"); - if (NULL != child) { - switch (child->type) - { - case cJSON_False: - ESP_LOGI(TAG, "\thas_children : false"); - break; - case cJSON_True: - ESP_LOGI(TAG, "\thas_children : true"); - break; - } - } - cJSON *weight = cJSON_GetObjectItem(subItem, "weight"); - if (NULL != weight) { - ESP_LOGI(TAG, "\tweight : %d", weight->valueint); - } - cJSON *height = cJSON_GetObjectItem(subItem, "height"); - if (NULL != height) { - ESP_LOGI(TAG, "\theight : %lf", height->valuedouble); - } - } - } - ESP_LOGI(TAG, "]"); - } - } -} - -void app_main(void) -{ - ESP_LOGI(TAG, "enter main"); - - char *json_str = json_encode(); - ESP_LOGI(TAG, "=================================="); - json_decode(json_str); - - free(json_str); // do not forget to free string buffer +/** + * Nicholas3388 + * 2017.05.21 + */ + +#include +#include +#include "esp_log.h" +#include "cJSON.h" + + +static const char *TAG = "main"; + +// return unformated json string +static char *json_encode(void) +{ + cJSON *json = cJSON_CreateObject(); + cJSON_AddStringToObject(json, "name", "Jack"); + + cJSON *subArray = cJSON_CreateArray(); + + cJSON *subItem1 = cJSON_CreateObject(); + cJSON_AddStringToObject(subItem1, "sex", "male"); + cJSON *subItem2 = cJSON_CreateObject(); + cJSON_AddStringToObject(subItem2, "address", "Beijing"); + cJSON *subItem3 = cJSON_CreateObject(); + cJSON_AddBoolToObject(subItem3, "has_children", true); + cJSON *subItem4 = cJSON_CreateObject(); + cJSON_AddItemToObject(subItem4, "weight", cJSON_CreateNumber(62)); // or cJSON_AddNumberToObject(subItem4, 62) + cJSON *subItem5 = cJSON_CreateObject(); + cJSON_AddItemToObject(subItem5, "height", cJSON_CreateDouble(1.80, 2)); + + cJSON_AddItemToArray(subArray, subItem1); + cJSON_AddItemToArray(subArray, subItem2); + cJSON_AddItemToArray(subArray, subItem3); + cJSON_AddItemToArray(subArray, subItem4); + cJSON_AddItemToArray(subArray, subItem5); + + cJSON_AddItemToObject(json, "subArray", subArray); + + char *formated_str = cJSON_Print(json); + char *unformated_str = cJSON_PrintUnformatted(json); + ESP_LOGI(TAG, "----------- formated -----------"); + ESP_LOGI(TAG, "%s", formated_str); + ESP_LOGI(TAG, "----------- unformated -----------"); + ESP_LOGI(TAG, "%s", unformated_str); + + free(formated_str); // do not forget to free string buffer + + if ( NULL != json ) { + cJSON_Delete(json); + json = NULL; + } + + return unformated_str; +} + +static void json_decode(char *unformated_string) +{ + int i; + cJSON *json = cJSON_Parse(unformated_string); + if ( NULL != json ) { + cJSON *temp = cJSON_GetObjectItem(json, "name"); + if (NULL != temp) { + ESP_LOGI(TAG, "name : %s", temp->valuestring); + } + + temp = cJSON_GetObjectItem(json, "subArray"); + if (NULL != temp) { + ESP_LOGI(TAG, "subArray : ["); + int len = cJSON_GetArraySize(temp); + for (i = 0; i < len; i++) { + cJSON *subItem = cJSON_GetArrayItem(temp, i); + if (NULL != subItem) { + cJSON *sex = cJSON_GetObjectItem(subItem, "sex"); + if (NULL != sex) { + ESP_LOGI(TAG, "\tsex : %s", sex->valuestring); + } + cJSON *addr = cJSON_GetObjectItem(subItem, "address"); + if (NULL != addr) { + ESP_LOGI(TAG, "\taddress : %s", addr->valuestring); + } + cJSON *child = cJSON_GetObjectItem(subItem, "has_children"); + if (NULL != child) { + switch (child->type) + { + case cJSON_False: + ESP_LOGI(TAG, "\thas_children : false"); + break; + case cJSON_True: + ESP_LOGI(TAG, "\thas_children : true"); + break; + } + } + cJSON *weight = cJSON_GetObjectItem(subItem, "weight"); + if (NULL != weight) { + ESP_LOGI(TAG, "\tweight : %d", weight->valueint); + } + cJSON *height = cJSON_GetObjectItem(subItem, "height"); + if (NULL != height) { + ESP_LOGI(TAG, "\theight : %lf", height->valuedouble); + } + } + } + ESP_LOGI(TAG, "]"); + } + } +} + +void app_main(void) +{ + ESP_LOGI(TAG, "enter main"); + + char *json_str = json_encode(); + ESP_LOGI(TAG, "=================================="); + json_decode(json_str); + + free(json_str); // do not forget to free string buffer } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c b/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c index a738f11..730cab3 100644 --- a/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c @@ -1,146 +1,146 @@ -/** - * This is a LwIP Raw API sample. The sample create a TCP server listen port 11000. - * When received data, the server send the data back to client. - * - * Nicholas3388 - **/ -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "espconn.h" -#include "tmr.h" -#include "lwip/tcp.h" - -#define FEEDBACK_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define TCP_TASK_PRIORITY 12 -#define LOCAL_PORT 11000 -#define REMOTE_PORT 6000 - -static EventGroupHandle_t wifi_event_group; -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static err_t tcp_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - ESP_LOGI(TAG, "sent data"); - return ERR_OK; -} - -static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - ESP_LOGI(TAG, "received data"); - if (err == ERR_OK && p != NULL) { - uint8_t *data_ptr = NULL; - u32_t data_cntr = 0; - data_ptr = (uint8_t *)malloc(p ->tot_len + 1); - memset(data_ptr, 0, p->tot_len + 1); - data_cntr = pbuf_copy_partial(p, data_ptr, p ->tot_len, 0); - pbuf_free(p); - if (data_cntr != 0) { - ESP_LOGI(TAG, "content: %s", data_ptr); - tcp_write(pcb, data_ptr, data_cntr, 1); // data is not sent yet, until tcp_output called - tcp_output(pcb); - } - free(data_ptr); - data_ptr = NULL; - } - return ERR_OK; -} - -static err_t tcp_server_poll(void *arg, struct tcp_pcb *pcb) -{ - ESP_LOGI(TAG, "poll"); - return ERR_OK; -} - -static err_t tcp_accept_callback(void *arg, struct tcp_pcb *pcb, err_t err) -{ - ESP_LOGI(TAG, "client try connecting"); - tcp_sent(pcb, tcp_server_sent); - tcp_recv(pcb, tcp_server_recv); - tcp_poll(pcb, tcp_server_poll, 8); /* every 1 seconds */ - return ERR_OK; -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - struct tcp_pcb *pcb = tcp_new(); - if (pcb == NULL) { - ESP_LOGI(TAG, "tcp_pcb create failed"); - break; - } - tcp_bind(pcb, IP_ADDR_ANY, LOCAL_PORT); - pcb = tcp_listen(pcb); - //tcp_arg(pcb, (void *)params); - ESP_LOGI(TAG, "wait for client"); - tcp_accept(pcb, tcp_accept_callback); - break; - } - vTaskDelete(NULL); -} - -void app_main() -{ - nvs_flash_init(); - initialise_wifi(); - - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - -} +/** + * This is a LwIP Raw API sample. The sample create a TCP server listen port 11000. + * When received data, the server send the data back to client. + * + * Nicholas3388 + **/ +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "espconn.h" +#include "tmr.h" +#include "lwip/tcp.h" + +#define FEEDBACK_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define TCP_TASK_PRIORITY 12 +#define LOCAL_PORT 11000 +#define REMOTE_PORT 6000 + +static EventGroupHandle_t wifi_event_group; +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static err_t tcp_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + ESP_LOGI(TAG, "sent data"); + return ERR_OK; +} + +static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + ESP_LOGI(TAG, "received data"); + if (err == ERR_OK && p != NULL) { + uint8_t *data_ptr = NULL; + u32_t data_cntr = 0; + data_ptr = (uint8_t *)malloc(p ->tot_len + 1); + memset(data_ptr, 0, p->tot_len + 1); + data_cntr = pbuf_copy_partial(p, data_ptr, p ->tot_len, 0); + pbuf_free(p); + if (data_cntr != 0) { + ESP_LOGI(TAG, "content: %s", data_ptr); + tcp_write(pcb, data_ptr, data_cntr, 1); // data is not sent yet, until tcp_output called + tcp_output(pcb); + } + free(data_ptr); + data_ptr = NULL; + } + return ERR_OK; +} + +static err_t tcp_server_poll(void *arg, struct tcp_pcb *pcb) +{ + ESP_LOGI(TAG, "poll"); + return ERR_OK; +} + +static err_t tcp_accept_callback(void *arg, struct tcp_pcb *pcb, err_t err) +{ + ESP_LOGI(TAG, "client try connecting"); + tcp_sent(pcb, tcp_server_sent); + tcp_recv(pcb, tcp_server_recv); + tcp_poll(pcb, tcp_server_poll, 8); /* every 1 seconds */ + return ERR_OK; +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + + struct tcp_pcb *pcb = tcp_new(); + if (pcb == NULL) { + ESP_LOGI(TAG, "tcp_pcb create failed"); + break; + } + tcp_bind(pcb, IP_ADDR_ANY, LOCAL_PORT); + pcb = tcp_listen(pcb); + //tcp_arg(pcb, (void *)params); + ESP_LOGI(TAG, "wait for client"); + tcp_accept(pcb, tcp_accept_callback); + break; + } + vTaskDelete(NULL); +} + +void app_main() +{ + nvs_flash_init(); + initialise_wifi(); + + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); + +} diff --git a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c index 1b820d3..7b6a6ad 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c @@ -1,100 +1,100 @@ -// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * Nicholas3388 - * 2017.06.04 - * email: wangwei@doit.am - */ - -#include "ota.h" -#include "user_config.h" -#include "utils.h" - -#include "esp_log.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - -static const char *TAG = "main"; - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = WIFI_SSID, - .password = WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - -static void tmp_task(void *pvParameter) -{ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to OTA Server...."); - ota_init(); - vTaskDelete(NULL); -} - -void app_main(void) -{ - delay_ms(1000); - ESP_LOGI(TAG, "enter main"); - initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); - +// Copyright 2015-2016 Doctors of Intelligence & Technology (Shenzhen) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * Nicholas3388 + * 2017.06.04 + * email: wangwei@doit.am + */ + +#include "ota.h" +#include "user_config.h" +#include "utils.h" + +#include "esp_log.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" + +static const char *TAG = "main"; + +/* FreeRTOS event group to signal when we are connected & ready to make a request */ +static EventGroupHandle_t wifi_event_group; + +/* The event group allows multiple bits for each event, + but we only care about one event - are we connected + to the AP with an IP? */ +const int CONNECTED_BIT = BIT0; + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch (event->event_id) { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + wifi_config_t wifi_config = { + .sta = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + }, + }; + ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_start() ); +} + +static void tmp_task(void *pvParameter) +{ + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to OTA Server...."); + ota_init(); + vTaskDelete(NULL); +} + +void app_main(void) +{ + delay_ms(1000); + ESP_LOGI(TAG, "enter main"); + initialise_wifi(); + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); + } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/server/ota_server.py b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/server/ota_server.py index af9eb66..8913749 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/server/ota_server.py +++ b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/server/ota_server.py @@ -1,73 +1,73 @@ -import socket -import os -import time - -################################################ -## change firmware and port to yours -firmware_name = 'hello-world.bin' -server_ip = 8070 -################################################ - - -ip_port = ('0.0.0.0', server_ip) - -file_size = os.path.getsize(firmware_name) - -# open binary file -reopen = True; -while reopen: - try: - fd = open(firmware_name, 'rb') - reopen = False - except: - print 'open file failed' - time.sleep(1) - -sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -sock.bind(ip_port) -sock.listen(5) - -last_package = None -send_count = 0 - -while True: - print 'wait for client' - conn, addr = sock.accept() - print addr - while True: - client_data = conn.recv(1024) - if client_data == "req0\r\n\r\n": - send_fail_retry = True - is_over = False - while send_fail_retry: - try: - dat = fd.read(512) - send_data = 'total: ' + str(file_size) + '\r\nlength: ' + str(len(dat)) + '\r\n\r\n' + dat - last_package = send_data - conn.send(send_data) - send_fail_retry = False - send_count += len(dat) - print ('send progress: %%%d' %(send_count*100/file_size)) - if send_count >= file_size: - print 'file send end' - last_package = None - send_count = 0 - is_over = True - except: - print 'read file error, try again later' - time.sleep(1) - if is_over: - fd.seek(0) - break - elif client_data == "req1\r\n\r\n": - retry = True - while retry: - try: - conn.send(last_package) - retry = False - print 'resend OK' - except: - print 'resend data failed' - time.sleep(1) - +import socket +import os +import time + +################################################ +## change firmware and port to yours +firmware_name = 'hello-world.bin' +server_ip = 8070 +################################################ + + +ip_port = ('0.0.0.0', server_ip) + +file_size = os.path.getsize(firmware_name) + +# open binary file +reopen = True; +while reopen: + try: + fd = open(firmware_name, 'rb') + reopen = False + except: + print 'open file failed' + time.sleep(1) + +sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.bind(ip_port) +sock.listen(5) + +last_package = None +send_count = 0 + +while True: + print 'wait for client' + conn, addr = sock.accept() + print addr + while True: + client_data = conn.recv(1024) + if client_data == "req0\r\n\r\n": + send_fail_retry = True + is_over = False + while send_fail_retry: + try: + dat = fd.read(512) + send_data = 'total: ' + str(file_size) + '\r\nlength: ' + str(len(dat)) + '\r\n\r\n' + dat + last_package = send_data + conn.send(send_data) + send_fail_retry = False + send_count += len(dat) + print ('send progress: %%%d' %(send_count*100/file_size)) + if send_count >= file_size: + print 'file send end' + last_package = None + send_count = 0 + is_over = True + except: + print 'read file error, try again later' + time.sleep(1) + if is_over: + fd.seek(0) + break + elif client_data == "req1\r\n\r\n": + retry = True + while retry: + try: + conn.send(last_package) + retry = False + print 'resend OK' + except: + print 'resend data failed' + time.sleep(1) + print 'something went wrong' \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c b/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c index 7ce2c9b..7661d20 100644 --- a/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c @@ -1,162 +1,162 @@ -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "espconn.h" -#include "tmr.h" - -#define FEEDBACK_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define SEND_TASK_PRIORITY 12 -#define REMOTE_PORT 11000 -static uint8 serverIP[] = { 192, 168, 1, 101 }; - -static struct espconn *_ptrUDPServer; -static EventGroupHandle_t wifi_event_group; -static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; -static int wifi_status = 0; -static tcpip_adapter_ip_info_t ip_info; - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - wifi_status = event->event_id; - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; - } - return ESP_OK; -} - -uint8_t wifi_station_get_connect_status(void) -{ - return wifi_status; -} - -static void initialise_wifi(void) -{ - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void send_task(void *pvParameters) -{ - struct espconn *pespconn = (struct espconn *) pvParameters; - while(1) { - tmr_delay_msec(2000); - espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); - } - vTaskDelete(NULL); -} - -void disconnect_cb(void *arg) -{ - ESP_LOGI(TAG, "disconnected"); -} - -void receive_cb(void *arg, char *pdata, unsigned short len) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); -} - -void send_cb(void *arg) -{ - ESP_LOGI(TAG, "sent data"); -} - -void connect_cb(void *arg) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "connected"); - espconn_regist_disconcb(pespconn, disconnect_cb); - espconn_regist_recvcb(pespconn, receive_cb); - espconn_regist_sentcb(pespconn, send_cb); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); - xTaskCreate(&send_task, "send_task", 4096, pespconn, TMP_TASK_PRIORITY, NULL); -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { - ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); - ESP_LOGI(TAG, "~~~~~~~~~~~"); - } - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_TCP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); - _ptrUDPServer->proto.tcp->local_port = espconn_port(); - _ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; - memcpy(_ptrUDPServer->proto.tcp->remote_ip, serverIP, 4); - - espconn_regist_connectcb(_ptrUDPServer, connect_cb); - ESP_LOGI(TAG, "wait for client"); - - // connect to tcp server - espconn_connect(_ptrUDPServer); - - while(1) { - tmr_delay_msec(5000); - ESP_LOGI(TAG, "tmp_task loop"); - } - } - vTaskDelete(NULL); -} - -void app_main() -{ - nvs_flash_init(); - initialise_wifi(); - - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - -} +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "espconn.h" +#include "tmr.h" + +#define FEEDBACK_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define SEND_TASK_PRIORITY 12 +#define REMOTE_PORT 11000 +static uint8 serverIP[] = { 192, 168, 1, 101 }; + +static struct espconn *_ptrUDPServer; +static EventGroupHandle_t wifi_event_group; +static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; +static int wifi_status = 0; +static tcpip_adapter_ip_info_t ip_info; + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + wifi_status = event->event_id; + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; + } + return ESP_OK; +} + +uint8_t wifi_station_get_connect_status(void) +{ + return wifi_status; +} + +static void initialise_wifi(void) +{ + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static void send_task(void *pvParameters) +{ + struct espconn *pespconn = (struct espconn *) pvParameters; + while(1) { + tmr_delay_msec(2000); + espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + } + vTaskDelete(NULL); +} + +void disconnect_cb(void *arg) +{ + ESP_LOGI(TAG, "disconnected"); +} + +void receive_cb(void *arg, char *pdata, unsigned short len) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); + //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); +} + +void send_cb(void *arg) +{ + ESP_LOGI(TAG, "sent data"); +} + +void connect_cb(void *arg) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "connected"); + espconn_regist_disconcb(pespconn, disconnect_cb); + espconn_regist_recvcb(pespconn, receive_cb); + espconn_regist_sentcb(pespconn, send_cb); + //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + xTaskCreate(&send_task, "send_task", 4096, pespconn, TMP_TASK_PRIORITY, NULL); +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + ESP_LOGI(TAG, "~~~~~~~~~~~"); + ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "~~~~~~~~~~~"); + } + + // start espconn + _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_TCP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); + _ptrUDPServer->proto.tcp->local_port = espconn_port(); + _ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; + memcpy(_ptrUDPServer->proto.tcp->remote_ip, serverIP, 4); + + espconn_regist_connectcb(_ptrUDPServer, connect_cb); + ESP_LOGI(TAG, "wait for client"); + + // connect to tcp server + espconn_connect(_ptrUDPServer); + + while(1) { + tmr_delay_msec(5000); + ESP_LOGI(TAG, "tmp_task loop"); + } + } + vTaskDelete(NULL); +} + +void app_main() +{ + nvs_flash_init(); + initialise_wifi(); + + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); + +} diff --git a/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c b/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c index efcf88c..ad96abc 100644 --- a/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c @@ -1,135 +1,135 @@ -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "espconn.h" -#include "tmr.h" - -#define FEEDBACK_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define TCP_TASK_PRIORITY 12 -#define LOCAL_PORT 11000 -#define REMOTE_PORT 6000 - -static struct espconn *_ptrUDPServer; -static EventGroupHandle_t wifi_event_group; -static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -void disconnect_cb(void *arg) -{ - ESP_LOGI(TAG, "disconnected"); -} - -void receive_cb(void *arg, char *pdata, unsigned short len) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "received data"); - ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); -} - -void send_cb(void *arg) -{ - ESP_LOGI(TAG, "sent data"); -} - -void connect_cb(void *arg) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "connected"); - espconn_regist_disconcb(pespconn, disconnect_cb); - espconn_regist_recvcb(pespconn, receive_cb); - espconn_regist_sentcb(pespconn, send_cb); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_TCP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); - _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; - //_ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; - - espconn_regist_connectcb(_ptrUDPServer, connect_cb); - ESP_LOGI(TAG, "wait for client"); - espconn_accept(_ptrUDPServer); - espconn_regist_time(_ptrUDPServer, srv_timeout, 0); - - while(1) { - tmr_delay_msec(5000); - ESP_LOGI(TAG, "tmp_task loop"); - } - } - vTaskDelete(NULL); -} - -void app_main() -{ - nvs_flash_init(); - initialise_wifi(); - - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - -} +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "espconn.h" +#include "tmr.h" + +#define FEEDBACK_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define TCP_TASK_PRIORITY 12 +#define LOCAL_PORT 11000 +#define REMOTE_PORT 6000 + +static struct espconn *_ptrUDPServer; +static EventGroupHandle_t wifi_event_group; +static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +void disconnect_cb(void *arg) +{ + ESP_LOGI(TAG, "disconnected"); +} + +void receive_cb(void *arg, char *pdata, unsigned short len) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "received data"); + ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); + //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); +} + +void send_cb(void *arg) +{ + ESP_LOGI(TAG, "sent data"); +} + +void connect_cb(void *arg) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "connected"); + espconn_regist_disconcb(pespconn, disconnect_cb); + espconn_regist_recvcb(pespconn, receive_cb); + espconn_regist_sentcb(pespconn, send_cb); + //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + + // start espconn + _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_TCP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); + _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; + //_ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; + + espconn_regist_connectcb(_ptrUDPServer, connect_cb); + ESP_LOGI(TAG, "wait for client"); + espconn_accept(_ptrUDPServer); + espconn_regist_time(_ptrUDPServer, srv_timeout, 0); + + while(1) { + tmr_delay_msec(5000); + ESP_LOGI(TAG, "tmp_task loop"); + } + } + vTaskDelete(NULL); +} + +void app_main() +{ + nvs_flash_init(); + initialise_wifi(); + + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); + +} diff --git a/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c b/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c index 000f82e..13d6e67 100644 --- a/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c @@ -1,165 +1,165 @@ -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "espconn.h" -#include "tmr.h" - -#define FEEDBACK1 "\r\nhello back\r\n" -#define FEEDBACK2 "\r\nok\r\n" -#define FEEDBACK3 "\r\ninvalid command\r\n" -#define PROMPT "You can input the following command:\r\n1. hello\r\n2. test\r\n" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define CMD1 "hello" -#define CMD2 "test" -#define TMP_TASK_PRIORITY 13 -#define TCP_TASK_PRIORITY 12 -#define LOCAL_PORT 23 // Telnet use port 23 -#define BUFF_SIZE 256 - -static struct espconn *_ptrUDPServer; -static EventGroupHandle_t wifi_event_group; -static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; -static char buff[BUFF_SIZE]; - - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.tcp); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -void parse(struct espconn *pespconn, char *pdata, unsigned short len) -{ - if (pdata[0] != 0x0a && pdata[0] != 0x0d) { // the input is not Enter key - int index = strlen(buff); - buff[index] = pdata[0]; - return; - } - - ESP_LOGI(TAG, "command: %s, len: %d", buff, strlen(buff)); - if (strstr(buff, CMD1)) { - espconn_sent(pespconn, (uint8 *)FEEDBACK1, strlen(FEEDBACK1)); - } else if (strstr(buff, CMD2)) { - espconn_sent(pespconn, (uint8 *)FEEDBACK2, strlen(FEEDBACK2)); - } else { - espconn_sent(pespconn, (uint8 *)FEEDBACK3, strlen(FEEDBACK3)); - } - memset(buff, 0, BUFF_SIZE); -} - -void disconnect_cb(void *arg) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "disconnected"); - espconn_disconnect(pespconn); - memset(buff, 0, BUFF_SIZE); -} - -void receive_cb(void *arg, char *pdata, unsigned short len) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); - parse(pespconn, pdata, len); -} - -void send_cb(void *arg) -{ - ESP_LOGI(TAG, "sent data"); -} - -void connect_cb(void *arg) -{ - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "connected"); - espconn_regist_disconcb(pespconn, disconnect_cb); - espconn_regist_recvcb(pespconn, receive_cb); - espconn_regist_sentcb(pespconn, send_cb); - espconn_sent(pespconn, (uint8 *)PROMPT, strlen(PROMPT)); -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_TCP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); - _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; - - espconn_regist_connectcb(_ptrUDPServer, connect_cb); - ESP_LOGI(TAG, "wait for client"); - espconn_accept(_ptrUDPServer); - espconn_regist_time(_ptrUDPServer, srv_timeout, 0); - - } - vTaskDelete(NULL); -} - -void app_init() -{ - memset(buff, 0, BUFF_SIZE); -} - -void app_main() -{ - nvs_flash_init(); - tcpip_adapter_init(); - initialise_wifi(); - app_init(); - - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - -} +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "espconn.h" +#include "tmr.h" + +#define FEEDBACK1 "\r\nhello back\r\n" +#define FEEDBACK2 "\r\nok\r\n" +#define FEEDBACK3 "\r\ninvalid command\r\n" +#define PROMPT "You can input the following command:\r\n1. hello\r\n2. test\r\n" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define CMD1 "hello" +#define CMD2 "test" +#define TMP_TASK_PRIORITY 13 +#define TCP_TASK_PRIORITY 12 +#define LOCAL_PORT 23 // Telnet use port 23 +#define BUFF_SIZE 256 + +static struct espconn *_ptrUDPServer; +static EventGroupHandle_t wifi_event_group; +static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; +static char buff[BUFF_SIZE]; + + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.tcp); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +void parse(struct espconn *pespconn, char *pdata, unsigned short len) +{ + if (pdata[0] != 0x0a && pdata[0] != 0x0d) { // the input is not Enter key + int index = strlen(buff); + buff[index] = pdata[0]; + return; + } + + ESP_LOGI(TAG, "command: %s, len: %d", buff, strlen(buff)); + if (strstr(buff, CMD1)) { + espconn_sent(pespconn, (uint8 *)FEEDBACK1, strlen(FEEDBACK1)); + } else if (strstr(buff, CMD2)) { + espconn_sent(pespconn, (uint8 *)FEEDBACK2, strlen(FEEDBACK2)); + } else { + espconn_sent(pespconn, (uint8 *)FEEDBACK3, strlen(FEEDBACK3)); + } + memset(buff, 0, BUFF_SIZE); +} + +void disconnect_cb(void *arg) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "disconnected"); + espconn_disconnect(pespconn); + memset(buff, 0, BUFF_SIZE); +} + +void receive_cb(void *arg, char *pdata, unsigned short len) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); + parse(pespconn, pdata, len); +} + +void send_cb(void *arg) +{ + ESP_LOGI(TAG, "sent data"); +} + +void connect_cb(void *arg) +{ + struct espconn *pespconn = (struct espconn *) arg; + ESP_LOGI(TAG, "connected"); + espconn_regist_disconcb(pespconn, disconnect_cb); + espconn_regist_recvcb(pespconn, receive_cb); + espconn_regist_sentcb(pespconn, send_cb); + espconn_sent(pespconn, (uint8 *)PROMPT, strlen(PROMPT)); +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + + // start espconn + _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_TCP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); + _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; + + espconn_regist_connectcb(_ptrUDPServer, connect_cb); + ESP_LOGI(TAG, "wait for client"); + espconn_accept(_ptrUDPServer); + espconn_regist_time(_ptrUDPServer, srv_timeout, 0); + + } + vTaskDelete(NULL); +} + +void app_init() +{ + memset(buff, 0, BUFF_SIZE); +} + +void app_main() +{ + nvs_flash_init(); + tcpip_adapter_init(); + initialise_wifi(); + app_init(); + + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); + +} diff --git a/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c b/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c index d13e8ae..6eaf436 100644 --- a/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c @@ -1,54 +1,54 @@ -#include -#include -#include "esp_log.h" -#include "esp_system.h" -#include "spiffs.h" -#include "vfs.h" -#include "platform.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "flash_api.h" - -static const char *TAG = "main"; -static spiffs fs; - -void app_main() -{ - char buf[12] = {0}; - - if(flash_safe_get_size_byte() != flash_rom_get_size_byte()) { - ESP_LOGI(TAG, "Incorrect flash size reported, adjusting..."); - flash_rom_set_size_byte(flash_safe_get_size_byte()); - system_restart(); - return; - } - - ESP_LOGI (TAG, "Mounting flash filesystem..."); - if (!vfs_mount("/FLASH", 0)) { - // Failed to mount -- try reformat - ESP_LOGI(TAG, "Formatting file system. Please wait..."); - if (!vfs_format()) { - ESP_LOGI(TAG, "*** ERROR ***: unable to format. FS might be compromised." ); - ESP_LOGI(TAG, "It is advised to re-flash the NodeMCU image." ); - } - // Note that fs_format leaves the file system mounted - } - - spiffs_file fd = SPIFFS_open(&fs, "test_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); - ESP_LOGI(TAG, "fd=%d", fd); - if (SPIFFS_write(&fs, fd, (u8_t *)"Hello SPIFFS", 12) < 0) { - ESP_LOGI(TAG, "write errno %i", SPIFFS_errno(&fs)); - } - SPIFFS_close(&fs, fd); - - vTaskDelay(1000 / portTICK_RATE_MS); - - fd = SPIFFS_open(&fs, "test_file", SPIFFS_RDWR, 0); - ESP_LOGI(TAG, "fd=%d", fd); - if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) { - ESP_LOGI(TAG, "read errno %i", SPIFFS_errno(&fs)); - } - SPIFFS_close(&fs, fd); - - ESP_LOGI(TAG, "--> %s <--", buf); -} +#include +#include +#include "esp_log.h" +#include "esp_system.h" +#include "spiffs.h" +#include "vfs.h" +#include "platform.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "flash_api.h" + +static const char *TAG = "main"; +static spiffs fs; + +void app_main() +{ + char buf[12] = {0}; + + if(flash_safe_get_size_byte() != flash_rom_get_size_byte()) { + ESP_LOGI(TAG, "Incorrect flash size reported, adjusting..."); + flash_rom_set_size_byte(flash_safe_get_size_byte()); + system_restart(); + return; + } + + ESP_LOGI (TAG, "Mounting flash filesystem..."); + if (!vfs_mount("/FLASH", 0)) { + // Failed to mount -- try reformat + ESP_LOGI(TAG, "Formatting file system. Please wait..."); + if (!vfs_format()) { + ESP_LOGI(TAG, "*** ERROR ***: unable to format. FS might be compromised." ); + ESP_LOGI(TAG, "It is advised to re-flash the NodeMCU image." ); + } + // Note that fs_format leaves the file system mounted + } + + spiffs_file fd = SPIFFS_open(&fs, "test_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); + ESP_LOGI(TAG, "fd=%d", fd); + if (SPIFFS_write(&fs, fd, (u8_t *)"Hello SPIFFS", 12) < 0) { + ESP_LOGI(TAG, "write errno %i", SPIFFS_errno(&fs)); + } + SPIFFS_close(&fs, fd); + + vTaskDelay(1000 / portTICK_RATE_MS); + + fd = SPIFFS_open(&fs, "test_file", SPIFFS_RDWR, 0); + ESP_LOGI(TAG, "fd=%d", fd); + if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) { + ESP_LOGI(TAG, "read errno %i", SPIFFS_errno(&fs)); + } + SPIFFS_close(&fs, fd); + + ESP_LOGI(TAG, "--> %s <--", buf); +} diff --git a/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c b/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c index 6abe78f..b39d062 100644 --- a/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c @@ -1,114 +1,114 @@ -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "espconn.h" -#include "tmr.h" - -#define USER_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_router" -#define EXAMPLE_WIFI_PASS "123456789" -#define TMP_TASK_PRIORITY 13 -#define SEND_TASK_PRIORITY 12 - -static uint8 udpServerIP[] = { 192, 168, 1, 255 }; -static struct espconn *_ptrUDPServer; -static EventGroupHandle_t wifi_event_group; - -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; - - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void send_task(void *pvParameters) -{ - espconn_create(_ptrUDPServer); - while(1) { - tmr_delay_msec(3000); - ESP_LOGI(TAG, "broadcast data"); - espconn_sent(_ptrUDPServer, (uint8 *) USER_DATA, (uint16) strlen(USER_DATA)); - } - espconn_delete(_ptrUDPServer); - vTaskDelete(NULL); -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_UDP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.udp = (esp_udp *) malloc(sizeof(esp_udp)); - _ptrUDPServer->proto.udp->local_port = espconn_port(); - _ptrUDPServer->proto.udp->remote_port = 11000; - memcpy(_ptrUDPServer->proto.udp->remote_ip, udpServerIP, 4); - - xTaskCreate(&send_task, "send_task", 4096, NULL, SEND_TASK_PRIORITY, NULL); - - break; - } - vTaskDelete(NULL); -} - -void app_main() -{ - nvs_flash_init(); - initialise_wifi(); - - xTaskCreate(&tmp_task, "tmp_task", 1536, NULL, TMP_TASK_PRIORITY, NULL); - -} +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "espconn.h" +#include "tmr.h" + +#define USER_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_router" +#define EXAMPLE_WIFI_PASS "123456789" +#define TMP_TASK_PRIORITY 13 +#define SEND_TASK_PRIORITY 12 + +static uint8 udpServerIP[] = { 192, 168, 1, 255 }; +static struct espconn *_ptrUDPServer; +static EventGroupHandle_t wifi_event_group; + +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; + + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static void send_task(void *pvParameters) +{ + espconn_create(_ptrUDPServer); + while(1) { + tmr_delay_msec(3000); + ESP_LOGI(TAG, "broadcast data"); + espconn_sent(_ptrUDPServer, (uint8 *) USER_DATA, (uint16) strlen(USER_DATA)); + } + espconn_delete(_ptrUDPServer); + vTaskDelete(NULL); +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + + // start espconn + _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_UDP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.udp = (esp_udp *) malloc(sizeof(esp_udp)); + _ptrUDPServer->proto.udp->local_port = espconn_port(); + _ptrUDPServer->proto.udp->remote_port = 11000; + memcpy(_ptrUDPServer->proto.udp->remote_ip, udpServerIP, 4); + + xTaskCreate(&send_task, "send_task", 4096, NULL, SEND_TASK_PRIORITY, NULL); + + break; + } + vTaskDelete(NULL); +} + +void app_main() +{ + nvs_flash_init(); + initialise_wifi(); + + xTaskCreate(&tmp_task, "tmp_task", 1536, NULL, TMP_TASK_PRIORITY, NULL); + +} diff --git a/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c b/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c index 573ebf4..d2c3d92 100644 --- a/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c @@ -1,122 +1,122 @@ -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "espconn.h" -#include "tmr.h" - -#define USER_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define LOCAL_PORT 11000 -#define BUFF_SIZE 128 - -static struct espconn *_ptrUDPServer; -static EventGroupHandle_t wifi_event_group; - -const int CONNECTED_BIT = BIT0; -static const char *TAG = "main"; - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void udp_recv(void *arg, char *pdata, unsigned short length) -{ - struct espconn *pesp_conn = arg; - char buff[BUFF_SIZE]; - memset(buff, 0, BUFF_SIZE); - ESP_LOGI(TAG, "client %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->remote_ip[0], - pesp_conn->proto.udp->remote_ip[1],pesp_conn->proto.udp->remote_ip[2], - pesp_conn->proto.udp->remote_ip[3],pesp_conn->proto.udp->remote_port); - ESP_LOGI(TAG, "local %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->local_ip[0], - pesp_conn->proto.udp->local_ip[1],pesp_conn->proto.udp->local_ip[2], - pesp_conn->proto.udp->local_ip[3],pesp_conn->proto.udp->local_port); - ESP_LOGI(TAG, "received %d bytes of data", length); - if (length > BUFF_SIZE) { - ESP_LOGI(TAG, "received data out of bound"); - } - memcpy(buff, pdata, length); - ESP_LOGI(TAG, "content: %s", pdata); - -} - -static void tmp_task(void *pvParameters) -{ - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_UDP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.udp = (esp_udp *) malloc(sizeof(esp_udp)); - memset(_ptrUDPServer->proto.udp, 0, sizeof(esp_udp)); - _ptrUDPServer->proto.udp->local_port = LOCAL_PORT; - - espconn_regist_recvcb(_ptrUDPServer, udp_recv); - espconn_create(_ptrUDPServer); - ESP_LOGI(TAG, "Wait for client"); - - break; - } - vTaskDelete(NULL); -} - -void app_main() -{ - nvs_flash_init(); - initialise_wifi(); - - xTaskCreate(&tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIORITY, NULL); - -} +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "espconn.h" +#include "tmr.h" + +#define USER_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define LOCAL_PORT 11000 +#define BUFF_SIZE 128 + +static struct espconn *_ptrUDPServer; +static EventGroupHandle_t wifi_event_group; + +const int CONNECTED_BIT = BIT0; +static const char *TAG = "main"; + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch(event->event_id) { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static void udp_recv(void *arg, char *pdata, unsigned short length) +{ + struct espconn *pesp_conn = arg; + char buff[BUFF_SIZE]; + memset(buff, 0, BUFF_SIZE); + ESP_LOGI(TAG, "client %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->remote_ip[0], + pesp_conn->proto.udp->remote_ip[1],pesp_conn->proto.udp->remote_ip[2], + pesp_conn->proto.udp->remote_ip[3],pesp_conn->proto.udp->remote_port); + ESP_LOGI(TAG, "local %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->local_ip[0], + pesp_conn->proto.udp->local_ip[1],pesp_conn->proto.udp->local_ip[2], + pesp_conn->proto.udp->local_ip[3],pesp_conn->proto.udp->local_port); + ESP_LOGI(TAG, "received %d bytes of data", length); + if (length > BUFF_SIZE) { + ESP_LOGI(TAG, "received data out of bound"); + } + memcpy(buff, pdata, length); + ESP_LOGI(TAG, "content: %s", pdata); + +} + +static void tmp_task(void *pvParameters) +{ + while(1) { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Got IP"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + + // start espconn + _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_UDP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.udp = (esp_udp *) malloc(sizeof(esp_udp)); + memset(_ptrUDPServer->proto.udp, 0, sizeof(esp_udp)); + _ptrUDPServer->proto.udp->local_port = LOCAL_PORT; + + espconn_regist_recvcb(_ptrUDPServer, udp_recv); + espconn_create(_ptrUDPServer); + ESP_LOGI(TAG, "Wait for client"); + + break; + } + vTaskDelete(NULL); +} + +void app_main() +{ + nvs_flash_init(); + initialise_wifi(); + + xTaskCreate(&tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIORITY, NULL); + +} diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/file/file_write.lua b/LuaNode_Esp32/LuaNode32/lua_samples/file/file_write.lua index d339627..4d059ce 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/file/file_write.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/file/file_write.lua @@ -1,21 +1,21 @@ --- file create and write --- To read a file, you should open it first - -res = file.open("myfile.lua","w") -- Open file myfile.lua. If it doesn't exist, create it, otherwise, overwrite the file -while true do - if(res == false) then - print("open file failed"); - break; - end - - file.write("hello"); - file.close(); - - break; -end - ---[[ -file.open("myfile.lua","w+") -- Open and append content to myfile.lua -file.write("hello"); -file.close(); -]] +-- file create and write +-- To read a file, you should open it first + +res = file.open("myfile.lua","w") -- Open file myfile.lua. If it doesn't exist, create it, otherwise, overwrite the file +while true do + if(res == false) then + print("open file failed"); + break; + end + + file.write("hello"); + file.close(); + + break; +end + +--[[ +file.open("myfile.lua","w+") -- Open and append content to myfile.lua +file.write("hello"); +file.close(); +]] diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/gpio/gpio_out.lua b/LuaNode_Esp32/LuaNode32/lua_samples/gpio/gpio_out.lua index b6330aa..5a7700b 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/gpio/gpio_out.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/gpio/gpio_out.lua @@ -1,11 +1,11 @@ --- GPIO sample --- The pin gpio2 connect to a led. when the pin output high level, the led will be light up --- gpio.mode(pin, mode) --- mode = 1(INPUT), 2(OUTPUT),4(PULLUP),5(INPUT_PULLUP),8(PULLDOWN),9(INPUT_PULLDOWN)...... --- gpio.write(pin, level) --- level = gpio.read(pin) - -gpio.mode(2,gpio.OUTPUT); -gpio.write(2,1); -- led on -gpio.write(2,0); -- led off - +-- GPIO sample +-- The pin gpio2 connect to a led. when the pin output high level, the led will be light up +-- gpio.mode(pin, mode) +-- mode = 1(INPUT), 2(OUTPUT),4(PULLUP),5(INPUT_PULLUP),8(PULLDOWN),9(INPUT_PULLDOWN)...... +-- gpio.write(pin, level) +-- level = gpio.read(pin) + +gpio.mode(2,gpio.OUTPUT); +gpio.write(2,1); -- led on +gpio.write(2,0); -- led off + diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c.lua b/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c.lua index 1937660..98ba9ad 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c.lua @@ -1,25 +1,25 @@ --- Since there are two i2c on esp32, I setup one i2c as master and the other one as slave, and read/write them on the esp32 --- slave : --- GPIO25 is assigned as the data signal of i2c slave port --- GPIO26 is assigned as the clock signal of i2c slave port --- master: --- GPIO18 is assigned as the data signal of i2c master port --- GPIO19 is assigned as the clock signal of i2c master port --- connect GPIO18 with GPIO25 --- connect GPIO19 with GPIO26 -i2c.setup(i2c.SLAVE,i2c.I2C_0,26,25,40) -i2c.setup(i2c.MASTER,i2c.I2C_1,19,18) --- slave write something, master read -i2c.write(i2c.SLAVE,i2c.I2C_0,40,"helloworld") -c=i2c.read(i2c.MASTER,i2c.I2C_1,40,10) -print(c) - -tmr.delay(5) --- master write something, slave read -i2c.write(i2c.MASTER,i2c.I2C_1,40,"test") -c=i2c.read(i2c.SLAVE,i2c.I2C_0,40,4) -print(c) - --- i2c uninstall -i2c.uninstall(i2c.I2C_0) -i2c.uninstall(i2c.I2C_1) +-- Since there are two i2c on esp32, I setup one i2c as master and the other one as slave, and read/write them on the esp32 +-- slave : +-- GPIO25 is assigned as the data signal of i2c slave port +-- GPIO26 is assigned as the clock signal of i2c slave port +-- master: +-- GPIO18 is assigned as the data signal of i2c master port +-- GPIO19 is assigned as the clock signal of i2c master port +-- connect GPIO18 with GPIO25 +-- connect GPIO19 with GPIO26 +i2c.setup(i2c.SLAVE,i2c.I2C_0,26,25,40) +i2c.setup(i2c.MASTER,i2c.I2C_1,19,18) +-- slave write something, master read +i2c.write(i2c.SLAVE,i2c.I2C_0,40,"helloworld") +c=i2c.read(i2c.MASTER,i2c.I2C_1,40,10) +print(c) + +tmr.delay(5) +-- master write something, slave read +i2c.write(i2c.MASTER,i2c.I2C_1,40,"test") +c=i2c.read(i2c.SLAVE,i2c.I2C_0,40,4) +print(c) + +-- i2c uninstall +i2c.uninstall(i2c.I2C_0) +i2c.uninstall(i2c.I2C_1) diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c_test.lua b/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c_test.lua index 7f29b7e..c0fe9b1 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c_test.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/i2c/i2c_test.lua @@ -1,23 +1,23 @@ --- ESP32 Lua I2c bus scanner --- vslinuxdotnet@github - 11/02/2017 - -sda=18 -scl=19 - -function find_dev(dev_addr) - c=i2c.read(i2c.MASTER, i2c.I2C_1, dev_addr, 4) - if c == "" then - return false - else - return true - end -end - -i2c.setup(i2c.MASTER, i2c.I2C_1, scl, sda) -print("Scanning I2C Bus...") -for i=0,127 do - if find_dev(i)==true then - print("Device found at address 0x"..string.format("%02X",i).."!") - end -end +-- ESP32 Lua I2c bus scanner +-- vslinuxdotnet@github - 11/02/2017 + +sda=18 +scl=19 + +function find_dev(dev_addr) + c=i2c.read(i2c.MASTER, i2c.I2C_1, dev_addr, 4) + if c == "" then + return false + else + return true + end +end + +i2c.setup(i2c.MASTER, i2c.I2C_1, scl, sda) +print("Scanning I2C Bus...") +for i=0,127 do + if find_dev(i)==true then + print("Device found at address 0x"..string.format("%02X",i).."!") + end +end print("Done!") \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/mqtt/mqtt.lua b/LuaNode_Esp32/LuaNode32/lua_samples/mqtt/mqtt.lua index dbf5410..f91202f 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/mqtt/mqtt.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/mqtt/mqtt.lua @@ -1,31 +1,31 @@ --- mqtt.new(host, client_id, keepalive, connected_callback, [username], [password], [encrypt]) --- host: the mqtt host IP --- client_id: client id --- keepalive: keep alive seconds --- connected_callback: a callback when connection established --- username: optional argument, mqtt user name --- password: --- encrypt: not support encrypt now - --- mqtt.on(handle, event, callback): the method is used to register callback to monitor the following event: 'data'/'publish'/'subscribe'/'disconnect' - --- mqtt.unsubscribe(handle, topic): unsubscribe a topic - --- mqtt.close(handle): use this method to close an mqtt connection - --- Note: --- 1. the mqtt.new retern a handle, which is used for subscribe/publish, remember to save the handle. --- 2. you can create 3 mqtt connections at most. You will fail to create more than 3 mqtt connections. - -ccb=function() print("mqtt connected\n"); end -dcb=function(t,d) print(t);print(d); end -wifi.setmode(1); -wifi.start(); -wifi.sta.config({ssid="Doit",pwd="doit3305"}); -tmr.delay(15); -handle=mqtt.new('test.mosquitto.org','c1',600,ccb); -- if you don't need connect callback, write like this: mqtt.new('test.mosquitto.org','c1',600,nil) -tmr.delay(8); -mqtt.subscribe(handle,'/chann1',mqtt.QOS0); -tmr.delay(3); -mqtt.on(handle,'data',dcb); +-- mqtt.new(host, client_id, keepalive, connected_callback, [username], [password], [encrypt]) +-- host: the mqtt host IP +-- client_id: client id +-- keepalive: keep alive seconds +-- connected_callback: a callback when connection established +-- username: optional argument, mqtt user name +-- password: +-- encrypt: not support encrypt now + +-- mqtt.on(handle, event, callback): the method is used to register callback to monitor the following event: 'data'/'publish'/'subscribe'/'disconnect' + +-- mqtt.unsubscribe(handle, topic): unsubscribe a topic + +-- mqtt.close(handle): use this method to close an mqtt connection + +-- Note: +-- 1. the mqtt.new retern a handle, which is used for subscribe/publish, remember to save the handle. +-- 2. you can create 3 mqtt connections at most. You will fail to create more than 3 mqtt connections. + +ccb=function() print("mqtt connected\n"); end +dcb=function(t,d) print(t);print(d); end +wifi.setmode(1); +wifi.start(); +wifi.sta.config({ssid="Doit",pwd="doit3305"}); +tmr.delay(15); +handle=mqtt.new('test.mosquitto.org','c1',600,ccb); -- if you don't need connect callback, write like this: mqtt.new('test.mosquitto.org','c1',600,nil) +tmr.delay(8); +mqtt.subscribe(handle,'/chann1',mqtt.QOS0); +tmr.delay(3); +mqtt.on(handle,'data',dcb); mqtt.publish(handle,'/chann1','test'); \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/pwm/pwm.lua b/LuaNode_Esp32/LuaNode32/lua_samples/pwm/pwm.lua index fdda829..1fbf1e4 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/pwm/pwm.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/pwm/pwm.lua @@ -1,29 +1,29 @@ ------------------------------------------------------------------------------------ --- The following methods are provided by PWM module: --- --- 1. pwm.setup(pin, freqency, duty, channel) --- pin: pin to set --- frequency: frequency to set --- duty: duty to set. range from 0 to 8192 --- channel: used channel, valid channel range from 0 to 7 --- 2. pwm.stop(channel) --- 3. pwm.getduty(channel) --- 4. pwm.setduty(channel, duty) --- 5. pwm.getfreq() --- 6. pwm.setfreq(frequency) --- --- Note: once pwm.setup is called, your device start to generate PWM. ------------------------------------------------------------------------------------ - --- The following example is to make the blue LED on DOIT ESP32 dev-board blink per seconds. --- There is a blue LED connect to GPIO2 on DOIT ESP32 dev-board. - -pwm.setup(2, 1, 4096, 0); -- blink per seconds -duty=pwm.getduty(0); -print(duty); -freq = pwm.getfreq(); -print(freq); -tmr.delay(10); -pwm.setfreq(2); -- blink twice per seconds -tmr.delay(10); +----------------------------------------------------------------------------------- +-- The following methods are provided by PWM module: +-- +-- 1. pwm.setup(pin, freqency, duty, channel) +-- pin: pin to set +-- frequency: frequency to set +-- duty: duty to set. range from 0 to 8192 +-- channel: used channel, valid channel range from 0 to 7 +-- 2. pwm.stop(channel) +-- 3. pwm.getduty(channel) +-- 4. pwm.setduty(channel, duty) +-- 5. pwm.getfreq() +-- 6. pwm.setfreq(frequency) +-- +-- Note: once pwm.setup is called, your device start to generate PWM. +----------------------------------------------------------------------------------- + +-- The following example is to make the blue LED on DOIT ESP32 dev-board blink per seconds. +-- There is a blue LED connect to GPIO2 on DOIT ESP32 dev-board. + +pwm.setup(2, 1, 4096, 0); -- blink per seconds +duty=pwm.getduty(0); +print(duty); +freq = pwm.getfreq(); +print(freq); +tmr.delay(10); +pwm.setfreq(2); -- blink twice per seconds +tmr.delay(10); pwm.stop(0); \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/timer/timer.lua b/LuaNode_Esp32/LuaNode32/lua_samples/timer/timer.lua index 96d59ca..1d0cb94 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/timer/timer.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/timer/timer.lua @@ -1,14 +1,14 @@ --- timer --- tmr.delay(us) - -tmr.delay_us(1000000); -- Delay 1000000us, and then output hello -print("hello"); - -tmr.delay_ms(1000); -- delay 1000ms -print("hello"); - -tmr.delay(1); -- delay 1s -print("hello"); - -tmr.now(); -- Output timestamp - +-- timer +-- tmr.delay(us) + +tmr.delay_us(1000000); -- Delay 1000000us, and then output hello +print("hello"); + +tmr.delay_ms(1000); -- delay 1000ms +print("hello"); + +tmr.delay(1); -- delay 1s +print("hello"); + +tmr.now(); -- Output timestamp + diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/uart/uart.lua b/LuaNode_Esp32/LuaNode32/lua_samples/uart/uart.lua index 2fd892a..a6ece03 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/uart/uart.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/uart/uart.lua @@ -1,23 +1,23 @@ --- The uart module provide the following method --- --- 1. uart.setup(id, baud, databits, parity, stopbits, flow_ctrl, [txd], [rxd], [rts], [cts]) --- id: the uart number --- baud: the uart baud rate --- databits: can be the following constants: uart.DATA_8_BITS/uart.DATA_7_BITS/uart.DATA_6_BITS/uart.DATA_5_BITS --- parity: can be uart.PARITY_NONE/uart.PARITY_ODD/uart.PARITY_EVEN --- stopbits: can be uart.STOPBITS_1/uart.STOPBITS_1_5/uart.STOPBITS_2 --- flow_ctrl: flow control enable. normally set to uart.FLOWCTRL_DISABLE --- txd: pin of txd, optional, default pin is GPIO4 --- rxd: pin of rxd, optional, default pin is GPIO5 --- rts: pin of rts, optional, default pin is GPIO18 --- cts: pin of cts, optional, default is GPIO19 --- 2. uart.write(id, string1, [string2], ..., [stringn]) --- 3. uart.uninstall(id) - -uart.setup(uart.UART_1, 115200, uart.DATA_8_BITS, uart.PARITY_NONE, uart.STOPBITS_1, uart.FLOWCTRL_DISABLE); -while true do - tmr.delay(2); - uart.write(1, "hello"); -end - +-- The uart module provide the following method +-- +-- 1. uart.setup(id, baud, databits, parity, stopbits, flow_ctrl, [txd], [rxd], [rts], [cts]) +-- id: the uart number +-- baud: the uart baud rate +-- databits: can be the following constants: uart.DATA_8_BITS/uart.DATA_7_BITS/uart.DATA_6_BITS/uart.DATA_5_BITS +-- parity: can be uart.PARITY_NONE/uart.PARITY_ODD/uart.PARITY_EVEN +-- stopbits: can be uart.STOPBITS_1/uart.STOPBITS_1_5/uart.STOPBITS_2 +-- flow_ctrl: flow control enable. normally set to uart.FLOWCTRL_DISABLE +-- txd: pin of txd, optional, default pin is GPIO4 +-- rxd: pin of rxd, optional, default pin is GPIO5 +-- rts: pin of rts, optional, default pin is GPIO18 +-- cts: pin of cts, optional, default is GPIO19 +-- 2. uart.write(id, string1, [string2], ..., [stringn]) +-- 3. uart.uninstall(id) + +uart.setup(uart.UART_1, 115200, uart.DATA_8_BITS, uart.PARITY_NONE, uart.STOPBITS_1, uart.FLOWCTRL_DISABLE); +while true do + tmr.delay(2); + uart.write(1, "hello"); +end + -- uart.uninstall(uart.UART_1) \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/lua_samples/utils/utils.lua b/LuaNode_Esp32/LuaNode32/lua_samples/utils/utils.lua index f1d5d28..e4db2e4 100644 --- a/LuaNode_Esp32/LuaNode32/lua_samples/utils/utils.lua +++ b/LuaNode_Esp32/LuaNode32/lua_samples/utils/utils.lua @@ -1,6 +1,6 @@ --- utils module -print(utils.leapyear(2016)) -- is the input year leap year? - -str = "hello" -encodeStr = utils.base64_encode(str) +-- utils module +print(utils.leapyear(2016)) -- is the input year leap year? + +str = "hello" +encodeStr = utils.base64_encode(str) decodeStr = utils.base64_decode(encodeStr) \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/main/include/extras/esp_intr_ext.h b/LuaNode_Esp32/LuaNode32/main/include/extras/esp_intr_ext.h index 7ef1550..953489b 100644 --- a/LuaNode_Esp32/LuaNode32/main/include/extras/esp_intr_ext.h +++ b/LuaNode_Esp32/LuaNode32/main/include/extras/esp_intr_ext.h @@ -1,13 +1,13 @@ -#ifndef _ESP_INTR_EXT_H_ -#define _ESP_INTR_EXT_H_ - -#include "esp_intr.h" -#include "soc_ext.h" - -#define ESP_UART0_INTR_ENABLE() \ - ESP_INTR_ENABLE(ETS_UART0_INUM) - -#define ESP_UART0_INTR_DISABLE() \ - ESP_INTR_DISABLE(ETS_UART0_INUM) - +#ifndef _ESP_INTR_EXT_H_ +#define _ESP_INTR_EXT_H_ + +#include "esp_intr.h" +#include "soc_ext.h" + +#define ESP_UART0_INTR_ENABLE() \ + ESP_INTR_ENABLE(ETS_UART0_INUM) + +#define ESP_UART0_INTR_DISABLE() \ + ESP_INTR_DISABLE(ETS_UART0_INUM) + #endif \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_ext.h b/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_ext.h index ade65c3..33672a5 100644 --- a/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_ext.h +++ b/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_ext.h @@ -1,8 +1,8 @@ -/*typedef enum { - GPIO_PIN_INTR_DISABLE = 0, - GPIO_PIN_INTR_POSEDGE = 1, - GPIO_PIN_INTR_NEGEDGE = 2, - GPIO_PIN_INTR_ANYEDGE = 3, - GPIO_PIN_INTR_LOLEVEL = 4, - GPIO_PIN_INTR_HILEVEL = 5 +/*typedef enum { + GPIO_PIN_INTR_DISABLE = 0, + GPIO_PIN_INTR_POSEDGE = 1, + GPIO_PIN_INTR_NEGEDGE = 2, + GPIO_PIN_INTR_ANYEDGE = 3, + GPIO_PIN_INTR_LOLEVEL = 4, + GPIO_PIN_INTR_HILEVEL = 5 } GPIO_INT_TYPE;*/ \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_reg_ext.h b/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_reg_ext.h index bd5b1d9..9c03549 100644 --- a/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_reg_ext.h +++ b/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_reg_ext.h @@ -1,22 +1,22 @@ -#define GPIO_GPIO_PIN0_INT_ENA 0x0000001F -#define GPIO_GPIO_PIN0_INT_ENA_S 13 -#define GPIO_GPIO_PIN0_PAD_DRIVER (BIT(2)) - -#define GPIO_PIN_INT_TYPE_LSB 7 -#define GPIO_PIN_INT_TYPE_MASK 0x380 - -#define GPIO_OUT_W1TS (DR_REG_GPIO_BASE + 0x0008) -#define GPIO_OUT_W1TC (DR_REG_GPIO_BASE + 0x000c) -#define GPIO_ENABLE_W1TC (DR_REG_GPIO_BASE + 0x0028) -#define GPIO_ENABLE_W1TS (DR_REG_GPIO_BASE + 0x0024) -#define GPIO_OUT1_W1TS (DR_REG_GPIO_BASE + 0x0014) -#define GPIO_OUT1_W1TC (DR_REG_GPIO_BASE + 0x0018) -#define GPIO_ENABLE1_W1TS (DR_REG_GPIO_BASE + 0x0030) -#define GPIO_ENABLE1_W1TC (DR_REG_GPIO_BASE + 0x0034) -#define GPIO_IN (DR_REG_GPIO_BASE + 0x003c) -#define GPIO_IN1 (DR_REG_GPIO_BASE + 0x0040) - -#define GPIO_PIN_PAD_DRIVER_LSB 2 -#define GPIO_PIN_PAD_DRIVER_MASK 0x00000004 -#define GPIO_PIN_PAD_DRIVER_SET(x) (((x) << GPIO_PIN_PAD_DRIVER_LSB) & GPIO_PIN_PAD_DRIVER_MASK) +#define GPIO_GPIO_PIN0_INT_ENA 0x0000001F +#define GPIO_GPIO_PIN0_INT_ENA_S 13 +#define GPIO_GPIO_PIN0_PAD_DRIVER (BIT(2)) + +#define GPIO_PIN_INT_TYPE_LSB 7 +#define GPIO_PIN_INT_TYPE_MASK 0x380 + +#define GPIO_OUT_W1TS (DR_REG_GPIO_BASE + 0x0008) +#define GPIO_OUT_W1TC (DR_REG_GPIO_BASE + 0x000c) +#define GPIO_ENABLE_W1TC (DR_REG_GPIO_BASE + 0x0028) +#define GPIO_ENABLE_W1TS (DR_REG_GPIO_BASE + 0x0024) +#define GPIO_OUT1_W1TS (DR_REG_GPIO_BASE + 0x0014) +#define GPIO_OUT1_W1TC (DR_REG_GPIO_BASE + 0x0018) +#define GPIO_ENABLE1_W1TS (DR_REG_GPIO_BASE + 0x0030) +#define GPIO_ENABLE1_W1TC (DR_REG_GPIO_BASE + 0x0034) +#define GPIO_IN (DR_REG_GPIO_BASE + 0x003c) +#define GPIO_IN1 (DR_REG_GPIO_BASE + 0x0040) + +#define GPIO_PIN_PAD_DRIVER_LSB 2 +#define GPIO_PIN_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN_PAD_DRIVER_SET(x) (((x) << GPIO_PIN_PAD_DRIVER_LSB) & GPIO_PIN_PAD_DRIVER_MASK) #define GPIO_PAD_DRIVER_ENABLE 1 \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_sd_reg_ext.h b/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_sd_reg_ext.h index c256dbf..23ead33 100644 --- a/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_sd_reg_ext.h +++ b/LuaNode_Esp32/LuaNode32/main/include/extras/gpio_sd_reg_ext.h @@ -1,8 +1,8 @@ -#ifndef _GPIO_SD_REG_EXT_H_ -#define _GPIO_SD_REG_EXT_H_ - -#define SIGMADELTA0 (DR_REG_GPIO_SD_BASE + 0x0000) -#define SIGMADELTA_SD0_PRESCALE 0x000000FF -#define SIGMADELTA_SD0_PRESCALE_S 8 - +#ifndef _GPIO_SD_REG_EXT_H_ +#define _GPIO_SD_REG_EXT_H_ + +#define SIGMADELTA0 (DR_REG_GPIO_SD_BASE + 0x0000) +#define SIGMADELTA_SD0_PRESCALE 0x000000FF +#define SIGMADELTA_SD0_PRESCALE_S 8 + #endif \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/main/include/mem.h b/LuaNode_Esp32/LuaNode32/main/include/mem.h index aa3ea15..1de2672 100644 --- a/LuaNode_Esp32/LuaNode32/main/include/mem.h +++ b/LuaNode_Esp32/LuaNode32/main/include/mem.h @@ -1,27 +1,27 @@ -#ifndef __MEM_H__ -#define __MEM_H__ - -#ifndef MEMLEAK_DEBUG -#define os_free(s) vPortFree(s, "", 0) -#define os_malloc(s) pvPortMalloc(s, "", 0) -#define os_calloc(s) pvPortCalloc(s, "", 0); -#define os_realloc(p, s) pvPortRealloc(p, s, "", 0) -#define os_zalloc(s) pvPortZalloc(s, "", 0) -#else -#define os_free(s) \ -do{\ - const char *file = mem_debug_file;\ - vPortFree(s, file, __LINE__);\ -}while(0) - -#define os_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) - -#define os_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) - -#define os_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) - -#define os_zalloc(s) ({const char *file = mem_debug_file; pvPortZalloc(s, file, __LINE__);}) -#endif - -#endif - +#ifndef __MEM_H__ +#define __MEM_H__ + +#ifndef MEMLEAK_DEBUG +#define os_free(s) vPortFree(s, "", 0) +#define os_malloc(s) pvPortMalloc(s, "", 0) +#define os_calloc(s) pvPortCalloc(s, "", 0); +#define os_realloc(p, s) pvPortRealloc(p, s, "", 0) +#define os_zalloc(s) pvPortZalloc(s, "", 0) +#else +#define os_free(s) \ +do{\ + const char *file = mem_debug_file;\ + vPortFree(s, file, __LINE__);\ +}while(0) + +#define os_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) + +#define os_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) + +#define os_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) + +#define os_zalloc(s) ({const char *file = mem_debug_file; pvPortZalloc(s, file, __LINE__);}) +#endif + +#endif + diff --git a/LuaNode_Esp32/LuaNode32/main/include/user_config.h b/LuaNode_Esp32/LuaNode32/main/include/user_config.h index 1d916d3..317b77b 100644 --- a/LuaNode_Esp32/LuaNode32/main/include/user_config.h +++ b/LuaNode_Esp32/LuaNode32/main/include/user_config.h @@ -1,71 +1,71 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __USER_CONFIG_H__ -#define __USER_CONFIG_H__ - -#include "esp_misc.h" - -#define GPIO_INTERRUPT_ENABLE - -/* -#ifdef LUA_OPTRAM -#define LUA_OPTIMIZE_MEMORY 2 -#else -#define LUA_OPTIMIZE_MEMORY 0 -#endif */ - - -#define ICACHE_STORE_ATTR __attribute__((aligned(4))) -#define ICACHE_STORE_TYPEDEF_ATTR __attribute__((aligned(4))) - - -#define BUILD_SPIFFS 1 - - -#define NODE_ERROR -#define NODE_DEBUG - -#ifdef NODE_DEBUG -#define NODE_DBG os_printf -#else -#define NODE_DBG -#endif /* NODE_DEBUG */ - -#ifdef NODE_ERROR -#define NODE_ERR os_printf -#else -#define NODE_ERR -#endif /* NODE_ERROR */ - -#define SHOW_WRITE_PROGRESS - -#define ENABLE_SOCK2UART 1 - -#define VERSION "1.3.0" - -#define FLASH_READ_SIZE 1024 - -#endif - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __USER_CONFIG_H__ +#define __USER_CONFIG_H__ + +#include "esp_misc.h" + +#define GPIO_INTERRUPT_ENABLE + +/* +#ifdef LUA_OPTRAM +#define LUA_OPTIMIZE_MEMORY 2 +#else +#define LUA_OPTIMIZE_MEMORY 0 +#endif */ + + +#define ICACHE_STORE_ATTR __attribute__((aligned(4))) +#define ICACHE_STORE_TYPEDEF_ATTR __attribute__((aligned(4))) + + +#define BUILD_SPIFFS 1 + + +#define NODE_ERROR +#define NODE_DEBUG + +#ifdef NODE_DEBUG +#define NODE_DBG os_printf +#else +#define NODE_DBG +#endif /* NODE_DEBUG */ + +#ifdef NODE_ERROR +#define NODE_ERR os_printf +#else +#define NODE_ERR +#endif /* NODE_ERROR */ + +#define SHOW_WRITE_PROGRESS + +#define ENABLE_SOCK2UART 1 + +#define VERSION "1.3.0" + +#define FLASH_READ_SIZE 1024 + +#endif + From 719e5dbb9a5bc60274b2f51417f7d9c274871631 Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 20:08:47 +0000 Subject: [PATCH 7/8] Formatting: given all code some clang-format love --- .../LuaNode32/components/easy_mem/easy_heap.c | 233 +- .../LuaNode32/components/easy_mem/easy_mem.c | 257 +- .../LuaNode32/components/espconn/dhcpserver.c | 1691 +++---- .../LuaNode32/components/espconn/espconn.c | 1805 ++++---- .../components/espconn/espconn_tcp.c | 2095 +++++---- .../components/espconn/espconn_udp.c | 374 +- .../LuaNode32/components/espconn/netio.c | 579 +-- .../LuaNode32/components/espconn/ping.c | 415 +- .../LuaNode32/components/espmqtt/mqtt.c | 259 +- .../LuaNode32/components/espmqtt/mqtt_msg.c | 136 +- .../LuaNode32/components/espmqtt/ringbuf.c | 103 +- .../components/free80211/free80211.c | 51 +- .../LuaNode32/components/lpeg/lpcap.c | 818 ++-- .../LuaNode32/components/lpeg/lpcode.c | 1546 ++++--- .../LuaNode32/components/lpeg/lpprint.c | 399 +- .../LuaNode32/components/lpeg/lptree.c | 1894 ++++---- .../LuaNode32/components/lpeg/lpvm.c | 625 +-- LuaNode_Esp32/LuaNode32/components/lua/lapi.c | 1966 +++++---- .../LuaNode32/components/lua/lauxlib.c | 1331 +++--- .../LuaNode32/components/lua/lbaselib.c | 1170 ++--- .../LuaNode32/components/lua/lcode.c | 1709 ++++---- .../LuaNode32/components/lua/ldblib.c | 666 +-- .../LuaNode32/components/lua/ldebug.c | 1310 +++--- LuaNode_Esp32/LuaNode32/components/lua/ldo.c | 861 ++-- .../LuaNode32/components/lua/ldump.c | 499 ++- LuaNode_Esp32/LuaNode32/components/lua/legc.c | 13 +- .../LuaNode32/components/lua/lfunc.c | 269 +- LuaNode_Esp32/LuaNode32/components/lua/lgc.c | 1347 +++--- .../LuaNode32/components/lua/liolib.c | 798 ++-- LuaNode_Esp32/LuaNode32/components/lua/llex.c | 805 ++-- .../LuaNode32/components/lua/lmathlib.c | 401 +- LuaNode_Esp32/LuaNode32/components/lua/lmem.c | 80 +- .../LuaNode32/components/lua/loadlib.c | 1035 +++-- .../LuaNode32/components/lua/lobject.c | 376 +- .../LuaNode32/components/lua/lopcodes.c | 170 +- .../LuaNode32/components/lua/lparser.c | 2482 ++++++----- .../LuaNode32/components/lua/lrotable.c | 193 +- .../LuaNode32/components/lua/lstate.c | 370 +- .../LuaNode32/components/lua/lstring.c | 227 +- .../LuaNode32/components/lua/lstrlib.c | 1668 +++---- .../LuaNode32/components/lua/ltable.c | 1223 +++--- .../LuaNode32/components/lua/ltablib.c | 476 +- LuaNode_Esp32/LuaNode32/components/lua/ltm.c | 110 +- LuaNode_Esp32/LuaNode32/components/lua/lua.c | 867 ++-- .../LuaNode32/components/lua/lundump.c | 555 +-- LuaNode_Esp32/LuaNode32/components/lua/lvm.c | 1615 +++---- LuaNode_Esp32/LuaNode32/components/lua/lzio.c | 114 +- .../LuaNode32/components/modules/file.c | 455 +- .../LuaNode32/components/modules/gpio.c | 394 +- .../LuaNode32/components/modules/i2c.c | 328 +- .../LuaNode32/components/modules/ip_fmt.c | 34 +- .../LuaNode32/components/modules/linit.c | 114 +- .../LuaNode32/components/modules/mqtt.c | 807 ++-- .../LuaNode32/components/modules/net.c | 2142 ++++----- .../LuaNode32/components/modules/node.c | 928 ++-- .../LuaNode32/components/modules/nvs.c | 556 +-- .../LuaNode32/components/modules/pwm.c | 209 +- .../LuaNode32/components/modules/tmr.c | 631 +-- .../LuaNode32/components/modules/uart.c | 355 +- .../LuaNode32/components/modules/utils.c | 105 +- .../LuaNode32/components/modules/wifi.c | 849 ++-- .../LuaNode32/components/mydriver/gpio.c | 282 +- .../LuaNode32/components/mydriver/gpio16.c | 42 +- .../components/mydriver/i2c_master.c | 105 +- .../LuaNode32/components/mydriver/mygpio.c | 210 +- .../LuaNode32/components/mydriver/pwm.c | 474 +- .../LuaNode32/components/mylibc/c_ctype.c | 1 + .../LuaNode32/components/mylibc/c_math.c | 71 +- .../LuaNode32/components/mylibc/c_stdio.c | 742 ++-- .../LuaNode32/components/mylibc/c_stdlib.c | 87 +- .../LuaNode32/components/platform/flash_api.c | 220 +- .../LuaNode32/components/platform/flash_fs.c | 55 +- .../LuaNode32/components/platform/pin_map.c | 31 +- .../LuaNode32/components/platform/platform.c | 780 ++-- .../components/platform/platform_flash.c | 322 +- .../components/platform/platform_partition.c | 117 +- .../LuaNode32/components/platform/vfs.c | 597 +-- .../LuaNode32/components/spiffs/spiffs.c | 834 ++-- .../components/spiffs/spiffs_cache.c | 487 ++- .../components/spiffs/spiffs_check.c | 2007 +++++---- .../LuaNode32/components/spiffs/spiffs_gc.c | 1138 ++--- .../components/spiffs/spiffs_hydrogen.c | 1911 ++++---- .../components/spiffs/spiffs_nucleus.c | 3876 +++++++++-------- .../LuaNode32/components/spiffs/test/main.c | 10 +- .../components/spiffs/test/test_bugreports.c | 289 +- .../components/spiffs/test/test_check.c | 725 +-- .../components/spiffs/test/test_dev.c | 175 +- .../components/spiffs/test/test_hydrogen.c | 2054 ++++----- .../components/spiffs/test/test_spiffs.c | 1322 +++--- .../components/spiffs/test/testrunner.c | 307 +- .../components/spiffs/test/testsuites.c | 11 +- .../LuaNode32/components/task/task.c | 176 +- .../LuaNode32/components/uart/my_uart.c | 247 +- .../LuaNode32/components/utils/base64.c | 71 +- .../LuaNode32/components/utils/crc16.c | 68 +- .../LuaNode32/components/utils/crc8.c | 32 +- .../LuaNode32/components/utils/datetime.c | 230 +- .../LuaNode32/components/utils/md5.c | 157 +- .../alexa_esp32/components/alexa/alexa.c | 581 +-- .../alexa_esp32/components/utils/utils.c | 25 +- .../examples/alexa_esp32/main/main.c | 145 +- .../components/alexa/alexa.c | 86 +- .../components/alexa/alexa_device.c | 642 +-- .../alexa/upnp_broadcast_responder.c | 189 +- .../components/utils/utils.c | 25 +- .../examples/alexa_multi_esp32/main/main.c | 145 +- .../ble_led_control/client/main/gattc_demo.c | 1354 +++--- .../ble_led_control/server/main/gatts_demo.c | 715 +-- .../gatt_client/main/gattc_demo.c | 527 ++- .../gatt_server/main/gatts_demo.c | 947 ++-- .../ble_to_udp_server/components/ble/ble.c | 370 +- .../components/uart/my_uart.c | 446 +- .../components/utils/my_list.c | 85 +- .../components/utils/utils.c | 17 +- .../examples/ble_to_udp_server/main/main.c | 463 +- .../ble_to_udp_server/main/udp_task.c | 148 +- .../bluetooth_scanner/main/app_main.c | 365 +- .../camera/components/camera/camera.c | 310 +- .../camera/components/camera/ov7725.c | 220 +- .../examples/camera/components/camera/sccb.c | 54 +- .../examples/camera/components/camera/twi.c | 432 +- .../camera/components/camera/wiring.c | 45 +- .../LuaNode32/examples/camera/main/app_main.c | 72 +- .../examples/dns_resolver/app_main.c | 409 +- .../examples/ds1307/components/bsp/ds1307.c | 221 +- .../LuaNode32/examples/ds1307/main/main.c | 124 +- .../LuaNode32/examples/easy_mem/app_main.c | 39 +- .../main/gatts_demo.c | 658 +-- .../esp32_nrf51822_ble_conn/main/gattc_demo.c | 1279 +++--- .../examples/free80211send/app_main.c | 211 +- .../LuaNode32/examples/json/main/main.c | 198 +- .../examples/lcd_nokia5110_driver/app_main.c | 1186 +++-- .../examples/lwip_raw_api/app_main.c | 182 +- .../client/components/ota/ota.c | 359 +- .../client/components/utils/utils.c | 25 +- .../ota_tcp_update/client/main/main.c | 85 +- .../examples/raw_flash_rw/app_main.c | 66 +- .../examples/simple_http_server/app_main.c | 351 +- .../examples/tcp_client_espconn/app_main.c | 206 +- .../examples/tcp_server_espconn/app_main.c | 173 +- .../examples/telnet_server/app_main.c | 220 +- .../LuaNode32/examples/test_spiffs/app_main.c | 72 +- .../examples/udp_broadcast/app_main.c | 138 +- .../examples/udp_server_espconn/app_main.c | 156 +- .../LuaNode32/examples/wifi_scan/app_main.c | 161 +- LuaNode_Esp32/LuaNode32/main/app_main.c | 180 +- 146 files changed, 43282 insertions(+), 37981 deletions(-) diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c index 0478dcd..f0c19b8 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_heap.c @@ -1,8 +1,9 @@ #include "easy_heap.h" + #include "easy_conf.h" //#include "easy_os.h" -uint8_t ram_heap[HEAP_SIZE + 2*sizeof(struct mem_heap) + HEAP_ALIGNMENT - 1]; +uint8_t ram_heap[HEAP_SIZE + 2 * sizeof(struct mem_heap) + HEAP_ALIGNMENT - 1]; void *ram; struct mem_heap *pfree; struct mem_heap *heap_end; @@ -10,156 +11,160 @@ struct mem_heap *heap_end; /** * Fill hole */ -static void -plug_hole(struct mem_heap *heap) +static void plug_hole(struct mem_heap *heap) { - struct mem_heap *nheap, *pheap; - nheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->next]); - if(heap != nheap && !nheap->used && nheap != heap_end) { - if(pfree == nheap) - pfree = heap; - heap->next = nheap->next; - ((struct mem_heap *)&(((uint8_t *)ram)[nheap->next]))->prev = (uint8_t *)heap - (uint8_t *)ram; - } - pheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->prev]); - if(heap != pheap && !pheap->used) { - if(pfree == heap) - pfree = pheap; - pheap->next = heap->next; - ((struct mem_heap *)&(((uint8_t *)ram)[heap->next]))->prev = (uint8_t *)pheap - (uint8_t *)ram; - } + struct mem_heap *nheap, *pheap; + nheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->next]); + if (heap != nheap && !nheap->used && nheap != heap_end) + { + if (pfree == nheap) + pfree = heap; + heap->next = nheap->next; + ((struct mem_heap *)&(((uint8_t *)ram)[nheap->next]))->prev = (uint8_t *)heap - (uint8_t *)ram; + } + pheap = (struct mem_heap *)&(((uint8_t *)ram)[heap->prev]); + if (heap != pheap && !pheap->used) + { + if (pfree == heap) + pfree = pheap; + pheap->next = heap->next; + ((struct mem_heap *)&(((uint8_t *)ram)[heap->next]))->prev = (uint8_t *)pheap - (uint8_t *)ram; + } } /** * Heap initialization */ -void -easy_heap_init(void) +void easy_heap_init(void) { - ram = heap_align(ram_heap); - struct mem_heap *start = (struct mem_heap *)ram; - pfree = start; - start->used = 0; - start->prev = 0; - start->next = HEAP_SIZE; - heap_end = (struct mem_heap *)(ram+HEAP_SIZE+sizeof(struct mem_heap)); - heap_end->prev = 0; - heap_end->next = 0; - heap_end->used = 1; + ram = heap_align(ram_heap); + struct mem_heap *start = (struct mem_heap *)ram; + pfree = start; + start->used = 0; + start->prev = 0; + start->next = HEAP_SIZE; + heap_end = (struct mem_heap *)(ram + HEAP_SIZE + sizeof(struct mem_heap)); + heap_end->prev = 0; + heap_end->next = 0; + heap_end->used = 1; #ifdef ENABLE_DEBUG - easy_heap_statistics(); -#endif // ENABLE_DEBUG + easy_heap_statistics(); +#endif // ENABLE_DEBUG } /** * Heap alloc */ -void * -easy_heap_alloc(uint16_t size) +void *easy_heap_alloc(uint16_t size) { #ifdef ENABLE_DEBUG - easy_assert(size >= 0 && size <= HEAP_SIZE); -#endif // ENABLE_DEBUG - uint8_t ptr, ptr2; - struct mem_heap *mem, *mem2; + easy_assert(size >= 0 && size <= HEAP_SIZE); +#endif // ENABLE_DEBUG + uint8_t ptr, ptr2; + struct mem_heap *mem, *mem2; + + if (ram == NULL) + { + ERROR_PRINT("Heap is not initialized\n"); + return NULL; + } - if(ram == NULL) { - ERROR_PRINT("Heap is not initialized\n"); - return NULL; - } + if (size <= 0) + { + ERROR_PRINT("Invalid size of memory\n"); + return NULL; + } - if(size <= 0) { - ERROR_PRINT("Invalid size of memory\n"); - return NULL; - } + uint32_t aligned_size = ((size + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT - 1)); + if (aligned_size > HEAP_SIZE) + { + ERROR_PRINT("Require too much memory\n"); + return NULL; + } - uint32_t aligned_size = ((size + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT-1)); - if(aligned_size > HEAP_SIZE) { - ERROR_PRINT("Require too much memory\n"); - return NULL; - } - - for(ptr=(uint8_t *)pfree-(uint8_t *)ram; ptrnext) { - mem = (struct mem_heap *)&(((uint8_t *)ram)[ptr]); - if (!(mem->used) && (uint32_t)(mem->next-(ptr+sizeof(struct mem_heap))) >= aligned_size) { - /** - * Now, can alloc memory - * If the remaining free memory after alloc is enough to construct - * a new heap, we split the current heap to two part. Otherwise, - * return the current heap. - */ - if((uint8_t *)(mem->next)-(ptr+sizeof(struct mem_heap)) >= aligned_size+MIN_SIZE_ALIGNED) { - ptr2 = ptr+sizeof(struct mem_heap)+aligned_size; - mem2 = (struct mem_heap *)&(((uint8_t *)ram)[ptr2]); - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - mem->next = ptr2; - if(mem2->next != HEAP_SIZE) - ((struct mem_heap *)&(((uint8_t *)ram)[mem2->next]))->prev = ptr2; - } - mem->used = 1; - - if(mem == pfree) { // update pfree - while(pfree->used && pfree != heap_end) - pfree = (struct mem_heap *)&(((uint8_t *)ram)[pfree->next]); - } - return ((void *)skip_heap_head(mem)); + for (ptr = (uint8_t *)pfree - (uint8_t *)ram; ptr < HEAP_SIZE; + ptr = ((struct mem_heap *)&(((uint8_t *)ram)[ptr]))->next) + { + mem = (struct mem_heap *)&(((uint8_t *)ram)[ptr]); + if (!(mem->used) && (uint32_t)(mem->next - (ptr + sizeof(struct mem_heap))) >= aligned_size) + { + /** + * Now, can alloc memory + * If the remaining free memory after alloc is enough to construct + * a new heap, we split the current heap to two part. Otherwise, + * return the current heap. + */ + if ((uint8_t *)(mem->next) - (ptr + sizeof(struct mem_heap)) >= aligned_size + MIN_SIZE_ALIGNED) + { + ptr2 = ptr + sizeof(struct mem_heap) + aligned_size; + mem2 = (struct mem_heap *)&(((uint8_t *)ram)[ptr2]); + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + mem->next = ptr2; + if (mem2->next != HEAP_SIZE) + ((struct mem_heap *)&(((uint8_t *)ram)[mem2->next]))->prev = ptr2; + } + mem->used = 1; + + if (mem == pfree) + { // update pfree + while (pfree->used && pfree != heap_end) pfree = (struct mem_heap *)&(((uint8_t *)ram)[pfree->next]); + } + return ((void *)skip_heap_head(mem)); + } } - } - return NULL; + return NULL; } /** * Heap free */ -void -easy_heap_free(void *heap) +void easy_heap_free(void *heap) { #ifdef ENABLE_DEBUG - easy_assert(heap != NULL && heap >= ram+sizeof(struct mem_heap) && heap <= sizeof(ram_heap)); -#endif // ENABLE_DEBUG - if(heap == NULL) - return; - - if(heap < ram || heap > ram + HEAP_SIZE) { - ERROR_PRINT("Invalid address\n"); - return; - } - - struct mem_heap *mem = get_heap_head(heap); - mem->used = 0; - if(mem < pfree) - pfree = mem; - - plug_hole(mem); + easy_assert(heap != NULL && heap >= ram + sizeof(struct mem_heap) && heap <= sizeof(ram_heap)); +#endif // ENABLE_DEBUG + if (heap == NULL) + return; + + if (heap < ram || heap > ram + HEAP_SIZE) + { + ERROR_PRINT("Invalid address\n"); + return; + } + + struct mem_heap *mem = get_heap_head(heap); + mem->used = 0; + if (mem < pfree) + pfree = mem; + + plug_hole(mem); } /** * Heap realloc */ -void * -easy_heap_realloc(void *heap, uint16_t size) +void *easy_heap_realloc(void *heap, uint16_t size) { - easy_heap_free(heap); - return easy_heap_alloc(size); + easy_heap_free(heap); + return easy_heap_alloc(size); } /** * Heap statistics */ -void -easy_heap_statistics(void) +void easy_heap_statistics(void) { - uint32_t total = sizeof(ram_heap); - uint32_t used = 0; - uint32_t remaining = 0; - DEBUG_PRINT("+----- Easy heap memory -----\n"); - DEBUG_PRINT("| Total: %d bytes\n", total); - DEBUG_PRINT("| Can be used: %d bytes\n", HEAP_SIZE); - DEBUG_PRINT("| Used: %d bytes\n", used); - DEBUG_PRINT("| Remaining: %d bytes\n", total-used); - DEBUG_PRINT("| Memory start from: %p\n", ram); - DEBUG_PRINT("+-----------------------\n"); + uint32_t total = sizeof(ram_heap); + uint32_t used = 0; + uint32_t remaining = 0; + DEBUG_PRINT("+----- Easy heap memory -----\n"); + DEBUG_PRINT("| Total: %d bytes\n", total); + DEBUG_PRINT("| Can be used: %d bytes\n", HEAP_SIZE); + DEBUG_PRINT("| Used: %d bytes\n", used); + DEBUG_PRINT("| Remaining: %d bytes\n", total - used); + DEBUG_PRINT("| Memory start from: %p\n", ram); + DEBUG_PRINT("+-----------------------\n"); } diff --git a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c index 8dffa1d..0586531 100644 --- a/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c +++ b/LuaNode_Esp32/LuaNode32/components/easy_mem/easy_mem.c @@ -1,175 +1,186 @@ #include "easy_mem.h" + #include "easy_conf.h" //#include "easy_os.h" #include "chain.h" - /** * multiply to make sure there are (2<<(MAX_ORDER+1)-1) heads */ -uint8_t mem_total[MAX_CHUNK_NUM*MAX_CHUNK_SIZE + layer_heads_size(MAX_ORDER+1) + MEM_ALIGNMENT - 1]; -void *mem_memory = NULL; //alignment memory -struct chunk *mem_heads[MAX_ORDER+1]; +uint8_t mem_total[MAX_CHUNK_NUM * MAX_CHUNK_SIZE + layer_heads_size(MAX_ORDER + 1) + MEM_ALIGNMENT - 1]; +void *mem_memory = NULL; // alignment memory +struct chunk *mem_heads[MAX_ORDER + 1]; /** * Split chunk recursively */ -static struct chunk * -split(struct chunk *c, uint8_t cnt, uint8_t order) +static struct chunk *split(struct chunk *c, uint8_t cnt, uint8_t order) { - add_to_head(mem_heads[cnt], c); - c->curr_order = cnt; - struct chunk *buddy = (struct chunk *)((void *)c+layer_size(cnt)+layer_heads_size(cnt+1)); - buddy->next = NULL; - buddy->order = c->order; - buddy->curr_order = c->curr_order; - buddy->used = 0; - - if(cnt > order) { - adjust_head(buddy, 1); - return split(buddy, --cnt, order); - } - buddy->used = 1; - return buddy; + add_to_head(mem_heads[cnt], c); + c->curr_order = cnt; + struct chunk *buddy = (struct chunk *)((void *)c + layer_size(cnt) + layer_heads_size(cnt + 1)); + buddy->next = NULL; + buddy->order = c->order; + buddy->curr_order = c->curr_order; + buddy->used = 0; + + if (cnt > order) + { + adjust_head(buddy, 1); + return split(buddy, --cnt, order); + } + buddy->used = 1; + return buddy; } /** * Merge two free chunks to a larger one recursively */ -static void -merge(struct chunk *mem_chunk, uint8_t order) +static void merge(struct chunk *mem_chunk, uint8_t order) { - // chunk list is empty, insert directly - if(mem_heads[order] == NULL) { - mem_chunk->used = 0; - mem_heads[order] = mem_chunk; - return; - } - - struct chunk *tmp = mem_heads[order]; - while(tmp != NULL) { - uint32_t length = layer_size(order)+layer_heads_size(order+1); - if(tmp->order == mem_chunk->order) { - // only those two neighboring buddies can be merged - if((void *)mem_chunk == (void *)tmp+length) { - adjust_head(tmp, -1); - merge((struct chunk *)tmp, ++order); - } else if((void *)mem_chunk+length == (void *)tmp) { - adjust_head(mem_chunk, -1); - merge(mem_chunk, ++order); - } else { // cannot merge, add to list head + // chunk list is empty, insert directly + if (mem_heads[order] == NULL) + { mem_chunk->used = 0; - add_to_head(mem_heads[order], mem_chunk); - } - return; + mem_heads[order] = mem_chunk; + return; + } + + struct chunk *tmp = mem_heads[order]; + while (tmp != NULL) + { + uint32_t length = layer_size(order) + layer_heads_size(order + 1); + if (tmp->order == mem_chunk->order) + { + // only those two neighboring buddies can be merged + if ((void *)mem_chunk == (void *)tmp + length) + { + adjust_head(tmp, -1); + merge((struct chunk *)tmp, ++order); + } + else if ((void *)mem_chunk + length == (void *)tmp) + { + adjust_head(mem_chunk, -1); + merge(mem_chunk, ++order); + } + else + { // cannot merge, add to list head + mem_chunk->used = 0; + add_to_head(mem_heads[order], mem_chunk); + } + return; + } + tmp = tmp->next; } - tmp = tmp->next; - } } /** * Memory initialization */ -void -easy_mem_init(void) +void easy_mem_init(void) { - mem_memory = (void *)mem_align(mem_total); - mem_heads[MAX_ORDER] = (struct chunk *)mem_memory; - struct chunk *head = mem_heads[MAX_ORDER]; - head->next = NULL; - head->order = MAX_ORDER; - head->curr_order = MAX_ORDER; - head->used = 0; + mem_memory = (void *)mem_align(mem_total); + mem_heads[MAX_ORDER] = (struct chunk *)mem_memory; + struct chunk *head = mem_heads[MAX_ORDER]; + head->next = NULL; + head->order = MAX_ORDER; + head->curr_order = MAX_ORDER; + head->used = 0; #ifdef ENABLE_DEBUG - easy_mem_statistics(); -#endif // ENABLE_DEBUG + easy_mem_statistics(); +#endif // ENABLE_DEBUG } /** * Memory alloc */ -void * -easy_mem_alloc(uint32_t size) +void *easy_mem_alloc(uint32_t size) { #ifdef ENABLE_DEBUG - easy_assert(size > 0 && size < MAX_CHUNK_NUM * MAX_CHUNK_SIZE && mem_memory != NULL); -#endif // ENABLE_DEBUG - struct chunk *res = NULL; - - if(size < 0 || size > MAX_CHUNK_NUM * MAX_CHUNK_SIZE) { - ERROR_PRINT("Invalid memory size\n"); - goto alloc_failed; - } - - if(mem_memory == NULL) { - ERROR_PRINT("Memory not init\n"); - goto alloc_failed; - } - - uint8_t order = 0; - while(1< 0 && size < MAX_CHUNK_NUM * MAX_CHUNK_SIZE && mem_memory != NULL); +#endif // ENABLE_DEBUG + struct chunk *res = NULL; + + if (size < 0 || size > MAX_CHUNK_NUM * MAX_CHUNK_SIZE) + { + ERROR_PRINT("Invalid memory size\n"); + goto alloc_failed; + } + + if (mem_memory == NULL) + { + ERROR_PRINT("Memory not init\n"); + goto alloc_failed; + } + + uint8_t order = 0; + while (1 << order < quotient(size, MIN_CHUNK_SIZE)) order++; + + if (mem_heads[order] == NULL) + { // chunk split + if (order == MAX_ORDER) + { + ERROR_PRINT("Not enough memory\n"); + goto alloc_failed; + } + uint8_t cnt = order; + while (++cnt <= MAX_ORDER) + { + if (mem_heads[cnt] != NULL) + break; + } + struct chunk *target = mem_heads[cnt]; + remove_from_chain(mem_heads[cnt], struct chunk, target); + adjust_head(target, 1); + res = split(target, --cnt, order); } - uint8_t cnt = order; - while(++cnt <= MAX_ORDER) { - if(mem_heads[cnt] != NULL) break; + else + { + res = mem_heads[order]; + res->used = 1; + remove_from_chain(mem_heads[order], struct chunk, res); } - struct chunk *target = mem_heads[cnt]; - remove_from_chain(mem_heads[cnt], struct chunk, target); - adjust_head(target, 1); - res = split(target, --cnt, order); - } else { - res = mem_heads[order]; - res->used = 1; - remove_from_chain(mem_heads[order], struct chunk, res); - } - - return ((void *)skip_chunk_head(res)); + + return ((void *)skip_chunk_head(res)); alloc_failed: - return NULL; + return NULL; } /** * Memory free */ -void -easy_mem_free(void *mem) +void easy_mem_free(void *mem) { #ifdef ENABLE_DEBUG - easy_assert(mem != NULL && mem <= mem_memory+sizeof(mem_total) && mem >= mem_memory); -#endif // ENABLE_DEBUG - if(mem == NULL) - return; - - if(mem < mem_memory || mem > mem_memory+sizeof(mem_total)) { - ERROR_PRINT("Invalid memory address"); - return; - } - - struct chunk *head = (struct chunk *)get_chunk_head(mem); - uint8_t curr_order = head->curr_order; - merge(head, curr_order); + easy_assert(mem != NULL && mem <= mem_memory + sizeof(mem_total) && mem >= mem_memory); +#endif // ENABLE_DEBUG + if (mem == NULL) + return; + + if (mem < mem_memory || mem > mem_memory + sizeof(mem_total)) + { + ERROR_PRINT("Invalid memory address"); + return; + } + + struct chunk *head = (struct chunk *)get_chunk_head(mem); + uint8_t curr_order = head->curr_order; + merge(head, curr_order); } /** * Print system memory statistics */ -void -easy_mem_statistics(void) +void easy_mem_statistics(void) { - uint32_t total = sizeof(mem_total); - uint32_t used = 0; - uint32_t remaining = 0; - DEBUG_PRINT("+---- Easy chunk memory -----\n"); - DEBUG_PRINT("| Total: %d bytes\n", total); - DEBUG_PRINT("| Can be used: %d bytes\n", MAX_CHUNK_NUM*MAX_CHUNK_SIZE); - DEBUG_PRINT("| Used: %d bytes\n", used); - DEBUG_PRINT("| Remaining: %d bytes\n", total-used); - DEBUG_PRINT("| Memory start from: %p\n", mem_memory); - DEBUG_PRINT("+-----------------------\n"); + uint32_t total = sizeof(mem_total); + uint32_t used = 0; + uint32_t remaining = 0; + DEBUG_PRINT("+---- Easy chunk memory -----\n"); + DEBUG_PRINT("| Total: %d bytes\n", total); + DEBUG_PRINT("| Can be used: %d bytes\n", MAX_CHUNK_NUM * MAX_CHUNK_SIZE); + DEBUG_PRINT("| Used: %d bytes\n", used); + DEBUG_PRINT("| Remaining: %d bytes\n", total - used); + DEBUG_PRINT("| Memory start from: %p\n", mem_memory); + DEBUG_PRINT("+-----------------------\n"); } diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c b/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c index 1a8a54b..a3b6e72 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/dhcpserver.c @@ -1,28 +1,29 @@ +#include "dhcpserver.h" + #include -#include "lwip/inet.h" #include "lwip/err.h" -#include "lwip/pbuf.h" +#include "lwip/inet.h" #include "lwip/mem.h" +#include "lwip/pbuf.h" #include "lwip/udp.h" -#include "dhcpserver.h" #define LWIP_OPEN_SRC #ifndef LWIP_OPEN_SRC #include "net80211/ieee80211_var.h" #endif -#include "esp_wifi.h" #include "dhcpserver.h" +#include "esp_wifi.h" #include "tcpip_adapter.h" -extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info* ipinfo); +extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info *ipinfo); // #include "user_interface.h" #define NULL_MODE 0xFF #define DHCP_STARTED 0xFF #define DHCP_STOPPED 0xFF -extern bool wifi_softap_set_station_info(uint8_t* chaddr, ip_addr_t* ipaddr); -extern void* eagle_lwip_getif(uint8 type); +extern bool wifi_softap_set_station_info(uint8_t *chaddr, ip_addr_t *ipaddr); +extern void *eagle_lwip_getif(uint8 type); extern uint8 wifi_softap_dhcps_status(); #define ICACHE_FLASH_ATTR @@ -31,47 +32,53 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif //////////////////////////////////////////////////////////////////////////////////// -//static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; -//static u8_t old_xid[4] = {0}; +// static const uint8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; +// static u8_t old_xid[4] = {0}; static const uint32 magic_cookie ICACHE_FLASH_ATTR = 0x63538263; static struct udp_pcb *pcb_dhcps = NULL; static ip_addr_t broadcast_dhcps; static ip_addr_t server_address; -static ip_addr_t client_address;//added +static ip_addr_t client_address; // added static ip_addr_t client_address_plus; static struct dhcps_lease dhcps_lease; -//static bool dhcps_lease_flag = true; +// static bool dhcps_lease_flag = true; static list_node *plist = NULL; static uint8 offer = 0xFF; static bool renew = false; -#define DHCPS_LEASE_TIME_DEF (120) -uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; //minute +#define DHCPS_LEASE_TIME_DEF (120) +uint32 dhcps_lease_time = DHCPS_LEASE_TIME_DEF; // minute /****************************************************************************** * FunctionName : node_insert_to_list * Description : insert the node to the list * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert) + *******************************************************************************/ +void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node *pinsert) { - list_node *plist = NULL; - struct dhcps_pool *pdhcps_pool = NULL; - struct dhcps_pool *pdhcps_node = NULL; - if (*phead == NULL) - *phead = pinsert; - else { - plist = *phead; - pdhcps_node = pinsert->pnode; - pdhcps_pool = plist->pnode; - - if(pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { - pinsert->pnext = plist; - *phead = pinsert; - } else { - while (plist->pnext != NULL) { + list_node *plist = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + struct dhcps_pool *pdhcps_node = NULL; + if (*phead == NULL) + *phead = pinsert; + else + { + plist = *phead; + pdhcps_node = pinsert->pnode; + pdhcps_pool = plist->pnode; + + if (pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) + { + pinsert->pnext = plist; + *phead = pinsert; + } + else + { + while (plist->pnext != NULL) + { pdhcps_pool = plist->pnext->pnode; - if (pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { + if (pdhcps_node->ip.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) + { pinsert->pnext = plist->pnext; plist->pnext = pinsert; break; @@ -79,12 +86,13 @@ void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert plist = plist->pnext; } - if(plist->pnext == NULL) { + if (plist->pnext == NULL) + { plist->pnext = pinsert; } - } - } -// pinsert->pnext = NULL; + } + } + // pinsert->pnext = NULL; } /****************************************************************************** @@ -92,26 +100,34 @@ void ICACHE_FLASH_ATTR node_insert_to_list(list_node **phead, list_node* pinsert * Description : remove the node from list * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR node_remove_from_list_0(list_node **phead, list_node* pdelete) + *******************************************************************************/ +void ICACHE_FLASH_ATTR node_remove_from_list_0(list_node **phead, list_node *pdelete) { - list_node *plist = NULL; - - plist = *phead; - if (plist == NULL){ - *phead = NULL; - } else { - if (plist == pdelete){ - *phead = plist->pnext; - } else { - while (plist != NULL) { - if (plist->pnext == pdelete){ - plist->pnext = pdelete->pnext; - } - plist = plist->pnext; - } - } - } + list_node *plist = NULL; + + plist = *phead; + if (plist == NULL) + { + *phead = NULL; + } + else + { + if (plist == pdelete) + { + *phead = plist->pnext; + } + else + { + while (plist != NULL) + { + if (plist->pnext == pdelete) + { + plist->pnext = pdelete->pnext; + } + plist = plist->pnext; + } + } + } } /////////////////////////////////////////////////////////////////////////////////// /* @@ -123,13 +139,12 @@ void ICACHE_FLASH_ATTR node_remove_from_list_0(list_node **phead, list_node* pde * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ */ /////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) +static uint8_t *ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) { - - *optptr++ = DHCP_OPTION_MSG_TYPE; - *optptr++ = 1; - *optptr++ = type; - return optptr; + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; } /////////////////////////////////////////////////////////////////////////////////// /* @@ -140,105 +155,106 @@ static uint8_t* ICACHE_FLASH_ATTR add_msg_type(uint8_t *optptr, uint8_t type) * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ */ /////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) +static uint8_t *ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) { - ip_addr_t ipadd; + ip_addr_t ipadd; - ipadd.u_addr.ip4.addr = *( (uint32_t *) &server_address); + ipadd.u_addr.ip4.addr = *((uint32_t *)&server_address); #ifdef USE_CLASS_B_NET - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; //length - *optptr++ = 255; - *optptr++ = 240; - *optptr++ = 0; - *optptr++ = 0; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = 4; // length + *optptr++ = 255; + *optptr++ = 240; + *optptr++ = 0; + *optptr++ = 0; #else - *optptr++ = DHCP_OPTION_SUBNET_MASK; - *optptr++ = 4; - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 0; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = 4; + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 0; #endif - *optptr++ = DHCP_OPTION_LEASE_TIME; - *optptr++ = 4; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; - *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; - - *optptr++ = DHCP_OPTION_SERVER_ID; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr4( &ipadd.u_addr.ip4); - - if (dhcps_router_enabled(offer)){ - struct ip_info if_ip; - bzero(&if_ip, sizeof(struct ip_info)); - wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &if_ip); - - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = 4; - *optptr++ = ip4_addr1( &if_ip.gw); - *optptr++ = ip4_addr2( &if_ip.gw); - *optptr++ = ip4_addr3( &if_ip.gw); - *optptr++ = ip4_addr4( &if_ip.gw); - } + *optptr++ = DHCP_OPTION_LEASE_TIME; + *optptr++ = 4; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 24) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 16) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 8) & 0xFF; + *optptr++ = ((DHCPS_LEASE_TIMER * 60) >> 0) & 0xFF; + + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + *optptr++ = ip4_addr1(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr2(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr3(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr4(&ipadd.u_addr.ip4); + + if (dhcps_router_enabled(offer)) + { + struct ip_info if_ip; + bzero(&if_ip, sizeof(struct ip_info)); + wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &if_ip); + + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = 4; + *optptr++ = ip4_addr1(&if_ip.gw); + *optptr++ = ip4_addr2(&if_ip.gw); + *optptr++ = ip4_addr3(&if_ip.gw); + *optptr++ = ip4_addr4(&if_ip.gw); + } #ifdef USE_DNS - *optptr++ = DHCP_OPTION_DNS_SERVER; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr4( &ipadd.u_addr.ip4); + *optptr++ = DHCP_OPTION_DNS_SERVER; + *optptr++ = 4; + *optptr++ = ip4_addr1(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr2(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr3(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr4(&ipadd.u_addr.ip4); #endif #ifdef CLASS_B_NET - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd); - *optptr++ = 255; - *optptr++ = 255; - *optptr++ = 255; + *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; + *optptr++ = 4; + *optptr++ = ip4_addr1(&ipadd); + *optptr++ = 255; + *optptr++ = 255; + *optptr++ = 255; #else - *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; - *optptr++ = 4; - *optptr++ = ip4_addr1( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr2( &ipadd.u_addr.ip4); - *optptr++ = ip4_addr3( &ipadd.u_addr.ip4); - *optptr++ = 255; + *optptr++ = DHCP_OPTION_BROADCAST_ADDRESS; + *optptr++ = 4; + *optptr++ = ip4_addr1(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr2(&ipadd.u_addr.ip4); + *optptr++ = ip4_addr3(&ipadd.u_addr.ip4); + *optptr++ = 255; #endif - *optptr++ = DHCP_OPTION_INTERFACE_MTU; - *optptr++ = 2; + *optptr++ = DHCP_OPTION_INTERFACE_MTU; + *optptr++ = 2; #ifdef CLASS_B_NET - *optptr++ = 0x05; - *optptr++ = 0xdc; + *optptr++ = 0x05; + *optptr++ = 0xdc; #else - *optptr++ = 0x02; - *optptr++ = 0x40; + *optptr++ = 0x02; + *optptr++ = 0x40; #endif - *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; - *optptr++ = 1; - *optptr++ = 0x00; + *optptr++ = DHCP_OPTION_PERFORM_ROUTER_DISCOVERY; + *optptr++ = 1; + *optptr++ = 0x00; - *optptr++ = 43; - *optptr++ = 6; + *optptr++ = 43; + *optptr++ = 6; - *optptr++ = 0x01; - *optptr++ = 4; - *optptr++ = 0x00; - *optptr++ = 0x00; - *optptr++ = 0x00; - *optptr++ = 0x02; + *optptr++ = 0x01; + *optptr++ = 4; + *optptr++ = 0x00; + *optptr++ = 0x00; + *optptr++ = 0x00; + *optptr++ = 0x02; - return optptr; + return optptr; } /////////////////////////////////////////////////////////////////////////////////// /* @@ -249,38 +265,37 @@ static uint8_t* ICACHE_FLASH_ATTR add_offer_options(uint8_t *optptr) * @return uint8_t* ����DHCP msgƫ�Ƶ�ַ */ /////////////////////////////////////////////////////////////////////////////////// -static uint8_t* ICACHE_FLASH_ATTR add_end(uint8_t *optptr) +static uint8_t *ICACHE_FLASH_ATTR add_end(uint8_t *optptr) { - - *optptr++ = DHCP_OPTION_END; - return optptr; + *optptr++ = DHCP_OPTION_END; + return optptr; } /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) { - ip_addr_t client; + ip_addr_t client; - client.u_addr.ip4.addr = *( (uint32_t *) &client_address); + client.u_addr.ip4.addr = *((uint32_t *)&client_address); - m->op = DHCP_REPLY; - m->htype = DHCP_HTYPE_ETHERNET; - m->hlen = 6; - m->hops = 0; -// memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); - m->secs = 0; - m->flags = htons(BOOTP_BROADCAST); + m->op = DHCP_REPLY; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = 6; + m->hops = 0; + // memcpy((char *) xid, (char *) m->xid, sizeof(m->xid)); + m->secs = 0; + m->flags = htons(BOOTP_BROADCAST); - memcpy((char *) m->yiaddr, (char *) &client.u_addr.ip4.addr, sizeof(m->yiaddr)); + memcpy((char *)m->yiaddr, (char *)&client.u_addr.ip4.addr, sizeof(m->yiaddr)); - memset((char *) m->ciaddr, 0, sizeof(m->ciaddr)); - memset((char *) m->siaddr, 0, sizeof(m->siaddr)); - memset((char *) m->giaddr, 0, sizeof(m->giaddr)); - memset((char *) m->sname, 0, sizeof(m->sname)); - memset((char *) m->file, 0, sizeof(m->file)); + memset((char *)m->ciaddr, 0, sizeof(m->ciaddr)); + memset((char *)m->siaddr, 0, sizeof(m->siaddr)); + memset((char *)m->giaddr, 0, sizeof(m->giaddr)); + memset((char *)m->sname, 0, sizeof(m->sname)); + memset((char *)m->file, 0, sizeof(m->file)); - memset((char *) m->options, 0, sizeof(m->options)); - memcpy((char *) m->options, &magic_cookie, sizeof(magic_cookie)); + memset((char *)m->options, 0, sizeof(m->options)); + memcpy((char *)m->options, &magic_cookie, sizeof(magic_cookie)); } /////////////////////////////////////////////////////////////////////////////////// /* @@ -291,62 +306,66 @@ static void ICACHE_FLASH_ATTR create_msg(struct dhcps_msg *m) /////////////////////////////////////////////////////////////////////////////////// static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) { - uint8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendOffer_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPOFFER); - end = add_offer_options(end); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); + uint8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt = 0; + u16_t i; + err_t SendOffer_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPOFFER); + end = add_offer_options(end); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); #if DHCPS_DEBUG - printf("udhcp: send_offer>>p->ref = %d\n", p->ref); + printf("udhcp: send_offer>>p->ref = %d\n", p->ref); #endif - if(p != NULL){ - + if (p != NULL) + { #if DHCPS_DEBUG - printf("dhcps: send_offer>>pbuf_alloc succeed\n"); - printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_offer>>p->len = %d\n", p->len); + printf("dhcps: send_offer>>pbuf_alloc succeed\n"); + printf("dhcps: send_offer>>p->tot_len = %d\n", p->tot_len); + printf("dhcps: send_offer>>p->len = %d\n", p->len); #endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; + q = p; + while (q != NULL) + { + data = (u8_t *)q->payload; + for (i = 0; i < q->len; i++) + { + data[i] = ((u8_t *)m)[cnt++]; #if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } + printf("%02x ", data[i]); + if ((i + 1) % 16 == 0) + { + printf("\n"); + } #endif - } + } - q = q->next; - } - }else{ - + q = q->next; + } + } + else + { #if DHCPS_DEBUG - printf("dhcps: send_offer>>pbuf_alloc failed\n"); + printf("dhcps: send_offer>>pbuf_alloc failed\n"); #endif - return; - } - SendOffer_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); + return; + } + SendOffer_err_t = udp_sendto(pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT); #if DHCPS_DEBUG - printf("dhcps: send_offer>>udp_sendto result %x\n",SendOffer_err_t); + printf("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t); #endif - if(p->ref != 0){ + if (p->ref != 0) + { #if DHCPS_DEBUG - printf("udhcp: send_offer>>free pbuf\n"); + printf("udhcp: send_offer>>free pbuf\n"); #endif - pbuf_free(p); - } + pbuf_free(p); + } } /////////////////////////////////////////////////////////////////////////////////// /* @@ -357,62 +376,65 @@ static void ICACHE_FLASH_ATTR send_offer(struct dhcps_msg *m) /////////////////////////////////////////////////////////////////////////////////// static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) { - - u8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendNak_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPNAK); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); + u8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt = 0; + u16_t i; + err_t SendNak_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPNAK); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); #if DHCPS_DEBUG - printf("udhcp: send_nak>>p->ref = %d\n", p->ref); + printf("udhcp: send_nak>>p->ref = %d\n", p->ref); #endif - if(p != NULL){ - + if (p != NULL) + { #if DHCPS_DEBUG - printf("dhcps: send_nak>>pbuf_alloc succeed\n"); - printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_nak>>p->len = %d\n", p->len); + printf("dhcps: send_nak>>pbuf_alloc succeed\n"); + printf("dhcps: send_nak>>p->tot_len = %d\n", p->tot_len); + printf("dhcps: send_nak>>p->len = %d\n", p->len); #endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } + q = p; + while (q != NULL) + { + data = (u8_t *)q->payload; + for (i = 0; i < q->len; i++) + { + data[i] = ((u8_t *)m)[cnt++]; +#if DHCPS_DEBUG + printf("%02x ", data[i]); + if ((i + 1) % 16 == 0) + { + printf("\n"); + } #endif - } + } - q = q->next; - } - }else{ - + q = q->next; + } + } + else + { #if DHCPS_DEBUG - printf("dhcps: send_nak>>pbuf_alloc failed\n"); + printf("dhcps: send_nak>>pbuf_alloc failed\n"); #endif - return; - } - SendNak_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); + return; + } + SendNak_err_t = udp_sendto(pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT); #if DHCPS_DEBUG - printf("dhcps: send_nak>>udp_sendto result %x\n",SendNak_err_t); + printf("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t); #endif - if(p->ref != 0){ -#if DHCPS_DEBUG - printf("udhcp: send_nak>>free pbuf\n"); + if (p->ref != 0) + { +#if DHCPS_DEBUG + printf("udhcp: send_nak>>free pbuf\n"); #endif - pbuf_free(p); - } + pbuf_free(p); + } } /////////////////////////////////////////////////////////////////////////////////// /* @@ -423,64 +445,67 @@ static void ICACHE_FLASH_ATTR send_nak(struct dhcps_msg *m) /////////////////////////////////////////////////////////////////////////////////// static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) { - - u8_t *end; - struct pbuf *p, *q; - u8_t *data; - u16_t cnt=0; - u16_t i; - err_t SendAck_err_t; - create_msg(m); - - end = add_msg_type(&m->options[4], DHCPACK); - end = add_offer_options(end); - end = add_end(end); - - p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); + u8_t *end; + struct pbuf *p, *q; + u8_t *data; + u16_t cnt = 0; + u16_t i; + err_t SendAck_err_t; + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPACK); + end = add_offer_options(end); + end = add_end(end); + + p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcps_msg), PBUF_RAM); #if DHCPS_DEBUG - printf("udhcp: send_ack>>p->ref = %d\n", p->ref); + printf("udhcp: send_ack>>p->ref = %d\n", p->ref); #endif - if(p != NULL){ - + if (p != NULL) + { #if DHCPS_DEBUG - printf("dhcps: send_ack>>pbuf_alloc succeed\n"); - printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); - printf("dhcps: send_ack>>p->len = %d\n", p->len); + printf("dhcps: send_ack>>pbuf_alloc succeed\n"); + printf("dhcps: send_ack>>p->tot_len = %d\n", p->tot_len); + printf("dhcps: send_ack>>p->len = %d\n", p->len); #endif - q = p; - while(q != NULL){ - data = (u8_t *)q->payload; - for(i=0; ilen; i++) - { - data[i] = ((u8_t *) m)[cnt++]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } + q = p; + while (q != NULL) + { + data = (u8_t *)q->payload; + for (i = 0; i < q->len; i++) + { + data[i] = ((u8_t *)m)[cnt++]; +#if DHCPS_DEBUG + printf("%02x ", data[i]); + if ((i + 1) % 16 == 0) + { + printf("\n"); + } #endif - } + } - q = q->next; - } - }else{ - + q = q->next; + } + } + else + { #if DHCPS_DEBUG - printf("dhcps: send_ack>>pbuf_alloc failed\n"); + printf("dhcps: send_ack>>pbuf_alloc failed\n"); #endif - return; - } - SendAck_err_t = udp_sendto( pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT ); + return; + } + SendAck_err_t = udp_sendto(pcb_dhcps, p, &broadcast_dhcps, DHCPS_CLIENT_PORT); #if DHCPS_DEBUG - printf("dhcps: send_ack>>udp_sendto result %x\n",SendAck_err_t); + printf("dhcps: send_ack>>udp_sendto result %x\n", SendAck_err_t); #endif - - if(p->ref != 0){ + + if (p->ref != 0) + { #if DHCPS_DEBUG - printf("udhcp: send_ack>>free pbuf\n"); + printf("udhcp: send_ack>>free pbuf\n"); #endif - pbuf_free(p); - } + pbuf_free(p); + } } /////////////////////////////////////////////////////////////////////////////////// /* @@ -494,250 +519,289 @@ static void ICACHE_FLASH_ATTR send_ack(struct dhcps_msg *m) /////////////////////////////////////////////////////////////////////////////////// static uint8_t ICACHE_FLASH_ATTR parse_options(uint8_t *optptr, sint16_t len) { - ip_addr_t client; - bool is_dhcp_parse_end = false; - struct dhcps_state s; + ip_addr_t client; + bool is_dhcp_parse_end = false; + struct dhcps_state s; - client.u_addr.ip4.addr = *( (uint32_t *) &client_address);// Ҫ�����DHCP�ͻ��˵�IP + client.u_addr.ip4.addr = *((uint32_t *)&client_address); // Ҫ�����DHCP�ͻ��˵�IP - u8_t *end = optptr + len; - u16_t type = 0; + u8_t *end = optptr + len; + u16_t type = 0; - s.state = DHCPS_STATE_IDLE; + s.state = DHCPS_STATE_IDLE; - while (optptr < end) { + while (optptr < end) + { #if DHCPS_DEBUG - printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); + printf("dhcps: (sint16_t)*optptr = %d\n", (sint16_t)*optptr); #endif - switch ((sint16_t) *optptr) { - - case DHCP_OPTION_MSG_TYPE: //53 - type = *(optptr + 2); - break; + switch ((sint16_t)*optptr) + { + case DHCP_OPTION_MSG_TYPE: // 53 + type = *(optptr + 2); + break; - case DHCP_OPTION_REQ_IPADDR://50 - if( memcmp( (char *) &client.u_addr.ip4.addr, (char *) optptr+2,4)==0 ) { + case DHCP_OPTION_REQ_IPADDR: // 50 + if (memcmp((char *)&client.u_addr.ip4.addr, (char *)optptr + 2, 4) == 0) + { #if DHCPS_DEBUG - printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); + printf("dhcps: DHCP_OPTION_REQ_IPADDR = 0 ok\n"); #endif - s.state = DHCPS_STATE_ACK; - }else { + s.state = DHCPS_STATE_ACK; + } + else + { #if DHCPS_DEBUG - printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); + printf("dhcps: DHCP_OPTION_REQ_IPADDR != 0 err\n"); #endif - s.state = DHCPS_STATE_NAK; - } - break; - case DHCP_OPTION_END: - { - is_dhcp_parse_end = true; - } - break; + s.state = DHCPS_STATE_NAK; + } + break; + case DHCP_OPTION_END: + { + is_dhcp_parse_end = true; } + break; + } - if(is_dhcp_parse_end){ - break; - } - - optptr += optptr[1] + 2; + if (is_dhcp_parse_end) + { + break; } - switch (type){ - - case DHCPDISCOVER://1 - s.state = DHCPS_STATE_OFFER; -#if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_OFFER\n"); -#endif - break; + optptr += optptr[1] + 2; + } - case DHCPREQUEST://3 - if ( !(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK) ) { - if(renew == true) { - s.state = DHCPS_STATE_ACK; - } else { - s.state = DHCPS_STATE_NAK; - } + switch (type) + { + case DHCPDISCOVER: // 1 + s.state = DHCPS_STATE_OFFER; #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_NAK\n"); + printf("dhcps: DHCPD_STATE_OFFER\n"); #endif + break; + + case DHCPREQUEST: // 3 + if (!(s.state == DHCPS_STATE_ACK || s.state == DHCPS_STATE_NAK)) + { + if (renew == true) + { + s.state = DHCPS_STATE_ACK; } - break; + else + { + s.state = DHCPS_STATE_NAK; + } +#if DHCPS_DEBUG + printf("dhcps: DHCPD_STATE_NAK\n"); +#endif + } + break; - case DHCPDECLINE://4 - s.state = DHCPS_STATE_IDLE; + case DHCPDECLINE: // 4 + s.state = DHCPS_STATE_IDLE; #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_IDLE\n"); + printf("dhcps: DHCPD_STATE_IDLE\n"); #endif - break; + break; - case DHCPRELEASE://7 - s.state = DHCPS_STATE_RELEASE; + case DHCPRELEASE: // 7 + s.state = DHCPS_STATE_RELEASE; #if DHCPS_DEBUG - printf("dhcps: DHCPD_STATE_IDLE\n"); + printf("dhcps: DHCPD_STATE_IDLE\n"); #endif - break; - } + break; + } #if DHCPS_DEBUG - printf("dhcps: return s.state = %d\n", s.state); + printf("dhcps: return s.state = %d\n", s.state); #endif - return s.state; + return s.state; } /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) { - if(memcmp((char *)m->options, - &magic_cookie, - sizeof(magic_cookie)) == 0){ + if (memcmp((char *)m->options, &magic_cookie, sizeof(magic_cookie)) == 0) + { #if DHCPS_DEBUG - printf("dhcps: len = %d\n", len); + printf("dhcps: len = %d\n", len); #endif - /* - * ��¼��ǰ��xid���ﴦ���? - * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� - */ -// if((old_xid[0] == 0) && -// (old_xid[1] == 0) && -// (old_xid[2] == 0) && -// (old_xid[3] == 0)){ -// /* -// * old_xidδ��¼�κ����? -// * �϶��ǵ�һ��ʹ�� -// */ -// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); -// }else{ -// /* -// * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� -// * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP -// * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) -// * -// */ -// if(memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ - /* - * ��¼���ε�xid�ţ�ͬʱ�����IP���� - */ - ip_addr_t addr_tmp; -// memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); - -// { - struct dhcps_pool *pdhcps_pool = NULL; - list_node *pnode = NULL; - list_node *pback_node = NULL; - ip_addr_t first_address; - bool flag = false; - -// POOL_START: - first_address.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; - renew = false; -// addr_tmp.addr = htonl(client_address_plus.addr); -// addr_tmp.addr++; -// client_address_plus.addr = htonl(addr_tmp.addr); - for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { - pdhcps_pool = pback_node->pnode; - if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){ -// printf("the same device request ip\n"); - if (memcmp(&pdhcps_pool->ip.u_addr.ip4.addr, m->ciaddr, sizeof(pdhcps_pool->ip.u_addr.ip4.addr)) == 0) { - renew = true; - } - client_address.u_addr.ip4.addr = pdhcps_pool->ip.u_addr.ip4.addr; - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; - pnode = pback_node; - goto POOL_CHECK; - } else if (pdhcps_pool->ip.u_addr.ip4.addr == client_address_plus.u_addr.ip4.addr){ -// client_address.addr = client_address_plus.addr; -// printf("the ip addr has been request\n"); - addr_tmp.u_addr.ip4.addr = htonl(client_address_plus.u_addr.ip4.addr); - addr_tmp.u_addr.ip4.addr++; - client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); - client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; - } - - if(flag == false) { // search the fisrt unused ip - if(first_address.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) { - flag = true; - } else { - addr_tmp.u_addr.ip4.addr = htonl(first_address.u_addr.ip4.addr); - addr_tmp.u_addr.ip4.addr++; - first_address.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); - } - } - } - if (client_address_plus.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) { - client_address.u_addr.ip4.addr = first_address.u_addr.ip4.addr; - } - if (client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) { - client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - pdhcps_pool = NULL; - pnode = NULL; - } else { - pdhcps_pool = (struct dhcps_pool *)malloc(sizeof(struct dhcps_pool)); - pdhcps_pool->ip.u_addr.ip4.addr = client_address.u_addr.ip4.addr; - memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); - pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; - pnode = (list_node *)malloc(sizeof(list_node )); - pnode->pnode = pdhcps_pool; - pnode->pnext = NULL; - node_insert_to_list(&plist,pnode); - if (client_address.u_addr.ip4.addr == dhcps_lease.end_ip.u_addr.ip4.addr) { - client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - } else { - addr_tmp.u_addr.ip4.addr = htonl(client_address.u_addr.ip4.addr); - addr_tmp.u_addr.ip4.addr++; - client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); - } - } - - POOL_CHECK: - if ((client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) || (ip_addr_isany(&client_address))){ - printf("client_address_plus.addr %x\n", client_address_plus.u_addr.ip4.addr); - if(pnode != NULL) { - node_remove_from_list_0(&plist,pnode); - free(pnode); - pnode = NULL; - } - - if (pdhcps_pool != NULL) { - free(pdhcps_pool); - pdhcps_pool = NULL; - } -// client_address_plus.addr = dhcps_lease.start_ip.addr; - return 4; - } - - sint16_t ret = parse_options(&m->options[4], len);; - - if(ret == DHCPS_STATE_RELEASE) { - if(pnode != NULL) { - node_remove_from_list_0(&plist,pnode); - free(pnode); - pnode = NULL; - } - - if (pdhcps_pool != NULL) { - free(pdhcps_pool); - pdhcps_pool = NULL; - } - memset(&client_address,0x0,sizeof(client_address)); - } - - if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { - return 0; - } -// } + /* + * ��¼��ǰ��xid���ﴦ���? + * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� + */ + // if((old_xid[0] == 0) && + // (old_xid[1] == 0) && + // (old_xid[2] == 0) && + // (old_xid[3] == 0)){ + // /* + // * old_xidδ��¼�κ����? + // * �϶��ǵ�һ��ʹ�� + // */ + // memcpy((char *)old_xid, (char *)m->xid, + // sizeof(m->xid)); }else{ + // /* + // * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� + // * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP + // * ���� 192.168.4.100(0x6404A8C0) <--> + // 192.168.4.200(0xC804A8C0) + // * + // */ + // if(memcmp((char *)old_xid, (char *)m->xid, + // sizeof(m->xid)) != 0){ + /* + * ��¼���ε�xid�ţ�ͬʱ�����IP���� + */ + ip_addr_t addr_tmp; + // memcpy((char *)old_xid, (char *)m->xid, + // sizeof(m->xid)); + + // { + struct dhcps_pool *pdhcps_pool = NULL; + list_node *pnode = NULL; + list_node *pback_node = NULL; + ip_addr_t first_address; + bool flag = false; + + // POOL_START: + first_address.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; + renew = false; + // addr_tmp.addr = + // htonl(client_address_plus.addr); + // addr_tmp.addr++; client_address_plus.addr = + // htonl(addr_tmp.addr); + for (pback_node = plist; pback_node != NULL; pback_node = pback_node->pnext) + { + pdhcps_pool = pback_node->pnode; + if (memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0) + { + // printf("the + // same device request ip\n"); + if (memcmp(&pdhcps_pool->ip.u_addr.ip4.addr, m->ciaddr, sizeof(pdhcps_pool->ip.u_addr.ip4.addr)) == 0) + { + renew = true; + } + client_address.u_addr.ip4.addr = pdhcps_pool->ip.u_addr.ip4.addr; + pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pnode = pback_node; + goto POOL_CHECK; + } + else if (pdhcps_pool->ip.u_addr.ip4.addr == client_address_plus.u_addr.ip4.addr) + { + // client_address.addr + //= client_address_plus.addr; + // printf("the ip addr has been request\n"); + addr_tmp.u_addr.ip4.addr = htonl(client_address_plus.u_addr.ip4.addr); + addr_tmp.u_addr.ip4.addr++; + client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); + client_address.u_addr.ip4.addr = client_address_plus.u_addr.ip4.addr; + } + + if (flag == false) + { // search the fisrt unused ip + if (first_address.u_addr.ip4.addr < pdhcps_pool->ip.u_addr.ip4.addr) + { + flag = true; + } + else + { + addr_tmp.u_addr.ip4.addr = htonl(first_address.u_addr.ip4.addr); + addr_tmp.u_addr.ip4.addr++; + first_address.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); + } + } + } + if (client_address_plus.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) + { + client_address.u_addr.ip4.addr = first_address.u_addr.ip4.addr; + } + if (client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) + { + client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + pdhcps_pool = NULL; + pnode = NULL; + } + else + { + pdhcps_pool = (struct dhcps_pool *)malloc(sizeof(struct dhcps_pool)); + pdhcps_pool->ip.u_addr.ip4.addr = client_address.u_addr.ip4.addr; + memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); + pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; + pnode = (list_node *)malloc(sizeof(list_node)); + pnode->pnode = pdhcps_pool; + pnode->pnext = NULL; + node_insert_to_list(&plist, pnode); + if (client_address.u_addr.ip4.addr == dhcps_lease.end_ip.u_addr.ip4.addr) + { + client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + } + else + { + addr_tmp.u_addr.ip4.addr = htonl(client_address.u_addr.ip4.addr); + addr_tmp.u_addr.ip4.addr++; + client_address_plus.u_addr.ip4.addr = htonl(addr_tmp.u_addr.ip4.addr); + } + } + + POOL_CHECK: + if ((client_address.u_addr.ip4.addr > dhcps_lease.end_ip.u_addr.ip4.addr) || (ip_addr_isany(&client_address))) + { + printf("client_address_plus.addr %x\n", client_address_plus.u_addr.ip4.addr); + if (pnode != NULL) + { + node_remove_from_list_0(&plist, pnode); + free(pnode); + pnode = NULL; + } + + if (pdhcps_pool != NULL) + { + free(pdhcps_pool); + pdhcps_pool = NULL; + } + // client_address_plus.addr + //= dhcps_lease.start_ip.addr; + return 4; + } + + sint16_t ret = parse_options(&m->options[4], len); + ; + + if (ret == DHCPS_STATE_RELEASE) + { + if (pnode != NULL) + { + node_remove_from_list_0(&plist, pnode); + free(pnode); + pnode = NULL; + } + + if (pdhcps_pool != NULL) + { + free(pdhcps_pool); + pdhcps_pool = NULL; + } + memset(&client_address, 0x0, sizeof(client_address)); + } + + if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) + { + return 0; + } + // } #if DHCPS_DEBUG - printf("dhcps: xid changed\n"); - printf("dhcps: client_address.addr = %x\n", client_address.addr); + printf("dhcps: xid changed\n"); + printf("dhcps: client_address.addr = %x\n", client_address.addr); #endif - -// } - -// } - return ret; - } - return 0; + + // } + + // } + return ret; + } + return 0; } /////////////////////////////////////////////////////////////////////////////////// /* @@ -751,202 +815,218 @@ static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) * @param port ���ʹ�UDP���Դ�����UDPͨ���˿ں� */ /////////////////////////////////////////////////////////////////////////////////// -static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, - struct udp_pcb *pcb, - struct pbuf *p, - const ip_addr_t *addr, - uint16_t port) +static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, + uint16_t port) { - struct dhcps_msg *pmsg_dhcps = NULL; - sint16_t tlen = 0; - u16_t i = 0; - u16_t dhcps_msg_cnt = 0; - u8_t *p_dhcps_msg = NULL; - u8_t *data = NULL; + struct dhcps_msg *pmsg_dhcps = NULL; + sint16_t tlen = 0; + u16_t i = 0; + u16_t dhcps_msg_cnt = 0; + u8_t *p_dhcps_msg = NULL; + u8_t *data = NULL; + +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> receive a packet\n"); +#endif + if (p == NULL) + return; + + pmsg_dhcps = (struct dhcps_msg *)malloc(sizeof(struct dhcps_msg)); + if (NULL == pmsg_dhcps) + { + pbuf_free(p); + return; + } + p_dhcps_msg = (u8_t *)pmsg_dhcps; + tlen = p->tot_len; + data = p->payload; #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> receive a packet\n"); + printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); + printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); #endif - if (p==NULL) return; - pmsg_dhcps = (struct dhcps_msg *)malloc(sizeof(struct dhcps_msg)); - if (NULL == pmsg_dhcps){ - pbuf_free(p); - return; - } - p_dhcps_msg = (u8_t *)pmsg_dhcps; - tlen = p->tot_len; - data = p->payload; + for (i = 0; i < p->len; i++) + { + p_dhcps_msg[dhcps_msg_cnt++] = data[i]; +#if DHCPS_DEBUG + printf("%02x ", data[i]); + if ((i + 1) % 16 == 0) + { + printf("\n"); + } +#endif + } + if (p->next != NULL) + { #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); - printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); -#endif - - for(i=0; ilen; i++){ - p_dhcps_msg[dhcps_msg_cnt++] = data[i]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } + printf("dhcps: handle_dhcp-> p->next != NULL\n"); + printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n", p->next->tot_len); + printf("dhcps: handle_dhcp-> p->next->len = %d\n", p->next->len); #endif - } - - if(p->next != NULL) { + + data = p->next->payload; + for (i = 0; i < p->next->len; i++) + { + p_dhcps_msg[dhcps_msg_cnt++] = data[i]; #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> p->next != NULL\n"); - printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len); - printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); + printf("%02x ", data[i]); + if ((i + 1) % 16 == 0) + { + printf("\n"); + } #endif - - data = p->next->payload; - for(i=0; inext->len; i++){ - p_dhcps_msg[dhcps_msg_cnt++] = data[i]; -#if DHCPS_DEBUG - printf("%02x ",data[i]); - if((i+1)%16 == 0){ - printf("\n"); - } + } + } + + /* + * DHCP �ͻ���������Ϣ���� + */ +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> parse_msg(p)\n"); #endif - } - } - /* - * DHCP �ͻ���������Ϣ���� - */ + switch (parse_msg(pmsg_dhcps, tlen - 240)) + { + case DHCPS_STATE_OFFER: // 1 #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> parse_msg(p)\n"); + printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); #endif - - switch(parse_msg(pmsg_dhcps, tlen - 240)) { - - case DHCPS_STATE_OFFER://1 -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); -#endif - send_offer(pmsg_dhcps); - break; - case DHCPS_STATE_ACK://3 + send_offer(pmsg_dhcps); + break; + case DHCPS_STATE_ACK: // 3 #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); -#endif - send_ack(pmsg_dhcps); - break; - case DHCPS_STATE_NAK://4 -#if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); + printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); #endif - send_nak(pmsg_dhcps); - break; - default : - break; - } + send_ack(pmsg_dhcps); + break; + case DHCPS_STATE_NAK: // 4 #if DHCPS_DEBUG - printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); + printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); #endif - pbuf_free(p); - free(pmsg_dhcps); - pmsg_dhcps = NULL; + send_nak(pmsg_dhcps); + break; + default: + break; + } +#if DHCPS_DEBUG + printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); +#endif + pbuf_free(p); + free(pmsg_dhcps); + pmsg_dhcps = NULL; } /////////////////////////////////////////////////////////////////////////////////// static void ICACHE_FLASH_ATTR wifi_softap_init_dhcps_lease(uint32 ip) { - uint32 softap_ip = 0,local_ip = 0; - uint32 start_ip = 0; - uint32 end_ip = 0; -// if (dhcps_lease_flag) { - if (dhcps_lease.enable == true) { - softap_ip = htonl(ip); - start_ip = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); - end_ip = htonl(dhcps_lease.end_ip.u_addr.ip4.addr); - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) { - dhcps_lease.enable = false; - } else { - /*config ip information must be in the same segment as the local ip*/ - softap_ip >>= 8; - if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) - || (end_ip - start_ip > DHCPS_MAX_LEASE)) { - dhcps_lease.enable = false; - } - } - } - - if (dhcps_lease.enable == false) { - local_ip = softap_ip = htonl(ip); - softap_ip &= 0xFFFFFF00; - local_ip &= 0xFF; - if (local_ip >= 0x80) - local_ip -= DHCPS_MAX_LEASE; - else - local_ip ++; - - bzero(&dhcps_lease, sizeof(dhcps_lease)); - dhcps_lease.start_ip.u_addr.ip4.addr = softap_ip | local_ip; - dhcps_lease.end_ip.u_addr.ip4.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); - dhcps_lease.start_ip.u_addr.ip4.addr = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); - dhcps_lease.end_ip.u_addr.ip4.addr= htonl(dhcps_lease.end_ip.u_addr.ip4.addr); - } -// dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); -// dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); -// printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, dhcps_lease.end_ip); + uint32 softap_ip = 0, local_ip = 0; + uint32 start_ip = 0; + uint32 end_ip = 0; + // if (dhcps_lease_flag) { + if (dhcps_lease.enable == true) + { + softap_ip = htonl(ip); + start_ip = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); + end_ip = htonl(dhcps_lease.end_ip.u_addr.ip4.addr); + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) + { + dhcps_lease.enable = false; + } + else + { + /*config ip information must be in the same segment as the local + * ip*/ + softap_ip >>= 8; + if (((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) || (end_ip - start_ip > DHCPS_MAX_LEASE)) + { + dhcps_lease.enable = false; + } + } + } + + if (dhcps_lease.enable == false) + { + local_ip = softap_ip = htonl(ip); + softap_ip &= 0xFFFFFF00; + local_ip &= 0xFF; + if (local_ip >= 0x80) + local_ip -= DHCPS_MAX_LEASE; + else + local_ip++; + + bzero(&dhcps_lease, sizeof(dhcps_lease)); + dhcps_lease.start_ip.u_addr.ip4.addr = softap_ip | local_ip; + dhcps_lease.end_ip.u_addr.ip4.addr = softap_ip | (local_ip + DHCPS_MAX_LEASE - 1); + dhcps_lease.start_ip.u_addr.ip4.addr = htonl(dhcps_lease.start_ip.u_addr.ip4.addr); + dhcps_lease.end_ip.u_addr.ip4.addr = htonl(dhcps_lease.end_ip.u_addr.ip4.addr); + } + // dhcps_lease.start_ip.addr = htonl(dhcps_lease.start_ip.addr); + // dhcps_lease.end_ip.addr= htonl(dhcps_lease.end_ip.addr); + // printf("start_ip = 0x%x, end_ip = 0x%x\n",dhcps_lease.start_ip, + // dhcps_lease.end_ip); } /////////////////////////////////////////////////////////////////////////////////// void ICACHE_FLASH_ATTR espconn_dhcps_start(struct ip_info *info) { - struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); - - if(apnetif->dhcps_pcb != NULL) { + struct netif *apnetif = (struct netif *)eagle_lwip_getif(0x01); + + if (apnetif->dhcps_pcb != NULL) + { udp_remove(apnetif->dhcps_pcb); } - pcb_dhcps = udp_new(); - if (pcb_dhcps == NULL || info ==NULL) { - printf("dhcps_start(): could not obtain pcb\n"); - } + pcb_dhcps = udp_new(); + if (pcb_dhcps == NULL || info == NULL) + { + printf("dhcps_start(): could not obtain pcb\n"); + } - apnetif->dhcps_pcb = pcb_dhcps; + apnetif->dhcps_pcb = pcb_dhcps; - IP4_ADDR(&broadcast_dhcps.u_addr.ip4, 255, 255, 255, 255); + IP4_ADDR(&broadcast_dhcps.u_addr.ip4, 255, 255, 255, 255); - server_address.u_addr.ip4.addr = info->ip.addr; - wifi_softap_init_dhcps_lease(server_address.u_addr.ip4.addr); - client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + server_address.u_addr.ip4.addr = info->ip.addr; + wifi_softap_init_dhcps_lease(server_address.u_addr.ip4.addr); + client_address_plus.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); + udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT); - udp_recv(pcb_dhcps, &handle_dhcp, NULL); + udp_recv(pcb_dhcps, &handle_dhcp, NULL); #if DHCPS_DEBUG - printf("dhcps:dhcps_start->udp_recv function Set a receive callback handle_dhcp for UDP_PCB pcb_dhcps\n"); + printf( + "dhcps:dhcps_start->udp_recv function Set a receive callback " + "handle_dhcp for UDP_PCB pcb_dhcps\n"); #endif - } void ICACHE_FLASH_ATTR espconn_dhcps_stop(void) { - struct netif * apnetif = (struct netif *)eagle_lwip_getif(0x01); + struct netif *apnetif = (struct netif *)eagle_lwip_getif(0x01); - udp_disconnect(pcb_dhcps); -// dhcps_lease_flag = true; - if(apnetif->dhcps_pcb != NULL) { + udp_disconnect(pcb_dhcps); + // dhcps_lease_flag = true; + if (apnetif->dhcps_pcb != NULL) + { udp_remove(apnetif->dhcps_pcb); apnetif->dhcps_pcb = NULL; } - //udp_remove(pcb_dhcps); - list_node *pnode = NULL; - list_node *pback_node = NULL; - pnode = plist; - while (pnode != NULL) { - pback_node = pnode; - pnode = pback_node->pnext; - node_remove_from_list_0(&plist, pback_node); - free(pback_node->pnode); - pback_node->pnode = NULL; - free(pback_node); - pback_node = NULL; - } + // udp_remove(pcb_dhcps); + list_node *pnode = NULL; + list_node *pback_node = NULL; + pnode = plist; + while (pnode != NULL) + { + pback_node = pnode; + pnode = pback_node->pnext; + node_remove_from_list_0(&plist, pback_node); + free(pback_node->pnode); + pback_node->pnode = NULL; + free(pback_node); + pback_node = NULL; + } } /****************************************************************************** @@ -955,53 +1035,55 @@ void ICACHE_FLASH_ATTR espconn_dhcps_stop(void) * Parameters : please -- Additional argument to set the lease information, * Little-Endian. * Returns : true or false -*******************************************************************************/ + *******************************************************************************/ bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) { - struct ip_info info; - uint32 softap_ip = 0; - uint32 start_ip = 0; - uint32 end_ip = 0; - - uint8 opmode = esp_wifi_get_mode(NULL); - - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { - return false; - } - - if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) - return false; - - if(please->enable) { - bzero(&info, sizeof(struct ip_info)); - wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &info); - softap_ip = htonl(info.ip.addr); - start_ip = htonl(please->start_ip.u_addr.ip4.addr); - end_ip = htonl(please->end_ip.u_addr.ip4.addr); - - /*config ip information can't contain local ip*/ - if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) - return false; - - /*config ip information must be in the same segment as the local ip*/ - softap_ip >>= 8; - if ((start_ip >> 8 != softap_ip) - || (end_ip >> 8 != softap_ip)) { - return false; - } - - if (end_ip - start_ip > DHCPS_MAX_LEASE) - return false; - - bzero(&dhcps_lease, sizeof(dhcps_lease)); -// dhcps_lease.start_ip.addr = start_ip; -// dhcps_lease.end_ip.addr = end_ip; - dhcps_lease.start_ip.u_addr.ip4.addr = please->start_ip.u_addr.ip4.addr; - dhcps_lease.end_ip.u_addr.ip4.addr = please->end_ip.u_addr.ip4.addr; - } - dhcps_lease.enable = please->enable; -// dhcps_lease_flag = false; - return true; + struct ip_info info; + uint32 softap_ip = 0; + uint32 start_ip = 0; + uint32 end_ip = 0; + + uint8 opmode = esp_wifi_get_mode(NULL); + + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) + { + return false; + } + + if (please == NULL || wifi_softap_dhcps_status() == DHCP_STARTED) + return false; + + if (please->enable) + { + bzero(&info, sizeof(struct ip_info)); + wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &info); + softap_ip = htonl(info.ip.addr); + start_ip = htonl(please->start_ip.u_addr.ip4.addr); + end_ip = htonl(please->end_ip.u_addr.ip4.addr); + + /*config ip information can't contain local ip*/ + if ((start_ip <= softap_ip) && (softap_ip <= end_ip)) + return false; + + /*config ip information must be in the same segment as the local ip*/ + softap_ip >>= 8; + if ((start_ip >> 8 != softap_ip) || (end_ip >> 8 != softap_ip)) + { + return false; + } + + if (end_ip - start_ip > DHCPS_MAX_LEASE) + return false; + + bzero(&dhcps_lease, sizeof(dhcps_lease)); + // dhcps_lease.start_ip.addr = start_ip; + // dhcps_lease.end_ip.addr = end_ip; + dhcps_lease.start_ip.u_addr.ip4.addr = please->start_ip.u_addr.ip4.addr; + dhcps_lease.end_ip.u_addr.ip4.addr = please->end_ip.u_addr.ip4.addr; + } + dhcps_lease.enable = please->enable; + // dhcps_lease_flag = false; + return true; } /****************************************************************************** @@ -1010,129 +1092,144 @@ bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease(struct dhcps_lease *please) * Parameters : please -- Additional argument to get the lease information, * Little-Endian. * Returns : true or false -*******************************************************************************/ + *******************************************************************************/ bool ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease(struct dhcps_lease *please) { - uint8 opmode = esp_wifi_get_mode(NULL); - - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { - return false; - } - - if (NULL == please) - return false; - -// if (dhcps_lease_flag){ - if (dhcps_lease.enable == false){ - if (wifi_softap_dhcps_status() == DHCP_STOPPED) - return false; - } else { -// bzero(please, sizeof(dhcps_lease)); -// if (wifi_softap_dhcps_status() == DHCP_STOPPED){ -// please->start_ip.addr = htonl(dhcps_lease.start_ip.addr); -// please->end_ip.addr = htonl(dhcps_lease.end_ip.addr); -// } - } - -// if (wifi_softap_dhcps_status() == DHCP_STARTED){ -// bzero(please, sizeof(dhcps_lease)); -// please->start_ip.addr = dhcps_lease.start_ip.addr; -// please->end_ip.addr = dhcps_lease.end_ip.addr; -// } - please->start_ip.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; - please->end_ip.u_addr.ip4.addr = dhcps_lease.end_ip.u_addr.ip4.addr; - return true; + uint8 opmode = esp_wifi_get_mode(NULL); + + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) + { + return false; + } + + if (NULL == please) + return false; + + // if (dhcps_lease_flag){ + if (dhcps_lease.enable == false) + { + if (wifi_softap_dhcps_status() == DHCP_STOPPED) + return false; + } + else + { + // bzero(please, sizeof(dhcps_lease)); + // if (wifi_softap_dhcps_status() == DHCP_STOPPED){ + // please->start_ip.addr = + // htonl(dhcps_lease.start_ip.addr); please->end_ip.addr + // = htonl(dhcps_lease.end_ip.addr); + // } + } + + // if (wifi_softap_dhcps_status() == DHCP_STARTED){ + // bzero(please, sizeof(dhcps_lease)); + // please->start_ip.addr = dhcps_lease.start_ip.addr; + // please->end_ip.addr = dhcps_lease.end_ip.addr; + // } + please->start_ip.u_addr.ip4.addr = dhcps_lease.start_ip.u_addr.ip4.addr; + please->end_ip.u_addr.ip4.addr = dhcps_lease.end_ip.u_addr.ip4.addr; + return true; } static void ICACHE_FLASH_ATTR kill_oldest_dhcps_pool(void) { - list_node *pre = NULL, *p = NULL; - list_node *minpre = NULL, *minp = NULL; - struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; - pre = plist; - p = pre->pnext; - minpre = pre; - minp = p; - while (p != NULL){ - pdhcps_pool = p->pnode; - pmin_pool = minp->pnode; - if (pdhcps_pool->lease_timer < pmin_pool->lease_timer){ - minp = p; - minpre = pre; - } - pre = p; - p = p->pnext; - } - minpre->pnext = minp->pnext; - free(minp->pnode); - minp->pnode = NULL; - free(minp); - minp = NULL; + list_node *pre = NULL, *p = NULL; + list_node *minpre = NULL, *minp = NULL; + struct dhcps_pool *pdhcps_pool = NULL, *pmin_pool = NULL; + pre = plist; + p = pre->pnext; + minpre = pre; + minp = p; + while (p != NULL) + { + pdhcps_pool = p->pnode; + pmin_pool = minp->pnode; + if (pdhcps_pool->lease_timer < pmin_pool->lease_timer) + { + minp = p; + minpre = pre; + } + pre = p; + p = p->pnext; + } + minpre->pnext = minp->pnext; + free(minp->pnode); + minp->pnode = NULL; + free(minp); + minp = NULL; } void ICACHE_FLASH_ATTR dhcps_coarse_tmr(void) { - uint8 num_dhcps_pool = 0; - list_node *pback_node = NULL; - list_node *pnode = NULL; - struct dhcps_pool *pdhcps_pool = NULL; - pnode = plist; - while (pnode != NULL) { - pdhcps_pool = pnode->pnode; - pdhcps_pool->lease_timer --; - if (pdhcps_pool->lease_timer == 0){ - pback_node = pnode; - pnode = pback_node->pnext; - node_remove_from_list_0(&plist,pback_node); - free(pback_node->pnode); - pback_node->pnode = NULL; - free(pback_node); - pback_node = NULL; - } else { - pnode = pnode ->pnext; - num_dhcps_pool ++; - } - } - - if (num_dhcps_pool >= MAX_STATION_NUM) - kill_oldest_dhcps_pool(); + uint8 num_dhcps_pool = 0; + list_node *pback_node = NULL; + list_node *pnode = NULL; + struct dhcps_pool *pdhcps_pool = NULL; + pnode = plist; + while (pnode != NULL) + { + pdhcps_pool = pnode->pnode; + pdhcps_pool->lease_timer--; + if (pdhcps_pool->lease_timer == 0) + { + pback_node = pnode; + pnode = pback_node->pnext; + node_remove_from_list_0(&plist, pback_node); + free(pback_node->pnode); + pback_node->pnode = NULL; + free(pback_node); + pback_node = NULL; + } + else + { + pnode = pnode->pnext; + num_dhcps_pool++; + } + } + + if (num_dhcps_pool >= MAX_STATION_NUM) + kill_oldest_dhcps_pool(); } -bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg) +bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_offer_option(uint8 level, void *optarg) { - bool offer_flag = true; - uint8 option = 0; - if (optarg == NULL && wifi_softap_dhcps_status() == false) - return false; - - if (level <= OFFER_START || level >= OFFER_END) - return false; - - switch (level){ - case OFFER_ROUTER: - offer = (*(uint8 *)optarg) & 0x01; - offer_flag = true; - break; - default : - offer_flag = false; - break; - } - return offer_flag; + bool offer_flag = true; + uint8 option = 0; + if (optarg == NULL && wifi_softap_dhcps_status() == false) + return false; + + if (level <= OFFER_START || level >= OFFER_END) + return false; + + switch (level) + { + case OFFER_ROUTER: + offer = (*(uint8 *)optarg) & 0x01; + offer_flag = true; + break; + default: + offer_flag = false; + break; + } + return offer_flag; } bool ICACHE_FLASH_ATTR wifi_softap_set_dhcps_lease_time(uint32 minute) { uint8 opmode = esp_wifi_get_mode(NULL); - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) + { return false; } - if (wifi_softap_dhcps_status() == DHCP_STARTED) { + if (wifi_softap_dhcps_status() == DHCP_STARTED) + { return false; } - if(minute == 0) { + if (minute == 0) + { return false; } dhcps_lease_time = minute; @@ -1143,18 +1240,20 @@ bool ICACHE_FLASH_ATTR wifi_softap_reset_dhcps_lease_time(void) { uint8 opmode = esp_wifi_get_mode(NULL); - if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) { + if (opmode == WIFI_MODE_STA || opmode == NULL_MODE) + { return false; } - if (wifi_softap_dhcps_status() == DHCP_STARTED) { + if (wifi_softap_dhcps_status() == DHCP_STARTED) + { return false; } dhcps_lease_time = DHCPS_LEASE_TIME_DEF; return true; } -uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute +uint32 ICACHE_FLASH_ATTR wifi_softap_get_dhcps_lease_time(void) // minute { return dhcps_lease_time; } diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/espconn.c b/LuaNode_Esp32/LuaNode32/components/espconn/espconn.c index 2186ba7..5612d52 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/espconn.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/espconn.c @@ -7,49 +7,43 @@ * * Modification history: * 2014/3/31, v1.0 create this file. -*******************************************************************************/ + *******************************************************************************/ #include - // #include -#include "lwip/opt.h" -#include "lwip/netif.h" -#include "lwip/inet.h" -#include "netif/etharp.h" -#include "lwip/tcp.h" -#include "lwip/ip.h" -#include "lwip/init.h" -#include "lwip/mem.h" +// #include +#include "esp_event.h" +#include "esp_system.h" #include "esp_wifi.h" - +#include "espconn.h" #include "espconn_tcp.h" #include "espconn_udp.h" -#include "espconn.h" -#include "esp_event.h" -#include "esp_system.h" +#include "lwip/inet.h" +#include "lwip/init.h" +#include "lwip/ip.h" +#include "lwip/mem.h" +#include "lwip/netif.h" +#include "lwip/opt.h" +#include "lwip/tcp.h" +#include "netif/etharp.h" #define ICACHE_FLASH_ATTR - #include "tcpip_adapter.h" #undef TCP_SND_BUF -#define TCP_SND_BUF(pcb) (2 * TCP_MSS) +#define TCP_SND_BUF(pcb) (2 * TCP_MSS) #undef TCP_WND -#define TCP_WND(pcb) (4 * TCP_MSS) +#define TCP_WND(pcb) (4 * TCP_MSS) extern uint8_t wifi_station_get_connect_status(void); -void ICACHE_FLASH_ATTR -wifi_get_ip_info(tcpip_adapter_if_t type, tcpip_adapter_ip_info_t* ipinfo) -{ - tcpip_adapter_get_ip_info(type, ipinfo); - // printf("wifi_get_ip_info:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n", - // IP2STR(&ipinfo->ip), IP2STR(&ipinfo->netmask), IP2STR(&ipinfo->gw)); - -} -void* ICACHE_FLASH_ATTR -eagle_lwip_getif(uint8 type) +void ICACHE_FLASH_ATTR wifi_get_ip_info(tcpip_adapter_if_t type, tcpip_adapter_ip_info_t *ipinfo) { - return NULL; + tcpip_adapter_get_ip_info(type, ipinfo); + // printf("wifi_get_ip_info:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR + // ")\n", + // IP2STR(&ipinfo->ip), IP2STR(&ipinfo->netmask), + // IP2STR(&ipinfo->gw)); } +void *ICACHE_FLASH_ATTR eagle_lwip_getif(uint8 type) { return NULL; } // uint8 ICACHE_FLASH_ATTR // wifi_station_get_connect_status(void) // { @@ -59,14 +53,6 @@ eagle_lwip_getif(uint8 type) // return status; // } - - - - - - - - #ifdef MEMLEAK_DEBUG static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif @@ -83,30 +69,32 @@ static uint8 espconn_tcp_get_buf_count(espconn_buf *pesp_buf); * Description : reconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR -espconn_copy_partial(struct espconn *pesp_dest, struct espconn *pesp_source) + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_copy_partial(struct espconn *pesp_dest, struct espconn *pesp_source) { - pesp_dest->type = pesp_source->type; - pesp_dest->state = pesp_source->state; - if (pesp_source->type == ESPCONN_TCP){ - pesp_dest->proto.tcp->remote_port = pesp_source->proto.tcp->remote_port; - pesp_dest->proto.tcp->local_port = pesp_source->proto.tcp->local_port; - memcpy(pesp_dest->proto.tcp->remote_ip, pesp_source->proto.tcp->remote_ip, 4); - memcpy(pesp_dest->proto.tcp->local_ip, pesp_source->proto.tcp->local_ip, 4); - pesp_dest->proto.tcp->connect_callback = pesp_source->proto.tcp->connect_callback; - pesp_dest->proto.tcp->reconnect_callback = pesp_source->proto.tcp->reconnect_callback; - pesp_dest->proto.tcp->disconnect_callback = pesp_source->proto.tcp->disconnect_callback; - } else { - pesp_dest->proto.udp->remote_port = pesp_source->proto.udp->remote_port; - pesp_dest->proto.udp->local_port = pesp_source->proto.udp->local_port; - memcpy(pesp_dest->proto.udp->remote_ip, pesp_source->proto.udp->remote_ip, 4); - memcpy(pesp_dest->proto.udp->local_ip, pesp_source->proto.udp->local_ip, 4); - } - pesp_dest->recv_callback = pesp_source->recv_callback; - pesp_dest->sent_callback = pesp_source->sent_callback; - pesp_dest->link_cnt = pesp_source->link_cnt; - pesp_dest->reserve = pesp_source->reserve; + pesp_dest->type = pesp_source->type; + pesp_dest->state = pesp_source->state; + if (pesp_source->type == ESPCONN_TCP) + { + pesp_dest->proto.tcp->remote_port = pesp_source->proto.tcp->remote_port; + pesp_dest->proto.tcp->local_port = pesp_source->proto.tcp->local_port; + memcpy(pesp_dest->proto.tcp->remote_ip, pesp_source->proto.tcp->remote_ip, 4); + memcpy(pesp_dest->proto.tcp->local_ip, pesp_source->proto.tcp->local_ip, 4); + pesp_dest->proto.tcp->connect_callback = pesp_source->proto.tcp->connect_callback; + pesp_dest->proto.tcp->reconnect_callback = pesp_source->proto.tcp->reconnect_callback; + pesp_dest->proto.tcp->disconnect_callback = pesp_source->proto.tcp->disconnect_callback; + } + else + { + pesp_dest->proto.udp->remote_port = pesp_source->proto.udp->remote_port; + pesp_dest->proto.udp->local_port = pesp_source->proto.udp->local_port; + memcpy(pesp_dest->proto.udp->remote_ip, pesp_source->proto.udp->remote_ip, 4); + memcpy(pesp_dest->proto.udp->local_ip, pesp_source->proto.udp->local_ip, 4); + } + pesp_dest->recv_callback = pesp_source->recv_callback; + pesp_dest->sent_callback = pesp_source->sent_callback; + pesp_dest->link_cnt = pesp_source->link_cnt; + pesp_dest->reserve = pesp_source->reserve; } /****************************************************************************** @@ -114,30 +102,31 @@ espconn_copy_partial(struct espconn *pesp_dest, struct espconn *pesp_source) * Description : insert the node to the active connection list * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR espconn_list_creat(espconn_msg **phead, espconn_msg* pinsert) + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_list_creat(espconn_msg **phead, espconn_msg *pinsert) { - espconn_msg *plist = NULL; -// espconn_msg *ptest = NULL; - if (*phead == NULL) { - *phead = pinsert; - // (*phead)->pcommon.pbuf = (espconn_buf*) malloc(sizeof(espconn_buf)); - } - else { - plist = *phead; - while (plist->pnext != NULL) { - plist = plist->pnext; - } - plist->pnext = pinsert; - // plist->pnext->pcommon.pbuf = (espconn_buf*) malloc(sizeof(espconn_buf)); - } - pinsert->pnext = NULL; - -/* ptest = *phead; - while(ptest != NULL){ - os_printf("espconn_list_creat %p\n", ptest); - ptest = ptest->pnext; - }*/ + espconn_msg *plist = NULL; + // espconn_msg *ptest = NULL; + if (*phead == NULL) + { + *phead = pinsert; + // (*phead)->pcommon.pbuf = (espconn_buf*) malloc(sizeof(espconn_buf)); + } + else + { + plist = *phead; + while (plist->pnext != NULL) { plist = plist->pnext; } + plist->pnext = pinsert; + // plist->pnext->pcommon.pbuf = (espconn_buf*) + // malloc(sizeof(espconn_buf)); + } + pinsert->pnext = NULL; + + /* ptest = *phead; + while(ptest != NULL){ + os_printf("espconn_list_creat %p\n", ptest); + ptest = ptest->pnext; + }*/ } /****************************************************************************** @@ -145,38 +134,46 @@ void ICACHE_FLASH_ATTR espconn_list_creat(espconn_msg **phead, espconn_msg* pins * Description : remove the node from the active connection list * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR espconn_list_delete(espconn_msg **phead, espconn_msg* pdelete) + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_list_delete(espconn_msg **phead, espconn_msg *pdelete) { - espconn_msg *plist = NULL; -// espconn_msg *ptest = NULL; - plist = *phead; - if (plist == NULL){ - *phead = NULL; - // if((*phead)->pcommon.pbuf != NULL) - // free((*phead)->pcommon.pbuf); - } else { - if (plist == pdelete){ - // if((*phead)->pcommon.pbuf != NULL) - // free((*phead)->pcommon.pbuf); - *phead = plist->pnext; - } else { - while (plist != NULL) { - if (plist->pnext == pdelete){ - // if((*phead)->pcommon.pbuf != NULL) - // free((*phead)->pcommon.pbuf); - plist->pnext = pdelete->pnext; - } - plist = plist->pnext; - } - } - } - //printf("deleted\n"); -/* ptest = *phead; - while(ptest != NULL){ - os_printf("espconn_list_delete %p\n", ptest); - ptest = ptest->pnext; - }*/ + espconn_msg *plist = NULL; + // espconn_msg *ptest = NULL; + plist = *phead; + if (plist == NULL) + { + *phead = NULL; + // if((*phead)->pcommon.pbuf != NULL) + // free((*phead)->pcommon.pbuf); + } + else + { + if (plist == pdelete) + { + // if((*phead)->pcommon.pbuf != NULL) + // free((*phead)->pcommon.pbuf); + *phead = plist->pnext; + } + else + { + while (plist != NULL) + { + if (plist->pnext == pdelete) + { + // if((*phead)->pcommon.pbuf != NULL) + // free((*phead)->pcommon.pbuf); + plist->pnext = pdelete->pnext; + } + plist = plist->pnext; + } + } + } + // printf("deleted\n"); + /* ptest = *phead; + while(ptest != NULL){ + os_printf("espconn_list_delete %p\n", ptest); + ptest = ptest->pnext; + }*/ } /****************************************************************************** @@ -184,21 +181,20 @@ void ICACHE_FLASH_ATTR espconn_list_delete(espconn_msg **phead, espconn_msg* pde * Description : insert the node to the active connection list * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR espconn_pbuf_create(espconn_buf **phead, espconn_buf* pinsert) + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_pbuf_create(espconn_buf **phead, espconn_buf *pinsert) { - espconn_buf *plist = NULL; - - if (*phead == NULL) - *phead = pinsert; - else { - plist = *phead; - while (plist->pnext != NULL) { - plist = plist->pnext; - } - plist->pnext = pinsert; - } - pinsert->pnext = NULL; + espconn_buf *plist = NULL; + + if (*phead == NULL) + *phead = pinsert; + else + { + plist = *phead; + while (plist->pnext != NULL) { plist = plist->pnext; } + plist->pnext = pinsert; + } + pinsert->pnext = NULL; } /****************************************************************************** @@ -206,26 +202,34 @@ void ICACHE_FLASH_ATTR espconn_pbuf_create(espconn_buf **phead, espconn_buf* pin * Description : remove the node from the active connection list * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR espconn_pbuf_delete(espconn_buf **phead, espconn_buf* pdelete) + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_pbuf_delete(espconn_buf **phead, espconn_buf *pdelete) { - espconn_buf *plist = NULL; - - plist = *phead; - if (plist == NULL){ - *phead = NULL; - } else { - if (plist == pdelete){ - *phead = plist->pnext; - } else { - while (plist != NULL) { - if (plist->pnext == pdelete){ - plist->pnext = pdelete->pnext; - } - plist = plist->pnext; - } - } - } + espconn_buf *plist = NULL; + + plist = *phead; + if (plist == NULL) + { + *phead = NULL; + } + else + { + if (plist == pdelete) + { + *phead = plist->pnext; + } + else + { + while (plist != NULL) + { + if (plist->pnext == pdelete) + { + plist->pnext = pdelete->pnext; + } + plist = plist->pnext; + } + } + } } /****************************************************************************** @@ -237,47 +241,51 @@ void ICACHE_FLASH_ATTR espconn_pbuf_delete(espconn_buf **phead, espconn_buf* pde *******************************************************************************/ bool ICACHE_FLASH_ATTR espconn_find_connection(struct espconn *pespconn, espconn_msg **pnode) { - espconn_msg *plist = NULL; - ip_addr_t ip_remot; - ip_addr_t ip_list; + espconn_msg *plist = NULL; + ip_addr_t ip_remot; + ip_addr_t ip_list; if (pespconn == NULL) - return false; + return false; /*find the active connection node*/ - for (plist = plink_active; plist != NULL; plist = plist->pnext){ - if (pespconn == plist->pespconn) { - *pnode = plist; - return true; - } - } + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + if (pespconn == plist->pespconn) + { + *pnode = plist; + return true; + } + } /*find the active server node*/ - for (plist = pserver_list; plist != NULL; plist = plist->pnext){ - if (pespconn == plist->pespconn) { - if (pespconn->proto.tcp == NULL) - return false; - - IP4_ADDR(&ip_remot.u_addr.ip4, pespconn->proto.tcp->remote_ip[0], - pespconn->proto.tcp->remote_ip[1], - pespconn->proto.tcp->remote_ip[2], - pespconn->proto.tcp->remote_ip[3]); - if ((ip_remot.u_addr.ip4.addr == IPADDR_ANY) || (pespconn->proto.tcp->remote_port == 0)) - return false; - - /*find the active connection node*/ - for (plist = plink_active; plist != NULL; plist = plist->pnext){ - IP4_ADDR(&ip_list.u_addr.ip4, plist->pcommon.remote_ip[0], - plist->pcommon.remote_ip[1], plist->pcommon.remote_ip[2], - plist->pcommon.remote_ip[3]); - if ((ip_list.u_addr.ip4.addr == ip_remot.u_addr.ip4.addr) && (pespconn->proto.tcp->remote_port == plist->pcommon.remote_port)) { - *pnode = plist; - return true; - } - } - return false; - } - } + for (plist = pserver_list; plist != NULL; plist = plist->pnext) + { + if (pespconn == plist->pespconn) + { + if (pespconn->proto.tcp == NULL) + return false; + + IP4_ADDR(&ip_remot.u_addr.ip4, pespconn->proto.tcp->remote_ip[0], pespconn->proto.tcp->remote_ip[1], + pespconn->proto.tcp->remote_ip[2], pespconn->proto.tcp->remote_ip[3]); + if ((ip_remot.u_addr.ip4.addr == IPADDR_ANY) || (pespconn->proto.tcp->remote_port == 0)) + return false; + + /*find the active connection node*/ + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + IP4_ADDR(&ip_list.u_addr.ip4, plist->pcommon.remote_ip[0], plist->pcommon.remote_ip[1], + plist->pcommon.remote_ip[2], plist->pcommon.remote_ip[3]); + if ((ip_list.u_addr.ip4.addr == ip_remot.u_addr.ip4.addr) && + (pespconn->proto.tcp->remote_port == plist->pcommon.remote_port)) + { + *pnode = plist; + return true; + } + } + return false; + } + } return false; } @@ -287,19 +295,20 @@ bool ICACHE_FLASH_ATTR espconn_find_connection(struct espconn *pespconn, espconn * Parameters : type -- the type * Returns : the count of simulatenously active connections *******************************************************************************/ -static uint8 ICACHE_FLASH_ATTR -espconn_get_acticve_num(uint8 type) +static uint8 ICACHE_FLASH_ATTR espconn_get_acticve_num(uint8 type) { - espconn_msg *plist = NULL; - uint8 num_tcp_active = 0; + espconn_msg *plist = NULL; + uint8 num_tcp_active = 0; - for (plist = plink_active; plist != NULL; plist = plist->pnext) { - if (plist->pespconn != NULL && plist->pespconn->type == type) { - num_tcp_active++; - } - } + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + if (plist->pespconn != NULL && plist->pespconn->type == type) + { + num_tcp_active++; + } + } - return num_tcp_active; + return num_tcp_active; } /****************************************************************************** @@ -307,83 +316,99 @@ espconn_get_acticve_num(uint8 type) * Description : The function given as the connect * Parameters : espconn -- the espconn used to listen the connection * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_connect(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_connect(struct espconn *espconn) { - ip_addr_t ipaddr; - tcpip_adapter_ip_info_t ipinfo; - uint8 connect_status = 0; - sint8 value = ESPCONN_OK; - espconn_msg *plist = NULL; - // remot_info *pinfo = NULL; - - if (espconn == NULL) { + ip_addr_t ipaddr; + tcpip_adapter_ip_info_t ipinfo; + uint8 connect_status = 0; + sint8 value = ESPCONN_OK; + espconn_msg *plist = NULL; + // remot_info *pinfo = NULL; + + if (espconn == NULL) + { + return ESPCONN_ARG; + } + else if (espconn->type != ESPCONN_TCP) return ESPCONN_ARG; - } else if (espconn ->type != ESPCONN_TCP) - return ESPCONN_ARG; /*Check the active node count whether is the limit or not*/ if (espconn_get_acticve_num(ESPCONN_TCP) >= espconn_tcp_get_max_con()) { - printf("espconn_tcp_get_max_con \n"); - return ESPCONN_ISCONN; + printf("espconn_tcp_get_max_con \n"); + return ESPCONN_ISCONN; } /*Check the IP address whether is zero or not in different mode*/ - esp_wifi_get_mode((wifi_mode_t*)&value); - if (value == WIFI_MODE_STA){ - wifi_get_ip_info(TCPIP_ADAPTER_IF_STA,&ipinfo); - if (ipinfo.ip.addr == 0){ - return ESPCONN_RTE; - } - } else if(value == WIFI_MODE_AP){ - wifi_get_ip_info(TCPIP_ADAPTER_IF_AP,&ipinfo); - if (ipinfo.ip.addr == 0){ - return ESPCONN_RTE; - } - } else if(value == WIFI_MODE_APSTA){ - IP4_ADDR(&ipaddr.u_addr.ip4, espconn->proto.tcp->remote_ip[0], - espconn->proto.tcp->remote_ip[1], - espconn->proto.tcp->remote_ip[2], - espconn->proto.tcp->remote_ip[3]); - ipaddr.u_addr.ip4.addr <<= 8; - wifi_get_ip_info(TCPIP_ADAPTER_IF_AP,&ipinfo); - ipinfo.ip.addr <<= 8; - // espconn_printf("softap_addr = %x, remote_addr = %x\n", ipinfo.ip.addr, ipaddr.u_addr.ip4.addr); - - if (ipaddr.u_addr.ip4.addr != ipinfo.ip.addr){ - - connect_status = wifi_station_get_connect_status(); - - if (connect_status == SYSTEM_EVENT_STA_GOT_IP){ - wifi_get_ip_info(TCPIP_ADAPTER_IF_STA,&ipinfo); - // espconn_printf("wifi_get_ip_info:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n", - // IP2STR(&ipinfo.ip), IP2STR(&ipinfo.netmask), IP2STR(&ipinfo.gw)); - - - - if (ipinfo.ip.addr == 0) - return ESPCONN_RTE; - } else if (connect_status != SYSTEM_EVENT_STA_GOT_IP){ - return ESPCONN_RTE; - } else { - return connect_status; - } - } + esp_wifi_get_mode((wifi_mode_t *)&value); + if (value == WIFI_MODE_STA) + { + wifi_get_ip_info(TCPIP_ADAPTER_IF_STA, &ipinfo); + if (ipinfo.ip.addr == 0) + { + return ESPCONN_RTE; + } } - /*check the active node information whether is the same as the entity or not*/ - for (plist = plink_active; plist != NULL; plist = plist->pnext){ - if (plist->pespconn && plist->pespconn->type == ESPCONN_TCP){ - if (espconn->proto.tcp->local_port == plist->pespconn->proto.tcp->local_port){ - return ESPCONN_ISCONN; - } - } + else if (value == WIFI_MODE_AP) + { + wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &ipinfo); + if (ipinfo.ip.addr == 0) + { + return ESPCONN_RTE; + } + } + else if (value == WIFI_MODE_APSTA) + { + IP4_ADDR(&ipaddr.u_addr.ip4, espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1], + espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3]); + ipaddr.u_addr.ip4.addr <<= 8; + wifi_get_ip_info(TCPIP_ADAPTER_IF_AP, &ipinfo); + ipinfo.ip.addr <<= 8; + // espconn_printf("softap_addr = %x, remote_addr = %x\n", + // ipinfo.ip.addr, ipaddr.u_addr.ip4.addr); + + if (ipaddr.u_addr.ip4.addr != ipinfo.ip.addr) + { + connect_status = wifi_station_get_connect_status(); + + if (connect_status == SYSTEM_EVENT_STA_GOT_IP) + { + wifi_get_ip_info(TCPIP_ADAPTER_IF_STA, &ipinfo); + // espconn_printf("wifi_get_ip_info:(ip: " IPSTR ", mask: " + // IPSTR ", gw: " IPSTR ")\n", + // IP2STR(&ipinfo.ip), IP2STR(&ipinfo.netmask), + // IP2STR(&ipinfo.gw)); + + if (ipinfo.ip.addr == 0) + return ESPCONN_RTE; + } + else if (connect_status != SYSTEM_EVENT_STA_GOT_IP) + { + return ESPCONN_RTE; + } + else + { + return connect_status; + } + } + } + /*check the active node information whether is the same as the entity or + * not*/ + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + if (plist->pespconn && plist->pespconn->type == ESPCONN_TCP) + { + if (espconn->proto.tcp->local_port == plist->pespconn->proto.tcp->local_port) + { + return ESPCONN_ISCONN; + } + } } - espconn_set_opt(espconn, ESPCONN_COPY|ESPCONN_NODELAY); + espconn_set_opt(espconn, ESPCONN_COPY | ESPCONN_NODELAY); value = espconn_tcp_client(espconn); - espconn_printf("espconn_connect err value %d \n",value); + espconn_printf("espconn_connect err value %d \n", value); return value; } @@ -393,31 +418,37 @@ espconn_connect(struct espconn *espconn) * Description : sent data for client or server * Parameters : espconn -- espconn to the data transmission * Returns : result -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_create(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_create(struct espconn *espconn) { - sint8 value = ESPCONN_OK; - espconn_msg *plist = NULL; - - if (espconn == NULL) { - return ESPCONN_ARG; - } else if (espconn ->type != ESPCONN_UDP){ - return ESPCONN_ARG; - } - - /*check the active node information whether is the same as the entity or not*/ - for (plist = plink_active; plist != NULL; plist = plist->pnext){ - if (plist->pespconn && plist->pespconn->type == ESPCONN_UDP){ - if (espconn->proto.udp->local_port == plist->pespconn->proto.udp->local_port){ - return ESPCONN_ISCONN; - } - } - } - - value = espconn_udp_server(espconn); - - return value; + sint8 value = ESPCONN_OK; + espconn_msg *plist = NULL; + + if (espconn == NULL) + { + return ESPCONN_ARG; + } + else if (espconn->type != ESPCONN_UDP) + { + return ESPCONN_ARG; + } + + /*check the active node information whether is the same as the entity or + * not*/ + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + if (plist->pespconn && plist->pespconn->type == ESPCONN_UDP) + { + if (espconn->proto.udp->local_port == plist->pespconn->proto.udp->local_port) + { + return ESPCONN_ISCONN; + } + } + } + + value = espconn_udp_server(espconn); + + return value; } /****************************************************************************** @@ -427,77 +458,93 @@ espconn_create(struct espconn *espconn) * psent -- data to send * length -- length of data to send * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) { - espconn_msg *pnode = NULL; - bool value = false; - err_t error = ESPCONN_OK; - espconn_buf *pbuf = NULL; - - if (espconn == NULL || psent == NULL || length == 0) { + espconn_msg *pnode = NULL; + bool value = false; + err_t error = ESPCONN_OK; + espconn_buf *pbuf = NULL; + + if (espconn == NULL || psent == NULL || length == 0) + { return ESPCONN_ARG; } - //printf("espconn_sent len %d %s \n",length,psent); - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value){ - espconn ->state = ESPCONN_WRITE; - switch (espconn ->type) { - case ESPCONN_TCP: - /* calling sent function frequently,make sure last packet has been backup or sent fully*/ - if (pnode->pcommon.write_flag){ - /*If total number of espconn_buf on the unsent lists exceeds the set maximum, return an error */ - if (espconn_copy_enabled(pnode)){ - if (espconn_tcp_get_buf_count(pnode->pcommon.pbuf) >= pnode ->pcommon.pbuf_num) - return ESPCONN_MAXNUM; - } else { - // struct tcp_pcb *pcb = (struct tcp_pcb *)pnode->pcommon.pcb; - if (((struct tcp_pcb *)pnode->pcommon.pcb)->snd_queuelen >= TCP_SND_QUEUELEN(0)) - return ESPCONN_MAXNUM; - } - - pbuf = (espconn_buf*) malloc(sizeof(espconn_buf)); - if (pbuf == NULL) - return ESPCONN_MEM; - else { - /*Backup the application packet information for send more data*/ - pbuf->payload = psent; - pbuf->punsent = pbuf->payload; - pbuf->unsent = length; - pbuf->len = length; - /*insert the espconn_pbuf to the list*/ - espconn_pbuf_create(&pnode->pcommon.pbuf, pbuf); - if (pnode->pcommon.ptail == NULL) { - pnode->pcommon.ptail = pbuf; - } - //printf("espconn_pbuf_create %p pesp_buf %p\n",pnode,pnode->pcommon.pbuf); - } - /*when set the data copy option. change the flag for next packet*/ - if (espconn_copy_disabled(pnode)) - pnode->pcommon.write_flag = false; - error = espconn_tcp_write(pnode); - if (error != ESPCONN_OK){ - /*send the application packet fail, - * ensure that each allocated is deleted*/ - espconn_pbuf_delete(&pnode->pcommon.pbuf, pbuf); - // free(); - free(pbuf); - pbuf = NULL; - } - return error; - } else - return ESPCONN_ARG; - break; - - case ESPCONN_UDP: - return espconn_udp_sent(pnode, psent, length); - break; - - default : - break; - } + // printf("espconn_sent len %d %s \n",length,psent); + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value) + { + espconn->state = ESPCONN_WRITE; + switch (espconn->type) + { + case ESPCONN_TCP: + /* calling sent function frequently,make sure last packet has + * been backup or sent fully*/ + if (pnode->pcommon.write_flag) + { + /*If total number of espconn_buf on the unsent lists exceeds + * the set maximum, return an error */ + if (espconn_copy_enabled(pnode)) + { + if (espconn_tcp_get_buf_count(pnode->pcommon.pbuf) >= pnode->pcommon.pbuf_num) + return ESPCONN_MAXNUM; + } + else + { + // struct tcp_pcb *pcb = (struct tcp_pcb + // *)pnode->pcommon.pcb; + if (((struct tcp_pcb *)pnode->pcommon.pcb)->snd_queuelen >= TCP_SND_QUEUELEN(0)) + return ESPCONN_MAXNUM; + } + + pbuf = (espconn_buf *)malloc(sizeof(espconn_buf)); + if (pbuf == NULL) + return ESPCONN_MEM; + else + { + /*Backup the application packet information for send + * more data*/ + pbuf->payload = psent; + pbuf->punsent = pbuf->payload; + pbuf->unsent = length; + pbuf->len = length; + /*insert the espconn_pbuf to the list*/ + espconn_pbuf_create(&pnode->pcommon.pbuf, pbuf); + if (pnode->pcommon.ptail == NULL) + { + pnode->pcommon.ptail = pbuf; + } + // printf("espconn_pbuf_create %p pesp_buf + // %p\n",pnode,pnode->pcommon.pbuf); + } + /*when set the data copy option. change the flag for next + * packet*/ + if (espconn_copy_disabled(pnode)) + pnode->pcommon.write_flag = false; + error = espconn_tcp_write(pnode); + if (error != ESPCONN_OK) + { + /*send the application packet fail, + * ensure that each allocated is deleted*/ + espconn_pbuf_delete(&pnode->pcommon.pbuf, pbuf); + // free(); + free(pbuf); + pbuf = NULL; + } + return error; + } + else + return ESPCONN_ARG; + break; + + case ESPCONN_UDP: + return espconn_udp_sent(pnode, psent, length); + break; + + default: + break; + } } return ESPCONN_ARG; } @@ -509,24 +556,24 @@ espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length) * psent -- data to send * length -- length of data to send * Returns : error -*******************************************************************************/ -sint16 ICACHE_FLASH_ATTR -espconn_sendto(struct espconn *espconn, uint8 *psent, uint16 length) + *******************************************************************************/ +sint16 ICACHE_FLASH_ATTR espconn_sendto(struct espconn *espconn, uint8 *psent, uint16 length) { - espconn_msg *pnode = NULL; - bool value = false; - // err_t error = ESPCONN_OK; - - if (espconn == NULL || psent == NULL || length == 0) { - return ESPCONN_ARG; - } - - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value && espconn->type == ESPCONN_UDP) - return espconn_udp_sendto(pnode, psent, length); - else - return ESPCONN_ARG; + espconn_msg *pnode = NULL; + bool value = false; + // err_t error = ESPCONN_OK; + + if (espconn == NULL || psent == NULL || length == 0) + { + return ESPCONN_ARG; + } + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value && espconn->type == ESPCONN_UDP) + return espconn_udp_sendto(pnode, psent, length); + else + return ESPCONN_ARG; } /****************************************************************************** @@ -536,7 +583,7 @@ espconn_sendto(struct espconn *espconn, uint8 *psent, uint16 length) * psent -- data to send * length -- length of data to send * Returns : none -*******************************************************************************/ + *******************************************************************************/ sint8 espconn_send(struct espconn *espconn, uint8 *psent, uint16 length) __attribute__((alias("espconn_sent"))); @@ -545,14 +592,14 @@ sint8 espconn_send(struct espconn *espconn, uint8 *psent, uint16 length) __attri * Description : get the window size of simulatenously active TCP connections * Parameters : none * Returns : the number of TCP_MSS active TCP connections -*******************************************************************************/ + *******************************************************************************/ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_wnd(void) { - uint8 tcp_num = 0; + uint8 tcp_num = 0; - tcp_num = (TCP_WND(0) / TCP_MSS); + tcp_num = (TCP_WND(0) / TCP_MSS); - return tcp_num; + return tcp_num; } /****************************************************************************** * FunctionName : espconn_tcp_set_max_con @@ -560,14 +607,14 @@ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_wnd(void) * Parameters : num -- the number of TCP_MSS * Returns : ESPCONN_ARG -- Illegal argument * ESPCONN_OK -- No error -*******************************************************************************/ + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_wnd(uint8 num) { - if (num == 0 || num > linkMax) - return ESPCONN_ARG; + if (num == 0 || num > linkMax) + return ESPCONN_ARG; - // TCP_WND = (num * TCP_MSS); - return ESPCONN_OK; + // TCP_WND = (num * TCP_MSS); + return ESPCONN_OK; } /****************************************************************************** @@ -575,14 +622,14 @@ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_wnd(uint8 num) * Description : get the mss size of simulatenously active TCP connections * Parameters : none * Returns : the size of TCP_MSS active TCP connections -*******************************************************************************/ + *******************************************************************************/ uint16 ICACHE_FLASH_ATTR espconn_tcp_get_mss(void) { - uint16 tcp_num = 0; + uint16 tcp_num = 0; - tcp_num = TCP_MSS; + tcp_num = TCP_MSS; - return tcp_num; + return tcp_num; } /****************************************************************************** @@ -590,14 +637,14 @@ uint16 ICACHE_FLASH_ATTR espconn_tcp_get_mss(void) * Description : get the number of simulatenously active TCP connections * Parameters : espconn -- espconn to set the connect callback * Returns : none -*******************************************************************************/ + *******************************************************************************/ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_max_con(void) { - uint8 tcp_num = 0; + uint8 tcp_num = 0; - tcp_num = MEMP_NUM_TCP_PCB; + tcp_num = MEMP_NUM_TCP_PCB; - return tcp_num; + return tcp_num; } /****************************************************************************** @@ -605,44 +652,44 @@ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_max_con(void) * Description : set the number of simulatenously active TCP connections * Parameters : espconn -- espconn to set the connect callback * Returns : none -*******************************************************************************/ + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_max_con(uint8 num) { - if (num == 0 || num > linkMax) - return ESPCONN_ARG; + if (num == 0 || num > linkMax) + return ESPCONN_ARG; - // MEMP_NUM_TCP_PCB = num; - return ESPCONN_OK; + // MEMP_NUM_TCP_PCB = num; + return ESPCONN_OK; } /****************************************************************************** * FunctionName : espconn_tcp_get_max_retran - * Description : get the Maximum number of retransmissions of data active TCP connections - * Parameters : none - * Returns : the Maximum number of retransmissions -*******************************************************************************/ + * Description : get the Maximum number of retransmissions of data active TCP + *connections Parameters : none Returns : the Maximum number of + *retransmissions + *******************************************************************************/ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_max_retran(void) { - uint8 tcp_num = 0; + uint8 tcp_num = 0; - tcp_num = TCP_MAXRTX; + tcp_num = TCP_MAXRTX; - return tcp_num; + return tcp_num; } /****************************************************************************** * FunctionName : espconn_tcp_set_max_retran - * Description : set the Maximum number of retransmissions of data active TCP connections - * Parameters : num -- the Maximum number of retransmissions + * Description : set the Maximum number of retransmissions of data active TCP + *connections Parameters : num -- the Maximum number of retransmissions * Returns : result -*******************************************************************************/ + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_max_retran(uint8 num) { - if (num == 0 || num > 12) - return ESPCONN_ARG; + if (num == 0 || num > 12) + return ESPCONN_ARG; - // TCP_MAXRTX = num; - return ESPCONN_OK; + // TCP_MAXRTX = num; + return ESPCONN_OK; } /****************************************************************************** @@ -650,14 +697,14 @@ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_max_retran(uint8 num) * Description : get the Maximum number of retransmissions of SYN segments * Parameters : none * Returns : the Maximum number of retransmissions -*******************************************************************************/ + *******************************************************************************/ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_max_syn(void) { - uint8 tcp_num = 0; + uint8 tcp_num = 0; - tcp_num = TCP_SYNMAXRTX; + tcp_num = TCP_SYNMAXRTX; - return tcp_num; + return tcp_num; } /****************************************************************************** @@ -665,86 +712,90 @@ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_max_syn(void) * Description : set the Maximum number of retransmissions of SYN segments * Parameters : num -- the Maximum number of retransmissions * Returns : result -*******************************************************************************/ + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_max_syn(uint8 num) { - if (num == 0 || num > 12) - return ESPCONN_ARG; + if (num == 0 || num > 12) + return ESPCONN_ARG; - // TCP_SYNMAXRTX = num; - return ESPCONN_OK; + // TCP_SYNMAXRTX = num; + return ESPCONN_OK; } /****************************************************************************** * FunctionName : espconn_tcp_get_max_con_allow - * Description : get the count of simulatenously active connections on the server - * Parameters : espconn -- espconn to get the count - * Returns : result -*******************************************************************************/ + * Description : get the count of simulatenously active connections on the + *server Parameters : espconn -- espconn to get the count Returns : + *result + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_get_max_con_allow(struct espconn *espconn) { - espconn_msg *pget_msg = NULL; - if ((espconn == NULL) || (espconn->type == ESPCONN_UDP)) - return ESPCONN_ARG; - - pget_msg = pserver_list; - while (pget_msg != NULL){ - if (pget_msg->pespconn == espconn){ - return pget_msg->count_opt; - } - pget_msg = pget_msg->pnext; - } - return ESPCONN_ARG; + espconn_msg *pget_msg = NULL; + if ((espconn == NULL) || (espconn->type == ESPCONN_UDP)) + return ESPCONN_ARG; + + pget_msg = pserver_list; + while (pget_msg != NULL) + { + if (pget_msg->pespconn == espconn) + { + return pget_msg->count_opt; + } + pget_msg = pget_msg->pnext; + } + return ESPCONN_ARG; } /****************************************************************************** * FunctionName : espconn_tcp_set_max_con_allow - * Description : set the count of simulatenously active connections on the server - * Parameters : espconn -- espconn to set the count - * Returns : result -*******************************************************************************/ + * Description : set the count of simulatenously active connections on the + *server Parameters : espconn -- espconn to set the count Returns : + *result + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_max_con_allow(struct espconn *espconn, uint8 num) { - espconn_msg *pset_msg = NULL; - if ((espconn == NULL) || (num > MEMP_NUM_TCP_PCB) || (espconn->type == ESPCONN_UDP)) - return ESPCONN_ARG; - - pset_msg = pserver_list; - while (pset_msg != NULL){ - if (pset_msg->pespconn == espconn){ - pset_msg->count_opt = num; - return ESPCONN_OK; - } - pset_msg = pset_msg->pnext; - } - return ESPCONN_ARG; + espconn_msg *pset_msg = NULL; + if ((espconn == NULL) || (num > MEMP_NUM_TCP_PCB) || (espconn->type == ESPCONN_UDP)) + return ESPCONN_ARG; + + pset_msg = pserver_list; + while (pset_msg != NULL) + { + if (pset_msg->pespconn == espconn) + { + pset_msg->count_opt = num; + return ESPCONN_OK; + } + pset_msg = pset_msg->pnext; + } + return ESPCONN_ARG; } /****************************************************************************** * FunctionName : espconn_tcp_set_buf_count - * Description : set the total number of espconn_buf on the unsent lists for one - * activate connection - * Parameters : espconn -- espconn to set the count - * num -- the total number of espconn_buf - * Returns : result -*******************************************************************************/ + * Description : set the total number of espconn_buf on the unsent lists for + *one activate connection Parameters : espconn -- espconn to set the count num + *-- the total number of espconn_buf Returns : result + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_buf_count(struct espconn *espconn, uint8 num) { - espconn_msg *plist = NULL; - if (espconn == NULL || (num > TCP_SND_QUEUELEN(0))) - return ESPCONN_ARG; - - /*find the node from the active connection list*/ - for (plist = plink_active; plist != NULL; plist = plist->pnext){ - if (plist->pespconn && plist->pespconn == espconn && espconn->type == ESPCONN_TCP){ - plist->pcommon.pbuf_num = num; - return ESPCONN_OK; - } - } - - if (plist == NULL) - return ESPCONN_ARG; - return ESPCONN_RTE; + espconn_msg *plist = NULL; + if (espconn == NULL || (num > TCP_SND_QUEUELEN(0))) + return ESPCONN_ARG; + + /*find the node from the active connection list*/ + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + if (plist->pespconn && plist->pespconn == espconn && espconn->type == ESPCONN_TCP) + { + plist->pcommon.pbuf_num = num; + return ESPCONN_OK; + } + } + + if (plist == NULL) + return ESPCONN_ARG; + return ESPCONN_RTE; } /****************************************************************************** @@ -752,20 +803,21 @@ sint8 ICACHE_FLASH_ATTR espconn_tcp_set_buf_count(struct espconn *espconn, uint8 * Description : get the count of the current node which has espconn_buf * Parameters : pesp_buf -- the list head of espconn_buf type * Returns : the count of the current node which has espconn_buf -*******************************************************************************/ + *******************************************************************************/ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_buf_count(espconn_buf *pesp_buf) { - espconn_buf *pbuf_list = pesp_buf; - uint8 pbuf_num = 0; + espconn_buf *pbuf_list = pesp_buf; + uint8 pbuf_num = 0; - printf("espconn_tcp_get_buf_count %p pesp_buf %p\n",pbuf_list,pesp_buf); + printf("espconn_tcp_get_buf_count %p pesp_buf %p\n", pbuf_list, pesp_buf); - /*polling the list get the count of the current node*/ - while (pbuf_list != NULL){ - pbuf_list = pbuf_list->pnext; - pbuf_num ++; - } - return pbuf_num; + /*polling the list get the count of the current node*/ + while (pbuf_list != NULL) + { + pbuf_list = pbuf_list->pnext; + pbuf_num++; + } + return pbuf_num; } /****************************************************************************** @@ -776,15 +828,15 @@ uint8 ICACHE_FLASH_ATTR espconn_tcp_get_buf_count(espconn_buf *pesp_buf) * sent_cb -- sent callback function to call for this espconn * when data is successfully sent * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_cb) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_cb) { - if (espconn == NULL) { - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; } - espconn ->sent_callback = sent_cb; + espconn->sent_callback = sent_cb; return ESPCONN_OK; } @@ -796,15 +848,15 @@ espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_cb) * sent_cb -- sent callback function to call for this espconn * when data is successfully sent * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback write_finish_fn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback write_finish_fn) { - if (espconn == NULL || espconn ->proto.tcp == NULL || espconn->type == ESPCONN_UDP) { - return ESPCONN_ARG; + if (espconn == NULL || espconn->proto.tcp == NULL || espconn->type == ESPCONN_UDP) + { + return ESPCONN_ARG; } - espconn ->proto.tcp->write_finish_fn = write_finish_fn; + espconn->proto.tcp->write_finish_fn = write_finish_fn; return ESPCONN_OK; } @@ -813,14 +865,14 @@ espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback wr * Description : used to specify the function that should be called when * connects to host. * Parameters : espconn -- espconn to set the connect callback - * connect_cb -- connected callback function to call when connected - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_regist_connectcb(struct espconn *espconn, espconn_connect_callback connect_cb) + * connect_cb -- connected callback function to call when + *connected Returns : none + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_regist_connectcb(struct espconn *espconn, espconn_connect_callback connect_cb) { - if (espconn == NULL) { - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; } espconn->proto.tcp->connect_callback = connect_cb; @@ -834,104 +886,105 @@ espconn_regist_connectcb(struct espconn *espconn, espconn_connect_callback conne * Parameters : espconn -- espconn to set the recv callback * recv_cb -- recv callback function to call when recv data * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_regist_recvcb(struct espconn *espconn, espconn_recv_callback recv_cb) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_regist_recvcb(struct espconn *espconn, espconn_recv_callback recv_cb) { - if (espconn == NULL) { - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; } - espconn ->recv_callback = recv_cb; + espconn->recv_callback = recv_cb; return ESPCONN_OK; } /****************************************************************************** * FunctionName : espconn_regist_reconcb - * Description : used to specify the function that should be called when connection - * because of err disconnect. - * Parameters : espconn -- espconn to set the err callback - * recon_cb -- err callback function to call when err - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_regist_reconcb(struct espconn *espconn, espconn_reconnect_callback recon_cb) + * Description : used to specify the function that should be called when + *connection because of err disconnect. Parameters : espconn -- espconn to set + *the err callback recon_cb -- err callback function to call when err Returns : + *none + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_regist_reconcb(struct espconn *espconn, espconn_reconnect_callback recon_cb) { - if (espconn == NULL) { - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; } - espconn ->proto.tcp->reconnect_callback = recon_cb; + espconn->proto.tcp->reconnect_callback = recon_cb; return ESPCONN_OK; } /****************************************************************************** * FunctionName : espconn_regist_disconcb - * Description : used to specify the function that should be called when disconnect - * Parameters : espconn -- espconn to set the err callback - * discon_cb -- err callback function to call when err - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_regist_disconcb(struct espconn *espconn, espconn_connect_callback discon_cb) + * Description : used to specify the function that should be called when + *disconnect Parameters : espconn -- espconn to set the err callback discon_cb + *-- err callback function to call when err Returns : none + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_regist_disconcb(struct espconn *espconn, espconn_connect_callback discon_cb) { - if (espconn == NULL) { - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; } - espconn ->proto.tcp->disconnect_callback = discon_cb; + espconn->proto.tcp->disconnect_callback = discon_cb; return ESPCONN_OK; } /****************************************************************************** * FunctionName : espconn_get_connection_info - * Description : used to specify the function that should be called when disconnect - * Parameters : espconn -- espconn to set the err callback - * discon_cb -- err callback function to call when err - * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, uint8 typeflags) + * Description : used to specify the function that should be called when + *disconnect Parameters : espconn -- espconn to set the err callback discon_cb + *-- err callback function to call when err Returns : none + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, uint8 typeflags) { - espconn_msg *plist = NULL; - - if (pespconn == NULL) - return ESPCONN_ARG; - - memset(premot, 0, sizeof(premot)); - pespconn->link_cnt = 0; - plist = plink_active; - switch (pespconn->type){ - case ESPCONN_TCP: - while(plist != NULL){ - if (plist->preverse == pespconn){ - premot[pespconn->link_cnt].state = plist->pespconn->state; - premot[pespconn->link_cnt].remote_port = plist->pcommon.remote_port; - memcpy(premot[pespconn->link_cnt].remote_ip, plist->pcommon.remote_ip, 4); - pespconn->link_cnt ++; - } - plist = plist->pnext; - } - - break; - case ESPCONN_UDP: - while(plist != NULL){ - if (plist->pespconn == pespconn){ - premot[pespconn->link_cnt].state = plist->pespconn->state; - premot[pespconn->link_cnt].remote_port = plist->pcommon.remote_port; - memcpy(premot[pespconn->link_cnt].remote_ip, plist->pcommon.remote_ip, 4); - pespconn->link_cnt ++; - } - plist = plist->pnext; - } - break; - default: - break; - } - *pcon_info = premot; - if (pespconn->link_cnt == 0) - return ESPCONN_ARG; - return ESPCONN_OK; + espconn_msg *plist = NULL; + + if (pespconn == NULL) + return ESPCONN_ARG; + + memset(premot, 0, sizeof(premot)); + pespconn->link_cnt = 0; + plist = plink_active; + switch (pespconn->type) + { + case ESPCONN_TCP: + while (plist != NULL) + { + if (plist->preverse == pespconn) + { + premot[pespconn->link_cnt].state = plist->pespconn->state; + premot[pespconn->link_cnt].remote_port = plist->pcommon.remote_port; + memcpy(premot[pespconn->link_cnt].remote_ip, plist->pcommon.remote_ip, 4); + pespconn->link_cnt++; + } + plist = plist->pnext; + } + + break; + case ESPCONN_UDP: + while (plist != NULL) + { + if (plist->pespconn == pespconn) + { + premot[pespconn->link_cnt].state = plist->pespconn->state; + premot[pespconn->link_cnt].remote_port = plist->pcommon.remote_port; + memcpy(premot[pespconn->link_cnt].remote_ip, plist->pcommon.remote_ip, 4); + pespconn->link_cnt++; + } + plist = plist->pnext; + } + break; + default: + break; + } + *pcon_info = premot; + if (pespconn->link_cnt == 0) + return ESPCONN_ARG; + return ESPCONN_OK; } /****************************************************************************** @@ -939,25 +992,30 @@ espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, ui * Description : The function given as the listen * Parameters : espconn -- the espconn used to listen the connection * Returns : -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_accept(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_accept(struct espconn *espconn) { - sint8 value = ESPCONN_OK; - espconn_msg *plist = NULL; + sint8 value = ESPCONN_OK; + espconn_msg *plist = NULL; - if (espconn == NULL) { + if (espconn == NULL) + { return ESPCONN_ARG; - } else if (espconn ->type != ESPCONN_TCP) - return ESPCONN_ARG; - - /*check the active node information whether is the same as the entity or not*/ - for (plist = plink_active; plist != NULL; plist = plist->pnext){ - if (plist->pespconn && plist->pespconn->type == ESPCONN_TCP){ - if (espconn->proto.tcp->local_port == plist->pespconn->proto.tcp->local_port){ - return ESPCONN_ISCONN; - } - } + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; + + /*check the active node information whether is the same as the entity or + * not*/ + for (plist = plink_active; plist != NULL; plist = plist->pnext) + { + if (plist->pespconn && plist->pespconn->type == ESPCONN_TCP) + { + if (espconn->proto.tcp->local_port == plist->pespconn->proto.tcp->local_port) + { + return ESPCONN_ISCONN; + } + } } value = espconn_tcp_server(espconn); @@ -966,39 +1024,45 @@ espconn_accept(struct espconn *espconn) /****************************************************************************** * FunctionName : espconn_regist_time - * Description : used to specify the time that should be called when don't recv data - * Parameters : espconn -- the espconn used to the connection - * interval -- the timer when don't recv data - * Returns : none -*******************************************************************************/ + * Description : used to specify the time that should be called when don't recv + *data Parameters : espconn -- the espconn used to the connection interval -- + *the timer when don't recv data Returns : none + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_regist_time(struct espconn *espconn, uint32 interval, uint8 type_flag) { - espconn_msg *pnode = NULL; - espconn_msg *ptime_msg = NULL; - bool value = false; - if ((espconn == NULL) || (type_flag > 0x01)) - return ESPCONN_ARG; - - if (type_flag == 0x01){ - /*set the timeout time for one active connection of the server*/ - value = espconn_find_connection(espconn, &pnode); - if (value){ - pnode->pcommon.timeout = interval; - return ESPCONN_OK; - } else - return ESPCONN_ARG; - } else { - /*set the timeout time for all active connection of the server*/ - ptime_msg = pserver_list; - while (ptime_msg != NULL){ - if (ptime_msg->pespconn == espconn){ - ptime_msg->pcommon.timeout = interval; - return ESPCONN_OK; - } - ptime_msg = ptime_msg->pnext; - } - } - return ESPCONN_ARG; + espconn_msg *pnode = NULL; + espconn_msg *ptime_msg = NULL; + bool value = false; + if ((espconn == NULL) || (type_flag > 0x01)) + return ESPCONN_ARG; + + if (type_flag == 0x01) + { + /*set the timeout time for one active connection of the server*/ + value = espconn_find_connection(espconn, &pnode); + if (value) + { + pnode->pcommon.timeout = interval; + return ESPCONN_OK; + } + else + return ESPCONN_ARG; + } + else + { + /*set the timeout time for all active connection of the server*/ + ptime_msg = pserver_list; + while (ptime_msg != NULL) + { + if (ptime_msg->pespconn == espconn) + { + ptime_msg->pcommon.timeout = interval; + return ESPCONN_OK; + } + ptime_msg = ptime_msg->pnext; + } + } + return ESPCONN_ARG; } /****************************************************************************** @@ -1006,29 +1070,33 @@ sint8 ICACHE_FLASH_ATTR espconn_regist_time(struct espconn *espconn, uint32 inte * Description : disconnect with host * Parameters : espconn -- the espconn used to disconnect the connection * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_disconnect(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_disconnect(struct espconn *espconn) { - espconn_msg *pnode = NULL; - bool value = false; + espconn_msg *pnode = NULL; + bool value = false; - if (espconn == NULL) { - return ESPCONN_ARG;; - } else if (espconn ->type != ESPCONN_TCP) - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; /*Find the node depend on the espconn message*/ value = espconn_find_connection(espconn, &pnode); printf("espconn_find_connection %d\n", value); - if (value){ - /*protect for redisconnection*/ - if (espconn->state == ESPCONN_CLOSE) - return ESPCONN_INPROGRESS; - espconn_tcp_disconnect(pnode,0); //1 force, 0 normal - return ESPCONN_OK; - } else - return ESPCONN_ARG; + if (value) + { + /*protect for redisconnection*/ + if (espconn->state == ESPCONN_CLOSE) + return ESPCONN_INPROGRESS; + espconn_tcp_disconnect(pnode, 0); // 1 force, 0 normal + return ESPCONN_OK; + } + else + return ESPCONN_ARG; } /****************************************************************************** @@ -1036,153 +1104,168 @@ espconn_disconnect(struct espconn *espconn) * Description : Forcely abort with host * Parameters : espconn -- the espconn used to disconnect the connection * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_abort(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_abort(struct espconn *espconn) { - espconn_msg *pnode = NULL; - bool value = false; + espconn_msg *pnode = NULL; + bool value = false; - if (espconn == NULL) { - return ESPCONN_ARG;; - } else if (espconn ->type != ESPCONN_TCP) - return ESPCONN_ARG; + if (espconn == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; /*Find the node depend on the espconn message*/ value = espconn_find_connection(espconn, &pnode); - if (value){ - /*protect for redisconnection*/ - if (espconn->state == ESPCONN_CLOSE) - return ESPCONN_INPROGRESS; - espconn_tcp_disconnect(pnode,1); //1 force, 0 normal - return ESPCONN_OK; - } else - return ESPCONN_ARG; + if (value) + { + /*protect for redisconnection*/ + if (espconn->state == ESPCONN_CLOSE) + return ESPCONN_INPROGRESS; + espconn_tcp_disconnect(pnode, 1); // 1 force, 0 normal + return ESPCONN_OK; + } + else + return ESPCONN_ARG; } - /****************************************************************************** * FunctionName : espconn_get_packet_info * Description : get the packet info with host * Parameters : espconn -- the espconn used to disconnect the connection * infoarg -- the packet info * Returns : the errur code -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_get_packet_info(struct espconn *espconn, struct espconn_packet* infoarg) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_get_packet_info(struct espconn *espconn, struct espconn_packet *infoarg) { - espconn_msg *pnode = NULL; - err_t err; - bool value = false; - - if (espconn == NULL || infoarg == NULL) { - return ESPCONN_ARG;; - } else if (espconn->type != ESPCONN_TCP) - return ESPCONN_ARG; - - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value) { - struct tcp_pcb *pcb = pnode->pcommon.pcb; - if (pcb == NULL) - return ESPCONN_ARG; - - pnode->pcommon.packet_info.packseq_nxt = pcb->rcv_nxt; - pnode->pcommon.packet_info.packseqno = pcb->snd_nxt; - pnode->pcommon.packet_info.snd_buf_size = pcb->snd_buf; - pnode->pcommon.packet_info.total_queuelen = TCP_SND_QUEUELEN(0); - pnode->pcommon.packet_info.snd_queuelen = pnode->pcommon.packet_info.total_queuelen - pcb->snd_queuelen; - memcpy(infoarg,(void*)&pnode->pcommon.packet_info, sizeof(struct espconn_packet)); - return ESPCONN_OK; - } else { - switch (espconn->state){ - case ESPCONN_CLOSE: - memcpy(infoarg,(void*)&pktinfo[0], sizeof(struct espconn_packet)); - err = ESPCONN_OK; - break; - case ESPCONN_NONE: - memcpy(infoarg,(void*)&pktinfo[1], sizeof(struct espconn_packet)); - err = ESPCONN_OK; - break; - default: - err = ESPCONN_ARG; - break; - } - return err; - } + espconn_msg *pnode = NULL; + err_t err; + bool value = false; + + if (espconn == NULL || infoarg == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value) + { + struct tcp_pcb *pcb = pnode->pcommon.pcb; + if (pcb == NULL) + return ESPCONN_ARG; + + pnode->pcommon.packet_info.packseq_nxt = pcb->rcv_nxt; + pnode->pcommon.packet_info.packseqno = pcb->snd_nxt; + pnode->pcommon.packet_info.snd_buf_size = pcb->snd_buf; + pnode->pcommon.packet_info.total_queuelen = TCP_SND_QUEUELEN(0); + pnode->pcommon.packet_info.snd_queuelen = pnode->pcommon.packet_info.total_queuelen - pcb->snd_queuelen; + memcpy(infoarg, (void *)&pnode->pcommon.packet_info, sizeof(struct espconn_packet)); + return ESPCONN_OK; + } + else + { + switch (espconn->state) + { + case ESPCONN_CLOSE: + memcpy(infoarg, (void *)&pktinfo[0], sizeof(struct espconn_packet)); + err = ESPCONN_OK; + break; + case ESPCONN_NONE: + memcpy(infoarg, (void *)&pktinfo[1], sizeof(struct espconn_packet)); + err = ESPCONN_OK; + break; + default: + err = ESPCONN_ARG; + break; + } + return err; + } } /****************************************************************************** * FunctionName : espconn_set_opt - * Description : set the option for connections so that we don't end up bouncing - * all connections at the same time . - * Parameters : espconn -- the espconn used to set the connection - * opt -- the option for set - * Returns : the result -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_set_opt(struct espconn *espconn, uint8 opt) + * Description : set the option for connections so that we don't end up + *bouncing all connections at the same time . Parameters : espconn -- the + *espconn used to set the connection opt -- the option for set Returns : + *the result + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_set_opt(struct espconn *espconn, uint8 opt) { - espconn_msg *pnode = NULL; - struct tcp_pcb *tpcb; - bool value = false; - - if (espconn == NULL) { - return ESPCONN_ARG;; - } else if (espconn->type != ESPCONN_TCP) - return ESPCONN_ARG; - - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value) { - pnode->pcommon.espconn_opt |= opt; - tpcb = pnode->pcommon.pcb; - if (espconn_delay_disabled(pnode)) - tcp_nagle_disable(tpcb); - - if (espconn_keepalive_disabled(pnode)) - espconn_keepalive_enable(tpcb); - - return ESPCONN_OK; - } else - return ESPCONN_ARG; + espconn_msg *pnode = NULL; + struct tcp_pcb *tpcb; + bool value = false; + + if (espconn == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value) + { + pnode->pcommon.espconn_opt |= opt; + tpcb = pnode->pcommon.pcb; + if (espconn_delay_disabled(pnode)) + tcp_nagle_disable(tpcb); + + if (espconn_keepalive_disabled(pnode)) + espconn_keepalive_enable(tpcb); + + return ESPCONN_OK; + } + else + return ESPCONN_ARG; } /****************************************************************************** * FunctionName : espconn_clear_opt - * Description : clear the option for connections so that we don't end up bouncing - * all connections at the same time . - * Parameters : espconn -- the espconn used to set the connection - * opt -- the option for clear - * Returns : the result -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_clear_opt(struct espconn *espconn, uint8 opt) + * Description : clear the option for connections so that we don't end up + *bouncing all connections at the same time . Parameters : espconn -- the + *espconn used to set the connection opt -- the option for clear Returns : + *the result + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_clear_opt(struct espconn *espconn, uint8 opt) { - espconn_msg *pnode = NULL; - struct tcp_pcb *tpcb; - bool value = false; - - if (espconn == NULL) { - return ESPCONN_ARG;; - } else if (espconn->type != ESPCONN_TCP) - return ESPCONN_ARG; - - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value) { - pnode->pcommon.espconn_opt &= ~opt; - tpcb = pnode->pcommon.pcb; - if (espconn_keepalive_enabled(pnode)) - espconn_keepalive_disable(tpcb); - - if (espconn_delay_enabled(pnode)) - tcp_nagle_enable(tpcb); - - return ESPCONN_OK; - } else - return ESPCONN_ARG; + espconn_msg *pnode = NULL; + struct tcp_pcb *tpcb; + bool value = false; + + if (espconn == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value) + { + pnode->pcommon.espconn_opt &= ~opt; + tpcb = pnode->pcommon.pcb; + if (espconn_keepalive_enabled(pnode)) + espconn_keepalive_disable(tpcb); + + if (espconn_delay_enabled(pnode)) + tcp_nagle_enable(tpcb); + + return ESPCONN_OK; + } + else + return ESPCONN_ARG; } /****************************************************************************** @@ -1193,42 +1276,48 @@ espconn_clear_opt(struct espconn *espconn, uint8 opt) * level -- the connection's level * value -- the value of time(s) * Returns : access port value -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR espconn_set_keepalive(struct espconn *espconn, uint8 level, void* optarg) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_set_keepalive(struct espconn *espconn, uint8 level, void *optarg) { - espconn_msg *pnode = NULL; - bool value = false; - sint8 ret = ESPCONN_OK; - - if (espconn == NULL || optarg == NULL) { - return ESPCONN_ARG;; - } else if (espconn->type != ESPCONN_TCP) - return ESPCONN_ARG; - - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value && espconn_keepalive_disabled(pnode)) { - struct tcp_pcb *pcb = pnode->pcommon.pcb; - switch (level){ - case ESPCONN_KEEPIDLE: - pcb->keep_idle = 1000 * (u32_t)(*(int*)optarg); - ret = ESPCONN_OK; - break; - case ESPCONN_KEEPINTVL: - pcb->keep_intvl = 1000 * (u32_t)(*(int*)optarg); - ret = ESPCONN_OK; - break; - case ESPCONN_KEEPCNT: - pcb->keep_cnt = (u32_t)(*(int*)optarg); - ret = ESPCONN_OK; - break; - default: - ret = ESPCONN_ARG; - break; - } - return ret; - } else - return ESPCONN_ARG; + espconn_msg *pnode = NULL; + bool value = false; + sint8 ret = ESPCONN_OK; + + if (espconn == NULL || optarg == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value && espconn_keepalive_disabled(pnode)) + { + struct tcp_pcb *pcb = pnode->pcommon.pcb; + switch (level) + { + case ESPCONN_KEEPIDLE: + pcb->keep_idle = 1000 * (u32_t)(*(int *)optarg); + ret = ESPCONN_OK; + break; + case ESPCONN_KEEPINTVL: + pcb->keep_intvl = 1000 * (u32_t)(*(int *)optarg); + ret = ESPCONN_OK; + break; + case ESPCONN_KEEPCNT: + pcb->keep_cnt = (u32_t)(*(int *)optarg); + ret = ESPCONN_OK; + break; + default: + ret = ESPCONN_ARG; + break; + } + return ret; + } + else + return ESPCONN_ARG; } /****************************************************************************** @@ -1238,42 +1327,48 @@ sint8 ICACHE_FLASH_ATTR espconn_set_keepalive(struct espconn *espconn, uint8 lev * Parameters : espconn -- the espconn used to get the connection * level -- the connection's level * Returns : access keep alive value -*******************************************************************************/ + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_get_keepalive(struct espconn *espconn, uint8 level, void *optarg) { - espconn_msg *pnode = NULL; - bool value = false; - sint8 ret = ESPCONN_OK; - - if (espconn == NULL || optarg == NULL) { - return ESPCONN_ARG;; - } else if (espconn->type != ESPCONN_TCP) - return ESPCONN_ARG; - - /*Find the node depend on the espconn message*/ - value = espconn_find_connection(espconn, &pnode); - if (value && espconn_keepalive_disabled(pnode)) { - struct tcp_pcb *pcb = pnode->pcommon.pcb; - switch (level) { - case ESPCONN_KEEPIDLE: - *(int*)optarg = (int)(pcb->keep_idle/1000); - ret = ESPCONN_OK; - break; - case ESPCONN_KEEPINTVL: - *(int*)optarg = (int)(pcb->keep_intvl/1000); - ret = ESPCONN_OK; - break; - case ESPCONN_KEEPCNT: - *(int*)optarg = (int)(pcb->keep_cnt); - ret = ESPCONN_OK; - break; - default: - ret = ESPCONN_ARG; - break; - } - return ret; - } else - return ESPCONN_ARG; + espconn_msg *pnode = NULL; + bool value = false; + sint8 ret = ESPCONN_OK; + + if (espconn == NULL || optarg == NULL) + { + return ESPCONN_ARG; + ; + } + else if (espconn->type != ESPCONN_TCP) + return ESPCONN_ARG; + + /*Find the node depend on the espconn message*/ + value = espconn_find_connection(espconn, &pnode); + if (value && espconn_keepalive_disabled(pnode)) + { + struct tcp_pcb *pcb = pnode->pcommon.pcb; + switch (level) + { + case ESPCONN_KEEPIDLE: + *(int *)optarg = (int)(pcb->keep_idle / 1000); + ret = ESPCONN_OK; + break; + case ESPCONN_KEEPINTVL: + *(int *)optarg = (int)(pcb->keep_intvl / 1000); + ret = ESPCONN_OK; + break; + case ESPCONN_KEEPCNT: + *(int *)optarg = (int)(pcb->keep_cnt); + ret = ESPCONN_OK; + break; + default: + ret = ESPCONN_ARG; + break; + } + return ret; + } + else + return ESPCONN_ARG; } /****************************************************************************** @@ -1281,26 +1376,29 @@ sint8 ICACHE_FLASH_ATTR espconn_get_keepalive(struct espconn *espconn, uint8 lev * Description : disconnect with host * Parameters : espconn -- the espconn used to disconnect the connection * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_delete(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_delete(struct espconn *espconn) { - espconn_msg *pnode = NULL; - bool value = false; + espconn_msg *pnode = NULL; + bool value = false; - if (espconn == NULL) { + if (espconn == NULL) + { return ESPCONN_ARG; - } else if (espconn ->type != ESPCONN_UDP) - return espconn_tcp_delete(espconn); + } + else if (espconn->type != ESPCONN_UDP) + return espconn_tcp_delete(espconn); /*Find the node depend on the espconn message*/ value = espconn_find_connection(espconn, &pnode); - if (value){ - espconn_udp_disconnect(pnode); - return ESPCONN_OK; - } else - return ESPCONN_ARG; + if (value) + { + espconn_udp_disconnect(pnode); + return ESPCONN_OK; + } + else + return ESPCONN_ARG; } /****************************************************************************** @@ -1309,23 +1407,25 @@ espconn_delete(struct espconn *espconn) * all connections at the same time . * Parameters : none * Returns : access port value -*******************************************************************************/ -uint32 ICACHE_FLASH_ATTR -espconn_port(void) + *******************************************************************************/ +uint32 ICACHE_FLASH_ATTR espconn_port(void) { uint32 port = 0; static uint32 randnum = 0; - do { + do + { port = esp_random(); - if (port < 0) { + if (port < 0) + { port = esp_random() - port; } port %= 0xc350; - if (port < 0x400) { + if (port < 0x400) + { port += 0x400; } @@ -1341,20 +1441,20 @@ espconn_port(void) * Description : Resolve a hostname (string) into an IP address. * Parameters : pespconn -- espconn to resolve a hostname * hostname -- the hostname that is to be queried - * addr -- pointer to a ip_addr_t where to store the address if + * addr -- pointer to a ip_addr_t where to store the address if * it is already cached in the dns_table (only valid if * ESPCONN_OK is returned!) * found -- a callback function to be called on success, failure * or timeout (only if ERR_INPROGRESS is returned!) * Returns : err_t return code - * - ESPCONN_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ESPCONN_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. + * - ESPCONN_OK if hostname is a valid IP address string or the + *host name is already in the local names table. + * - ESPCONN_INPROGRESS enqueue a request to be sent to the DNS + *server for resolution if no errors are present. * - ESPCONN_ARG: dns client not initialized or invalid hostname -*******************************************************************************/ -err_t ICACHE_FLASH_ATTR -espconn_gethostbyname(struct espconn *pespconn, const char *hostname, ip_addr_t *addr, dns_found_callback found) + *******************************************************************************/ +err_t ICACHE_FLASH_ATTR espconn_gethostbyname(struct espconn *pespconn, const char *hostname, ip_addr_t *addr, + dns_found_callback found) { return dns_gethostbyname(hostname, addr, found, pespconn); } @@ -1366,10 +1466,5 @@ espconn_gethostbyname(struct espconn *pespconn, const char *hostname, ip_addr_t * be < DNS_MAX_SERVERS = 2 * dnsserver -- IP address of the DNS server to set * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR -espconn_dns_setserver(u8_t numdns, ip_addr_t *dnsserver) -{ - dns_setserver(numdns,dnsserver); -} - + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_dns_setserver(u8_t numdns, ip_addr_t *dnsserver) { dns_setserver(numdns, dnsserver); } diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/espconn_tcp.c b/LuaNode_Esp32/LuaNode32/components/espconn/espconn_tcp.c index 456a5c0..e7d8df7 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/espconn_tcp.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/espconn_tcp.c @@ -7,26 +7,25 @@ * * Modification history: * 2014/3/31, v1.0 create this file. -*******************************************************************************/ + *******************************************************************************/ + +#include "espconn_tcp.h" #include + +#include "esp_types.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" - -#include "lwip/opt.h" -#include "lwip/netif.h" #include "lwip/inet.h" -#include "netif/etharp.h" -#include "lwip/tcp.h" +#include "lwip/init.h" #include "lwip/ip.h" #include "lwip/ip_addr.h" -#include "lwip/init.h" -#include "lwip/memp.h" - -#include "esp_types.h" #include "lwip/mem.h" -#include "espconn_tcp.h" - +#include "lwip/memp.h" +#include "lwip/netif.h" +#include "lwip/opt.h" +#include "lwip/tcp.h" +#include "netif/etharp.h" #define ICACHE_FLASH_ATTR #include "tcp_impl.h" @@ -36,26 +35,22 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif #undef TCP_SND_BUF -#define TCP_SND_BUF(pcb) (2 * TCP_MSS) +#define TCP_SND_BUF(pcb) (2 * TCP_MSS) #undef TCP_WND -#define TCP_WND(pcb) (4 * TCP_MSS) +#define TCP_WND(pcb) (4 * TCP_MSS) extern espconn_msg *plink_active; extern espconn_msg *pserver_list; extern struct espconn_packet pktinfo[2]; -extern struct tcp_pcb ** const tcp_pcb_lists[]; +extern struct tcp_pcb **const tcp_pcb_lists[]; ETSEvent espconn_TaskQueue[espconn_TaskQueueLen]; -static err_t -espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -static void -espconn_client_close(void *arg, struct tcp_pcb *pcb,uint8 type); +static err_t espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +static void espconn_client_close(void *arg, struct tcp_pcb *pcb, uint8 type); -static err_t -espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -static void -espconn_server_close(void *arg, struct tcp_pcb *pcb,uint8 type); +static err_t espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +static void espconn_server_close(void *arg, struct tcp_pcb *pcb, uint8 type); ///////////////////////////////common function///////////////////////////////// /****************************************************************************** @@ -63,59 +58,69 @@ espconn_server_close(void *arg, struct tcp_pcb *pcb,uint8 type); * Description : kill the oldest TCP block * Parameters : none * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_kill_oldest(void) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_kill_oldest(void) { - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - - inactivity = 0; - inactive = NULL; - /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - if ((u32_t) (tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - if (inactive != NULL) { - tcp_abort(inactive); - } - - /* Go through the list of FIN_WAIT_2 pcbs and get the oldest pcb. */ - inactivity = 0; - inactive = NULL; - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->state == FIN_WAIT_1 || pcb->state == FIN_WAIT_2){ - if ((u32_t) (tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - } - /*Purges the PCB, removes it from a PCB list and frees the memory*/ - if (inactive != NULL) { - tcp_pcb_remove(&tcp_active_pcbs, inactive); - memp_free(MEMP_TCP_PCB, inactive); - } - - /* Go through the list of LAST_ACK pcbs and get the oldest pcb. */ - inactivity = 0; - inactive = NULL; - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->state == LAST_ACK) { - if ((u32_t) (tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - } - /*Purges the PCB, removes it from a PCB list and frees the memory*/ - if (inactive != NULL) { - tcp_pcb_remove(&tcp_active_pcbs, inactive); - memp_free(MEMP_TCP_PCB, inactive); - } + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + inactive = NULL; + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) + { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) + { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + if (inactive != NULL) + { + tcp_abort(inactive); + } + + /* Go through the list of FIN_WAIT_2 pcbs and get the oldest pcb. */ + inactivity = 0; + inactive = NULL; + for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) + { + if (pcb->state == FIN_WAIT_1 || pcb->state == FIN_WAIT_2) + { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) + { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + } + /*Purges the PCB, removes it from a PCB list and frees the memory*/ + if (inactive != NULL) + { + tcp_pcb_remove(&tcp_active_pcbs, inactive); + memp_free(MEMP_TCP_PCB, inactive); + } + + /* Go through the list of LAST_ACK pcbs and get the oldest pcb. */ + inactivity = 0; + inactive = NULL; + for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) + { + if (pcb->state == LAST_ACK) + { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) + { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + } + /*Purges the PCB, removes it from a PCB list and frees the memory*/ + if (inactive != NULL) + { + tcp_pcb_remove(&tcp_active_pcbs, inactive); + memp_free(MEMP_TCP_PCB, inactive); + } } /****************************************************************************** @@ -123,34 +128,41 @@ espconn_kill_oldest(void) * Description : find the oldest TCP block by state * Parameters : none * Returns : none -*******************************************************************************/ + *******************************************************************************/ void ICACHE_FLASH_ATTR espconn_kill_oldest_pcb(void) { - struct tcp_pcb *cpcb = NULL; - uint8 i = 0; - uint8 num_tcp_fin = 0; - for(i = 2; i < 4; i ++){ - for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if (cpcb->state == TIME_WAIT){ - num_tcp_fin ++; - if (num_tcp_fin == MEMP_NUM_TCP_PCB) - break; - } - - if (cpcb->state == FIN_WAIT_1 || cpcb->state == FIN_WAIT_2 || cpcb->state == LAST_ACK){ - num_tcp_fin++; - if (num_tcp_fin == MEMP_NUM_TCP_PCB) - break; - } - } - - if (num_tcp_fin == MEMP_NUM_TCP_PCB){ - num_tcp_fin = 0; - espconn_kill_oldest(); - } else if (cpcb == NULL){ - num_tcp_fin = 0; - } - } + struct tcp_pcb *cpcb = NULL; + uint8 i = 0; + uint8 num_tcp_fin = 0; + for (i = 2; i < 4; i++) + { + for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) + { + if (cpcb->state == TIME_WAIT) + { + num_tcp_fin++; + if (num_tcp_fin == MEMP_NUM_TCP_PCB) + break; + } + + if (cpcb->state == FIN_WAIT_1 || cpcb->state == FIN_WAIT_2 || cpcb->state == LAST_ACK) + { + num_tcp_fin++; + if (num_tcp_fin == MEMP_NUM_TCP_PCB) + break; + } + } + + if (num_tcp_fin == MEMP_NUM_TCP_PCB) + { + num_tcp_fin = 0; + espconn_kill_oldest(); + } + else if (cpcb == NULL) + { + num_tcp_fin = 0; + } + } } /****************************************************************************** @@ -158,34 +170,40 @@ void ICACHE_FLASH_ATTR espconn_kill_oldest_pcb(void) * Description : kill all the TCP block by port * Parameters : none * Returns : none -*******************************************************************************/ + *******************************************************************************/ void ICACHE_FLASH_ATTR espconn_kill_pcb(u16_t port) { - struct tcp_pcb *cpcb = NULL; - uint8 i = 0; - struct tcp_pcb *inactive = NULL; - struct tcp_pcb *prev = NULL; - uint8_t pcb_remove; - /* Check if the address already is in use (on all lists) */ - for (i = 1; i < 4; i++) { - cpcb = *tcp_pcb_lists[i]; - while(cpcb != NULL){ - pcb_remove = 0; - if (cpcb->local_port == port) { - ++pcb_remove; - } - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - /* Remove PCB from tcp_pcb_lists list. */ - inactive = cpcb; - cpcb = inactive->next; - tcp_pcb_remove(tcp_pcb_lists[i], inactive); - memp_free(MEMP_TCP_PCB, inactive); - } else { - cpcb = cpcb->next; - } - } - } + struct tcp_pcb *cpcb = NULL; + uint8 i = 0; + struct tcp_pcb *inactive = NULL; + struct tcp_pcb *prev = NULL; + uint8_t pcb_remove; + /* Check if the address already is in use (on all lists) */ + for (i = 1; i < 4; i++) + { + cpcb = *tcp_pcb_lists[i]; + while (cpcb != NULL) + { + pcb_remove = 0; + if (cpcb->local_port == port) + { + ++pcb_remove; + } + /* If the PCB should be removed, do it. */ + if (pcb_remove) + { + /* Remove PCB from tcp_pcb_lists list. */ + inactive = cpcb; + cpcb = inactive->next; + tcp_pcb_remove(tcp_pcb_lists[i], inactive); + memp_free(MEMP_TCP_PCB, inactive); + } + else + { + cpcb = cpcb->next; + } + } + } } /****************************************************************************** @@ -193,42 +211,51 @@ void ICACHE_FLASH_ATTR espconn_kill_pcb(u16_t port) * Description : find the TCP block which option * Parameters : pcurrent_msg -- the node in the list which active * Returns : TCP block point -*******************************************************************************/ + *******************************************************************************/ struct tcp_pcb *ICACHE_FLASH_ATTR espconn_find_current_pcb(espconn_msg *pcurrent_msg) { - uint16 local_port = pcurrent_msg->pcommon.local_port; - uint32 local_ip = pcurrent_msg->pcommon.local_ip; - uint16 remote_port = pcurrent_msg->pcommon.remote_port; - uint32 remote_ip = *((uint32*)&pcurrent_msg->pcommon.remote_ip); - struct tcp_pcb *find_pcb = NULL; - if (pcurrent_msg ->preverse == NULL){/*Find the server's TCP block*/ - if (local_ip == 0|| local_port == 0) return pcurrent_msg->pcommon.pcb; - - for (find_pcb = tcp_active_pcbs; find_pcb != NULL; find_pcb = find_pcb->next){ - if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip) && - (find_pcb->local_port == local_port) && (find_pcb->local_ip.u_addr.ip4.addr == local_ip)) - return find_pcb; - } - - for (find_pcb = tcp_tw_pcbs; find_pcb != NULL; find_pcb = find_pcb->next){ - if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip) && - (find_pcb->local_port == local_port) && (find_pcb->local_ip.u_addr.ip4.addr == local_ip)) - return find_pcb; - } - } else {/*Find the client's TCP block*/ - if (remote_ip == 0|| remote_port == 0) return pcurrent_msg->pcommon.pcb; - - for (find_pcb = tcp_active_pcbs; find_pcb != NULL; find_pcb = find_pcb->next){ - if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip)) - return find_pcb; - } - - for (find_pcb = tcp_tw_pcbs; find_pcb != NULL; find_pcb = find_pcb->next){ - if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip)) - return find_pcb; - } - } - return NULL; + uint16 local_port = pcurrent_msg->pcommon.local_port; + uint32 local_ip = pcurrent_msg->pcommon.local_ip; + uint16 remote_port = pcurrent_msg->pcommon.remote_port; + uint32 remote_ip = *((uint32 *)&pcurrent_msg->pcommon.remote_ip); + struct tcp_pcb *find_pcb = NULL; + if (pcurrent_msg->preverse == NULL) + { /*Find the server's TCP block*/ + if (local_ip == 0 || local_port == 0) + return pcurrent_msg->pcommon.pcb; + + for (find_pcb = tcp_active_pcbs; find_pcb != NULL; find_pcb = find_pcb->next) + { + if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip) && + (find_pcb->local_port == local_port) && (find_pcb->local_ip.u_addr.ip4.addr == local_ip)) + return find_pcb; + } + + for (find_pcb = tcp_tw_pcbs; find_pcb != NULL; find_pcb = find_pcb->next) + { + if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip) && + (find_pcb->local_port == local_port) && (find_pcb->local_ip.u_addr.ip4.addr == local_ip)) + return find_pcb; + } + } + else + { /*Find the client's TCP block*/ + if (remote_ip == 0 || remote_port == 0) + return pcurrent_msg->pcommon.pcb; + + for (find_pcb = tcp_active_pcbs; find_pcb != NULL; find_pcb = find_pcb->next) + { + if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip)) + return find_pcb; + } + + for (find_pcb = tcp_tw_pcbs; find_pcb != NULL; find_pcb = find_pcb->next) + { + if ((find_pcb->remote_port == remote_port) && (find_pcb->remote_ip.u_addr.ip4.addr == remote_ip)) + return find_pcb; + } + } + return NULL; } /****************************************************************************** @@ -236,57 +263,66 @@ struct tcp_pcb *ICACHE_FLASH_ATTR espconn_find_current_pcb(espconn_msg *pcurrent * Description : reconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_tcp_reconnect(void *arg) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_tcp_reconnect(void *arg) { - espconn_msg *precon_cb = arg; - sint8 re_err = 0; - espconn_buf *perr_buf = NULL; - espconn_buf *perr_back = NULL; - espconn_kill_oldest_pcb(); - if (precon_cb != NULL) { - struct espconn *espconn = precon_cb->preverse; - re_err = precon_cb->pcommon.err; - if (precon_cb->pespconn != NULL){ - if (espconn != NULL){/*Process the server's message block*/ - if (precon_cb->pespconn->proto.tcp != NULL){ - espconn_copy_partial(espconn, precon_cb->pespconn); - espconn_printf("server: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->remote_ip[0], - espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], - espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); - free(precon_cb->pespconn->proto.tcp); - precon_cb->pespconn->proto.tcp = NULL; - } - free(precon_cb->pespconn); - precon_cb->pespconn = NULL; - } else {/*Process the client's message block*/ - espconn = precon_cb->pespconn; - espconn_printf("client: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->local_ip[0], - espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], - espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); - } - } - - /*to prevent memory leaks, ensure that each allocated is deleted*/ - perr_buf = precon_cb->pcommon.pbuf; - while (perr_buf != NULL){ - perr_back = perr_buf; - perr_buf = perr_back->pnext; - espconn_pbuf_delete(&precon_cb->pcommon.pbuf,perr_back); - free(perr_back); - perr_back = NULL; - } - bzero(&pktinfo[1], sizeof(struct espconn_packet)); - memcpy(&pktinfo[1], (void*)&precon_cb->pcommon.packet_info, sizeof(struct espconn_packet)); - free(precon_cb); - precon_cb = NULL; - if (espconn && espconn->proto.tcp && espconn->proto.tcp->reconnect_callback != NULL) { - espconn->proto.tcp->reconnect_callback(espconn, re_err); - } - } else { - espconn_printf("espconn_tcp_reconnect err\n"); - } + espconn_msg *precon_cb = arg; + sint8 re_err = 0; + espconn_buf *perr_buf = NULL; + espconn_buf *perr_back = NULL; + espconn_kill_oldest_pcb(); + if (precon_cb != NULL) + { + struct espconn *espconn = precon_cb->preverse; + re_err = precon_cb->pcommon.err; + if (precon_cb->pespconn != NULL) + { + if (espconn != NULL) + { /*Process the server's message block*/ + if (precon_cb->pespconn->proto.tcp != NULL) + { + espconn_copy_partial(espconn, precon_cb->pespconn); + espconn_printf("server: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->remote_ip[0], + espconn->proto.tcp->remote_ip[1], espconn->proto.tcp->remote_ip[2], + espconn->proto.tcp->remote_ip[3], espconn->proto.tcp->remote_port); + free(precon_cb->pespconn->proto.tcp); + precon_cb->pespconn->proto.tcp = NULL; + } + free(precon_cb->pespconn); + precon_cb->pespconn = NULL; + } + else + { /*Process the client's message block*/ + espconn = precon_cb->pespconn; + espconn_printf("client: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->local_ip[0], + espconn->proto.tcp->local_ip[1], espconn->proto.tcp->local_ip[2], + espconn->proto.tcp->local_ip[3], espconn->proto.tcp->local_port); + } + } + + /*to prevent memory leaks, ensure that each allocated is deleted*/ + perr_buf = precon_cb->pcommon.pbuf; + while (perr_buf != NULL) + { + perr_back = perr_buf; + perr_buf = perr_back->pnext; + espconn_pbuf_delete(&precon_cb->pcommon.pbuf, perr_back); + free(perr_back); + perr_back = NULL; + } + bzero(&pktinfo[1], sizeof(struct espconn_packet)); + memcpy(&pktinfo[1], (void *)&precon_cb->pcommon.packet_info, sizeof(struct espconn_packet)); + free(precon_cb); + precon_cb = NULL; + if (espconn && espconn->proto.tcp && espconn->proto.tcp->reconnect_callback != NULL) + { + espconn->proto.tcp->reconnect_callback(espconn, re_err); + } + } + else + { + espconn_printf("espconn_tcp_reconnect err\n"); + } } /****************************************************************************** @@ -294,100 +330,126 @@ espconn_tcp_reconnect(void *arg) * Description : disconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_tcp_disconnect_successful(void *arg) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_tcp_disconnect_successful(void *arg) { - espconn_msg *pdiscon_cb = arg; - sint8 dis_err = 0; - espconn_buf *pdis_buf = NULL; - espconn_buf *pdis_back = NULL; - espconn_kill_oldest_pcb(); - if (pdiscon_cb != NULL) { - struct espconn *espconn = pdiscon_cb->preverse; - - dis_err = pdiscon_cb->pcommon.err; - if (pdiscon_cb->pespconn != NULL){ - struct tcp_pcb *pcb = NULL; - if (espconn != NULL){/*Process the server's message block*/ - if (pdiscon_cb->pespconn->proto.tcp != NULL && espconn->proto.tcp){ - espconn_copy_partial(espconn, pdiscon_cb->pespconn); - espconn_printf("server: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->remote_ip[0], - espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], - espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); - free(pdiscon_cb->pespconn->proto.tcp); - pdiscon_cb->pespconn->proto.tcp = NULL; - } - free(pdiscon_cb->pespconn); - pdiscon_cb->pespconn = NULL; - } else {/*Process the client's message block*/ - espconn = pdiscon_cb->pespconn; - espconn_printf("client: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->local_ip[0], - espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], - espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); - } - /*process the current TCP block*/ - pcb = espconn_find_current_pcb(pdiscon_cb); - if (pcb != NULL){ - if (espconn_reuse_disabled(pdiscon_cb)) { - struct tcp_pcb *cpcb = NULL; - struct tcp_pcb *prev = NULL; - uint8_t pcb_remove; - espconn_printf("espconn_tcp_disconnect_successful %d, %d\n", pcb->state, pcb->local_port); - cpcb = tcp_tw_pcbs; - while (cpcb != NULL) { - pcb_remove = 0; - if (cpcb->local_port == pcb->local_port) { - ++pcb_remove; - } - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *backup_pcb = NULL; - tcp_pcb_purge(cpcb); - /* Remove PCB from tcp_tw_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("espconn_tcp_delete: middle cpcb != tcp_tw_pcbs",cpcb != tcp_tw_pcbs); - prev->next = cpcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("espconn_tcp_delete: first cpcb == tcp_tw_pcbs",tcp_tw_pcbs == cpcb); - tcp_tw_pcbs = cpcb->next; - } - backup_pcb = cpcb; - cpcb = cpcb->next; - memp_free(MEMP_TCP_PCB, backup_pcb); - } else { - prev = cpcb; - cpcb = cpcb->next; - } - } - - } else { - tcp_arg(pcb, NULL); - tcp_err(pcb, NULL); - } - } - } - - /*to prevent memory leaks, ensure that each allocated is deleted*/ - pdis_buf = pdiscon_cb->pcommon.pbuf; - while (pdis_buf != NULL) { - pdis_back = pdis_buf; - pdis_buf = pdis_back->pnext; - espconn_pbuf_delete(&pdiscon_cb->pcommon.pbuf, pdis_back); - free(pdis_back); - pdis_back = NULL; - } - bzero(&pktinfo[0], sizeof(struct espconn_packet)); - memcpy(&pktinfo[0], (void*)&pdiscon_cb->pcommon.packet_info, sizeof(struct espconn_packet)); - free(pdiscon_cb); - pdiscon_cb = NULL; - if (espconn->proto.tcp && espconn->proto.tcp->disconnect_callback != NULL) { - espconn->proto.tcp->disconnect_callback(espconn); - } - } else { - espconn_printf("espconn_tcp_disconnect err\n"); - } + espconn_msg *pdiscon_cb = arg; + sint8 dis_err = 0; + espconn_buf *pdis_buf = NULL; + espconn_buf *pdis_back = NULL; + espconn_kill_oldest_pcb(); + if (pdiscon_cb != NULL) + { + struct espconn *espconn = pdiscon_cb->preverse; + + dis_err = pdiscon_cb->pcommon.err; + if (pdiscon_cb->pespconn != NULL) + { + struct tcp_pcb *pcb = NULL; + if (espconn != NULL) + { /*Process the server's message block*/ + if (pdiscon_cb->pespconn->proto.tcp != NULL && espconn->proto.tcp) + { + espconn_copy_partial(espconn, pdiscon_cb->pespconn); + espconn_printf("server: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->remote_ip[0], + espconn->proto.tcp->remote_ip[1], espconn->proto.tcp->remote_ip[2], + espconn->proto.tcp->remote_ip[3], espconn->proto.tcp->remote_port); + free(pdiscon_cb->pespconn->proto.tcp); + pdiscon_cb->pespconn->proto.tcp = NULL; + } + free(pdiscon_cb->pespconn); + pdiscon_cb->pespconn = NULL; + } + else + { /*Process the client's message block*/ + espconn = pdiscon_cb->pespconn; + espconn_printf("client: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->local_ip[0], + espconn->proto.tcp->local_ip[1], espconn->proto.tcp->local_ip[2], + espconn->proto.tcp->local_ip[3], espconn->proto.tcp->local_port); + } + /*process the current TCP block*/ + pcb = espconn_find_current_pcb(pdiscon_cb); + if (pcb != NULL) + { + if (espconn_reuse_disabled(pdiscon_cb)) + { + struct tcp_pcb *cpcb = NULL; + struct tcp_pcb *prev = NULL; + uint8_t pcb_remove; + espconn_printf("espconn_tcp_disconnect_successful %d, %d\n", pcb->state, pcb->local_port); + cpcb = tcp_tw_pcbs; + while (cpcb != NULL) + { + pcb_remove = 0; + if (cpcb->local_port == pcb->local_port) + { + ++pcb_remove; + } + /* If the PCB should be removed, do it. */ + if (pcb_remove) + { + struct tcp_pcb *backup_pcb = NULL; + tcp_pcb_purge(cpcb); + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) + { + LWIP_ASSERT( + "espconn_tcp_delete: middle cpcb != " + "tcp_tw_pcbs", + cpcb != tcp_tw_pcbs); + prev->next = cpcb->next; + } + else + { + /* This PCB was the first. */ + LWIP_ASSERT( + "espconn_tcp_delete: first cpcb == " + "tcp_tw_pcbs", + tcp_tw_pcbs == cpcb); + tcp_tw_pcbs = cpcb->next; + } + backup_pcb = cpcb; + cpcb = cpcb->next; + memp_free(MEMP_TCP_PCB, backup_pcb); + } + else + { + prev = cpcb; + cpcb = cpcb->next; + } + } + } + else + { + tcp_arg(pcb, NULL); + tcp_err(pcb, NULL); + } + } + } + + /*to prevent memory leaks, ensure that each allocated is deleted*/ + pdis_buf = pdiscon_cb->pcommon.pbuf; + while (pdis_buf != NULL) + { + pdis_back = pdis_buf; + pdis_buf = pdis_back->pnext; + espconn_pbuf_delete(&pdiscon_cb->pcommon.pbuf, pdis_back); + free(pdis_back); + pdis_back = NULL; + } + bzero(&pktinfo[0], sizeof(struct espconn_packet)); + memcpy(&pktinfo[0], (void *)&pdiscon_cb->pcommon.packet_info, sizeof(struct espconn_packet)); + free(pdiscon_cb); + pdiscon_cb = NULL; + if (espconn->proto.tcp && espconn->proto.tcp->disconnect_callback != NULL) + { + espconn->proto.tcp->disconnect_callback(espconn); + } + } + else + { + espconn_printf("espconn_tcp_disconnect err\n"); + } } /****************************************************************************** @@ -395,7 +457,7 @@ espconn_tcp_disconnect_successful(void *arg) * Description : espconn processing task * Parameters : events -- contain the espconn processing data * Returns : none -*******************************************************************************/ + *******************************************************************************/ // static void ICACHE_FLASH_ATTR // espconn_Task(void *pvParameters) // { @@ -403,7 +465,6 @@ espconn_tcp_disconnect_successful(void *arg) // espconn_msg *task_msg = NULL; // struct espconn *pespconn = NULL; - // while(1){ // vTaskDelay(1000 * 1 / portTICK_PERIOD_MS); // printf("events->sig %d\n", events->sig); @@ -415,61 +476,63 @@ espconn_tcp_disconnect_successful(void *arg) // return; // } -// if (pespconn->proto.tcp->write_finish_fn != NULL) { -// pespconn->proto.tcp->write_finish_fn(pespconn); +// if (pespconn->proto.tcp->write_finish_fn != +// NULL) { +// pespconn->proto.tcp->write_finish_fn(pespconn); // } // } // break; // case SIG_ESPCONN_ERRER: -// /*remove the node from the client's active connection list*/ -// espconn_list_delete(&plink_active, task_msg); -// espconn_tcp_reconnect(task_msg); -// break; -// case SIG_ESPCONN_CLOSE: -// /*remove the node from the client's active connection list*/ -// espconn_list_delete(&plink_active, task_msg); -// espconn_tcp_disconnect_successful(task_msg); -// break; -// default: -// break; +// /*remove the node from the client's active +// connection +// list*/ espconn_list_delete(&plink_active, +// task_msg); espconn_tcp_reconnect(task_msg); break; case +// SIG_ESPCONN_CLOSE: +// /*remove the node from the client's active +// connection +// list*/ espconn_list_delete(&plink_active, +// task_msg); espconn_tcp_disconnect_successful(task_msg); break; +// default: break; // } // } // } -static void ICACHE_FLASH_ATTR -espconn_Task(ETSEvent *events) +static void ICACHE_FLASH_ATTR espconn_Task(ETSEvent *events) { - espconn_msg *task_msg = NULL; - struct espconn *pespconn = NULL; - - printf("events->sig %d\n", events->sig); - task_msg = (espconn_msg *) events->par; - switch (events->sig) { - case SIG_ESPCONN_WRITE: { - pespconn = task_msg->pespconn; - if (pespconn == NULL) { - return; - } - - if (pespconn->proto.tcp->write_finish_fn != NULL) { - pespconn->proto.tcp->write_finish_fn(pespconn); - } - } - break; - case SIG_ESPCONN_ERRER: - /*remove the node from the client's active connection list*/ - espconn_list_delete(&plink_active, task_msg); - espconn_tcp_reconnect(task_msg); - break; - case SIG_ESPCONN_CLOSE: - /*remove the node from the client's active connection list*/ - espconn_list_delete(&plink_active, task_msg); - espconn_tcp_disconnect_successful(task_msg); - break; - default: - break; - } -} + espconn_msg *task_msg = NULL; + struct espconn *pespconn = NULL; + + printf("events->sig %d\n", events->sig); + task_msg = (espconn_msg *)events->par; + switch (events->sig) + { + case SIG_ESPCONN_WRITE: + { + pespconn = task_msg->pespconn; + if (pespconn == NULL) + { + return; + } + if (pespconn->proto.tcp->write_finish_fn != NULL) + { + pespconn->proto.tcp->write_finish_fn(pespconn); + } + } + break; + case SIG_ESPCONN_ERRER: + /*remove the node from the client's active connection list*/ + espconn_list_delete(&plink_active, task_msg); + espconn_tcp_reconnect(task_msg); + break; + case SIG_ESPCONN_CLOSE: + /*remove the node from the client's active connection list*/ + espconn_list_delete(&plink_active, task_msg); + espconn_tcp_disconnect_successful(task_msg); + break; + default: + break; + } +} /****************************************************************************** * FunctionName : espconn_tcp_sent @@ -482,61 +545,72 @@ espconn_Task(ETSEvent *events) * - ESPCONN_MEM. Out of memory. * - ESPCONN_RTE. Could not find route to destination address. * - More errors could be returned by lower protocol layers. -*******************************************************************************/ -err_t ICACHE_FLASH_ATTR -espconn_tcp_sent(void *arg, uint8 *psent, uint16 length) + *******************************************************************************/ +err_t ICACHE_FLASH_ATTR espconn_tcp_sent(void *arg, uint8 *psent, uint16 length) { - espconn_msg *ptcp_sent = (espconn_msg *) arg; + espconn_msg *ptcp_sent = (espconn_msg *)arg; struct tcp_pcb *pcb = NULL; err_t err = 0; u16_t len = 0; uint8_t data_to_send = false; - //espconn_printf("espconn_tcp_sent ptcp_sent %p psent %p length %d\n", ptcp_sent, psent, length); + // espconn_printf("espconn_tcp_sent ptcp_sent %p psent %p length %d\n", + // ptcp_sent, psent, length); /*Check the parameters*/ - if (ptcp_sent == NULL || psent == NULL || length == 0) { + if (ptcp_sent == NULL || psent == NULL || length == 0) + { return ESPCONN_ARG; } /*Set the packet length depend on the sender buffer space*/ pcb = ptcp_sent->pcommon.pcb; - if (tcp_sndbuf(pcb) < length) { + if (tcp_sndbuf(pcb) < length) + { len = tcp_sndbuf(pcb); - } else { + } + else + { len = length; LWIP_ASSERT("length did not fit into uint16!", (len == length)); } - if (len > (2*pcb->mss)) { - len = 2*pcb->mss; + if (len > (2 * pcb->mss)) + { + len = 2 * pcb->mss; } /*Write data for sending, but does not send it immediately*/ - do { - if (espconn_copy_disabled(ptcp_sent)) - err = tcp_write(pcb, psent, len, 1); - else - err = tcp_write(pcb, psent, len, 0); - - if (err == ERR_MEM) { + do + { + if (espconn_copy_disabled(ptcp_sent)) + err = tcp_write(pcb, psent, len, 1); + else + err = tcp_write(pcb, psent, len, 0); + + if (err == ERR_MEM) + { len /= 2; } } while (err == ERR_MEM && len > 1); - /*Find out what we can send and send it, offset the buffer point for next send*/ - if (err == ERR_OK) { - ptcp_sent->pcommon.ptail->punsent = psent + len; - ptcp_sent->pcommon.ptail->unsent = length - len; - err = tcp_output(pcb); - /*If enable the copy option, change the flag for next write*/ - if (espconn_copy_disabled(ptcp_sent)){ - if (ptcp_sent->pcommon.ptail->unsent == 0) { - ptcp_sent->pcommon.write_flag = true; - ets_post(espconn_TaskPrio, SIG_ESPCONN_WRITE, (uint32_t)ptcp_sent); - espconn_printf("ets_post sent\n"); - } - } + /*Find out what we can send and send it, offset the buffer point for next + * send*/ + if (err == ERR_OK) + { + ptcp_sent->pcommon.ptail->punsent = psent + len; + ptcp_sent->pcommon.ptail->unsent = length - len; + err = tcp_output(pcb); + /*If enable the copy option, change the flag for next write*/ + if (espconn_copy_disabled(ptcp_sent)) + { + if (ptcp_sent->pcommon.ptail->unsent == 0) + { + ptcp_sent->pcommon.write_flag = true; + ets_post(espconn_TaskPrio, SIG_ESPCONN_WRITE, (uint32_t)ptcp_sent); + espconn_printf("ets_post sent\n"); + } + } espconn_printf("espconn_tcp_sent err %d\n", err); } return err; @@ -547,18 +621,21 @@ espconn_tcp_sent(void *arg, uint8 *psent, uint16 length) * Description : The connection has been successfully closed. * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ -void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon,uint8 type) + *******************************************************************************/ +void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon, uint8 type) { - if (pdiscon != NULL){ - /*disconnect with the host by send the FIN frame*/ - if (pdiscon->preverse != NULL) - espconn_server_close(pdiscon, pdiscon->pcommon.pcb,type); - else - espconn_client_close(pdiscon, pdiscon->pcommon.pcb,type); - } else{ - espconn_printf("espconn_tcp_disconnect err.\n"); - } + if (pdiscon != NULL) + { + /*disconnect with the host by send the FIN frame*/ + if (pdiscon->preverse != NULL) + espconn_server_close(pdiscon, pdiscon->pcommon.pcb, type); + else + espconn_client_close(pdiscon, pdiscon->pcommon.pcb, type); + } + else + { + espconn_printf("espconn_tcp_disconnect err.\n"); + } } ///////////////////////////////client function///////////////////////////////// @@ -568,88 +645,96 @@ void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon,uint8 type) * Parameters : pcb -- Additional argument to pass to the callback function * pcb -- the pcb to close * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_client_close(void *arg, struct tcp_pcb *pcb, uint8 type) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_client_close(void *arg, struct tcp_pcb *pcb, uint8 type) { err_t err; espconn_msg *pclose = arg; - pclose->pcommon.pcb = pcb; - /*avoid recalling the disconnect function*/ - tcp_recv(pcb, NULL); - - if(type == 0) - err = tcp_close(pcb); - else - {tcp_abort(pcb); err = ERR_OK;} - - if (err != ERR_OK) { - /* closing failed, try again later */ - tcp_recv(pcb, espconn_client_recv); - } else { - /* closing succeeded */ - tcp_sent(pcb, NULL); - tcp_err(pcb, NULL); - /*switch the state of espconn for application process*/ - pclose->pespconn->state = ESPCONN_CLOSE; - ets_post(espconn_TaskPrio, SIG_ESPCONN_CLOSE, (uint32_t)pclose); - printf("ets_post close\n"); - } + pclose->pcommon.pcb = pcb; + /*avoid recalling the disconnect function*/ + tcp_recv(pcb, NULL); + + if (type == 0) + err = tcp_close(pcb); + else + { + tcp_abort(pcb); + err = ERR_OK; + } + + if (err != ERR_OK) + { + /* closing failed, try again later */ + tcp_recv(pcb, espconn_client_recv); + } + else + { + /* closing succeeded */ + tcp_sent(pcb, NULL); + tcp_err(pcb, NULL); + /*switch the state of espconn for application process*/ + pclose->pespconn->state = ESPCONN_CLOSE; + ets_post(espconn_TaskPrio, SIG_ESPCONN_CLOSE, (uint32_t)pclose); + printf("ets_post close\n"); + } } //***********Code for WIFI_BLOCK from upper************** -sint8 ICACHE_FLASH_ATTR -espconn_recv_hold(struct espconn *pespconn) +sint8 ICACHE_FLASH_ATTR espconn_recv_hold(struct espconn *pespconn) { - //1st, according to espconn code, have to find out the escpconn_msg by pespconn; - espconn_msg *pnode = NULL; - bool value = false; - if (pespconn == NULL) { + // 1st, according to espconn code, have to find out the escpconn_msg by + // pespconn; + espconn_msg *pnode = NULL; + bool value = false; + if (pespconn == NULL) + { return ESPCONN_ARG; } value = espconn_find_connection(pespconn, &pnode); - if(value != true) - { - printf("RecvHold, By pespconn,find conn_msg fail\n"); - return ESPCONN_ARG; - } - - //2nd, the actual operation - if(pnode->recv_hold_flag == 0) - { - pnode->recv_hold_flag = 1; - pnode->recv_holded_buf_Len = 0; - } - return ESPCONN_OK; + if (value != true) + { + printf("RecvHold, By pespconn,find conn_msg fail\n"); + return ESPCONN_ARG; + } + + // 2nd, the actual operation + if (pnode->recv_hold_flag == 0) + { + pnode->recv_hold_flag = 1; + pnode->recv_holded_buf_Len = 0; + } + return ESPCONN_OK; } -sint8 ICACHE_FLASH_ATTR -espconn_recv_unhold(struct espconn *pespconn) +sint8 ICACHE_FLASH_ATTR espconn_recv_unhold(struct espconn *pespconn) { - //1st, according to espconn code, have to find out the escpconn_msg by pespconn; - espconn_msg *pnode = NULL; - bool value = false; - if (pespconn == NULL) { + // 1st, according to espconn code, have to find out the escpconn_msg by + // pespconn; + espconn_msg *pnode = NULL; + bool value = false; + if (pespconn == NULL) + { return ESPCONN_ARG; } value = espconn_find_connection(pespconn, &pnode); - if(value != true) - { - printf("RecvHold, By pespconn,find conn_msg fail\n"); - return ESPCONN_ARG; - } - - //2nd, the actual operation - if(pnode->recv_hold_flag == 1) - { - if(pespconn->type == ESPCONN_TCP) { - tcp_recved(pnode->pcommon.pcb, pnode->recv_holded_buf_Len); - } - pnode->recv_holded_buf_Len = 0; - pnode->recv_hold_flag = 0; - } - return ESPCONN_OK; + if (value != true) + { + printf("RecvHold, By pespconn,find conn_msg fail\n"); + return ESPCONN_ARG; + } + + // 2nd, the actual operation + if (pnode->recv_hold_flag == 1) + { + if (pespconn->type == ESPCONN_TCP) + { + tcp_recved(pnode->pcommon.pcb, pnode->recv_holded_buf_Len); + } + pnode->recv_holded_buf_Len = 0; + pnode->recv_hold_flag = 0; + } + return ESPCONN_OK; } //***********Code for WIFI_BLOCK from upper************** @@ -659,44 +744,47 @@ espconn_recv_unhold(struct espconn *pespconn) * Description : Data has been received on this pcb. * Parameters : arg -- Additional argument to pass to the callback function * pcb -- The connection pcb which received data - * p -- The received data (or NULL when the connection has been closed!) - * err -- An error code if there has been an error receiving - * Returns : ERR_ABRT: if you have called tcp_abort from within the function! -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) + * p -- The received data (or NULL when the connection has been + *closed!) err -- An error code if there has been an error receiving Returns : + *ERR_ABRT: if you have called tcp_abort from within the function! + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { - espconn_msg *precv_cb = arg; + espconn_msg *precv_cb = arg; - tcp_arg(pcb, arg); + tcp_arg(pcb, arg); - if (p != NULL) { - /*To update and advertise a larger window*/ - if(precv_cb->recv_hold_flag == 0) - tcp_recved(pcb, p->tot_len); - else - precv_cb->recv_holded_buf_Len += p->tot_len; + if (p != NULL) + { + /*To update and advertise a larger window*/ + if (precv_cb->recv_hold_flag == 0) + tcp_recved(pcb, p->tot_len); + else + precv_cb->recv_holded_buf_Len += p->tot_len; } - if (err == ERR_OK && p != NULL) { - char *pdata = NULL; - u16_t length = 0; - /*Copy the contents of a packet buffer to an application buffer. - *to prevent memory leaks, ensure that each allocated is deleted*/ - pdata = (char *)malloc(p ->tot_len + 1); - length = pbuf_copy_partial(p, pdata, p ->tot_len, 0); + if (err == ERR_OK && p != NULL) + { + char *pdata = NULL; + u16_t length = 0; + /*Copy the contents of a packet buffer to an application buffer. + *to prevent memory leaks, ensure that each allocated is deleted*/ + pdata = (char *)malloc(p->tot_len + 1); + length = pbuf_copy_partial(p, pdata, p->tot_len, 0); pbuf_free(p); - if (length != 0) { - /*switch the state of espconn for application process*/ - precv_cb->pespconn ->state = ESPCONN_READ; - precv_cb->pcommon.pcb = pcb; - if (precv_cb->pespconn->recv_callback != NULL) { - precv_cb->pespconn->recv_callback(precv_cb->pespconn, pdata, length); + if (length != 0) + { + /*switch the state of espconn for application process*/ + precv_cb->pespconn->state = ESPCONN_READ; + precv_cb->pcommon.pcb = pcb; + if (precv_cb->pespconn->recv_callback != NULL) + { + precv_cb->pespconn->recv_callback(precv_cb->pespconn, pdata, length); } /*switch the state of espconn for next packet copy*/ if (pcb->state == ESTABLISHED) - precv_cb->pespconn ->state = ESPCONN_CONNECT; + precv_cb->pespconn->state = ESPCONN_CONNECT; } /*to prevent memory leaks, ensure that each allocated is deleted*/ @@ -704,8 +792,9 @@ espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) pdata = NULL; } - if (err == ERR_OK && p == NULL) { - espconn_client_close(precv_cb, pcb,0); + if (err == ERR_OK && p == NULL) + { + espconn_client_close(precv_cb, pcb, 0); } return ERR_OK; @@ -717,32 +806,36 @@ espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) * Parameters : arg -- the node pointer which reverse the packet * Returns : ESPCONN_MEM: memory error * ESPCONN_OK:have enough space for write packet -*******************************************************************************/ + *******************************************************************************/ err_t ICACHE_FLASH_ATTR espconn_tcp_write(void *arg) { - espconn_msg *pwrite = (espconn_msg *) arg; - err_t err = ERR_OK; - struct tcp_pcb *pcb = (struct tcp_pcb *)(pwrite->pcommon.pcb); - /*for one active connection,limit the sender buffer space*/ - if (tcp_nagle_disabled(pcb) && (pcb->snd_queuelen >= TCP_SND_QUEUELEN(0))) - return ESPCONN_MEM; - - while (tcp_sndbuf(pcb) != 0){ - if (pwrite->pcommon.ptail != NULL) { - /*Find the node whether in the list's tail or not*/ - if (pwrite->pcommon.ptail->unsent == 0) { - pwrite->pcommon.ptail = pwrite->pcommon.ptail->pnext; - continue; - } - - /*Send the packet for the active connection*/ - err = espconn_tcp_sent(pwrite, pwrite->pcommon.ptail->punsent,pwrite->pcommon.ptail->unsent); - if (err != ERR_OK) - break; - } else - break; - } - return err; + espconn_msg *pwrite = (espconn_msg *)arg; + err_t err = ERR_OK; + struct tcp_pcb *pcb = (struct tcp_pcb *)(pwrite->pcommon.pcb); + /*for one active connection,limit the sender buffer space*/ + if (tcp_nagle_disabled(pcb) && (pcb->snd_queuelen >= TCP_SND_QUEUELEN(0))) + return ESPCONN_MEM; + + while (tcp_sndbuf(pcb) != 0) + { + if (pwrite->pcommon.ptail != NULL) + { + /*Find the node whether in the list's tail or not*/ + if (pwrite->pcommon.ptail->unsent == 0) + { + pwrite->pcommon.ptail = pwrite->pcommon.ptail->pnext; + continue; + } + + /*Send the packet for the active connection*/ + err = espconn_tcp_sent(pwrite, pwrite->pcommon.ptail->punsent, pwrite->pcommon.ptail->unsent); + if (err != ERR_OK) + break; + } + else + break; + } + return err; } /****************************************************************************** @@ -750,32 +843,36 @@ err_t ICACHE_FLASH_ATTR espconn_tcp_write(void *arg) * Description : reconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none -*******************************************************************************/ + *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_tcp_finish(void *arg) { - espconn_msg *pfinish = arg; - espconn_buf *premove = NULL; - uint16 len = 0; - espconn_tcp_write(pfinish); - while (pfinish->pcommon.pbuf != NULL){ - premove = pfinish->pcommon.pbuf; - pfinish->pcommon.pbuf->tot_len += len; - /*application packet has been sent and acknowledged by the remote host, - * to prevent memory leaks, ensure that each allocated is deleted*/ - if (premove->tot_len >= premove->len){ - espconn_pbuf_delete(&pfinish->pcommon.pbuf,premove); - len = premove->tot_len - premove->len; - pfinish->pcommon.packet_info.sent_length = premove->len; - free(premove); - premove = NULL; - pfinish->pespconn->state = ESPCONN_CONNECT; - if (pfinish->pespconn->sent_callback != NULL) { - pfinish->pespconn->sent_callback(pfinish->pespconn); - } - pfinish->pcommon.packet_info.sent_length = len; - } else - break; - } + espconn_msg *pfinish = arg; + espconn_buf *premove = NULL; + uint16 len = 0; + espconn_tcp_write(pfinish); + while (pfinish->pcommon.pbuf != NULL) + { + premove = pfinish->pcommon.pbuf; + pfinish->pcommon.pbuf->tot_len += len; + /*application packet has been sent and acknowledged by the remote host, + * to prevent memory leaks, ensure that each allocated is deleted*/ + if (premove->tot_len >= premove->len) + { + espconn_pbuf_delete(&pfinish->pcommon.pbuf, premove); + len = premove->tot_len - premove->len; + pfinish->pcommon.packet_info.sent_length = premove->len; + free(premove); + premove = NULL; + pfinish->pespconn->state = ESPCONN_CONNECT; + if (pfinish->pespconn->sent_callback != NULL) + { + pfinish->pespconn->sent_callback(pfinish->pespconn); + } + pfinish->pcommon.packet_info.sent_length = len; + } + else + break; + } } /****************************************************************************** @@ -786,19 +883,19 @@ static void ICACHE_FLASH_ATTR espconn_tcp_finish(void *arg) * pcb -- The connection pcb for which data has been acknowledged * len -- The amount of bytes acknowledged * Returns : ERR_OK: try to send some data by calling tcp_output - * ERR_ABRT: if you have called tcp_abort from within the function! -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_client_sent(void *arg, struct tcp_pcb *pcb, u16_t len) + * ERR_ABRT: if you have called tcp_abort from within the + *function! + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_client_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { - espconn_msg *psent_cb = arg; + espconn_msg *psent_cb = arg; - psent_cb->pcommon.pcb = pcb; - psent_cb->pcommon.pbuf->tot_len += len; - psent_cb->pcommon.packet_info.sent_length = len; + psent_cb->pcommon.pcb = pcb; + psent_cb->pcommon.pbuf->tot_len += len; + psent_cb->pcommon.packet_info.sent_length = len; - /*Send more data for one active connection*/ - espconn_tcp_finish(psent_cb); + /*Send more data for one active connection*/ + espconn_tcp_finish(psent_cb); return ERR_OK; } @@ -810,64 +907,77 @@ espconn_client_sent(void *arg, struct tcp_pcb *pcb, u16_t len) * Parameters : arg -- Additional argument to pass to the callback function * err -- Error code to indicate why the pcb has been closed * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_client_err(void *arg, err_t err) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_client_err(void *arg, err_t err) { - espconn_msg *perr_cb = arg; - struct tcp_pcb *pcb = NULL; + espconn_msg *perr_cb = arg; + struct tcp_pcb *pcb = NULL; LWIP_UNUSED_ARG(err); - if (perr_cb != NULL) { + if (perr_cb != NULL) + { pcb = perr_cb->pcommon.pcb; perr_cb->pespconn->state = ESPCONN_CLOSE; espconn_printf("espconn_client_err %d %d %d\n", pcb->state, pcb->nrtx, err); -// /*remove the node from the client's active connection list*/ -// espconn_list_delete(&plink_active, perr_cb); + // /*remove the node from the client's active connection list*/ + // espconn_list_delete(&plink_active, perr_cb); /*Set the error code depend on the error type and control block state*/ - if (err == ERR_ABRT) { - switch (pcb->state) { - case SYN_SENT: - if (pcb->nrtx == TCP_SYNMAXRTX) { - perr_cb->pcommon.err = ESPCONN_CONN; - } else { - perr_cb->pcommon.err = err; - } - - break; - - case ESTABLISHED: - if (pcb->nrtx == TCP_MAXRTX) { - perr_cb->pcommon.err = ESPCONN_TIMEOUT; - } else { - perr_cb->pcommon.err = err; - } - break; - - case FIN_WAIT_1: - if (pcb->nrtx == TCP_MAXRTX) { - perr_cb->pcommon.err = ESPCONN_CLSD; - } else { - perr_cb->pcommon.err = err; - } - break; - case FIN_WAIT_2: - perr_cb->pcommon.err = ESPCONN_CLSD; - break; - case CLOSED: - perr_cb->pcommon.err = ESPCONN_CONN; - break; - default: - break; - } - } else { - perr_cb->pcommon.err = err; - } - /*post the singer to the task for processing the connection*/ - ets_post(espconn_TaskPrio, SIG_ESPCONN_ERRER, (uint32_t)perr_cb); - } + if (err == ERR_ABRT) + { + switch (pcb->state) + { + case SYN_SENT: + if (pcb->nrtx == TCP_SYNMAXRTX) + { + perr_cb->pcommon.err = ESPCONN_CONN; + } + else + { + perr_cb->pcommon.err = err; + } + + break; + + case ESTABLISHED: + if (pcb->nrtx == TCP_MAXRTX) + { + perr_cb->pcommon.err = ESPCONN_TIMEOUT; + } + else + { + perr_cb->pcommon.err = err; + } + break; + + case FIN_WAIT_1: + if (pcb->nrtx == TCP_MAXRTX) + { + perr_cb->pcommon.err = ESPCONN_CLSD; + } + else + { + perr_cb->pcommon.err = err; + } + break; + case FIN_WAIT_2: + perr_cb->pcommon.err = ESPCONN_CLSD; + break; + case CLOSED: + perr_cb->pcommon.err = ESPCONN_CONN; + break; + default: + break; + } + } + else + { + perr_cb->pcommon.err = err; + } + /*post the singer to the task for processing the connection*/ + ets_post(espconn_TaskPrio, SIG_ESPCONN_ERRER, (uint32_t)perr_cb); + } } /****************************************************************************** @@ -877,48 +987,51 @@ espconn_client_err(void *arg, err_t err) * tpcb -- The connection pcb which is connected * err -- An unused error code, always ERR_OK currently * Returns : connection result -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err) + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err) { espconn_msg *pcon = arg; espconn_printf("espconn_client_connect pcon %p tpcb %p\n", pcon, tpcb); - if (err == ERR_OK){ - /*Reserve the remote information for current active connection*/ - pcon->pespconn->state = ESPCONN_CONNECT; - pcon->pcommon.err = err; - pcon->pcommon.pcb = tpcb; - pcon->pcommon.local_port = tpcb->local_port; - pcon->pcommon.local_ip = tpcb->local_ip.u_addr.ip4.addr; - pcon->pcommon.remote_port = tpcb->remote_port; - pcon->pcommon.remote_ip[0] = ip4_addr1_16(&tpcb->remote_ip.u_addr.ip4); - pcon->pcommon.remote_ip[1] = ip4_addr2_16(&tpcb->remote_ip.u_addr.ip4); - pcon->pcommon.remote_ip[2] = ip4_addr3_16(&tpcb->remote_ip.u_addr.ip4); - pcon->pcommon.remote_ip[3] = ip4_addr4_16(&tpcb->remote_ip.u_addr.ip4); - pcon->pcommon.write_flag = true; - tcp_arg(tpcb, (void *) pcon); - - /*Set the specify function that should be called - * when TCP data has been successfully delivered, - * when active connection receives data*/ - tcp_sent(tpcb, espconn_client_sent); - tcp_recv(tpcb, espconn_client_recv); - /*Disable Nagle algorithm default*/ - tcp_nagle_disable(tpcb); - /*Default set the total number of espconn_buf on the unsent lists for one*/ - espconn_tcp_set_buf_count(pcon->pespconn, 1); - - if (pcon->pespconn->proto.tcp->connect_callback != NULL) { - pcon->pespconn->proto.tcp->connect_callback(pcon->pespconn); - } - - /*Enable keep alive option*/ - if (espconn_keepalive_disabled(pcon)) - espconn_keepalive_enable(tpcb); - - } else{ - printf("err in host connected (%s)\n",lwip_strerr(err)); + if (err == ERR_OK) + { + /*Reserve the remote information for current active connection*/ + pcon->pespconn->state = ESPCONN_CONNECT; + pcon->pcommon.err = err; + pcon->pcommon.pcb = tpcb; + pcon->pcommon.local_port = tpcb->local_port; + pcon->pcommon.local_ip = tpcb->local_ip.u_addr.ip4.addr; + pcon->pcommon.remote_port = tpcb->remote_port; + pcon->pcommon.remote_ip[0] = ip4_addr1_16(&tpcb->remote_ip.u_addr.ip4); + pcon->pcommon.remote_ip[1] = ip4_addr2_16(&tpcb->remote_ip.u_addr.ip4); + pcon->pcommon.remote_ip[2] = ip4_addr3_16(&tpcb->remote_ip.u_addr.ip4); + pcon->pcommon.remote_ip[3] = ip4_addr4_16(&tpcb->remote_ip.u_addr.ip4); + pcon->pcommon.write_flag = true; + tcp_arg(tpcb, (void *)pcon); + + /*Set the specify function that should be called + * when TCP data has been successfully delivered, + * when active connection receives data*/ + tcp_sent(tpcb, espconn_client_sent); + tcp_recv(tpcb, espconn_client_recv); + /*Disable Nagle algorithm default*/ + tcp_nagle_disable(tpcb); + /*Default set the total number of espconn_buf on the unsent lists for + * one*/ + espconn_tcp_set_buf_count(pcon->pespconn, 1); + + if (pcon->pespconn->proto.tcp->connect_callback != NULL) + { + pcon->pespconn->proto.tcp->connect_callback(pcon->pespconn); + } + + /*Enable keep alive option*/ + if (espconn_keepalive_disabled(pcon)) + espconn_keepalive_enable(tpcb); + } + else + { + printf("err in host connected (%s)\n", lwip_strerr(err)); } return err; } @@ -929,53 +1042,54 @@ espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err) * the defined port * Parameters : espconn -- the espconn used to build client * Returns : none -*******************************************************************************/ + *******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_tcp_client(struct espconn *espconn) +sint8 ICACHE_FLASH_ATTR espconn_tcp_client(struct espconn *espconn) { struct tcp_pcb *pcb = NULL; ip_addr_t ipaddr; espconn_msg *pclient = NULL; /*Creates a new client control message*/ - pclient = (espconn_msg *)malloc(sizeof(espconn_msg)); - memset(pclient,0,sizeof(espconn_msg)); - if (pclient == NULL){ - return ESPCONN_MEM; - } - - /*Set an IP address given for Little-endian.*/ - ipaddr.type = IPADDR_TYPE_V4; - IP4_ADDR(&ipaddr.u_addr.ip4, espconn->proto.tcp->remote_ip[0], - espconn->proto.tcp->remote_ip[1], - espconn->proto.tcp->remote_ip[2], - espconn->proto.tcp->remote_ip[3]); - - // printf("espconn_tcp_client ipaddr %d:%d:%d:%d\n" - // ,(uint8_t)(ipaddr.u_addr.ip4.addr) - // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>8) - // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>16) - // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>24)); + pclient = (espconn_msg *)malloc(sizeof(espconn_msg)); + memset(pclient, 0, sizeof(espconn_msg)); + if (pclient == NULL) + { + return ESPCONN_MEM; + } + + /*Set an IP address given for Little-endian.*/ + ipaddr.type = IPADDR_TYPE_V4; + IP4_ADDR(&ipaddr.u_addr.ip4, espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1], + espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3]); + + // printf("espconn_tcp_client ipaddr %d:%d:%d:%d\n" + // ,(uint8_t)(ipaddr.u_addr.ip4.addr) + // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>8) + // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>16) + // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>24)); /*Creates a new TCP protocol control block*/ pcb = tcp_new(); - if (pcb == NULL) { - /*to prevent memory leaks, ensure that each allocated is deleted*/ - free(pclient); - pclient = NULL; + if (pcb == NULL) + { + /*to prevent memory leaks, ensure that each allocated is deleted*/ + free(pclient); + pclient = NULL; return ESPCONN_MEM; - } else { - - /*insert the node to the active connection list*/ - espconn_list_creat(&plink_active, pclient); //printf("espconn_msg 3: %p\n", pclient); - tcp_arg(pcb, (void *)pclient); - tcp_err(pcb, espconn_client_err); - pclient->preverse = NULL; - pclient->pespconn = espconn; - pclient->pespconn->state = ESPCONN_WAIT; - pclient->pcommon.pcb = pcb; - tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); + } + else + { + /*insert the node to the active connection list*/ + espconn_list_creat(&plink_active, + pclient); // printf("espconn_msg 3: %p\n", pclient); + tcp_arg(pcb, (void *)pclient); + tcp_err(pcb, espconn_client_err); + pclient->preverse = NULL; + pclient->pespconn = espconn; + pclient->pespconn->state = ESPCONN_WAIT; + pclient->pcommon.pcb = pcb; + tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); #if 0 pclient->pcommon.err = tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); if (pclient->pcommon.err != ERR_OK){ @@ -988,17 +1102,18 @@ espconn_tcp_client(struct espconn *espconn) } #endif /*Establish the connection*/ - pclient->pcommon.err = tcp_connect(pcb, &ipaddr, - pclient->pespconn->proto.tcp->remote_port, espconn_client_connect); - if (pclient->pcommon.err == ERR_RTE){ - /*remove the node from the client's active connection list*/ - printf("fail to connect %s\n",__FILE__); - espconn_list_delete(&plink_active, pclient); - espconn_kill_pcb(pcb->local_port); - free(pclient); - pclient = NULL; - return ESPCONN_RTE; - } + pclient->pcommon.err = + tcp_connect(pcb, &ipaddr, pclient->pespconn->proto.tcp->remote_port, espconn_client_connect); + if (pclient->pcommon.err == ERR_RTE) + { + /*remove the node from the client's active connection list*/ + printf("fail to connect %s\n", __FILE__); + espconn_list_delete(&plink_active, pclient); + espconn_kill_pcb(pcb->local_port); + free(pclient); + pclient = NULL; + return ESPCONN_RTE; + } return pclient->pcommon.err; } } @@ -1010,26 +1125,31 @@ espconn_tcp_client(struct espconn *espconn) * Parameters : arg -- Additional argument to pass to the callback function * pcb -- the pcb to close * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_server_close(void *arg, struct tcp_pcb *pcb,uint8 type) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_server_close(void *arg, struct tcp_pcb *pcb, uint8 type) { err_t err; espconn_msg *psclose = arg; - psclose->pcommon.pcb = pcb; - /*avoid recalling the disconnect function*/ - tcp_recv(pcb, NULL); + psclose->pcommon.pcb = pcb; + /*avoid recalling the disconnect function*/ + tcp_recv(pcb, NULL); - if(type ==0) - err = tcp_close(pcb); - else - {tcp_abort(pcb); err = ERR_OK;} + if (type == 0) + err = tcp_close(pcb); + else + { + tcp_abort(pcb); + err = ERR_OK; + } - if (err != ERR_OK) { + if (err != ERR_OK) + { /* closing failed, try again later */ tcp_recv(pcb, espconn_server_recv); - } else { + } + else + { /* closing succeeded */ tcp_poll(pcb, NULL, 0); tcp_sent(pcb, NULL); @@ -1037,7 +1157,7 @@ espconn_server_close(void *arg, struct tcp_pcb *pcb,uint8 type) /*switch the state of espconn for application process*/ psclose->pespconn->state = ESPCONN_CLOSE; ets_post(espconn_TaskPrio, SIG_ESPCONN_CLOSE, (uint32_t)psclose); - } + } } /****************************************************************************** @@ -1045,68 +1165,74 @@ espconn_server_close(void *arg, struct tcp_pcb *pcb,uint8 type) * Description : Data has been received on this pcb. * Parameters : arg -- Additional argument to pass to the callback function * pcb -- The connection pcb which received data - * p -- The received data (or NULL when the connection has been closed!) - * err -- An error code if there has been an error receiving - * Returns : ERR_ABRT: if you have called tcp_abort from within the function! -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) + * p -- The received data (or NULL when the connection has been + *closed!) err -- An error code if there has been an error receiving Returns : + *ERR_ABRT: if you have called tcp_abort from within the function! + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { - espconn_msg *precv_cb = arg; + espconn_msg *precv_cb = arg; tcp_arg(pcb, arg); - //espconn_printf("server has application data received: \n"); - if (p != NULL) { - /*To update and advertise a larger window*/ - if(precv_cb->recv_hold_flag == 0) - tcp_recved(pcb, p->tot_len); - else - precv_cb->recv_holded_buf_Len += p->tot_len; + // espconn_printf("server has application data received: \n"); + if (p != NULL) + { + /*To update and advertise a larger window*/ + if (precv_cb->recv_hold_flag == 0) + tcp_recved(pcb, p->tot_len); + else + precv_cb->recv_holded_buf_Len += p->tot_len; } - if (err == ERR_OK && p != NULL) { - uint8_t *data_ptr = NULL; - u32_t data_cntr = 0; - /*clear the count for connection timeout*/ - precv_cb->pcommon.recv_check = 0; - /*Copy the contents of a packet buffer to an application buffer. - *to prevent memory leaks, ensure that each allocated is deleted*/ - data_ptr = (uint8_t *)malloc(p ->tot_len + 1); - data_cntr = pbuf_copy_partial(p, data_ptr, p ->tot_len, 0); + if (err == ERR_OK && p != NULL) + { + uint8_t *data_ptr = NULL; + u32_t data_cntr = 0; + /*clear the count for connection timeout*/ + precv_cb->pcommon.recv_check = 0; + /*Copy the contents of a packet buffer to an application buffer. + *to prevent memory leaks, ensure that each allocated is deleted*/ + data_ptr = (uint8_t *)malloc(p->tot_len + 1); + data_cntr = pbuf_copy_partial(p, data_ptr, p->tot_len, 0); pbuf_free(p); - if (data_cntr != 0) { - /*switch the state of espconn for application process*/ - precv_cb->pespconn ->state = ESPCONN_READ; - precv_cb->pcommon.pcb = pcb; - /*espconn_printf("server prepare to call callback: \n"); - if (precv_cb->pespconn->proto.tcp->connect_callback == NULL) { - espconn_printf("connect_callback is null! \n"); - } else { - espconn_printf("connect_callback is not null! \n"); - }*/ - if (precv_cb->pespconn->recv_callback != NULL) { - //espconn_printf("server has called callback: \n"); - precv_cb->pespconn->recv_callback(precv_cb->pespconn, (char*)data_ptr, data_cntr); + if (data_cntr != 0) + { + /*switch the state of espconn for application process*/ + precv_cb->pespconn->state = ESPCONN_READ; + precv_cb->pcommon.pcb = pcb; + /*espconn_printf("server prepare to call callback: \n"); + if (precv_cb->pespconn->proto.tcp->connect_callback == NULL) { + espconn_printf("connect_callback is null! \n"); + } else { + espconn_printf("connect_callback is not null! \n"); + }*/ + if (precv_cb->pespconn->recv_callback != NULL) + { + // espconn_printf("server has called callback: \n"); + precv_cb->pespconn->recv_callback(precv_cb->pespconn, (char *)data_ptr, data_cntr); } /*else { - espconn_printf("recv_callback is null! \n"); - }*/ + espconn_printf("recv_callback is null! \n"); + }*/ /*switch the state of espconn for next packet copy*/ if (pcb->state == ESTABLISHED) - precv_cb->pespconn ->state = ESPCONN_CONNECT; + precv_cb->pespconn->state = ESPCONN_CONNECT; } /*to prevent memory leaks, ensure that each allocated is deleted*/ free(data_ptr); data_ptr = NULL; - //espconn_printf("server's application data has been processed: \n"); - } else { - if (p != NULL) { + // espconn_printf("server's application data has been processed: \n"); + } + else + { + if (p != NULL) + { pbuf_free(p); } - espconn_server_close(precv_cb, pcb,0); + espconn_server_close(precv_cb, pcb, 0); } return ERR_OK; @@ -1120,42 +1246,43 @@ espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) * pcb -- The connection pcb for which data has been acknowledged * len -- The amount of bytes acknowledged * Returns : ERR_OK: try to send some data by calling tcp_output - * ERR_ABRT: if you have called tcp_abort from within the function! -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) + * ERR_ABRT: if you have called tcp_abort from within the + *function! + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { - espconn_msg *psent_cb = arg; + espconn_msg *psent_cb = arg; - psent_cb->pcommon.pcb = pcb; - psent_cb->pcommon.recv_check = 0; - psent_cb->pcommon.pbuf->tot_len += len; - psent_cb->pcommon.packet_info.sent_length = len; + psent_cb->pcommon.pcb = pcb; + psent_cb->pcommon.recv_check = 0; + psent_cb->pcommon.pbuf->tot_len += len; + psent_cb->pcommon.packet_info.sent_length = len; - /*Send more data for one active connection*/ - espconn_tcp_finish(psent_cb); + /*Send more data for one active connection*/ + espconn_tcp_finish(psent_cb); return ERR_OK; } /****************************************************************************** * FunctionName : espconn_server_poll * Description : The poll function is called every 3nd second. - * If there has been no data sent (which resets the retries) in 3 seconds, close. - * If the last portion of a file has not been sent in 3 seconds, close. + * If there has been no data sent (which resets the retries) in 3 seconds, + *close. If the last portion of a file has not been sent in 3 seconds, close. * - * This could be increased, but we don't want to waste resources for bad connections. - * Parameters : arg -- Additional argument to pass to the callback function - * pcb -- The connection pcb for which data has been acknowledged + * This could be increased, but we don't want to waste resources for bad + *connections. Parameters : arg -- Additional argument to pass to the callback + *function pcb -- The connection pcb for which data has been acknowledged * Returns : ERR_OK: try to send some data by calling tcp_output - * ERR_ABRT: if you have called tcp_abort from within the function! -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_server_poll(void *arg, struct tcp_pcb *pcb) + * ERR_ABRT: if you have called tcp_abort from within the + *function! + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_server_poll(void *arg, struct tcp_pcb *pcb) { - espconn_msg *pspoll_cb = arg; + espconn_msg *pspoll_cb = arg; - /*exception calling abandon the connection for send a RST frame*/ - if (arg == NULL) { + /*exception calling abandon the connection for send a RST frame*/ + if (arg == NULL) + { tcp_abandon(pcb, 0); tcp_poll(pcb, NULL, 0); return ERR_OK; @@ -1163,32 +1290,45 @@ espconn_server_poll(void *arg, struct tcp_pcb *pcb) espconn_printf("espconn_server_poll %d %d\n", pspoll_cb->pcommon.recv_check, pcb->state); pspoll_cb->pcommon.pcb = pcb; - if (pcb->state == ESTABLISHED) { - pspoll_cb->pcommon.recv_check++; - if (pspoll_cb->pcommon.timeout != 0){/*no data sent in one active connection's set timeout, close.*/ - if (pspoll_cb->pcommon.recv_check >= pspoll_cb->pcommon.timeout) { - pspoll_cb->pcommon.recv_check = 0; - espconn_server_close(pspoll_cb, pcb,0); - } - } else { - espconn_msg *ptime_msg = pserver_list; - while (ptime_msg != NULL) { - if (ptime_msg->pespconn == pspoll_cb->preverse){ - if (ptime_msg->pcommon.timeout != 0){/*no data sent in server's set timeout, close.*/ - if (pspoll_cb->pcommon.recv_check >= ptime_msg->pcommon.timeout){ - pspoll_cb->pcommon.recv_check = 0; - espconn_server_close(pspoll_cb, pcb,0); - } - } else {/*don't close for ever*/ - pspoll_cb->pcommon.recv_check = 0; - } - break; - } - ptime_msg = ptime_msg->pnext; - } - } - } else { - espconn_server_close(pspoll_cb, pcb,0); + if (pcb->state == ESTABLISHED) + { + pspoll_cb->pcommon.recv_check++; + if (pspoll_cb->pcommon.timeout != 0) + { /*no data sent in one active connection's set timeout, close.*/ + if (pspoll_cb->pcommon.recv_check >= pspoll_cb->pcommon.timeout) + { + pspoll_cb->pcommon.recv_check = 0; + espconn_server_close(pspoll_cb, pcb, 0); + } + } + else + { + espconn_msg *ptime_msg = pserver_list; + while (ptime_msg != NULL) + { + if (ptime_msg->pespconn == pspoll_cb->preverse) + { + if (ptime_msg->pcommon.timeout != 0) + { /*no data sent in server's set timeout, close.*/ + if (pspoll_cb->pcommon.recv_check >= ptime_msg->pcommon.timeout) + { + pspoll_cb->pcommon.recv_check = 0; + espconn_server_close(pspoll_cb, pcb, 0); + } + } + else + { /*don't close for ever*/ + pspoll_cb->pcommon.recv_check = 0; + } + break; + } + ptime_msg = ptime_msg->pnext; + } + } + } + else + { + espconn_server_close(pspoll_cb, pcb, 0); } return ERR_OK; @@ -1201,63 +1341,75 @@ espconn_server_poll(void *arg, struct tcp_pcb *pcb) * Parameters : arg -- Additional argument to pass to the callback function * err -- Error code to indicate why the pcb has been closed * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -esponn_server_err(void *arg, err_t err) + *******************************************************************************/ +static void ICACHE_FLASH_ATTR esponn_server_err(void *arg, err_t err) { - espconn_msg *pserr_cb = arg; - struct tcp_pcb *pcb = NULL; - if (pserr_cb != NULL) { - - pcb = pserr_cb->pcommon.pcb; - pserr_cb->pespconn->state = ESPCONN_CLOSE; - -// /*remove the node from the server's active connection list*/ -// espconn_list_delete(&plink_active, pserr_cb); - - /*Set the error code depend on the error type and control block state*/ - if (err == ERR_ABRT) { - switch (pcb->state) { - case SYN_RCVD: - if (pcb->nrtx == TCP_SYNMAXRTX) { - pserr_cb->pcommon.err = ESPCONN_CONN; - } else { - pserr_cb->pcommon.err = err; - } - - break; - - case ESTABLISHED: - if (pcb->nrtx == TCP_MAXRTX) { - pserr_cb->pcommon.err = ESPCONN_TIMEOUT; - } else { - pserr_cb->pcommon.err = err; - } - - break; - - case CLOSE_WAIT: - if (pcb->nrtx == TCP_MAXRTX) { - pserr_cb->pcommon.err = ESPCONN_CLSD; - } else { - pserr_cb->pcommon.err = err; - } - break; - case LAST_ACK: - pserr_cb->pcommon.err = ESPCONN_CLSD; - break; - - case CLOSED: - pserr_cb->pcommon.err = ESPCONN_CONN; - break; - default : - break; - } - } else { - pserr_cb->pcommon.err = err; - } - /*post the singer to the task for processing the connection*/ - ets_post(espconn_TaskPrio, SIG_ESPCONN_ERRER, (uint32_t)pserr_cb); + espconn_msg *pserr_cb = arg; + struct tcp_pcb *pcb = NULL; + if (pserr_cb != NULL) + { + pcb = pserr_cb->pcommon.pcb; + pserr_cb->pespconn->state = ESPCONN_CLOSE; + + // /*remove the node from the server's active connection + // list*/ espconn_list_delete(&plink_active, pserr_cb); + + /*Set the error code depend on the error type and control block state*/ + if (err == ERR_ABRT) + { + switch (pcb->state) + { + case SYN_RCVD: + if (pcb->nrtx == TCP_SYNMAXRTX) + { + pserr_cb->pcommon.err = ESPCONN_CONN; + } + else + { + pserr_cb->pcommon.err = err; + } + + break; + + case ESTABLISHED: + if (pcb->nrtx == TCP_MAXRTX) + { + pserr_cb->pcommon.err = ESPCONN_TIMEOUT; + } + else + { + pserr_cb->pcommon.err = err; + } + + break; + + case CLOSE_WAIT: + if (pcb->nrtx == TCP_MAXRTX) + { + pserr_cb->pcommon.err = ESPCONN_CLSD; + } + else + { + pserr_cb->pcommon.err = err; + } + break; + case LAST_ACK: + pserr_cb->pcommon.err = ESPCONN_CLSD; + break; + + case CLOSED: + pserr_cb->pcommon.err = ESPCONN_CONN; + break; + default: + break; + } + } + else + { + pserr_cb->pcommon.err = err; + } + /*post the singer to the task for processing the connection*/ + ets_post(espconn_TaskPrio, SIG_ESPCONN_ERRER, (uint32_t)pserr_cb); } } @@ -1268,79 +1420,81 @@ esponn_server_err(void *arg, err_t err) * pcb -- The connection pcb which is accepted * err -- An unused error code, always ERR_OK currently * Returns : acception result -*******************************************************************************/ -static err_t ICACHE_FLASH_ATTR -espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err) + *******************************************************************************/ +static err_t ICACHE_FLASH_ATTR espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct espconn *espconn = arg; espconn_msg *paccept = NULL; remot_info *pinfo = NULL; LWIP_UNUSED_ARG(err); - if (!espconn || !espconn->proto.tcp) { - return ERR_ARG; + if (!espconn || !espconn->proto.tcp) + { + return ERR_ARG; } tcp_arg(pcb, paccept); tcp_err(pcb, esponn_server_err); - /*Ensure the active connection is less than the count of active connections on the server*/ - espconn_get_connection_info(espconn, &pinfo , 0); - espconn_printf("espconn_tcp_accept link_cnt: %d\n", espconn->link_cnt); - if (espconn->link_cnt == espconn_tcp_get_max_con_allow(espconn)) - return ERR_ISCONN; - - /*Creates a new active connect control message*/ + /*Ensure the active connection is less than the count of active connections + * on the server*/ + espconn_get_connection_info(espconn, &pinfo, 0); + espconn_printf("espconn_tcp_accept link_cnt: %d\n", espconn->link_cnt); + if (espconn->link_cnt == espconn_tcp_get_max_con_allow(espconn)) + return ERR_ISCONN; + + /*Creates a new active connect control message*/ paccept = (espconn_msg *)malloc(sizeof(espconn_msg)); - memset(paccept, 0, sizeof(espconn_msg)); + memset(paccept, 0, sizeof(espconn_msg)); tcp_arg(pcb, paccept); - if (paccept == NULL) - return ERR_MEM; - /*Insert the node to the active connection list*/ - espconn_list_creat(&plink_active, paccept); + if (paccept == NULL) + return ERR_MEM; + /*Insert the node to the active connection list*/ + espconn_list_creat(&plink_active, paccept); paccept->preverse = espconn; - paccept->pespconn = (struct espconn *)malloc(sizeof(struct espconn)); - if (paccept->pespconn == NULL) - return ERR_MEM; - paccept->pespconn->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp)); - if (paccept->pespconn->proto.tcp == NULL) - return ERR_MEM; - - /*Reserve the remote information for current active connection*/ - paccept->pcommon.pcb = pcb; - - paccept->pcommon.remote_port = pcb->remote_port; - paccept->pcommon.remote_ip[0] = ip4_addr1_16(&pcb->remote_ip.u_addr.ip4); - paccept->pcommon.remote_ip[1] = ip4_addr2_16(&pcb->remote_ip.u_addr.ip4); - paccept->pcommon.remote_ip[2] = ip4_addr3_16(&pcb->remote_ip.u_addr.ip4); - paccept->pcommon.remote_ip[3] = ip4_addr4_16(&pcb->remote_ip.u_addr.ip4); - paccept->pcommon.write_flag = true; - - memcpy(espconn->proto.tcp->remote_ip, paccept->pcommon.remote_ip, 4); - espconn->proto.tcp->remote_port = pcb->remote_port; - espconn->state = ESPCONN_CONNECT; - espconn_copy_partial(paccept->pespconn, espconn); - - /*Set the specify function that should be called - * when TCP data has been successfully delivered, - * when active connection receives data, - * or periodically from active connection*/ - tcp_sent(pcb, espconn_server_sent); - tcp_recv(pcb, espconn_server_recv); - tcp_poll(pcb, espconn_server_poll, 8); /* every 1 seconds */ - /*Disable Nagle algorithm default*/ - tcp_nagle_disable(pcb); - /*Default set the total number of espconn_buf on the unsent lists for one*/ - espconn_tcp_set_buf_count(paccept->pespconn, 1); - - if (paccept->pespconn->proto.tcp->connect_callback != NULL) { - paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn); - } - - /*Enable keep alive option*/ - if (espconn_keepalive_disabled(paccept)) - espconn_keepalive_enable(pcb); + paccept->pespconn = (struct espconn *)malloc(sizeof(struct espconn)); + if (paccept->pespconn == NULL) + return ERR_MEM; + paccept->pespconn->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp)); + if (paccept->pespconn->proto.tcp == NULL) + return ERR_MEM; + + /*Reserve the remote information for current active connection*/ + paccept->pcommon.pcb = pcb; + + paccept->pcommon.remote_port = pcb->remote_port; + paccept->pcommon.remote_ip[0] = ip4_addr1_16(&pcb->remote_ip.u_addr.ip4); + paccept->pcommon.remote_ip[1] = ip4_addr2_16(&pcb->remote_ip.u_addr.ip4); + paccept->pcommon.remote_ip[2] = ip4_addr3_16(&pcb->remote_ip.u_addr.ip4); + paccept->pcommon.remote_ip[3] = ip4_addr4_16(&pcb->remote_ip.u_addr.ip4); + paccept->pcommon.write_flag = true; + + memcpy(espconn->proto.tcp->remote_ip, paccept->pcommon.remote_ip, 4); + espconn->proto.tcp->remote_port = pcb->remote_port; + espconn->state = ESPCONN_CONNECT; + espconn_copy_partial(paccept->pespconn, espconn); + + /*Set the specify function that should be called + * when TCP data has been successfully delivered, + * when active connection receives data, + * or periodically from active connection*/ + tcp_sent(pcb, espconn_server_sent); + tcp_recv(pcb, espconn_server_recv); + tcp_poll(pcb, espconn_server_poll, 8); /* every 1 seconds */ + /*Disable Nagle algorithm default*/ + tcp_nagle_disable(pcb); + /*Default set the total number of espconn_buf on the unsent lists for one*/ + espconn_tcp_set_buf_count(paccept->pespconn, 1); + + if (paccept->pespconn->proto.tcp->connect_callback != NULL) + { + paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn); + } + + /*Enable keep alive option*/ + if (espconn_keepalive_disabled(paccept)) + espconn_keepalive_enable(pcb); return ERR_OK; } @@ -1351,52 +1505,59 @@ espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err) * the defined port * Parameters : espconn -- the espconn used to build server * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_tcp_server(struct espconn *espconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_tcp_server(struct espconn *espconn) { struct tcp_pcb *pcb = NULL; espconn_msg *pserver = NULL; /*Creates a new server control message*/ pserver = (espconn_msg *)malloc(sizeof(espconn_msg)); - if (pserver == NULL){ - return ESPCONN_MEM; + if (pserver == NULL) + { + return ESPCONN_MEM; } - memset(pserver, 0, sizeof(espconn_msg)); + memset(pserver, 0, sizeof(espconn_msg)); /*Creates a new TCP protocol control block*/ pcb = tcp_new(); - if (pcb == NULL) { - /*to prevent memory leaks, ensure that each allocated is deleted*/ - free(pserver); - pserver = NULL; + if (pcb == NULL) + { + /*to prevent memory leaks, ensure that each allocated is deleted*/ + free(pserver); + pserver = NULL; return ESPCONN_MEM; - } else { - struct tcp_pcb *lpcb = NULL; - /*Binds the connection to a local port number and any IP address*/ + } + else + { + struct tcp_pcb *lpcb = NULL; + /*Binds the connection to a local port number and any IP address*/ tcp_bind(pcb, IP_ADDR_ANY, espconn->proto.tcp->local_port); lpcb = pcb; /*malloc and set the state of the connection to be LISTEN*/ pcb = tcp_listen(pcb); - if (pcb != NULL) { - /*insert the node to the active connection list*/ - espconn_list_creat(&pserver_list, pserver); printf("espconn_msg 2: %p\n", pserver); - pserver->preverse = pcb; - pserver->pespconn = espconn; - pserver->count_opt = MEMP_NUM_TCP_PCB; - pserver->pcommon.timeout = 0x0a; - espconn ->state = ESPCONN_LISTEN; + if (pcb != NULL) + { + /*insert the node to the active connection list*/ + espconn_list_creat(&pserver_list, pserver); + printf("espconn_msg 2: %p\n", pserver); + pserver->preverse = pcb; + pserver->pespconn = espconn; + pserver->count_opt = MEMP_NUM_TCP_PCB; + pserver->pcommon.timeout = 0x0a; + espconn->state = ESPCONN_LISTEN; /*set the specify argument that should be passed callback function*/ tcp_arg(pcb, (void *)espconn); /*accept callback function to call for this control block*/ tcp_accept(pcb, espconn_tcp_accept); return ESPCONN_OK; - } else { - /*to prevent memory leaks, ensure that each allocated is deleted*/ - memp_free(MEMP_TCP_PCB,lpcb); - free(pserver); - pserver = NULL; + } + else + { + /*to prevent memory leaks, ensure that each allocated is deleted*/ + memp_free(MEMP_TCP_PCB, lpcb); + free(pserver); + pserver = NULL; return ESPCONN_MEM; } } @@ -1407,43 +1568,46 @@ espconn_tcp_server(struct espconn *espconn) * Description : delete the server: delete a listening PCB and free it * Parameters : pdeletecon -- the espconn used to delete a server * Returns : none -*******************************************************************************/ + *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_delete(struct espconn *pdeletecon) { - err_t err=ESPCONN_ARG; - remot_info *pinfo = NULL; - espconn_msg *pdelete_msg = NULL; - struct tcp_pcb *pcb = NULL; - - if (pdeletecon == NULL) - return ESPCONN_ARG; - - espconn_get_connection_info(pdeletecon, &pinfo , 0); - /*make sure all the active connection have been disconnect*/ - if (pdeletecon->link_cnt != 0) - return ESPCONN_INPROGRESS; - else { - espconn_printf("espconn_tcp_delete %p\n",pdeletecon); - pdelete_msg = pserver_list; - while (pdelete_msg != NULL){ - if (pdelete_msg->pespconn == pdeletecon){ - /*remove the node from the client's active connection list*/ - espconn_list_delete(&pserver_list, pdelete_msg); - pcb = pdelete_msg->preverse; - printf("espconn_tcp_delete %d, %d\n",pcb->state, pcb->local_port); - espconn_kill_pcb(pcb->local_port); - err = tcp_close(pcb); - free(pdelete_msg); - pdelete_msg = NULL; - break; - } - pdelete_msg = pdelete_msg->pnext; - } - if (err == ERR_OK) - return err; - else - return ESPCONN_ARG; - } + err_t err = ESPCONN_ARG; + remot_info *pinfo = NULL; + espconn_msg *pdelete_msg = NULL; + struct tcp_pcb *pcb = NULL; + + if (pdeletecon == NULL) + return ESPCONN_ARG; + + espconn_get_connection_info(pdeletecon, &pinfo, 0); + /*make sure all the active connection have been disconnect*/ + if (pdeletecon->link_cnt != 0) + return ESPCONN_INPROGRESS; + else + { + espconn_printf("espconn_tcp_delete %p\n", pdeletecon); + pdelete_msg = pserver_list; + while (pdelete_msg != NULL) + { + if (pdelete_msg->pespconn == pdeletecon) + { + /*remove the node from the client's active connection list*/ + espconn_list_delete(&pserver_list, pdelete_msg); + pcb = pdelete_msg->preverse; + printf("espconn_tcp_delete %d, %d\n", pcb->state, pcb->local_port); + espconn_kill_pcb(pcb->local_port); + err = tcp_close(pcb); + free(pdelete_msg); + pdelete_msg = NULL; + break; + } + pdelete_msg = pdelete_msg->pnext; + } + if (err == ERR_OK) + return err; + else + return ESPCONN_ARG; + } } /****************************************************************************** @@ -1451,11 +1615,12 @@ sint8 ICACHE_FLASH_ATTR espconn_tcp_delete(struct espconn *pdeletecon) * Description : used to init the function that should be used when * Parameters : none * Returns : none -*******************************************************************************/ + *******************************************************************************/ void ICACHE_FLASH_ATTR espconn_init(void) { - ets_task(espconn_Task, espconn_TaskPrio, espconn_TaskQueue, espconn_TaskQueueLen); - ets_run(); - // espcon_event_t even; - // xTaskCreatePinnedToCore(&espconn_Task, "espconn_Task", 4096, &even, 5, NULL, 0); + ets_task(espconn_Task, espconn_TaskPrio, espconn_TaskQueue, espconn_TaskQueueLen); + ets_run(); + // espcon_event_t even; + // xTaskCreatePinnedToCore(&espconn_Task, "espconn_Task", 4096, &even, 5, + // NULL, 0); } diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c b/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c index 65ca997..15fee88 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/espconn_udp.c @@ -7,34 +7,34 @@ * * Modification history: * 2014/3/31, v1.0 create this file. -*******************************************************************************/ + *******************************************************************************/ // #include "ets_sys.h" // #include "os_type.h" #include -#include "lwip/inet.h" #include "lwip/err.h" -#include "lwip/pbuf.h" +#include "lwip/inet.h" #include "lwip/mem.h" +#include "lwip/pbuf.h" // #include "lwip/tcp_impl.h" -#include "lwip/udp.h" #include "esp_wifi.h" - #include "espconn_udp.h" +#include "lwip/udp.h" -struct ip_info { - ip4_addr_t ip; +struct ip_info +{ + ip4_addr_t ip; ip4_addr_t netmask; ip4_addr_t gw; }; ////////未对以下函数进行实现 #include "tcpip_adapter.h" -extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info* ipinfo); +extern void wifi_get_ip_info(tcpip_adapter_if_t type, struct ip_info *ipinfo); extern uint8 igmp_leavegroup(ip_addr_t *host_ip, ip_addr_t *multicast_ip); extern uint8 igmp_joingroup(ip_addr_t *host_ip, ip_addr_t *multicast_ip); -extern void* eagle_lwip_getif(uint8 type); +extern void *eagle_lwip_getif(uint8 type); #define ICACHE_FLASH_ATTR #ifdef MEMLEAK_DEBUG @@ -42,19 +42,22 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif extern espconn_msg *plink_active; - uint8 default_interface = ESPCONN_AP_STA; +uint8 default_interface = ESPCONN_AP_STA; -enum send_opt{ - ESPCONN_SENDTO, - ESPCONN_SEND +enum send_opt +{ + ESPCONN_SENDTO, + ESPCONN_SEND }; static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn) { - if (pespconn == NULL) { + if (pespconn == NULL) + { return; } - if (pespconn->sent_callback != NULL) { + if (pespconn->sent_callback != NULL) + { pespconn->sent_callback(pespconn); } } @@ -63,20 +66,27 @@ static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt) { espconn_msg *psent = arg; - if (psent == NULL) { + if (psent == NULL) + { return; } - if (psent->pcommon.cntr == 0) { + if (psent->pcommon.cntr == 0) + { psent->pespconn->state = ESPCONN_CONNECT; -// sys_timeout(10, espconn_data_sentcb, psent->pespconn); + // sys_timeout(10, espconn_data_sentcb, psent->pespconn); espconn_data_sentcb(psent->pespconn); - } else { - if (opt == ESPCONN_SEND){ - espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); - } else { - espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); - } + } + else + { + if (opt == ESPCONN_SEND) + { + espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + } + else + { + espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr); + } } } @@ -91,13 +101,12 @@ static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt) * - ESPCONN_MEM. Out of memory. * - ESPCONN_RTE. Could not find route to destination address. * - More errors could be returned by lower protocol layers. -*******************************************************************************/ -err_t ICACHE_FLASH_ATTR -espconn_udp_sent(void *arg, uint8 *psent, uint16 length) + *******************************************************************************/ +err_t ICACHE_FLASH_ATTR espconn_udp_sent(void *arg, uint8 *psent, uint16 length) { espconn_msg *pudp_sent = arg; struct udp_pcb *upcb = pudp_sent->pcommon.pcb; - struct pbuf *p, *q ,*p_temp; + struct pbuf *p, *q, *p_temp; u8_t *data = NULL; u16_t cnt = 0; u16_t datalen = 0; @@ -105,82 +114,91 @@ espconn_udp_sent(void *arg, uint8 *psent, uint16 length) err_t err; LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); - if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { + if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) + { return ESPCONN_ARG; } - if (1470 < length) { + if (1470 < length) + { datalen = 1470; - } else { + } + else + { datalen = length; } p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); - if (p != NULL) { + if (p != NULL) + { q = p; - while (q != NULL) { + while (q != NULL) + { data = (u8_t *)q->payload; LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); - for (i = 0; i < q->len; i++) { - data[i] = ((u8_t *) psent)[cnt++]; - } + for (i = 0; i < q->len; i++) { data[i] = ((u8_t *)psent)[cnt++]; } q = q->next; } - } else { + } + else + { return ESPCONN_MEM; } upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port; IP4_ADDR(&upcb->remote_ip.u_addr.ip4, pudp_sent->pespconn->proto.udp->remote_ip[0], - pudp_sent->pespconn->proto.udp->remote_ip[1], - pudp_sent->pespconn->proto.udp->remote_ip[2], - pudp_sent->pespconn->proto.udp->remote_ip[3]); + pudp_sent->pespconn->proto.udp->remote_ip[1], pudp_sent->pespconn->proto.udp->remote_ip[2], + pudp_sent->pespconn->proto.udp->remote_ip[3]); - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, + ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); - struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); - - sint8 value = ESPCONN_OK; - esp_wifi_get_mode((wifi_mode_t*)&value); - if(value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) + struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); + + sint8 value = ESPCONN_OK; + esp_wifi_get_mode((wifi_mode_t *)&value); + if (value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) { - if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { - - p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - if (pbuf_copy (p_temp,p) != ERR_OK) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n")); - return ESPCONN_ARG; - } - netif_set_default(sta_netif); - err = udp_send(upcb, p_temp); - pbuf_free(p_temp); - netif_set_default(ap_netif); - } + if (netif_is_up(sta_netif) && netif_is_up(ap_netif) && ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && + ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) + { + p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + if (pbuf_copy(p_temp, p) != ERR_OK) + { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n")); + return ESPCONN_ARG; + } + netif_set_default(sta_netif); + err = udp_send(upcb, p_temp); + pbuf_free(p_temp); + netif_set_default(ap_netif); + } } - err = udp_send(upcb, p); + err = udp_send(upcb, p); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err)); - if (p->ref != 0) { + if (p->ref != 0) + { LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); pbuf_free(p); pudp_sent->pcommon.ptrbuf = psent + datalen; pudp_sent->pcommon.cntr = length - datalen; espconn_data_sent(pudp_sent, ESPCONN_SEND); if (err > 0) - return ESPCONN_IF; + return ESPCONN_IF; return err; - } else { - pbuf_free(p); - return ESPCONN_RTE; + } + else + { + pbuf_free(p); + return ESPCONN_RTE; } } @@ -195,14 +213,13 @@ espconn_udp_sent(void *arg, uint8 *psent, uint16 length) * - ESPCONN_MEM. Out of memory. * - ESPCONN_RTE. Could not find route to destination address. * - More errors could be returned by lower protocol layers. -*******************************************************************************/ -err_t ICACHE_FLASH_ATTR -espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) + *******************************************************************************/ +err_t ICACHE_FLASH_ATTR espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) { espconn_msg *pudp_sent = arg; struct udp_pcb *upcb = pudp_sent->pcommon.pcb; struct espconn *pespconn = pudp_sent->pespconn; - struct pbuf *p, *q ,*p_temp; + struct pbuf *p, *q, *p_temp; ip_addr_t dst_ip; u16_t dst_port; u8_t *data = NULL; @@ -212,79 +229,88 @@ espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) err_t err; LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb)); - if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) { + if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) + { return ESPCONN_ARG; } - if (1470 < length) { + if (1470 < length) + { datalen = 1470; - } else { + } + else + { datalen = length; } p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p)); - if (p != NULL) { + if (p != NULL) + { q = p; - while (q != NULL) { + while (q != NULL) + { data = (u8_t *)q->payload; LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data)); - for (i = 0; i < q->len; i++) { - data[i] = ((u8_t *) psent)[cnt++]; - } + for (i = 0; i < q->len; i++) { data[i] = ((u8_t *)psent)[cnt++]; } q = q->next; } - } else { + } + else + { return ESPCONN_MEM; } dst_port = pespconn->proto.udp->remote_port; - IP4_ADDR(&dst_ip.u_addr.ip4, pespconn->proto.udp->remote_ip[0], - pespconn->proto.udp->remote_ip[1], pespconn->proto.udp->remote_ip[2], - pespconn->proto.udp->remote_ip[3]); - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); + IP4_ADDR(&dst_ip.u_addr.ip4, pespconn->proto.udp->remote_ip[0], pespconn->proto.udp->remote_ip[1], + pespconn->proto.udp->remote_ip[2], pespconn->proto.udp->remote_ip[3]); + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, + ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip.u_addr.ip4.addr, upcb->remote_port)); struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00); - struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); - - sint8 value = ESPCONN_OK; - esp_wifi_get_mode((wifi_mode_t*)&value); - if(value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) - { - if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { - - p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - if (pbuf_copy (p_temp,p) != ERR_OK) { - LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); - return ESPCONN_ARG; - } - netif_set_default(sta_netif); - err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); - pbuf_free(p_temp); - netif_set_default(ap_netif); - } - } + struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01); + + sint8 value = ESPCONN_OK; + esp_wifi_get_mode((wifi_mode_t *)&value); + if (value == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) + { + if (netif_is_up(sta_netif) && netif_is_up(ap_netif) && ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && + ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) + { + p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + if (pbuf_copy(p_temp, p) != ERR_OK) + { + LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n")); + return ESPCONN_ARG; + } + netif_set_default(sta_netif); + err = udp_sendto(upcb, p_temp, &dst_ip, dst_port); + pbuf_free(p_temp); + netif_set_default(ap_netif); + } + } err = udp_sendto(upcb, p, &dst_ip, dst_port); - if (p->ref != 0) { - pbuf_free(p); - pudp_sent->pcommon.ptrbuf = psent + datalen; - pudp_sent->pcommon.cntr = length - datalen; - if (err == ERR_OK) - espconn_data_sent(pudp_sent, ESPCONN_SENDTO); - - if (err > 0) - return ESPCONN_IF; - return err; - } else { - pbuf_free(p); - return ESPCONN_RTE; + if (p->ref != 0) + { + pbuf_free(p); + pudp_sent->pcommon.ptrbuf = psent + datalen; + pudp_sent->pcommon.cntr = length - datalen; + if (err == ERR_OK) + espconn_data_sent(pudp_sent, ESPCONN_SENDTO); + + if (err > 0) + return ESPCONN_IF; + return err; + } + else + { + pbuf_free(p); + return ESPCONN_RTE; } } @@ -294,13 +320,12 @@ espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) * Parameters : arg -- user supplied argument * upcb -- the udp_pcb which received data * p -- the packet buffer that was received - * addr -- the remote IP address from which the packet was received - * port -- the remote port from which the packet was received - * Returns : none -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port) + * addr -- the remote IP address from which the packet was + *received port -- the remote port from which the packet was received Returns : + *none + *******************************************************************************/ +static void ICACHE_FLASH_ATTR espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, + u16_t port) { espconn_msg *precv = arg; struct pbuf *q = NULL; @@ -317,35 +342,44 @@ espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, precv->pcommon.remote_port = port; precv->pcommon.pcb = upcb; - sint8 value = ESPCONN_OK; - esp_wifi_get_mode((wifi_mode_t*)&value); - if (value != 1) { - wifi_get_ip_info(1, &ipconfig); - - if (!ip4_addr_netcmp(&addr->u_addr.ip4, &ipconfig.ip, &ipconfig.netmask)) { - wifi_get_ip_info(0, &ipconfig); - } - } else { - wifi_get_ip_info(0, &ipconfig); - } - - precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip); - precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip); - precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip); - precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip); - - if (p != NULL) { - pdata = (u8_t *)malloc(p ->tot_len + 1); - length = pbuf_copy_partial(p, pdata, p ->tot_len, 0); - precv->pcommon.pcb = upcb; + sint8 value = ESPCONN_OK; + esp_wifi_get_mode((wifi_mode_t *)&value); + if (value != 1) + { + wifi_get_ip_info(1, &ipconfig); + + if (!ip4_addr_netcmp(&addr->u_addr.ip4, &ipconfig.ip, &ipconfig.netmask)) + { + wifi_get_ip_info(0, &ipconfig); + } + } + else + { + wifi_get_ip_info(0, &ipconfig); + } + + precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip); + precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip); + precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip); + precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip); + + if (p != NULL) + { + pdata = (u8_t *)malloc(p->tot_len + 1); + length = pbuf_copy_partial(p, pdata, p->tot_len, 0); + precv->pcommon.pcb = upcb; pbuf_free(p); - if (length != 0) { - if (precv->pespconn->recv_callback != NULL) { - precv->pespconn->recv_callback(precv->pespconn, (char*)pdata, length); - } - } - free(pdata); - } else { + if (length != 0) + { + if (precv->pespconn->recv_callback != NULL) + { + precv->pespconn->recv_callback(precv->pespconn, (char *)pdata, length); + } + } + free(pdata); + } + else + { return; } } @@ -355,10 +389,11 @@ espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, * Description : A new incoming connection has been disconnected. * Parameters : espconn -- the espconn used to disconnect with host * Returns : none -*******************************************************************************/ + *******************************************************************************/ void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon) { - if (pdiscon == NULL) { + if (pdiscon == NULL) + { return; } @@ -379,20 +414,23 @@ void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon) * Description : Initialize the server: set up a PCB and bind it to the port * Parameters : pespconn -- the espconn used to build server * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_udp_server(struct espconn *pespconn) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_udp_server(struct espconn *pespconn) { struct udp_pcb *upcb = NULL; espconn_msg *pserver = NULL; upcb = udp_new(); - if (upcb == NULL) { + if (upcb == NULL) + { return ESPCONN_MEM; - } else { + } + else + { pserver = (espconn_msg *)malloc(sizeof(espconn_msg)); - if (pserver == NULL) { + if (pserver == NULL) + { udp_remove(upcb); return ESPCONN_MEM; } @@ -412,11 +450,11 @@ espconn_udp_server(struct espconn *pespconn) * Parameters : host_ip -- the ip address of udp server * multicast_ip -- multicast ip given by user * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip) { - if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) { + if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) + { LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n")); return -1; }; @@ -430,11 +468,11 @@ espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip) * Parameters : host_ip -- the ip address of udp server * multicast_ip -- multicast ip given by user * Returns : none -*******************************************************************************/ -sint8 ICACHE_FLASH_ATTR -espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip) + *******************************************************************************/ +sint8 ICACHE_FLASH_ATTR espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip) { - if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) { + if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) + { LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n")); return -1; }; diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/netio.c b/LuaNode_Esp32/LuaNode32/components/espconn/netio.c index 7eca28b..38aaed2 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/netio.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/netio.c @@ -5,8 +5,8 @@ */ /* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: + * 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. @@ -18,20 +18,20 @@ * * 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. + * 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. * */ #include "lwip/opt.h" - extern u32_t sys_now(void); +extern u32_t sys_now(void); #if LWIP_TCP #include "lwip/tcp.h" @@ -40,334 +40,373 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif - #define ICACHE_FLASH_ATTR /* * This implements a netio server. * The client sends a command word (4 bytes) then a data length word (4 bytes). - * If the command is "receive", the server is to consume "data length" bytes into - * a circular buffer until the first byte is non-zero, then it is to consume - * another command/data pair. - * If the command is "send", the server is to send "data length" bytes from a circular - * buffer with the first byte being zero, until "some time" (6 seconds in the - * current netio126.zip download) has passed and then send one final buffer with - * the first byte being non-zero. Then it is to consume another command/data pair. + * If the command is "receive", the server is to consume "data length" bytes + * into a circular buffer until the first byte is non-zero, then it is to + * consume another command/data pair. If the command is "send", the server is to + * send "data length" bytes from a circular buffer with the first byte being + * zero, until "some time" (6 seconds in the current netio126.zip download) has + * passed and then send one final buffer with the first byte being non-zero. + * Then it is to consume another command/data pair. */ /* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */ /* implementation options */ -#define NETIO_BUF_SIZE (4 * 1024) -#define NETIO_USE_STATIC_BUF 0 +#define NETIO_BUF_SIZE (4 * 1024) +#define NETIO_USE_STATIC_BUF 0 /* NetIO server state definition */ -#define NETIO_STATE_WAIT_FOR_CMD 0 -#define NETIO_STATE_RECV_DATA 1 -#define NETIO_STATE_SEND_DATA 2 -#define NETIO_STATE_SEND_DATA_LAST 3 -#define NETIO_STATE_DONE 4 - -struct netio_state { - u32_t state; - u32_t cmd; - u32_t data_len; - u32_t cntr; - u8_t * buf_ptr; - u32_t buf_pos; - u32_t first_byte; - u32_t time_stamp; +#define NETIO_STATE_WAIT_FOR_CMD 0 +#define NETIO_STATE_RECV_DATA 1 +#define NETIO_STATE_SEND_DATA 2 +#define NETIO_STATE_SEND_DATA_LAST 3 +#define NETIO_STATE_DONE 4 + +struct netio_state +{ + u32_t state; + u32_t cmd; + u32_t data_len; + u32_t cntr; + u8_t *buf_ptr; + u32_t buf_pos; + u32_t first_byte; + u32_t time_stamp; }; /* NetIO command protocol definition */ -#define NETIO_CMD_QUIT 0 -#define NETIO_CMD_C2S 1 -#define NETIO_CMD_S2C 2 -#define NETIO_CMD_RES 3 +#define NETIO_CMD_QUIT 0 +#define NETIO_CMD_C2S 1 +#define NETIO_CMD_S2C 2 +#define NETIO_CMD_RES 3 static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -static void ICACHE_FLASH_ATTR -netio_close(void *arg, struct tcp_pcb *pcb) +static void ICACHE_FLASH_ATTR netio_close(void *arg, struct tcp_pcb *pcb) { - err_t err; + err_t err; - struct netio_state *ns = arg; - ns->state = NETIO_STATE_DONE; - tcp_recv(pcb, NULL); - err = tcp_close(pcb); + struct netio_state *ns = arg; + ns->state = NETIO_STATE_DONE; + tcp_recv(pcb, NULL); + err = tcp_close(pcb); - if (err != ERR_OK) { - /* closing failed, try again later */ - tcp_recv(pcb, netio_recv); - } else { - /* closing succeeded */ -#if NETIO_USE_STATIC_BUF != 1 - if(ns->buf_ptr != NULL){ - mem_free(ns->buf_ptr); + if (err != ERR_OK) + { + /* closing failed, try again later */ + tcp_recv(pcb, netio_recv); } + else + { + /* closing succeeded */ +#if NETIO_USE_STATIC_BUF != 1 + if (ns->buf_ptr != NULL) + { + mem_free(ns->buf_ptr); + } #endif - tcp_arg(pcb, NULL); - tcp_poll(pcb, NULL, 0); - tcp_sent(pcb, NULL); - if (arg != NULL) { - mem_free(arg); + tcp_arg(pcb, NULL); + tcp_poll(pcb, NULL, 0); + tcp_sent(pcb, NULL); + if (arg != NULL) + { + mem_free(arg); + } } - } } -static err_t ICACHE_FLASH_ATTR -netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +static err_t ICACHE_FLASH_ATTR netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { - struct netio_state *ns = arg; - u8_t * data_ptr; - u32_t data_cntr; - struct pbuf *q = p; - u16_t len; - - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - } - - if (err == ERR_OK && q != NULL) { - - while (q != NULL) { - data_cntr = q->len; - data_ptr = q->payload; - while (data_cntr--) { - if (ns->state == NETIO_STATE_DONE){ - netio_close(ns, pcb); - break; - } else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) { - if (ns->cntr < 4) { - /* build up the CMD field */ - ns->cmd <<= 8; - ns->cmd |= *data_ptr++; - ns->cntr++; - } else if (ns->cntr < 8) { - /* build up the DATA field */ - ns->data_len <<= 8; - ns->data_len |= *data_ptr++; - ns->cntr++; - - if (ns->cntr == 8) { - /* now we have full command and data words */ - ns->cntr = 0; - ns->buf_pos = 0; - ns->buf_ptr[0] = 0; - if (ns->cmd == NETIO_CMD_C2S) { - ns->state = NETIO_STATE_RECV_DATA; - } else if (ns->cmd == NETIO_CMD_S2C) { - ns->state = NETIO_STATE_SEND_DATA; - /* start timer */ - ns->time_stamp = sys_now(); - /* send first round of data */ - - len = tcp_sndbuf(pcb); - len = LWIP_MIN(len, ns->data_len - ns->cntr); - len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); - - do { - err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); - if (err == ERR_MEM) { - len /= 2; - } - } while ((err == ERR_MEM) && (len > 1)); - - ns->buf_pos += len; - ns->cntr += len; - - } else { - /* unrecognized command, punt */ - ns->cntr = 0; - ns->buf_pos = 0; - ns->buf_ptr[0] = 0; - netio_close(ns, pcb); - break; - } - } - } else { - /* in trouble... shouldn't be in this state! */ - } - - } else if (ns->state == NETIO_STATE_RECV_DATA) { - - if(ns->cntr == 0){ - /* save the first byte of this new round of data - * this will not match ns->buf_ptr[0] in the case that - * NETIO_BUF_SIZE is less than ns->data_len. - */ - ns->first_byte = *data_ptr; - } - - ns->buf_ptr[ns->buf_pos++] = *data_ptr++; - ns->cntr++; - - if (ns->buf_pos == NETIO_BUF_SIZE) { - /* circularize the buffer */ - ns->buf_pos = 0; - } - - if(ns->cntr == ns->data_len){ - ns->cntr = 0; - if (ns->first_byte != 0) { - /* if this last round did not start with 0, - * go look for another command */ - ns->state = NETIO_STATE_WAIT_FOR_CMD; - ns->data_len = 0; - ns->cmd = 0; - /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ - } else { - /* stay here and wait on more data */ - } - } - - } else if (ns->state == NETIO_STATE_SEND_DATA - || ns->state == NETIO_STATE_SEND_DATA_LAST) { - /* I don't think this should happen... */ - } else { - /* done / quit */ - netio_close(ns, pcb); - break; - } /* end of ns->state condition */ - } /* end of while data still in this pbuf */ - - q = q->next; + struct netio_state *ns = arg; + u8_t *data_ptr; + u32_t data_cntr; + struct pbuf *q = p; + u16_t len; + + if (p != NULL) + { + tcp_recved(pcb, p->tot_len); } - pbuf_free(p); - - } else { + if (err == ERR_OK && q != NULL) + { + while (q != NULL) + { + data_cntr = q->len; + data_ptr = q->payload; + while (data_cntr--) + { + if (ns->state == NETIO_STATE_DONE) + { + netio_close(ns, pcb); + break; + } + else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) + { + if (ns->cntr < 4) + { + /* build up the CMD field */ + ns->cmd <<= 8; + ns->cmd |= *data_ptr++; + ns->cntr++; + } + else if (ns->cntr < 8) + { + /* build up the DATA field */ + ns->data_len <<= 8; + ns->data_len |= *data_ptr++; + ns->cntr++; + + if (ns->cntr == 8) + { + /* now we have full command and data words */ + ns->cntr = 0; + ns->buf_pos = 0; + ns->buf_ptr[0] = 0; + if (ns->cmd == NETIO_CMD_C2S) + { + ns->state = NETIO_STATE_RECV_DATA; + } + else if (ns->cmd == NETIO_CMD_S2C) + { + ns->state = NETIO_STATE_SEND_DATA; + /* start timer */ + ns->time_stamp = sys_now(); + /* send first round of data */ + + len = tcp_sndbuf(pcb); + len = LWIP_MIN(len, ns->data_len - ns->cntr); + len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); + + do + { + err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); + if (err == ERR_MEM) + { + len /= 2; + } + } while ((err == ERR_MEM) && (len > 1)); + + ns->buf_pos += len; + ns->cntr += len; + } + else + { + /* unrecognized command, punt */ + ns->cntr = 0; + ns->buf_pos = 0; + ns->buf_ptr[0] = 0; + netio_close(ns, pcb); + break; + } + } + } + else + { + /* in trouble... shouldn't be in this state! */ + } + } + else if (ns->state == NETIO_STATE_RECV_DATA) + { + if (ns->cntr == 0) + { + /* save the first byte of this new round of data + * this will not match ns->buf_ptr[0] in the case that + * NETIO_BUF_SIZE is less than ns->data_len. + */ + ns->first_byte = *data_ptr; + } + + ns->buf_ptr[ns->buf_pos++] = *data_ptr++; + ns->cntr++; + + if (ns->buf_pos == NETIO_BUF_SIZE) + { + /* circularize the buffer */ + ns->buf_pos = 0; + } + + if (ns->cntr == ns->data_len) + { + ns->cntr = 0; + if (ns->first_byte != 0) + { + /* if this last round did not start with 0, + * go look for another command */ + ns->state = NETIO_STATE_WAIT_FOR_CMD; + ns->data_len = 0; + ns->cmd = 0; + /* TODO LWIP_DEBUGF( print out some throughput + * calculation results... ); */ + } + else + { + /* stay here and wait on more data */ + } + } + } + else if (ns->state == NETIO_STATE_SEND_DATA || ns->state == NETIO_STATE_SEND_DATA_LAST) + { + /* I don't think this should happen... */ + } + else + { + /* done / quit */ + netio_close(ns, pcb); + break; + } /* end of ns->state condition */ + } /* end of while data still in this pbuf */ + + q = q->next; + } - /* error or closed by other side */ - if (p != NULL) { - pbuf_free(p); + pbuf_free(p); } + else + { + /* error or closed by other side */ + if (p != NULL) + { + pbuf_free(p); + } - /* close the connection */ - netio_close(ns, pcb); - - } - return ERR_OK; - + /* close the connection */ + netio_close(ns, pcb); + } + return ERR_OK; } -static err_t ICACHE_FLASH_ATTR -netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +static err_t ICACHE_FLASH_ATTR netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { - struct netio_state *ns = arg; - err_t err = ERR_OK; + struct netio_state *ns = arg; + err_t err = ERR_OK; - if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) { - /* done with this round of sending */ - ns->buf_pos = 0; - ns->cntr = 0; + if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) + { + /* done with this round of sending */ + ns->buf_pos = 0; + ns->cntr = 0; - /* check if timer expired */ - if (sys_now() - ns->time_stamp > 600) { - ns->buf_ptr[0] = 1; - ns->state = NETIO_STATE_SEND_DATA_LAST; - } else { - ns->buf_ptr[0] = 0; - } - } - - if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){ - len = tcp_sndbuf(pcb); - len = LWIP_MIN(len, ns->data_len - ns->cntr); - len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); - - if(ns->cntr < ns->data_len){ - do { - err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); - if (err == ERR_MEM) { - len /= 2; + /* check if timer expired */ + if (sys_now() - ns->time_stamp > 600) + { + ns->buf_ptr[0] = 1; + ns->state = NETIO_STATE_SEND_DATA_LAST; } - } while ((err == ERR_MEM) && (len > 1)); + else + { + ns->buf_ptr[0] = 0; + } + } - ns->buf_pos += len; - if(ns->buf_pos >= NETIO_BUF_SIZE){ - ns->buf_pos = 0; - } + if (ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA) + { + len = tcp_sndbuf(pcb); + len = LWIP_MIN(len, ns->data_len - ns->cntr); + len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos); + + if (ns->cntr < ns->data_len) + { + do + { + err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY); + if (err == ERR_MEM) + { + len /= 2; + } + } while ((err == ERR_MEM) && (len > 1)); + + ns->buf_pos += len; + if (ns->buf_pos >= NETIO_BUF_SIZE) + { + ns->buf_pos = 0; + } - ns->cntr += len; + ns->cntr += len; + } } - } - if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){ - /* we have buffered up all our data to send this last round, go look for a command */ - ns->state = NETIO_STATE_WAIT_FOR_CMD; - ns->cntr = 0; - /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */ - } + if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST) + { + /* we have buffered up all our data to send this last round, go look for + * a command */ + ns->state = NETIO_STATE_WAIT_FOR_CMD; + ns->cntr = 0; + /* TODO LWIP_DEBUGF( print out some throughput calculation results... ); + */ + } - return ERR_OK; + return ERR_OK; } -static err_t ICACHE_FLASH_ATTR -netio_poll(void *arg, struct tcp_pcb *pcb) +static err_t ICACHE_FLASH_ATTR netio_poll(void *arg, struct tcp_pcb *pcb) { - struct netio_state * ns = arg; - if(ns->state == NETIO_STATE_SEND_DATA){ - - } else if(ns->state == NETIO_STATE_DONE){ - netio_close(ns, pcb); - } - - return ERR_OK; + struct netio_state *ns = arg; + if (ns->state == NETIO_STATE_SEND_DATA) {} + else if (ns->state == NETIO_STATE_DONE) + { + netio_close(ns, pcb); + } + return ERR_OK; } #if NETIO_USE_STATIC_BUF == 1 static u8_t netio_buf[NETIO_BUF_SIZE]; #endif -static err_t ICACHE_FLASH_ATTR -netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) +static err_t ICACHE_FLASH_ATTR netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) { - struct netio_state * ns; + struct netio_state *ns; - LWIP_UNUSED_ARG(err); + LWIP_UNUSED_ARG(err); - ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state)); + ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state)); - if(ns == NULL){ - return ERR_MEM; - } + if (ns == NULL) + { + return ERR_MEM; + } - ns->state = NETIO_STATE_WAIT_FOR_CMD; - ns->data_len = 0; - ns->cmd = 0; - ns->cntr = 0; - ns->buf_pos = 0; + ns->state = NETIO_STATE_WAIT_FOR_CMD; + ns->data_len = 0; + ns->cmd = 0; + ns->cntr = 0; + ns->buf_pos = 0; #if NETIO_USE_STATIC_BUF == 1 - ns->buf_ptr = netio_buf; + ns->buf_ptr = netio_buf; #else - ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE); + ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE); - if(ns->buf_ptr == NULL){ - mem_free(ns); - return ERR_MEM; - } + if (ns->buf_ptr == NULL) + { + mem_free(ns); + return ERR_MEM; + } #endif - ns->buf_ptr[0] = 0; + ns->buf_ptr[0] = 0; - tcp_arg(pcb, ns); - tcp_sent(pcb, netio_sent); - tcp_recv(pcb, netio_recv); - tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */ - return ERR_OK; + tcp_arg(pcb, ns); + tcp_sent(pcb, netio_sent); + tcp_recv(pcb, netio_recv); + tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */ + return ERR_OK; } void ICACHE_FLASH_ATTR netio_init(void) { - struct tcp_pcb *pcb; + struct tcp_pcb *pcb; - pcb = tcp_new(); - tcp_bind(pcb, IP_ADDR_ANY, 18767); - pcb = tcp_listen(pcb); - tcp_accept(pcb, netio_accept); + pcb = tcp_new(); + tcp_bind(pcb, IP_ADDR_ANY, 18767); + pcb = tcp_listen(pcb); + tcp_accept(pcb, netio_accept); } #endif /* LWIP_TCP */ diff --git a/LuaNode_Esp32/LuaNode32/components/espconn/ping.c b/LuaNode_Esp32/LuaNode32/components/espconn/ping.c index 014d4c6..7753655 100644 --- a/LuaNode_Esp32/LuaNode32/components/espconn/ping.c +++ b/LuaNode_Esp32/LuaNode32/components/espconn/ping.c @@ -5,8 +5,8 @@ */ /* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: + * 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. @@ -14,24 +14,24 @@ * 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. + * 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 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. - * + * */ -/** +/** * This is an example of a "ping" sender (with raw API and socket API). * It can be used as a start point to maintain opened a network connection, or * like a network "watchdog" for your device. @@ -42,19 +42,18 @@ #if LWIP_IPV4 && LWIP_RAW /* don't build if not configured for use in lwipopts.h */ -#include "ping.h" - -#include "lwip/mem.h" -#include "lwip/raw.h" #include "lwip/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/mem.h" #include "lwip/netif.h" +#include "lwip/raw.h" #include "lwip/sys.h" #include "lwip/timers.h" -#include "lwip/inet_chksum.h" +#include "ping.h" #if PING_USE_SOCKETS -#include "lwip/sockets.h" #include "lwip/inet.h" +#include "lwip/sockets.h" #endif /* PING_USE_SOCKETS */ #ifdef ESP_LWIP @@ -65,12 +64,12 @@ * PING_DEBUG: Enable debugging for PING. */ #ifndef PING_DEBUG -#define PING_DEBUG LWIP_DBG_ON +#define PING_DEBUG LWIP_DBG_ON #endif /** ping target - should be an "ip4_addr_t" */ #ifndef PING_TARGET -#define PING_TARGET (netif_default ? *netif_ip4_gw(netif_default) : (*IP4_ADDR_ANY)) +#define PING_TARGET (netif_default ? *netif_ip4_gw(netif_default) : (*IP4_ADDR_ANY)) #endif /** ping receive timeout - in milliseconds */ @@ -80,12 +79,12 @@ /** ping delay - in milliseconds */ #ifndef PING_DELAY -#define PING_DELAY 1000 +#define PING_DELAY 1000 #endif /** ping identifier - must fit on a u16_t */ #ifndef PING_ID -#define PING_ID 0xAFAF +#define PING_ID 0xAFAF #endif /** ping additional data size to include in the packet */ @@ -106,260 +105,266 @@ static struct raw_pcb *ping_pcb; #endif /* PING_USE_SOCKETS */ /** Prepare a echo ICMP request */ -static void -ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) +static void ping_prepare_echo(struct icmp_echo_hdr *iecho, u16_t len) { - size_t i; - size_t data_len = len - sizeof(struct icmp_echo_hdr); + size_t i; + size_t data_len = len - sizeof(struct icmp_echo_hdr); - ICMPH_TYPE_SET(iecho, ICMP_ECHO); - ICMPH_CODE_SET(iecho, 0); - iecho->chksum = 0; - iecho->id = PING_ID; - iecho->seqno = lwip_htons(++ping_seq_num); + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = PING_ID; + iecho->seqno = lwip_htons(++ping_seq_num); - /* fill the additional data buffer with some data */ - for(i = 0; i < data_len; i++) { - ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; - } + /* fill the additional data buffer with some data */ + for (i = 0; i < data_len; i++) { ((char *)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; } - iecho->chksum = inet_chksum(iecho, len); + iecho->chksum = inet_chksum(iecho, len); } #if PING_USE_SOCKETS /* Ping using the socket ip */ -static err_t -ping_send(int s, ip_addr_t *addr) +static err_t ping_send(int s, ip_addr_t *addr) { - int err; - struct icmp_echo_hdr *iecho; - struct sockaddr_in to; - size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; - LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); - LWIP_ASSERT("ping: expect IPv4 address", !IP_IS_V6(addr)); - - iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); - if (!iecho) { - return ERR_MEM; - } + int err; + struct icmp_echo_hdr *iecho; + struct sockaddr_in to; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); + LWIP_ASSERT("ping: expect IPv4 address", !IP_IS_V6(addr)); + + iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); + if (!iecho) + { + return ERR_MEM; + } - ping_prepare_echo(iecho, (u16_t)ping_size); + ping_prepare_echo(iecho, (u16_t)ping_size); - to.sin_len = sizeof(to); - to.sin_family = AF_INET; - inet_addr_from_ipaddr(&to.sin_addr, ip_2_ip4(addr)); + to.sin_len = sizeof(to); + to.sin_family = AF_INET; + inet_addr_from_ipaddr(&to.sin_addr, ip_2_ip4(addr)); - err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)); + err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr *)&to, sizeof(to)); - mem_free(iecho); + mem_free(iecho); - return (err ? ERR_OK : ERR_VAL); + return (err ? ERR_OK : ERR_VAL); } -static void -ping_recv(int s) +static void ping_recv(int s) { - char buf[64]; - int len; - struct sockaddr_in from; - struct ip_hdr *iphdr; - struct icmp_echo_hdr *iecho; - int fromlen = sizeof(from); - - while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) { - if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) { - if (from.sin_family != AF_INET) { - /* Ping is not IPv4 */ - LWIP_DEBUGF( PING_DEBUG, ("ping: invalid sin_family\n")); - } else { - ip4_addr_t fromaddr; - inet_addr_to_ipaddr(&fromaddr, &from.sin_addr); - LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); - ip4_addr_debug_print(PING_DEBUG, &fromaddr); - LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now() - ping_time))); - - iphdr = (struct ip_hdr *)buf; - iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); - if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) { - /* do some ping result processing */ + char buf[64]; + int len; + struct sockaddr_in from; + struct ip_hdr *iphdr; + struct icmp_echo_hdr *iecho; + int fromlen = sizeof(from); + + while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen)) > 0) + { + if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) + { + if (from.sin_family != AF_INET) + { + /* Ping is not IPv4 */ + LWIP_DEBUGF(PING_DEBUG, ("ping: invalid sin_family\n")); + } + else + { + ip4_addr_t fromaddr; + inet_addr_to_ipaddr(&fromaddr, &from.sin_addr); + LWIP_DEBUGF(PING_DEBUG, ("ping: recv ")); + ip4_addr_debug_print(PING_DEBUG, &fromaddr); + LWIP_DEBUGF(PING_DEBUG, (" %" U32_F " ms\n", (sys_now() - ping_time))); + + iphdr = (struct ip_hdr *)buf; + iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); + if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) + { + /* do some ping result processing */ #ifdef ESP_LWIP - esp_ping_result((ICMPH_TYPE(iecho) == ICMP_ER), len, (sys_now() - ping_time)); + esp_ping_result((ICMPH_TYPE(iecho) == ICMP_ER), len, (sys_now() - ping_time)); #else - PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); + PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); #endif - return; - } else { - LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n")); + return; + } + else + { + LWIP_DEBUGF(PING_DEBUG, ("ping: drop\n")); + } + } } - } + fromlen = sizeof(from); } - fromlen = sizeof(from); - } - if (len == 0) { - LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeout\n", (sys_now()-ping_time))); - } + if (len == 0) + { + LWIP_DEBUGF(PING_DEBUG, ("ping: recv - %" U32_F " ms - timeout\n", (sys_now() - ping_time))); + } - /* do some ping result processing */ + /* do some ping result processing */ #ifdef ESP_LWIP - esp_ping_result(0, len, (sys_now()-ping_time)); + esp_ping_result(0, len, (sys_now() - ping_time)); #else - PING_RESULT(0); + PING_RESULT(0); #endif } -static void -ping_thread(void *arg) +static void ping_thread(void *arg) { - int s; - int ret; - ip_addr_t ping_target; + int s; + int ret; + ip_addr_t ping_target; #if LWIP_SO_SNDRCVTIMEO_NONSTANDARD - int timeout = PING_RCV_TIMEO; + int timeout = PING_RCV_TIMEO; #else - struct timeval timeout; - timeout.tv_sec = PING_RCV_TIMEO/1000; - timeout.tv_usec = (PING_RCV_TIMEO%1000)*1000; + struct timeval timeout; + timeout.tv_sec = PING_RCV_TIMEO / 1000; + timeout.tv_usec = (PING_RCV_TIMEO % 1000) * 1000; #endif - LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(arg); - if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { - return; - } + if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) + { + return; + } - ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - LWIP_ASSERT("setting receive timeout failed", ret == 0); - LWIP_UNUSED_ARG(ret); + ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + LWIP_ASSERT("setting receive timeout failed", ret == 0); + LWIP_UNUSED_ARG(ret); - while (1) { + while (1) + { #ifdef ESP_LWIP - ip4_addr_t ipaddr; - esp_ping_get_target(PING_TARGET_IP_ADDRESS, &ipaddr.addr, sizeof(uint32_t)); - ip_addr_copy_from_ip4(ping_target, ipaddr); + ip4_addr_t ipaddr; + esp_ping_get_target(PING_TARGET_IP_ADDRESS, &ipaddr.addr, sizeof(uint32_t)); + ip_addr_copy_from_ip4(ping_target, ipaddr); #else - ip_addr_copy_from_ip4(ping_target, PING_TARGET); + ip_addr_copy_from_ip4(ping_target, PING_TARGET); #endif - if (ping_send(s, &ping_target) == ERR_OK) { - LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); - ip_addr_debug_print(PING_DEBUG, &ping_target); - LWIP_DEBUGF( PING_DEBUG, ("\n")); - - ping_time = sys_now(); - ping_recv(s); - } else { - LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); - ip_addr_debug_print(PING_DEBUG, &ping_target); - LWIP_DEBUGF( PING_DEBUG, (" - error\n")); + if (ping_send(s, &ping_target) == ERR_OK) + { + LWIP_DEBUGF(PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF(PING_DEBUG, ("\n")); + + ping_time = sys_now(); + ping_recv(s); + } + else + { + LWIP_DEBUGF(PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF(PING_DEBUG, (" - error\n")); + } + sys_msleep(PING_DELAY); } - sys_msleep(PING_DELAY); - } } #else /* PING_USE_SOCKETS */ /* Ping using the raw ip */ -static u8_t -ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) +static u8_t ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) { - struct icmp_echo_hdr *iecho; - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_ASSERT("p != NULL", p != NULL); - - if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) && - pbuf_header(p, -PBUF_IP_HLEN) == 0) { - iecho = (struct icmp_echo_hdr *)p->payload; - - if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) { - LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); - ip_addr_debug_print(PING_DEBUG, addr); - LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now()-ping_time))); - - /* do some ping result processing */ - PING_RESULT(1); - pbuf_free(p); - return 1; /* eat the packet */ + struct icmp_echo_hdr *iecho; + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_ASSERT("p != NULL", p != NULL); + + if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) && pbuf_header(p, -PBUF_IP_HLEN) == 0) + { + iecho = (struct icmp_echo_hdr *)p->payload; + + if ((iecho->id == PING_ID) && (iecho->seqno == lwip_htons(ping_seq_num))) + { + LWIP_DEBUGF(PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF(PING_DEBUG, (" %" U32_F " ms\n", (sys_now() - ping_time))); + + /* do some ping result processing */ + PING_RESULT(1); + pbuf_free(p); + return 1; /* eat the packet */ + } + /* not eaten, restore original packet */ + pbuf_header(p, PBUF_IP_HLEN); } - /* not eaten, restore original packet */ - pbuf_header(p, PBUF_IP_HLEN); - } - return 0; /* don't eat the packet */ + return 0; /* don't eat the packet */ } -static void -ping_send(struct raw_pcb *raw, ip_addr_t *addr) +static void ping_send(struct raw_pcb *raw, ip_addr_t *addr) { - struct pbuf *p; - struct icmp_echo_hdr *iecho; - size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; - - LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); - ip_addr_debug_print(PING_DEBUG, addr); - LWIP_DEBUGF( PING_DEBUG, ("\n")); - LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff); - - p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM); - if (!p) { - return; - } - if ((p->len == p->tot_len) && (p->next == NULL)) { - iecho = (struct icmp_echo_hdr *)p->payload; + struct pbuf *p; + struct icmp_echo_hdr *iecho; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + + LWIP_DEBUGF(PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF(PING_DEBUG, ("\n")); + LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff); + + p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM); + if (!p) + { + return; + } + if ((p->len == p->tot_len) && (p->next == NULL)) + { + iecho = (struct icmp_echo_hdr *)p->payload; - ping_prepare_echo(iecho, (u16_t)ping_size); + ping_prepare_echo(iecho, (u16_t)ping_size); - raw_sendto(raw, p, addr); - ping_time = sys_now(); - } - pbuf_free(p); + raw_sendto(raw, p, addr); + ping_time = sys_now(); + } + pbuf_free(p); } -static void -ping_timeout(void *arg) +static void ping_timeout(void *arg) { - struct raw_pcb *pcb = (struct raw_pcb*)arg; - ip_addr_t ping_target; + struct raw_pcb *pcb = (struct raw_pcb *)arg; + ip_addr_t ping_target; - LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); + LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); - ip_addr_copy_from_ip4(ping_target, PING_TARGET); - ping_send(pcb, &ping_target); + ip_addr_copy_from_ip4(ping_target, PING_TARGET); + ping_send(pcb, &ping_target); - sys_timeout(PING_DELAY, ping_timeout, pcb); + sys_timeout(PING_DELAY, ping_timeout, pcb); } -static void -ping_raw_init(void) +static void ping_raw_init(void) { - ping_pcb = raw_new(IP_PROTO_ICMP); - LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); + ping_pcb = raw_new(IP_PROTO_ICMP); + LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); - raw_recv(ping_pcb, ping_recv, NULL); - raw_bind(ping_pcb, IP_ADDR_ANY); - sys_timeout(PING_DELAY, ping_timeout, ping_pcb); + raw_recv(ping_pcb, ping_recv, NULL); + raw_bind(ping_pcb, IP_ADDR_ANY); + sys_timeout(PING_DELAY, ping_timeout, ping_pcb); } -void -ping_send_now(void) +void ping_send_now(void) { - ip_addr_t ping_target; - LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); - ip_addr_copy_from_ip4(ping_target, PING_TARGET); - ping_send(ping_pcb, &ping_target); + ip_addr_t ping_target; + LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); + ip_addr_copy_from_ip4(ping_target, PING_TARGET); + ping_send(ping_pcb, &ping_target); } #endif /* PING_USE_SOCKETS */ -void -ping_init(void) +void ping_init(void) { #if PING_USE_SOCKETS - sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); -#else /* PING_USE_SOCKETS */ - ping_raw_init(); + sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +#else /* PING_USE_SOCKETS */ + ping_raw_init(); #endif /* PING_USE_SOCKETS */ } diff --git a/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt.c b/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt.c index b666fc6..526dd8b 100644 --- a/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt.c +++ b/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt.c @@ -1,70 +1,73 @@ /* -* @Author: Tuan PM -* @Date: 2016-09-10 09:33:06 -* @Last Modified by: Tuan PM -* @Last Modified time: 2016-09-23 22:02:04 -*/ + * @Author: Tuan PM + * @Date: 2016-09-10 09:33:06 + * @Last Modified by: Tuan PM + * @Last Modified time: 2016-09-23 22:02:04 + */ +#include "mqtt.h" + #include + #include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" #include "freertos/queue.h" - -#include "lwip/sockets.h" +#include "freertos/semphr.h" +#include "freertos/task.h" #include "lwip/dns.h" #include "lwip/netdb.h" +#include "lwip/sockets.h" #include "ringbuf.h" -#include "mqtt.h" static TaskHandle_t xMqttTask = NULL; static TaskHandle_t xMqttSendingTask = NULL; - -static int resolve_dns(const char *host, struct sockaddr_in *ip) { +static int resolve_dns(const char *host, struct sockaddr_in *ip) +{ struct hostent *he; struct in_addr **addr_list; he = gethostbyname(host); - if (he == NULL) return 0; + if (he == NULL) + return 0; addr_list = (struct in_addr **)he->h_addr_list; - if (addr_list[0] == NULL) return 0; + if (addr_list[0] == NULL) + return 0; ip->sin_family = AF_INET; memcpy(&ip->sin_addr, addr_list[0], sizeof(ip->sin_addr)); return 1; } static void mqtt_queue(mqtt_client *client) { -// TODO: detect buffer full (ringbuf and queue) - rb_write(&client->send_rb, - client->mqtt_state.outbound_message->data, - client->mqtt_state.outbound_message->length); + // TODO: detect buffer full (ringbuf and queue) + rb_write(&client->send_rb, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); xQueueSend(client->xSendingQueue, &client->mqtt_state.outbound_message->length, 0); } static int client_connect(const char *stream_host, int stream_port) { int sock; struct sockaddr_in remote_ip; - while (1) { + while (1) + { bzero(&remote_ip, sizeof(struct sockaddr_in)); remote_ip.sin_family = AF_INET; - //if stream_host is not ip address, resolve it - if (inet_aton(stream_host, &(remote_ip.sin_addr)) == 0) { + // if stream_host is not ip address, resolve it + if (inet_aton(stream_host, &(remote_ip.sin_addr)) == 0) + { mqtt_info("Resolve dns for domain: %s", stream_host); - if (!resolve_dns(stream_host, &remote_ip)) { + if (!resolve_dns(stream_host, &remote_ip)) + { vTaskDelay(1000 / portTICK_RATE_MS); continue; } } sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock == -1) { + if (sock == -1) + { continue; } remote_ip.sin_port = htons(stream_port); - mqtt_info("Connecting to server %s:%d,%d", - inet_ntoa((remote_ip.sin_addr)), - stream_port, - remote_ip.sin_port); + mqtt_info("Connecting to server %s:%d,%d", inet_ntoa((remote_ip.sin_addr)), stream_port, remote_ip.sin_port); - if (connect(sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 00) { + if (connect(sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 00) + { close(sock); mqtt_error("Conn err."); vTaskDelay(1000 / portTICK_RATE_MS); @@ -88,36 +91,37 @@ static bool mqtt_connect(mqtt_client *client) setsockopt(client->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); - mqtt_msg_init(&client->mqtt_state.mqtt_connection, - client->mqtt_state.out_buffer, + mqtt_msg_init(&client->mqtt_state.mqtt_connection, client->mqtt_state.out_buffer, client->mqtt_state.out_buffer_length); - client->mqtt_state.outbound_message = mqtt_msg_connect(&client->mqtt_state.mqtt_connection, - client->mqtt_state.connect_info); + client->mqtt_state.outbound_message = + mqtt_msg_connect(&client->mqtt_state.mqtt_connection, client->mqtt_state.connect_info); client->mqtt_state.pending_msg_type = mqtt_get_type(client->mqtt_state.outbound_message->data); - client->mqtt_state.pending_msg_id = mqtt_get_id(client->mqtt_state.outbound_message->data, - client->mqtt_state.outbound_message->length); - mqtt_info("Sending MQTT CONNECT message, type: %d, id: %04X", - client->mqtt_state.pending_msg_type, + client->mqtt_state.pending_msg_id = + mqtt_get_id(client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); + mqtt_info("Sending MQTT CONNECT message, type: %d, id: %04X", client->mqtt_state.pending_msg_type, client->mqtt_state.pending_msg_id); - write_len = write(client->socket, - client->mqtt_state.outbound_message->data, - client->mqtt_state.outbound_message->length); + write_len = + write(client->socket, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); mqtt_info("Reading MQTT CONNECT response message"); read_len = read(client->socket, client->mqtt_state.in_buffer, CONFIG_MQTT_BUFFER_SIZE_BYTE); - tv.tv_sec = 0; /* No timeout */ + tv.tv_sec = 0; /* No timeout */ setsockopt(client->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); - if (read_len < 0) { + if (read_len < 0) + { mqtt_error("Error network response"); return false; } - if (mqtt_get_type(client->mqtt_state.in_buffer) != MQTT_MSG_TYPE_CONNACK) { - mqtt_error("Invalid MSG_TYPE response: %d, read_len: %d", mqtt_get_type(client->mqtt_state.in_buffer), read_len); + if (mqtt_get_type(client->mqtt_state.in_buffer) != MQTT_MSG_TYPE_CONNACK) + { + mqtt_error("Invalid MSG_TYPE response: %d, read_len: %d", mqtt_get_type(client->mqtt_state.in_buffer), + read_len); return false; } connect_rsp_code = mqtt_get_connect_return_code(client->mqtt_state.in_buffer); - switch (connect_rsp_code) { + switch (connect_rsp_code) + { case CONNECTION_ACCEPTED: mqtt_info("Connected"); return true; @@ -140,10 +144,13 @@ void mqtt_sending_task(void *pvParameters) uint32_t msg_len, send_len; mqtt_info("mqtt_sending_task"); - while (1) { - if (xQueueReceive(client->xSendingQueue, &msg_len, 1000 / portTICK_RATE_MS)) { - //queue available - while (msg_len > 0) { + while (1) + { + if (xQueueReceive(client->xSendingQueue, &msg_len, 1000 / portTICK_RATE_MS)) + { + // queue available + while (msg_len > 0) + { send_len = msg_len; if (send_len > CONFIG_MQTT_BUFFER_SIZE_BYTE) send_len = CONFIG_MQTT_BUFFER_SIZE_BYTE; @@ -153,23 +160,25 @@ void mqtt_sending_task(void *pvParameters) client->mqtt_state.pending_msg_type = mqtt_get_type(client->mqtt_state.out_buffer); client->mqtt_state.pending_msg_id = mqtt_get_id(client->mqtt_state.out_buffer, send_len); write(client->socket, client->mqtt_state.out_buffer, send_len); - //TODO: Check sending type, to callback publish message + // TODO: Check sending type, to callback publish message msg_len -= send_len; } - //invalidate keepalive timer + // invalidate keepalive timer client->keepalive_tick = client->settings->keepalive / 2; } - else { - if (client->keepalive_tick > 0) client->keepalive_tick --; - else { + else + { + if (client->keepalive_tick > 0) + client->keepalive_tick--; + else + { client->keepalive_tick = client->settings->keepalive / 2; client->mqtt_state.outbound_message = mqtt_msg_pingreq(&client->mqtt_state.mqtt_connection); client->mqtt_state.pending_msg_type = mqtt_get_type(client->mqtt_state.outbound_message->data); - client->mqtt_state.pending_msg_id = mqtt_get_id(client->mqtt_state.outbound_message->data, - client->mqtt_state.outbound_message->length); - //mqtt_info("Sending pingreq"); - write(client->socket, - client->mqtt_state.outbound_message->data, + client->mqtt_state.pending_msg_id = + mqtt_get_id(client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); + // mqtt_info("Sending pingreq"); + write(client->socket, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length); } } @@ -189,10 +198,14 @@ void deliver_publish(mqtt_client *client, uint8_t *message, int length) event_data.data_length = length; event_data.data = mqtt_get_publish_data(message, &event_data.data_length); - if(total_mqtt_len == 0){ - total_mqtt_len = client->mqtt_state.message_length - client->mqtt_state.message_length_read + event_data.data_length; + if (total_mqtt_len == 0) + { + total_mqtt_len = + client->mqtt_state.message_length - client->mqtt_state.message_length_read + event_data.data_length; mqtt_len = event_data.data_length; - } else { + } + else + { mqtt_len = len_read; } @@ -201,20 +214,21 @@ void deliver_publish(mqtt_client *client, uint8_t *message, int length) event_data.data_length = mqtt_len; mqtt_info("Data received: %d/%d bytes ", mqtt_len, total_mqtt_len); - - if(client->settings->data_cb) { + + if (client->settings->data_cb) + { client->settings->data_cb(client, &event_data); } - if(client->settings->publish_cb) { - client->settings->publish_cb(client, &event_data); - } + if (client->settings->publish_cb) + { + client->settings->publish_cb(client, &event_data); + } mqtt_offset += mqtt_len; if (client->mqtt_state.message_length_read >= client->mqtt_state.message_length) break; - len_read = read(client->socket, client->mqtt_state.in_buffer, CONFIG_MQTT_BUFFER_SIZE_BYTE); + len_read = read(client->socket, client->mqtt_state.in_buffer, CONFIG_MQTT_BUFFER_SIZE_BYTE); client->mqtt_state.message_length_read += len_read; } while (1); - } void mqtt_start_receive_schedule(mqtt_client *client) { @@ -223,28 +237,34 @@ void mqtt_start_receive_schedule(mqtt_client *client) uint8_t msg_qos; uint16_t msg_id; - while (1) { + while (1) + { read_len = read(client->socket, client->mqtt_state.in_buffer, CONFIG_MQTT_BUFFER_SIZE_BYTE); - //mqtt_info("Read len %d", read_len); + // mqtt_info("Read len %d", read_len); if (read_len == 0) break; msg_type = mqtt_get_type(client->mqtt_state.in_buffer); msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer); msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length); - // mqtt_info("msg_type %d, msg_id: %d, pending_id: %d", msg_type, msg_id, client->mqtt_state.pending_msg_type); + // mqtt_info("msg_type %d, msg_id: %d, pending_id: %d", msg_type, + // msg_id, client->mqtt_state.pending_msg_type); switch (msg_type) { case MQTT_MSG_TYPE_SUBACK: - if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) { + if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && + client->mqtt_state.pending_msg_id == msg_id) + { mqtt_info("Subscribe successful"); - if (client->settings->subscribe_cb) { + if (client->settings->subscribe_cb) + { client->settings->subscribe_cb(client, NULL); } } break; case MQTT_MSG_TYPE_UNSUBACK: - if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id) + if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && + client->mqtt_state.pending_msg_id == msg_id) mqtt_info("UnSubscribe successful"); break; case MQTT_MSG_TYPE_PUBLISH: @@ -253,23 +273,30 @@ void mqtt_start_receive_schedule(mqtt_client *client) else if (msg_qos == 2) client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id); - if (msg_qos == 1 || msg_qos == 2) { + if (msg_qos == 1 || msg_qos == 2) + { mqtt_info("Queue response QoS: %d", msg_qos); mqtt_queue(client); - // if (QUEUE_Puts(&client->msgQueue, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length) == -1) { + // if (QUEUE_Puts(&client->msgQueue, + // client->mqtt_state.outbound_message->data, + // client->mqtt_state.outbound_message->length) == -1) { // mqtt_info("MQTT: Queue full"); // } } client->mqtt_state.message_length_read = read_len; - client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); + client->mqtt_state.message_length = + mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); mqtt_info("deliver_publish"); deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); - // deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read); + // deliver_publish(client, client->mqtt_state.in_buffer, + // client->mqtt_state.message_length_read); break; case MQTT_MSG_TYPE_PUBACK: - if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { + if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && + client->mqtt_state.pending_msg_id == msg_id) + { mqtt_info("received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish"); } @@ -284,7 +311,9 @@ void mqtt_start_receive_schedule(mqtt_client *client) break; case MQTT_MSG_TYPE_PUBCOMP: - if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id) { + if (client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && + client->mqtt_state.pending_msg_id == msg_id) + { mqtt_info("Receive MQTT_MSG_TYPE_PUBCOMP, finish QoS2 publish"); } break; @@ -293,11 +322,11 @@ void mqtt_start_receive_schedule(mqtt_client *client) mqtt_queue(client); break; case MQTT_MSG_TYPE_PINGRESP: - //mqtt_info("MQTT_MSG_TYPE_PINGRESP"); + // mqtt_info("MQTT_MSG_TYPE_PINGRESP"); // Ignore break; } - vTaskDelay(5 / portTICK_RATE_MS); + vTaskDelay(5 / portTICK_RATE_MS); } mqtt_info("network disconnected"); } @@ -314,16 +343,21 @@ void mqtt_task(void *pvParameters) { mqtt_client *client = (mqtt_client *)pvParameters; - while (1) { + while (1) + { client->socket = client_connect(client->settings->host, client->settings->port); mqtt_info("Connected to server %s:%d", client->settings->host, client->settings->port); - if (!mqtt_connect(client)) { + if (!mqtt_connect(client)) + { continue; - //return; + // return; } - mqtt_info("Connected to MQTT broker, create sending thread before call connected callback"); + mqtt_info( + "Connected to MQTT broker, create sending thread before call " + "connected callback"); xTaskCreate(&mqtt_sending_task, "mqtt_sending_task", 4096, client, CONFIG_MQTT_PRIORITY + 1, &xMqttSendingTask); - if (client->settings->connected_cb) { + if (client->settings->connected_cb) + { client->settings->connected_cb(client, NULL); } @@ -333,11 +367,8 @@ void mqtt_task(void *pvParameters) close(client->socket); vTaskDelete(xMqttSendingTask); vTaskDelay(1000 / portTICK_RATE_MS); - } mqtt_destroy(client); - - } mqtt_client *mqtt_start(mqtt_settings *settings) @@ -347,7 +378,8 @@ mqtt_client *mqtt_start(mqtt_settings *settings) return NULL; mqtt_client *client = malloc(sizeof(mqtt_client)); - if (client == NULL) { + if (client == NULL) + { mqtt_error("Memory not enough"); return NULL; } @@ -362,7 +394,6 @@ mqtt_client *mqtt_start(mqtt_settings *settings) client->connect_info.will_qos = settings->lwt_qos; client->connect_info.will_retain = settings->lwt_retain; - client->keepalive_tick = settings->keepalive / 2; client->connect_info.keepalive = settings->keepalive; @@ -370,25 +401,23 @@ mqtt_client *mqtt_start(mqtt_settings *settings) client->mqtt_state.in_buffer = (uint8_t *)malloc(CONFIG_MQTT_BUFFER_SIZE_BYTE); client->mqtt_state.in_buffer_length = CONFIG_MQTT_BUFFER_SIZE_BYTE; - client->mqtt_state.out_buffer = (uint8_t *)malloc(CONFIG_MQTT_BUFFER_SIZE_BYTE); + client->mqtt_state.out_buffer = (uint8_t *)malloc(CONFIG_MQTT_BUFFER_SIZE_BYTE); client->mqtt_state.out_buffer_length = CONFIG_MQTT_BUFFER_SIZE_BYTE; client->mqtt_state.connect_info = &client->connect_info; - - /* Create a queue capable of containing 64 unsigned long values. */ - client->xSendingQueue = xQueueCreate(64, sizeof( uint32_t )); - rb_buf = (uint8_t*) malloc(CONFIG_MQTT_QUEUE_BUFFER_SIZE_WORD * 4); + client->xSendingQueue = xQueueCreate(64, sizeof(uint32_t)); + rb_buf = (uint8_t *)malloc(CONFIG_MQTT_QUEUE_BUFFER_SIZE_WORD * 4); - if (rb_buf == NULL) { + if (rb_buf == NULL) + { mqtt_error("Memory not enough"); return NULL; } rb_init(&client->send_rb, rb_buf, CONFIG_MQTT_QUEUE_BUFFER_SIZE_WORD * 4, 1); - mqtt_msg_init(&client->mqtt_state.mqtt_connection, - client->mqtt_state.out_buffer, + mqtt_msg_init(&client->mqtt_state.mqtt_connection, client->mqtt_state.out_buffer, client->mqtt_state.out_buffer_length); xTaskCreate(&mqtt_task, "mqtt_task", 6144, client, CONFIG_MQTT_PRIORITY, &xMqttTask); @@ -397,33 +426,23 @@ mqtt_client *mqtt_start(mqtt_settings *settings) void mqtt_subscribe(mqtt_client *client, char *topic, uint8_t qos) { - client->mqtt_state.outbound_message = mqtt_msg_subscribe(&client->mqtt_state.mqtt_connection, - topic, qos, - &client->mqtt_state.pending_msg_id); + client->mqtt_state.outbound_message = + mqtt_msg_subscribe(&client->mqtt_state.mqtt_connection, topic, qos, &client->mqtt_state.pending_msg_id); mqtt_info("Queue subscribe, topic\"%s\", id: %d", topic, client->mqtt_state.pending_msg_id); mqtt_queue(client); } -void mqtt_unsubscribe(mqtt_client *client, char *topic) +void mqtt_unsubscribe(mqtt_client *client, char *topic) { - mqtt_msg_unsubscribe(&client->mqtt_state.mqtt_connection, topic, &client->mqtt_state.pending_msg_id); + mqtt_msg_unsubscribe(&client->mqtt_state.mqtt_connection, topic, &client->mqtt_state.pending_msg_id); } -void mqtt_publish(mqtt_client* client, char *topic, char *data, int len, int qos, int retain) +void mqtt_publish(mqtt_client *client, char *topic, char *data, int len, int qos, int retain) { - - client->mqtt_state.outbound_message = mqtt_msg_publish(&client->mqtt_state.mqtt_connection, - topic, data, len, - qos, retain, - &client->mqtt_state.pending_msg_id); + client->mqtt_state.outbound_message = mqtt_msg_publish(&client->mqtt_state.mqtt_connection, topic, data, len, qos, + retain, &client->mqtt_state.pending_msg_id); mqtt_queue(client); - mqtt_info("Queuing publish, length: %d, queue size(%d/%d)\r\n", - client->mqtt_state.outbound_message->length, - client->send_rb.fill_cnt, - client->send_rb.size); -} -void mqtt_stop() -{ - + mqtt_info("Queuing publish, length: %d, queue size(%d/%d)\r\n", client->mqtt_state.outbound_message->length, + client->send_rb.fill_cnt, client->send_rb.size); } - +void mqtt_stop() {} diff --git a/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt_msg.c b/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt_msg.c index b88ca4e..ea9038a 100644 --- a/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt_msg.c +++ b/LuaNode_Esp32/LuaNode32/components/espmqtt/mqtt_msg.c @@ -1,36 +1,38 @@ /* -* Copyright (c) 2014, Stephen Robinson -* 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. Neither the name of the copyright holder nor the names of its -* contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. -* -*/ + * Copyright (c) 2014, Stephen Robinson + * 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. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + */ +#include "mqtt_msg.h" + #include #include -#include "mqtt_msg.h" + #include "mqtt_config.h" #define MQTT_MAX_FIXED_HEADER_SIZE 3 @@ -75,8 +77,7 @@ static uint16_t append_message_id(mqtt_connection_t* connection, uint16_t messag { // If message_id is zero then we should assign one, otherwise // we'll use the one supplied by the caller - while (message_id == 0) - message_id = ++connection->message_id; + while (message_id == 0) message_id = ++connection->message_id; if (connection->message.length + 2 > connection->buffer_length) return 0; @@ -232,39 +233,41 @@ uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length) switch (mqtt_get_type(buffer)) { case MQTT_MSG_TYPE_PUBLISH: - { - int i; - int topiclen; + { + int i; + int topiclen; - for (i = 1; i < length; ++i) + for (i = 1; i < length; ++i) + { + if ((buffer[i] & 0x80) == 0) { - if ((buffer[i] & 0x80) == 0) - { - ++i; - break; - } + ++i; + break; } + } - if (i + 2 >= length) - return 0; - topiclen = buffer[i++] << 8; - topiclen |= buffer[i++]; + if (i + 2 >= length) + return 0; + topiclen = buffer[i++] << 8; + topiclen |= buffer[i++]; - if (i + topiclen >= length) - return 0; - i += topiclen; + if (i + topiclen >= length) + return 0; + i += topiclen; - if (mqtt_get_qos(buffer) > 0) - { - if (i + 2 >= length) - return 0; - //i += 2; - } else { + if (mqtt_get_qos(buffer) > 0) + { + if (i + 2 >= length) return 0; - } - - return (buffer[i] << 8) | buffer[i + 1]; + // i += 2; } + else + { + return 0; + } + + return (buffer[i] << 8) | buffer[i + 1]; + } case MQTT_MSG_TYPE_PUBACK: case MQTT_MSG_TYPE_PUBREC: case MQTT_MSG_TYPE_PUBREL: @@ -272,14 +275,14 @@ uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length) case MQTT_MSG_TYPE_SUBACK: case MQTT_MSG_TYPE_UNSUBACK: case MQTT_MSG_TYPE_SUBSCRIBE: - { - // This requires the remaining length to be encoded in 1 byte, - // which it should be. - if (length >= 4 && (buffer[1] & 0x80) == 0) - return (buffer[2] << 8) | buffer[3]; - else - return 0; - } + { + // This requires the remaining length to be encoded in 1 byte, + // which it should be. + if (length >= 4 && (buffer[1] & 0x80) == 0) + return (buffer[2] << 8) | buffer[3]; + else + return 0; + } default: return 0; @@ -356,7 +359,8 @@ mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_inf return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0); } -mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id) +mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, + int qos, int retain, uint16_t* message_id) { init_message(connection); diff --git a/LuaNode_Esp32/LuaNode32/components/espmqtt/ringbuf.c b/LuaNode_Esp32/LuaNode32/components/espmqtt/ringbuf.c index 5bb4adb..19094d3 100644 --- a/LuaNode_Esp32/LuaNode32/components/espmqtt/ringbuf.c +++ b/LuaNode_Esp32/LuaNode32/components/espmqtt/ringbuf.c @@ -1,24 +1,27 @@ /** -* \file -* Ring Buffer library -*/ + * \file + * Ring Buffer library + */ +#include "ringbuf.h" + #include #include -#include "ringbuf.h" /** -* \brief init a RINGBUF object -* \param r pointer to a RINGBUF object -* \param buf pointer to a byte array -* \param size size of buf -* \param block_size is size of data as block -* \return 0 if successfull, otherwise failed -*/ -int32_t rb_init(RINGBUF *r, uint8_t* buf, int32_t size, int32_t block_size) + * \brief init a RINGBUF object + * \param r pointer to a RINGBUF object + * \param buf pointer to a byte array + * \param size size of buf + * \param block_size is size of data as block + * \return 0 if successfull, otherwise failed + */ +int32_t rb_init(RINGBUF *r, uint8_t *buf, int32_t size, int32_t block_size) { - if (r == 0 || buf == 0 || size < 2) return -1; + if (r == 0 || buf == 0 || size < 2) + return -1; - if (size % block_size != 0) return -1; + if (size % block_size != 0) + return -1; r->p_o = r->p_r = r->p_w = buf; r->fill_cnt = 0; @@ -27,70 +30,70 @@ int32_t rb_init(RINGBUF *r, uint8_t* buf, int32_t size, int32_t block_size) return 0; } /** -* \brief put a character into ring buffer -* \param r pointer to a ringbuf object -* \param c character to be put -* \return 0 if successfull, otherwise failed -*/ + * \brief put a character into ring buffer + * \param r pointer to a ringbuf object + * \param c character to be put + * \return 0 if successfull, otherwise failed + */ int32_t rb_put(RINGBUF *r, uint8_t *c) { int32_t i; uint8_t *data = c; if (r->fill_cnt >= r->size) - return -1; // ring buffer is full, this should be atomic operation - + return -1; // ring buffer is full, this should be atomic operation - r->fill_cnt += r->block_size; // increase filled slots count, this should be atomic operation + r->fill_cnt += r->block_size; // increase filled slots count, this should + // be atomic operation - for (i = 0; i < r->block_size; i++) { - *r->p_w = *data; // put character into buffer + for (i = 0; i < r->block_size; i++) + { + *r->p_w = *data; // put character into buffer - r->p_w ++; - data ++; + r->p_w++; + data++; } - if (r->p_w >= r->p_o + r->size) // rollback if write pointer go pass - r->p_w = r->p_o; // the physical boundary + if (r->p_w >= r->p_o + r->size) // rollback if write pointer go pass + r->p_w = r->p_o; // the physical boundary return 0; } /** -* \brief get a character from ring buffer -* \param r pointer to a ringbuf object -* \param c read character -* \return 0 if successfull, otherwise failed -*/ + * \brief get a character from ring buffer + * \param r pointer to a ringbuf object + * \param c read character + * \return 0 if successfull, otherwise failed + */ int32_t rb_get(RINGBUF *r, uint8_t *c) { int32_t i; uint8_t *data = c; - if (r->fill_cnt <= 0)return -1; // ring buffer is empty, this should be atomic operation + if (r->fill_cnt <= 0) + return -1; // ring buffer is empty, this should be atomic operation - r->fill_cnt -= r->block_size; // decrease filled slots count + r->fill_cnt -= r->block_size; // decrease filled slots count - for (i = 0; i < r->block_size; i++) - *data++ = *r->p_r++; // get the character out + for (i = 0; i < r->block_size; i++) *data++ = *r->p_r++; // get the character out - if (r->p_r >= r->p_o + r->size) // rollback if write pointer go pass - r->p_r = r->p_o; // the physical boundary + if (r->p_r >= r->p_o + r->size) // rollback if write pointer go pass + r->p_r = r->p_o; // the physical boundary return 0; } -int32_t rb_available(RINGBUF *r) -{ - return (r->size - r->fill_cnt); -} +int32_t rb_available(RINGBUF *r) { return (r->size - r->fill_cnt); } uint32_t rb_read(RINGBUF *r, uint8_t *buf, int len) { int n = 0; uint8_t data; - while (len > 0) { - while (rb_get(r, &data) != 0); + while (len > 0) + { + while (rb_get(r, &data) != 0) + ; *buf++ = data; - n ++; - len --; + n++; + len--; } return n; @@ -99,8 +102,10 @@ uint32_t rb_read(RINGBUF *r, uint8_t *buf, int len) uint32_t rb_write(RINGBUF *r, uint8_t *buf, int len) { uint32_t wi; - for (wi = 0; wi < len; wi++) { - while (rb_put(r, &buf[wi]) != 0); + for (wi = 0; wi < len; wi++) + { + while (rb_put(r, &buf[wi]) != 0) + ; } return 0; } diff --git a/LuaNode_Esp32/LuaNode32/components/free80211/free80211.c b/LuaNode_Esp32/LuaNode32/components/free80211/free80211.c index 4ac55da..fb5c521 100644 --- a/LuaNode_Esp32/LuaNode32/components/free80211/free80211.c +++ b/LuaNode_Esp32/LuaNode32/components/free80211/free80211.c @@ -1,39 +1,44 @@ #include "esp_system.h" int8_t ieee80211_freedom_output(uint32_t *ifx, uint8_t *buffer, uint16_t len); -extern void* g_wifi_menuconfig; -uint32_t zeros[64] = { 0x00000000 }; +extern void *g_wifi_menuconfig; +uint32_t zeros[64] = {0x00000000}; /* - * ieee80211_freedom_output returns -4 if value at addr [content of register a7] + 149 is 0. - * So we need to find out which address [content of register a7] refers to and set that to 1. - * Due to window shifting by 8, the contents of register a7 will most likely be in a15. - * This address turns out to be &g_wifi_menuconfig - 0x253, propably some local variable? - * I don't know why this works, but after setting this local variable to something other than 0, + * ieee80211_freedom_output returns -4 if value at addr [content of register a7] + * + 149 is 0. So we need to find out which address [content of register a7] + * refers to and set that to 1. Due to window shifting by 8, the contents of + * register a7 will most likely be in a15. This address turns out to be + * &g_wifi_menuconfig - 0x253, propably some local variable? I don't know why + * this works, but after setting this local variable to something other than 0, * outputting arbitrary 802.11 frames works fine. * - * ieee80211_freedom_output also seems to read stuff from offsets starting at the address its first - * parameter refers to, so we need to make sure this address is accessible. In order to make sure - * other code doesn't interfere with ieee80211_freedom_output we just pass an array of zeros. - * The first parameter is propably supposed to be a pointer to the wifi peripheral or config options, - * but since we don't really know what ieee80211_freedom_output expects, we just use this workaround. + * ieee80211_freedom_output also seems to read stuff from offsets starting at + * the address its first parameter refers to, so we need to make sure this + * address is accessible. In order to make sure other code doesn't interfere + * with ieee80211_freedom_output we just pass an array of zeros. The first + * parameter is propably supposed to be a pointer to the wifi peripheral or + * config options, but since we don't really know what ieee80211_freedom_output + * expects, we just use this workaround. * * Parameters: - * buffer: Raw IEEE 802.11 packet to send, will be sent as-is, apart from bytes 24 - 31 which will be set to 0x00 in case buffer[0] is 0x80. - * len: Length of IEEE 802.11 packet. Must be larger than 23 and smaller than or equal 0x578. + * buffer: Raw IEEE 802.11 packet to send, will be sent as-is, apart from bytes + * 24 - 31 which will be set to 0x00 in case buffer[0] is 0x80. len: Length of + * IEEE 802.11 packet. Must be larger than 23 and smaller than or equal 0x578. * * Return values: * -3: Invalid packet length. - * -2: Something is wrong with the frame header (the first two bytes) of the buffer. - * -1: ?? - * 0: Everything worked fine. + * -2: Something is wrong with the frame header (the first two bytes) of the + * buffer. -1: ?? 0: Everything worked fine. */ -int8_t free80211_send(uint8_t *buffer, uint16_t len) { - int8_t rval = 0; +int8_t free80211_send(uint8_t *buffer, uint16_t len) +{ + int8_t rval = 0; - *(uint32_t *)((uint32_t)&g_wifi_menuconfig - 0x253) = 1; - rval = ieee80211_freedom_output(zeros, buffer, len); - if (rval == -4) asm("ill"); - return rval; + *(uint32_t *)((uint32_t)&g_wifi_menuconfig - 0x253) = 1; + rval = ieee80211_freedom_output(zeros, buffer, len); + if (rval == -4) + asm("ill"); + return rval; } diff --git a/LuaNode_Esp32/LuaNode32/components/lpeg/lpcap.c b/LuaNode_Esp32/LuaNode32/components/lpeg/lpcap.c index c9085de..ddd224e 100644 --- a/LuaNode_Esp32/LuaNode32/components/lpeg/lpcap.c +++ b/LuaNode_Esp32/LuaNode32/components/lpeg/lpcap.c @@ -3,79 +3,84 @@ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ -#include "lua.h" -#include "lauxlib.h" - #include "lpcap.h" -#include "lptypes.h" +#include "lauxlib.h" +#include "lptypes.h" +#include "lua.h" -#define captype(cap) ((cap)->kind) - -#define isclosecap(cap) (captype(cap) == Cclose) - -#define closeaddr(c) ((c)->s + (c)->siz - 1) +#define captype(cap) ((cap)->kind) -#define isfullcap(cap) ((cap)->siz != 0) +#define isclosecap(cap) (captype(cap) == Cclose) -#define getfromktable(cs,v) lua_rawgeti((cs)->L, ktableidx((cs)->ptop), v) +#define closeaddr(c) ((c)->s + (c)->siz - 1) -#define pushluaval(cs) getfromktable(cs, (cs)->cap->idx) +#define isfullcap(cap) ((cap)->siz != 0) +#define getfromktable(cs, v) lua_rawgeti((cs)->L, ktableidx((cs)->ptop), v) +#define pushluaval(cs) getfromktable(cs, (cs)->cap->idx) /* ** Put at the cache for Lua values the value indexed by 'v' in ktable ** of the running pattern (if it is not there yet); returns its index. */ -static int updatecache (CapState *cs, int v) { - int idx = cs->ptop + 1; /* stack index of cache for Lua values */ - if (v != cs->valuecached) { /* not there? */ - getfromktable(cs, v); /* get value from 'ktable' */ - lua_replace(cs->L, idx); /* put it at reserved stack position */ - cs->valuecached = v; /* keep track of what is there */ - } - return idx; +static int updatecache(CapState *cs, int v) +{ + int idx = cs->ptop + 1; /* stack index of cache for Lua values */ + if (v != cs->valuecached) + { /* not there? */ + getfromktable(cs, v); /* get value from 'ktable' */ + lua_replace(cs->L, idx); /* put it at reserved stack position */ + cs->valuecached = v; /* keep track of what is there */ + } + return idx; } - -static int pushcapture (CapState *cs); - +static int pushcapture(CapState *cs); /* ** Goes back in a list of captures looking for an open capture ** corresponding to a close */ -static Capture *findopen (Capture *cap) { - int n = 0; /* number of closes waiting an open */ - for (;;) { - cap--; - if (isclosecap(cap)) n++; /* one more open to skip */ - else if (!isfullcap(cap)) - if (n-- == 0) return cap; - } +static Capture *findopen(Capture *cap) +{ + int n = 0; /* number of closes waiting an open */ + for (;;) + { + cap--; + if (isclosecap(cap)) + n++; /* one more open to skip */ + else if (!isfullcap(cap)) + if (n-- == 0) + return cap; + } } - /* ** Go to the next capture */ -static void nextcap (CapState *cs) { - Capture *cap = cs->cap; - if (!isfullcap(cap)) { /* not a single capture? */ - int n = 0; /* number of opens waiting a close */ - for (;;) { /* look for corresponding close */ - cap++; - if (isclosecap(cap)) { - if (n-- == 0) break; - } - else if (!isfullcap(cap)) n++; +static void nextcap(CapState *cs) +{ + Capture *cap = cs->cap; + if (!isfullcap(cap)) + { /* not a single capture? */ + int n = 0; /* number of opens waiting a close */ + for (;;) + { /* look for corresponding close */ + cap++; + if (isclosecap(cap)) + { + if (n-- == 0) + break; + } + else if (!isfullcap(cap)) + n++; + } } - } - cs->cap = cap + 1; /* + 1 to skip last close (or entire single capture) */ + cs->cap = cap + 1; /* + 1 to skip last close (or entire single capture) */ } - /* ** Push on the Lua stack all values generated by nested captures inside ** the current capture. Returns number of values pushed. 'addextra' @@ -83,243 +88,262 @@ static void nextcap (CapState *cs) { ** entire match is pushed also if there are no other nested values, ** so the function never returns zero. */ -static int pushnestedvalues (CapState *cs, int addextra) { - Capture *co = cs->cap; - if (isfullcap(cs->cap++)) { /* no nested captures? */ - lua_pushlstring(cs->L, co->s, co->siz - 1); /* push whole match */ - return 1; /* that is it */ - } - else { - int n = 0; - while (!isclosecap(cs->cap)) /* repeat for all nested patterns */ - n += pushcapture(cs); - if (addextra || n == 0) { /* need extra? */ - lua_pushlstring(cs->L, co->s, cs->cap->s - co->s); /* push whole match */ - n++; +static int pushnestedvalues(CapState *cs, int addextra) +{ + Capture *co = cs->cap; + if (isfullcap(cs->cap++)) + { /* no nested captures? */ + lua_pushlstring(cs->L, co->s, co->siz - 1); /* push whole match */ + return 1; /* that is it */ + } + else + { + int n = 0; + while (!isclosecap(cs->cap)) /* repeat for all nested patterns */ + n += pushcapture(cs); + if (addextra || n == 0) + { /* need extra? */ + lua_pushlstring(cs->L, co->s, cs->cap->s - co->s); /* push whole match */ + n++; + } + cs->cap++; /* skip close entry */ + return n; } - cs->cap++; /* skip close entry */ - return n; - } } - /* ** Push only the first value generated by nested captures */ -static void pushonenestedvalue (CapState *cs) { - int n = pushnestedvalues(cs, 0); - if (n > 1) - lua_pop(cs->L, n - 1); /* pop extra values */ +static void pushonenestedvalue(CapState *cs) +{ + int n = pushnestedvalues(cs, 0); + if (n > 1) + lua_pop(cs->L, n - 1); /* pop extra values */ } - /* ** Try to find a named group capture with the name given at the top of ** the stack; goes backward from 'cap'. */ -static Capture *findback (CapState *cs, Capture *cap) { - lua_State *L = cs->L; - while (cap-- > cs->ocap) { /* repeat until end of list */ - if (isclosecap(cap)) - cap = findopen(cap); /* skip nested captures */ - else if (!isfullcap(cap)) - continue; /* opening an enclosing capture: skip and get previous */ - if (captype(cap) == Cgroup) { - getfromktable(cs, cap->idx); /* get group name */ - if (lp_equal(L, -2, -1)) { /* right group? */ - lua_pop(L, 2); /* remove reference name and group name */ - return cap; - } - else lua_pop(L, 1); /* remove group name */ +static Capture *findback(CapState *cs, Capture *cap) +{ + lua_State *L = cs->L; + while (cap-- > cs->ocap) + { /* repeat until end of list */ + if (isclosecap(cap)) + cap = findopen(cap); /* skip nested captures */ + else if (!isfullcap(cap)) + continue; /* opening an enclosing capture: skip and get previous */ + if (captype(cap) == Cgroup) + { + getfromktable(cs, cap->idx); /* get group name */ + if (lp_equal(L, -2, -1)) + { /* right group? */ + lua_pop(L, 2); /* remove reference name and group name */ + return cap; + } + else + lua_pop(L, 1); /* remove group name */ + } } - } - luaL_error(L, "back reference '%s' not found", lua_tostring(L, -1)); - return NULL; /* to avoid warnings */ + luaL_error(L, "back reference '%s' not found", lua_tostring(L, -1)); + return NULL; /* to avoid warnings */ } - /* ** Back-reference capture. Return number of values pushed. */ -static int backrefcap (CapState *cs) { - int n; - Capture *curr = cs->cap; - pushluaval(cs); /* reference name */ - cs->cap = findback(cs, curr); /* find corresponding group */ - n = pushnestedvalues(cs, 0); /* push group's values */ - cs->cap = curr + 1; - return n; +static int backrefcap(CapState *cs) +{ + int n; + Capture *curr = cs->cap; + pushluaval(cs); /* reference name */ + cs->cap = findback(cs, curr); /* find corresponding group */ + n = pushnestedvalues(cs, 0); /* push group's values */ + cs->cap = curr + 1; + return n; } - /* ** Table capture: creates a new table and populates it with nested ** captures. */ -static int tablecap (CapState *cs) { - lua_State *L = cs->L; - int n = 0; - lua_newtable(L); - if (isfullcap(cs->cap++)) - return 1; /* table is empty */ - while (!isclosecap(cs->cap)) { - if (captype(cs->cap) == Cgroup && cs->cap->idx != 0) { /* named group? */ - pushluaval(cs); /* push group name */ - pushonenestedvalue(cs); - lua_settable(L, -3); - } - else { /* not a named group */ - int i; - int k = pushcapture(cs); - for (i = k; i > 0; i--) /* store all values into table */ - lua_rawseti(L, -(i + 1), n + i); - n += k; +static int tablecap(CapState *cs) +{ + lua_State *L = cs->L; + int n = 0; + lua_newtable(L); + if (isfullcap(cs->cap++)) + return 1; /* table is empty */ + while (!isclosecap(cs->cap)) + { + if (captype(cs->cap) == Cgroup && cs->cap->idx != 0) + { /* named group? */ + pushluaval(cs); /* push group name */ + pushonenestedvalue(cs); + lua_settable(L, -3); + } + else + { /* not a named group */ + int i; + int k = pushcapture(cs); + for (i = k; i > 0; i--) /* store all values into table */ + lua_rawseti(L, -(i + 1), n + i); + n += k; + } } - } - cs->cap++; /* skip close entry */ - return 1; /* number of values pushed (only the table) */ + cs->cap++; /* skip close entry */ + return 1; /* number of values pushed (only the table) */ } - /* ** Table-query capture */ -static int querycap (CapState *cs) { - int idx = cs->cap->idx; - pushonenestedvalue(cs); /* get nested capture */ - lua_gettable(cs->L, updatecache(cs, idx)); /* query cap. value at table */ - if (!lua_isnil(cs->L, -1)) - return 1; - else { /* no value */ - lua_pop(cs->L, 1); /* remove nil */ - return 0; - } +static int querycap(CapState *cs) +{ + int idx = cs->cap->idx; + pushonenestedvalue(cs); /* get nested capture */ + lua_gettable(cs->L, updatecache(cs, idx)); /* query cap. value at table */ + if (!lua_isnil(cs->L, -1)) + return 1; + else + { /* no value */ + lua_pop(cs->L, 1); /* remove nil */ + return 0; + } } - /* ** Fold capture */ -static int foldcap (CapState *cs) { - int n; - lua_State *L = cs->L; - int idx = cs->cap->idx; - if (isfullcap(cs->cap++) || /* no nested captures? */ - isclosecap(cs->cap) || /* no nested captures (large subject)? */ - (n = pushcapture(cs)) == 0) /* nested captures with no values? */ - return luaL_error(L, "no initial value for fold capture"); - if (n > 1) - lua_pop(L, n - 1); /* leave only one result for accumulator */ - while (!isclosecap(cs->cap)) { - lua_pushvalue(L, updatecache(cs, idx)); /* get folding function */ - lua_insert(L, -2); /* put it before accumulator */ - n = pushcapture(cs); /* get next capture's values */ - lua_call(L, n + 1, 1); /* call folding function */ - } - cs->cap++; /* skip close entry */ - return 1; /* only accumulator left on the stack */ +static int foldcap(CapState *cs) +{ + int n; + lua_State *L = cs->L; + int idx = cs->cap->idx; + if (isfullcap(cs->cap++) || /* no nested captures? */ + isclosecap(cs->cap) || /* no nested captures (large subject)? */ + (n = pushcapture(cs)) == 0) /* nested captures with no values? */ + return luaL_error(L, "no initial value for fold capture"); + if (n > 1) + lua_pop(L, n - 1); /* leave only one result for accumulator */ + while (!isclosecap(cs->cap)) + { + lua_pushvalue(L, updatecache(cs, idx)); /* get folding function */ + lua_insert(L, -2); /* put it before accumulator */ + n = pushcapture(cs); /* get next capture's values */ + lua_call(L, n + 1, 1); /* call folding function */ + } + cs->cap++; /* skip close entry */ + return 1; /* only accumulator left on the stack */ } - /* ** Function capture */ -static int functioncap (CapState *cs) { - int n; - int top = lua_gettop(cs->L); - pushluaval(cs); /* push function */ - n = pushnestedvalues(cs, 0); /* push nested captures */ - lua_call(cs->L, n, LUA_MULTRET); /* call function */ - return lua_gettop(cs->L) - top; /* return function's results */ +static int functioncap(CapState *cs) +{ + int n; + int top = lua_gettop(cs->L); + pushluaval(cs); /* push function */ + n = pushnestedvalues(cs, 0); /* push nested captures */ + lua_call(cs->L, n, LUA_MULTRET); /* call function */ + return lua_gettop(cs->L) - top; /* return function's results */ } - /* ** Select capture */ -static int numcap (CapState *cs) { - int idx = cs->cap->idx; /* value to select */ - if (idx == 0) { /* no values? */ - nextcap(cs); /* skip entire capture */ - return 0; /* no value produced */ - } - else { - int n = pushnestedvalues(cs, 0); - if (n < idx) /* invalid index? */ - return luaL_error(cs->L, "no capture '%d'", idx); - else { - lua_pushvalue(cs->L, -(n - idx + 1)); /* get selected capture */ - lua_replace(cs->L, -(n + 1)); /* put it in place of 1st capture */ - lua_pop(cs->L, n - 1); /* remove other captures */ - return 1; +static int numcap(CapState *cs) +{ + int idx = cs->cap->idx; /* value to select */ + if (idx == 0) + { /* no values? */ + nextcap(cs); /* skip entire capture */ + return 0; /* no value produced */ + } + else + { + int n = pushnestedvalues(cs, 0); + if (n < idx) /* invalid index? */ + return luaL_error(cs->L, "no capture '%d'", idx); + else + { + lua_pushvalue(cs->L, -(n - idx + 1)); /* get selected capture */ + lua_replace(cs->L, -(n + 1)); /* put it in place of 1st capture */ + lua_pop(cs->L, n - 1); /* remove other captures */ + return 1; + } } - } } - /* ** Return the stack index of the first runtime capture in the given ** list of captures (or zero if no runtime captures) */ -int finddyncap (Capture *cap, Capture *last) { - for (; cap < last; cap++) { - if (cap->kind == Cruntime) - return cap->idx; /* stack position of first capture */ - } - return 0; /* no dynamic captures in this segment */ +int finddyncap(Capture *cap, Capture *last) +{ + for (; cap < last; cap++) + { + if (cap->kind == Cruntime) + return cap->idx; /* stack position of first capture */ + } + return 0; /* no dynamic captures in this segment */ } - /* ** Calls a runtime capture. Returns number of captures removed by ** the call, including the initial Cgroup. (Captures to be added are ** on the Lua stack.) */ -int runtimecap (CapState *cs, Capture *close, const char *s, int *rem) { - int n, id; - lua_State *L = cs->L; - int otop = lua_gettop(L); - Capture *open = findopen(close); - assert(captype(open) == Cgroup); - id = finddyncap(open, close); /* get first dynamic capture argument */ - close->kind = Cclose; /* closes the group */ - close->s = s; - cs->cap = open; cs->valuecached = 0; /* prepare capture state */ - luaL_checkstack(L, 4, "too many runtime captures"); - pushluaval(cs); /* push function to be called */ - lua_pushvalue(L, SUBJIDX); /* push original subject */ - lua_pushinteger(L, s - cs->s + 1); /* push current position */ - n = pushnestedvalues(cs, 0); /* push nested captures */ - lua_call(L, n + 2, LUA_MULTRET); /* call dynamic function */ - if (id > 0) { /* are there old dynamic captures to be removed? */ - int i; - for (i = id; i <= otop; i++) - lua_remove(L, id); /* remove old dynamic captures */ - *rem = otop - id + 1; /* total number of dynamic captures removed */ - } - else - *rem = 0; /* no dynamic captures removed */ - return close - open; /* number of captures of all kinds removed */ +int runtimecap(CapState *cs, Capture *close, const char *s, int *rem) +{ + int n, id; + lua_State *L = cs->L; + int otop = lua_gettop(L); + Capture *open = findopen(close); + assert(captype(open) == Cgroup); + id = finddyncap(open, close); /* get first dynamic capture argument */ + close->kind = Cclose; /* closes the group */ + close->s = s; + cs->cap = open; + cs->valuecached = 0; /* prepare capture state */ + luaL_checkstack(L, 4, "too many runtime captures"); + pushluaval(cs); /* push function to be called */ + lua_pushvalue(L, SUBJIDX); /* push original subject */ + lua_pushinteger(L, s - cs->s + 1); /* push current position */ + n = pushnestedvalues(cs, 0); /* push nested captures */ + lua_call(L, n + 2, LUA_MULTRET); /* call dynamic function */ + if (id > 0) + { /* are there old dynamic captures to be removed? */ + int i; + for (i = id; i <= otop; i++) lua_remove(L, id); /* remove old dynamic captures */ + *rem = otop - id + 1; /* total number of dynamic captures removed */ + } + else + *rem = 0; /* no dynamic captures removed */ + return close - open; /* number of captures of all kinds removed */ } - /* ** Auxiliary structure for substitution and string captures: keep ** information about nested captures for future use, avoiding to push ** string results into Lua */ -typedef struct StrAux { - int isstring; /* whether capture is a string */ - union { - Capture *cp; /* if not a string, respective capture */ - struct { /* if it is a string... */ - const char *s; /* ... starts here */ - const char *e; /* ... ends here */ - } s; - } u; +typedef struct StrAux +{ + int isstring; /* whether capture is a string */ + union { + Capture *cp; /* if not a string, respective capture */ + struct + { /* if it is a string... */ + const char *s; /* ... starts here */ + const char *e; /* ... ends here */ + } s; + } u; } StrAux; -#define MAXSTRCAPS 10 +#define MAXSTRCAPS 10 /* ** Collect values from current capture into array 'cps'. Current @@ -327,211 +351,245 @@ typedef struct StrAux { ** (In first call, fills %0 with whole match for Cstring.) ** Returns number of elements in the array that were filled. */ -static int getstrcaps (CapState *cs, StrAux *cps, int n) { - int k = n++; - cps[k].isstring = 1; /* get string value */ - cps[k].u.s.s = cs->cap->s; /* starts here */ - if (!isfullcap(cs->cap++)) { /* nested captures? */ - while (!isclosecap(cs->cap)) { /* traverse them */ - if (n >= MAXSTRCAPS) /* too many captures? */ - nextcap(cs); /* skip extra captures (will not need them) */ - else if (captype(cs->cap) == Csimple) /* string? */ - n = getstrcaps(cs, cps, n); /* put info. into array */ - else { - cps[n].isstring = 0; /* not a string */ - cps[n].u.cp = cs->cap; /* keep original capture */ - nextcap(cs); - n++; - } +static int getstrcaps(CapState *cs, StrAux *cps, int n) +{ + int k = n++; + cps[k].isstring = 1; /* get string value */ + cps[k].u.s.s = cs->cap->s; /* starts here */ + if (!isfullcap(cs->cap++)) + { /* nested captures? */ + while (!isclosecap(cs->cap)) + { /* traverse them */ + if (n >= MAXSTRCAPS) /* too many captures? */ + nextcap(cs); /* skip extra captures (will not need them) */ + else if (captype(cs->cap) == Csimple) /* string? */ + n = getstrcaps(cs, cps, n); /* put info. into array */ + else + { + cps[n].isstring = 0; /* not a string */ + cps[n].u.cp = cs->cap; /* keep original capture */ + nextcap(cs); + n++; + } + } + cs->cap++; /* skip close */ } - cs->cap++; /* skip close */ - } - cps[k].u.s.e = closeaddr(cs->cap - 1); /* ends here */ - return n; + cps[k].u.s.e = closeaddr(cs->cap - 1); /* ends here */ + return n; } - /* ** add next capture value (which should be a string) to buffer 'b' */ -static int addonestring (luaL_Buffer *b, CapState *cs, const char *what); - +static int addonestring(luaL_Buffer *b, CapState *cs, const char *what); /* ** String capture: add result to buffer 'b' (instead of pushing ** it into the stack) */ -static void stringcap (luaL_Buffer *b, CapState *cs) { - StrAux cps[MAXSTRCAPS]; - int n; - size_t len, i; - const char *fmt; /* format string */ - fmt = lua_tolstring(cs->L, updatecache(cs, cs->cap->idx), &len); - n = getstrcaps(cs, cps, 0) - 1; /* collect nested captures */ - for (i = 0; i < len; i++) { /* traverse them */ - if (fmt[i] != '%') /* not an escape? */ - luaL_addchar(b, fmt[i]); /* add it to buffer */ - else if (fmt[++i] < '0' || fmt[i] > '9') /* not followed by a digit? */ - luaL_addchar(b, fmt[i]); /* add to buffer */ - else { - int l = fmt[i] - '0'; /* capture index */ - if (l > n) - luaL_error(cs->L, "invalid capture index (%d)", l); - else if (cps[l].isstring) - luaL_addlstring(b, cps[l].u.s.s, cps[l].u.s.e - cps[l].u.s.s); - else { - Capture *curr = cs->cap; - cs->cap = cps[l].u.cp; /* go back to evaluate that nested capture */ - if (!addonestring(b, cs, "capture")) - luaL_error(cs->L, "no values in capture index %d", l); - cs->cap = curr; /* continue from where it stopped */ - } +static void stringcap(luaL_Buffer *b, CapState *cs) +{ + StrAux cps[MAXSTRCAPS]; + int n; + size_t len, i; + const char *fmt; /* format string */ + fmt = lua_tolstring(cs->L, updatecache(cs, cs->cap->idx), &len); + n = getstrcaps(cs, cps, 0) - 1; /* collect nested captures */ + for (i = 0; i < len; i++) + { /* traverse them */ + if (fmt[i] != '%') /* not an escape? */ + luaL_addchar(b, fmt[i]); /* add it to buffer */ + else if (fmt[++i] < '0' || fmt[i] > '9') /* not followed by a digit? */ + luaL_addchar(b, fmt[i]); /* add to buffer */ + else + { + int l = fmt[i] - '0'; /* capture index */ + if (l > n) + luaL_error(cs->L, "invalid capture index (%d)", l); + else if (cps[l].isstring) + luaL_addlstring(b, cps[l].u.s.s, cps[l].u.s.e - cps[l].u.s.s); + else + { + Capture *curr = cs->cap; + cs->cap = cps[l].u.cp; /* go back to evaluate that nested capture */ + if (!addonestring(b, cs, "capture")) + luaL_error(cs->L, "no values in capture index %d", l); + cs->cap = curr; /* continue from where it stopped */ + } + } } - } } - /* ** Substitution capture: add result to buffer 'b' */ -static void substcap (luaL_Buffer *b, CapState *cs) { - const char *curr = cs->cap->s; - if (isfullcap(cs->cap)) /* no nested captures? */ - luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */ - else { - cs->cap++; /* skip open entry */ - while (!isclosecap(cs->cap)) { /* traverse nested captures */ - const char *next = cs->cap->s; - luaL_addlstring(b, curr, next - curr); /* add text up to capture */ - if (addonestring(b, cs, "replacement")) - curr = closeaddr(cs->cap - 1); /* continue after match */ - else /* no capture value */ - curr = next; /* keep original text in final result */ +static void substcap(luaL_Buffer *b, CapState *cs) +{ + const char *curr = cs->cap->s; + if (isfullcap(cs->cap)) /* no nested captures? */ + luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */ + else + { + cs->cap++; /* skip open entry */ + while (!isclosecap(cs->cap)) + { /* traverse nested captures */ + const char *next = cs->cap->s; + luaL_addlstring(b, curr, next - curr); /* add text up to capture */ + if (addonestring(b, cs, "replacement")) + curr = closeaddr(cs->cap - 1); /* continue after match */ + else /* no capture value */ + curr = next; /* keep original text in final result */ + } + luaL_addlstring(b, curr, cs->cap->s - curr); /* add last piece of text */ } - luaL_addlstring(b, curr, cs->cap->s - curr); /* add last piece of text */ - } - cs->cap++; /* go to next capture */ + cs->cap++; /* go to next capture */ } - /* ** Evaluates a capture and adds its first value to buffer 'b'; returns ** whether there was a value */ -static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) { - switch (captype(cs->cap)) { - case Cstring: - stringcap(b, cs); /* add capture directly to buffer */ - return 1; - case Csubst: - substcap(b, cs); /* add capture directly to buffer */ - return 1; - default: { - lua_State *L = cs->L; - int n = pushcapture(cs); - if (n > 0) { - if (n > 1) lua_pop(L, n - 1); /* only one result */ - if (!lua_isstring(L, -1)) - luaL_error(L, "invalid %s value (a %s)", what, luaL_typename(L, -1)); - luaL_addvalue(b); - } - return n; +static int addonestring(luaL_Buffer *b, CapState *cs, const char *what) +{ + switch (captype(cs->cap)) + { + case Cstring: + stringcap(b, cs); /* add capture directly to buffer */ + return 1; + case Csubst: + substcap(b, cs); /* add capture directly to buffer */ + return 1; + default: + { + lua_State *L = cs->L; + int n = pushcapture(cs); + if (n > 0) + { + if (n > 1) + lua_pop(L, n - 1); /* only one result */ + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid %s value (a %s)", what, luaL_typename(L, -1)); + luaL_addvalue(b); + } + return n; + } } - } } - /* ** Push all values of the current capture into the stack; returns ** number of values pushed */ -static int pushcapture (CapState *cs) { - lua_State *L = cs->L; - luaL_checkstack(L, 4, "too many captures"); - switch (captype(cs->cap)) { - case Cposition: { - lua_pushinteger(L, cs->cap->s - cs->s + 1); - cs->cap++; - return 1; +static int pushcapture(CapState *cs) +{ + lua_State *L = cs->L; + luaL_checkstack(L, 4, "too many captures"); + switch (captype(cs->cap)) + { + case Cposition: + { + lua_pushinteger(L, cs->cap->s - cs->s + 1); + cs->cap++; + return 1; + } + case Cconst: + { + pushluaval(cs); + cs->cap++; + return 1; + } + case Carg: + { + int arg = (cs->cap++)->idx; + if (arg + FIXEDARGS > cs->ptop) + return luaL_error(L, "reference to absent extra argument #%d", arg); + lua_pushvalue(L, arg + FIXEDARGS); + return 1; + } + case Csimple: + { + int k = pushnestedvalues(cs, 1); + lua_insert(L, -k); /* make whole match be first result */ + return k; + } + case Cruntime: + { + lua_pushvalue(L, (cs->cap++)->idx); /* value is in the stack */ + return 1; + } + case Cstring: + { + luaL_Buffer b; + luaL_buffinit(L, &b); + stringcap(&b, cs); + luaL_pushresult(&b); + return 1; + } + case Csubst: + { + luaL_Buffer b; + luaL_buffinit(L, &b); + substcap(&b, cs); + luaL_pushresult(&b); + return 1; + } + case Cgroup: + { + if (cs->cap->idx == 0) /* anonymous group? */ + return pushnestedvalues(cs, 0); /* add all nested values */ + else + { /* named group: add no values */ + nextcap(cs); /* skip capture */ + return 0; + } + } + case Cbackref: + return backrefcap(cs); + case Ctable: + return tablecap(cs); + case Cfunction: + return functioncap(cs); + case Cnum: + return numcap(cs); + case Cquery: + return querycap(cs); + case Cfold: + return foldcap(cs); + default: + assert(0); + return 0; } - case Cconst: { - pushluaval(cs); - cs->cap++; - return 1; - } - case Carg: { - int arg = (cs->cap++)->idx; - if (arg + FIXEDARGS > cs->ptop) - return luaL_error(L, "reference to absent extra argument #%d", arg); - lua_pushvalue(L, arg + FIXEDARGS); - return 1; - } - case Csimple: { - int k = pushnestedvalues(cs, 1); - lua_insert(L, -k); /* make whole match be first result */ - return k; - } - case Cruntime: { - lua_pushvalue(L, (cs->cap++)->idx); /* value is in the stack */ - return 1; - } - case Cstring: { - luaL_Buffer b; - luaL_buffinit(L, &b); - stringcap(&b, cs); - luaL_pushresult(&b); - return 1; - } - case Csubst: { - luaL_Buffer b; - luaL_buffinit(L, &b); - substcap(&b, cs); - luaL_pushresult(&b); - return 1; - } - case Cgroup: { - if (cs->cap->idx == 0) /* anonymous group? */ - return pushnestedvalues(cs, 0); /* add all nested values */ - else { /* named group: add no values */ - nextcap(cs); /* skip capture */ - return 0; - } - } - case Cbackref: return backrefcap(cs); - case Ctable: return tablecap(cs); - case Cfunction: return functioncap(cs); - case Cnum: return numcap(cs); - case Cquery: return querycap(cs); - case Cfold: return foldcap(cs); - default: assert(0); return 0; - } } - /* ** Prepare a CapState structure and traverse the entire list of ** captures in the stack pushing its results. 's' is the subject -** string, 'r' is the final position of the match, and 'ptop' +** string, 'r' is the final position of the match, and 'ptop' ** the index in the stack where some useful values were pushed. ** Returns the number of results pushed. (If the list produces no ** results, push the final position of the match.) */ -int getcaptures (lua_State *L, const char *s, const char *r, int ptop) { - Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop)); - int n = 0; - if (!isclosecap(capture)) { /* is there any capture? */ - CapState cs; - cs.ocap = cs.cap = capture; cs.L = L; - cs.s = s; cs.valuecached = 0; cs.ptop = ptop; - do { /* collect their values */ - n += pushcapture(&cs); - } while (!isclosecap(cs.cap)); - } - if (n == 0) { /* no capture values? */ - lua_pushinteger(L, r - s + 1); /* return only end position */ - n = 1; - } - return n; +int getcaptures(lua_State *L, const char *s, const char *r, int ptop) +{ + Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop)); + int n = 0; + if (!isclosecap(capture)) + { /* is there any capture? */ + CapState cs; + cs.ocap = cs.cap = capture; + cs.L = L; + cs.s = s; + cs.valuecached = 0; + cs.ptop = ptop; + do + { /* collect their values */ + n += pushcapture(&cs); + } while (!isclosecap(cs.cap)); + } + if (n == 0) + { /* no capture values? */ + lua_pushinteger(L, r - s + 1); /* return only end position */ + n = 1; + } + return n; } - - diff --git a/LuaNode_Esp32/LuaNode32/components/lpeg/lpcode.c b/LuaNode_Esp32/LuaNode32/components/lpeg/lpcode.c index fbf44fe..906c9a9 100644 --- a/LuaNode_Esp32/LuaNode32/components/lpeg/lpcode.c +++ b/LuaNode_Esp32/LuaNode32/components/lpeg/lpcode.c @@ -3,26 +3,20 @@ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ -#include +#include "lpcode.h" +#include -#include "lua.h" #include "lauxlib.h" - #include "lptypes.h" -#include "lpcode.h" - +#include "lua.h" /* signals a "no-instruction */ -#define NOINST -1 - - +#define NOINST -1 -static const Charset fullset_ = - {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; +static const Charset fullset_ = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; static const Charset *fullset = &fullset_; @@ -38,119 +32,155 @@ static const Charset *fullset = &fullset_; ** which character it is. (When generic set, the set was the input, ** so there is no need to return it.) */ -static Opcode charsettype (const byte *cs, int *c) { - int count = 0; /* number of characters in the set */ - int i; - int candidate = -1; /* candidate position for the singleton char */ - for (i = 0; i < CHARSETSIZE; i++) { /* for each byte */ - int b = cs[i]; - if (b == 0) { /* is byte empty? */ - if (count > 1) /* was set neither empty nor singleton? */ - return ISet; /* neither full nor empty nor singleton */ - /* else set is still empty or singleton */ - } - else if (b == 0xFF) { /* is byte full? */ - if (count < (i * BITSPERCHAR)) /* was set not full? */ - return ISet; /* neither full nor empty nor singleton */ - else count += BITSPERCHAR; /* set is still full */ - } - else if ((b & (b - 1)) == 0) { /* has byte only one bit? */ - if (count > 0) /* was set not empty? */ - return ISet; /* neither full nor empty nor singleton */ - else { /* set has only one char till now; track it */ - count++; - candidate = i; - } - } - else return ISet; /* byte is neither empty, full, nor singleton */ - } - switch (count) { - case 0: return IFail; /* empty set */ - case 1: { /* singleton; find character bit inside byte */ - int b = cs[candidate]; - *c = candidate * BITSPERCHAR; - if ((b & 0xF0) != 0) { *c += 4; b >>= 4; } - if ((b & 0x0C) != 0) { *c += 2; b >>= 2; } - if ((b & 0x02) != 0) { *c += 1; } - return IChar; +static Opcode charsettype(const byte *cs, int *c) +{ + int count = 0; /* number of characters in the set */ + int i; + int candidate = -1; /* candidate position for the singleton char */ + for (i = 0; i < CHARSETSIZE; i++) + { /* for each byte */ + int b = cs[i]; + if (b == 0) + { /* is byte empty? */ + if (count > 1) /* was set neither empty nor singleton? */ + return ISet; /* neither full nor empty nor singleton */ + /* else set is still empty or singleton */ + } + else if (b == 0xFF) + { /* is byte full? */ + if (count < (i * BITSPERCHAR)) /* was set not full? */ + return ISet; /* neither full nor empty nor singleton */ + else + count += BITSPERCHAR; /* set is still full */ + } + else if ((b & (b - 1)) == 0) + { /* has byte only one bit? */ + if (count > 0) /* was set not empty? */ + return ISet; /* neither full nor empty nor singleton */ + else + { /* set has only one char till now; track it */ + count++; + candidate = i; + } + } + else + return ISet; /* byte is neither empty, full, nor singleton */ } - default: { - assert(count == CHARSETSIZE * BITSPERCHAR); /* full set */ - return IAny; + switch (count) + { + case 0: + return IFail; /* empty set */ + case 1: + { /* singleton; find character bit inside byte */ + int b = cs[candidate]; + *c = candidate * BITSPERCHAR; + if ((b & 0xF0) != 0) + { + *c += 4; + b >>= 4; + } + if ((b & 0x0C) != 0) + { + *c += 2; + b >>= 2; + } + if ((b & 0x02) != 0) + { + *c += 1; + } + return IChar; + } + default: + { + assert(count == CHARSETSIZE * BITSPERCHAR); /* full set */ + return IAny; + } } - } } - /* ** A few basic operations on Charsets */ -static void cs_complement (Charset *cs) { - loopset(i, cs->cs[i] = ~cs->cs[i]); -} +static void cs_complement(Charset *cs) { loopset(i, cs->cs[i] = ~cs->cs[i]); } -static int cs_equal (const byte *cs1, const byte *cs2) { - loopset(i, if (cs1[i] != cs2[i]) return 0); - return 1; +static int cs_equal(const byte *cs1, const byte *cs2) +{ + loopset(i, if (cs1[i] != cs2[i]) return 0); + return 1; } -static int cs_disjoint (const Charset *cs1, const Charset *cs2) { - loopset(i, if ((cs1->cs[i] & cs2->cs[i]) != 0) return 0;) - return 1; +static int cs_disjoint(const Charset *cs1, const Charset *cs2) +{ + loopset(i, if ((cs1->cs[i] & cs2->cs[i]) != 0) return 0;) return 1; } - /* ** If 'tree' is a 'char' pattern (TSet, TChar, TAny), convert it into a ** charset and return 1; else return 0. */ -int tocharset (TTree *tree, Charset *cs) { - switch (tree->tag) { - case TSet: { /* copy set */ - loopset(i, cs->cs[i] = treebuffer(tree)[i]); - return 1; - } - case TChar: { /* only one char */ - assert(0 <= tree->u.n && tree->u.n <= UCHAR_MAX); - loopset(i, cs->cs[i] = 0); /* erase all chars */ - setchar(cs->cs, tree->u.n); /* add that one */ - return 1; - } - case TAny: { - loopset(i, cs->cs[i] = 0xFF); /* add all characters to the set */ - return 1; +int tocharset(TTree *tree, Charset *cs) +{ + switch (tree->tag) + { + case TSet: + { /* copy set */ + loopset(i, cs->cs[i] = treebuffer(tree)[i]); + return 1; + } + case TChar: + { /* only one char */ + assert(0 <= tree->u.n && tree->u.n <= UCHAR_MAX); + loopset(i, cs->cs[i] = 0); /* erase all chars */ + setchar(cs->cs, tree->u.n); /* add that one */ + return 1; + } + case TAny: + { + loopset(i, cs->cs[i] = 0xFF); /* add all characters to the set */ + return 1; + } + default: + return 0; } - default: return 0; - } } - /* ** Check whether a pattern tree has captures */ -int hascaptures (TTree *tree) { - tailcall: - switch (tree->tag) { - case TCapture: case TRunTime: - return 1; - case TCall: - tree = sib2(tree); goto tailcall; /* return hascaptures(sib2(tree)); */ - case TOpenCall: assert(0); - default: { - switch (numsiblings[tree->tag]) { - case 1: /* return hascaptures(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case 2: - if (hascaptures(sib1(tree))) return 1; - /* else return hascaptures(sib2(tree)); */ - tree = sib2(tree); goto tailcall; - default: assert(numsiblings[tree->tag] == 0); return 0; - } +int hascaptures(TTree *tree) +{ +tailcall: + switch (tree->tag) + { + case TCapture: + case TRunTime: + return 1; + case TCall: + tree = sib2(tree); + goto tailcall; /* return hascaptures(sib2(tree)); */ + case TOpenCall: + assert(0); + default: + { + switch (numsiblings[tree->tag]) + { + case 1: /* return hascaptures(sib1(tree)); */ + tree = sib1(tree); + goto tailcall; + case 2: + if (hascaptures(sib1(tree))) + return 1; + /* else return hascaptures(sib2(tree)); */ + tree = sib2(tree); + goto tailcall; + default: + assert(numsiblings[tree->tag] == 0); + return 0; + } + } } - } } - /* ** Checks how a pattern behaves regarding the empty string, ** in one of two different ways: @@ -169,83 +199,127 @@ int hascaptures (TTree *tree) { ** Run-time captures can do whatever they want, so the result ** is conservative. */ -int checkaux (TTree *tree, int pred) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - case TFalse: case TOpenCall: - return 0; /* not nullable */ - case TRep: case TTrue: - return 1; /* no fail */ - case TNot: case TBehind: /* can match empty, but can fail */ - if (pred == PEnofail) return 0; - else return 1; /* PEnullable */ - case TAnd: /* can match empty; fail iff body does */ - if (pred == PEnullable) return 1; - /* else return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TRunTime: /* can fail; match empty iff body does */ - if (pred == PEnofail) return 0; - /* else return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TSeq: - if (!checkaux(sib1(tree), pred)) return 0; - /* else return checkaux(sib2(tree), pred); */ - tree = sib2(tree); goto tailcall; - case TChoice: - if (checkaux(sib2(tree), pred)) return 1; - /* else return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TCapture: case TGrammar: case TRule: - /* return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TCall: /* return checkaux(sib2(tree), pred); */ - tree = sib2(tree); goto tailcall; - default: assert(0); return 0; - } +int checkaux(TTree *tree, int pred) +{ +tailcall: + switch (tree->tag) + { + case TChar: + case TSet: + case TAny: + case TFalse: + case TOpenCall: + return 0; /* not nullable */ + case TRep: + case TTrue: + return 1; /* no fail */ + case TNot: + case TBehind: /* can match empty, but can fail */ + if (pred == PEnofail) + return 0; + else + return 1; /* PEnullable */ + case TAnd: /* can match empty; fail iff body does */ + if (pred == PEnullable) + return 1; + /* else return checkaux(sib1(tree), pred); */ + tree = sib1(tree); + goto tailcall; + case TRunTime: /* can fail; match empty iff body does */ + if (pred == PEnofail) + return 0; + /* else return checkaux(sib1(tree), pred); */ + tree = sib1(tree); + goto tailcall; + case TSeq: + if (!checkaux(sib1(tree), pred)) + return 0; + /* else return checkaux(sib2(tree), pred); */ + tree = sib2(tree); + goto tailcall; + case TChoice: + if (checkaux(sib2(tree), pred)) + return 1; + /* else return checkaux(sib1(tree), pred); */ + tree = sib1(tree); + goto tailcall; + case TCapture: + case TGrammar: + case TRule: + /* return checkaux(sib1(tree), pred); */ + tree = sib1(tree); + goto tailcall; + case TCall: /* return checkaux(sib2(tree), pred); */ + tree = sib2(tree); + goto tailcall; + default: + assert(0); + return 0; + } } - /* ** number of characters to match a pattern (or -1 if variable) ** ('count' avoids infinite loops for grammars) */ -int fixedlenx (TTree *tree, int count, int len) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - return len + 1; - case TFalse: case TTrue: case TNot: case TAnd: case TBehind: - return len; - case TRep: case TRunTime: case TOpenCall: - return -1; - case TCapture: case TRule: case TGrammar: - /* return fixedlenx(sib1(tree), count); */ - tree = sib1(tree); goto tailcall; - case TCall: - if (count++ >= MAXRULES) - return -1; /* may be a loop */ - /* else return fixedlenx(sib2(tree), count); */ - tree = sib2(tree); goto tailcall; - case TSeq: { - len = fixedlenx(sib1(tree), count, len); - if (len < 0) return -1; - /* else return fixedlenx(sib2(tree), count, len); */ - tree = sib2(tree); goto tailcall; - } - case TChoice: { - int n1, n2; - n1 = fixedlenx(sib1(tree), count, len); - if (n1 < 0) return -1; - n2 = fixedlenx(sib2(tree), count, len); - if (n1 == n2) return n1; - else return -1; - } - default: assert(0); return 0; - }; +int fixedlenx(TTree *tree, int count, int len) +{ +tailcall: + switch (tree->tag) + { + case TChar: + case TSet: + case TAny: + return len + 1; + case TFalse: + case TTrue: + case TNot: + case TAnd: + case TBehind: + return len; + case TRep: + case TRunTime: + case TOpenCall: + return -1; + case TCapture: + case TRule: + case TGrammar: + /* return fixedlenx(sib1(tree), count); */ + tree = sib1(tree); + goto tailcall; + case TCall: + if (count++ >= MAXRULES) + return -1; /* may be a loop */ + /* else return fixedlenx(sib2(tree), count); */ + tree = sib2(tree); + goto tailcall; + case TSeq: + { + len = fixedlenx(sib1(tree), count, len); + if (len < 0) + return -1; + /* else return fixedlenx(sib2(tree), count, len); */ + tree = sib2(tree); + goto tailcall; + } + case TChoice: + { + int n1, n2; + n1 = fixedlenx(sib1(tree), count, len); + if (n1 < 0) + return -1; + n2 = fixedlenx(sib2(tree), count, len); + if (n1 == n2) + return n1; + else + return -1; + } + default: + assert(0); + return 0; + }; } - /* ** Computes the 'first set' of a pattern. ** The result is a conservative aproximation: @@ -264,172 +338,244 @@ int fixedlenx (TTree *tree, int count, int len) { ** 2) there is a match-time capture ==> return has bit 2 set ** (optimizations should not bypass match-time captures). */ -static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: { - tocharset(tree, firstset); - return 0; - } - case TTrue: { - loopset(i, firstset->cs[i] = follow->cs[i]); - return 1; /* accepts the empty string */ - } - case TFalse: { - loopset(i, firstset->cs[i] = 0); - return 0; - } - case TChoice: { - Charset csaux; - int e1 = getfirst(sib1(tree), follow, firstset); - int e2 = getfirst(sib2(tree), follow, &csaux); - loopset(i, firstset->cs[i] |= csaux.cs[i]); - return e1 | e2; - } - case TSeq: { - if (!nullable(sib1(tree))) { - /* when p1 is not nullable, p2 has nothing to contribute; - return getfirst(sib1(tree), fullset, firstset); */ - tree = sib1(tree); follow = fullset; goto tailcall; - } - else { /* FIRST(p1 p2, fl) = FIRST(p1, FIRST(p2, fl)) */ - Charset csaux; - int e2 = getfirst(sib2(tree), follow, &csaux); - int e1 = getfirst(sib1(tree), &csaux, firstset); - if (e1 == 0) return 0; /* 'e1' ensures that first can be used */ - else if ((e1 | e2) & 2) /* one of the children has a matchtime? */ - return 2; /* pattern has a matchtime capture */ - else return e2; /* else depends on 'e2' */ - } - } - case TRep: { - getfirst(sib1(tree), follow, firstset); - loopset(i, firstset->cs[i] |= follow->cs[i]); - return 1; /* accept the empty string */ - } - case TCapture: case TGrammar: case TRule: { - /* return getfirst(sib1(tree), follow, firstset); */ - tree = sib1(tree); goto tailcall; - } - case TRunTime: { /* function invalidates any follow info. */ - int e = getfirst(sib1(tree), fullset, firstset); - if (e) return 2; /* function is not "protected"? */ - else return 0; /* pattern inside capture ensures first can be used */ - } - case TCall: { - /* return getfirst(sib2(tree), follow, firstset); */ - tree = sib2(tree); goto tailcall; - } - case TAnd: { - int e = getfirst(sib1(tree), follow, firstset); - loopset(i, firstset->cs[i] &= follow->cs[i]); - return e; - } - case TNot: { - if (tocharset(sib1(tree), firstset)) { - cs_complement(firstset); - return 1; - } - /* else go through */ - } - case TBehind: { /* instruction gives no new information */ - /* call 'getfirst' only to check for math-time captures */ - int e = getfirst(sib1(tree), follow, firstset); - loopset(i, firstset->cs[i] = follow->cs[i]); /* uses follow */ - return e | 1; /* always can accept the empty string */ +static int getfirst(TTree *tree, const Charset *follow, Charset *firstset) +{ +tailcall: + switch (tree->tag) + { + case TChar: + case TSet: + case TAny: + { + tocharset(tree, firstset); + return 0; + } + case TTrue: + { + loopset(i, firstset->cs[i] = follow->cs[i]); + return 1; /* accepts the empty string */ + } + case TFalse: + { + loopset(i, firstset->cs[i] = 0); + return 0; + } + case TChoice: + { + Charset csaux; + int e1 = getfirst(sib1(tree), follow, firstset); + int e2 = getfirst(sib2(tree), follow, &csaux); + loopset(i, firstset->cs[i] |= csaux.cs[i]); + return e1 | e2; + } + case TSeq: + { + if (!nullable(sib1(tree))) + { + /* when p1 is not nullable, p2 has nothing to contribute; + return getfirst(sib1(tree), fullset, firstset); */ + tree = sib1(tree); + follow = fullset; + goto tailcall; + } + else + { /* FIRST(p1 p2, fl) = FIRST(p1, FIRST(p2, fl)) */ + Charset csaux; + int e2 = getfirst(sib2(tree), follow, &csaux); + int e1 = getfirst(sib1(tree), &csaux, firstset); + if (e1 == 0) + return 0; /* 'e1' ensures that first can be used */ + else if ((e1 | e2) & 2) /* one of the children has a matchtime? */ + return 2; /* pattern has a matchtime capture */ + else + return e2; /* else depends on 'e2' */ + } + } + case TRep: + { + getfirst(sib1(tree), follow, firstset); + loopset(i, firstset->cs[i] |= follow->cs[i]); + return 1; /* accept the empty string */ + } + case TCapture: + case TGrammar: + case TRule: + { + /* return getfirst(sib1(tree), follow, firstset); */ + tree = sib1(tree); + goto tailcall; + } + case TRunTime: + { /* function invalidates any follow info. */ + int e = getfirst(sib1(tree), fullset, firstset); + if (e) + return 2; /* function is not "protected"? */ + else + return 0; /* pattern inside capture ensures first can be used */ + } + case TCall: + { + /* return getfirst(sib2(tree), follow, firstset); */ + tree = sib2(tree); + goto tailcall; + } + case TAnd: + { + int e = getfirst(sib1(tree), follow, firstset); + loopset(i, firstset->cs[i] &= follow->cs[i]); + return e; + } + case TNot: + { + if (tocharset(sib1(tree), firstset)) + { + cs_complement(firstset); + return 1; + } + /* else go through */ + } + case TBehind: + { /* instruction gives no new information */ + /* call 'getfirst' only to check for math-time captures */ + int e = getfirst(sib1(tree), follow, firstset); + loopset(i, firstset->cs[i] = follow->cs[i]); /* uses follow */ + return e | 1; /* always can accept the empty string */ + } + default: + assert(0); + return 0; } - default: assert(0); return 0; - } } - /* ** If 'headfail(tree)' true, then 'tree' can fail only depending on the ** next character of the subject. */ -static int headfail (TTree *tree) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: case TFalse: - return 1; - case TTrue: case TRep: case TRunTime: case TNot: - case TBehind: - return 0; - case TCapture: case TGrammar: case TRule: case TAnd: - tree = sib1(tree); goto tailcall; /* return headfail(sib1(tree)); */ - case TCall: - tree = sib2(tree); goto tailcall; /* return headfail(sib2(tree)); */ - case TSeq: - if (!nofail(sib2(tree))) return 0; - /* else return headfail(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case TChoice: - if (!headfail(sib1(tree))) return 0; - /* else return headfail(sib2(tree)); */ - tree = sib2(tree); goto tailcall; - default: assert(0); return 0; - } +static int headfail(TTree *tree) +{ +tailcall: + switch (tree->tag) + { + case TChar: + case TSet: + case TAny: + case TFalse: + return 1; + case TTrue: + case TRep: + case TRunTime: + case TNot: + case TBehind: + return 0; + case TCapture: + case TGrammar: + case TRule: + case TAnd: + tree = sib1(tree); + goto tailcall; /* return headfail(sib1(tree)); */ + case TCall: + tree = sib2(tree); + goto tailcall; /* return headfail(sib2(tree)); */ + case TSeq: + if (!nofail(sib2(tree))) + return 0; + /* else return headfail(sib1(tree)); */ + tree = sib1(tree); + goto tailcall; + case TChoice: + if (!headfail(sib1(tree))) + return 0; + /* else return headfail(sib2(tree)); */ + tree = sib2(tree); + goto tailcall; + default: + assert(0); + return 0; + } } - /* ** Check whether the code generation for the given tree can benefit ** from a follow set (to avoid computing the follow set when it is ** not needed) */ -static int needfollow (TTree *tree) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - case TFalse: case TTrue: case TAnd: case TNot: - case TRunTime: case TGrammar: case TCall: case TBehind: - return 0; - case TChoice: case TRep: - return 1; - case TCapture: - tree = sib1(tree); goto tailcall; - case TSeq: - tree = sib2(tree); goto tailcall; - default: assert(0); return 0; - } +static int needfollow(TTree *tree) +{ +tailcall: + switch (tree->tag) + { + case TChar: + case TSet: + case TAny: + case TFalse: + case TTrue: + case TAnd: + case TNot: + case TRunTime: + case TGrammar: + case TCall: + case TBehind: + return 0; + case TChoice: + case TRep: + return 1; + case TCapture: + tree = sib1(tree); + goto tailcall; + case TSeq: + tree = sib2(tree); + goto tailcall; + default: + assert(0); + return 0; + } } /* }====================================================== */ - - /* ** {====================================================== ** Code generation ** ======================================================= */ - /* ** size of an instruction */ -int sizei (const Instruction *i) { - switch((Opcode)i->i.code) { - case ISet: case ISpan: return CHARSETINSTSIZE; - case ITestSet: return CHARSETINSTSIZE + 1; - case ITestChar: case ITestAny: case IChoice: case IJmp: case ICall: - case IOpenCall: case ICommit: case IPartialCommit: case IBackCommit: - return 2; - default: return 1; - } +int sizei(const Instruction *i) +{ + switch ((Opcode)i->i.code) + { + case ISet: + case ISpan: + return CHARSETINSTSIZE; + case ITestSet: + return CHARSETINSTSIZE + 1; + case ITestChar: + case ITestAny: + case IChoice: + case IJmp: + case ICall: + case IOpenCall: + case ICommit: + case IPartialCommit: + case IBackCommit: + return 2; + default: + return 1; + } } - /* ** state for the compiler */ -typedef struct CompileState { - Pattern *p; /* pattern being compiled */ - int ncode; /* next position in p->code to be filled */ - lua_State *L; +typedef struct CompileState +{ + Pattern *p; /* pattern being compiled */ + int ncode; /* next position in p->code to be filled */ + lua_State *L; } CompileState; - /* ** code generation is recursive; 'opt' indicates that the code is being ** generated as the last thing inside an optional pattern (so, if that @@ -437,205 +583,205 @@ typedef struct CompileState { ** the outer pattern). 'tt' points to a previous test protecting this ** code (or NOINST). 'fl' is the follow set of the pattern. */ -static void codegen (CompileState *compst, TTree *tree, int opt, int tt, - const Charset *fl); - - -void realloccode (lua_State *L, Pattern *p, int nsize) { - void *ud; - lua_Alloc f = lua_getallocf(L, &ud); - void *newblock = f(ud, p->code, p->codesize * sizeof(Instruction), - nsize * sizeof(Instruction)); - if (newblock == NULL && nsize > 0) - luaL_error(L, "not enough memory"); - p->code = (Instruction *)newblock; - p->codesize = nsize; +static void codegen(CompileState *compst, TTree *tree, int opt, int tt, const Charset *fl); + +void realloccode(lua_State *L, Pattern *p, int nsize) +{ + void *ud; + lua_Alloc f = lua_getallocf(L, &ud); + void *newblock = f(ud, p->code, p->codesize * sizeof(Instruction), nsize * sizeof(Instruction)); + if (newblock == NULL && nsize > 0) + luaL_error(L, "not enough memory"); + p->code = (Instruction *)newblock; + p->codesize = nsize; } - -static int nextinstruction (CompileState *compst) { - int size = compst->p->codesize; - if (compst->ncode >= size) - realloccode(compst->L, compst->p, size * 2); - return compst->ncode++; +static int nextinstruction(CompileState *compst) +{ + int size = compst->p->codesize; + if (compst->ncode >= size) + realloccode(compst->L, compst->p, size * 2); + return compst->ncode++; } +#define getinstr(cs, i) ((cs)->p->code[i]) -#define getinstr(cs,i) ((cs)->p->code[i]) - - -static int addinstruction (CompileState *compst, Opcode op, int aux) { - int i = nextinstruction(compst); - getinstr(compst, i).i.code = op; - getinstr(compst, i).i.aux = aux; - return i; +static int addinstruction(CompileState *compst, Opcode op, int aux) +{ + int i = nextinstruction(compst); + getinstr(compst, i).i.code = op; + getinstr(compst, i).i.aux = aux; + return i; } - /* ** Add an instruction followed by space for an offset (to be set later) */ -static int addoffsetinst (CompileState *compst, Opcode op) { - int i = addinstruction(compst, op, 0); /* instruction */ - addinstruction(compst, (Opcode)0, 0); /* open space for offset */ - assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2); - return i; +static int addoffsetinst(CompileState *compst, Opcode op) +{ + int i = addinstruction(compst, op, 0); /* instruction */ + addinstruction(compst, (Opcode)0, 0); /* open space for offset */ + assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2); + return i; } - /* ** Set the offset of an instruction */ -static void setoffset (CompileState *compst, int instruction, int offset) { - getinstr(compst, instruction + 1).offset = offset; +static void setoffset(CompileState *compst, int instruction, int offset) +{ + getinstr(compst, instruction + 1).offset = offset; } - /* ** Add a capture instruction: ** 'op' is the capture instruction; 'cap' the capture kind; ** 'key' the key into ktable; 'aux' is the optional capture offset ** */ -static int addinstcap (CompileState *compst, Opcode op, int cap, int key, - int aux) { - int i = addinstruction(compst, op, joinkindoff(cap, aux)); - getinstr(compst, i).i.key = key; - return i; +static int addinstcap(CompileState *compst, Opcode op, int cap, int key, int aux) +{ + int i = addinstruction(compst, op, joinkindoff(cap, aux)); + getinstr(compst, i).i.key = key; + return i; } +#define gethere(compst) ((compst)->ncode) -#define gethere(compst) ((compst)->ncode) - -#define target(code,i) ((i) + code[i + 1].offset) - +#define target(code, i) ((i) + code[i + 1].offset) /* ** Patch 'instruction' to jump to 'target' */ -static void jumptothere (CompileState *compst, int instruction, int target) { - if (instruction >= 0) - setoffset(compst, instruction, target - instruction); +static void jumptothere(CompileState *compst, int instruction, int target) +{ + if (instruction >= 0) + setoffset(compst, instruction, target - instruction); } - /* ** Patch 'instruction' to jump to current position */ -static void jumptohere (CompileState *compst, int instruction) { - jumptothere(compst, instruction, gethere(compst)); -} - +static void jumptohere(CompileState *compst, int instruction) { jumptothere(compst, instruction, gethere(compst)); } /* ** Code an IChar instruction, or IAny if there is an equivalent ** test dominating it */ -static void codechar (CompileState *compst, int c, int tt) { - if (tt >= 0 && getinstr(compst, tt).i.code == ITestChar && - getinstr(compst, tt).i.aux == c) - addinstruction(compst, IAny, 0); - else - addinstruction(compst, IChar, c); +static void codechar(CompileState *compst, int c, int tt) +{ + if (tt >= 0 && getinstr(compst, tt).i.code == ITestChar && getinstr(compst, tt).i.aux == c) + addinstruction(compst, IAny, 0); + else + addinstruction(compst, IChar, c); } - /* ** Add a charset posfix to an instruction */ -static void addcharset (CompileState *compst, const byte *cs) { - int p = gethere(compst); - int i; - for (i = 0; i < (int)CHARSETINSTSIZE - 1; i++) - nextinstruction(compst); /* space for buffer */ - /* fill buffer with charset */ - loopset(j, getinstr(compst, p).buff[j] = cs[j]); +static void addcharset(CompileState *compst, const byte *cs) +{ + int p = gethere(compst); + int i; + for (i = 0; i < (int)CHARSETINSTSIZE - 1; i++) nextinstruction(compst); /* space for buffer */ + /* fill buffer with charset */ + loopset(j, getinstr(compst, p).buff[j] = cs[j]); } - /* ** code a char set, optimizing unit sets for IChar, "complete" ** sets for IAny, and empty sets for IFail; also use an IAny ** when instruction is dominated by an equivalent test. */ -static void codecharset (CompileState *compst, const byte *cs, int tt) { - int c = 0; /* (=) to avoid warnings */ - Opcode op = charsettype(cs, &c); - switch (op) { - case IChar: codechar(compst, c, tt); break; - case ISet: { /* non-trivial set? */ - if (tt >= 0 && getinstr(compst, tt).i.code == ITestSet && - cs_equal(cs, getinstr(compst, tt + 2).buff)) - addinstruction(compst, IAny, 0); - else { - addinstruction(compst, ISet, 0); - addcharset(compst, cs); - } - break; +static void codecharset(CompileState *compst, const byte *cs, int tt) +{ + int c = 0; /* (=) to avoid warnings */ + Opcode op = charsettype(cs, &c); + switch (op) + { + case IChar: + codechar(compst, c, tt); + break; + case ISet: + { /* non-trivial set? */ + if (tt >= 0 && getinstr(compst, tt).i.code == ITestSet && cs_equal(cs, getinstr(compst, tt + 2).buff)) + addinstruction(compst, IAny, 0); + else + { + addinstruction(compst, ISet, 0); + addcharset(compst, cs); + } + break; + } + default: + addinstruction(compst, op, c); + break; } - default: addinstruction(compst, op, c); break; - } } - /* ** code a test set, optimizing unit sets for ITestChar, "complete" ** sets for ITestAny, and empty sets for IJmp (always fails). ** 'e' is true iff test should accept the empty string. (Test ** instructions in the current VM never accept the empty string.) */ -static int codetestset (CompileState *compst, Charset *cs, int e) { - if (e) return NOINST; /* no test */ - else { - int c = 0; - Opcode op = charsettype(cs->cs, &c); - switch (op) { - case IFail: return addoffsetinst(compst, IJmp); /* always jump */ - case IAny: return addoffsetinst(compst, ITestAny); - case IChar: { - int i = addoffsetinst(compst, ITestChar); - getinstr(compst, i).i.aux = c; - return i; - } - case ISet: { - int i = addoffsetinst(compst, ITestSet); - addcharset(compst, cs->cs); - return i; - } - default: assert(0); return 0; +static int codetestset(CompileState *compst, Charset *cs, int e) +{ + if (e) + return NOINST; /* no test */ + else + { + int c = 0; + Opcode op = charsettype(cs->cs, &c); + switch (op) + { + case IFail: + return addoffsetinst(compst, IJmp); /* always jump */ + case IAny: + return addoffsetinst(compst, ITestAny); + case IChar: + { + int i = addoffsetinst(compst, ITestChar); + getinstr(compst, i).i.aux = c; + return i; + } + case ISet: + { + int i = addoffsetinst(compst, ITestSet); + addcharset(compst, cs->cs); + return i; + } + default: + assert(0); + return 0; + } } - } } - /* ** Find the final destination of a sequence of jumps */ -static int finaltarget (Instruction *code, int i) { - while (code[i].i.code == IJmp) - i = target(code, i); - return i; +static int finaltarget(Instruction *code, int i) +{ + while (code[i].i.code == IJmp) i = target(code, i); + return i; } - /* ** final label (after traversing any jumps) */ -static int finallabel (Instruction *code, int i) { - return finaltarget(code, target(code, i)); -} - +static int finallabel(Instruction *code, int i) { return finaltarget(code, target(code, i)); } /* ** == behind n;

(where n = fixedlen(p)) */ -static void codebehind (CompileState *compst, TTree *tree) { - if (tree->u.n > 0) - addinstruction(compst, IBehind, tree->u.n); - codegen(compst, sib1(tree), 0, NOINST, fullset); +static void codebehind(CompileState *compst, TTree *tree) +{ + if (tree->u.n > 0) + addinstruction(compst, IBehind, tree->u.n); + codegen(compst, sib1(tree), 0, NOINST, fullset); } - /* ** Choice; optimizations: ** - when p1 is headfail or @@ -647,95 +793,99 @@ static void codebehind (CompileState *compst, TTree *tree) { ** - when p2 is empty and opt is true; a IPartialCommit can reuse ** the Choice already active in the stack. */ -static void codechoice (CompileState *compst, TTree *p1, TTree *p2, int opt, - const Charset *fl) { - int emptyp2 = (p2->tag == TTrue); - Charset cs1, cs2; - int e1 = getfirst(p1, fullset, &cs1); - if (headfail(p1) || - (!e1 && (getfirst(p2, fl, &cs2), cs_disjoint(&cs1, &cs2)))) { - /* == test (fail(p1)) -> L1 ; p1 ; jmp L2; L1: p2; L2: */ - int test = codetestset(compst, &cs1, 0); - int jmp = NOINST; - codegen(compst, p1, 0, test, fl); - if (!emptyp2) - jmp = addoffsetinst(compst, IJmp); - jumptohere(compst, test); - codegen(compst, p2, opt, NOINST, fl); - jumptohere(compst, jmp); - } - else if (opt && emptyp2) { - /* p1? == IPartialCommit; p1 */ - jumptohere(compst, addoffsetinst(compst, IPartialCommit)); - codegen(compst, p1, 1, NOINST, fullset); - } - else { - /* == - test(first(p1)) -> L1; choice L1; ; commit L2; L1: ; L2: */ - int pcommit; - int test = codetestset(compst, &cs1, e1); - int pchoice = addoffsetinst(compst, IChoice); - codegen(compst, p1, emptyp2, test, fullset); - pcommit = addoffsetinst(compst, ICommit); - jumptohere(compst, pchoice); - jumptohere(compst, test); - codegen(compst, p2, opt, NOINST, fl); - jumptohere(compst, pcommit); - } +static void codechoice(CompileState *compst, TTree *p1, TTree *p2, int opt, const Charset *fl) +{ + int emptyp2 = (p2->tag == TTrue); + Charset cs1, cs2; + int e1 = getfirst(p1, fullset, &cs1); + if (headfail(p1) || (!e1 && (getfirst(p2, fl, &cs2), cs_disjoint(&cs1, &cs2)))) + { + /* == test (fail(p1)) -> L1 ; p1 ; jmp L2; L1: p2; L2: */ + int test = codetestset(compst, &cs1, 0); + int jmp = NOINST; + codegen(compst, p1, 0, test, fl); + if (!emptyp2) + jmp = addoffsetinst(compst, IJmp); + jumptohere(compst, test); + codegen(compst, p2, opt, NOINST, fl); + jumptohere(compst, jmp); + } + else if (opt && emptyp2) + { + /* p1? == IPartialCommit; p1 */ + jumptohere(compst, addoffsetinst(compst, IPartialCommit)); + codegen(compst, p1, 1, NOINST, fullset); + } + else + { + /* == + test(first(p1)) -> L1; choice L1; ; commit L2; L1: ; L2: */ + int pcommit; + int test = codetestset(compst, &cs1, e1); + int pchoice = addoffsetinst(compst, IChoice); + codegen(compst, p1, emptyp2, test, fullset); + pcommit = addoffsetinst(compst, ICommit); + jumptohere(compst, pchoice); + jumptohere(compst, test); + codegen(compst, p2, opt, NOINST, fl); + jumptohere(compst, pcommit); + } } - /* ** And predicate ** optimization: fixedlen(p) = n ==> <&p> ==

; behind n ** (valid only when 'p' has no captures) */ -static void codeand (CompileState *compst, TTree *tree, int tt) { - int n = fixedlen(tree); - if (n >= 0 && n <= MAXBEHIND && !hascaptures(tree)) { - codegen(compst, tree, 0, tt, fullset); - if (n > 0) - addinstruction(compst, IBehind, n); - } - else { /* default: Choice L1; p1; BackCommit L2; L1: Fail; L2: */ - int pcommit; - int pchoice = addoffsetinst(compst, IChoice); - codegen(compst, tree, 0, tt, fullset); - pcommit = addoffsetinst(compst, IBackCommit); - jumptohere(compst, pchoice); - addinstruction(compst, IFail, 0); - jumptohere(compst, pcommit); - } +static void codeand(CompileState *compst, TTree *tree, int tt) +{ + int n = fixedlen(tree); + if (n >= 0 && n <= MAXBEHIND && !hascaptures(tree)) + { + codegen(compst, tree, 0, tt, fullset); + if (n > 0) + addinstruction(compst, IBehind, n); + } + else + { /* default: Choice L1; p1; BackCommit L2; L1: Fail; L2: */ + int pcommit; + int pchoice = addoffsetinst(compst, IChoice); + codegen(compst, tree, 0, tt, fullset); + pcommit = addoffsetinst(compst, IBackCommit); + jumptohere(compst, pchoice); + addinstruction(compst, IFail, 0); + jumptohere(compst, pcommit); + } } - /* ** Captures: if pattern has fixed (and not too big) length, use ** a single IFullCapture instruction after the match; otherwise, ** enclose the pattern with OpenCapture - CloseCapture. */ -static void codecapture (CompileState *compst, TTree *tree, int tt, - const Charset *fl) { - int len = fixedlen(sib1(tree)); - if (len >= 0 && len <= MAXOFF && !hascaptures(sib1(tree))) { - codegen(compst, sib1(tree), 0, tt, fl); - addinstcap(compst, IFullCapture, tree->cap, tree->key, len); - } - else { - addinstcap(compst, IOpenCapture, tree->cap, tree->key, 0); - codegen(compst, sib1(tree), 0, tt, fl); - addinstcap(compst, ICloseCapture, Cclose, 0, 0); - } +static void codecapture(CompileState *compst, TTree *tree, int tt, const Charset *fl) +{ + int len = fixedlen(sib1(tree)); + if (len >= 0 && len <= MAXOFF && !hascaptures(sib1(tree))) + { + codegen(compst, sib1(tree), 0, tt, fl); + addinstcap(compst, IFullCapture, tree->cap, tree->key, len); + } + else + { + addinstcap(compst, IOpenCapture, tree->cap, tree->key, 0); + codegen(compst, sib1(tree), 0, tt, fl); + addinstcap(compst, ICloseCapture, Cclose, 0, 0); + } } - -static void coderuntime (CompileState *compst, TTree *tree, int tt) { - addinstcap(compst, IOpenCapture, Cgroup, tree->key, 0); - codegen(compst, sib1(tree), 0, tt, fullset); - addinstcap(compst, ICloseRunTime, Cclose, 0, 0); +static void coderuntime(CompileState *compst, TTree *tree, int tt) +{ + addinstcap(compst, IOpenCapture, Cgroup, tree->key, 0); + codegen(compst, sib1(tree), 0, tt, fullset); + addinstcap(compst, ICloseRunTime, Cclose, 0, 0); } - /* ** Repetion; optimizations: ** When pattern is a charset, can use special instruction ISpan. @@ -746,45 +896,49 @@ static void coderuntime (CompileState *compst, TTree *tree, int tt) { ** When 'opt' is true, the repetion can reuse the Choice already ** active in the stack. */ -static void coderep (CompileState *compst, TTree *tree, int opt, - const Charset *fl) { - Charset st; - if (tocharset(tree, &st)) { - addinstruction(compst, ISpan, 0); - addcharset(compst, st.cs); - } - else { - int e1 = getfirst(tree, fullset, &st); - if (headfail(tree) || (!e1 && cs_disjoint(&st, fl))) { - /* L1: test (fail(p1)) -> L2;

; jmp L1; L2: */ - int jmp; - int test = codetestset(compst, &st, 0); - codegen(compst, tree, 0, test, fullset); - jmp = addoffsetinst(compst, IJmp); - jumptohere(compst, test); - jumptothere(compst, jmp, test); +static void coderep(CompileState *compst, TTree *tree, int opt, const Charset *fl) +{ + Charset st; + if (tocharset(tree, &st)) + { + addinstruction(compst, ISpan, 0); + addcharset(compst, st.cs); } - else { - /* test(fail(p1)) -> L2; choice L2; L1:

; partialcommit L1; L2: */ - /* or (if 'opt'): partialcommit L1; L1:

; partialcommit L1; */ - int commit, l2; - int test = codetestset(compst, &st, e1); - int pchoice = NOINST; - if (opt) - jumptohere(compst, addoffsetinst(compst, IPartialCommit)); - else - pchoice = addoffsetinst(compst, IChoice); - l2 = gethere(compst); - codegen(compst, tree, 0, NOINST, fullset); - commit = addoffsetinst(compst, IPartialCommit); - jumptothere(compst, commit, l2); - jumptohere(compst, pchoice); - jumptohere(compst, test); + else + { + int e1 = getfirst(tree, fullset, &st); + if (headfail(tree) || (!e1 && cs_disjoint(&st, fl))) + { + /* L1: test (fail(p1)) -> L2;

; jmp L1; L2: */ + int jmp; + int test = codetestset(compst, &st, 0); + codegen(compst, tree, 0, test, fullset); + jmp = addoffsetinst(compst, IJmp); + jumptohere(compst, test); + jumptothere(compst, jmp, test); + } + else + { + /* test(fail(p1)) -> L2; choice L2; L1:

; partialcommit L1; L2: + */ + /* or (if 'opt'): partialcommit L1; L1:

; partialcommit L1; */ + int commit, l2; + int test = codetestset(compst, &st, e1); + int pchoice = NOINST; + if (opt) + jumptohere(compst, addoffsetinst(compst, IPartialCommit)); + else + pchoice = addoffsetinst(compst, IChoice); + l2 = gethere(compst); + codegen(compst, tree, 0, NOINST, fullset); + commit = addoffsetinst(compst, IPartialCommit); + jumptothere(compst, commit, l2); + jumptohere(compst, pchoice); + jumptohere(compst, test); + } } - } } - /* ** Not predicate; optimizations: ** In any case, if first test fails, 'not' succeeds, so it can jump to @@ -792,130 +946,164 @@ static void coderep (CompileState *compst, TTree *tree, int opt, ** in other parts); this case includes 'not' of simple sets. Otherwise, ** use the default code (a choice plus a failtwice). */ -static void codenot (CompileState *compst, TTree *tree) { - Charset st; - int e = getfirst(tree, fullset, &st); - int test = codetestset(compst, &st, e); - if (headfail(tree)) /* test (fail(p1)) -> L1; fail; L1: */ - addinstruction(compst, IFail, 0); - else { - /* test(fail(p))-> L1; choice L1;

; failtwice; L1: */ - int pchoice = addoffsetinst(compst, IChoice); - codegen(compst, tree, 0, NOINST, fullset); - addinstruction(compst, IFailTwice, 0); - jumptohere(compst, pchoice); - } - jumptohere(compst, test); +static void codenot(CompileState *compst, TTree *tree) +{ + Charset st; + int e = getfirst(tree, fullset, &st); + int test = codetestset(compst, &st, e); + if (headfail(tree)) /* test (fail(p1)) -> L1; fail; L1: */ + addinstruction(compst, IFail, 0); + else + { + /* test(fail(p))-> L1; choice L1;

; failtwice; L1: */ + int pchoice = addoffsetinst(compst, IChoice); + codegen(compst, tree, 0, NOINST, fullset); + addinstruction(compst, IFailTwice, 0); + jumptohere(compst, pchoice); + } + jumptohere(compst, test); } - /* ** change open calls to calls, using list 'positions' to find ** correct offsets; also optimize tail calls */ -static void correctcalls (CompileState *compst, int *positions, - int from, int to) { - int i; - Instruction *code = compst->p->code; - for (i = from; i < to; i += sizei(&code[i])) { - if (code[i].i.code == IOpenCall) { - int n = code[i].i.key; /* rule number */ - int rule = positions[n]; /* rule position */ - assert(rule == from || code[rule - 1].i.code == IRet); - if (code[finaltarget(code, i + 2)].i.code == IRet) /* call; ret ? */ - code[i].i.code = IJmp; /* tail call */ - else - code[i].i.code = ICall; - jumptothere(compst, i, rule); /* call jumps to respective rule */ +static void correctcalls(CompileState *compst, int *positions, int from, int to) +{ + int i; + Instruction *code = compst->p->code; + for (i = from; i < to; i += sizei(&code[i])) + { + if (code[i].i.code == IOpenCall) + { + int n = code[i].i.key; /* rule number */ + int rule = positions[n]; /* rule position */ + assert(rule == from || code[rule - 1].i.code == IRet); + if (code[finaltarget(code, i + 2)].i.code == IRet) /* call; ret ? */ + code[i].i.code = IJmp; /* tail call */ + else + code[i].i.code = ICall; + jumptothere(compst, i, rule); /* call jumps to respective rule */ + } } - } - assert(i == to); + assert(i == to); } - /* ** Code for a grammar: ** call L1; jmp L2; L1: rule 1; ret; rule 2; ret; ...; L2: */ -static void codegrammar (CompileState *compst, TTree *grammar) { - int positions[MAXRULES]; - int rulenumber = 0; - TTree *rule; - int firstcall = addoffsetinst(compst, ICall); /* call initial rule */ - int jumptoend = addoffsetinst(compst, IJmp); /* jump to the end */ - int start = gethere(compst); /* here starts the initial rule */ - jumptohere(compst, firstcall); - for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) { - positions[rulenumber++] = gethere(compst); /* save rule position */ - codegen(compst, sib1(rule), 0, NOINST, fullset); /* code rule */ - addinstruction(compst, IRet, 0); - } - assert(rule->tag == TTrue); - jumptohere(compst, jumptoend); - correctcalls(compst, positions, start, gethere(compst)); +static void codegrammar(CompileState *compst, TTree *grammar) +{ + int positions[MAXRULES]; + int rulenumber = 0; + TTree *rule; + int firstcall = addoffsetinst(compst, ICall); /* call initial rule */ + int jumptoend = addoffsetinst(compst, IJmp); /* jump to the end */ + int start = gethere(compst); /* here starts the initial rule */ + jumptohere(compst, firstcall); + for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) + { + positions[rulenumber++] = gethere(compst); /* save rule position */ + codegen(compst, sib1(rule), 0, NOINST, fullset); /* code rule */ + addinstruction(compst, IRet, 0); + } + assert(rule->tag == TTrue); + jumptohere(compst, jumptoend); + correctcalls(compst, positions, start, gethere(compst)); } - -static void codecall (CompileState *compst, TTree *call) { - int c = addoffsetinst(compst, IOpenCall); /* to be corrected later */ - getinstr(compst, c).i.key = sib2(call)->cap; /* rule number */ - assert(sib2(call)->tag == TRule); +static void codecall(CompileState *compst, TTree *call) +{ + int c = addoffsetinst(compst, IOpenCall); /* to be corrected later */ + getinstr(compst, c).i.key = sib2(call)->cap; /* rule number */ + assert(sib2(call)->tag == TRule); } - /* ** Code first child of a sequence ** (second child is called in-place to allow tail call) ** Return 'tt' for second child */ -static int codeseq1 (CompileState *compst, TTree *p1, TTree *p2, - int tt, const Charset *fl) { - if (needfollow(p1)) { - Charset fl1; - getfirst(p2, fl, &fl1); /* p1 follow is p2 first */ - codegen(compst, p1, 0, tt, &fl1); - } - else /* use 'fullset' as follow */ - codegen(compst, p1, 0, tt, fullset); - if (fixedlen(p1) != 0) /* can 'p1' consume anything? */ - return NOINST; /* invalidate test */ - else return tt; /* else 'tt' still protects sib2 */ +static int codeseq1(CompileState *compst, TTree *p1, TTree *p2, int tt, const Charset *fl) +{ + if (needfollow(p1)) + { + Charset fl1; + getfirst(p2, fl, &fl1); /* p1 follow is p2 first */ + codegen(compst, p1, 0, tt, &fl1); + } + else /* use 'fullset' as follow */ + codegen(compst, p1, 0, tt, fullset); + if (fixedlen(p1) != 0) /* can 'p1' consume anything? */ + return NOINST; /* invalidate test */ + else + return tt; /* else 'tt' still protects sib2 */ } - /* ** Main code-generation function: dispatch to auxiliar functions ** according to kind of tree. ('needfollow' should return true ** only for consructions that use 'fl'.) */ -static void codegen (CompileState *compst, TTree *tree, int opt, int tt, - const Charset *fl) { - tailcall: - switch (tree->tag) { - case TChar: codechar(compst, tree->u.n, tt); break; - case TAny: addinstruction(compst, IAny, 0); break; - case TSet: codecharset(compst, treebuffer(tree), tt); break; - case TTrue: break; - case TFalse: addinstruction(compst, IFail, 0); break; - case TChoice: codechoice(compst, sib1(tree), sib2(tree), opt, fl); break; - case TRep: coderep(compst, sib1(tree), opt, fl); break; - case TBehind: codebehind(compst, tree); break; - case TNot: codenot(compst, sib1(tree)); break; - case TAnd: codeand(compst, sib1(tree), tt); break; - case TCapture: codecapture(compst, tree, tt, fl); break; - case TRunTime: coderuntime(compst, tree, tt); break; - case TGrammar: codegrammar(compst, tree); break; - case TCall: codecall(compst, tree); break; - case TSeq: { - tt = codeseq1(compst, sib1(tree), sib2(tree), tt, fl); /* code 'p1' */ - /* codegen(compst, p2, opt, tt, fl); */ - tree = sib2(tree); goto tailcall; +static void codegen(CompileState *compst, TTree *tree, int opt, int tt, const Charset *fl) +{ +tailcall: + switch (tree->tag) + { + case TChar: + codechar(compst, tree->u.n, tt); + break; + case TAny: + addinstruction(compst, IAny, 0); + break; + case TSet: + codecharset(compst, treebuffer(tree), tt); + break; + case TTrue: + break; + case TFalse: + addinstruction(compst, IFail, 0); + break; + case TChoice: + codechoice(compst, sib1(tree), sib2(tree), opt, fl); + break; + case TRep: + coderep(compst, sib1(tree), opt, fl); + break; + case TBehind: + codebehind(compst, tree); + break; + case TNot: + codenot(compst, sib1(tree)); + break; + case TAnd: + codeand(compst, sib1(tree), tt); + break; + case TCapture: + codecapture(compst, tree, tt, fl); + break; + case TRunTime: + coderuntime(compst, tree, tt); + break; + case TGrammar: + codegrammar(compst, tree); + break; + case TCall: + codecall(compst, tree); + break; + case TSeq: + { + tt = codeseq1(compst, sib1(tree), sib2(tree), tt, fl); /* code 'p1' */ + /* codegen(compst, p2, opt, tt, fl); */ + tree = sib2(tree); + goto tailcall; + } + default: + assert(0); } - default: assert(0); - } } - /* ** Optimize jumps and other jump-like instructions. ** * Update labels of instructions with labels to their final @@ -925,62 +1113,80 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt, ** instructions (e.g., jump to return becomes a return; jump ** to commit becomes a commit) */ -static void peephole (CompileState *compst) { - Instruction *code = compst->p->code; - int i; - for (i = 0; i < compst->ncode; i += sizei(&code[i])) { - redo: - switch (code[i].i.code) { - case IChoice: case ICall: case ICommit: case IPartialCommit: - case IBackCommit: case ITestChar: case ITestSet: - case ITestAny: { /* instructions with labels */ - jumptothere(compst, i, finallabel(code, i)); /* optimize label */ - break; - } - case IJmp: { - int ft = finaltarget(code, i); - switch (code[ft].i.code) { /* jumping to what? */ - case IRet: case IFail: case IFailTwice: - case IEnd: { /* instructions with unconditional implicit jumps */ - code[i] = code[ft]; /* jump becomes that instruction */ - code[i + 1].i.code = IAny; /* 'no-op' for target position */ - break; - } - case ICommit: case IPartialCommit: - case IBackCommit: { /* inst. with unconditional explicit jumps */ - int fft = finallabel(code, ft); - code[i] = code[ft]; /* jump becomes that instruction... */ - jumptothere(compst, i, fft); /* but must correct its offset */ - goto redo; /* reoptimize its label */ - } - default: { - jumptothere(compst, i, ft); /* optimize label */ - break; - } +static void peephole(CompileState *compst) +{ + Instruction *code = compst->p->code; + int i; + for (i = 0; i < compst->ncode; i += sizei(&code[i])) + { + redo: + switch (code[i].i.code) + { + case IChoice: + case ICall: + case ICommit: + case IPartialCommit: + case IBackCommit: + case ITestChar: + case ITestSet: + case ITestAny: + { /* instructions with labels */ + jumptothere(compst, i, finallabel(code, i)); /* optimize label */ + break; + } + case IJmp: + { + int ft = finaltarget(code, i); + switch (code[ft].i.code) + { /* jumping to what? */ + case IRet: + case IFail: + case IFailTwice: + case IEnd: + { /* instructions with unconditional implicit jumps */ + code[i] = code[ft]; /* jump becomes that instruction */ + code[i + 1].i.code = IAny; /* 'no-op' for target position */ + break; + } + case ICommit: + case IPartialCommit: + case IBackCommit: + { /* inst. with unconditional explicit jumps */ + int fft = finallabel(code, ft); + code[i] = code[ft]; /* jump becomes that instruction... */ + jumptothere(compst, i, fft); /* but must correct its offset */ + goto redo; /* reoptimize its label */ + } + default: + { + jumptothere(compst, i, ft); /* optimize label */ + break; + } + } + break; + } + default: + break; } - break; - } - default: break; } - } - assert(code[i - 1].i.code == IEnd); + assert(code[i - 1].i.code == IEnd); } - /* ** Compile a pattern */ -Instruction *compile (lua_State *L, Pattern *p) { - CompileState compst; - compst.p = p; compst.ncode = 0; compst.L = L; - realloccode(L, p, 2); /* minimum initial size */ - codegen(&compst, p->tree, 0, NOINST, fullset); - addinstruction(&compst, IEnd, 0); - realloccode(L, p, compst.ncode); /* set final size */ - peephole(&compst); - return p->code; +Instruction *compile(lua_State *L, Pattern *p) +{ + CompileState compst; + compst.p = p; + compst.ncode = 0; + compst.L = L; + realloccode(L, p, 2); /* minimum initial size */ + codegen(&compst, p->tree, 0, NOINST, fullset); + addinstruction(&compst, IEnd, 0); + realloccode(L, p, compst.ncode); /* set final size */ + peephole(&compst); + return p->code; } - /* }====================================================== */ - diff --git a/LuaNode_Esp32/LuaNode32/components/lpeg/lpprint.c b/LuaNode_Esp32/LuaNode32/components/lpeg/lpprint.c index 174d168..a58f107 100644 --- a/LuaNode_Esp32/LuaNode32/components/lpeg/lpprint.c +++ b/LuaNode_Esp32/LuaNode32/components/lpeg/lpprint.c @@ -3,15 +3,14 @@ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ +#include "lpprint.h" + #include #include #include - -#include "lptypes.h" -#include "lpprint.h" #include "lpcode.h" - +#include "lptypes.h" #if defined(LPEG_DEBUG) @@ -21,222 +20,236 @@ ** ======================================================= */ - -void printcharset (const byte *st) { - int i; - printf("["); - for (i = 0; i <= UCHAR_MAX; i++) { - int first = i; - while (testchar(st, i) && i <= UCHAR_MAX) i++; - if (i - 1 == first) /* unary range? */ - printf("(%02x)", first); - else if (i - 1 > first) /* non-empty range? */ - printf("(%02x-%02x)", first, i - 1); - } - printf("]"); -} - - -static void printcapkind (int kind) { - const char *const modes[] = { - "close", "position", "constant", "backref", - "argument", "simple", "table", "function", - "query", "string", "num", "substitution", "fold", - "runtime", "group"}; - printf("%s", modes[kind]); +void printcharset(const byte *st) +{ + int i; + printf("["); + for (i = 0; i <= UCHAR_MAX; i++) + { + int first = i; + while (testchar(st, i) && i <= UCHAR_MAX) i++; + if (i - 1 == first) /* unary range? */ + printf("(%02x)", first); + else if (i - 1 > first) /* non-empty range? */ + printf("(%02x-%02x)", first, i - 1); + } + printf("]"); } - -static void printjmp (const Instruction *op, const Instruction *p) { - printf("-> %d", (int)(p + (p + 1)->offset - op)); +static void printcapkind(int kind) +{ + const char *const modes[] = {"close", "position", "constant", "backref", "argument", + "simple", "table", "function", "query", "string", + "num", "substitution", "fold", "runtime", "group"}; + printf("%s", modes[kind]); } +static void printjmp(const Instruction *op, const Instruction *p) { printf("-> %d", (int)(p + (p + 1)->offset - op)); } -void printinst (const Instruction *op, const Instruction *p) { - const char *const names[] = { - "any", "char", "set", - "testany", "testchar", "testset", - "span", "behind", - "ret", "end", - "choice", "jmp", "call", "open_call", - "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup", - "fullcapture", "opencapture", "closecapture", "closeruntime" - }; - printf("%02ld: %s ", (long)(p - op), names[p->i.code]); - switch ((Opcode)p->i.code) { - case IChar: { - printf("'%c'", p->i.aux); - break; - } - case ITestChar: { - printf("'%c'", p->i.aux); printjmp(op, p); - break; - } - case IFullCapture: { - printcapkind(getkind(p)); - printf(" (size = %d) (idx = %d)", getoff(p), p->i.key); - break; - } - case IOpenCapture: { - printcapkind(getkind(p)); - printf(" (idx = %d)", p->i.key); - break; - } - case ISet: { - printcharset((p+1)->buff); - break; - } - case ITestSet: { - printcharset((p+2)->buff); printjmp(op, p); - break; - } - case ISpan: { - printcharset((p+1)->buff); - break; +void printinst(const Instruction *op, const Instruction *p) +{ + const char *const names[] = { + "any", "char", "set", "testany", "testchar", "testset", "span", "behind", + "ret", "end", "choice", "jmp", "call", "open_call", "commit", "partial_commit", + "back_commit", "failtwice", "fail", "giveup", "fullcapture", "opencapture", "closecapture", "closeruntime"}; + printf("%02ld: %s ", (long)(p - op), names[p->i.code]); + switch ((Opcode)p->i.code) + { + case IChar: + { + printf("'%c'", p->i.aux); + break; + } + case ITestChar: + { + printf("'%c'", p->i.aux); + printjmp(op, p); + break; + } + case IFullCapture: + { + printcapkind(getkind(p)); + printf(" (size = %d) (idx = %d)", getoff(p), p->i.key); + break; + } + case IOpenCapture: + { + printcapkind(getkind(p)); + printf(" (idx = %d)", p->i.key); + break; + } + case ISet: + { + printcharset((p + 1)->buff); + break; + } + case ITestSet: + { + printcharset((p + 2)->buff); + printjmp(op, p); + break; + } + case ISpan: + { + printcharset((p + 1)->buff); + break; + } + case IOpenCall: + { + printf("-> %d", (p + 1)->offset); + break; + } + case IBehind: + { + printf("%d", p->i.aux); + break; + } + case IJmp: + case ICall: + case ICommit: + case IChoice: + case IPartialCommit: + case IBackCommit: + case ITestAny: + { + printjmp(op, p); + break; + } + default: + break; } - case IOpenCall: { - printf("-> %d", (p + 1)->offset); - break; - } - case IBehind: { - printf("%d", p->i.aux); - break; - } - case IJmp: case ICall: case ICommit: case IChoice: - case IPartialCommit: case IBackCommit: case ITestAny: { - printjmp(op, p); - break; - } - default: break; - } - printf("\n"); + printf("\n"); } - -void printpatt (Instruction *p, int n) { - Instruction *op = p; - while (p < op + n) { - printinst(op, p); - p += sizei(p); - } +void printpatt(Instruction *p, int n) +{ + Instruction *op = p; + while (p < op + n) + { + printinst(op, p); + p += sizei(p); + } } - #if defined(LPEG_DEBUG) -static void printcap (Capture *cap) { - printcapkind(cap->kind); - printf(" (idx: %d - size: %d) -> %p\n", cap->idx, cap->siz, cap->s); +static void printcap(Capture *cap) +{ + printcapkind(cap->kind); + printf(" (idx: %d - size: %d) -> %p\n", cap->idx, cap->siz, cap->s); } - -void printcaplist (Capture *cap, Capture *limit) { - printf(">======\n"); - for (; cap->s && (limit == NULL || cap < limit); cap++) - printcap(cap); - printf("=======\n"); +void printcaplist(Capture *cap, Capture *limit) +{ + printf(">======\n"); + for (; cap->s && (limit == NULL || cap < limit); cap++) printcap(cap); + printf("=======\n"); } #endif /* }====================================================== */ - /* ** {====================================================== ** Printing trees (for debugging) ** ======================================================= */ -static const char *tagnames[] = { - "char", "set", "any", - "true", "false", - "rep", - "seq", "choice", - "not", "and", - "call", "opencall", "rule", "grammar", - "behind", - "capture", "run-time" -}; - - -void printtree (TTree *tree, int ident) { - int i; - for (i = 0; i < ident; i++) printf(" "); - printf("%s", tagnames[tree->tag]); - switch (tree->tag) { - case TChar: { - int c = tree->u.n; - if (isprint(c)) - printf(" '%c'\n", c); - else - printf(" (%02X)\n", c); - break; - } - case TSet: { - printcharset(treebuffer(tree)); - printf("\n"); - break; - } - case TOpenCall: case TCall: { - printf(" key: %d\n", tree->key); - break; - } - case TBehind: { - printf(" %d\n", tree->u.n); - printtree(sib1(tree), ident + 2); - break; - } - case TCapture: { - printf(" cap: %d key: %d n: %d\n", tree->cap, tree->key, tree->u.n); - printtree(sib1(tree), ident + 2); - break; - } - case TRule: { - printf(" n: %d key: %d\n", tree->cap, tree->key); - printtree(sib1(tree), ident + 2); - break; /* do not print next rule as a sibling */ - } - case TGrammar: { - TTree *rule = sib1(tree); - printf(" %d\n", tree->u.n); /* number of rules */ - for (i = 0; i < tree->u.n; i++) { - printtree(rule, ident + 2); - rule = sib2(rule); - } - assert(rule->tag == TTrue); /* sentinel */ - break; - } - default: { - int sibs = numsiblings[tree->tag]; - printf("\n"); - if (sibs >= 1) { - printtree(sib1(tree), ident + 2); - if (sibs >= 2) - printtree(sib2(tree), ident + 2); - } - break; +static const char *tagnames[] = {"char", "set", "any", "true", "false", "rep", "seq", "choice", "not", + "and", "call", "opencall", "rule", "grammar", "behind", "capture", "run-time"}; + +void printtree(TTree *tree, int ident) +{ + int i; + for (i = 0; i < ident; i++) printf(" "); + printf("%s", tagnames[tree->tag]); + switch (tree->tag) + { + case TChar: + { + int c = tree->u.n; + if (isprint(c)) + printf(" '%c'\n", c); + else + printf(" (%02X)\n", c); + break; + } + case TSet: + { + printcharset(treebuffer(tree)); + printf("\n"); + break; + } + case TOpenCall: + case TCall: + { + printf(" key: %d\n", tree->key); + break; + } + case TBehind: + { + printf(" %d\n", tree->u.n); + printtree(sib1(tree), ident + 2); + break; + } + case TCapture: + { + printf(" cap: %d key: %d n: %d\n", tree->cap, tree->key, tree->u.n); + printtree(sib1(tree), ident + 2); + break; + } + case TRule: + { + printf(" n: %d key: %d\n", tree->cap, tree->key); + printtree(sib1(tree), ident + 2); + break; /* do not print next rule as a sibling */ + } + case TGrammar: + { + TTree *rule = sib1(tree); + printf(" %d\n", tree->u.n); /* number of rules */ + for (i = 0; i < tree->u.n; i++) + { + printtree(rule, ident + 2); + rule = sib2(rule); + } + assert(rule->tag == TTrue); /* sentinel */ + break; + } + default: + { + int sibs = numsiblings[tree->tag]; + printf("\n"); + if (sibs >= 1) + { + printtree(sib1(tree), ident + 2); + if (sibs >= 2) + printtree(sib2(tree), ident + 2); + } + break; + } } - } } - -void printktable (lua_State *L, int idx) { - int n, i; - lua_getuservalue(L, idx); - if (lua_isnil(L, -1)) /* no ktable? */ - return; - n = lua_rawlen(L, -1); - printf("["); - for (i = 1; i <= n; i++) { - printf("%d = ", i); - lua_rawgeti(L, -1, i); - if (lua_isstring(L, -1)) - printf("%s ", lua_tostring(L, -1)); - else - printf("%s ", lua_typename(L, lua_type(L, -1))); - lua_pop(L, 1); - } - printf("]\n"); - /* leave ktable at the stack */ +void printktable(lua_State *L, int idx) +{ + int n, i; + lua_getuservalue(L, idx); + if (lua_isnil(L, -1)) /* no ktable? */ + return; + n = lua_rawlen(L, -1); + printf("["); + for (i = 1; i <= n; i++) + { + printf("%d = ", i); + lua_rawgeti(L, -1, i); + if (lua_isstring(L, -1)) + printf("%s ", lua_tostring(L, -1)); + else + printf("%s ", lua_typename(L, lua_type(L, -1))); + lua_pop(L, 1); + } + printf("]\n"); + /* leave ktable at the stack */ } /* }====================================================== */ diff --git a/LuaNode_Esp32/LuaNode32/components/lpeg/lptree.c b/LuaNode_Esp32/LuaNode32/components/lpeg/lptree.c index ad056ea..6fdc1b4 100644 --- a/LuaNode_Esp32/LuaNode32/components/lpeg/lptree.c +++ b/LuaNode_Esp32/LuaNode32/components/lpeg/lptree.c @@ -3,71 +3,68 @@ ** Copyright 2013, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ +#include "lptree.h" + #include #include #include - -#include "lua.h" #include "lauxlib.h" - -#include "lptypes.h" #include "lpcap.h" #include "lpcode.h" #include "lpprint.h" -#include "lptree.h" - +#include "lptypes.h" +#include "lua.h" /* number of siblings for each tree */ const byte numsiblings[] = { - 0, 0, 0, /* char, set, any */ - 0, 0, /* true, false */ - 1, /* rep */ - 2, 2, /* seq, choice */ - 1, 1, /* not, and */ - 0, 0, 2, 1, /* call, opencall, rule, grammar */ - 1, /* behind */ - 1, 1 /* capture, runtime capture */ + 0, 0, 0, /* char, set, any */ + 0, 0, /* true, false */ + 1, /* rep */ + 2, 2, /* seq, choice */ + 1, 1, /* not, and */ + 0, 0, 2, 1, /* call, opencall, rule, grammar */ + 1, /* behind */ + 1, 1 /* capture, runtime capture */ }; - -static TTree *newgrammar (lua_State *L, int arg); - +static TTree *newgrammar(lua_State *L, int arg); /* ** returns a reasonable name for value at index 'idx' on the stack */ -static const char *val2str (lua_State *L, int idx) { - const char *k = lua_tostring(L, idx); - if (k != NULL) - return lua_pushfstring(L, "%s", k); - else - return lua_pushfstring(L, "(a %s)", luaL_typename(L, idx)); +static const char *val2str(lua_State *L, int idx) +{ + const char *k = lua_tostring(L, idx); + if (k != NULL) + return lua_pushfstring(L, "%s", k); + else + return lua_pushfstring(L, "(a %s)", luaL_typename(L, idx)); } - /* ** Fix a TOpenCall into a TCall node, using table 'postable' to ** translate a key to its rule address in the tree. Raises an ** error if key does not exist. */ -static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { - int n; - lua_rawgeti(L, -1, t->key); /* get rule's name */ - lua_gettable(L, postable); /* query name in position table */ - n = lua_tonumber(L, -1); /* get (absolute) position */ - lua_pop(L, 1); /* remove position */ - if (n == 0) { /* no position? */ - lua_rawgeti(L, -1, t->key); /* get rule's name again */ - luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1)); - } - t->tag = TCall; - t->u.ps = n - (t - g); /* position relative to node */ - assert(sib2(t)->tag == TRule); - sib2(t)->key = t->key; +static void fixonecall(lua_State *L, int postable, TTree *g, TTree *t) +{ + int n; + lua_rawgeti(L, -1, t->key); /* get rule's name */ + lua_gettable(L, postable); /* query name in position table */ + n = lua_tonumber(L, -1); /* get (absolute) position */ + lua_pop(L, 1); /* remove position */ + if (n == 0) + { /* no position? */ + lua_rawgeti(L, -1, t->key); /* get rule's name again */ + luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1)); + } + t->tag = TCall; + t->u.ps = n - (t - g); /* position relative to node */ + assert(sib2(t)->tag == TRule); + sib2(t)->key = t->key; } - /* ** Transform left associative constructions into right ** associative ones, for sequence and choice; that is: @@ -75,21 +72,22 @@ static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { ** (t11 * t12) * t2 => t11 * (t12 * t2) ** (that is, Op (Op t11 t12) t2 => Op t11 (Op t12 t2)) */ -static void correctassociativity (TTree *tree) { - TTree *t1 = sib1(tree); - assert(tree->tag == TChoice || tree->tag == TSeq); - while (t1->tag == tree->tag) { - int n1size = tree->u.ps - 1; /* t1 == Op t11 t12 */ - int n11size = t1->u.ps - 1; - int n12size = n1size - n11size - 1; - memmove(sib1(tree), sib1(t1), n11size * sizeof(TTree)); /* move t11 */ - tree->u.ps = n11size + 1; - sib2(tree)->tag = tree->tag; - sib2(tree)->u.ps = n12size + 1; - } +static void correctassociativity(TTree *tree) +{ + TTree *t1 = sib1(tree); + assert(tree->tag == TChoice || tree->tag == TSeq); + while (t1->tag == tree->tag) + { + int n1size = tree->u.ps - 1; /* t1 == Op t11 t12 */ + int n11size = t1->u.ps - 1; + int n12size = n1size - n11size - 1; + memmove(sib1(tree), sib1(t1), n11size * sizeof(TTree)); /* move t11 */ + tree->u.ps = n11size + 1; + sib2(tree)->tag = tree->tag; + sib2(tree)->u.ps = n12size + 1; + } } - /* ** Make final adjustments in a tree. Fix open calls in tree 't', ** making them refer to their respective rules or raising appropriate @@ -97,36 +95,44 @@ static void correctassociativity (TTree *tree) { ** constructions (making them right associative). Assume that tree's ** ktable is at the top of the stack (for error messages). */ -static void finalfix (lua_State *L, int postable, TTree *g, TTree *t) { - tailcall: - switch (t->tag) { - case TGrammar: /* subgrammars were already fixed */ - return; - case TOpenCall: { - if (g != NULL) /* inside a grammar? */ - fixonecall(L, postable, g, t); - else { /* open call outside grammar */ - lua_rawgeti(L, -1, t->key); - luaL_error(L, "rule '%s' used outside a grammar", val2str(L, -1)); - } - break; +static void finalfix(lua_State *L, int postable, TTree *g, TTree *t) +{ +tailcall: + switch (t->tag) + { + case TGrammar: /* subgrammars were already fixed */ + return; + case TOpenCall: + { + if (g != NULL) /* inside a grammar? */ + fixonecall(L, postable, g, t); + else + { /* open call outside grammar */ + lua_rawgeti(L, -1, t->key); + luaL_error(L, "rule '%s' used outside a grammar", val2str(L, -1)); + } + break; + } + case TSeq: + case TChoice: + correctassociativity(t); + break; + } + switch (numsiblings[t->tag]) + { + case 1: /* finalfix(L, postable, g, sib1(t)); */ + t = sib1(t); + goto tailcall; + case 2: + finalfix(L, postable, g, sib1(t)); + t = sib2(t); + goto tailcall; /* finalfix(L, postable, g, sib2(t)); */ + default: + assert(numsiblings[t->tag] == 0); + break; } - case TSeq: case TChoice: - correctassociativity(t); - break; - } - switch (numsiblings[t->tag]) { - case 1: /* finalfix(L, postable, g, sib1(t)); */ - t = sib1(t); goto tailcall; - case 2: - finalfix(L, postable, g, sib1(t)); - t = sib2(t); goto tailcall; /* finalfix(L, postable, g, sib2(t)); */ - default: assert(numsiblings[t->tag] == 0); break; - } } - - /* ** {=================================================================== ** KTable manipulation @@ -144,171 +150,192 @@ static void finalfix (lua_State *L, int postable, TTree *g, TTree *t) { /* ** Create a new 'ktable' to the pattern at the top of the stack. */ -static void newktable (lua_State *L, int n) { - lua_createtable(L, n, 0); /* create a fresh table */ - lua_setuservalue(L, -2); /* set it as 'ktable' for pattern */ +static void newktable(lua_State *L, int n) +{ + lua_createtable(L, n, 0); /* create a fresh table */ + lua_setuservalue(L, -2); /* set it as 'ktable' for pattern */ } - /* ** Add element 'idx' to 'ktable' of pattern at the top of the stack; ** Return index of new element. ** If new element is nil, does not add it to table (as it would be ** useless) and returns 0, as ktable[0] is always nil. */ -static int addtoktable (lua_State *L, int idx) { - if (lua_isnil(L, idx)) /* nil value? */ - return 0; - else { - int n; - lua_getuservalue(L, -1); /* get ktable from pattern */ - n = lua_rawlen(L, -1); - if (n >= USHRT_MAX) - luaL_error(L, "too many Lua values in pattern"); - lua_pushvalue(L, idx); /* element to be added */ - lua_rawseti(L, -2, ++n); - lua_pop(L, 1); /* remove 'ktable' */ - return n; - } +static int addtoktable(lua_State *L, int idx) +{ + if (lua_isnil(L, idx)) /* nil value? */ + return 0; + else + { + int n; + lua_getuservalue(L, -1); /* get ktable from pattern */ + n = lua_rawlen(L, -1); + if (n >= USHRT_MAX) + luaL_error(L, "too many Lua values in pattern"); + lua_pushvalue(L, idx); /* element to be added */ + lua_rawseti(L, -2, ++n); + lua_pop(L, 1); /* remove 'ktable' */ + return n; + } } - /* ** Return the number of elements in the ktable at 'idx'. ** In Lua 5.2/5.3, default "environment" for patterns is nil, not ** a table. Treat it as an empty table. In Lua 5.1, assumes that ** the environment has no numeric indices (len == 0) */ -static int ktablelen (lua_State *L, int idx) { - if (!lua_istable(L, idx)) return 0; - else return lua_rawlen(L, idx); +static int ktablelen(lua_State *L, int idx) +{ + if (!lua_istable(L, idx)) + return 0; + else + return lua_rawlen(L, idx); } - /* ** Concatentate the contents of table 'idx1' into table 'idx2'. ** (Assume that both indices are negative.) ** Return the original length of table 'idx2' (or 0, if no ** element was added, as there is no need to correct any index). */ -static int concattable (lua_State *L, int idx1, int idx2) { - int i; - int n1 = ktablelen(L, idx1); - int n2 = ktablelen(L, idx2); - if (n1 + n2 > USHRT_MAX) - luaL_error(L, "too many Lua values in pattern"); - if (n1 == 0) return 0; /* nothing to correct */ - for (i = 1; i <= n1; i++) { - lua_rawgeti(L, idx1, i); - lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ - } - return n2; +static int concattable(lua_State *L, int idx1, int idx2) +{ + int i; + int n1 = ktablelen(L, idx1); + int n2 = ktablelen(L, idx2); + if (n1 + n2 > USHRT_MAX) + luaL_error(L, "too many Lua values in pattern"); + if (n1 == 0) + return 0; /* nothing to correct */ + for (i = 1; i <= n1; i++) + { + lua_rawgeti(L, idx1, i); + lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ + } + return n2; } - /* ** When joining 'ktables', constants from one of the subpatterns must ** be renumbered; 'correctkeys' corrects their indices (adding 'n' ** to each of them) */ -static void correctkeys (TTree *tree, int n) { - if (n == 0) return; /* no correction? */ - tailcall: - switch (tree->tag) { - case TOpenCall: case TCall: case TRunTime: case TRule: { - if (tree->key > 0) - tree->key += n; - break; +static void correctkeys(TTree *tree, int n) +{ + if (n == 0) + return; /* no correction? */ +tailcall: + switch (tree->tag) + { + case TOpenCall: + case TCall: + case TRunTime: + case TRule: + { + if (tree->key > 0) + tree->key += n; + break; + } + case TCapture: + { + if (tree->key > 0 && tree->cap != Carg && tree->cap != Cnum) + tree->key += n; + break; + } + default: + break; } - case TCapture: { - if (tree->key > 0 && tree->cap != Carg && tree->cap != Cnum) - tree->key += n; - break; + switch (numsiblings[tree->tag]) + { + case 1: /* correctkeys(sib1(tree), n); */ + tree = sib1(tree); + goto tailcall; + case 2: + correctkeys(sib1(tree), n); + tree = sib2(tree); + goto tailcall; /* correctkeys(sib2(tree), n); */ + default: + assert(numsiblings[tree->tag] == 0); + break; } - default: break; - } - switch (numsiblings[tree->tag]) { - case 1: /* correctkeys(sib1(tree), n); */ - tree = sib1(tree); goto tailcall; - case 2: - correctkeys(sib1(tree), n); - tree = sib2(tree); goto tailcall; /* correctkeys(sib2(tree), n); */ - default: assert(numsiblings[tree->tag] == 0); break; - } } - /* ** Join the ktables from p1 and p2 the ktable for the new pattern at the ** top of the stack, reusing them when possible. */ -static void joinktables (lua_State *L, int p1, TTree *t2, int p2) { - int n1, n2; - lua_getuservalue(L, p1); /* get ktables */ - lua_getuservalue(L, p2); - n1 = ktablelen(L, -2); - n2 = ktablelen(L, -1); - if (n1 == 0 && n2 == 0) /* are both tables empty? */ - lua_pop(L, 2); /* nothing to be done; pop tables */ - else if (n2 == 0 || lp_equal(L, -2, -1)) { /* 2nd table empty or equal? */ - lua_pop(L, 1); /* pop 2nd table */ - lua_setuservalue(L, -2); /* set 1st ktable into new pattern */ - } - else if (n1 == 0) { /* first table is empty? */ - lua_setuservalue(L, -3); /* set 2nd table into new pattern */ - lua_pop(L, 1); /* pop 1st table */ - } - else { - lua_createtable(L, n1 + n2, 0); /* create ktable for new pattern */ - /* stack: new p; ktable p1; ktable p2; new ktable */ - concattable(L, -3, -1); /* from p1 into new ktable */ - concattable(L, -2, -1); /* from p2 into new ktable */ - lua_setuservalue(L, -4); /* new ktable becomes 'p' environment */ - lua_pop(L, 2); /* pop other ktables */ - correctkeys(t2, n1); /* correction for indices from p2 */ - } +static void joinktables(lua_State *L, int p1, TTree *t2, int p2) +{ + int n1, n2; + lua_getuservalue(L, p1); /* get ktables */ + lua_getuservalue(L, p2); + n1 = ktablelen(L, -2); + n2 = ktablelen(L, -1); + if (n1 == 0 && n2 == 0) /* are both tables empty? */ + lua_pop(L, 2); /* nothing to be done; pop tables */ + else if (n2 == 0 || lp_equal(L, -2, -1)) + { /* 2nd table empty or equal? */ + lua_pop(L, 1); /* pop 2nd table */ + lua_setuservalue(L, -2); /* set 1st ktable into new pattern */ + } + else if (n1 == 0) + { /* first table is empty? */ + lua_setuservalue(L, -3); /* set 2nd table into new pattern */ + lua_pop(L, 1); /* pop 1st table */ + } + else + { + lua_createtable(L, n1 + n2, 0); /* create ktable for new pattern */ + /* stack: new p; ktable p1; ktable p2; new ktable */ + concattable(L, -3, -1); /* from p1 into new ktable */ + concattable(L, -2, -1); /* from p2 into new ktable */ + lua_setuservalue(L, -4); /* new ktable becomes 'p' environment */ + lua_pop(L, 2); /* pop other ktables */ + correctkeys(t2, n1); /* correction for indices from p2 */ + } } - /* ** copy 'ktable' of element 'idx' to new tree (on top of stack) */ -static void copyktable (lua_State *L, int idx) { - lua_getuservalue(L, idx); - lua_setuservalue(L, -2); +static void copyktable(lua_State *L, int idx) +{ + lua_getuservalue(L, idx); + lua_setuservalue(L, -2); } - /* ** merge 'ktable' from 'stree' at stack index 'idx' into 'ktable' ** from tree at the top of the stack, and correct corresponding ** tree. */ -static void mergektable (lua_State *L, int idx, TTree *stree) { - int n; - lua_getuservalue(L, -1); /* get ktables */ - lua_getuservalue(L, idx); - n = concattable(L, -1, -2); - lua_pop(L, 2); /* remove both ktables */ - correctkeys(stree, n); +static void mergektable(lua_State *L, int idx, TTree *stree) +{ + int n; + lua_getuservalue(L, -1); /* get ktables */ + lua_getuservalue(L, idx); + n = concattable(L, -1, -2); + lua_pop(L, 2); /* remove both ktables */ + correctkeys(stree, n); } - /* ** Create a new 'ktable' to the pattern at the top of the stack, adding ** all elements from pattern 'p' (if not 0) plus element 'idx' to it. ** Return index of new element. */ -static int addtonewktable (lua_State *L, int p, int idx) { - newktable(L, 1); - if (p) - mergektable(L, p, NULL); - return addtoktable(L, idx); +static int addtonewktable(lua_State *L, int p, int idx) +{ + newktable(L, 1); + if (p) + mergektable(L, p, NULL); + return addtoktable(L, idx); } /* }====================================================== */ - /* ** {====================================================== ** Tree generation @@ -318,546 +345,562 @@ static int addtonewktable (lua_State *L, int p, int idx) { /* ** In 5.2, could use 'luaL_testudata'... */ -static int testpattern (lua_State *L, int idx) { - if (lua_touserdata(L, idx)) { /* value is a userdata? */ - if (lua_getmetatable(L, idx)) { /* does it have a metatable? */ - luaL_getmetatable(L, PATTERN_T); - if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ - lua_pop(L, 2); /* remove both metatables */ - return 1; - } +static int testpattern(lua_State *L, int idx) +{ + if (lua_touserdata(L, idx)) + { /* value is a userdata? */ + if (lua_getmetatable(L, idx)) + { /* does it have a metatable? */ + luaL_getmetatable(L, PATTERN_T); + if (lua_rawequal(L, -1, -2)) + { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return 1; + } + } } - } - return 0; -} - - -static Pattern *getpattern (lua_State *L, int idx) { - return (Pattern *)luaL_checkudata(L, idx, PATTERN_T); + return 0; } +static Pattern *getpattern(lua_State *L, int idx) { return (Pattern *)luaL_checkudata(L, idx, PATTERN_T); } -static int getsize (lua_State *L, int idx) { - return (lua_rawlen(L, idx) - sizeof(Pattern)) / sizeof(TTree) + 1; -} - +static int getsize(lua_State *L, int idx) { return (lua_rawlen(L, idx) - sizeof(Pattern)) / sizeof(TTree) + 1; } -static TTree *gettree (lua_State *L, int idx, int *len) { - Pattern *p = getpattern(L, idx); - if (len) - *len = getsize(L, idx); - return p->tree; +static TTree *gettree(lua_State *L, int idx, int *len) +{ + Pattern *p = getpattern(L, idx); + if (len) + *len = getsize(L, idx); + return p->tree; } - /* ** create a pattern. Set its uservalue (the 'ktable') equal to its ** metatable. (It could be any empty sequence; the metatable is at ** hand here, so we use it.) */ -static TTree *newtree (lua_State *L, int len) { - size_t size = (len - 1) * sizeof(TTree) + sizeof(Pattern); - Pattern *p = (Pattern *)lua_newuserdata(L, size); - luaL_getmetatable(L, PATTERN_T); - lua_pushvalue(L, -1); - lua_setuservalue(L, -3); - lua_setmetatable(L, -2); - p->code = NULL; p->codesize = 0; - return p->tree; -} - - -static TTree *newleaf (lua_State *L, int tag) { - TTree *tree = newtree(L, 1); - tree->tag = tag; - return tree; +static TTree *newtree(lua_State *L, int len) +{ + size_t size = (len - 1) * sizeof(TTree) + sizeof(Pattern); + Pattern *p = (Pattern *)lua_newuserdata(L, size); + luaL_getmetatable(L, PATTERN_T); + lua_pushvalue(L, -1); + lua_setuservalue(L, -3); + lua_setmetatable(L, -2); + p->code = NULL; + p->codesize = 0; + return p->tree; +} + +static TTree *newleaf(lua_State *L, int tag) +{ + TTree *tree = newtree(L, 1); + tree->tag = tag; + return tree; } - -static TTree *newcharset (lua_State *L) { - TTree *tree = newtree(L, bytes2slots(CHARSETSIZE) + 1); - tree->tag = TSet; - loopset(i, treebuffer(tree)[i] = 0); - return tree; +static TTree *newcharset(lua_State *L) +{ + TTree *tree = newtree(L, bytes2slots(CHARSETSIZE) + 1); + tree->tag = TSet; + loopset(i, treebuffer(tree)[i] = 0); + return tree; } - /* ** add to tree a sequence where first sibling is 'sib' (with size ** 'sibsize'); returns position for second sibling */ -static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) { - tree->tag = TSeq; tree->u.ps = sibsize + 1; - memcpy(sib1(tree), sib, sibsize * sizeof(TTree)); - return sib2(tree); +static TTree *seqaux(TTree *tree, TTree *sib, int sibsize) +{ + tree->tag = TSeq; + tree->u.ps = sibsize + 1; + memcpy(sib1(tree), sib, sibsize * sizeof(TTree)); + return sib2(tree); } - /* ** Build a sequence of 'n' nodes, each with tag 'tag' and 'u.n' got ** from the array 's' (or 0 if array is NULL). (TSeq is binary, so it ** must build a sequence of sequence of sequence...) */ -static void fillseq (TTree *tree, int tag, int n, const char *s) { - int i; - for (i = 0; i < n - 1; i++) { /* initial n-1 copies of Seq tag; Seq ... */ - tree->tag = TSeq; tree->u.ps = 2; - sib1(tree)->tag = tag; - sib1(tree)->u.n = s ? (byte)s[i] : 0; - tree = sib2(tree); - } - tree->tag = tag; /* last one does not need TSeq */ - tree->u.n = s ? (byte)s[i] : 0; +static void fillseq(TTree *tree, int tag, int n, const char *s) +{ + int i; + for (i = 0; i < n - 1; i++) + { /* initial n-1 copies of Seq tag; Seq ... */ + tree->tag = TSeq; + tree->u.ps = 2; + sib1(tree)->tag = tag; + sib1(tree)->u.n = s ? (byte)s[i] : 0; + tree = sib2(tree); + } + tree->tag = tag; /* last one does not need TSeq */ + tree->u.n = s ? (byte)s[i] : 0; } - /* ** Numbers as patterns: ** 0 == true (always match); n == TAny repeated 'n' times; ** -n == not (TAny repeated 'n' times) */ -static TTree *numtree (lua_State *L, int n) { - if (n == 0) - return newleaf(L, TTrue); - else { - TTree *tree, *nd; - if (n > 0) - tree = nd = newtree(L, 2 * n - 1); - else { /* negative: code it as !(-n) */ - n = -n; - tree = newtree(L, 2 * n); - tree->tag = TNot; - nd = sib1(tree); +static TTree *numtree(lua_State *L, int n) +{ + if (n == 0) + return newleaf(L, TTrue); + else + { + TTree *tree, *nd; + if (n > 0) + tree = nd = newtree(L, 2 * n - 1); + else + { /* negative: code it as !(-n) */ + n = -n; + tree = newtree(L, 2 * n); + tree->tag = TNot; + nd = sib1(tree); + } + fillseq(nd, TAny, n, NULL); /* sequence of 'n' any's */ + return tree; } - fillseq(nd, TAny, n, NULL); /* sequence of 'n' any's */ - return tree; - } } - /* ** Convert value at index 'idx' to a pattern */ -static TTree *getpatt (lua_State *L, int idx, int *len) { - TTree *tree; - switch (lua_type(L, idx)) { - case LUA_TSTRING: { - size_t slen; - const char *s = lua_tolstring(L, idx, &slen); /* get string */ - if (slen == 0) /* empty? */ - tree = newleaf(L, TTrue); /* always match */ - else { - tree = newtree(L, 2 * (slen - 1) + 1); - fillseq(tree, TChar, slen, s); /* sequence of 'slen' chars */ - } - break; - } - case LUA_TNUMBER: { - int n = lua_tointeger(L, idx); - tree = numtree(L, n); - break; - } - case LUA_TBOOLEAN: { - tree = (lua_toboolean(L, idx) ? newleaf(L, TTrue) : newleaf(L, TFalse)); - break; - } - case LUA_TTABLE: { - tree = newgrammar(L, idx); - break; - } - case LUA_TFUNCTION: { - tree = newtree(L, 2); - tree->tag = TRunTime; - tree->key = addtonewktable(L, 0, idx); - sib1(tree)->tag = TTrue; - break; - } - default: { - return gettree(L, idx, len); +static TTree *getpatt(lua_State *L, int idx, int *len) +{ + TTree *tree; + switch (lua_type(L, idx)) + { + case LUA_TSTRING: + { + size_t slen; + const char *s = lua_tolstring(L, idx, &slen); /* get string */ + if (slen == 0) /* empty? */ + tree = newleaf(L, TTrue); /* always match */ + else + { + tree = newtree(L, 2 * (slen - 1) + 1); + fillseq(tree, TChar, slen, s); /* sequence of 'slen' chars */ + } + break; + } + case LUA_TNUMBER: + { + int n = lua_tointeger(L, idx); + tree = numtree(L, n); + break; + } + case LUA_TBOOLEAN: + { + tree = (lua_toboolean(L, idx) ? newleaf(L, TTrue) : newleaf(L, TFalse)); + break; + } + case LUA_TTABLE: + { + tree = newgrammar(L, idx); + break; + } + case LUA_TFUNCTION: + { + tree = newtree(L, 2); + tree->tag = TRunTime; + tree->key = addtonewktable(L, 0, idx); + sib1(tree)->tag = TTrue; + break; + } + default: + { + return gettree(L, idx, len); + } } - } - lua_replace(L, idx); /* put new tree into 'idx' slot */ - if (len) - *len = getsize(L, idx); - return tree; + lua_replace(L, idx); /* put new tree into 'idx' slot */ + if (len) + *len = getsize(L, idx); + return tree; } - /* ** create a new tree, whith a new root and one sibling. ** Sibling must be on the Lua stack, at index 1. */ -static TTree *newroot1sib (lua_State *L, int tag) { - int s1; - TTree *tree1 = getpatt(L, 1, &s1); - TTree *tree = newtree(L, 1 + s1); /* create new tree */ - tree->tag = tag; - memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); - copyktable(L, 1); - return tree; +static TTree *newroot1sib(lua_State *L, int tag) +{ + int s1; + TTree *tree1 = getpatt(L, 1, &s1); + TTree *tree = newtree(L, 1 + s1); /* create new tree */ + tree->tag = tag; + memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); + copyktable(L, 1); + return tree; } - /* ** create a new tree, whith a new root and 2 siblings. ** Siblings must be on the Lua stack, first one at index 1. */ -static TTree *newroot2sib (lua_State *L, int tag) { - int s1, s2; - TTree *tree1 = getpatt(L, 1, &s1); - TTree *tree2 = getpatt(L, 2, &s2); - TTree *tree = newtree(L, 1 + s1 + s2); /* create new tree */ - tree->tag = tag; - tree->u.ps = 1 + s1; - memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); - memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); - joinktables(L, 1, sib2(tree), 2); - return tree; +static TTree *newroot2sib(lua_State *L, int tag) +{ + int s1, s2; + TTree *tree1 = getpatt(L, 1, &s1); + TTree *tree2 = getpatt(L, 2, &s2); + TTree *tree = newtree(L, 1 + s1 + s2); /* create new tree */ + tree->tag = tag; + tree->u.ps = 1 + s1; + memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); + memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); + joinktables(L, 1, sib2(tree), 2); + return tree; } - -static int lp_P (lua_State *L) { - luaL_checkany(L, 1); - getpatt(L, 1, NULL); - lua_settop(L, 1); - return 1; +static int lp_P(lua_State *L) +{ + luaL_checkany(L, 1); + getpatt(L, 1, NULL); + lua_settop(L, 1); + return 1; } - /* ** sequence operator; optimizations: ** false x => false, x true => x, true x => x ** (cannot do x . false => false because x may have runtime captures) */ -static int lp_seq (lua_State *L) { - TTree *tree1 = getpatt(L, 1, NULL); - TTree *tree2 = getpatt(L, 2, NULL); - if (tree1->tag == TFalse || tree2->tag == TTrue) - lua_pushvalue(L, 1); /* false . x == false, x . true = x */ - else if (tree1->tag == TTrue) - lua_pushvalue(L, 2); /* true . x = x */ - else - newroot2sib(L, TSeq); - return 1; +static int lp_seq(lua_State *L) +{ + TTree *tree1 = getpatt(L, 1, NULL); + TTree *tree2 = getpatt(L, 2, NULL); + if (tree1->tag == TFalse || tree2->tag == TTrue) + lua_pushvalue(L, 1); /* false . x == false, x . true = x */ + else if (tree1->tag == TTrue) + lua_pushvalue(L, 2); /* true . x = x */ + else + newroot2sib(L, TSeq); + return 1; } - /* ** choice operator; optimizations: ** charset / charset => charset ** true / x => true, x / false => x, false / x => x ** (x / true is not equivalent to true) */ -static int lp_choice (lua_State *L) { - Charset st1, st2; - TTree *t1 = getpatt(L, 1, NULL); - TTree *t2 = getpatt(L, 2, NULL); - if (tocharset(t1, &st1) && tocharset(t2, &st2)) { - TTree *t = newcharset(L); - loopset(i, treebuffer(t)[i] = st1.cs[i] | st2.cs[i]); - } - else if (nofail(t1) || t2->tag == TFalse) - lua_pushvalue(L, 1); /* true / x => true, x / false => x */ - else if (t1->tag == TFalse) - lua_pushvalue(L, 2); /* false / x => x */ - else - newroot2sib(L, TChoice); - return 1; +static int lp_choice(lua_State *L) +{ + Charset st1, st2; + TTree *t1 = getpatt(L, 1, NULL); + TTree *t2 = getpatt(L, 2, NULL); + if (tocharset(t1, &st1) && tocharset(t2, &st2)) + { + TTree *t = newcharset(L); + loopset(i, treebuffer(t)[i] = st1.cs[i] | st2.cs[i]); + } + else if (nofail(t1) || t2->tag == TFalse) + lua_pushvalue(L, 1); /* true / x => true, x / false => x */ + else if (t1->tag == TFalse) + lua_pushvalue(L, 2); /* false / x => x */ + else + newroot2sib(L, TChoice); + return 1; } - /* ** p^n */ -static int lp_star (lua_State *L) { - int size1; - int n = (int)luaL_checkinteger(L, 2); - TTree *tree1 = getpatt(L, 1, &size1); - if (n >= 0) { /* seq tree1 (seq tree1 ... (seq tree1 (rep tree1))) */ - TTree *tree = newtree(L, (n + 1) * (size1 + 1)); - if (nullable(tree1)) - luaL_error(L, "loop body may accept empty string"); - while (n--) /* repeat 'n' times */ - tree = seqaux(tree, tree1, size1); - tree->tag = TRep; - memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); - } - else { /* choice (seq tree1 ... choice tree1 true ...) true */ - TTree *tree; - n = -n; - /* size = (choice + seq + tree1 + true) * n, but the last has no seq */ - tree = newtree(L, n * (size1 + 3) - 1); - for (; n > 1; n--) { /* repeat (n - 1) times */ - tree->tag = TChoice; tree->u.ps = n * (size1 + 3) - 2; - sib2(tree)->tag = TTrue; - tree = sib1(tree); - tree = seqaux(tree, tree1, size1); +static int lp_star(lua_State *L) +{ + int size1; + int n = (int)luaL_checkinteger(L, 2); + TTree *tree1 = getpatt(L, 1, &size1); + if (n >= 0) + { /* seq tree1 (seq tree1 ... (seq tree1 (rep tree1))) */ + TTree *tree = newtree(L, (n + 1) * (size1 + 1)); + if (nullable(tree1)) + luaL_error(L, "loop body may accept empty string"); + while (n--) /* repeat 'n' times */ + tree = seqaux(tree, tree1, size1); + tree->tag = TRep; + memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); + } + else + { /* choice (seq tree1 ... choice tree1 true ...) true */ + TTree *tree; + n = -n; + /* size = (choice + seq + tree1 + true) * n, but the last has no seq */ + tree = newtree(L, n * (size1 + 3) - 1); + for (; n > 1; n--) + { /* repeat (n - 1) times */ + tree->tag = TChoice; + tree->u.ps = n * (size1 + 3) - 2; + sib2(tree)->tag = TTrue; + tree = sib1(tree); + tree = seqaux(tree, tree1, size1); + } + tree->tag = TChoice; + tree->u.ps = size1 + 1; + sib2(tree)->tag = TTrue; + memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); } - tree->tag = TChoice; tree->u.ps = size1 + 1; - sib2(tree)->tag = TTrue; - memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); - } - copyktable(L, 1); - return 1; + copyktable(L, 1); + return 1; } - /* ** #p == &p */ -static int lp_and (lua_State *L) { - newroot1sib(L, TAnd); - return 1; +static int lp_and(lua_State *L) +{ + newroot1sib(L, TAnd); + return 1; } - /* ** -p == !p */ -static int lp_not (lua_State *L) { - newroot1sib(L, TNot); - return 1; +static int lp_not(lua_State *L) +{ + newroot1sib(L, TNot); + return 1; } - /* ** [t1 - t2] == Seq (Not t2) t1 ** If t1 and t2 are charsets, make their difference. */ -static int lp_sub (lua_State *L) { - Charset st1, st2; - int s1, s2; - TTree *t1 = getpatt(L, 1, &s1); - TTree *t2 = getpatt(L, 2, &s2); - if (tocharset(t1, &st1) && tocharset(t2, &st2)) { - TTree *t = newcharset(L); - loopset(i, treebuffer(t)[i] = st1.cs[i] & ~st2.cs[i]); - } - else { - TTree *tree = newtree(L, 2 + s1 + s2); - tree->tag = TSeq; /* sequence of... */ - tree->u.ps = 2 + s2; - sib1(tree)->tag = TNot; /* ...not... */ - memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ - memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ - joinktables(L, 1, sib1(tree), 2); - } - return 1; -} - - -static int lp_set (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - TTree *tree = newcharset(L); - while (l--) { - setchar(treebuffer(tree), (byte)(*s)); - s++; - } - return 1; -} - - -static int lp_range (lua_State *L) { - int arg; - int top = lua_gettop(L); - TTree *tree = newcharset(L); - for (arg = 1; arg <= top; arg++) { - int c; +static int lp_sub(lua_State *L) +{ + Charset st1, st2; + int s1, s2; + TTree *t1 = getpatt(L, 1, &s1); + TTree *t2 = getpatt(L, 2, &s2); + if (tocharset(t1, &st1) && tocharset(t2, &st2)) + { + TTree *t = newcharset(L); + loopset(i, treebuffer(t)[i] = st1.cs[i] & ~st2.cs[i]); + } + else + { + TTree *tree = newtree(L, 2 + s1 + s2); + tree->tag = TSeq; /* sequence of... */ + tree->u.ps = 2 + s2; + sib1(tree)->tag = TNot; /* ...not... */ + memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ + memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ + joinktables(L, 1, sib1(tree), 2); + } + return 1; +} + +static int lp_set(lua_State *L) +{ size_t l; - const char *r = luaL_checklstring(L, arg, &l); - luaL_argcheck(L, l == 2, arg, "range must have two characters"); - for (c = (byte)r[0]; c <= (byte)r[1]; c++) - setchar(treebuffer(tree), c); - } - return 1; + const char *s = luaL_checklstring(L, 1, &l); + TTree *tree = newcharset(L); + while (l--) + { + setchar(treebuffer(tree), (byte)(*s)); + s++; + } + return 1; } +static int lp_range(lua_State *L) +{ + int arg; + int top = lua_gettop(L); + TTree *tree = newcharset(L); + for (arg = 1; arg <= top; arg++) + { + int c; + size_t l; + const char *r = luaL_checklstring(L, arg, &l); + luaL_argcheck(L, l == 2, arg, "range must have two characters"); + for (c = (byte)r[0]; c <= (byte)r[1]; c++) setchar(treebuffer(tree), c); + } + return 1; +} /* ** Look-behind predicate */ -static int lp_behind (lua_State *L) { - TTree *tree; - TTree *tree1 = getpatt(L, 1, NULL); - int n = fixedlen(tree1); - luaL_argcheck(L, n >= 0, 1, "pattern may not have fixed length"); - luaL_argcheck(L, !hascaptures(tree1), 1, "pattern have captures"); - luaL_argcheck(L, n <= MAXBEHIND, 1, "pattern too long to look behind"); - tree = newroot1sib(L, TBehind); - tree->u.n = n; - return 1; +static int lp_behind(lua_State *L) +{ + TTree *tree; + TTree *tree1 = getpatt(L, 1, NULL); + int n = fixedlen(tree1); + luaL_argcheck(L, n >= 0, 1, "pattern may not have fixed length"); + luaL_argcheck(L, !hascaptures(tree1), 1, "pattern have captures"); + luaL_argcheck(L, n <= MAXBEHIND, 1, "pattern too long to look behind"); + tree = newroot1sib(L, TBehind); + tree->u.n = n; + return 1; } - /* ** Create a non-terminal */ -static int lp_V (lua_State *L) { - TTree *tree = newleaf(L, TOpenCall); - luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); - tree->key = addtonewktable(L, 0, 1); - return 1; +static int lp_V(lua_State *L) +{ + TTree *tree = newleaf(L, TOpenCall); + luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); + tree->key = addtonewktable(L, 0, 1); + return 1; } - /* ** Create a tree for a non-empty capture, with a body and ** optionally with an associated Lua value (at index 'labelidx' in the ** stack) */ -static int capture_aux (lua_State *L, int cap, int labelidx) { - TTree *tree = newroot1sib(L, TCapture); - tree->cap = cap; - tree->key = (labelidx == 0) ? 0 : addtonewktable(L, 1, labelidx); - return 1; +static int capture_aux(lua_State *L, int cap, int labelidx) +{ + TTree *tree = newroot1sib(L, TCapture); + tree->cap = cap; + tree->key = (labelidx == 0) ? 0 : addtonewktable(L, 1, labelidx); + return 1; } - /* ** Fill a tree with an empty capture, using an empty (TTrue) sibling. */ -static TTree *auxemptycap (TTree *tree, int cap) { - tree->tag = TCapture; - tree->cap = cap; - sib1(tree)->tag = TTrue; - return tree; +static TTree *auxemptycap(TTree *tree, int cap) +{ + tree->tag = TCapture; + tree->cap = cap; + sib1(tree)->tag = TTrue; + return tree; } - /* ** Create a tree for an empty capture */ -static TTree *newemptycap (lua_State *L, int cap) { - return auxemptycap(newtree(L, 2), cap); -} - +static TTree *newemptycap(lua_State *L, int cap) { return auxemptycap(newtree(L, 2), cap); } /* ** Create a tree for an empty capture with an associated Lua value */ -static TTree *newemptycapkey (lua_State *L, int cap, int idx) { - TTree *tree = auxemptycap(newtree(L, 2), cap); - tree->key = addtonewktable(L, 0, idx); - return tree; +static TTree *newemptycapkey(lua_State *L, int cap, int idx) +{ + TTree *tree = auxemptycap(newtree(L, 2), cap); + tree->key = addtonewktable(L, 0, idx); + return tree; } - /* ** Captures with syntax p / v ** (function capture, query capture, string capture, or number capture) */ -static int lp_divcapture (lua_State *L) { - switch (lua_type(L, 2)) { - case LUA_TFUNCTION: return capture_aux(L, Cfunction, 2); - case LUA_TTABLE: return capture_aux(L, Cquery, 2); - case LUA_TSTRING: return capture_aux(L, Cstring, 2); - case LUA_TNUMBER: { - int n = lua_tointeger(L, 2); - TTree *tree = newroot1sib(L, TCapture); - luaL_argcheck(L, 0 <= n && n <= SHRT_MAX, 1, "invalid number"); - tree->cap = Cnum; - tree->key = n; - return 1; +static int lp_divcapture(lua_State *L) +{ + switch (lua_type(L, 2)) + { + case LUA_TFUNCTION: + return capture_aux(L, Cfunction, 2); + case LUA_TTABLE: + return capture_aux(L, Cquery, 2); + case LUA_TSTRING: + return capture_aux(L, Cstring, 2); + case LUA_TNUMBER: + { + int n = lua_tointeger(L, 2); + TTree *tree = newroot1sib(L, TCapture); + luaL_argcheck(L, 0 <= n && n <= SHRT_MAX, 1, "invalid number"); + tree->cap = Cnum; + tree->key = n; + return 1; + } + default: + return luaL_argerror(L, 2, "invalid replacement value"); } - default: return luaL_argerror(L, 2, "invalid replacement value"); - } } +static int lp_substcapture(lua_State *L) { return capture_aux(L, Csubst, 0); } -static int lp_substcapture (lua_State *L) { - return capture_aux(L, Csubst, 0); -} - - -static int lp_tablecapture (lua_State *L) { - return capture_aux(L, Ctable, 0); -} - +static int lp_tablecapture(lua_State *L) { return capture_aux(L, Ctable, 0); } -static int lp_groupcapture (lua_State *L) { - if (lua_isnoneornil(L, 2)) - return capture_aux(L, Cgroup, 0); - else - return capture_aux(L, Cgroup, 2); -} - - -static int lp_foldcapture (lua_State *L) { - luaL_checktype(L, 2, LUA_TFUNCTION); - return capture_aux(L, Cfold, 2); +static int lp_groupcapture(lua_State *L) +{ + if (lua_isnoneornil(L, 2)) + return capture_aux(L, Cgroup, 0); + else + return capture_aux(L, Cgroup, 2); } - -static int lp_simplecapture (lua_State *L) { - return capture_aux(L, Csimple, 0); +static int lp_foldcapture(lua_State *L) +{ + luaL_checktype(L, 2, LUA_TFUNCTION); + return capture_aux(L, Cfold, 2); } +static int lp_simplecapture(lua_State *L) { return capture_aux(L, Csimple, 0); } -static int lp_poscapture (lua_State *L) { - newemptycap(L, Cposition); - return 1; +static int lp_poscapture(lua_State *L) +{ + newemptycap(L, Cposition); + return 1; } - -static int lp_argcapture (lua_State *L) { - int n = (int)luaL_checkinteger(L, 1); - TTree *tree = newemptycap(L, Carg); - tree->key = n; - luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, "invalid argument index"); - return 1; +static int lp_argcapture(lua_State *L) +{ + int n = (int)luaL_checkinteger(L, 1); + TTree *tree = newemptycap(L, Carg); + tree->key = n; + luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, "invalid argument index"); + return 1; } - -static int lp_backref (lua_State *L) { - luaL_checkany(L, 1); - newemptycapkey(L, Cbackref, 1); - return 1; +static int lp_backref(lua_State *L) +{ + luaL_checkany(L, 1); + newemptycapkey(L, Cbackref, 1); + return 1; } - /* ** Constant capture */ -static int lp_constcapture (lua_State *L) { - int i; - int n = lua_gettop(L); /* number of values */ - if (n == 0) /* no values? */ - newleaf(L, TTrue); /* no capture */ - else if (n == 1) - newemptycapkey(L, Cconst, 1); /* single constant capture */ - else { /* create a group capture with all values */ - TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); - newktable(L, n); /* create a 'ktable' for new tree */ - tree->tag = TCapture; - tree->cap = Cgroup; - tree->key = 0; - tree = sib1(tree); - for (i = 1; i <= n - 1; i++) { - tree->tag = TSeq; - tree->u.ps = 3; /* skip TCapture and its sibling */ - auxemptycap(sib1(tree), Cconst); - sib1(tree)->key = addtoktable(L, i); - tree = sib2(tree); +static int lp_constcapture(lua_State *L) +{ + int i; + int n = lua_gettop(L); /* number of values */ + if (n == 0) /* no values? */ + newleaf(L, TTrue); /* no capture */ + else if (n == 1) + newemptycapkey(L, Cconst, 1); /* single constant capture */ + else + { /* create a group capture with all values */ + TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); + newktable(L, n); /* create a 'ktable' for new tree */ + tree->tag = TCapture; + tree->cap = Cgroup; + tree->key = 0; + tree = sib1(tree); + for (i = 1; i <= n - 1; i++) + { + tree->tag = TSeq; + tree->u.ps = 3; /* skip TCapture and its sibling */ + auxemptycap(sib1(tree), Cconst); + sib1(tree)->key = addtoktable(L, i); + tree = sib2(tree); + } + auxemptycap(tree, Cconst); + tree->key = addtoktable(L, i); } - auxemptycap(tree, Cconst); - tree->key = addtoktable(L, i); - } - return 1; + return 1; } - -static int lp_matchtime (lua_State *L) { - TTree *tree; - luaL_checktype(L, 2, LUA_TFUNCTION); - tree = newroot1sib(L, TRunTime); - tree->key = addtonewktable(L, 1, 2); - return 1; +static int lp_matchtime(lua_State *L) +{ + TTree *tree; + luaL_checktype(L, 2, LUA_TFUNCTION); + tree = newroot1sib(L, TRunTime); + tree->key = addtonewktable(L, 1, 2); + return 1; } /* }====================================================== */ - /* ** {====================================================== ** Grammar - Tree generation @@ -869,25 +912,29 @@ static int lp_matchtime (lua_State *L) { ** initial rule of grammar at index 'arg' in the stack; ** also add that index into position table. */ -static void getfirstrule (lua_State *L, int arg, int postab) { - lua_rawgeti(L, arg, 1); /* access first element */ - if (lua_isstring(L, -1)) { /* is it the name of initial rule? */ - lua_pushvalue(L, -1); /* duplicate it to use as key */ - lua_gettable(L, arg); /* get associated rule */ - } - else { - lua_pushinteger(L, 1); /* key for initial rule */ - lua_insert(L, -2); /* put it before rule */ - } - if (!testpattern(L, -1)) { /* initial rule not a pattern? */ - if (lua_isnil(L, -1)) - luaL_error(L, "grammar has no initial rule"); +static void getfirstrule(lua_State *L, int arg, int postab) +{ + lua_rawgeti(L, arg, 1); /* access first element */ + if (lua_isstring(L, -1)) + { /* is it the name of initial rule? */ + lua_pushvalue(L, -1); /* duplicate it to use as key */ + lua_gettable(L, arg); /* get associated rule */ + } else - luaL_error(L, "initial rule '%s' is not a pattern", lua_tostring(L, -2)); - } - lua_pushvalue(L, -2); /* push key */ - lua_pushinteger(L, 1); /* push rule position (after TGrammar) */ - lua_settable(L, postab); /* insert pair at position table */ + { + lua_pushinteger(L, 1); /* key for initial rule */ + lua_insert(L, -2); /* put it before rule */ + } + if (!testpattern(L, -1)) + { /* initial rule not a pattern? */ + if (lua_isnil(L, -1)) + luaL_error(L, "grammar has no initial rule"); + else + luaL_error(L, "initial rule '%s' is not a pattern", lua_tostring(L, -2)); + } + lua_pushvalue(L, -2); /* push key */ + lua_pushinteger(L, 1); /* push rule position (after TGrammar) */ + lua_settable(L, postab); /* insert pair at position table */ } /* @@ -898,91 +945,103 @@ static void getfirstrule (lua_State *L, int arg, int postab) { ** Return the number of rules and (in 'totalsize') the total size ** for the new tree. */ -static int collectrules (lua_State *L, int arg, int *totalsize) { - int n = 1; /* to count number of rules */ - int postab = lua_gettop(L) + 1; /* index of position table */ - int size; /* accumulator for total size */ - lua_newtable(L); /* create position table */ - getfirstrule(L, arg, postab); - size = 2 + getsize(L, postab + 2); /* TGrammar + TRule + rule */ - lua_pushnil(L); /* prepare to traverse grammar table */ - while (lua_next(L, arg) != 0) { - if (lua_tonumber(L, -2) == 1 || - lp_equal(L, -2, postab + 1)) { /* initial rule? */ - lua_pop(L, 1); /* remove value (keep key for lua_next) */ - continue; +static int collectrules(lua_State *L, int arg, int *totalsize) +{ + int n = 1; /* to count number of rules */ + int postab = lua_gettop(L) + 1; /* index of position table */ + int size; /* accumulator for total size */ + lua_newtable(L); /* create position table */ + getfirstrule(L, arg, postab); + size = 2 + getsize(L, postab + 2); /* TGrammar + TRule + rule */ + lua_pushnil(L); /* prepare to traverse grammar table */ + while (lua_next(L, arg) != 0) + { + if (lua_tonumber(L, -2) == 1 || lp_equal(L, -2, postab + 1)) + { /* initial rule? */ + lua_pop(L, 1); /* remove value (keep key for lua_next) */ + continue; + } + if (!testpattern(L, -1)) /* value is not a pattern? */ + luaL_error(L, "rule '%s' is not a pattern", val2str(L, -2)); + luaL_checkstack(L, LUA_MINSTACK, "grammar has too many rules"); + lua_pushvalue(L, -2); /* push key (to insert into position table) */ + lua_pushinteger(L, size); + lua_settable(L, postab); + size += 1 + getsize(L, -1); /* update size */ + lua_pushvalue(L, -2); /* push key (for next lua_next) */ + n++; } - if (!testpattern(L, -1)) /* value is not a pattern? */ - luaL_error(L, "rule '%s' is not a pattern", val2str(L, -2)); - luaL_checkstack(L, LUA_MINSTACK, "grammar has too many rules"); - lua_pushvalue(L, -2); /* push key (to insert into position table) */ - lua_pushinteger(L, size); - lua_settable(L, postab); - size += 1 + getsize(L, -1); /* update size */ - lua_pushvalue(L, -2); /* push key (for next lua_next) */ - n++; - } - *totalsize = size + 1; /* TTrue to finish list of rules */ - return n; -} - - -static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) { - int i; - TTree *nd = sib1(grammar); /* auxiliary pointer to traverse the tree */ - for (i = 0; i < n; i++) { /* add each rule into new tree */ - int ridx = frule + 2*i + 1; /* index of i-th rule */ - int rulesize; - TTree *rn = gettree(L, ridx, &rulesize); - nd->tag = TRule; - nd->key = 0; - nd->cap = i; /* rule number */ - nd->u.ps = rulesize + 1; /* point to next rule */ - memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */ - mergektable(L, ridx, sib1(nd)); /* merge its ktable into new one */ - nd = sib2(nd); /* move to next rule */ - } - nd->tag = TTrue; /* finish list of rules */ + *totalsize = size + 1; /* TTrue to finish list of rules */ + return n; } +static void buildgrammar(lua_State *L, TTree *grammar, int frule, int n) +{ + int i; + TTree *nd = sib1(grammar); /* auxiliary pointer to traverse the tree */ + for (i = 0; i < n; i++) + { /* add each rule into new tree */ + int ridx = frule + 2 * i + 1; /* index of i-th rule */ + int rulesize; + TTree *rn = gettree(L, ridx, &rulesize); + nd->tag = TRule; + nd->key = 0; + nd->cap = i; /* rule number */ + nd->u.ps = rulesize + 1; /* point to next rule */ + memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */ + mergektable(L, ridx, sib1(nd)); /* merge its ktable into new one */ + nd = sib2(nd); /* move to next rule */ + } + nd->tag = TTrue; /* finish list of rules */ +} /* ** Check whether a tree has potential infinite loops */ -static int checkloops (TTree *tree) { - tailcall: - if (tree->tag == TRep && nullable(sib1(tree))) - return 1; - else if (tree->tag == TGrammar) - return 0; /* sub-grammars already checked */ - else { - switch (numsiblings[tree->tag]) { - case 1: /* return checkloops(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case 2: - if (checkloops(sib1(tree))) return 1; - /* else return checkloops(sib2(tree)); */ - tree = sib2(tree); goto tailcall; - default: assert(numsiblings[tree->tag] == 0); return 0; +static int checkloops(TTree *tree) +{ +tailcall: + if (tree->tag == TRep && nullable(sib1(tree))) + return 1; + else if (tree->tag == TGrammar) + return 0; /* sub-grammars already checked */ + else + { + switch (numsiblings[tree->tag]) + { + case 1: /* return checkloops(sib1(tree)); */ + tree = sib1(tree); + goto tailcall; + case 2: + if (checkloops(sib1(tree))) + return 1; + /* else return checkloops(sib2(tree)); */ + tree = sib2(tree); + goto tailcall; + default: + assert(numsiblings[tree->tag] == 0); + return 0; + } } - } } - -static int verifyerror (lua_State *L, int *passed, int npassed) { - int i, j; - for (i = npassed - 1; i >= 0; i--) { /* search for a repetition */ - for (j = i - 1; j >= 0; j--) { - if (passed[i] == passed[j]) { - lua_rawgeti(L, -1, passed[i]); /* get rule's key */ - return luaL_error(L, "rule '%s' may be left recursive", val2str(L, -1)); - } +static int verifyerror(lua_State *L, int *passed, int npassed) +{ + int i, j; + for (i = npassed - 1; i >= 0; i--) + { /* search for a repetition */ + for (j = i - 1; j >= 0; j--) + { + if (passed[i] == passed[j]) + { + lua_rawgeti(L, -1, passed[i]); /* get rule's key */ + return luaL_error(L, "rule '%s' may be left recursive", val2str(L, -1)); + } + } } - } - return luaL_error(L, "too many left calls in grammar"); + return luaL_error(L, "too many left calls in grammar"); } - /* ** Check whether a rule can be left recursive; raise an error in that ** case; otherwise return 1 iff pattern is nullable. @@ -992,182 +1051,209 @@ static int verifyerror (lua_State *L, int *passed, int npassed) { ** choices. ('nb' true makes function returns true.) ** Assume ktable at the top of the stack. */ -static int verifyrule (lua_State *L, TTree *tree, int *passed, int npassed, - int nb) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - case TFalse: - return nb; /* cannot pass from here */ - case TTrue: - case TBehind: /* look-behind cannot have calls */ - return 1; - case TNot: case TAnd: case TRep: - /* return verifyrule(L, sib1(tree), passed, npassed, 1); */ - tree = sib1(tree); nb = 1; goto tailcall; - case TCapture: case TRunTime: - /* return verifyrule(L, sib1(tree), passed, npassed, nb); */ - tree = sib1(tree); goto tailcall; - case TCall: - /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ - tree = sib2(tree); goto tailcall; - case TSeq: /* only check 2nd child if first is nb */ - if (!verifyrule(L, sib1(tree), passed, npassed, 0)) - return nb; - /* else return verifyrule(L, sib2(tree), passed, npassed, nb); */ - tree = sib2(tree); goto tailcall; - case TChoice: /* must check both children */ - nb = verifyrule(L, sib1(tree), passed, npassed, nb); - /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ - tree = sib2(tree); goto tailcall; - case TRule: - if (npassed >= MAXRULES) - return verifyerror(L, passed, npassed); - else { - passed[npassed++] = tree->key; - /* return verifyrule(L, sib1(tree), passed, npassed); */ - tree = sib1(tree); goto tailcall; - } - case TGrammar: - return nullable(tree); /* sub-grammar cannot be left recursive */ - default: assert(0); return 0; - } -} - - -static void verifygrammar (lua_State *L, TTree *grammar) { - int passed[MAXRULES]; - TTree *rule; - /* check left-recursive rules */ - for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) { - if (rule->key == 0) continue; /* unused rule */ - verifyrule(L, sib1(rule), passed, 0, 0); - } - assert(rule->tag == TTrue); - /* check infinite loops inside rules */ - for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) { - if (rule->key == 0) continue; /* unused rule */ - if (checkloops(sib1(rule))) { - lua_rawgeti(L, -1, rule->key); /* get rule's key */ - luaL_error(L, "empty loop in rule '%s'", val2str(L, -1)); +static int verifyrule(lua_State *L, TTree *tree, int *passed, int npassed, int nb) +{ +tailcall: + switch (tree->tag) + { + case TChar: + case TSet: + case TAny: + case TFalse: + return nb; /* cannot pass from here */ + case TTrue: + case TBehind: /* look-behind cannot have calls */ + return 1; + case TNot: + case TAnd: + case TRep: + /* return verifyrule(L, sib1(tree), passed, npassed, 1); */ + tree = sib1(tree); + nb = 1; + goto tailcall; + case TCapture: + case TRunTime: + /* return verifyrule(L, sib1(tree), passed, npassed, nb); */ + tree = sib1(tree); + goto tailcall; + case TCall: + /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ + tree = sib2(tree); + goto tailcall; + case TSeq: /* only check 2nd child if first is nb */ + if (!verifyrule(L, sib1(tree), passed, npassed, 0)) + return nb; + /* else return verifyrule(L, sib2(tree), passed, npassed, nb); */ + tree = sib2(tree); + goto tailcall; + case TChoice: /* must check both children */ + nb = verifyrule(L, sib1(tree), passed, npassed, nb); + /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ + tree = sib2(tree); + goto tailcall; + case TRule: + if (npassed >= MAXRULES) + return verifyerror(L, passed, npassed); + else + { + passed[npassed++] = tree->key; + /* return verifyrule(L, sib1(tree), passed, npassed); */ + tree = sib1(tree); + goto tailcall; + } + case TGrammar: + return nullable(tree); /* sub-grammar cannot be left recursive */ + default: + assert(0); + return 0; } - } - assert(rule->tag == TTrue); } +static void verifygrammar(lua_State *L, TTree *grammar) +{ + int passed[MAXRULES]; + TTree *rule; + /* check left-recursive rules */ + for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) + { + if (rule->key == 0) + continue; /* unused rule */ + verifyrule(L, sib1(rule), passed, 0, 0); + } + assert(rule->tag == TTrue); + /* check infinite loops inside rules */ + for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) + { + if (rule->key == 0) + continue; /* unused rule */ + if (checkloops(sib1(rule))) + { + lua_rawgeti(L, -1, rule->key); /* get rule's key */ + luaL_error(L, "empty loop in rule '%s'", val2str(L, -1)); + } + } + assert(rule->tag == TTrue); +} /* ** Give a name for the initial rule if it is not referenced */ -static void initialrulename (lua_State *L, TTree *grammar, int frule) { - if (sib1(grammar)->key == 0) { /* initial rule is not referenced? */ - int n = lua_rawlen(L, -1) + 1; /* index for name */ - lua_pushvalue(L, frule); /* rule's name */ - lua_rawseti(L, -2, n); /* ktable was on the top of the stack */ - sib1(grammar)->key = n; - } -} - - -static TTree *newgrammar (lua_State *L, int arg) { - int treesize; - int frule = lua_gettop(L) + 2; /* position of first rule's key */ - int n = collectrules(L, arg, &treesize); - TTree *g = newtree(L, treesize); - luaL_argcheck(L, n <= MAXRULES, arg, "grammar has too many rules"); - g->tag = TGrammar; g->u.n = n; - lua_newtable(L); /* create 'ktable' */ - lua_setuservalue(L, -2); - buildgrammar(L, g, frule, n); - lua_getuservalue(L, -1); /* get 'ktable' for new tree */ - finalfix(L, frule - 1, g, sib1(g)); - initialrulename(L, g, frule); - verifygrammar(L, g); - lua_pop(L, 1); /* remove 'ktable' */ - lua_insert(L, -(n * 2 + 2)); /* move new table to proper position */ - lua_pop(L, n * 2 + 1); /* remove position table + rule pairs */ - return g; /* new table at the top of the stack */ +static void initialrulename(lua_State *L, TTree *grammar, int frule) +{ + if (sib1(grammar)->key == 0) + { /* initial rule is not referenced? */ + int n = lua_rawlen(L, -1) + 1; /* index for name */ + lua_pushvalue(L, frule); /* rule's name */ + lua_rawseti(L, -2, n); /* ktable was on the top of the stack */ + sib1(grammar)->key = n; + } } -/* }====================================================== */ - - -static Instruction *prepcompile (lua_State *L, Pattern *p, int idx) { - lua_getuservalue(L, idx); /* push 'ktable' (may be used by 'finalfix') */ - finalfix(L, 0, NULL, p->tree); - lua_pop(L, 1); /* remove 'ktable' */ - return compile(L, p); +static TTree *newgrammar(lua_State *L, int arg) +{ + int treesize; + int frule = lua_gettop(L) + 2; /* position of first rule's key */ + int n = collectrules(L, arg, &treesize); + TTree *g = newtree(L, treesize); + luaL_argcheck(L, n <= MAXRULES, arg, "grammar has too many rules"); + g->tag = TGrammar; + g->u.n = n; + lua_newtable(L); /* create 'ktable' */ + lua_setuservalue(L, -2); + buildgrammar(L, g, frule, n); + lua_getuservalue(L, -1); /* get 'ktable' for new tree */ + finalfix(L, frule - 1, g, sib1(g)); + initialrulename(L, g, frule); + verifygrammar(L, g); + lua_pop(L, 1); /* remove 'ktable' */ + lua_insert(L, -(n * 2 + 2)); /* move new table to proper position */ + lua_pop(L, n * 2 + 1); /* remove position table + rule pairs */ + return g; /* new table at the top of the stack */ } +/* }====================================================== */ -static int lp_printtree (lua_State *L) { - TTree *tree = getpatt(L, 1, NULL); - int c = lua_toboolean(L, 2); - if (c) { - lua_getuservalue(L, 1); /* push 'ktable' (may be used by 'finalfix') */ - finalfix(L, 0, NULL, tree); - lua_pop(L, 1); /* remove 'ktable' */ - } - printktable(L, 1); - printtree(tree, 0); - return 0; +static Instruction *prepcompile(lua_State *L, Pattern *p, int idx) +{ + lua_getuservalue(L, idx); /* push 'ktable' (may be used by 'finalfix') */ + finalfix(L, 0, NULL, p->tree); + lua_pop(L, 1); /* remove 'ktable' */ + return compile(L, p); +} + +static int lp_printtree(lua_State *L) +{ + TTree *tree = getpatt(L, 1, NULL); + int c = lua_toboolean(L, 2); + if (c) + { + lua_getuservalue(L, 1); /* push 'ktable' (may be used by 'finalfix') */ + finalfix(L, 0, NULL, tree); + lua_pop(L, 1); /* remove 'ktable' */ + } + printktable(L, 1); + printtree(tree, 0); + return 0; } - -static int lp_printcode (lua_State *L) { - Pattern *p = getpattern(L, 1); - printktable(L, 1); - if (p->code == NULL) /* not compiled yet? */ - prepcompile(L, p, 1); - printpatt(p->code, p->codesize); - return 0; +static int lp_printcode(lua_State *L) +{ + Pattern *p = getpattern(L, 1); + printktable(L, 1); + if (p->code == NULL) /* not compiled yet? */ + prepcompile(L, p, 1); + printpatt(p->code, p->codesize); + return 0; } - /* ** Get the initial position for the match, interpreting negative ** values from the end of the subject */ -static size_t initposition (lua_State *L, size_t len) { - lua_Integer ii = luaL_optinteger(L, 3, 1); - if (ii > 0) { /* positive index? */ - if ((size_t)ii <= len) /* inside the string? */ - return (size_t)ii - 1; /* return it (corrected to 0-base) */ - else return len; /* crop at the end */ - } - else { /* negative index */ - if ((size_t)(-ii) <= len) /* inside the string? */ - return len - ((size_t)(-ii)); /* return position from the end */ - else return 0; /* crop at the beginning */ - } +static size_t initposition(lua_State *L, size_t len) +{ + lua_Integer ii = luaL_optinteger(L, 3, 1); + if (ii > 0) + { /* positive index? */ + if ((size_t)ii <= len) /* inside the string? */ + return (size_t)ii - 1; /* return it (corrected to 0-base) */ + else + return len; /* crop at the end */ + } + else + { /* negative index */ + if ((size_t)(-ii) <= len) /* inside the string? */ + return len - ((size_t)(-ii)); /* return position from the end */ + else + return 0; /* crop at the beginning */ + } } - /* ** Main match function */ -static int lp_match (lua_State *L) { - Capture capture[INITCAPSIZE]; - const char *r; - size_t l; - Pattern *p = (getpatt(L, 1, NULL), getpattern(L, 1)); - Instruction *code = (p->code != NULL) ? p->code : prepcompile(L, p, 1); - const char *s = luaL_checklstring(L, SUBJIDX, &l); - size_t i = initposition(L, l); - int ptop = lua_gettop(L); - lua_pushnil(L); /* initialize subscache */ - lua_pushlightuserdata(L, capture); /* initialize caplistidx */ - lua_getuservalue(L, 1); /* initialize penvidx */ - r = match(L, s, s + i, s + l, code, capture, ptop); - if (r == NULL) { - lua_pushnil(L); - return 1; - } - return getcaptures(L, s, r, ptop); +static int lp_match(lua_State *L) +{ + Capture capture[INITCAPSIZE]; + const char *r; + size_t l; + Pattern *p = (getpatt(L, 1, NULL), getpattern(L, 1)); + Instruction *code = (p->code != NULL) ? p->code : prepcompile(L, p, 1); + const char *s = luaL_checklstring(L, SUBJIDX, &l); + size_t i = initposition(L, l); + int ptop = lua_gettop(L); + lua_pushnil(L); /* initialize subscache */ + lua_pushlightuserdata(L, capture); /* initialize caplistidx */ + lua_getuservalue(L, 1); /* initialize penvidx */ + r = match(L, s, s + i, s + l, code, capture, ptop); + if (r == NULL) + { + lua_pushnil(L); + return 1; + } + return getcaptures(L, s, r, ptop); } - - /* ** {====================================================== ** Library creation and functions not related to matching @@ -1175,121 +1261,113 @@ static int lp_match (lua_State *L) { */ /* maximum limit for stack size */ -#define MAXLIM (INT_MAX / 100) +#define MAXLIM (INT_MAX / 100) -static int lp_setmax (lua_State *L) { - lua_Integer lim = luaL_checkinteger(L, 1); - luaL_argcheck(L, 0 < lim && lim <= MAXLIM, 1, "out of range"); - lua_settop(L, 1); - lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); - return 0; +static int lp_setmax(lua_State *L) +{ + lua_Integer lim = luaL_checkinteger(L, 1); + luaL_argcheck(L, 0 < lim && lim <= MAXLIM, 1, "out of range"); + lua_settop(L, 1); + lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); + return 0; } - -static int lp_version (lua_State *L) { - lua_pushstring(L, VERSION); - return 1; +static int lp_version(lua_State *L) +{ + lua_pushstring(L, VERSION); + return 1; } - -static int lp_type (lua_State *L) { - if (testpattern(L, 1)) - lua_pushliteral(L, "pattern"); - else - lua_pushnil(L); - return 1; +static int lp_type(lua_State *L) +{ + if (testpattern(L, 1)) + lua_pushliteral(L, "pattern"); + else + lua_pushnil(L); + return 1; } - -int lp_gc (lua_State *L) { - Pattern *p = getpattern(L, 1); - realloccode(L, p, 0); /* delete code block */ - return 0; +int lp_gc(lua_State *L) +{ + Pattern *p = getpattern(L, 1); + realloccode(L, p, 0); /* delete code block */ + return 0; } - -static void createcat (lua_State *L, const char *catname, int (catf) (int)) { - TTree *t = newcharset(L); - int i; - for (i = 0; i <= UCHAR_MAX; i++) - if (catf(i)) setchar(treebuffer(t), i); - lua_setfield(L, -2, catname); +static void createcat(lua_State *L, const char *catname, int(catf)(int)) +{ + TTree *t = newcharset(L); + int i; + for (i = 0; i <= UCHAR_MAX; i++) + if (catf(i)) + setchar(treebuffer(t), i); + lua_setfield(L, -2, catname); +} + +static int lp_locale(lua_State *L) +{ + if (lua_isnoneornil(L, 1)) + { + lua_settop(L, 0); + lua_createtable(L, 0, 12); + } + else + { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); + } + createcat(L, "alnum", isalnum); + createcat(L, "alpha", isalpha); + createcat(L, "cntrl", iscntrl); + createcat(L, "digit", isdigit); + createcat(L, "graph", isgraph); + createcat(L, "lower", islower); + createcat(L, "print", isprint); + createcat(L, "punct", ispunct); + createcat(L, "space", isspace); + createcat(L, "upper", isupper); + createcat(L, "xdigit", isxdigit); + return 1; } - -static int lp_locale (lua_State *L) { - if (lua_isnoneornil(L, 1)) { - lua_settop(L, 0); - lua_createtable(L, 0, 12); - } - else { - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); - } - createcat(L, "alnum", isalnum); - createcat(L, "alpha", isalpha); - createcat(L, "cntrl", iscntrl); - createcat(L, "digit", isdigit); - createcat(L, "graph", isgraph); - createcat(L, "lower", islower); - createcat(L, "print", isprint); - createcat(L, "punct", ispunct); - createcat(L, "space", isspace); - createcat(L, "upper", isupper); - createcat(L, "xdigit", isxdigit); - return 1; -} - - -static struct luaL_Reg pattreg[] = { - {"ptree", lp_printtree}, - {"pcode", lp_printcode}, - {"match", lp_match}, - {"B", lp_behind}, - {"V", lp_V}, - {"C", lp_simplecapture}, - {"Cc", lp_constcapture}, - {"Cmt", lp_matchtime}, - {"Cb", lp_backref}, - {"Carg", lp_argcapture}, - {"Cp", lp_poscapture}, - {"Cs", lp_substcapture}, - {"Ct", lp_tablecapture}, - {"Cf", lp_foldcapture}, - {"Cg", lp_groupcapture}, - {"P", lp_P}, - {"S", lp_set}, - {"R", lp_range}, - {"locale", lp_locale}, - {"version", lp_version}, - {"setmaxstack", lp_setmax}, - {"type", lp_type}, - {NULL, NULL} -}; - - -static struct luaL_Reg metareg[] = { - {"__mul", lp_seq}, - {"__add", lp_choice}, - {"__pow", lp_star}, - {"__gc", lp_gc}, - {"__len", lp_and}, - {"__div", lp_divcapture}, - {"__unm", lp_not}, - {"__sub", lp_sub}, - {NULL, NULL} -}; - - -int luaopen_lpeg (lua_State *L) { - luaL_newmetatable(L, PATTERN_T); - lua_pushnumber(L, MAXBACK); /* initialize maximum backtracking */ - lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); - luaL_setfuncs(L, metareg, 0); - luaL_newlib(L, pattreg); - lua_pushvalue(L, -1); - lua_setfield(L, -3, "__index"); - return 1; +static struct luaL_Reg pattreg[] = {{"ptree", lp_printtree}, + {"pcode", lp_printcode}, + {"match", lp_match}, + {"B", lp_behind}, + {"V", lp_V}, + {"C", lp_simplecapture}, + {"Cc", lp_constcapture}, + {"Cmt", lp_matchtime}, + {"Cb", lp_backref}, + {"Carg", lp_argcapture}, + {"Cp", lp_poscapture}, + {"Cs", lp_substcapture}, + {"Ct", lp_tablecapture}, + {"Cf", lp_foldcapture}, + {"Cg", lp_groupcapture}, + {"P", lp_P}, + {"S", lp_set}, + {"R", lp_range}, + {"locale", lp_locale}, + {"version", lp_version}, + {"setmaxstack", lp_setmax}, + {"type", lp_type}, + {NULL, NULL}}; + +static struct luaL_Reg metareg[] = {{"__mul", lp_seq}, {"__add", lp_choice}, {"__pow", lp_star}, + {"__gc", lp_gc}, {"__len", lp_and}, {"__div", lp_divcapture}, + {"__unm", lp_not}, {"__sub", lp_sub}, {NULL, NULL}}; + +int luaopen_lpeg(lua_State *L) +{ + luaL_newmetatable(L, PATTERN_T); + lua_pushnumber(L, MAXBACK); /* initialize maximum backtracking */ + lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); + luaL_setfuncs(L, metareg, 0); + luaL_newlib(L, pattreg); + lua_pushvalue(L, -1); + lua_setfield(L, -3, "__index"); + return 1; } /* }====================================================== */ diff --git a/LuaNode_Esp32/LuaNode32/components/lpeg/lpvm.c b/LuaNode_Esp32/LuaNode32/components/lpeg/lpvm.c index eaf2ebf..32a24f1 100644 --- a/LuaNode_Esp32/LuaNode32/components/lpeg/lpvm.c +++ b/LuaNode_Esp32/LuaNode32/components/lpeg/lpvm.c @@ -3,84 +3,79 @@ ** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) */ +#include "lpvm.h" + #include #include - -#include "lua.h" #include "lauxlib.h" - #include "lpcap.h" -#include "lptypes.h" -#include "lpvm.h" #include "lpprint.h" - +#include "lptypes.h" +#include "lua.h" /* initial size for call/backtrack stack */ #if !defined(INITBACK) -#define INITBACK MAXBACK +#define INITBACK MAXBACK #endif - -#define getoffset(p) (((p) + 1)->offset) +#define getoffset(p) (((p) + 1)->offset) static const Instruction giveup = {{IGiveup, 0, 0}}; - /* ** {====================================================== ** Virtual Machine ** ======================================================= */ - -typedef struct Stack { - const char *s; /* saved position (or NULL for calls) */ - const Instruction *p; /* next instruction */ - int caplevel; +typedef struct Stack +{ + const char *s; /* saved position (or NULL for calls) */ + const Instruction *p; /* next instruction */ + int caplevel; } Stack; - -#define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop))) - +#define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop))) /* ** Double the size of the array of captures */ -static Capture *doublecap (lua_State *L, Capture *cap, int captop, int ptop) { - Capture *newc; - if (captop >= INT_MAX/((int)sizeof(Capture) * 2)) - luaL_error(L, "too many captures"); - newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture)); - memcpy(newc, cap, captop * sizeof(Capture)); - lua_replace(L, caplistidx(ptop)); - return newc; +static Capture *doublecap(lua_State *L, Capture *cap, int captop, int ptop) +{ + Capture *newc; + if (captop >= INT_MAX / ((int)sizeof(Capture) * 2)) + luaL_error(L, "too many captures"); + newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture)); + memcpy(newc, cap, captop * sizeof(Capture)); + lua_replace(L, caplistidx(ptop)); + return newc; } - /* ** Double the size of the stack */ -static Stack *doublestack (lua_State *L, Stack **stacklimit, int ptop) { - Stack *stack = getstackbase(L, ptop); - Stack *newstack; - int n = *stacklimit - stack; /* current stack size */ - int max, newn; - lua_getfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); - max = lua_tointeger(L, -1); /* maximum allowed size */ - lua_pop(L, 1); - if (n >= max) /* already at maximum size? */ - luaL_error(L, "backtrack stack overflow (current limit is %d)", max); - newn = 2 * n; /* new size */ - if (newn > max) newn = max; - newstack = (Stack *)lua_newuserdata(L, newn * sizeof(Stack)); - memcpy(newstack, stack, n * sizeof(Stack)); - lua_replace(L, stackidx(ptop)); - *stacklimit = newstack + newn; - return newstack + n; /* return next position */ +static Stack *doublestack(lua_State *L, Stack **stacklimit, int ptop) +{ + Stack *stack = getstackbase(L, ptop); + Stack *newstack; + int n = *stacklimit - stack; /* current stack size */ + int max, newn; + lua_getfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); + max = lua_tointeger(L, -1); /* maximum allowed size */ + lua_pop(L, 1); + if (n >= max) /* already at maximum size? */ + luaL_error(L, "backtrack stack overflow (current limit is %d)", max); + newn = 2 * n; /* new size */ + if (newn > max) + newn = max; + newstack = (Stack *)lua_newuserdata(L, newn * sizeof(Stack)); + memcpy(newstack, stack, n * sizeof(Stack)); + lua_replace(L, stackidx(ptop)); + *stacklimit = newstack + newn; + return newstack + n; /* return next position */ } - /* ** Interpret the result of a dynamic capture: false -> fail; ** true -> keep current position; number -> next position. @@ -88,268 +83,328 @@ static Stack *doublestack (lua_State *L, Stack **stacklimit, int ptop) { ** is the result; 'curr' is current subject position; 'limit' ** is subject's size. */ -static int resdyncaptures (lua_State *L, int fr, int curr, int limit) { - lua_Integer res; - if (!lua_toboolean(L, fr)) { /* false value? */ - lua_settop(L, fr - 1); /* remove results */ - return -1; /* and fail */ - } - else if (lua_isboolean(L, fr)) /* true? */ - res = curr; /* keep current position */ - else { - res = lua_tointeger(L, fr) - 1; /* new position */ - if (res < curr || res > limit) - luaL_error(L, "invalid position returned by match-time capture"); - } - lua_remove(L, fr); /* remove first result (offset) */ - return res; +static int resdyncaptures(lua_State *L, int fr, int curr, int limit) +{ + lua_Integer res; + if (!lua_toboolean(L, fr)) + { /* false value? */ + lua_settop(L, fr - 1); /* remove results */ + return -1; /* and fail */ + } + else if (lua_isboolean(L, fr)) /* true? */ + res = curr; /* keep current position */ + else + { + res = lua_tointeger(L, fr) - 1; /* new position */ + if (res < curr || res > limit) + luaL_error(L, "invalid position returned by match-time capture"); + } + lua_remove(L, fr); /* remove first result (offset) */ + return res; } - /* ** Add capture values returned by a dynamic capture to the capture list ** 'base', nested inside a group capture. 'fd' indexes the first capture ** value, 'n' is the number of values (at least 1). */ -static void adddyncaptures (const char *s, Capture *base, int n, int fd) { - int i; - /* Cgroup capture is already there */ - assert(base[0].kind == Cgroup && base[0].siz == 0); - base[0].idx = 0; /* make it an anonymous group */ - for (i = 1; i <= n; i++) { /* add runtime captures */ - base[i].kind = Cruntime; - base[i].siz = 1; /* mark it as closed */ - base[i].idx = fd + i - 1; /* stack index of capture value */ +static void adddyncaptures(const char *s, Capture *base, int n, int fd) +{ + int i; + /* Cgroup capture is already there */ + assert(base[0].kind == Cgroup && base[0].siz == 0); + base[0].idx = 0; /* make it an anonymous group */ + for (i = 1; i <= n; i++) + { /* add runtime captures */ + base[i].kind = Cruntime; + base[i].siz = 1; /* mark it as closed */ + base[i].idx = fd + i - 1; /* stack index of capture value */ + base[i].s = s; + } + base[i].kind = Cclose; /* close group */ + base[i].siz = 1; base[i].s = s; - } - base[i].kind = Cclose; /* close group */ - base[i].siz = 1; - base[i].s = s; } - /* ** Remove dynamic captures from the Lua stack (called in case of failure) */ -static int removedyncap (lua_State *L, Capture *capture, - int level, int last) { - int id = finddyncap(capture + level, capture + last); /* index of 1st cap. */ - int top = lua_gettop(L); - if (id == 0) return 0; /* no dynamic captures? */ - lua_settop(L, id - 1); /* remove captures */ - return top - id + 1; /* number of values removed */ +static int removedyncap(lua_State *L, Capture *capture, int level, int last) +{ + int id = finddyncap(capture + level, capture + last); /* index of 1st cap. */ + int top = lua_gettop(L); + if (id == 0) + return 0; /* no dynamic captures? */ + lua_settop(L, id - 1); /* remove captures */ + return top - id + 1; /* number of values removed */ } - /* ** Opcode interpreter */ -const char *match (lua_State *L, const char *o, const char *s, const char *e, - Instruction *op, Capture *capture, int ptop) { - Stack stackbase[INITBACK]; - Stack *stacklimit = stackbase + INITBACK; - Stack *stack = stackbase; /* point to first empty slot in stack */ - int capsize = INITCAPSIZE; - int captop = 0; /* point to first empty slot in captures */ - int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ - const Instruction *p = op; /* current instruction */ - stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; - lua_pushlightuserdata(L, stackbase); - for (;;) { +const char *match(lua_State *L, const char *o, const char *s, const char *e, Instruction *op, Capture *capture, + int ptop) +{ + Stack stackbase[INITBACK]; + Stack *stacklimit = stackbase + INITBACK; + Stack *stack = stackbase; /* point to first empty slot in stack */ + int capsize = INITCAPSIZE; + int captop = 0; /* point to first empty slot in captures */ + int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ + const Instruction *p = op; /* current instruction */ + stack->p = &giveup; + stack->s = s; + stack->caplevel = 0; + stack++; + lua_pushlightuserdata(L, stackbase); + for (;;) + { #if defined(DEBUG) - printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", - s, stack - getstackbase(L, ptop), ndyncap, captop); - printinst(op, p); - printcaplist(capture, capture + captop); + printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", s, stack - getstackbase(L, ptop), ndyncap, captop); + printinst(op, p); + printcaplist(capture, capture + captop); #endif - assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); - switch ((Opcode)p->i.code) { - case IEnd: { - assert(stack == getstackbase(L, ptop) + 1); - capture[captop].kind = Cclose; - capture[captop].s = NULL; - return s; - } - case IGiveup: { - assert(stack == getstackbase(L, ptop)); - return NULL; - } - case IRet: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s == NULL); - p = (--stack)->p; - continue; - } - case IAny: { - if (s < e) { p++; s++; } - else goto fail; - continue; - } - case ITestAny: { - if (s < e) p += 2; - else p += getoffset(p); - continue; - } - case IChar: { - if ((byte)*s == p->i.aux && s < e) { p++; s++; } - else goto fail; - continue; - } - case ITestChar: { - if ((byte)*s == p->i.aux && s < e) p += 2; - else p += getoffset(p); - continue; - } - case ISet: { - int c = (byte)*s; - if (testchar((p+1)->buff, c) && s < e) - { p += CHARSETINSTSIZE; s++; } - else goto fail; - continue; - } - case ITestSet: { - int c = (byte)*s; - if (testchar((p + 2)->buff, c) && s < e) - p += 1 + CHARSETINSTSIZE; - else p += getoffset(p); - continue; - } - case IBehind: { - int n = p->i.aux; - if (n > s - o) goto fail; - s -= n; p++; - continue; - } - case ISpan: { - for (; s < e; s++) { - int c = (byte)*s; - if (!testchar((p+1)->buff, c)) break; - } - p += CHARSETINSTSIZE; - continue; - } - case IJmp: { - p += getoffset(p); - continue; - } - case IChoice: { - if (stack == stacklimit) - stack = doublestack(L, &stacklimit, ptop); - stack->p = p + getoffset(p); - stack->s = s; - stack->caplevel = captop; - stack++; - p += 2; - continue; - } - case ICall: { - if (stack == stacklimit) - stack = doublestack(L, &stacklimit, ptop); - stack->s = NULL; - stack->p = p + 2; /* save return address */ - stack++; - p += getoffset(p); - continue; - } - case ICommit: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); - stack--; - p += getoffset(p); - continue; - } - case IPartialCommit: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); - (stack - 1)->s = s; - (stack - 1)->caplevel = captop; - p += getoffset(p); - continue; - } - case IBackCommit: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); - s = (--stack)->s; - captop = stack->caplevel; - p += getoffset(p); - continue; - } - case IFailTwice: - assert(stack > getstackbase(L, ptop)); - stack--; - /* go through */ - case IFail: - fail: { /* pattern failed: try to backtrack */ - do { /* remove pending calls */ - assert(stack > getstackbase(L, ptop)); - s = (--stack)->s; - } while (s == NULL); - if (ndyncap > 0) /* is there matchtime captures? */ - ndyncap -= removedyncap(L, capture, stack->caplevel, captop); - captop = stack->caplevel; - p = stack->p; - continue; - } - case ICloseRunTime: { - CapState cs; - int rem, res, n; - int fr = lua_gettop(L) + 1; /* stack index of first result */ - cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop; - n = runtimecap(&cs, capture + captop, s, &rem); /* call function */ - captop -= n; /* remove nested captures */ - fr -= rem; /* 'rem' items were popped from Lua stack */ - res = resdyncaptures(L, fr, s - o, e - o); /* get result */ - if (res == -1) /* fail? */ - goto fail; - s = o + res; /* else update current position */ - n = lua_gettop(L) - fr + 1; /* number of new captures */ - ndyncap += n - rem; /* update number of dynamic captures */ - if (n > 0) { /* any new capture? */ - if ((captop += n + 2) >= capsize) { - capture = doublecap(L, capture, captop, ptop); - capsize = 2 * captop; - } - /* add new captures to 'capture' list */ - adddyncaptures(s, capture + captop - n - 2, n, fr); - } - p++; - continue; - } - case ICloseCapture: { - const char *s1 = s; - assert(captop > 0); - /* if possible, turn capture into a full capture */ - if (capture[captop - 1].siz == 0 && - s1 - capture[captop - 1].s < UCHAR_MAX) { - capture[captop - 1].siz = s1 - capture[captop - 1].s + 1; - p++; - continue; - } - else { - capture[captop].siz = 1; /* mark entry as closed */ - capture[captop].s = s; - goto pushcapture; + assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); + switch ((Opcode)p->i.code) + { + case IEnd: + { + assert(stack == getstackbase(L, ptop) + 1); + capture[captop].kind = Cclose; + capture[captop].s = NULL; + return s; + } + case IGiveup: + { + assert(stack == getstackbase(L, ptop)); + return NULL; + } + case IRet: + { + assert(stack > getstackbase(L, ptop) && (stack - 1)->s == NULL); + p = (--stack)->p; + continue; + } + case IAny: + { + if (s < e) + { + p++; + s++; + } + else + goto fail; + continue; + } + case ITestAny: + { + if (s < e) + p += 2; + else + p += getoffset(p); + continue; + } + case IChar: + { + if ((byte)*s == p->i.aux && s < e) + { + p++; + s++; + } + else + goto fail; + continue; + } + case ITestChar: + { + if ((byte)*s == p->i.aux && s < e) + p += 2; + else + p += getoffset(p); + continue; + } + case ISet: + { + int c = (byte)*s; + if (testchar((p + 1)->buff, c) && s < e) + { + p += CHARSETINSTSIZE; + s++; + } + else + goto fail; + continue; + } + case ITestSet: + { + int c = (byte)*s; + if (testchar((p + 2)->buff, c) && s < e) + p += 1 + CHARSETINSTSIZE; + else + p += getoffset(p); + continue; + } + case IBehind: + { + int n = p->i.aux; + if (n > s - o) + goto fail; + s -= n; + p++; + continue; + } + case ISpan: + { + for (; s < e; s++) + { + int c = (byte)*s; + if (!testchar((p + 1)->buff, c)) + break; + } + p += CHARSETINSTSIZE; + continue; + } + case IJmp: + { + p += getoffset(p); + continue; + } + case IChoice: + { + if (stack == stacklimit) + stack = doublestack(L, &stacklimit, ptop); + stack->p = p + getoffset(p); + stack->s = s; + stack->caplevel = captop; + stack++; + p += 2; + continue; + } + case ICall: + { + if (stack == stacklimit) + stack = doublestack(L, &stacklimit, ptop); + stack->s = NULL; + stack->p = p + 2; /* save return address */ + stack++; + p += getoffset(p); + continue; + } + case ICommit: + { + assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); + stack--; + p += getoffset(p); + continue; + } + case IPartialCommit: + { + assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); + (stack - 1)->s = s; + (stack - 1)->caplevel = captop; + p += getoffset(p); + continue; + } + case IBackCommit: + { + assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); + s = (--stack)->s; + captop = stack->caplevel; + p += getoffset(p); + continue; + } + case IFailTwice: + assert(stack > getstackbase(L, ptop)); + stack--; + /* go through */ + case IFail: + fail: + { /* pattern failed: try to backtrack */ + do + { /* remove pending calls */ + assert(stack > getstackbase(L, ptop)); + s = (--stack)->s; + } while (s == NULL); + if (ndyncap > 0) /* is there matchtime captures? */ + ndyncap -= removedyncap(L, capture, stack->caplevel, captop); + captop = stack->caplevel; + p = stack->p; + continue; + } + case ICloseRunTime: + { + CapState cs; + int rem, res, n; + int fr = lua_gettop(L) + 1; /* stack index of first result */ + cs.s = o; + cs.L = L; + cs.ocap = capture; + cs.ptop = ptop; + n = runtimecap(&cs, capture + captop, s, &rem); /* call function */ + captop -= n; /* remove nested captures */ + fr -= rem; /* 'rem' items were popped from Lua stack */ + res = resdyncaptures(L, fr, s - o, e - o); /* get result */ + if (res == -1) /* fail? */ + goto fail; + s = o + res; /* else update current position */ + n = lua_gettop(L) - fr + 1; /* number of new captures */ + ndyncap += n - rem; /* update number of dynamic captures */ + if (n > 0) + { /* any new capture? */ + if ((captop += n + 2) >= capsize) + { + capture = doublecap(L, capture, captop, ptop); + capsize = 2 * captop; + } + /* add new captures to 'capture' list */ + adddyncaptures(s, capture + captop - n - 2, n, fr); + } + p++; + continue; + } + case ICloseCapture: + { + const char *s1 = s; + assert(captop > 0); + /* if possible, turn capture into a full capture */ + if (capture[captop - 1].siz == 0 && s1 - capture[captop - 1].s < UCHAR_MAX) + { + capture[captop - 1].siz = s1 - capture[captop - 1].s + 1; + p++; + continue; + } + else + { + capture[captop].siz = 1; /* mark entry as closed */ + capture[captop].s = s; + goto pushcapture; + } + } + case IOpenCapture: + capture[captop].siz = 0; /* mark entry as open */ + capture[captop].s = s; + goto pushcapture; + case IFullCapture: + capture[captop].siz = getoff(p) + 1; /* save capture size */ + capture[captop].s = s - getoff(p); + /* goto pushcapture; */ + pushcapture: + { + capture[captop].idx = p->i.key; + capture[captop].kind = getkind(p); + if (++captop >= capsize) + { + capture = doublecap(L, capture, captop, ptop); + capsize = 2 * captop; + } + p++; + continue; + } + default: + assert(0); + return NULL; } - } - case IOpenCapture: - capture[captop].siz = 0; /* mark entry as open */ - capture[captop].s = s; - goto pushcapture; - case IFullCapture: - capture[captop].siz = getoff(p) + 1; /* save capture size */ - capture[captop].s = s - getoff(p); - /* goto pushcapture; */ - pushcapture: { - capture[captop].idx = p->i.key; - capture[captop].kind = getkind(p); - if (++captop >= capsize) { - capture = doublecap(L, capture, captop, ptop); - capsize = 2 * captop; - } - p++; - continue; - } - default: assert(0); return NULL; } - } } /* }====================================================== */ - - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lapi.c b/LuaNode_Esp32/LuaNode32/components/lua/lapi.c index 4f7d1c4..b3cd92a 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lapi.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lapi.c @@ -20,13 +20,13 @@ #include "lgc.h" #include "lmem.h" #include "lobject.h" +#include "lrotable.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lundump.h" #include "lvm.h" -#include "lrotable.h" #if 0 const char lua_ident[] = @@ -35,1125 +35,1169 @@ const char lua_ident[] = "$URL: www.lua.org $\n"; #endif +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) -#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) - -#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) - -#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} - +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) +#define api_incr_top(L) \ + { \ + api_check(L, L->top < L->ci->top); \ + L->top++; \ + } -static TValue *index2adr (lua_State *L, int idx) { - if (idx > 0) { - TValue *o = L->base + (idx - 1); - api_check(L, idx <= L->ci->top - L->base); - if (o >= L->top) return cast(TValue *, luaO_nilobject); - else return o; - } - else if (idx > LUA_REGISTRYINDEX) { - api_check(L, idx != 0 && -idx <= L->top - L->base); - return L->top + idx; - } - else switch (idx) { /* pseudo-indices */ - case LUA_REGISTRYINDEX: return registry(L); - case LUA_ENVIRONINDEX: { - Closure *func = curr_func(L); - sethvalue(L, &L->env, func ? func->c.env : hvalue(gt(L))); - return &L->env; +static TValue *index2adr(lua_State *L, int idx) +{ + if (idx > 0) + { + TValue *o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) + return cast(TValue *, luaO_nilobject); + else + return o; } - case LUA_GLOBALSINDEX: return gt(L); - default: { - Closure *func = curr_func(L); - if (!func) return cast(TValue *, luaO_nilobject); - idx = LUA_GLOBALSINDEX - idx; - return (idx <= func->c.nupvalues) - ? &func->c.upvalue[idx-1] - : cast(TValue *, luaO_nilobject); + else if (idx > LUA_REGISTRYINDEX) + { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; } - } -} - - -static Table *getcurrenv (lua_State *L) { - if (L->ci == L->base_ci) /* no enclosing function? */ - return hvalue(gt(L)); /* use global table as environment */ - else { - Closure *func = curr_func(L); - return func ? func->c.env : hvalue(gt(L)); - } -} - - -void luaA_pushobject (lua_State *L, const TValue *o) { - setobj2s(L, L->top, o); - api_incr_top(L); + else + switch (idx) + { /* pseudo-indices */ + case LUA_REGISTRYINDEX: + return registry(L); + case LUA_ENVIRONINDEX: + { + Closure *func = curr_func(L); + sethvalue(L, &L->env, func ? func->c.env : hvalue(gt(L))); + return &L->env; + } + case LUA_GLOBALSINDEX: + return gt(L); + default: + { + Closure *func = curr_func(L); + if (!func) + return cast(TValue *, luaO_nilobject); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->c.nupvalues) ? &func->c.upvalue[idx - 1] : cast(TValue *, luaO_nilobject); + } + } } - -LUA_API int lua_checkstack (lua_State *L, int size) { - int res = 1; - lua_lock(L); - if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) - res = 0; /* stack overflow */ - else if (size > 0) { - luaD_checkstack(L, size); - if (L->ci->top < L->top + size) - L->ci->top = L->top + size; - } - lua_unlock(L); - return res; +static Table *getcurrenv(lua_State *L) +{ + if (L->ci == L->base_ci) /* no enclosing function? */ + return hvalue(gt(L)); /* use global table as environment */ + else + { + Closure *func = curr_func(L); + return func ? func->c.env : hvalue(gt(L)); + } } - -LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { - int i; - if (from == to) return; - lua_lock(to); - api_checknelems(from, n); - api_check(from, G(from) == G(to)); - api_check(from, to->ci->top - to->top >= n); - from->top -= n; - for (i = 0; i < n; i++) { - setobj2s(to, to->top++, from->top + i); - } - lua_unlock(to); +void luaA_pushobject(lua_State *L, const TValue *o) +{ + setobj2s(L, L->top, o); + api_incr_top(L); } - -LUA_API void lua_setlevel (lua_State *from, lua_State *to) { - to->nCcalls = from->nCcalls; +LUA_API int lua_checkstack(lua_State *L, int size) +{ + int res = 1; + lua_lock(L); + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; /* stack overflow */ + else if (size > 0) + { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + } + lua_unlock(L); + return res; } - -LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { - lua_CFunction old; - lua_lock(L); - old = G(L)->panic; - G(L)->panic = panicf; - lua_unlock(L); - return old; +LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) +{ + int i; + if (from == to) + return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to)); + api_check(from, to->ci->top - to->top >= n); + from->top -= n; + for (i = 0; i < n; i++) { setobj2s(to, to->top++, from->top + i); } + lua_unlock(to); +} + +LUA_API void lua_setlevel(lua_State *from, lua_State *to) { to->nCcalls = from->nCcalls; } + +LUA_API lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf) +{ + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; } - -LUA_API lua_State *lua_newthread (lua_State *L) { - lua_State *L1; - lua_lock(L); - luaC_checkGC(L); - L1 = luaE_newthread(L); - setthvalue(L, L->top, L1); - api_incr_top(L); - lua_unlock(L); - luai_userstatethread(L, L1); - return L1; +LUA_API lua_State *lua_newthread(lua_State *L) +{ + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + lua_unlock(L); + luai_userstatethread(L, L1); + return L1; } - - /* ** basic stack manipulation */ +LUA_API int lua_gettop(lua_State *L) { return cast_int(L->top - L->base); } -LUA_API int lua_gettop (lua_State *L) { - return cast_int(L->top - L->base); -} - - -LUA_API void lua_settop (lua_State *L, int idx) { - lua_lock(L); - if (idx >= 0) { - api_check(L, idx <= L->stack_last - L->base); - while (L->top < L->base + idx) - setnilvalue(L->top++); - L->top = L->base + idx; - } - else { - api_check(L, -(idx+1) <= (L->top - L->base)); - L->top += idx+1; /* `subtract' index (index is negative) */ - } - lua_unlock(L); -} - - -LUA_API void lua_remove (lua_State *L, int idx) { - StkId p; - lua_lock(L); - p = index2adr(L, idx); - api_checkvalidindex(L, p); - while (++p < L->top) setobjs2s(L, p-1, p); - L->top--; - lua_unlock(L); -} - - -LUA_API void lua_insert (lua_State *L, int idx) { - StkId p; - StkId q; - lua_lock(L); - p = index2adr(L, idx); - api_checkvalidindex(L, p); - for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); - setobjs2s(L, p, L->top); - lua_unlock(L); -} - - -LUA_API void lua_replace (lua_State *L, int idx) { - StkId o; - lua_lock(L); - /* explicit test for incompatible code */ - if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) - luaG_runerror(L, "no calling environment"); - api_checknelems(L, 1); - o = index2adr(L, idx); - api_checkvalidindex(L, o); - if (idx == LUA_ENVIRONINDEX) { - Closure *func = curr_func(L); - if (!func) - luaG_runerror(L, "attempt to set environment on lightfunction"); - else { - api_check(L, ttistable(L->top - 1)); - func->c.env = hvalue(L->top - 1); - luaC_barrier(L, func, L->top - 1); +LUA_API void lua_settop(lua_State *L, int idx) +{ + lua_lock(L); + if (idx >= 0) + { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) setnilvalue(L->top++); + L->top = L->base + idx; } - } - else { - setobj(L, o, L->top - 1); - if (curr_func(L) && idx < LUA_GLOBALSINDEX) /* function upvalue? */ - luaC_barrier(L, curr_func(L), L->top - 1); - } - L->top--; - lua_unlock(L); + else + { + api_check(L, -(idx + 1) <= (L->top - L->base)); + L->top += idx + 1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); } - -LUA_API void lua_pushvalue (lua_State *L, int idx) { - lua_lock(L); - setobj2s(L, L->top, index2adr(L, idx)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_remove(lua_State *L, int idx) +{ + StkId p; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) setobjs2s(L, p - 1, p); + L->top--; + lua_unlock(L); } - - -/* -** access functions (stack -> C) -*/ - - -LUA_API int lua_type (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +LUA_API void lua_insert(lua_State *L, int idx) +{ + StkId p; + StkId q; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + for (q = L->top; q > p; q--) setobjs2s(L, q, q - 1); + setobjs2s(L, p, L->top); + lua_unlock(L); } - -LUA_API const char *lua_typename (lua_State *L, int t) { - UNUSED(L); - return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +LUA_API void lua_replace(lua_State *L, int idx) +{ + StkId o; + lua_lock(L); + /* explicit test for incompatible code */ + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) + luaG_runerror(L, "no calling environment"); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) + { + Closure *func = curr_func(L); + if (!func) + luaG_runerror(L, "attempt to set environment on lightfunction"); + else + { + api_check(L, ttistable(L->top - 1)); + func->c.env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + } + else + { + setobj(L, o, L->top - 1); + if (curr_func(L) && idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; + lua_unlock(L); } - -LUA_API int lua_iscfunction (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return iscfunction(o); +LUA_API void lua_pushvalue(lua_State *L, int idx) +{ + lua_lock(L); + setobj2s(L, L->top, index2adr(L, idx)); + api_incr_top(L); + lua_unlock(L); } +/* +** access functions (stack -> C) +*/ -LUA_API int lua_isnumber (lua_State *L, int idx) { - TValue n; - const TValue *o = index2adr(L, idx); - return tonumber(o, &n); +LUA_API int lua_type(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); } - -LUA_API int lua_isstring (lua_State *L, int idx) { - int t = lua_type(L, idx); - return (t == LUA_TSTRING || t == LUA_TNUMBER); +LUA_API const char *lua_typename(lua_State *L, int t) +{ + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; } - -LUA_API int lua_isuserdata (lua_State *L, int idx) { - const TValue *o = index2adr(L, idx); - return (ttisuserdata(o) || ttislightuserdata(o)); +LUA_API int lua_iscfunction(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + return iscfunction(o); } - -LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { - StkId o1 = index2adr(L, index1); - StkId o2 = index2adr(L, index2); - return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 - : luaO_rawequalObj(o1, o2); +LUA_API int lua_isnumber(lua_State *L, int idx) +{ + TValue n; + const TValue *o = index2adr(L, idx); + return tonumber(o, &n); } - -LUA_API int lua_equal (lua_State *L, int index1, int index2) { - StkId o1, o2; - int i; - lua_lock(L); /* may call tag method */ - o1 = index2adr(L, index1); - o2 = index2adr(L, index2); - i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); - lua_unlock(L); - return i; +LUA_API int lua_isstring(lua_State *L, int idx) +{ + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); } - -LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { - StkId o1, o2; - int i; - lua_lock(L); /* may call tag method */ - o1 = index2adr(L, index1); - o2 = index2adr(L, index2); - i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 - : luaV_lessthan(L, o1, o2); - lua_unlock(L); - return i; +LUA_API int lua_isuserdata(lua_State *L, int idx) +{ + const TValue *o = index2adr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); } - - -LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { - TValue n; - const TValue *o = index2adr(L, idx); - if (tonumber(o, &n)) - return nvalue(o); - else - return 0; +LUA_API int lua_rawequal(lua_State *L, int index1, int index2) +{ + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : luaO_rawequalObj(o1, o2); } - -LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { - TValue n; - const TValue *o = index2adr(L, idx); - if (tonumber(o, &n)) { - lua_Integer res; - lua_Number num = nvalue(o); - lua_number2integer(res, num); - return res; - } - else - return 0; +LUA_API int lua_equal(lua_State *L, int index1, int index2) +{ + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + lua_unlock(L); + return i; } - -LUA_API int lua_toboolean (lua_State *L, int idx) { - const TValue *o = index2adr(L, idx); - return !l_isfalse(o); +LUA_API int lua_lessthan(lua_State *L, int index1, int index2) +{ + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; } - -LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { - StkId o = index2adr(L, idx); - if (!ttisstring(o)) { - lua_lock(L); /* `luaV_tostring' may create a new string */ - if (!luaV_tostring(L, o)) { /* conversion failed? */ - if (len != NULL) *len = 0; - lua_unlock(L); - return NULL; +LUA_API lua_Number lua_tonumber(lua_State *L, int idx) +{ + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + +LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) +{ + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + return res; } - luaC_checkGC(L); - o = index2adr(L, idx); /* previous call may reallocate the stack */ - lua_unlock(L); - } - if (len != NULL) *len = tsvalue(o)->len; - return svalue(o); -} - - -LUA_API size_t lua_objlen (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - switch (ttype(o)) { - case LUA_TSTRING: return tsvalue(o)->len; - case LUA_TUSERDATA: return uvalue(o)->len; - case LUA_TTABLE: return luaH_getn(hvalue(o)); - case LUA_TROTABLE: return luaH_getn_ro(rvalue(o)); - case LUA_TNUMBER: { - size_t l; - lua_lock(L); /* `luaV_tostring' may create a new string */ - l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); - lua_unlock(L); - return l; + else + return 0; +} + +LUA_API int lua_toboolean(lua_State *L, int idx) +{ + const TValue *o = index2adr(L, idx); + return !l_isfalse(o); +} + +LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len) +{ + StkId o = index2adr(L, idx); + if (!ttisstring(o)) + { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) + { /* conversion failed? */ + if (len != NULL) + *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2adr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) + *len = tsvalue(o)->len; + return svalue(o); +} + +LUA_API size_t lua_objlen(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + switch (ttype(o)) + { + case LUA_TSTRING: + return tsvalue(o)->len; + case LUA_TUSERDATA: + return uvalue(o)->len; + case LUA_TTABLE: + return luaH_getn(hvalue(o)); + case LUA_TROTABLE: + return luaH_getn_ro(rvalue(o)); + case LUA_TNUMBER: + { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: + return 0; } - default: return 0; - } -} - - -LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; } - -LUA_API void *lua_touserdata (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - switch (ttype(o)) { - case LUA_TUSERDATA: return (rawuvalue(o) + 1); - case LUA_TLIGHTUSERDATA: return pvalue(o); - default: return NULL; - } +LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; } - -LUA_API lua_State *lua_tothread (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return (!ttisthread(o)) ? NULL : thvalue(o); +LUA_API void *lua_touserdata(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + switch (ttype(o)) + { + case LUA_TUSERDATA: + return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: + return pvalue(o); + default: + return NULL; + } } - -LUA_API const void *lua_topointer (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - switch (ttype(o)) { - case LUA_TTABLE: return hvalue(o); - case LUA_TFUNCTION: return clvalue(o); - case LUA_TTHREAD: return thvalue(o); - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - return lua_touserdata(L, idx); - case LUA_TROTABLE: - case LUA_TLIGHTFUNCTION: - return pvalue(o); - default: return NULL; - } +LUA_API lua_State *lua_tothread(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + +LUA_API const void *lua_topointer(lua_State *L, int idx) +{ + StkId o = index2adr(L, idx); + switch (ttype(o)) + { + case LUA_TTABLE: + return hvalue(o); + case LUA_TFUNCTION: + return clvalue(o); + case LUA_TTHREAD: + return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + case LUA_TROTABLE: + case LUA_TLIGHTFUNCTION: + return pvalue(o); + default: + return NULL; + } } - - /* ** push functions (C -> stack) */ - -LUA_API void lua_pushnil (lua_State *L) { - lua_lock(L); - setnilvalue(L->top); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushnil(lua_State *L) +{ + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { - lua_lock(L); - setnvalue(L->top, n); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushnumber(lua_State *L, lua_Number n) +{ + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { - lua_lock(L); - setnvalue(L->top, cast_num(n)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushinteger(lua_State *L, lua_Integer n) +{ + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { - lua_lock(L); - luaC_checkGC(L); - setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushlstring(lua_State *L, const char *s, size_t len) +{ + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushrolstring (lua_State *L, const char *s, size_t len) { - lua_lock(L); - luaC_checkGC(L); - setsvalue2s(L, L->top, luaS_newrolstr(L, s, len)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushrolstring(lua_State *L, const char *s, size_t len) +{ + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newrolstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushstring (lua_State *L, const char *s) { - if (s == NULL) - lua_pushnil(L); - else - lua_pushlstring(L, s, strlen(s)); +LUA_API void lua_pushstring(lua_State *L, const char *s) +{ + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); } +LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt, va_list argp) +{ + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} -LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, - va_list argp) { - const char *ret; - lua_lock(L); - luaC_checkGC(L); - ret = luaO_pushvfstring(L, fmt, argp); - lua_unlock(L); - return ret; +LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) +{ + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; } +LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n) +{ + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n, getcurrenv(L)); + cl->c.f = fn; + L->top -= n; + while (n--) setobj2n(L, &cl->c.upvalue[n], L->top + n); + setclvalue(L, L->top, cl); + lua_assert(iswhite(obj2gco(cl))); + api_incr_top(L); + lua_unlock(L); +} -LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { - const char *ret; - va_list argp; - lua_lock(L); - luaC_checkGC(L); - va_start(argp, fmt); - ret = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - lua_unlock(L); - return ret; +LUA_API void lua_pushboolean(lua_State *L, int b) +{ + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); } +LUA_API void lua_pushlightuserdata(lua_State *L, void *p) +{ + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} -LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { - Closure *cl; - lua_lock(L); - luaC_checkGC(L); - api_checknelems(L, n); - cl = luaF_newCclosure(L, n, getcurrenv(L)); - cl->c.f = fn; - L->top -= n; - while (n--) - setobj2n(L, &cl->c.upvalue[n], L->top+n); - setclvalue(L, L->top, cl); - lua_assert(iswhite(obj2gco(cl))); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushrotable(lua_State *L, void *p) +{ + lua_lock(L); + setrvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); } +LUA_API void lua_pushlightfunction(lua_State *L, void *p) +{ + lua_lock(L); + setfvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} -LUA_API void lua_pushboolean (lua_State *L, int b) { - lua_lock(L); - setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ - api_incr_top(L); - lua_unlock(L); +LUA_API int lua_pushthread(lua_State *L) +{ + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); } +/* +** get functions (Lua -> stack) +*/ -LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { - lua_lock(L); - setpvalue(L->top, p); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_gettable(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); } -LUA_API void lua_pushrotable (lua_State *L, void *p) { - lua_lock(L); - setrvalue(L->top, p); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_getfield(lua_State *L, int idx, const char *k) +{ + StkId t; + TValue key; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + fixedstack(L); + setsvalue(L, &key, luaS_new(L, k)); + unfixedstack(L); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + lua_unlock(L); } -LUA_API void lua_pushlightfunction(lua_State *L, void *p) { - lua_lock(L); - setfvalue(L->top, p); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_rawget(lua_State *L, int idx) +{ + StkId t; + const TValue *res; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t) || ttisrotable(t)); + res = ttistable(t) ? luaH_get(hvalue(t), L->top - 1) : luaH_get_ro(rvalue(t), L->top - 1); + setobj2s(L, L->top - 1, res); + lua_unlock(L); } +LUA_API void lua_rawgeti(lua_State *L, int idx, int n) +{ + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_check(L, ttistable(o) || ttisrotable(o)); + setobj2s(L, L->top, ttistable(o) ? luaH_getnum(hvalue(o), n) : luaH_getnum_ro(rvalue(o), n)) api_incr_top(L); + lua_unlock(L); +} -LUA_API int lua_pushthread (lua_State *L) { - lua_lock(L); - setthvalue(L, L->top, L); - api_incr_top(L); - lua_unlock(L); - return (G(L)->mainthread == L); +LUA_API void lua_createtable(lua_State *L, int narray, int nrec) +{ + lua_lock(L); + luaC_checkGC(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); + lua_unlock(L); } +LUA_API int lua_getmetatable(lua_State *L, int objindex) +{ + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2adr(L, objindex); + switch (ttype(obj)) + { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + case LUA_TROTABLE: + mt = (Table *)luaR_getmeta(rvalue(obj)); + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt == NULL) + res = 0; + else + { + if (luaR_isrotable(mt)) + setrvalue(L->top, mt) else sethvalue(L, L->top, mt) api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} +LUA_API void lua_getfenv(lua_State *L, int idx) +{ + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) + { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->c.env); + break; + case LUA_TUSERDATA: + sethvalue(L, L->top, uvalue(o)->env); + break; + case LUA_TTHREAD: + setobj2s(L, L->top, gt(thvalue(o))); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); + lua_unlock(L); +} /* -** get functions (Lua -> stack) +** set functions (stack -> Lua) */ +LUA_API void lua_settable(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} -LUA_API void lua_gettable (lua_State *L, int idx) { - StkId t; - lua_lock(L); - t = index2adr(L, idx); - api_checkvalidindex(L, t); - luaV_gettable(L, t, L->top - 1, L->top - 1); - lua_unlock(L); -} - - -LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { - StkId t; - TValue key; - lua_lock(L); - t = index2adr(L, idx); - api_checkvalidindex(L, t); - fixedstack(L); - setsvalue(L, &key, luaS_new(L, k)); - unfixedstack(L); - luaV_gettable(L, t, &key, L->top); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_rawget (lua_State *L, int idx) { - StkId t; - const TValue *res; - lua_lock(L); - t = index2adr(L, idx); - api_check(L, ttistable(t) || ttisrotable(t)); - res = ttistable(t) ? luaH_get(hvalue(t), L->top - 1) : luaH_get_ro(rvalue(t), L->top - 1); - setobj2s(L, L->top - 1, res); - lua_unlock(L); -} - - -LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { - StkId o; - lua_lock(L); - o = index2adr(L, idx); - api_check(L, ttistable(o) || ttisrotable(o)); - setobj2s(L, L->top, ttistable(o) ? luaH_getnum(hvalue(o), n) : luaH_getnum_ro(rvalue(o), n)) - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { - lua_lock(L); - luaC_checkGC(L); - sethvalue(L, L->top, luaH_new(L, narray, nrec)); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API int lua_getmetatable (lua_State *L, int objindex) { - const TValue *obj; - Table *mt = NULL; - int res; - lua_lock(L); - obj = index2adr(L, objindex); - switch (ttype(obj)) { - case LUA_TTABLE: - mt = hvalue(obj)->metatable; - break; - case LUA_TUSERDATA: - mt = uvalue(obj)->metatable; - break; - case LUA_TROTABLE: - mt = (Table*)luaR_getmeta(rvalue(obj)); - break; - default: - mt = G(L)->mt[ttype(obj)]; - break; - } - if (mt == NULL) - res = 0; - else { - if(luaR_isrotable(mt)) - setrvalue(L->top, mt) - else - sethvalue(L, L->top, mt) +LUA_API void lua_setfield(lua_State *L, int idx, const char *k) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue2s(L, L->top, luaS_new(L, k)); api_incr_top(L); - res = 1; - } - lua_unlock(L); - return res; -} - - -LUA_API void lua_getfenv (lua_State *L, int idx) { - StkId o; - lua_lock(L); - o = index2adr(L, idx); - api_checkvalidindex(L, o); - switch (ttype(o)) { - case LUA_TFUNCTION: - sethvalue(L, L->top, clvalue(o)->c.env); - break; - case LUA_TUSERDATA: - sethvalue(L, L->top, uvalue(o)->env); - break; - case LUA_TTHREAD: - setobj2s(L, L->top, gt(thvalue(o))); - break; - default: - setnilvalue(L->top); - break; - } - api_incr_top(L); - lua_unlock(L); + luaV_settable(L, t, L->top - 1, L->top - 2); + L->top -= 2; /* pop key and value */ + lua_unlock(L); } +LUA_API void lua_rawset(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + fixedstack(L); + setobj2t(L, luaH_set(L, hvalue(t), L->top - 2), L->top - 1); + unfixedstack(L); + luaC_barriert(L, hvalue(t), L->top - 1); + L->top -= 2; + lua_unlock(L); +} -/* -** set functions (stack -> Lua) -*/ - +LUA_API void lua_rawseti(lua_State *L, int idx, int n) +{ + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + fixedstack(L); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top - 1); + unfixedstack(L); + luaC_barriert(L, hvalue(o), L->top - 1); + L->top--; + lua_unlock(L); +} -LUA_API void lua_settable (lua_State *L, int idx) { - StkId t; - lua_lock(L); - api_checknelems(L, 2); - t = index2adr(L, idx); - api_checkvalidindex(L, t); - luaV_settable(L, t, L->top - 2, L->top - 1); - L->top -= 2; /* pop index and value */ - lua_unlock(L); -} - - -LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { - StkId t; - lua_lock(L); - api_checknelems(L, 1); - t = index2adr(L, idx); - api_checkvalidindex(L, t); - setsvalue2s(L, L->top, luaS_new(L, k)); - api_incr_top(L); - luaV_settable(L, t, L->top - 1, L->top - 2); - L->top -= 2; /* pop key and value */ - lua_unlock(L); -} - - -LUA_API void lua_rawset (lua_State *L, int idx) { - StkId t; - lua_lock(L); - api_checknelems(L, 2); - t = index2adr(L, idx); - api_check(L, ttistable(t)); - fixedstack(L); - setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); - unfixedstack(L); - luaC_barriert(L, hvalue(t), L->top-1); - L->top -= 2; - lua_unlock(L); -} - - -LUA_API void lua_rawseti (lua_State *L, int idx, int n) { - StkId o; - lua_lock(L); - api_checknelems(L, 1); - o = index2adr(L, idx); - api_check(L, ttistable(o)); - fixedstack(L); - setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); - unfixedstack(L); - luaC_barriert(L, hvalue(o), L->top-1); - L->top--; - lua_unlock(L); -} - - -LUA_API int lua_setmetatable (lua_State *L, int objindex) { - TValue *obj; - Table *mt; - int isrometa = 0; - lua_lock(L); - api_checknelems(L, 1); - obj = index2adr(L, objindex); - api_checkvalidindex(L, obj); - if (ttisnil(L->top - 1)) - mt = NULL; - else { - api_check(L, ttistable(L->top - 1) || ttisrotable(L->top - 1)); - if (ttistable(L->top - 1)) - mt = hvalue(L->top - 1); - else { - mt = (Table*)rvalue(L->top - 1); - isrometa = 1; - } - } - switch (ttype(obj)) { - case LUA_TTABLE: { - hvalue(obj)->metatable = mt; - if (mt && !isrometa) - luaC_objbarriert(L, hvalue(obj), mt); - break; - } - case LUA_TUSERDATA: { - uvalue(obj)->metatable = mt; - if (mt && !isrometa) - luaC_objbarrier(L, rawuvalue(obj), mt); - break; +LUA_API int lua_setmetatable(lua_State *L, int objindex) +{ + TValue *obj; + Table *mt; + int isrometa = 0; + lua_lock(L); + api_checknelems(L, 1); + obj = index2adr(L, objindex); + api_checkvalidindex(L, obj); + if (ttisnil(L->top - 1)) + mt = NULL; + else + { + api_check(L, ttistable(L->top - 1) || ttisrotable(L->top - 1)); + if (ttistable(L->top - 1)) + mt = hvalue(L->top - 1); + else + { + mt = (Table *)rvalue(L->top - 1); + isrometa = 1; + } } - default: { - G(L)->mt[ttype(obj)] = mt; - break; + switch (ttype(obj)) + { + case LUA_TTABLE: + { + hvalue(obj)->metatable = mt; + if (mt && !isrometa) + luaC_objbarriert(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: + { + uvalue(obj)->metatable = mt; + if (mt && !isrometa) + luaC_objbarrier(L, rawuvalue(obj), mt); + break; + } + default: + { + G(L)->mt[ttype(obj)] = mt; + break; + } } - } - L->top--; - lua_unlock(L); - return 1; -} - - -LUA_API int lua_setfenv (lua_State *L, int idx) { - StkId o; - int res = 1; - lua_lock(L); - api_checknelems(L, 1); - o = index2adr(L, idx); - api_checkvalidindex(L, o); - api_check(L, ttistable(L->top - 1)); - switch (ttype(o)) { - case LUA_TFUNCTION: - clvalue(o)->c.env = hvalue(L->top - 1); - break; - case LUA_TUSERDATA: - uvalue(o)->env = hvalue(L->top - 1); - break; - case LUA_TTHREAD: - sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); - break; - default: - res = 0; - break; - } - if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); - L->top--; - lua_unlock(L); - return res; + L->top--; + lua_unlock(L); + return 1; } +LUA_API int lua_setfenv(lua_State *L, int idx) +{ + StkId o; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) + { + case LUA_TFUNCTION: + clvalue(o)->c.env = hvalue(L->top - 1); + break; + case LUA_TUSERDATA: + uvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); + break; + default: + res = 0; + break; + } + if (res) + luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + L->top--; + lua_unlock(L); + return res; +} /* ** `load' and `call' functions (run Lua code) */ +#define adjustresults(L, nres) \ + { \ + if (nres == LUA_MULTRET && L->top >= L->ci->top) \ + L->ci->top = L->top; \ + } -#define adjustresults(L,nres) \ - { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } - - -#define checkresults(L,na,nr) \ - api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) - - -LUA_API void lua_call (lua_State *L, int nargs, int nresults) { - StkId func; - lua_lock(L); - api_checknelems(L, nargs+1); - checkresults(L, nargs, nresults); - func = L->top - (nargs+1); - luaD_call(L, func, nresults); - adjustresults(L, nresults); - lua_unlock(L); +#define checkresults(L, na, nr) api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + +LUA_API void lua_call(lua_State *L, int nargs, int nresults) +{ + StkId func; + lua_lock(L); + api_checknelems(L, nargs + 1); + checkresults(L, nargs, nresults); + func = L->top - (nargs + 1); + luaD_call(L, func, nresults); + adjustresults(L, nresults); + lua_unlock(L); } - - /* ** Execute a protected call. */ -struct CallS { /* data to `f_call' */ - StkId func; - int nresults; +struct CallS +{ /* data to `f_call' */ + StkId func; + int nresults; }; - -static void f_call (lua_State *L, void *ud) { - struct CallS *c = cast(struct CallS *, ud); - luaD_call(L, c->func, c->nresults); -} - - - -LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { - struct CallS c; - int status; - ptrdiff_t func; - lua_lock(L); - api_checknelems(L, nargs+1); - checkresults(L, nargs, nresults); - if (errfunc == 0) - func = 0; - else { - StkId o = index2adr(L, errfunc); - api_checkvalidindex(L, o); - func = savestack(L, o); - } - c.func = L->top - (nargs+1); /* function to be called */ - c.nresults = nresults; - status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); - adjustresults(L, nresults); - lua_unlock(L); - return status; +static void f_call(lua_State *L, void *ud) +{ + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + +LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) +{ + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_checknelems(L, nargs + 1); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else + { + StkId o = index2adr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + c.func = L->top - (nargs + 1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + adjustresults(L, nresults); + lua_unlock(L); + return status; } - /* ** Execute a protected C call. */ -struct CCallS { /* data to `f_Ccall' */ - lua_CFunction func; - void *ud; +struct CCallS +{ /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; }; - -static void f_Ccall (lua_State *L, void *ud) { - struct CCallS *c = cast(struct CCallS *, ud); - Closure *cl; - cl = luaF_newCclosure(L, 0, getcurrenv(L)); - cl->c.f = c->func; - setclvalue(L, L->top, cl); /* push function */ - api_incr_top(L); - setpvalue(L->top, c->ud); /* push only argument */ - api_incr_top(L); - luaD_call(L, L->top - 2, 0); -} - - -LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { - struct CCallS c; - int status; - lua_lock(L); - c.func = func; - c.ud = ud; - status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); - lua_unlock(L); - return status; -} - - -LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, - const char *chunkname) { - ZIO z; - int status; - lua_lock(L); - if (!chunkname) chunkname = "?"; - luaZ_init(L, &z, reader, data); - status = luaD_protectedparser(L, &z, chunkname); - lua_unlock(L); - return status; -} - - -LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { - int status; - TValue *o; - lua_lock(L); - api_checknelems(L, 1); - o = L->top - 1; - if (isLfunction(o)) - status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); - else - status = 1; - lua_unlock(L); - return status; +static void f_Ccall(lua_State *L, void *ud) +{ + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0, getcurrenv(L)); + cl->c.f = c->func; + setclvalue(L, L->top, cl); /* push function */ + api_incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + api_incr_top(L); + luaD_call(L, L->top - 2, 0); } - -LUA_API int lua_status (lua_State *L) { - return L->status; +LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) +{ + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + +LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char *chunkname) +{ + ZIO z; + int status; + lua_lock(L); + if (!chunkname) + chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname); + lua_unlock(L); + return status; +} + +LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data) +{ + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; } +LUA_API int lua_status(lua_State *L) { return L->status; } /* ** Garbage-collection function */ -LUA_API int lua_gc (lua_State *L, int what, int data) { - int res = 0; - global_State *g; - lua_lock(L); - g = G(L); - switch (what) { - case LUA_GCSTOP: { - set_block_gc(L); - break; - } - case LUA_GCRESTART: { - unset_block_gc(L); - break; - } - case LUA_GCCOLLECT: { - luaC_fullgc(L); - break; - } - case LUA_GCCOUNT: { - /* GC values are expressed in Kbytes: #bytes/2^10 */ - res = cast_int(g->totalbytes >> 10); - break; - } - case LUA_GCCOUNTB: { - res = cast_int(g->totalbytes & 0x3ff); - break; - } - case LUA_GCSTEP: { - if(is_block_gc(L)) { - res = 1; /* gc is block so we need to pretend that the collection cycle finished. */ - break; - } - lu_mem a = (cast(lu_mem, data) << 10); - if (a <= g->totalbytes) - g->GCthreshold = g->totalbytes - a; - else - g->GCthreshold = 0; - while (g->GCthreshold <= g->totalbytes) { - luaC_step(L); - if (g->gcstate == GCSpause) { /* end of cycle? */ - res = 1; /* signal it */ - break; +LUA_API int lua_gc(lua_State *L, int what, int data) +{ + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) + { + case LUA_GCSTOP: + { + set_block_gc(L); + break; } - } - break; - } - case LUA_GCSETPAUSE: { - res = g->gcpause; - g->gcpause = data; - break; - } - case LUA_GCSETSTEPMUL: { - res = g->gcstepmul; - g->gcstepmul = data; - break; - } - case LUA_GCSETMEMLIMIT: { - /* GC values are expressed in Kbytes: #bytes/2^10 */ - lu_mem new_memlimit = (cast(lu_mem, data) << 10); - if(new_memlimit > 0 && new_memlimit < g->totalbytes) { - /* run a full GC to make totalbytes < the new limit. */ - luaC_fullgc(L); - if(new_memlimit < g->totalbytes) - new_memlimit = (g->totalbytes + 1024) & ~(1024-1); /* round up to next multiple of 1024 */ - } - g->memlimit = new_memlimit; - /* new memlimit might be > then requested memlimit. */ - res = cast_int(new_memlimit >> 10); - break; - } - case LUA_GCGETMEMLIMIT: { - res = cast_int(g->memlimit >> 10); - break; + case LUA_GCRESTART: + { + unset_block_gc(L); + break; + } + case LUA_GCCOLLECT: + { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: + { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: + { + res = cast_int(g->totalbytes & 0x3ff); + break; + } + case LUA_GCSTEP: + { + if (is_block_gc(L)) + { + res = 1; /* gc is block so we need to pretend that the + collection cycle finished. */ + break; + } + lu_mem a = (cast(lu_mem, data) << 10); + if (a <= g->totalbytes) + g->GCthreshold = g->totalbytes - a; + else + g->GCthreshold = 0; + while (g->GCthreshold <= g->totalbytes) + { + luaC_step(L); + if (g->gcstate == GCSpause) + { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } + break; + } + case LUA_GCSETPAUSE: + { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: + { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + case LUA_GCSETMEMLIMIT: + { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + lu_mem new_memlimit = (cast(lu_mem, data) << 10); + if (new_memlimit > 0 && new_memlimit < g->totalbytes) + { + /* run a full GC to make totalbytes < the new limit. */ + luaC_fullgc(L); + if (new_memlimit < g->totalbytes) + new_memlimit = (g->totalbytes + 1024) & ~(1024 - 1); /* round up to next multiple of 1024 */ + } + g->memlimit = new_memlimit; + /* new memlimit might be > then requested memlimit. */ + res = cast_int(new_memlimit >> 10); + break; + } + case LUA_GCGETMEMLIMIT: + { + res = cast_int(g->memlimit >> 10); + break; + } + default: + res = -1; /* invalid option */ } - default: res = -1; /* invalid option */ - } - lua_unlock(L); - return res; + lua_unlock(L); + return res; } - - /* ** miscellaneous functions */ - -LUA_API int lua_error (lua_State *L) { - lua_lock(L); - api_checknelems(L, 1); - luaG_errormsg(L); - lua_unlock(L); - return 0; /* to avoid warnings */ -} - - -LUA_API int lua_next (lua_State *L, int idx) { - StkId t; - int more; - lua_lock(L); - t = index2adr(L, idx); - api_check(L, ttistable(t) || ttisrotable(t)); - more = ttistable(t) ? luaH_next(L, hvalue(t), L->top - 1) : luaH_next_ro(L, rvalue(t), L->top - 1); - if (more) { - api_incr_top(L); - } - else /* no more elements */ - L->top -= 1; /* remove key */ - lua_unlock(L); - return more; -} - - -LUA_API void lua_concat (lua_State *L, int n) { - lua_lock(L); - api_checknelems(L, n); - if (n >= 2) { - luaC_checkGC(L); - luaV_concat(L, n, cast_int(L->top - L->base) - 1); - L->top -= (n-1); - } - else if (n == 0) { /* push empty string */ - setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); - api_incr_top(L); - } - /* else n == 1; nothing to do */ - lua_unlock(L); -} - - -LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { - lua_Alloc f; - lua_lock(L); - if (ud) *ud = G(L)->ud; - f = G(L)->frealloc; - lua_unlock(L); - return f; -} - - -LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { - lua_lock(L); - G(L)->ud = ud; - G(L)->frealloc = f; - lua_unlock(L); +LUA_API int lua_error(lua_State *L) +{ + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + +LUA_API int lua_next(lua_State *L, int idx) +{ + StkId t; + int more; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t) || ttisrotable(t)); + more = ttistable(t) ? luaH_next(L, hvalue(t), L->top - 1) : luaH_next_ro(L, rvalue(t), L->top - 1); + if (more) + { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + +LUA_API void lua_concat(lua_State *L, int n) +{ + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) + { + luaC_checkGC(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n - 1); + } + else if (n == 0) + { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); } - -LUA_API void *lua_newuserdata (lua_State *L, size_t size) { - Udata *u; - lua_lock(L); - luaC_checkGC(L); - u = luaS_newudata(L, size, getcurrenv(L)); - setuvalue(L, L->top, u); - api_incr_top(L); - lua_unlock(L); - return u + 1; +LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud) +{ + lua_Alloc f; + lua_lock(L); + if (ud) + *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; } - - - -static const char *aux_upvalue (StkId fi, int n, TValue **val) { - Closure *f; - if (!ttisfunction(fi)) return NULL; - f = clvalue(fi); - if (f->c.isC) { - if (!(1 <= n && n <= f->c.nupvalues)) return NULL; - *val = &f->c.upvalue[n-1]; - return ""; - } - else { - Proto *p = f->l.p; - if (!(1 <= n && n <= p->sizeupvalues)) return NULL; - *val = f->l.upvals[n-1]->v; - return getstr(p->upvalues[n-1]); - } +LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud) +{ + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); } - -LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TValue *val; - lua_lock(L); - name = aux_upvalue(index2adr(L, funcindex), n, &val); - if (name) { - setobj2s(L, L->top, val); +LUA_API void *lua_newuserdata(lua_State *L, size_t size) +{ + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, getcurrenv(L)); + setuvalue(L, L->top, u); api_incr_top(L); - } - lua_unlock(L); - return name; + lua_unlock(L); + return u + 1; +} + +static const char *aux_upvalue(StkId fi, int n, TValue **val) +{ + Closure *f; + if (!ttisfunction(fi)) + return NULL; + f = clvalue(fi); + if (f->c.isC) + { + if (!(1 <= n && n <= f->c.nupvalues)) + return NULL; + *val = &f->c.upvalue[n - 1]; + return ""; + } + else + { + Proto *p = f->l.p; + if (!(1 <= n && n <= p->sizeupvalues)) + return NULL; + *val = f->l.upvals[n - 1]->v; + return getstr(p->upvalues[n - 1]); + } } - -LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TValue *val; - StkId fi; - lua_lock(L); - fi = index2adr(L, funcindex); - api_checknelems(L, 1); - name = aux_upvalue(fi, n, &val); - if (name) { - L->top--; - setobj(L, val, L->top); - luaC_barrier(L, clvalue(fi), L->top); - } - lua_unlock(L); - return name; +LUA_API const char *lua_getupvalue(lua_State *L, int funcindex, int n) +{ + const char *name; + TValue *val; + lua_lock(L); + name = aux_upvalue(index2adr(L, funcindex), n, &val); + if (name) + { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + +LUA_API const char *lua_setupvalue(lua_State *L, int funcindex, int n) +{ + const char *name; + TValue *val; + StkId fi; + lua_lock(L); + fi = index2adr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val); + if (name) + { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + lua_unlock(L); + return name; } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lauxlib.c b/LuaNode_Esp32/LuaNode32/components/lua/lauxlib.c index b79f5c2..19b7b60 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lauxlib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lauxlib.c @@ -24,25 +24,22 @@ #define lauxlib_c #define LUA_LIB -#include "lrotable.h" - #include "lauxlib.h" -#include "lgc.h" #include "ldo.h" +#include "legc.h" +#include "lgc.h" #include "lobject.h" +#include "lrotable.h" #include "lstate.h" -#include "legc.h" - -#define FREELIST_REF 0 /* free list of references */ +#define FREELIST_REF 0 /* free list of references */ /* convert a stack index to positive */ -#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ - lua_gettop(L) + (i) + 1) +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1) // Parameters for luaI_openlib -#define LUA_USECCLOSURES 0 -#define LUA_USELIGHTFUNCTIONS 1 +#define LUA_USECCLOSURES 0 +#define LUA_USELIGHTFUNCTIONS 1 /* ** {====================================================== @@ -50,272 +47,276 @@ ** ======================================================= */ - -LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { - lua_Debug ar; - if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ - return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); - lua_getinfo(L, "n", &ar); - if (strcmp(ar.namewhat, "method") == 0) { - narg--; /* do not count `self' */ - if (narg == 0) /* error is in the self argument itself? */ - return luaL_error(L, "calling " LUA_QS " on bad self (%s)", - ar.name, extramsg); - } - if (ar.name == NULL) - ar.name = "?"; - return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", - narg, ar.name, extramsg); -} - - -LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { - const char *msg = lua_pushfstring(L, "%s expected, got %s", - tname, luaL_typename(L, narg)); - return luaL_argerror(L, narg, msg); -} - - -static void tag_error (lua_State *L, int narg, int tag) { - luaL_typerror(L, narg, lua_typename(L, tag)); -} - - -LUALIB_API void luaL_where (lua_State *L, int level) { - lua_Debug ar; - if (lua_getstack(L, level, &ar)) { /* check function at level */ - lua_getinfo(L, "Sl", &ar); /* get info about it */ - if (ar.currentline > 0) { /* is there info? */ - lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); - return; +LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *extramsg) +{ + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) + { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name, extramsg); +} + +LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *tname) +{ + const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + +static void tag_error(lua_State *L, int narg, int tag) { luaL_typerror(L, narg, lua_typename(L, tag)); } + +LUALIB_API void luaL_where(lua_State *L, int level) +{ + lua_Debug ar; + if (lua_getstack(L, level, &ar)) + { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) + { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } } - } - lua_pushliteral(L, ""); /* else, no information available... */ + lua_pushliteral(L, ""); /* else, no information available... */ } - -LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - luaL_where(L, 1); - lua_pushvfstring(L, fmt, argp); - va_end(argp); - lua_concat(L, 2); - return lua_error(L); +LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); } /* }====================================================== */ - -LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, - const char *const lst[]) { - const char *name = (def) ? luaL_optstring(L, narg, def) : - luaL_checkstring(L, narg); - int i; - for (i=0; lst[i]; i++) - if (strcmp(lst[i], name) == 0) - return i; - return luaL_argerror(L, narg, - lua_pushfstring(L, "invalid option " LUA_QS, name)); -} - - -LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ - if (!lua_isnil(L, -1)) /* name already in use? */ - return 0; /* leave previous value on top, but return 0 */ - lua_pop(L, 1); - lua_newtable(L); /* create metatable */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ - return 1; +LUALIB_API int luaL_checkoption(lua_State *L, int narg, const char *def, const char *const lst[]) +{ + const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); + int i; + for (i = 0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + +LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname) +{ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; } -LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) { - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ - if (!lua_isnil(L, -1)) /* name already in use? */ - return 0; /* leave previous value on top, but return 0 */ - lua_pop(L, 1); - lua_pushrotable(L, p); - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ - return 1; +LUALIB_API int luaL_rometatable(lua_State *L, const char *tname, void *p) +{ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_pushrotable(L, p); + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; } -LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { - void *p = lua_touserdata(L, ud); - if (p != NULL) { /* value is a userdata? */ - if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ - if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ - lua_pop(L, 2); /* remove both metatables */ - return p; - } +LUALIB_API void *luaL_checkudata(lua_State *L, int ud, const char *tname) +{ + void *p = lua_touserdata(L, ud); + if (p != NULL) + { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) + { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) + { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } } - } - luaL_typerror(L, ud, tname); /* else error */ - return NULL; /* to avoid warnings */ + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ } - -LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { - if (!lua_checkstack(L, space)) - luaL_error(L, "stack overflow (%s)", mes); +LUALIB_API void luaL_checkstack(lua_State *L, int space, const char *mes) +{ + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); } - -LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { - if (lua_type(L, narg) != t) - tag_error(L, narg, t); +LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) +{ + if (lua_type(L, narg) != t) + tag_error(L, narg, t); } -LUALIB_API void luaL_checkanyfunction (lua_State *L, int narg) { - if (lua_type(L, narg) != LUA_TFUNCTION && lua_type(L, narg) != LUA_TLIGHTFUNCTION) { - const char *msg = lua_pushfstring(L, "function or lightfunction expected, got %s", - luaL_typename(L, narg)); - luaL_argerror(L, narg, msg); - } +LUALIB_API void luaL_checkanyfunction(lua_State *L, int narg) +{ + if (lua_type(L, narg) != LUA_TFUNCTION && lua_type(L, narg) != LUA_TLIGHTFUNCTION) + { + const char *msg = lua_pushfstring(L, "function or lightfunction expected, got %s", luaL_typename(L, narg)); + luaL_argerror(L, narg, msg); + } } -LUALIB_API void luaL_checkanytable (lua_State *L, int narg) { - if (lua_type(L, narg) != LUA_TTABLE && lua_type(L, narg) != LUA_TROTABLE) { - const char *msg = lua_pushfstring(L, "table or rotable expected, got %s", - luaL_typename(L, narg)); - luaL_argerror(L, narg, msg); - } +LUALIB_API void luaL_checkanytable(lua_State *L, int narg) +{ + if (lua_type(L, narg) != LUA_TTABLE && lua_type(L, narg) != LUA_TROTABLE) + { + const char *msg = lua_pushfstring(L, "table or rotable expected, got %s", luaL_typename(L, narg)); + luaL_argerror(L, narg, msg); + } } - -LUALIB_API void luaL_checkany (lua_State *L, int narg) { - if (lua_type(L, narg) == LUA_TNONE) - luaL_argerror(L, narg, "value expected"); +LUALIB_API void luaL_checkany(lua_State *L, int narg) +{ + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); } - -LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { - const char *s = lua_tolstring(L, narg, len); - if (!s) tag_error(L, narg, LUA_TSTRING); - return s; +LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len) +{ + const char *s = lua_tolstring(L, narg, len); + if (!s) + tag_error(L, narg, LUA_TSTRING); + return s; } - -LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, - const char *def, size_t *len) { - if (lua_isnoneornil(L, narg)) { - if (len) - *len = (def ? strlen(def) : 0); - return def; - } - else return luaL_checklstring(L, narg, len); +LUALIB_API const char *luaL_optlstring(lua_State *L, int narg, const char *def, size_t *len) +{ + if (lua_isnoneornil(L, narg)) + { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else + return luaL_checklstring(L, narg, len); } - -LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { - lua_Number d = lua_tonumber(L, narg); - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ - tag_error(L, narg, LUA_TNUMBER); - return d; +LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg) +{ + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; } - -LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { - return luaL_opt(L, luaL_checknumber, narg, def); +LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def) +{ + return luaL_opt(L, luaL_checknumber, narg, def); } - -LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { - lua_Integer d = lua_tointeger(L, narg); - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ - tag_error(L, narg, LUA_TNUMBER); - return d; +LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg) +{ + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; } - -LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, - lua_Integer def) { - return luaL_opt(L, luaL_checkinteger, narg, def); +LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def) +{ + return luaL_opt(L, luaL_checkinteger, narg, def); } - -LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { - if (!lua_getmetatable(L, obj)) /* no metatable? */ - return 0; - lua_pushstring(L, event); - lua_rawget(L, -2); - if (lua_isnil(L, -1)) { - lua_pop(L, 2); /* remove metatable and metafield */ - return 0; - } - else { - lua_remove(L, -2); /* remove only metatable */ - return 1; - } +LUALIB_API int luaL_getmetafield(lua_State *L, int obj, const char *event) +{ + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) + { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else + { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } } - -LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { - obj = abs_index(L, obj); - if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ - return 0; - lua_pushvalue(L, obj); - lua_call(L, 1, 1); - return 1; +LUALIB_API int luaL_callmeta(lua_State *L, int obj, const char *event) +{ + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; } - -LUALIB_API void (luaL_register) (lua_State *L, const char *libname, - const luaL_Reg *l) { - luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES); +LUALIB_API void(luaL_register)(lua_State *L, const char *libname, const luaL_Reg *l) +{ + luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES); } -LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname, - const luaL_Reg *l) { -#if LUA_OPTIMIZE_MEMORY > 0 - luaI_openlib(L, libname, l, 0, LUA_USELIGHTFUNCTIONS); +LUALIB_API void(luaL_register_light)(lua_State *L, const char *libname, const luaL_Reg *l) +{ +#if LUA_OPTIMIZE_MEMORY > 0 + luaI_openlib(L, libname, l, 0, LUA_USELIGHTFUNCTIONS); #else - luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES); -#endif -} - -static int libsize (const luaL_Reg *l) { - int size = 0; - for (; l->name; l++) size++; - return size; -} - - -LUALIB_API void luaI_openlib (lua_State *L, const char *libname, - const luaL_Reg *l, int nup, int ftype) { - if (libname) { - int size = libsize(l); - /* check whether lib already exists */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); - lua_getfield(L, -1, libname); /* get _LOADED[libname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) - luaL_error(L, "name conflict for module " LUA_QS, libname); - lua_pushvalue(L, -1); - lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ - } - lua_remove(L, -2); /* remove _LOADED table */ - lua_insert(L, -(nup+1)); /* move library table to below upvalues */ - } - for (; l->name; l++) { - int i; - for (i=0; ifunc); - else - lua_pushcclosure(L, l->func, nup); - lua_setfield(L, -(nup+2), l->name); - } - lua_pop(L, nup); /* remove upvalues */ + luaI_openlib(L, libname, l, 0, LUA_USECCLOSURES); +#endif } - +static int libsize(const luaL_Reg *l) +{ + int size = 0; + for (; l->name; l++) size++; + return size; +} + +LUALIB_API void luaI_openlib(lua_State *L, const char *libname, const luaL_Reg *l, int nup, int ftype) +{ + if (libname) + { + int size = libsize(l); + /* check whether lib already exists */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); /* get _LOADED[libname] */ + if (!lua_istable(L, -1)) + { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ + } + for (; l->name; l++) + { + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + if (ftype == LUA_USELIGHTFUNCTIONS) + lua_pushlightfunction(L, l->func); + else + lua_pushcclosure(L, l->func, nup); + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} /* ** {====================================================== @@ -325,250 +326,263 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname, #if defined(LUA_COMPAT_GETN) -static int checkint (lua_State *L, int topop) { - int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; - lua_pop(L, topop); - return n; +static int checkint(lua_State *L, int topop) +{ + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; + lua_pop(L, topop); + return n; +} + +static void getsizes(lua_State *L) +{ + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); + if (lua_isnil(L, -1)) + { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ + } } - -static void getsizes (lua_State *L) { - lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); - if (lua_isnil(L, -1)) { /* no `size' table? */ - lua_pop(L, 1); /* remove nil */ - lua_newtable(L); /* create it */ - lua_pushvalue(L, -1); /* `size' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "kv"); - lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ - } -} - - -LUALIB_API void luaL_setn (lua_State *L, int t, int n) { - t = abs_index(L, t); - lua_pushliteral(L, "n"); - lua_rawget(L, t); - if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ - lua_pushliteral(L, "n"); /* use it */ - lua_pushinteger(L, n); - lua_rawset(L, t); - } - else { /* use `sizes' */ - getsizes(L); - lua_pushvalue(L, t); - lua_pushinteger(L, n); - lua_rawset(L, -3); /* sizes[t] = n */ - lua_pop(L, 1); /* remove `sizes' */ - } +LUALIB_API void luaL_setn(lua_State *L, int t, int n) +{ + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) + { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushinteger(L, n); + lua_rawset(L, t); + } + else + { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } } - -LUALIB_API int luaL_getn (lua_State *L, int t) { - int n; - t = abs_index(L, t); - lua_pushliteral(L, "n"); /* try t.n */ - lua_rawget(L, t); - if ((n = checkint(L, 1)) >= 0) return n; - getsizes(L); /* else try sizes[t] */ - lua_pushvalue(L, t); - lua_rawget(L, -2); - if ((n = checkint(L, 2)) >= 0) return n; - return (int)lua_objlen(L, t); +LUALIB_API int luaL_getn(lua_State *L, int t) +{ + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) + return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) + return n; + return (int)lua_objlen(L, t); } #endif /* }====================================================== */ - - -LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, - const char *r) { - const char *wild; - size_t l = strlen(p); - luaL_Buffer b; - luaL_buffinit(L, &b); - while ((wild = strstr(s, p)) != NULL) { - luaL_addlstring(&b, s, wild - s); /* push prefix */ - luaL_addstring(&b, r); /* push replacement in place of pattern */ - s = wild + l; /* continue after `p' */ - } - luaL_addstring(&b, s); /* push last suffix */ - luaL_pushresult(&b); - return lua_tostring(L, -1); -} - - -LUALIB_API const char *luaL_findtable (lua_State *L, int idx, - const char *fname, int szhint) { - const char *e; - lua_pushvalue(L, idx); - do { - e = strchr(fname, '.'); - if (e == NULL) e = fname + strlen(fname); - lua_pushlstring(L, fname, e - fname); - lua_rawget(L, -2); - if (lua_isnil(L, -1)) { - /* If looking for a global variable, check the rotables too */ - void *ptable = luaR_findglobal(fname, e - fname); - if (ptable) { - lua_pop(L, 1); - lua_pushrotable(L, ptable); - } - } - if (lua_isnil(L, -1)) { /* no such field? */ - lua_pop(L, 1); /* remove this nil */ - lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ - lua_pushlstring(L, fname, e - fname); - lua_pushvalue(L, -2); - lua_settable(L, -4); /* set new table into field */ +LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, const char *p, const char *r) +{ + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) + { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ } - else if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) { /* field has a non-table value? */ - lua_pop(L, 2); /* remove table and value */ - return fname; /* return problematic part of the name */ - } - lua_remove(L, -2); /* remove previous table */ - fname = e + 1; - } while (*e == '.'); - return NULL; + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + +LUALIB_API const char *luaL_findtable(lua_State *L, int idx, const char *fname, int szhint) +{ + const char *e; + lua_pushvalue(L, idx); + do + { + e = strchr(fname, '.'); + if (e == NULL) + e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) + { + /* If looking for a global variable, check the rotables too */ + void *ptable = luaR_findglobal(fname, e - fname); + if (ptable) + { + lua_pop(L, 1); + lua_pushrotable(L, ptable); + } + } + if (lua_isnil(L, -1)) + { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) + { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; } - - /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) -#define bufflen(B) ((B)->p - (B)->buffer) -#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) - -#define LIMIT (LUA_MINSTACK/2) +#define LIMIT (LUA_MINSTACK / 2) - -static int emptybuffer (luaL_Buffer *B) { - size_t l = bufflen(B); - if (l == 0) return 0; /* put nothing on stack */ - else { - lua_pushlstring(B->L, B->buffer, l); - B->p = B->buffer; - B->lvl++; - return 1; - } -} - - -static void adjuststack (luaL_Buffer *B) { - if (B->lvl > 1) { - lua_State *L = B->L; - int toget = 1; /* number of levels to concat */ - size_t toplen = lua_strlen(L, -1); - do { - size_t l = lua_strlen(L, -(toget+1)); - if (B->lvl - toget + 1 >= LIMIT || toplen > l) { - toplen += l; - toget++; - } - else break; - } while (toget < B->lvl); - lua_concat(L, toget); - B->lvl = B->lvl - toget + 1; - } +static int emptybuffer(luaL_Buffer *B) +{ + size_t l = bufflen(B); + if (l == 0) + return 0; /* put nothing on stack */ + else + { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } } - -LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { - if (emptybuffer(B)) - adjuststack(B); - return B->buffer; +static void adjuststack(luaL_Buffer *B) +{ + if (B->lvl > 1) + { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do + { + size_t l = lua_strlen(L, -(toget + 1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) + { + toplen += l; + toget++; + } + else + break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } } - -LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { - while (l--) - luaL_addchar(B, *s++); +LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B) +{ + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; } - -LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { - luaL_addlstring(B, s, strlen(s)); +LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l) +{ + while (l--) luaL_addchar(B, *s++); } +LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s) { luaL_addlstring(B, s, strlen(s)); } -LUALIB_API void luaL_pushresult (luaL_Buffer *B) { - emptybuffer(B); - lua_concat(B->L, B->lvl); - B->lvl = 1; +LUALIB_API void luaL_pushresult(luaL_Buffer *B) +{ + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; } - -LUALIB_API void luaL_addvalue (luaL_Buffer *B) { - lua_State *L = B->L; - size_t vl; - const char *s = lua_tolstring(L, -1, &vl); - if (vl <= bufffree(B)) { /* fit into buffer? */ - memcpy(B->p, s, vl); /* put it there */ - B->p += vl; - lua_pop(L, 1); /* remove from stack */ - } - else { - if (emptybuffer(B)) - lua_insert(L, -2); /* put buffer before new value */ - B->lvl++; /* add new value into B stack */ - adjuststack(B); - } +LUALIB_API void luaL_addvalue(luaL_Buffer *B) +{ + lua_State *L = B->L; + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); + if (vl <= bufffree(B)) + { /* fit into buffer? */ + memcpy(B->p, s, vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else + { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } } - -LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { - B->L = L; - B->p = B->buffer; - B->lvl = 0; +LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B) +{ + B->L = L; + B->p = B->buffer; + B->lvl = 0; } /* }====================================================== */ - -LUALIB_API int luaL_ref (lua_State *L, int t) { - int ref; - t = abs_index(L, t); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* remove from stack */ - return LUA_REFNIL; /* `nil' has a unique fixed reference */ - } - lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ - ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ - lua_pop(L, 1); /* remove it from stack */ - if (ref != 0) { /* any free element? */ - lua_rawgeti(L, t, ref); /* remove it from list */ - lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ - } - else { /* no free elements */ - ref = (int)lua_objlen(L, t); - ref++; /* create new reference */ - } - lua_rawseti(L, t, ref); - return ref; -} - - -LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { - if (ref >= 0) { +LUALIB_API int luaL_ref(lua_State *L, int t) +{ + int ref; t = abs_index(L, t); - lua_rawgeti(L, t, FREELIST_REF); - lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ - lua_pushinteger(L, ref); - lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ - } + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) + { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else + { /* no free elements */ + ref = (int)lua_objlen(L, t); + ref++; /* create new reference */ + } + lua_rawseti(L, t, ref); + return ref; +} + +LUALIB_API void luaL_unref(lua_State *L, int t, int ref) +{ + if (ref >= 0) + { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } } - - /* ** {====================================================== ** Load functions @@ -577,257 +591,288 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { #ifdef LUA_CROSS_COMPILER -typedef struct LoadF { - int extraline; - FILE *f; - char buff[LUAL_BUFFERSIZE]; +typedef struct LoadF +{ + int extraline; + FILE *f; + char buff[LUAL_BUFFERSIZE]; } LoadF; - -static const char *getF (lua_State *L, void *ud, size_t *size) { - LoadF *lf = (LoadF *)ud; - (void)L; - if (lf->extraline) { - lf->extraline = 0; - *size = 1; - return "\n"; - } - if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); - return (*size > 0) ? lf->buff : NULL; -} - - -static int errfile (lua_State *L, const char *what, int fnameindex) { - const char *serr = strerror(errno); - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); - lua_remove(L, fnameindex); - return LUA_ERRFILE; -} - - -LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { - LoadF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - lf.extraline = 0; - if (filename == NULL) { - lua_pushliteral(L, "=stdin"); - lf.f = stdin; - } - else { - lua_pushfstring(L, "@%s", filename); - lf.f = fopen(filename, "r"); - if (lf.f == NULL) return errfile(L, "open", fnameindex); - } - c = getc(lf.f); - if (c == '#') { /* Unix exec. file? */ - lf.extraline = 1; - while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ - if (c == '\n') c = getc(lf.f); - } - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ - lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ - if (lf.f == NULL) return errfile(L, "reopen", fnameindex); - /* skip eventual `#!...' */ - while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; +static const char *getF(lua_State *L, void *ud, size_t *size) +{ + LoadF *lf = (LoadF *)ud; + (void)L; + if (lf->extraline) + { + lf->extraline = 0; + *size = 1; + return "\n"; + } + if (feof(lf->f)) + return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); + return (*size > 0) ? lf->buff : NULL; +} + +static int errfile(lua_State *L, const char *what, int fnameindex) +{ + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + +LUALIB_API int luaL_loadfile(lua_State *L, const char *filename) +{ + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ lf.extraline = 0; - } - ungetc(c, lf.f); - status = lua_load(L, getF, &lf, lua_tostring(L, -1)); - readstatus = ferror(lf.f); - if (filename) fclose(lf.f); /* close file (even in case of errors) */ - if (readstatus) { - lua_settop(L, fnameindex); /* ignore results from `lua_load' */ - return errfile(L, "read", fnameindex); - } - lua_remove(L, fnameindex); - return status; + if (filename == NULL) + { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else + { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) + return errfile(L, "open", fnameindex); + } + c = getc(lf.f); + if (c == '#') + { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = getc(lf.f)) != EOF && c != '\n') + ; /* skip first line */ + if (c == '\n') + c = getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) + { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) + return errfile(L, "reopen", fnameindex); + /* skip eventual `#!...' */ + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) + ; + lf.extraline = 0; + } + ungetc(c, lf.f); + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = ferror(lf.f); + if (filename) + fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) + { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; } #else #include C_HEADER_FCNTL -typedef struct LoadFSF { - int extraline; - int f; - char buff[LUAL_BUFFERSIZE]; +typedef struct LoadFSF +{ + int extraline; + int f; + char buff[LUAL_BUFFERSIZE]; } LoadFSF; +static const char *getFSF(lua_State *L, void *ud, size_t *size) +{ + LoadFSF *lf = (LoadFSF *)ud; + (void)L; -static const char *getFSF (lua_State *L, void *ud, size_t *size) { - LoadFSF *lf = (LoadFSF *)ud; - (void)L; + if (L == NULL && size == NULL) // Direct mode check + return NULL; - if (L == NULL && size == NULL) // Direct mode check - return NULL; + if (lf->extraline) + { + lf->extraline = 0; + *size = 1; + return "\n"; + } - if (lf->extraline) { - lf->extraline = 0; - *size = 1; - return "\n"; - } - - if (vfs_eof(lf->f)) return NULL; - *size = vfs_read(lf->f, lf->buff, sizeof(lf->buff)); - - return (*size > 0) ? lf->buff : NULL; -} - - -static int errfsfile (lua_State *L, const char *what, int fnameindex) { - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot %s %s", what, filename); - lua_remove(L, fnameindex); - return LUA_ERRFILE; -} - - -LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) { - LoadFSF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - lf.extraline = 0; - if (filename == NULL) { - return luaL_error(L, "filename is NULL"); - } - else { - lua_pushfstring(L, "@%s", filename); - lf.f = vfs_open(filename, "r"); - if (!lf.f) return errfsfile(L, "open", fnameindex); - } - // if(vfs_size(lf.f)>LUAL_BUFFERSIZE) - // return luaL_error(L, "file is too big"); - c = vfs_getc(lf.f); - if (c == '#') { /* Unix exec. file? */ - lf.extraline = 1; - while ((c = vfs_getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ - if (c == '\n') c = vfs_getc(lf.f); - } - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ - vfs_close(lf.f); - lf.f = vfs_open(filename, "r"); /* reopen in binary mode */ - if (!lf.f) return errfsfile(L, "reopen", fnameindex); - /* skip eventual `#!...' */ - while ((c = vfs_getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; - lf.extraline = 0; - } - vfs_ungetc(c, lf.f); - status = lua_load(L, getFSF, &lf, lua_tostring(L, -1)); + if (vfs_eof(lf->f)) + return NULL; + *size = vfs_read(lf->f, lf->buff, sizeof(lf->buff)); - if (filename) vfs_close(lf.f); /* close file (even in case of errors) */ - lua_remove(L, fnameindex); - return status; + return (*size > 0) ? lf->buff : NULL; } -#endif - -typedef struct LoadS { - const char *s; - size_t size; -} LoadS; - - -static const char *getS (lua_State *L, void *ud, size_t *size) { - LoadS *ls = (LoadS *)ud; - (void)L; - if (L == NULL && size == NULL) // direct mode check - return NULL; - if (ls->size == 0) return NULL; - *size = ls->size; - ls->size = 0; - return ls->s; +static int errfsfile(lua_State *L, const char *what, int fnameindex) +{ + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s", what, filename); + lua_remove(L, fnameindex); + return LUA_ERRFILE; } +LUALIB_API int luaL_loadfsfile(lua_State *L, const char *filename) +{ + LoadFSF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; + if (filename == NULL) + { + return luaL_error(L, "filename is NULL"); + } + else + { + lua_pushfstring(L, "@%s", filename); + lf.f = vfs_open(filename, "r"); + if (!lf.f) + return errfsfile(L, "open", fnameindex); + } + // if(vfs_size(lf.f)>LUAL_BUFFERSIZE) + // return luaL_error(L, "file is too big"); + c = vfs_getc(lf.f); + if (c == '#') + { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = vfs_getc(lf.f)) != EOF && c != '\n') + ; /* skip first line */ + if (c == '\n') + c = vfs_getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) + { /* binary file? */ + vfs_close(lf.f); + lf.f = vfs_open(filename, "r"); /* reopen in binary mode */ + if (!lf.f) + return errfsfile(L, "reopen", fnameindex); + /* skip eventual `#!...' */ + while ((c = vfs_getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) + ; + lf.extraline = 0; + } + vfs_ungetc(c, lf.f); + status = lua_load(L, getFSF, &lf, lua_tostring(L, -1)); -LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, - const char *name) { - LoadS ls; - ls.s = buff; - ls.size = size; - return lua_load(L, getS, &ls, name); + if (filename) + vfs_close(lf.f); /* close file (even in case of errors) */ + lua_remove(L, fnameindex); + return status; } +#endif + +typedef struct LoadS +{ + const char *s; + size_t size; +} LoadS; -LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { - return luaL_loadbuffer(L, s, strlen(s), s); +static const char *getS(lua_State *L, void *ud, size_t *size) +{ + LoadS *ls = (LoadS *)ud; + (void)L; + if (L == NULL && size == NULL) // direct mode check + return NULL; + if (ls->size == 0) + return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; } +LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buff, size_t size, const char *name) +{ + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} +LUALIB_API int(luaL_loadstring)(lua_State *L, const char *s) { return luaL_loadbuffer(L, s, strlen(s), s); } /* }====================================================== */ - -static int l_check_memlimit(lua_State *L, size_t needbytes) { - global_State *g = G(L); - int cycle_count = 0; - lu_mem limit = g->memlimit - needbytes; - /* don't allow allocation if it requires more memory then the total limit. */ - if (needbytes > g->memlimit) return 1; - /* make sure the GC is not disabled. */ - if (!is_block_gc(L)) { - while (g->totalbytes >= limit) { - /* only allow the GC to finished atleast 1 full cycle. */ - if (g->gcstate == GCSpause && ++cycle_count > 1) break; - luaC_step(L); +static int l_check_memlimit(lua_State *L, size_t needbytes) +{ + global_State *g = G(L); + int cycle_count = 0; + lu_mem limit = g->memlimit - needbytes; + /* don't allow allocation if it requires more memory then the total limit. + */ + if (needbytes > g->memlimit) + return 1; + /* make sure the GC is not disabled. */ + if (!is_block_gc(L)) + { + while (g->totalbytes >= limit) + { + /* only allow the GC to finished atleast 1 full cycle. */ + if (g->gcstate == GCSpause && ++cycle_count > 1) + break; + luaC_step(L); + } } - } - return (g->totalbytes >= limit) ? 1 : 0; + return (g->totalbytes >= limit) ? 1 : 0; } +static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) +{ + lua_State *L = (lua_State *)ud; + int mode = L == NULL ? 0 : G(L)->egcmode; + void *nptr; -static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { - lua_State *L = (lua_State *)ud; - int mode = L == NULL ? 0 : G(L)->egcmode; - void *nptr; - - if (nsize == 0) { - free(ptr); - return NULL; - } - if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */ - luaC_fullgc(L); - if(nsize > osize && L != NULL) { + if (nsize == 0) + { + free(ptr); + return NULL; + } + if (L != NULL && (mode & EGC_ALWAYS)) /* always collect memory if requested */ + luaC_fullgc(L); + if (nsize > osize && L != NULL) + { #if defined(LUA_STRESS_EMERGENCY_GC) - luaC_fullgc(L); + luaC_fullgc(L); #endif - if(G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize)) - return NULL; - } - nptr = (void *)realloc(ptr, nsize); - if (nptr == NULL && L != NULL && (mode & EGC_ON_ALLOC_FAILURE)) { - luaC_fullgc(L); /* emergency full collection. */ - nptr = (void *)realloc(ptr, nsize); /* try allocation again */ - } - return nptr; + if (G(L)->memlimit > 0 && (mode & EGC_ON_MEM_LIMIT) && l_check_memlimit(L, nsize - osize)) + return NULL; + } + nptr = (void *)realloc(ptr, nsize); + if (nptr == NULL && L != NULL && (mode & EGC_ON_ALLOC_FAILURE)) + { + luaC_fullgc(L); /* emergency full collection. */ + nptr = (void *)realloc(ptr, nsize); /* try allocation again */ + } + return nptr; } -LUALIB_API void luaL_assertfail(const char *file, int line, const char *message) { - printf("ASSERT@%s(%d): %s\n", file, line, message); +LUALIB_API void luaL_assertfail(const char *file, int line, const char *message) +{ + printf("ASSERT@%s(%d): %s\n", file, line, message); } -static int panic (lua_State *L) { - (void)L; /* to avoid warnings */ +static int panic(lua_State *L) +{ + (void)L; /* to avoid warnings */ #if defined(LUA_USE_STDIO) - fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", - lua_tostring(L, -1)); + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); #else - luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", - lua_tostring(L, -1)); + luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); #endif - while (1) {} - return 0; + while (1) {} + return 0; } - -LUALIB_API lua_State *luaL_newstate (void) { - lua_State *L = lua_newstate(l_alloc, NULL); - lua_setallocf(L, l_alloc, L); /* allocator need lua_State. */ - if (L) lua_atpanic(L, &panic); - return L; +LUALIB_API lua_State *luaL_newstate(void) +{ + lua_State *L = lua_newstate(l_alloc, NULL); + lua_setallocf(L, l_alloc, L); /* allocator need lua_State. */ + if (L) + lua_atpanic(L, &panic); + return L; } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lbaselib.c b/LuaNode_Esp32/LuaNode32/components/lua/lbaselib.c index 878079a..7713ffc 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lbaselib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lbaselib.c @@ -4,8 +4,6 @@ ** See Copyright Notice in lua.h */ - - #define lbaselib_c #define LUA_LIB #define LUAC_CROSS_FILE @@ -15,11 +13,8 @@ #include C_HEADER_STRING #include C_HEADER_STDLIB #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" - - - +#include "lualib.h" /* ** If your system does not support `stdout', you can just remove this function. @@ -27,496 +22,516 @@ ** model but changing `fputs' to put the strings at a proper place ** (a console window or a log file, for instance). */ -static int luaB_print (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - lua_getglobal(L, "tostring"); - for (i=1; i<=n; i++) { - const char *s; - lua_pushvalue(L, -1); /* function to be called */ - lua_pushvalue(L, i); /* value to print */ - lua_call(L, 1, 1); - s = lua_tostring(L, -1); /* get result */ - if (s == NULL) - return luaL_error(L, LUA_QL("tostring") " must return a string to " - LUA_QL("print")); +static int luaB_print(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i = 1; i <= n; i++) + { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("print")); #if defined(LUA_USE_STDIO) - if (i>1) fputs("\t", stdout); - fputs(s, stdout); + if (i > 1) + fputs("\t", stdout); + fputs(s, stdout); #else - if (i>1) luai_writestring("\t", 1); - luai_writestring(s, strlen(s)); + if (i > 1) + luai_writestring("\t", 1); + luai_writestring(s, strlen(s)); #endif - lua_pop(L, 1); /* pop result */ - } + lua_pop(L, 1); /* pop result */ + } #if defined(LUA_USE_STDIO) - fputs("\n", stdout); + fputs("\n", stdout); #else - luai_writeline(); + luai_writeline(); #endif - return 0; + return 0; } - -static int luaB_tonumber (lua_State *L) { - int base = luaL_optint(L, 2, 10); - if (base == 10) { /* standard conversion */ - luaL_checkany(L, 1); - if (lua_isnumber(L, 1)) { - lua_pushnumber(L, lua_tonumber(L, 1)); - return 1; +static int luaB_tonumber(lua_State *L) +{ + int base = luaL_optint(L, 2, 10); + if (base == 10) + { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) + { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } } - } - else { - const char *s1 = luaL_checkstring(L, 1); - char *s2; - unsigned long n; - luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); - n = strtoul(s1, &s2, base); - if (s1 != s2) { /* at least one valid digit? */ - while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ - if (*s2 == '\0') { /* no invalid trailing characters? */ - lua_pushnumber(L, (lua_Number)n); - return 1; - } + else + { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) + { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') + { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } } - } - lua_pushnil(L); /* else not a number */ - return 1; -} - - -static int luaB_error (lua_State *L) { - int level = luaL_optint(L, 2, 1); - lua_settop(L, 1); - if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ - luaL_where(L, level); - lua_pushvalue(L, 1); - lua_concat(L, 2); - } - return lua_error(L); + lua_pushnil(L); /* else not a number */ + return 1; } - -static int luaB_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); - return 1; /* no metatable */ - } - luaL_getmetafield(L, 1, "__metatable"); - return 1; /* returns either __metatable field (if present) or metatable */ +static int luaB_error(lua_State *L) +{ + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) + { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); } - -static int luaB_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE || t == LUA_TROTABLE, 2, - "nil or table expected"); - if (luaL_getmetafield(L, 1, "__metatable")) - luaL_error(L, "cannot change a protected metatable"); - lua_settop(L, 2); - lua_setmetatable(L, 1); - return 1; +static int luaB_getmetatable(lua_State *L) +{ + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) + { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + +static int luaB_setmetatable(lua_State *L) +{ + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE || t == LUA_TROTABLE, 2, "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; } - -static void getfunc (lua_State *L, int opt) { - if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); - else { - lua_Debug ar; - int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); - luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); - if (lua_getstack(L, level, &ar) == 0) - luaL_argerror(L, 1, "invalid level"); - lua_getinfo(L, "f", &ar); - if (lua_isnil(L, -1)) - luaL_error(L, "no function environment for tail call at level %d", - level); - } +static void getfunc(lua_State *L, int opt) +{ + if (lua_isfunction(L, 1)) + lua_pushvalue(L, 1); + else + { + lua_Debug ar; + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", level); + } } - -static int luaB_getfenv (lua_State *L) { - getfunc(L, 1); - if (lua_iscfunction(L, -1)) /* is a C function? */ - lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ - else - lua_getfenv(L, -1); - return 1; +static int luaB_getfenv(lua_State *L) +{ + getfunc(L, 1); + if (lua_iscfunction(L, -1)) /* is a C function? */ + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ + else + lua_getfenv(L, -1); + return 1; } - -static int luaB_setfenv (lua_State *L) { - luaL_checktype(L, 2, LUA_TTABLE); - getfunc(L, 0); - lua_pushvalue(L, 2); - if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { - /* change environment of current thread */ - lua_pushthread(L); - lua_insert(L, -2); - lua_setfenv(L, -2); - return 0; - } - else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) - luaL_error(L, - LUA_QL("setfenv") " cannot change environment of given object"); - return 1; +static int luaB_setfenv(lua_State *L) +{ + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) + { + /* change environment of current thread */ + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, LUA_QL("setfenv") " cannot change environment of given object"); + return 1; } - -static int luaB_rawequal (lua_State *L) { - luaL_checkany(L, 1); - luaL_checkany(L, 2); - lua_pushboolean(L, lua_rawequal(L, 1, 2)); - return 1; +static int luaB_rawequal(lua_State *L) +{ + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; } - -static int luaB_rawget (lua_State *L) { - luaL_checkanytable(L, 1); - luaL_checkany(L, 2); - lua_settop(L, 2); - lua_rawget(L, 1); - return 1; +static int luaB_rawget(lua_State *L) +{ + luaL_checkanytable(L, 1); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; } -static int luaB_rawset (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - luaL_checkany(L, 3); - lua_settop(L, 3); - lua_rawset(L, 1); - return 1; +static int luaB_rawset(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; } - -static int luaB_gcinfo (lua_State *L) { - lua_pushinteger(L, lua_getgccount(L)); - return 1; +static int luaB_gcinfo(lua_State *L) +{ + lua_pushinteger(L, lua_getgccount(L)); + return 1; } - -static int luaB_collectgarbage (lua_State *L) { - static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpause", "setstepmul","setmemlimit","getmemlimit", NULL}; - static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, - LUA_GCSETMEMLIMIT,LUA_GCGETMEMLIMIT}; - int o = luaL_checkoption(L, 1, "collect", opts); - int ex = luaL_optint(L, 2, 0); - int res = lua_gc(L, optsnum[o], ex); - switch (optsnum[o]) { - case LUA_GCCOUNT: { - int b = lua_gc(L, LUA_GCCOUNTB, 0); - lua_pushnumber(L, res + ((lua_Number)b/1024)); - return 1; - } - case LUA_GCSTEP: { - lua_pushboolean(L, res); - return 1; +static int luaB_collectgarbage(lua_State *L) +{ + static const char *const opts[] = {"stop", "restart", "collect", "count", "step", + "setpause", "setstepmul", "setmemlimit", "getmemlimit", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCSTEP, + LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCSETMEMLIMIT, LUA_GCGETMEMLIMIT}; + int o = luaL_checkoption(L, 1, "collect", opts); + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, optsnum[o], ex); + switch (optsnum[o]) + { + case LUA_GCCOUNT: + { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b / 1024)); + return 1; + } + case LUA_GCSTEP: + { + lua_pushboolean(L, res); + return 1; + } + default: + { + lua_pushnumber(L, res); + return 1; + } } - default: { - lua_pushnumber(L, res); - return 1; - } - } } - -static int luaB_type (lua_State *L) { - luaL_checkany(L, 1); - lua_pushstring(L, luaL_typename(L, 1)); - return 1; -} - - -static int luaB_next (lua_State *L) { - luaL_checkanytable(L, 1); - lua_settop(L, 2); /* create a 2nd argument if there isn't one */ - if (lua_next(L, 1)) - return 2; - else { - lua_pushnil(L); +static int luaB_type(lua_State *L) +{ + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); return 1; - } } - -static int luaB_pairs (lua_State *L) { - luaL_checkanytable(L, 1); - lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushnil(L); /* and initial value */ - return 3; +static int luaB_next(lua_State *L) +{ + luaL_checkanytable(L, 1); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else + { + lua_pushnil(L); + return 1; + } } - -static int ipairsaux (lua_State *L) { - int i = luaL_checkint(L, 2); - luaL_checkanytable(L, 1); - i++; /* next value */ - lua_pushinteger(L, i); - lua_rawgeti(L, 1, i); - return (lua_isnil(L, -1)) ? 0 : 2; +static int luaB_pairs(lua_State *L) +{ + luaL_checkanytable(L, 1); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; } - -static int luaB_ipairs (lua_State *L) { - luaL_checkanytable(L, 1); - lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushinteger(L, 0); /* and initial value */ - return 3; +static int ipairsaux(lua_State *L) +{ + int i = luaL_checkint(L, 2); + luaL_checkanytable(L, 1); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; } - -static int load_aux (lua_State *L, int status) { - if (status == 0) /* OK? */ - return 1; - else { - lua_pushnil(L); - lua_insert(L, -2); /* put before error message */ - return 2; /* return nil plus error message */ - } +static int luaB_ipairs(lua_State *L) +{ + luaL_checkanytable(L, 1); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushinteger(L, 0); /* and initial value */ + return 3; } - -static int luaB_loadstring (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - const char *chunkname = luaL_optstring(L, 2, s); - return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +static int load_aux(lua_State *L, int status) +{ + if (status == 0) /* OK? */ + return 1; + else + { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } } +static int luaB_loadstring(lua_State *L) +{ + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} -static int luaB_loadfile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); +static int luaB_loadfile(lua_State *L) +{ + const char *fname = luaL_optstring(L, 1, NULL); #ifdef LUA_CROSS_COMPILER - return load_aux(L, luaL_loadfile(L, fname)); + return load_aux(L, luaL_loadfile(L, fname)); #else - return load_aux(L, luaL_loadfsfile(L, fname)); + return load_aux(L, luaL_loadfsfile(L, fname)); #endif } - /* ** Reader for generic `load' function: `lua_load' uses the ** stack for internal stuff, so the reader cannot change the ** stack top. Instead, it keeps its resulting string in a ** reserved slot inside the stack. */ -static const char *generic_reader (lua_State *L, void *ud, size_t *size) { - (void)ud; /* to avoid warnings */ - if (L == NULL && size == NULL) // direct mode check, doesn't happen - return NULL; - luaL_checkstack(L, 2, "too many nested functions"); - lua_pushvalue(L, 1); /* get function */ - lua_call(L, 0, 1); /* call it */ - if (lua_isnil(L, -1)) { - *size = 0; - return NULL; - } - else if (lua_isstring(L, -1)) { - lua_replace(L, 3); /* save string in a reserved stack slot */ - return lua_tolstring(L, 3, size); - } - else luaL_error(L, "reader function must return a string"); - return NULL; /* to avoid warnings */ -} - - -static int luaB_load (lua_State *L) { - int status; - const char *cname = luaL_optstring(L, 2, "=(load)"); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ - status = lua_load(L, generic_reader, NULL, cname); - return load_aux(L, status); -} - - -static int luaB_dofile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - int n = lua_gettop(L); +static const char *generic_reader(lua_State *L, void *ud, size_t *size) +{ + (void)ud; /* to avoid warnings */ + if (L == NULL && size == NULL) // direct mode check, doesn't happen + return NULL; + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) + { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) + { + lua_replace(L, 3); /* save string in a reserved stack slot */ + return lua_tolstring(L, 3, size); + } + else + luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + +static int luaB_load(lua_State *L) +{ + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ + status = lua_load(L, generic_reader, NULL, cname); + return load_aux(L, status); +} + +static int luaB_dofile(lua_State *L) +{ + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); #ifdef LUA_CROSS_COMPILER - if (luaL_loadfile(L, fname) != 0) lua_error(L); + if (luaL_loadfile(L, fname) != 0) + lua_error(L); #else - if (luaL_loadfsfile(L, fname) != 0) lua_error(L); + if (luaL_loadfsfile(L, fname) != 0) + lua_error(L); #endif - lua_call(L, 0, LUA_MULTRET); - return lua_gettop(L) - n; + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; } - -static int luaB_assert (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_toboolean(L, 1)) - return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); - return lua_gettop(L); +static int luaB_assert(lua_State *L) +{ + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + +static int luaB_unpack(lua_State *L) +{ + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) + return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + +static int luaB_select(lua_State *L) +{ + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') + { + lua_pushinteger(L, n - 1); + return 1; + } + else + { + int i = luaL_checkint(L, 1); + if (i < 0) + i = n + i; + else if (i > n) + i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } } - -static int luaB_unpack (lua_State *L) { - int i, e, n; - luaL_checktype(L, 1, LUA_TTABLE); - i = luaL_optint(L, 2, 1); - e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); - if (i > e) return 0; /* empty range */ - n = e - i + 1; /* number of elements */ - if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ - return luaL_error(L, "too many results to unpack"); - lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ - while (i++ < e) /* push arg[i + 1...e] */ - lua_rawgeti(L, 1, i); - return n; +static int luaB_pcall(lua_State *L) +{ + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + +static int luaB_xpcall(lua_State *L) +{ + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + +static int luaB_tostring(lua_State *L) +{ + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) + { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + break; + case LUA_TSTRING: + lua_pushvalue(L, 1); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); + break; + } + return 1; } - -static int luaB_select (lua_State *L) { - int n = lua_gettop(L); - if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { - lua_pushinteger(L, n-1); +static int luaB_newproxy(lua_State *L) +{ + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) + { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else + { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) + { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); return 1; - } - else { - int i = luaL_checkint(L, 1); - if (i < 0) i = n + i; - else if (i > n) i = n; - luaL_argcheck(L, 1 <= i, 1, "index out of range"); - return n - i; - } -} - - -static int luaB_pcall (lua_State *L) { - int status; - luaL_checkany(L, 1); - status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); - lua_pushboolean(L, (status == 0)); - lua_insert(L, 1); - return lua_gettop(L); /* return status + all results */ -} - - -static int luaB_xpcall (lua_State *L) { - int status; - luaL_checkany(L, 2); - lua_settop(L, 2); - lua_insert(L, 1); /* put error function under function to be called */ - status = lua_pcall(L, 0, LUA_MULTRET, 1); - lua_pushboolean(L, (status == 0)); - lua_replace(L, 1); - return lua_gettop(L); /* return status + all results */ -} - - -static int luaB_tostring (lua_State *L) { - luaL_checkany(L, 1); - if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ - return 1; /* use its value */ - switch (lua_type(L, 1)) { - case LUA_TNUMBER: - lua_pushstring(L, lua_tostring(L, 1)); - break; - case LUA_TSTRING: - lua_pushvalue(L, 1); - break; - case LUA_TBOOLEAN: - lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); - break; - case LUA_TNIL: - lua_pushliteral(L, "nil"); - break; - default: - lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); - break; - } - return 1; -} - - -static int luaB_newproxy (lua_State *L) { - lua_settop(L, 1); - lua_newuserdata(L, 0); /* create proxy */ - if (lua_toboolean(L, 1) == 0) - return 1; /* no metatable */ - else if (lua_isboolean(L, 1)) { - lua_newtable(L); /* create a new metatable `m' ... */ - lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ - lua_pushboolean(L, 1); - lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ - } - else { - int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ - if (lua_getmetatable(L, 1)) { - lua_rawget(L, lua_upvalueindex(1)); - validproxy = lua_toboolean(L, -1); - lua_pop(L, 1); /* remove value */ +} + +#define LUA_BASELIB_FUNCLIST \ + {LSTRKEY("assert"), LFUNCVAL(luaB_assert)}, {LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)}, \ + {LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)}, {LSTRKEY("error"), LFUNCVAL(luaB_error)}, \ + {LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)}, {LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)}, \ + {LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)}, {LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)}, \ + {LSTRKEY("load"), LFUNCVAL(luaB_load)}, {LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)}, \ + {LSTRKEY("next"), LFUNCVAL(luaB_next)}, {LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)}, \ + {LSTRKEY("print"), LFUNCVAL(luaB_print)}, {LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)}, \ + {LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)}, {LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)}, \ + {LSTRKEY("select"), LFUNCVAL(luaB_select)}, {LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)}, \ + {LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)}, {LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)}, \ + {LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)}, {LSTRKEY("type"), LFUNCVAL(luaB_type)}, \ + {LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)}, \ + { \ + LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall) \ } - luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); - lua_getmetatable(L, 1); /* metatable is valid; get it */ - } - lua_setmetatable(L, 2); - return 1; -} - -#define LUA_BASELIB_FUNCLIST\ - {LSTRKEY("assert"), LFUNCVAL(luaB_assert)},\ - {LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)},\ - {LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)},\ - {LSTRKEY("error"), LFUNCVAL(luaB_error)},\ - {LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)},\ - {LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)},\ - {LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)},\ - {LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)},\ - {LSTRKEY("load"), LFUNCVAL(luaB_load)},\ - {LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)},\ - {LSTRKEY("next"), LFUNCVAL(luaB_next)},\ - {LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)},\ - {LSTRKEY("print"), LFUNCVAL(luaB_print)},\ - {LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)},\ - {LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)},\ - {LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)},\ - {LSTRKEY("select"), LFUNCVAL(luaB_select)},\ - {LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)},\ - {LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)},\ - {LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)},\ - {LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)},\ - {LSTRKEY("type"), LFUNCVAL(luaB_type)},\ - {LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)},\ - {LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall)} - + #if LUA_OPTIMIZE_MEMORY == 2 #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 2 #include "lrodefs.h" -const LUA_REG_TYPE base_funcs_list[] = { - LUA_BASELIB_FUNCLIST, - {LNILKEY, LNILVAL} -}; +const LUA_REG_TYPE base_funcs_list[] = {LUA_BASELIB_FUNCLIST, {LNILKEY, LNILVAL}}; #endif - -static int luaB_index(lua_State *L) { +static int luaB_index(lua_State *L) +{ #if LUA_OPTIMIZE_MEMORY == 2 - int fres; - if ((fres = luaR_findfunction(L, base_funcs_list)) != 0) - return fres; -#endif - const char *keyname = luaL_checkstring(L, 2); - if (!strcmp(keyname, "_VERSION")) { - lua_pushliteral(L, LUA_VERSION); - return 1; - } - void *res = luaR_findglobal(keyname, strlen(keyname)); - if (!res) - return 0; - else { - lua_pushrotable(L, res); - return 1; - } + int fres; + if ((fres = luaR_findfunction(L, base_funcs_list)) != 0) + return fres; +#endif + const char *keyname = luaL_checkstring(L, 2); + if (!strcmp(keyname, "_VERSION")) + { + lua_pushliteral(L, LUA_VERSION); + return 1; + } + void *res = luaR_findglobal(keyname, strlen(keyname)); + if (!res) + return 0; + else + { + lua_pushrotable(L, res); + return 1; + } } static const luaL_Reg base_funcs[] = { @@ -524,12 +539,10 @@ static const luaL_Reg base_funcs[] = { #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 0 #include "lrodefs.h" - LUA_BASELIB_FUNCLIST, + LUA_BASELIB_FUNCLIST, #endif - {"__index", luaB_index}, - {NULL, NULL} -}; - + {"__index", luaB_index}, + {NULL, NULL}}; /* ** {====================================================== @@ -537,185 +550,188 @@ static const luaL_Reg base_funcs[] = { ** ======================================================= */ -#define CO_RUN 0 /* running */ -#define CO_SUS 1 /* suspended */ -#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ -#define CO_DEAD 3 - -static const char *const statnames[] = - {"running", "suspended", "normal", "dead"}; - -static int costatus (lua_State *L, lua_State *co) { - if (L == co) return CO_RUN; - switch (lua_status(co)) { - case LUA_YIELD: - return CO_SUS; - case 0: { - lua_Debug ar; - if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ - return CO_NOR; /* it is running */ - else if (lua_gettop(co) == 0) - return CO_DEAD; - else - return CO_SUS; /* initial state */ +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = {"running", "suspended", "normal", "dead"}; + +static int costatus(lua_State *L, lua_State *co) +{ + if (L == co) + return CO_RUN; + switch (lua_status(co)) + { + case LUA_YIELD: + return CO_SUS; + case 0: + { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; } - default: /* some error occured */ - return CO_DEAD; - } -} - - -static int luaB_costatus (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - lua_pushstring(L, statnames[costatus(L, co)]); - return 1; -} - - -static int auxresume (lua_State *L, lua_State *co, int narg) { - int status = costatus(L, co); - if (!lua_checkstack(co, narg)) - luaL_error(L, "too many arguments to resume"); - if (status != CO_SUS) { - lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); - return -1; /* error flag */ - } - lua_xmove(L, co, narg); - lua_setlevel(L, co); - status = lua_resume(co, narg); - if (status == 0 || status == LUA_YIELD) { - int nres = lua_gettop(co); - if (!lua_checkstack(L, nres + 1)) - luaL_error(L, "too many results to resume"); - lua_xmove(co, L, nres); /* move yielded values */ - return nres; - } - else { - lua_xmove(co, L, 1); /* move error message */ - return -1; /* error flag */ - } -} - - -static int luaB_coresume (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - int r; - luaL_argcheck(L, co, 1, "coroutine expected"); - r = auxresume(L, co, lua_gettop(L) - 1); - if (r < 0) { - lua_pushboolean(L, 0); - lua_insert(L, -2); - return 2; /* return false + error message */ - } - else { - lua_pushboolean(L, 1); - lua_insert(L, -(r + 1)); - return r + 1; /* return true + `resume' returns */ - } -} - - -static int luaB_auxwrap (lua_State *L) { - lua_State *co = lua_tothread(L, lua_upvalueindex(1)); - int r = auxresume(L, co, lua_gettop(L)); - if (r < 0) { - if (lua_isstring(L, -1)) { /* error object is a string? */ - luaL_where(L, 1); /* add extra info */ - lua_insert(L, -2); - lua_concat(L, 2); - } - lua_error(L); /* propagate error */ - } - return r; } +static int luaB_costatus(lua_State *L) +{ + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} -static int luaB_cocreate (lua_State *L) { - lua_State *NL = lua_newthread(L); - luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, - "Lua function expected"); - lua_pushvalue(L, 1); /* move function to top */ - lua_xmove(L, NL, 1); /* move function from L to NL */ - return 1; +static int auxresume(lua_State *L, lua_State *co, int narg) +{ + int status = costatus(L, co); + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + if (status != CO_SUS) + { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + lua_setlevel(L, co); + status = lua_resume(co, narg); + if (status == 0 || status == LUA_YIELD) + { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else + { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } } +static int luaB_coresume(lua_State *L) +{ + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) + { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else + { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} -static int luaB_cowrap (lua_State *L) { - luaB_cocreate(L); - lua_pushcclosure(L, luaB_auxwrap, 1); - return 1; +static int luaB_auxwrap(lua_State *L) +{ + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) + { + if (lua_isstring(L, -1)) + { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; } +static int luaB_cocreate(lua_State *L) +{ + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} -static int luaB_yield (lua_State *L) { - return lua_yield(L, lua_gettop(L)); +static int luaB_cowrap(lua_State *L) +{ + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; } +static int luaB_yield(lua_State *L) { return lua_yield(L, lua_gettop(L)); } -static int luaB_corunning (lua_State *L) { - if (lua_pushthread(L)) - lua_pushnil(L); /* main thread is not a coroutine */ - return 1; +static int luaB_corunning(lua_State *L) +{ + if (lua_pushthread(L)) + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; } #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 1 #include "lrodefs.h" -const LUA_REG_TYPE co_funcs[] = { - {LSTRKEY("create"), LFUNCVAL(luaB_cocreate)}, - {LSTRKEY("resume"), LFUNCVAL(luaB_coresume)}, - {LSTRKEY("running"), LFUNCVAL(luaB_corunning)}, - {LSTRKEY("status"), LFUNCVAL(luaB_costatus)}, - {LSTRKEY("wrap"), LFUNCVAL(luaB_cowrap)}, - {LSTRKEY("yield"), LFUNCVAL(luaB_yield)}, - {LNILKEY, LNILVAL} -}; +const LUA_REG_TYPE co_funcs[] = {{LSTRKEY("create"), LFUNCVAL(luaB_cocreate)}, + {LSTRKEY("resume"), LFUNCVAL(luaB_coresume)}, + {LSTRKEY("running"), LFUNCVAL(luaB_corunning)}, + {LSTRKEY("status"), LFUNCVAL(luaB_costatus)}, + {LSTRKEY("wrap"), LFUNCVAL(luaB_cowrap)}, + {LSTRKEY("yield"), LFUNCVAL(luaB_yield)}, + {LNILKEY, LNILVAL}}; /* }====================================================== */ - -static void auxopen (lua_State *L, const char *name, - lua_CFunction f, lua_CFunction u) { - lua_pushcfunction(L, u); - lua_pushcclosure(L, f, 1); - lua_setfield(L, -2, name); +static void auxopen(lua_State *L, const char *name, lua_CFunction f, lua_CFunction u) +{ + lua_pushcfunction(L, u); + lua_pushcclosure(L, f, 1); + lua_setfield(L, -2, name); } - -static void base_open (lua_State *L) { - /* set global _G */ - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setglobal(L, "_G"); - /* open lib into global table */ - luaL_register_light(L, "_G", base_funcs); +static void base_open(lua_State *L) +{ + /* set global _G */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + /* open lib into global table */ + luaL_register_light(L, "_G", base_funcs); #if LUA_OPTIMIZE_MEMORY > 0 - lua_pushvalue(L, -1); - lua_setmetatable(L, -2); + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); #else - lua_pushliteral(L, LUA_VERSION); - lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + lua_pushliteral(L, LUA_VERSION); + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ #endif - /* `ipairs' and `pairs' need auxliliary functions as upvalues */ - auxopen(L, "ipairs", luaB_ipairs, ipairsaux); - auxopen(L, "pairs", luaB_pairs, luaB_next); - /* `newproxy' needs a weaktable as upvalue */ - lua_createtable(L, 0, 1); /* new table `w' */ - lua_pushvalue(L, -1); /* `w' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "kv"); - lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ - lua_pushcclosure(L, luaB_newproxy, 1); - lua_setglobal(L, "newproxy"); /* set global `newproxy' */ -} - - -LUALIB_API int luaopen_base (lua_State *L) { - base_open(L); + /* `ipairs' and `pairs' need auxliliary functions as upvalues */ + auxopen(L, "ipairs", luaB_ipairs, ipairsaux); + auxopen(L, "pairs", luaB_pairs, luaB_next); + /* `newproxy' needs a weaktable as upvalue */ + lua_createtable(L, 0, 1); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ +} + +LUALIB_API int luaopen_base(lua_State *L) +{ + base_open(L); #if LUA_OPTIMIZE_MEMORY == 0 - luaL_register(L, LUA_COLIBNAME, co_funcs); - return 2; + luaL_register(L, LUA_COLIBNAME, co_funcs); + return 2; #else - return 1; + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lcode.c b/LuaNode_Esp32/LuaNode32/components/lua/lcode.c index a5e0a8e..e90e1e9 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lcode.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lcode.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define lcode_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -23,763 +22,908 @@ #include "lparser.h" #include "ltable.h" +#define hasjumps(e) ((e)->t != (e)->f) -#define hasjumps(e) ((e)->t != (e)->f) - - -static int isnumeral(expdesc *e) { - return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); -} - +static int isnumeral(expdesc *e) { return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); } -void luaK_nil (FuncState *fs, int from, int n) { - Instruction *previous; - if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ - if (fs->pc == 0) { /* function start? */ - if (from >= fs->nactvar) - return; /* positions are already clean */ - } - else { - previous = &fs->f->code[fs->pc-1]; - if (GET_OPCODE(*previous) == OP_LOADNIL) { - int pfrom = GETARG_A(*previous); - int pto = GETARG_B(*previous); - if (pfrom <= from && from <= pto+1) { /* can connect both? */ - if (from+n-1 > pto) - SETARG_B(*previous, from+n-1); - return; +void luaK_nil(FuncState *fs, int from, int n) +{ + Instruction *previous; + if (fs->pc > fs->lasttarget) + { /* no jumps to current position? */ + if (fs->pc == 0) + { /* function start? */ + if (from >= fs->nactvar) + return; /* positions are already clean */ + } + else + { + previous = &fs->f->code[fs->pc - 1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) + { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto + 1) + { /* can connect both? */ + if (from + n - 1 > pto) + SETARG_B(*previous, from + n - 1); + return; + } + } } - } } - } - luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ + luaK_codeABC(fs, OP_LOADNIL, from, from + n - 1, 0); /* else no optimization */ } - -int luaK_jump (FuncState *fs) { - int jpc = fs->jpc; /* save list of jumps to here */ - int j; - fs->jpc = NO_JUMP; - j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); - luaK_concat(fs, &j, jpc); /* keep them on hold */ - return j; -} - - -void luaK_ret (FuncState *fs, int first, int nret) { - luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +int luaK_jump(FuncState *fs) +{ + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; } +void luaK_ret(FuncState *fs, int first, int nret) { luaK_codeABC(fs, OP_RETURN, first, nret + 1, 0); } -static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { - luaK_codeABC(fs, op, A, B, C); - return luaK_jump(fs); +static int condjump(FuncState *fs, OpCode op, int A, int B, int C) +{ + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); } - -static void fixjump (FuncState *fs, int pc, int dest) { - Instruction *jmp = &fs->f->code[pc]; - int offset = dest-(pc+1); - lua_assert(dest != NO_JUMP); - if (abs(offset) > MAXARG_sBx) - luaX_syntaxerror(fs->ls, "control structure too long"); - SETARG_sBx(*jmp, offset); +static void fixjump(FuncState *fs, int pc, int dest) +{ + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); } - /* ** returns current `pc' and marks it as a jump target (to avoid wrong ** optimizations with consecutive instructions not in the same basic block). */ -int luaK_getlabel (FuncState *fs) { - fs->lasttarget = fs->pc; - return fs->pc; +int luaK_getlabel(FuncState *fs) +{ + fs->lasttarget = fs->pc; + return fs->pc; } - -static int getjump (FuncState *fs, int pc) { - int offset = GETARG_sBx(fs->f->code[pc]); - if (offset == NO_JUMP) /* point to itself represents end of list */ - return NO_JUMP; /* end of list */ - else - return (pc+1)+offset; /* turn offset into absolute position */ +static int getjump(FuncState *fs, int pc) +{ + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc + 1) + offset; /* turn offset into absolute position */ } - -static Instruction *getjumpcontrol (FuncState *fs, int pc) { - Instruction *pi = &fs->f->code[pc]; - if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) - return pi-1; - else - return pi; +static Instruction *getjumpcontrol(FuncState *fs, int pc) +{ + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi - 1)))) + return pi - 1; + else + return pi; } - /* ** check whether list has any jump that do not produce a value ** (or produce an inverted value) */ -static int need_value (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) { - Instruction i = *getjumpcontrol(fs, list); - if (GET_OPCODE(i) != OP_TESTSET) return 1; - } - return 0; /* not found */ +static int need_value(FuncState *fs, int list) +{ + for (; list != NO_JUMP; list = getjump(fs, list)) + { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) + return 1; + } + return 0; /* not found */ } - -static int patchtestreg (FuncState *fs, int node, int reg) { - Instruction *i = getjumpcontrol(fs, node); - if (GET_OPCODE(*i) != OP_TESTSET) - return 0; /* cannot patch other instructions */ - if (reg != NO_REG && reg != GETARG_B(*i)) - SETARG_A(*i, reg); - else /* no register to put value or register already has the value */ - *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); - - return 1; +static int patchtestreg(FuncState *fs, int node, int reg) +{ + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; } +static void removevalues(FuncState *fs, int list) +{ + for (; list != NO_JUMP; list = getjump(fs, list)) patchtestreg(fs, list, NO_REG); +} -static void removevalues (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) - patchtestreg(fs, list, NO_REG); +static void patchlistaux(FuncState *fs, int list, int vtarget, int reg, int dtarget) +{ + while (list != NO_JUMP) + { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } } +static void dischargejpc(FuncState *fs) +{ + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} -static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, - int dtarget) { - while (list != NO_JUMP) { - int next = getjump(fs, list); - if (patchtestreg(fs, list, reg)) - fixjump(fs, list, vtarget); +void luaK_patchlist(FuncState *fs, int list, int target) +{ + if (target == fs->pc) + luaK_patchtohere(fs, list); else - fixjump(fs, list, dtarget); /* jump to default target */ - list = next; - } + { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } } - -static void dischargejpc (FuncState *fs) { - patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); - fs->jpc = NO_JUMP; +void luaK_patchtohere(FuncState *fs, int list) +{ + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); } - -void luaK_patchlist (FuncState *fs, int list, int target) { - if (target == fs->pc) - luaK_patchtohere(fs, list); - else { - lua_assert(target < fs->pc); - patchlistaux(fs, list, target, NO_REG, target); - } +void luaK_concat(FuncState *fs, int *l1, int l2) +{ + if (l2 == NO_JUMP) + return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else + { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } } - -void luaK_patchtohere (FuncState *fs, int list) { - luaK_getlabel(fs); - luaK_concat(fs, &fs->jpc, list); +void luaK_checkstack(FuncState *fs, int n) +{ + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) + { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } } - -void luaK_concat (FuncState *fs, int *l1, int l2) { - if (l2 == NO_JUMP) return; - else if (*l1 == NO_JUMP) - *l1 = l2; - else { - int list = *l1; - int next; - while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ - list = next; - fixjump(fs, list, l2); - } +void luaK_reserveregs(FuncState *fs, int n) +{ + luaK_checkstack(fs, n); + fs->freereg += n; } - -void luaK_checkstack (FuncState *fs, int n) { - int newstack = fs->freereg + n; - if (newstack > fs->f->maxstacksize) { - if (newstack >= MAXSTACK) - luaX_syntaxerror(fs->ls, "function or expression too complex"); - fs->f->maxstacksize = cast_byte(newstack); - } +static void freereg(FuncState *fs, int reg) +{ + if (!ISK(reg) && reg >= fs->nactvar) + { + fs->freereg--; + lua_assert(reg == fs->freereg); + } } - -void luaK_reserveregs (FuncState *fs, int n) { - luaK_checkstack(fs, n); - fs->freereg += n; +static void freeexp(FuncState *fs, expdesc *e) +{ + if (e->k == VNONRELOC) + freereg(fs, e->u.s.info); } - -static void freereg (FuncState *fs, int reg) { - if (!ISK(reg) && reg >= fs->nactvar) { - fs->freereg--; - lua_assert(reg == fs->freereg); - } +static int addk(FuncState *fs, TValue *k, TValue *v) +{ + lua_State *L = fs->L; + TValue *idx = luaH_set(L, fs->h, k); + Proto *f = fs->f; + int oldsize = f->sizek; + if (ttisnumber(idx)) + { + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); + return cast_int(nvalue(idx)); + } + else + { /* constant not found; create a new entry */ + setnvalue(idx, cast_num(fs->nk)); + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[fs->nk], v); + luaC_barrier(L, f, v); + return fs->nk++; + } } - -static void freeexp (FuncState *fs, expdesc *e) { - if (e->k == VNONRELOC) - freereg(fs, e->u.s.info); +int luaK_stringK(FuncState *fs, TString *s) +{ + TValue o; + setsvalue(fs->L, &o, s); + return addk(fs, &o, &o); } - -static int addk (FuncState *fs, TValue *k, TValue *v) { - lua_State *L = fs->L; - TValue *idx = luaH_set(L, fs->h, k); - Proto *f = fs->f; - int oldsize = f->sizek; - if (ttisnumber(idx)) { - lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); - return cast_int(nvalue(idx)); - } - else { /* constant not found; create a new entry */ - setnvalue(idx, cast_num(fs->nk)); - luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, - MAXARG_Bx, "constant table overflow"); - while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); - setobj(L, &f->k[fs->nk], v); - luaC_barrier(L, f, v); - return fs->nk++; - } +int luaK_numberK(FuncState *fs, lua_Number r) +{ + TValue o; + setnvalue(&o, r); + return addk(fs, &o, &o); } - -int luaK_stringK (FuncState *fs, TString *s) { - TValue o; - setsvalue(fs->L, &o, s); - return addk(fs, &o, &o); +static int boolK(FuncState *fs, int b) +{ + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); } - -int luaK_numberK (FuncState *fs, lua_Number r) { - TValue o; - setnvalue(&o, r); - return addk(fs, &o, &o); +static int nilK(FuncState *fs) +{ + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->L, &k, fs->h); + return addk(fs, &k, &v); } - -static int boolK (FuncState *fs, int b) { - TValue o; - setbvalue(&o, b); - return addk(fs, &o, &o); +void luaK_setreturns(FuncState *fs, expdesc *e, int nresults) +{ + if (e->k == VCALL) + { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults + 1); + } + else if (e->k == VVARARG) + { + SETARG_B(getcode(fs, e), nresults + 1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } } - -static int nilK (FuncState *fs) { - TValue k, v; - setnilvalue(&v); - /* cannot use nil as key; instead use table itself to represent nil */ - sethvalue(fs->L, &k, fs->h); - return addk(fs, &k, &v); +void luaK_setoneret(FuncState *fs, expdesc *e) +{ + if (e->k == VCALL) + { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.s.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) + { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } } - -void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { - if (e->k == VCALL) { /* expression is an open function call? */ - SETARG_C(getcode(fs, e), nresults+1); - } - else if (e->k == VVARARG) { - SETARG_B(getcode(fs, e), nresults+1); - SETARG_A(getcode(fs, e), fs->freereg); - luaK_reserveregs(fs, 1); - } +void luaK_dischargevars(FuncState *fs, expdesc *e) +{ + switch (e->k) + { + case VLOCAL: + { + e->k = VNONRELOC; + break; + } + case VUPVAL: + { + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: + { + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: + { + freereg(fs, e->u.s.aux); + freereg(fs, e->u.s.info); + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: + { + luaK_setoneret(fs, e); + break; + } + default: + break; /* there is one value available (somewhere) */ + } } - -void luaK_setoneret (FuncState *fs, expdesc *e) { - if (e->k == VCALL) { /* expression is an open function call? */ - e->k = VNONRELOC; - e->u.s.info = GETARG_A(getcode(fs, e)); - } - else if (e->k == VVARARG) { - SETARG_B(getcode(fs, e), 2); - e->k = VRELOCABLE; /* can relocate its simple result */ - } +static int code_label(FuncState *fs, int A, int b, int jump) +{ + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); } - -void luaK_dischargevars (FuncState *fs, expdesc *e) { - switch (e->k) { - case VLOCAL: { - e->k = VNONRELOC; - break; - } - case VUPVAL: { - e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); - e->k = VRELOCABLE; - break; - } - case VGLOBAL: { - e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); - e->k = VRELOCABLE; - break; - } - case VINDEXED: { - freereg(fs, e->u.s.aux); - freereg(fs, e->u.s.info); - e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); - e->k = VRELOCABLE; - break; - } - case VVARARG: - case VCALL: { - luaK_setoneret(fs, e); - break; +static void discharge2reg(FuncState *fs, expdesc *e, int reg) +{ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VNIL: + { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: + case VTRUE: + { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: + { + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + break; + } + case VKNUM: + { + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: + { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: + { + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + break; + } + default: + { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } } - default: break; /* there is one value available (somewhere) */ - } + e->u.s.info = reg; + e->k = VNONRELOC; } - -static int code_label (FuncState *fs, int A, int b, int jump) { - luaK_getlabel(fs); /* those instructions may be jump targets */ - return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +static void discharge2anyreg(FuncState *fs, expdesc *e) +{ + if (e->k != VNONRELOC) + { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg - 1); + } } - -static void discharge2reg (FuncState *fs, expdesc *e, int reg) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: { - luaK_nil(fs, reg, 1); - break; - } - case VFALSE: case VTRUE: { - luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); - break; - } - case VK: { - luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); - break; - } - case VKNUM: { - luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); - break; - } - case VRELOCABLE: { - Instruction *pc = &getcode(fs, e); - SETARG_A(*pc, reg); - break; - } - case VNONRELOC: { - if (reg != e->u.s.info) - luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); - break; - } - default: { - lua_assert(e->k == VVOID || e->k == VJMP); - return; /* nothing to do... */ +static void exp2reg(FuncState *fs, expdesc *e, int reg) +{ + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + if (hasjumps(e)) + { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) + { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); } - } - e->u.s.info = reg; - e->k = VNONRELOC; + e->f = e->t = NO_JUMP; + e->u.s.info = reg; + e->k = VNONRELOC; } - -static void discharge2anyreg (FuncState *fs, expdesc *e) { - if (e->k != VNONRELOC) { +void luaK_exp2nextreg(FuncState *fs, expdesc *e) +{ + luaK_dischargevars(fs, e); + freeexp(fs, e); luaK_reserveregs(fs, 1); - discharge2reg(fs, e, fs->freereg-1); - } + exp2reg(fs, e, fs->freereg - 1); } - -static void exp2reg (FuncState *fs, expdesc *e, int reg) { - discharge2reg(fs, e, reg); - if (e->k == VJMP) - luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ - if (hasjumps(e)) { - int final; /* position after whole expression */ - int p_f = NO_JUMP; /* position of an eventual LOAD false */ - int p_t = NO_JUMP; /* position of an eventual LOAD true */ - if (need_value(fs, e->t) || need_value(fs, e->f)) { - int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); - p_f = code_label(fs, reg, 0, 1); - p_t = code_label(fs, reg, 1, 0); - luaK_patchtohere(fs, fj); +int luaK_exp2anyreg(FuncState *fs, expdesc *e) +{ + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) + { + if (!hasjumps(e)) + return e->u.s.info; /* exp is already in a register */ + if (e->u.s.info >= fs->nactvar) + { /* reg. is not a local? */ + exp2reg(fs, e, e->u.s.info); /* put value on it */ + return e->u.s.info; + } } - final = luaK_getlabel(fs); - patchlistaux(fs, e->f, final, reg, p_f); - patchlistaux(fs, e->t, final, reg, p_t); - } - e->f = e->t = NO_JUMP; - e->u.s.info = reg; - e->k = VNONRELOC; + luaK_exp2nextreg(fs, e); /* default */ + return e->u.s.info; } - -void luaK_exp2nextreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - freeexp(fs, e); - luaK_reserveregs(fs, 1); - exp2reg(fs, e, fs->freereg - 1); +void luaK_exp2val(FuncState *fs, expdesc *e) +{ + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); } - -int luaK_exp2anyreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - if (e->k == VNONRELOC) { - if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ - if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ - exp2reg(fs, e, e->u.s.info); /* put value on it */ - return e->u.s.info; +int luaK_exp2RK(FuncState *fs, expdesc *e) +{ + luaK_exp2val(fs, e); + switch (e->k) + { + case VKNUM: + case VTRUE: + case VFALSE: + case VNIL: + { + if (fs->nk <= MAXINDEXRK) + { /* constant fit in RK operand? */ + e->u.s.info = (e->k == VNIL) + ? nilK(fs) + : (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.s.info); + } + else + break; + } + case VK: + { + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e->u.s.info); + else + break; + } + default: + break; } - } - luaK_exp2nextreg(fs, e); /* default */ - return e->u.s.info; + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); } +void luaK_storevar(FuncState *fs, expdesc *var, expdesc *ex) +{ + switch (var->k) + { + case VLOCAL: + { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.s.info); + return; + } + case VUPVAL: + { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); + break; + } + case VGLOBAL: + { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + break; + } + case VINDEXED: + { + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + break; + } + default: + { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} -void luaK_exp2val (FuncState *fs, expdesc *e) { - if (hasjumps(e)) +void luaK_self(FuncState *fs, expdesc *e, expdesc *key) +{ + int func; luaK_exp2anyreg(fs, e); - else - luaK_dischargevars(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->u.s.info = func; + e->k = VNONRELOC; } +static void invertjump(FuncState *fs, expdesc *e) +{ + Instruction *pc = getjumpcontrol(fs, e->u.s.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} -int luaK_exp2RK (FuncState *fs, expdesc *e) { - luaK_exp2val(fs, e); - switch (e->k) { - case VKNUM: - case VTRUE: - case VFALSE: - case VNIL: { - if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ - e->u.s.info = (e->k == VNIL) ? nilK(fs) : - (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : - boolK(fs, (e->k == VTRUE)); - e->k = VK; - return RKASK(e->u.s.info); - } - else break; - } - case VK: { - if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ - return RKASK(e->u.s.info); - else break; +static int jumponcond(FuncState *fs, expdesc *e, int cond) +{ + if (e->k == VRELOCABLE) + { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) + { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ } - default: break; - } - /* not a constant in the right range: put it in a register */ - return luaK_exp2anyreg(fs, e); + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); } - -void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { - switch (var->k) { - case VLOCAL: { - freeexp(fs, ex); - exp2reg(fs, ex, var->u.s.info); - return; - } - case VUPVAL: { - int e = luaK_exp2anyreg(fs, ex); - luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); - break; +void luaK_goiftrue(FuncState *fs, expdesc *e) +{ + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VK: + case VKNUM: + case VTRUE: + { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VJMP: + { + invertjump(fs, e); + pc = e->u.s.info; + break; + } + default: + { + pc = jumponcond(fs, e, 0); + break; + } } - case VGLOBAL: { - int e = luaK_exp2anyreg(fs, ex); - luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); - break; + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + +static void luaK_goiffalse(FuncState *fs, expdesc *e) +{ + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VNIL: + case VFALSE: + { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VJMP: + { + pc = e->u.s.info; + break; + } + default: + { + pc = jumponcond(fs, e, 1); + break; + } } - case VINDEXED: { - int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); - break; + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + +static void codenot(FuncState *fs, expdesc *e) +{ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VNIL: + case VFALSE: + { + e->k = VTRUE; + break; + } + case VK: + case VKNUM: + case VTRUE: + { + e->k = VFALSE; + break; + } + case VJMP: + { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: + { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + default: + { + lua_assert(0); /* cannot happen */ + break; + } } - default: { - lua_assert(0); /* invalid var kind to store */ - break; + /* interchange true and false lists */ + { + int temp = e->f; + e->f = e->t; + e->t = temp; } - } - freeexp(fs, ex); + removevalues(fs, e->f); + removevalues(fs, e->t); } - -void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { - int func; - luaK_exp2anyreg(fs, e); - freeexp(fs, e); - func = fs->freereg; - luaK_reserveregs(fs, 2); - luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); - freeexp(fs, key); - e->u.s.info = func; - e->k = VNONRELOC; +void luaK_indexed(FuncState *fs, expdesc *t, expdesc *k) +{ + t->u.s.aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; } - -static void invertjump (FuncState *fs, expdesc *e) { - Instruction *pc = getjumpcontrol(fs, e->u.s.info); - lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && - GET_OPCODE(*pc) != OP_TEST); - SETARG_A(*pc, !(GETARG_A(*pc))); +static int constfolding(OpCode op, expdesc *e1, expdesc *e2) +{ + lua_Number v1, v2, r; + if (!isnumeral(e1) || !isnumeral(e2)) + return 0; + v1 = e1->u.nval; + v2 = e2->u.nval; + switch (op) + { + case OP_ADD: + r = luai_numadd(v1, v2); + break; + case OP_SUB: + r = luai_numsub(v1, v2); + break; + case OP_MUL: + r = luai_nummul(v1, v2); + break; + case OP_DIV: + if (v2 == 0) + return 0; /* do not attempt to divide by 0 */ + r = luai_numdiv(v1, v2); + break; + case OP_MOD: + if (v2 == 0) + return 0; /* do not attempt to divide by 0 */ + r = luai_nummod(v1, v2); + break; + case OP_POW: + r = luai_numpow(v1, v2); + break; + case OP_UNM: + r = luai_numunm(v1); + break; + case OP_LEN: + return 0; /* no constant folding for 'len' */ + default: + lua_assert(0); + r = 0; + break; + } + if (luai_numisnan(r)) + return 0; /* do not attempt to produce NaN */ + e1->u.nval = r; + return 1; } - -static int jumponcond (FuncState *fs, expdesc *e, int cond) { - if (e->k == VRELOCABLE) { - Instruction ie = getcode(fs, e); - if (GET_OPCODE(ie) == OP_NOT) { - fs->pc--; /* remove previous OP_NOT */ - return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); +static void codearith(FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) +{ + if (constfolding(op, e1, e2)) + return; + else + { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) + { + freeexp(fs, e1); + freeexp(fs, e2); + } + else + { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; } - /* else go through */ - } - discharge2anyreg(fs, e); - freeexp(fs, e); - return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); } - -void luaK_goiftrue (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VK: case VKNUM: case VTRUE: { - pc = NO_JUMP; /* always true; do nothing */ - break; - } - case VJMP: { - invertjump(fs, e); - pc = e->u.s.info; - break; - } - default: { - pc = jumponcond(fs, e, 0); - break; - } - } - luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ - luaK_patchtohere(fs, e->t); - e->t = NO_JUMP; -} - - -static void luaK_goiffalse (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: case VFALSE: { - pc = NO_JUMP; /* always false; do nothing */ - break; - } - case VJMP: { - pc = e->u.s.info; - break; - } - default: { - pc = jumponcond(fs, e, 1); - break; - } - } - luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ - luaK_patchtohere(fs, e->f); - e->f = NO_JUMP; -} - - -static void codenot (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: case VFALSE: { - e->k = VTRUE; - break; - } - case VK: case VKNUM: case VTRUE: { - e->k = VFALSE; - break; +static void codecomp(FuncState *fs, OpCode op, int cond, expdesc *e1, expdesc *e2) +{ + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) + { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; + o1 = o2; + o2 = temp; /* o1 <==> o2 */ + cond = 1; } - case VJMP: { - invertjump(fs, e); - break; + e1->u.s.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + +void luaK_prefix(FuncState *fs, UnOpr op, expdesc *e) +{ + expdesc e2; + e2.t = e2.f = NO_JUMP; + e2.k = VKNUM; + e2.u.nval = 0; + switch (op) + { + case OPR_MINUS: + { + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, OP_UNM, e, &e2); + break; + } + case OPR_NOT: + codenot(fs, e); + break; + case OPR_LEN: + { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); + break; + } + default: + lua_assert(0); } - case VRELOCABLE: - case VNONRELOC: { - discharge2anyreg(fs, e); - freeexp(fs, e); - e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); - e->k = VRELOCABLE; - break; - } - default: { - lua_assert(0); /* cannot happen */ - break; +} + +void luaK_infix(FuncState *fs, BinOpr op, expdesc *v) +{ + switch (op) + { + case OPR_AND: + { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: + { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: + { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: + case OPR_SUB: + case OPR_MUL: + case OPR_DIV: + case OPR_MOD: + case OPR_POW: + { + if (!isnumeral(v)) + luaK_exp2RK(fs, v); + break; + } + default: + { + luaK_exp2RK(fs, v); + break; + } } - } - /* interchange true and false lists */ - { int temp = e->f; e->f = e->t; e->t = temp; } - removevalues(fs, e->f); - removevalues(fs, e->t); -} - - -void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - t->u.s.aux = luaK_exp2RK(fs, k); - t->k = VINDEXED; -} - - -static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { - lua_Number v1, v2, r; - if (!isnumeral(e1) || !isnumeral(e2)) return 0; - v1 = e1->u.nval; - v2 = e2->u.nval; - switch (op) { - case OP_ADD: r = luai_numadd(v1, v2); break; - case OP_SUB: r = luai_numsub(v1, v2); break; - case OP_MUL: r = luai_nummul(v1, v2); break; - case OP_DIV: - if (v2 == 0) return 0; /* do not attempt to divide by 0 */ - r = luai_numdiv(v1, v2); break; - case OP_MOD: - if (v2 == 0) return 0; /* do not attempt to divide by 0 */ - r = luai_nummod(v1, v2); break; - case OP_POW: r = luai_numpow(v1, v2); break; - case OP_UNM: r = luai_numunm(v1); break; - case OP_LEN: return 0; /* no constant folding for 'len' */ - default: lua_assert(0); r = 0; break; - } - if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ - e1->u.nval = r; - return 1; -} - - -static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { - if (constfolding(op, e1, e2)) - return; - else { - int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; - int o1 = luaK_exp2RK(fs, e1); - if (o1 > o2) { - freeexp(fs, e1); - freeexp(fs, e2); - } - else { - freeexp(fs, e2); - freeexp(fs, e1); - } - e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); - e1->k = VRELOCABLE; - } -} - - -static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, - expdesc *e2) { - int o1 = luaK_exp2RK(fs, e1); - int o2 = luaK_exp2RK(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - if (cond == 0 && op != OP_EQ) { - int temp; /* exchange args to replace by `<' or `<=' */ - temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ - cond = 1; - } - e1->u.s.info = condjump(fs, op, cond, o1, o2); - e1->k = VJMP; -} - - -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { - expdesc e2; - e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; - switch (op) { - case OPR_MINUS: { - if (!isnumeral(e)) - luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ - codearith(fs, OP_UNM, e, &e2); - break; - } - case OPR_NOT: codenot(fs, e); break; - case OPR_LEN: { - luaK_exp2anyreg(fs, e); /* cannot operate on constants */ - codearith(fs, OP_LEN, e, &e2); - break; - } - default: lua_assert(0); - } -} - - -void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { - switch (op) { - case OPR_AND: { - luaK_goiftrue(fs, v); - break; - } - case OPR_OR: { - luaK_goiffalse(fs, v); - break; - } - case OPR_CONCAT: { - luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ - break; - } - case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: - case OPR_MOD: case OPR_POW: { - if (!isnumeral(v)) luaK_exp2RK(fs, v); - break; - } - default: { - luaK_exp2RK(fs, v); - break; - } - } -} - - -void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { - switch (op) { - case OPR_AND: { - lua_assert(e1->t == NO_JUMP); /* list must be closed */ - luaK_dischargevars(fs, e2); - luaK_concat(fs, &e2->f, e1->f); - *e1 = *e2; - break; - } - case OPR_OR: { - lua_assert(e1->f == NO_JUMP); /* list must be closed */ - luaK_dischargevars(fs, e2); - luaK_concat(fs, &e2->t, e1->t); - *e1 = *e2; - break; - } - case OPR_CONCAT: { - luaK_exp2val(fs, e2); - if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { - lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); - freeexp(fs, e1); - SETARG_B(getcode(fs, e2), e1->u.s.info); - e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; - } - else { - luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ - codearith(fs, OP_CONCAT, e1, e2); - } - break; - } - case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; - case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; - case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; - case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; - case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; - case OPR_POW: codearith(fs, OP_POW, e1, e2); break; - case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; - case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; - case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; - case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; - case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; - case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; - default: lua_assert(0); - } } +void luaK_posfix(FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) +{ + switch (op) + { + case OPR_AND: + { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: + { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: + { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) + { + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2)) - 1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = VRELOCABLE; + e1->u.s.info = e2->u.s.info; + } + else + { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); + } + break; + } + case OPR_ADD: + codearith(fs, OP_ADD, e1, e2); + break; + case OPR_SUB: + codearith(fs, OP_SUB, e1, e2); + break; + case OPR_MUL: + codearith(fs, OP_MUL, e1, e2); + break; + case OPR_DIV: + codearith(fs, OP_DIV, e1, e2); + break; + case OPR_MOD: + codearith(fs, OP_MOD, e1, e2); + break; + case OPR_POW: + codearith(fs, OP_POW, e1, e2); + break; + case OPR_EQ: + codecomp(fs, OP_EQ, 1, e1, e2); + break; + case OPR_NE: + codecomp(fs, OP_EQ, 0, e1, e2); + break; + case OPR_LT: + codecomp(fs, OP_LT, 1, e1, e2); + break; + case OPR_LE: + codecomp(fs, OP_LE, 1, e1, e2); + break; + case OPR_GT: + codecomp(fs, OP_LT, 0, e1, e2); + break; + case OPR_GE: + codecomp(fs, OP_LE, 0, e1, e2); + break; + default: + lua_assert(0); + } +} #ifdef LUA_OPTIMIZE_DEBUG @@ -787,144 +931,175 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { * Attempted to write to last (null terminator) byte of lineinfo, so need * to grow the lineinfo vector and extend the fill bytes */ -static unsigned char *growLineInfo(FuncState *fs) { - int i, oldsize = fs->packedlineinfoSize; - Proto *f = fs->f; - unsigned char *p, *r; - - lua_assert(f->packedlineinfo==NULL || f->packedlineinfo[oldsize-1] == 0); - - /* using the macro results in a redundant if test, but what the hell */ - luaM_growvector(fs->L, f->packedlineinfo, fs->packedlineinfoSize, fs->packedlineinfoSize, - unsigned char, MAX_INT, "code size overflow"); - r = p = f->packedlineinfo + oldsize; - if (oldsize) *--r = INFO_FILL_BYTE; - i = fs->packedlineinfoSize - oldsize - 1; - while (i--) *p++ = INFO_FILL_BYTE; - *p = 0; - return r; -} - -static void generateInfoDeltaLine(FuncState *fs, int line) { - /* Handle first time through when lineinfo points is NULL */ - unsigned char *p = fs->f->packedlineinfo ? lineInfoTop(fs) + 1 : growLineInfo(fs); -#define addDLbyte(v) if (*p==0) p = growLineInfo(fs); *p++ = (v); - int delta = line - fs->lastline - 1; - if (delta) { - if (delta<0) { - delta = -delta - 1; - addDLbyte((INFO_DELTA_MASK|INFO_SIGN_MASK) | (delta & INFO_DELTA_6BITS)); - } else { - delta = delta - 1; - addDLbyte(INFO_DELTA_MASK | (delta & INFO_DELTA_6BITS)); - } - delta >>= 6; - while (delta) { - addDLbyte(INFO_DELTA_MASK | (delta & INFO_DELTA_7BITS)); - delta >>= 7; - } - } - addDLbyte(1); - fs->lastline = line; - fs->lastlineOffset = p - fs->f->packedlineinfo - 1; +static unsigned char *growLineInfo(FuncState *fs) +{ + int i, oldsize = fs->packedlineinfoSize; + Proto *f = fs->f; + unsigned char *p, *r; + + lua_assert(f->packedlineinfo == NULL || f->packedlineinfo[oldsize - 1] == 0); + + /* using the macro results in a redundant if test, but what the hell */ + luaM_growvector(fs->L, f->packedlineinfo, fs->packedlineinfoSize, fs->packedlineinfoSize, unsigned char, MAX_INT, + "code size overflow"); + r = p = f->packedlineinfo + oldsize; + if (oldsize) + *--r = INFO_FILL_BYTE; + i = fs->packedlineinfoSize - oldsize - 1; + while (i--) *p++ = INFO_FILL_BYTE; + *p = 0; + return r; +} + +static void generateInfoDeltaLine(FuncState *fs, int line) +{ + /* Handle first time through when lineinfo points is NULL */ + unsigned char *p = fs->f->packedlineinfo ? lineInfoTop(fs) + 1 : growLineInfo(fs); +#define addDLbyte(v) \ + if (*p == 0) \ + p = growLineInfo(fs); \ + *p++ = (v); + int delta = line - fs->lastline - 1; + if (delta) + { + if (delta < 0) + { + delta = -delta - 1; + addDLbyte((INFO_DELTA_MASK | INFO_SIGN_MASK) | (delta & INFO_DELTA_6BITS)); + } + else + { + delta = delta - 1; + addDLbyte(INFO_DELTA_MASK | (delta & INFO_DELTA_6BITS)); + } + delta >>= 6; + while (delta) + { + addDLbyte(INFO_DELTA_MASK | (delta & INFO_DELTA_7BITS)); + delta >>= 7; + } + } + addDLbyte(1); + fs->lastline = line; + fs->lastlineOffset = p - fs->f->packedlineinfo - 1; #undef addDLbyte } #endif -void luaK_fixline (FuncState *fs, int line) { +void luaK_fixline(FuncState *fs, int line) +{ #ifdef LUA_OPTIMIZE_DEBUG - /* The fixup line can be the same as existing one and in this case there's nothing to do */ - if (line != fs->lastline) { - /* first remove the current line reference */ - unsigned char *p = lineInfoTop(fs); - lua_assert(*p < 127); - if (*p >1) { - (*p)--; /* this is simply decrementing the last count a multi-PC line */ - } else { - /* it's a bit more complicated if it's the 1st instruction on the line */ - int delta = 0; - unsigned char code; - /* this logic handles [1snnnnnnn [1nnnnnnn]*]? */ - *p-- = INFO_FILL_BYTE; - /* work backwards over the coded delta computing the delta */ - while ((code=*p) & INFO_DELTA_MASK) { - *p-- = INFO_FILL_BYTE; - if (*p & INFO_DELTA_MASK) { - delta = delta + ((code & INFO_DELTA_7BITS)<<7); - } else { - delta += (code & INFO_DELTA_6BITS) + 1; - if (code & INFO_SIGN_MASK) delta = -delta; - } - } - /* and reposition the FuncState lastline pointers at the previous instruction count */ - fs->lastline-= delta + 1; - fs->lastlineOffset = p - fs->f->packedlineinfo; - } - /* Then add the new line reference */ - generateInfoDeltaLine(fs, line); - } + /* The fixup line can be the same as existing one and in this case there's + * nothing to do */ + if (line != fs->lastline) + { + /* first remove the current line reference */ + unsigned char *p = lineInfoTop(fs); + lua_assert(*p < 127); + if (*p > 1) + { + (*p)--; /* this is simply decrementing the last count a multi-PC + line */ + } + else + { + /* it's a bit more complicated if it's the 1st instruction on the + * line */ + int delta = 0; + unsigned char code; + /* this logic handles [1snnnnnnn [1nnnnnnn]*]? */ + *p-- = INFO_FILL_BYTE; + /* work backwards over the coded delta computing the delta */ + while ((code = *p) & INFO_DELTA_MASK) + { + *p-- = INFO_FILL_BYTE; + if (*p & INFO_DELTA_MASK) + { + delta = delta + ((code & INFO_DELTA_7BITS) << 7); + } + else + { + delta += (code & INFO_DELTA_6BITS) + 1; + if (code & INFO_SIGN_MASK) + delta = -delta; + } + } + /* and reposition the FuncState lastline pointers at the previous + * instruction count */ + fs->lastline -= delta + 1; + fs->lastlineOffset = p - fs->f->packedlineinfo; + } + /* Then add the new line reference */ + generateInfoDeltaLine(fs, line); + } #else - fs->f->lineinfo[fs->pc - 1] = line; + fs->f->lineinfo[fs->pc - 1] = line; #endif } - -static int luaK_code (FuncState *fs, Instruction i, int line) { - Proto *f = fs->f; - dischargejpc(fs); /* `pc' will change */ - /* put new instruction in code array */ - luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, - MAX_INT, "code size overflow"); - f->code[fs->pc] = i; - /* save corresponding line information */ +static int luaK_code(FuncState *fs, Instruction i, int line) +{ + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ #ifdef LUA_OPTIMIZE_DEBUG - /* note that frst time fs->lastline==0 through, so the else branch is taken */ - if (fs->pc == fs->lineinfoLastPC+1) { - if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) { - f->packedlineinfo[fs->lastlineOffset]++; - } else { - generateInfoDeltaLine(fs, line); - } - } else { - /* The last instruction is occasionally overwritten as part of branch optimisation*/ - lua_assert(fs->pc == fs->lineinfoLastPC); /* panic if its anything other than this !! */ - luaK_fixline(fs,line); - } - fs->lineinfoLastPC = fs->pc; + /* note that frst time fs->lastline==0 through, so the else branch is taken + */ + if (fs->pc == fs->lineinfoLastPC + 1) + { + if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) + { + f->packedlineinfo[fs->lastlineOffset]++; + } + else + { + generateInfoDeltaLine(fs, line); + } + } + else + { + /* The last instruction is occasionally overwritten as part of branch + * optimisation*/ + lua_assert(fs->pc == fs->lineinfoLastPC); /* panic if its anything other than this !! */ + luaK_fixline(fs, line); + } + fs->lineinfoLastPC = fs->pc; #else - luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, - MAX_INT, "code size overflow"); - f->lineinfo[fs->pc] = line; + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; #endif - return fs->pc++; + return fs->pc++; } - -int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { - lua_assert(getOpMode(o) == iABC); - lua_assert(getBMode(o) != OpArgN || b == 0); - lua_assert(getCMode(o) != OpArgN || c == 0); - return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +int luaK_codeABC(FuncState *fs, OpCode o, int a, int b, int c) +{ + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); } - -int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { - lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); - lua_assert(getCMode(o) == OpArgN); - return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +int luaK_codeABx(FuncState *fs, OpCode o, int a, unsigned int bc) +{ + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); } - -void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { - int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; - int b = (tostore == LUA_MULTRET) ? 0 : tostore; - lua_assert(tostore != 0); - if (c <= MAXARG_C) - luaK_codeABC(fs, OP_SETLIST, base, b, c); - else { - luaK_codeABC(fs, OP_SETLIST, base, b, 0); - luaK_code(fs, cast(Instruction, c), fs->ls->lastline); - } - fs->freereg = base + 1; /* free registers with list values */ +void luaK_setlist(FuncState *fs, int base, int nelems, int tostore) +{ + int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else + { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ldblib.c b/LuaNode_Esp32/LuaNode32/components/lua/ldblib.c index 1a25ffb..2faa489 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ldblib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ldblib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define ldblib_c #define LUA_LIB #define LUAC_CROSS_FILE @@ -15,371 +14,403 @@ #include C_HEADER_STRING #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lualib.h" #include "sdkconfig.h" - -static int db_getregistry (lua_State *L) { - lua_pushvalue(L, LUA_REGISTRYINDEX); - return 1; +static int db_getregistry(lua_State *L) +{ + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; } #ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL -static int db_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); /* no metatable */ - } - return 1; +static int db_getmetatable(lua_State *L) +{ + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) + { + lua_pushnil(L); /* no metatable */ + } + return 1; } - -static int db_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, - "nil or table expected"); - lua_settop(L, 2); - lua_pushboolean(L, lua_setmetatable(L, 1)); - return 1; +static int db_setmetatable(lua_State *L) +{ + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); + lua_settop(L, 2); + lua_pushboolean(L, lua_setmetatable(L, 1)); + return 1; } - -static int db_getfenv (lua_State *L) { - luaL_checkany(L, 1); - lua_getfenv(L, 1); - return 1; +static int db_getfenv(lua_State *L) +{ + luaL_checkany(L, 1); + lua_getfenv(L, 1); + return 1; } - -static int db_setfenv (lua_State *L) { - luaL_checktype(L, 2, LUA_TTABLE); - lua_settop(L, 2); - if (lua_setfenv(L, 1) == 0) - luaL_error(L, LUA_QL("setfenv") - " cannot change environment of given object"); - return 1; +static int db_setfenv(lua_State *L) +{ + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + if (lua_setfenv(L, 1) == 0) + luaL_error(L, LUA_QL("setfenv") " cannot change environment of given object"); + return 1; } - -static void settabss (lua_State *L, const char *i, const char *v) { - lua_pushstring(L, v); - lua_setfield(L, -2, i); +static void settabss(lua_State *L, const char *i, const char *v) +{ + lua_pushstring(L, v); + lua_setfield(L, -2, i); } - -static void settabsi (lua_State *L, const char *i, int v) { - lua_pushinteger(L, v); - lua_setfield(L, -2, i); +static void settabsi(lua_State *L, const char *i, int v) +{ + lua_pushinteger(L, v); + lua_setfield(L, -2, i); } #endif -static lua_State *getthread (lua_State *L, int *arg) { - if (lua_isthread(L, 1)) { - *arg = 1; - return lua_tothread(L, 1); - } - else { - *arg = 0; - return L; - } +static lua_State *getthread(lua_State *L, int *arg) +{ + if (lua_isthread(L, 1)) + { + *arg = 1; + return lua_tothread(L, 1); + } + else + { + *arg = 0; + return L; + } } #ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL -static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { - if (L == L1) { - lua_pushvalue(L, -2); - lua_remove(L, -3); - } - else - lua_xmove(L1, L, 1); - lua_setfield(L, -2, fname); -} - - -static int db_getinfo (lua_State *L) { - lua_Debug ar; - int arg; - lua_State *L1 = getthread(L, &arg); - const char *options = luaL_optstring(L, arg+2, "flnSu"); - if (lua_isnumber(L, arg+1)) { - if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { - lua_pushnil(L); /* level out of range */ - return 1; +static void treatstackoption(lua_State *L, lua_State *L1, const char *fname) +{ + if (L == L1) + { + lua_pushvalue(L, -2); + lua_remove(L, -3); } - } - else if (lua_isfunction(L, arg+1) || lua_islightfunction(L, arg+1)) { - lua_pushfstring(L, ">%s", options); - options = lua_tostring(L, -1); - lua_pushvalue(L, arg+1); - lua_xmove(L, L1, 1); - } - else - return luaL_argerror(L, arg+1, "function or level expected"); - if (!lua_getinfo(L1, options, &ar)) - return luaL_argerror(L, arg+2, "invalid option"); - lua_createtable(L, 0, 2); - if (strchr(options, 'S')) { - settabss(L, "source", ar.source); - settabss(L, "short_src", ar.short_src); - settabsi(L, "linedefined", ar.linedefined); - settabsi(L, "lastlinedefined", ar.lastlinedefined); - settabss(L, "what", ar.what); - } - if (strchr(options, 'l')) - settabsi(L, "currentline", ar.currentline); - if (strchr(options, 'u')) - settabsi(L, "nups", ar.nups); - if (strchr(options, 'n')) { - settabss(L, "name", ar.name); - settabss(L, "namewhat", ar.namewhat); - } - if (strchr(options, 'L')) - treatstackoption(L, L1, "activelines"); - if (strchr(options, 'f')) - treatstackoption(L, L1, "func"); - return 1; /* return table */ + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); } - -static int db_getlocal (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - const char *name; - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ - return luaL_argerror(L, arg+1, "level out of range"); - name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); - if (name) { - lua_xmove(L1, L, 1); - lua_pushstring(L, name); - lua_pushvalue(L, -2); - return 2; - } - else { - lua_pushnil(L); - return 1; - } +static int db_getinfo(lua_State *L) +{ + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg + 2, "flnSu"); + if (lua_isnumber(L, arg + 1)) + { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg + 1), &ar)) + { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg + 1) || lua_islightfunction(L, arg + 1)) + { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg + 1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg + 1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg + 2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) + { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) + { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ } - -static int db_setlocal (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ - return luaL_argerror(L, arg+1, "level out of range"); - luaL_checkany(L, arg+3); - lua_settop(L, arg+3); - lua_xmove(L, L1, 1); - lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); - return 1; +static int db_getlocal(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) /* out of range? */ + return luaL_argerror(L, arg + 1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg + 2)); + if (name) + { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else + { + lua_pushnil(L); + return 1; + } } - -static int auxupvalue (lua_State *L, int get) { - const char *name; - int n = luaL_checkint(L, 2); - luaL_checktype(L, 1, LUA_TFUNCTION); - if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ - name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); - if (name == NULL) return 0; - lua_pushstring(L, name); - lua_insert(L, -(get+1)); - return get + 1; +static int db_setlocal(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) /* out of range? */ + return luaL_argerror(L, arg + 1, "level out of range"); + luaL_checkany(L, arg + 3); + lua_settop(L, arg + 3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg + 2))); + return 1; } - -static int db_getupvalue (lua_State *L) { - return auxupvalue(L, 1); +static int auxupvalue(lua_State *L, int get) +{ + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) + return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) + return 0; + lua_pushstring(L, name); + lua_insert(L, -(get + 1)); + return get + 1; } +static int db_getupvalue(lua_State *L) { return auxupvalue(L, 1); } -static int db_setupvalue (lua_State *L) { - luaL_checkany(L, 3); - return auxupvalue(L, 0); +static int db_setupvalue(lua_State *L) +{ + luaL_checkany(L, 3); + return auxupvalue(L, 0); } - - static const char KEY_HOOK = 'h'; - -static void hookf (lua_State *L, lua_Debug *ar) { - static const char *const hooknames[] = - {"call", "return", "line", "count", "tail return"}; - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_pushlightuserdata(L, L); - lua_rawget(L, -2); - if (lua_isfunction(L, -1)) { - lua_pushstring(L, hooknames[(int)ar->event]); - if (ar->currentline >= 0) - lua_pushinteger(L, ar->currentline); - else lua_pushnil(L); - lua_assert(lua_getinfo(L, "lS", ar)); - lua_call(L, 2, 0); - } +static void hookf(lua_State *L, lua_Debug *ar) +{ + static const char *const hooknames[] = {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) + { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else + lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } } - -static int makemask (const char *smask, int count) { - int mask = 0; - if (strchr(smask, 'c')) mask |= LUA_MASKCALL; - if (strchr(smask, 'r')) mask |= LUA_MASKRET; - if (strchr(smask, 'l')) mask |= LUA_MASKLINE; - if (count > 0) mask |= LUA_MASKCOUNT; - return mask; +static int makemask(const char *smask, int count) +{ + int mask = 0; + if (strchr(smask, 'c')) + mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) + mask |= LUA_MASKRET; + if (strchr(smask, 'l')) + mask |= LUA_MASKLINE; + if (count > 0) + mask |= LUA_MASKCOUNT; + return mask; } - -static char *unmakemask (int mask, char *smask) { - int i = 0; - if (mask & LUA_MASKCALL) smask[i++] = 'c'; - if (mask & LUA_MASKRET) smask[i++] = 'r'; - if (mask & LUA_MASKLINE) smask[i++] = 'l'; - smask[i] = '\0'; - return smask; +static char *unmakemask(int mask, char *smask) +{ + int i = 0; + if (mask & LUA_MASKCALL) + smask[i++] = 'c'; + if (mask & LUA_MASKRET) + smask[i++] = 'r'; + if (mask & LUA_MASKLINE) + smask[i++] = 'l'; + smask[i] = '\0'; + return smask; } - -static void gethooktable (lua_State *L) { - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - lua_createtable(L, 0, 1); +static void gethooktable(lua_State *L) +{ lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } -} - - -static int db_sethook (lua_State *L) { - int arg, mask, count; - lua_Hook func; - lua_State *L1 = getthread(L, &arg); - if (lua_isnoneornil(L, arg+1)) { - lua_settop(L, arg+1); - func = NULL; mask = 0; count = 0; /* turn off hooks */ - } - else { - const char *smask = luaL_checkstring(L, arg+2); - luaL_checkanyfunction(L, arg+1); - count = luaL_optint(L, arg+3, 0); - func = hookf; mask = makemask(smask, count); - } - gethooktable(L); - lua_pushlightuserdata(L, L1); - lua_pushvalue(L, arg+1); - lua_rawset(L, -3); /* set new hook */ - lua_pop(L, 1); /* remove hook table */ - lua_sethook(L1, func, mask, count); /* set hooks */ - return 0; + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) + { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } } - -static int db_gethook (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - char buff[5]; - int mask = lua_gethookmask(L1); - lua_Hook hook = lua_gethook(L1); - if (hook != NULL && hook != hookf) /* external hook? */ - lua_pushliteral(L, "external hook"); - else { +static int db_sethook(lua_State *L) +{ + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg + 1)) + { + lua_settop(L, arg + 1); + func = NULL; + mask = 0; + count = 0; /* turn off hooks */ + } + else + { + const char *smask = luaL_checkstring(L, arg + 2); + luaL_checkanyfunction(L, arg + 1); + count = luaL_optint(L, arg + 3, 0); + func = hookf; + mask = makemask(smask, count); + } gethooktable(L); lua_pushlightuserdata(L, L1); - lua_rawget(L, -2); /* get hook */ - lua_remove(L, -2); /* remove hook table */ - } - lua_pushstring(L, unmakemask(mask, buff)); - lua_pushinteger(L, lua_gethookcount(L1)); - return 3; + lua_pushvalue(L, arg + 1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; } +static int db_gethook(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else + { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} -static int db_debug (lua_State *L) { - for (;;) { - char buffer[LUA_MAXINPUT]; +static int db_debug(lua_State *L) +{ + for (;;) + { + char buffer[LUA_MAXINPUT]; #if defined(LUA_USE_STDIO) - fputs("lua_debug> ", stderr); - if (fgets(buffer, sizeof(buffer), stdin) == 0 || + fputs("lua_debug> ", stderr); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || #else -// luai_writestringerror("%s", "lua_debug>"); - if (lua_readline(L, buffer, "lua_debug>") == 0 || + // luai_writestringerror("%s", "lua_debug>"); + if (lua_readline(L, buffer, "lua_debug>") == 0 || #endif - strcmp(buffer, "cont\n") == 0) - return 0; - if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || - lua_pcall(L, 0, 0, 0)) { + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || lua_pcall(L, 0, 0, 0)) + { #if defined(LUA_USE_STDIO) - fputs(lua_tostring(L, -1), stderr); - fputs("\n", stderr); + fputs(lua_tostring(L, -1), stderr); + fputs("\n", stderr); #else - luai_writestringerror("%s\n", lua_tostring(L, -1)); + luai_writestringerror("%s\n", lua_tostring(L, -1)); #endif + } + lua_settop(L, 0); /* remove eventual returns */ } - lua_settop(L, 0); /* remove eventual returns */ - } } #endif -#define LEVELS1 12 /* size of the first part of the stack */ -#define LEVELS2 10 /* size of the second part of the stack */ - -static int db_errorfb (lua_State *L) { - int level; - int firstpart = 1; /* still before eventual `...' */ - int arg; - lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - if (lua_isnumber(L, arg+2)) { - level = (int)lua_tointeger(L, arg+2); - lua_pop(L, 1); - } - else - level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ - if (lua_gettop(L) == arg) - lua_pushliteral(L, ""); - else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ - else lua_pushliteral(L, "\n"); - lua_pushliteral(L, "stack traceback:"); - while (lua_getstack(L1, level++, &ar)) { - if (level > LEVELS1 && firstpart) { - /* no more than `LEVELS2' more levels? */ - if (!lua_getstack(L1, level+LEVELS2, &ar)) - level--; /* keep going */ - else { - lua_pushliteral(L, "\n\t..."); /* too many levels */ - while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ - level++; - } - firstpart = 0; - continue; +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb(lua_State *L) +{ + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg + 2)) + { + level = (int)lua_tointeger(L, arg + 2); + lua_pop(L, 1); } - lua_pushliteral(L, "\n\t"); - lua_getinfo(L1, "Snl", &ar); - lua_pushfstring(L, "%s:", ar.short_src); - if (ar.currentline > 0) - lua_pushfstring(L, "%d:", ar.currentline); - if (*ar.namewhat != '\0') /* is there a name? */ - lua_pushfstring(L, " in function " LUA_QS, ar.name); - else { - if (*ar.what == 'm') /* main? */ - lua_pushfstring(L, " in main chunk"); - else if (*ar.what == 'C' || *ar.what == 't') - lua_pushliteral(L, " ?"); /* C function or tail call */ - else - lua_pushfstring(L, " in function <%s:%d>", - ar.short_src, ar.linedefined); + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg + 1)) + return 1; /* message is not a string */ + else + lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) + { + if (level > LEVELS1 && firstpart) + { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level + LEVELS2, &ar)) + level--; /* keep going */ + else + { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level + LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else + { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); } lua_concat(L, lua_gettop(L) - arg); - } - lua_concat(L, lua_gettop(L) - arg); - return 1; + return 1; } #undef MIN_OPT_LEVEL @@ -387,26 +418,23 @@ static int db_errorfb (lua_State *L) { #include "lrodefs.h" const LUA_REG_TYPE dblib[] = { #ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL - {LSTRKEY("debug"), LFUNCVAL(db_debug)}, - {LSTRKEY("getfenv"), LFUNCVAL(db_getfenv)}, - {LSTRKEY("gethook"), LFUNCVAL(db_gethook)}, - {LSTRKEY("getinfo"), LFUNCVAL(db_getinfo)}, - {LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)}, + {LSTRKEY("debug"), LFUNCVAL(db_debug)}, + {LSTRKEY("getfenv"), LFUNCVAL(db_getfenv)}, + {LSTRKEY("gethook"), LFUNCVAL(db_gethook)}, + {LSTRKEY("getinfo"), LFUNCVAL(db_getinfo)}, + {LSTRKEY("getlocal"), LFUNCVAL(db_getlocal)}, #endif - {LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)}, + {LSTRKEY("getregistry"), LFUNCVAL(db_getregistry)}, #ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL - {LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)}, - {LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)}, - {LSTRKEY("setfenv"), LFUNCVAL(db_setfenv)}, - {LSTRKEY("sethook"), LFUNCVAL(db_sethook)}, - {LSTRKEY("setlocal"), LFUNCVAL(db_setlocal)}, - {LSTRKEY("setmetatable"), LFUNCVAL(db_setmetatable)}, - {LSTRKEY("setupvalue"), LFUNCVAL(db_setupvalue)}, + {LSTRKEY("getmetatable"), LFUNCVAL(db_getmetatable)}, + {LSTRKEY("getupvalue"), LFUNCVAL(db_getupvalue)}, + {LSTRKEY("setfenv"), LFUNCVAL(db_setfenv)}, + {LSTRKEY("sethook"), LFUNCVAL(db_sethook)}, + {LSTRKEY("setlocal"), LFUNCVAL(db_setlocal)}, + {LSTRKEY("setmetatable"), LFUNCVAL(db_setmetatable)}, + {LSTRKEY("setupvalue"), LFUNCVAL(db_setupvalue)}, #endif - {LSTRKEY("traceback"), LFUNCVAL(db_errorfb)}, - {LNILKEY, LNILVAL} -}; + {LSTRKEY("traceback"), LFUNCVAL(db_errorfb)}, + {LNILKEY, LNILVAL}}; -LUALIB_API int luaopen_debug (lua_State *L) { - LREGISTER(L, LUA_DBLIBNAME, dblib); -} +LUALIB_API int luaopen_debug(lua_State *L) { LREGISTER(L, LUA_DBLIBNAME, dblib); } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ldebug.c b/LuaNode_Esp32/LuaNode32/components/lua/ldebug.c index 0bdc094..ece9c07 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ldebug.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ldebug.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define ldebug_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -25,195 +24,195 @@ #include "ltm.h" #include "lvm.h" +static const char *getfuncname(lua_State *L, CallInfo *ci, const char **name); - -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); - - -static int currentpc (lua_State *L, CallInfo *ci) { - if (!isLua(ci)) return -1; /* function is not a Lua function? */ - if (ci == L->ci) - ci->savedpc = L->savedpc; - return pcRel(ci->savedpc, ci_func(ci)->l.p); +static int currentpc(lua_State *L, CallInfo *ci) +{ + if (!isLua(ci)) + return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; + return pcRel(ci->savedpc, ci_func(ci)->l.p); } - -static int currentline (lua_State *L, CallInfo *ci) { - int pc = currentpc(L, ci); - if (pc < 0) - return -1; /* only active lua functions have current-line information */ - else - return getline(ci_func(ci)->l.p, pc); +static int currentline(lua_State *L, CallInfo *ci) +{ + int pc = currentpc(L, ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); } - /* ** this function can be called asynchronous (e.g. during a signal) */ -LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { - if (func == NULL || mask == 0) { /* turn off hooks? */ - mask = 0; - func = NULL; - } - L->hook = func; - L->basehookcount = count; - resethookcount(L); - L->hookmask = cast_byte(mask); - return 1; -} - - -LUA_API lua_Hook lua_gethook (lua_State *L) { - return L->hook; -} - - -LUA_API int lua_gethookmask (lua_State *L) { - return L->hookmask; -} - - -LUA_API int lua_gethookcount (lua_State *L) { - return L->basehookcount; -} - - -LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { - int status; - CallInfo *ci; - lua_lock(L); - for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { - level--; - if (f_isLua(ci)) /* Lua function? */ - level -= ci->tailcalls; /* skip lost tail calls */ - } - if (level == 0 && ci > L->base_ci) { /* level found? */ - status = 1; - ar->i_ci = cast_int(ci - L->base_ci); - } - else if (level < 0) { /* level is of a lost tail call? */ - status = 1; - ar->i_ci = 0; - } - else status = 0; /* no such level */ - lua_unlock(L); - return status; +LUA_API int lua_sethook(lua_State *L, lua_Hook func, int mask, int count) +{ + if (func == NULL || mask == 0) + { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; } +LUA_API lua_Hook lua_gethook(lua_State *L) { return L->hook; } -static Proto *getluaproto (CallInfo *ci) { - return (isLua(ci) ? ci_func(ci)->l.p : NULL); -} +LUA_API int lua_gethookmask(lua_State *L) { return L->hookmask; } +LUA_API int lua_gethookcount(lua_State *L) { return L->basehookcount; } -static const char *findlocal (lua_State *L, CallInfo *ci, int n) { - const char *name; - Proto *fp = getluaproto(ci); - if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) - return name; /* is a local variable in a Lua function */ - else { - StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; - if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ - return "(*temporary)"; +LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar) +{ + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) + { + level--; + if (f_isLua(ci)) /* Lua function? */ + level -= ci->tailcalls; /* skip lost tail calls */ + } + if (level == 0 && ci > L->base_ci) + { /* level found? */ + status = 1; + ar->i_ci = cast_int(ci - L->base_ci); + } + else if (level < 0) + { /* level is of a lost tail call? */ + status = 1; + ar->i_ci = 0; + } else - return NULL; - } -} - - -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { - CallInfo *ci = L->base_ci + ar->i_ci; - const char *name = findlocal(L, ci, n); - lua_lock(L); - if (name) - luaA_pushobject(L, ci->base + (n - 1)); - lua_unlock(L); - return name; + status = 0; /* no such level */ + lua_unlock(L); + return status; } +static Proto *getluaproto(CallInfo *ci) { return (isLua(ci) ? ci_func(ci)->l.p : NULL); } -LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { - CallInfo *ci = L->base_ci + ar->i_ci; - const char *name = findlocal(L, ci, n); - lua_lock(L); - if (name) - setobjs2s(L, ci->base + (n - 1), L->top - 1); - L->top--; /* pop value */ - lua_unlock(L); - return name; +static const char *findlocal(lua_State *L, CallInfo *ci, int n) +{ + const char *name; + Proto *fp = getluaproto(ci); + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) + return name; /* is a local variable in a Lua function */ + else + { + StkId limit = (ci == L->ci) ? L->top : (ci + 1)->func; + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + return "(*temporary)"; + else + return NULL; + } } - -static void funcinfo (lua_Debug *ar, Closure *cl, void *plight) { - if (plight || cl->c.isC) { - ar->source = "=[C]"; - ar->linedefined = -1; - ar->lastlinedefined = -1; - ar->what = "C"; - } - else { - ar->source = getstr(cl->l.p->source); - ar->linedefined = cl->l.p->linedefined; - ar->lastlinedefined = cl->l.p->lastlinedefined; - ar->what = (ar->linedefined == 0) ? "main" : "Lua"; - } - luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n) +{ + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + luaA_pushobject(L, ci->base + (n - 1)); + lua_unlock(L); + return name; +} + +LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n) +{ + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + +static void funcinfo(lua_Debug *ar, Closure *cl, void *plight) +{ + if (plight || cl->c.isC) + { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else + { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); } - -static void info_tailcall (lua_Debug *ar) { - ar->name = ar->namewhat = ""; - ar->what = "tail"; - ar->lastlinedefined = ar->linedefined = ar->currentline = -1; - ar->source = "=(tail call)"; - luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); - ar->nups = 0; +static void info_tailcall(lua_Debug *ar) +{ + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; } - - static void collectvalidlines (lua_State *L, Closure *f) { - if (f == NULL || f->c.isC) { - setnilvalue(L->top); - } - else { - # define INFO_FILL_BYTE 0x7F -# define INFO_DELTA_MASK 0x80 -# define INFO_SIGN_MASK 0x40 -# define INFO_DELTA_6BITS 0x3F -# define INFO_DELTA_7BITS 0x7F -# define INFO_MAX_LINECNT 126 - - Table *t = luaH_new(L, 0, 0); +static void collectvalidlines(lua_State *L, Closure *f) +{ + if (f == NULL || f->c.isC) + { + setnilvalue(L->top); + } + else + { +#define INFO_FILL_BYTE 0x7F +#define INFO_DELTA_MASK 0x80 +#define INFO_SIGN_MASK 0x40 +#define INFO_DELTA_6BITS 0x3F +#define INFO_DELTA_7BITS 0x7F +#define INFO_MAX_LINECNT 126 + + Table *t = luaH_new(L, 0, 0); #ifdef LUA_OPTIMIZE_DEBUG - int line = 0; - unsigned char *p = f->l.p->packedlineinfo; - if (p) { - for (; *p && *p != INFO_FILL_BYTE; ) { - if (*p & INFO_DELTA_MASK) { /* line delta */ - int delta = *p & INFO_DELTA_6BITS; - unsigned char sign = *p++ & INFO_SIGN_MASK; - int shift; - for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) { - delta += (*p & INFO_DELTA_7BITS)<l.p->packedlineinfo; + if (p) + { + for (; *p && *p != INFO_FILL_BYTE;) + { + if (*p & INFO_DELTA_MASK) + { /* line delta */ + int delta = *p & INFO_DELTA_6BITS; + unsigned char sign = *p++ & INFO_SIGN_MASK; + int shift; + for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) + { delta += (*p & INFO_DELTA_7BITS) << shift; } + line += sign ? -delta : delta + 2; + } + else + { + line++; + } + p++; + setbvalue(luaH_setnum(L, t, line), 1); + } } - p++; - setbvalue(luaH_setnum(L, t, line), 1); - } - } #else - int *lineinfo = f->l.p->lineinfo; - int i; - for (i=0; il.p->sizelineinfo; i++) - setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i = 0; i < f->l.p->sizelineinfo; i++) setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); #endif - sethvalue(L, L->top, t); - } - incr_top(L); - } + sethvalue(L, L->top, t); + } + incr_top(L); +} #ifdef LUA_OPTIMIZE_DEBUG /* @@ -221,360 +220,423 @@ static void info_tailcall (lua_Debug *ar) { * and the while loop will be executed roughly half the number of non-blank * source lines in the Lua function and these tend to be short. */ -int luaG_getline (const Proto *f, int pc) { - int line = 0, thispc = 0, nextpc; - unsigned char *p; - - for (p = f->packedlineinfo; *p && *p != INFO_FILL_BYTE;) { - if (*p & INFO_DELTA_MASK) { /* line delta */ - int delta = *p & INFO_DELTA_6BITS; - unsigned char sign = *p++ & INFO_SIGN_MASK; - int shift; - for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) { - delta += (*p & INFO_DELTA_7BITS)<packedlineinfo; *p && *p != INFO_FILL_BYTE;) + { + if (*p & INFO_DELTA_MASK) + { /* line delta */ + int delta = *p & INFO_DELTA_6BITS; + unsigned char sign = *p++ & INFO_SIGN_MASK; + int shift; + for (shift = 6; *p & INFO_DELTA_MASK; p++, shift += 7) { delta += (*p & INFO_DELTA_7BITS) << shift; } + line += sign ? -delta : delta + 2; + } + else + { + line++; + } + lua_assert(*p < 127); + nextpc = thispc + *p++; + if (thispc <= pc && pc < nextpc) + { + return line; + } + thispc = nextpc; } - lua_assert(*p<127); - nextpc = thispc + *p++; - if (thispc <= pc && pc < nextpc) { - return line; + lua_assert(0); + return 0; +} + +static int stripdebug(lua_State *L, Proto *f, int level) +{ + int len = 0, sizepackedlineinfo; + TString *dummy; + switch (level) + { + case 3: + sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo)) + 1; + f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char); + len += sizepackedlineinfo; + case 2: + len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)); + f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) + + f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *)); + f->sizelocvars = 0; + f->sizeupvalues = 0; } - thispc = nextpc; - } - lua_assert(0); - return 0; + return len; } -static int stripdebug (lua_State *L, Proto *f, int level) { - int len = 0, sizepackedlineinfo; - TString* dummy; - switch (level) { - case 3: - sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1; - f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char); - len += sizepackedlineinfo; - case 2: - len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)); - f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); - f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); - len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) + - f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *)); - f->sizelocvars = 0; - f->sizeupvalues = 0; - } - return len; -} - -/* This is a recursive function so it's stack size has been kept to a minimum! */ -LUA_API int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){ - int len = 0, i; - if (recv != 0 && f->sizep != 0) { - for(i=0;isizep;i++) len += luaG_stripdebug(L, f->p[i], level, recv); - } - len += stripdebug (L, f, level); - return len; +/* This is a recursive function so it's stack size has been kept to a minimum! + */ +LUA_API int luaG_stripdebug(lua_State *L, Proto *f, int level, int recv) +{ + int len = 0, i; + if (recv != 0 && f->sizep != 0) + { + for (i = 0; i < f->sizep; i++) len += luaG_stripdebug(L, f->p[i], level, recv); + } + len += stripdebug(L, f, level); + return len; } #endif - -static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, - Closure *f, void *plight, CallInfo *ci) { - int status = 1; - if (plight == NULL && f == NULL) { - info_tailcall(ar); - return status; - } - for (; *what; what++) { - switch (*what) { - case 'S': { - funcinfo(ar, f, plight); - break; - } - case 'l': { - ar->currentline = (ci) ? currentline(L, ci) : -1; - break; - } - case 'u': { - ar->nups = f ? f->c.nupvalues : 0; - break; - } - case 'n': { - ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; - if (ar->namewhat == NULL) { - ar->namewhat = ""; /* not found */ - ar->name = NULL; +static int auxgetinfo(lua_State *L, const char *what, lua_Debug *ar, Closure *f, void *plight, CallInfo *ci) +{ + int status = 1; + if (plight == NULL && f == NULL) + { + info_tailcall(ar); + return status; + } + for (; *what; what++) + { + switch (*what) + { + case 'S': + { + funcinfo(ar, f, plight); + break; + } + case 'l': + { + ar->currentline = (ci) ? currentline(L, ci) : -1; + break; + } + case 'u': + { + ar->nups = f ? f->c.nupvalues : 0; + break; + } + case 'n': + { + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + if (ar->namewhat == NULL) + { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: + status = 0; /* invalid option */ } - break; - } - case 'L': - case 'f': /* handled by lua_getinfo */ - break; - default: status = 0; /* invalid option */ } - } - return status; + return status; } - -LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { - int status; - Closure *f = NULL; - CallInfo *ci = NULL; - void *plight = NULL; - lua_lock(L); - if (*what == '>') { - StkId func = L->top - 1; - luai_apicheck(L, ttisfunction(func) || ttislightfunction(func)); - what++; /* skip the '>' */ - if (ttisfunction(func)) - f = clvalue(func); - else - plight = fvalue(func); - L->top--; /* pop function */ - } - else if (ar->i_ci != 0) { /* no tail call? */ - ci = L->base_ci + ar->i_ci; - lua_assert(ttisfunction(ci->func) || ttislightfunction(ci->func)); - if (ttisfunction(ci->func)) - f = clvalue(ci->func); - else - plight = fvalue(ci->func); - } - status = auxgetinfo(L, what, ar, f, plight, ci); - if (strchr(what, 'f')) { - if (f != NULL) - setclvalue(L, L->top, f) - else if (plight != NULL) - setfvalue(L->top, plight) - else - setnilvalue(L->top); - incr_top(L); - } - if (strchr(what, 'L')) - collectvalidlines(L, f); - lua_unlock(L); - return status; +LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar) +{ + int status; + Closure *f = NULL; + CallInfo *ci = NULL; + void *plight = NULL; + lua_lock(L); + if (*what == '>') + { + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func) || ttislightfunction(func)); + what++; /* skip the '>' */ + if (ttisfunction(func)) + f = clvalue(func); + else + plight = fvalue(func); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) + { /* no tail call? */ + ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->func) || ttislightfunction(ci->func)); + if (ttisfunction(ci->func)) + f = clvalue(ci->func); + else + plight = fvalue(ci->func); + } + status = auxgetinfo(L, what, ar, f, plight, ci); + if (strchr(what, 'f')) + { + if (f != NULL) + setclvalue(L, L->top, f) else if (plight != NULL) setfvalue(L->top, plight) else setnilvalue(L->top); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); + lua_unlock(L); + return status; } - /* ** {====================================================== ** Symbolic Execution and code checker ** ======================================================= */ -#define check(x) if (!(x)) return 0; +#define check(x) \ + if (!(x)) \ + return 0; -#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) +#define checkjump(pt, pc) check(0 <= pc && pc < pt->sizecode) -#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) +#define checkreg(pt, reg) check((reg) < (pt)->maxstacksize) - - -static int precheck (const Proto *pt) { - check(pt->maxstacksize <= MAXSTACK); - check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); - check(!(pt->is_vararg & VARARG_NEEDSARG) || - (pt->is_vararg & VARARG_HASARG)); - check(pt->sizeupvalues <= pt->nups); +static int precheck(const Proto *pt) +{ + check(pt->maxstacksize <= MAXSTACK); + check(pt->numparams + (pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || (pt->is_vararg & VARARG_HASARG)); + check(pt->sizeupvalues <= pt->nups); #ifndef LUA_OPTIMIZE_DEBUG - check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); #endif - check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); - return 1; -} - - -#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) - -int luaG_checkopenop (Instruction i) { - switch (GET_OPCODE(i)) { - case OP_CALL: - case OP_TAILCALL: - case OP_RETURN: - case OP_SETLIST: { - check(GETARG_B(i) == 0); - return 1; + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode - 1]) == OP_RETURN); + return 1; +} + +#define checkopenop(pt, pc) luaG_checkopenop((pt)->code[(pc) + 1]) + +int luaG_checkopenop(Instruction i) +{ + switch (GET_OPCODE(i)) + { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: + case OP_SETLIST: + { + check(GETARG_B(i) == 0); + return 1; + } + default: + return 0; /* invalid instruction after an open call */ } - default: return 0; /* invalid instruction after an open call */ - } -} - - -static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { - switch (mode) { - case OpArgN: check(r == 0); break; - case OpArgU: break; - case OpArgR: checkreg(pt, r); break; - case OpArgK: - check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); - break; - } - return 1; } - -static Instruction symbexec (const Proto *pt, int lastpc, int reg) { - int pc; - int last; /* stores position of last instruction that changed `reg' */ - last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ - check(precheck(pt)); - for (pc = 0; pc < lastpc; pc++) { - Instruction i = pt->code[pc]; - OpCode op = GET_OPCODE(i); - int a = GETARG_A(i); - int b = 0; - int c = 0; - check(op < NUM_OPCODES); - checkreg(pt, a); - switch (getOpMode(op)) { - case iABC: { - b = GETARG_B(i); - c = GETARG_C(i); - check(checkArgMode(pt, b, getBMode(op))); - check(checkArgMode(pt, c, getCMode(op))); - break; - } - case iABx: { - b = GETARG_Bx(i); - if (getBMode(op) == OpArgK) check(b < pt->sizek); - break; - } - case iAsBx: { - b = GETARG_sBx(i); - if (getBMode(op) == OpArgR) { - int dest = pc+1+b; - check(0 <= dest && dest < pt->sizecode); - if (dest > 0) { - int j; - /* check that it does not jump to a setlist count; this - is tricky, because the count from a previous setlist may - have the same value of an invalid setlist; so, we must - go all the way back to the first of them (if any) */ - for (j = 0; j < dest; j++) { - Instruction d = pt->code[dest-1-j]; - if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; - } - /* if 'j' is even, previous value is not a setlist (even if - it looks like one) */ - check((j&1) == 0); - } - } - break; - } - } - if (testAMode(op)) { - if (a == reg) last = pc; /* change register `a' */ +static int checkArgMode(const Proto *pt, int r, enum OpArgMask mode) +{ + switch (mode) + { + case OpArgN: + check(r == 0); + break; + case OpArgU: + break; + case OpArgR: + checkreg(pt, r); + break; + case OpArgK: + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); + break; } - if (testTMode(op)) { - check(pc+2 < pt->sizecode); /* check skip */ - check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); - } - switch (op) { - case OP_LOADBOOL: { - if (c == 1) { /* does it jump? */ - check(pc+2 < pt->sizecode); /* check its jump */ - check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || - GETARG_C(pt->code[pc+1]) != 0); - } - break; - } - case OP_LOADNIL: { - if (a <= reg && reg <= b) - last = pc; /* set registers from `a' to `b' */ - break; - } - case OP_GETUPVAL: - case OP_SETUPVAL: { - check(b < pt->nups); - break; - } - case OP_GETGLOBAL: - case OP_SETGLOBAL: { - check(ttisstring(&pt->k[b])); - break; - } - case OP_SELF: { - checkreg(pt, a+1); - if (reg == a+1) last = pc; - break; - } - case OP_CONCAT: { - check(b < c); /* at least two operands */ - break; - } - case OP_TFORLOOP: { - check(c >= 1); /* at least one result (control variable) */ - checkreg(pt, a+2+c); /* space for results */ - if (reg >= a+2) last = pc; /* affect all regs above its base */ - break; - } - case OP_FORLOOP: - case OP_FORPREP: - checkreg(pt, a+3); - /* go through */ - case OP_JMP: { - int dest = pc+1+b; - /* not full check and jump is forward and do not skip `lastpc'? */ - if (reg != NO_REG && pc < dest && dest <= lastpc) - pc += b; /* do the jump */ - break; - } - case OP_CALL: - case OP_TAILCALL: { - if (b != 0) { - checkreg(pt, a+b-1); + return 1; +} + +static Instruction symbexec(const Proto *pt, int lastpc, int reg) +{ + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode - 1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) + { + Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + check(op < NUM_OPCODES); + checkreg(pt, a); + switch (getOpMode(op)) + { + case iABC: + { + b = GETARG_B(i); + c = GETARG_C(i); + check(checkArgMode(pt, b, getBMode(op))); + check(checkArgMode(pt, c, getCMode(op))); + break; + } + case iABx: + { + b = GETARG_Bx(i); + if (getBMode(op) == OpArgK) + check(b < pt->sizek); + break; + } + case iAsBx: + { + b = GETARG_sBx(i); + if (getBMode(op) == OpArgR) + { + int dest = pc + 1 + b; + check(0 <= dest && dest < pt->sizecode); + if (dest > 0) + { + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist + may have the same value of an invalid setlist; so, we + must go all the way back to the first of them (if + any) */ + for (j = 0; j < dest; j++) + { + Instruction d = pt->code[dest - 1 - j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) + break; + } + /* if 'j' is even, previous value is not a setlist (even + if it looks like one) */ + check((j & 1) == 0); + } + } + break; + } } - c--; /* c = num. returns */ - if (c == LUA_MULTRET) { - check(checkopenop(pt, pc)); + if (testAMode(op)) + { + if (a == reg) + last = pc; /* change register `a' */ } - else if (c != 0) - checkreg(pt, a+c-1); - if (reg >= a) last = pc; /* affect all registers above base */ - break; - } - case OP_RETURN: { - b--; /* b = num. returns */ - if (b > 0) checkreg(pt, a+b-1); - break; - } - case OP_SETLIST: { - if (b > 0) checkreg(pt, a + b); - if (c == 0) { - pc++; - check(pc < pt->sizecode - 1); + if (testTMode(op)) + { + check(pc + 2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc + 1]) == OP_JMP); } - break; - } - case OP_CLOSURE: { - int nup, j; - check(b < pt->sizep); - nup = pt->p[b]->nups; - check(pc + nup < pt->sizecode); - for (j = 1; j <= nup; j++) { - OpCode op1 = GET_OPCODE(pt->code[pc + j]); - check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + switch (op) + { + case OP_LOADBOOL: + { + if (c == 1) + { /* does it jump? */ + check(pc + 2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc + 1]) != OP_SETLIST || GETARG_C(pt->code[pc + 1]) != 0); + } + break; + } + case OP_LOADNIL: + { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: + { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: + { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: + { + checkreg(pt, a + 1); + if (reg == a + 1) + last = pc; + break; + } + case OP_CONCAT: + { + check(b < c); /* at least two operands */ + break; + } + case OP_TFORLOOP: + { + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a + 2 + c); /* space for results */ + if (reg >= a + 2) + last = pc; /* affect all regs above its base */ + break; + } + case OP_FORLOOP: + case OP_FORPREP: + checkreg(pt, a + 3); + /* go through */ + case OP_JMP: + { + int dest = pc + 1 + b; + /* not full check and jump is forward and do not skip `lastpc'? + */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: + { + if (b != 0) + { + checkreg(pt, a + b - 1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) + { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a + c - 1); + if (reg >= a) + last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: + { + b--; /* b = num. returns */ + if (b > 0) + checkreg(pt, a + b - 1); + break; + } + case OP_SETLIST: + { + if (b > 0) + checkreg(pt, a + b); + if (c == 0) + { + pc++; + check(pc < pt->sizecode - 1); + } + break; + } + case OP_CLOSURE: + { + int nup, j; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (j = 1; j <= nup; j++) + { + OpCode op1 = GET_OPCODE(pt->code[pc + j]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + if (reg != NO_REG) /* tracing? */ + pc += nup; /* do not 'execute' these pseudo-instructions */ + break; + } + case OP_VARARG: + { + check((pt->is_vararg & VARARG_ISVARARG) && !(pt->is_vararg & VARARG_NEEDSARG)); + b--; + if (b == LUA_MULTRET) + check(checkopenop(pt, pc)); + checkreg(pt, a + b - 1); + break; + } + default: + break; } - if (reg != NO_REG) /* tracing? */ - pc += nup; /* do not 'execute' these pseudo-instructions */ - break; - } - case OP_VARARG: { - check((pt->is_vararg & VARARG_ISVARARG) && - !(pt->is_vararg & VARARG_NEEDSARG)); - b--; - if (b == LUA_MULTRET) check(checkopenop(pt, pc)); - checkreg(pt, a+b-1); - break; - } - default: break; } - } - return pt->code[last]; + return pt->code[last]; } #undef check @@ -583,159 +645,163 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { /* }====================================================== */ +int luaG_checkcode(const Proto *pt) { return (symbexec(pt, pt->sizecode, NO_REG) != 0); } -int luaG_checkcode (const Proto *pt) { - return (symbexec(pt, pt->sizecode, NO_REG) != 0); -} - - -static const char *kname (Proto *p, int c) { - if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) - return svalue(&p->k[INDEXK(c)]); - else - return "?"; -} - - -static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, - const char **name) { - if (isLua(ci)) { /* a Lua function? */ - Proto *p = ci_func(ci)->l.p; - int pc = currentpc(L, ci); - Instruction i; - *name = luaF_getlocalname(p, stackpos+1, pc); - if (*name) /* is a local? */ - return "local"; - i = symbexec(p, pc, stackpos); /* try symbolic execution */ - lua_assert(pc != -1); - switch (GET_OPCODE(i)) { - case OP_GETGLOBAL: { - int g = GETARG_Bx(i); /* global index */ - lua_assert(ttisstring(&p->k[g])); - *name = svalue(&p->k[g]); - return "global"; - } - case OP_MOVE: { - int a = GETARG_A(i); - int b = GETARG_B(i); /* move from `b' to `a' */ - if (b < a) - return getobjname(L, ci, b, name); /* get name for `b' */ - break; - } - case OP_GETTABLE: { - int k = GETARG_C(i); /* key index */ - *name = kname(p, k); - return "field"; - } - case OP_GETUPVAL: { - int u = GETARG_B(i); /* upvalue index */ - *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; - return "upvalue"; - } - case OP_SELF: { - int k = GETARG_C(i); /* key index */ - *name = kname(p, k); - return "method"; - } - default: break; +static const char *kname(Proto *p, int c) +{ + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) + return svalue(&p->k[INDEXK(c)]); + else + return "?"; +} + +static const char *getobjname(lua_State *L, CallInfo *ci, int stackpos, const char **name) +{ + if (isLua(ci)) + { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(L, ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos + 1, pc); + if (*name) /* is a local? */ + return "local"; + i = symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) + { + case OP_GETGLOBAL: + { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: + { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(L, ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: + { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_GETUPVAL: + { + int u = GETARG_B(i); /* upvalue index */ + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + return "upvalue"; + } + case OP_SELF: + { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: + break; + } } - } - return NULL; /* no useful name found */ + return NULL; /* no useful name found */ } - -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - Instruction i; - if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) - return NULL; /* calling function is not Lua (or is unknown) */ - ci--; /* calling function */ - i = ci_func(ci)->l.p->code[currentpc(L, ci)]; - if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || - GET_OPCODE(i) == OP_TFORLOOP) - return getobjname(L, ci, GETARG_A(i), name); - else - return NULL; /* no useful name can be found */ +static const char *getfuncname(lua_State *L, CallInfo *ci, const char **name) +{ + Instruction i; + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || GET_OPCODE(i) == OP_TFORLOOP) + return getobjname(L, ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ } - /* only ANSI way to check whether a pointer points to an array */ -static int isinstack (CallInfo *ci, const TValue *o) { - StkId p; - for (p = ci->base; p < ci->top; p++) - if (o == p) return 1; - return 0; -} - - -void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { - const char *name = NULL; - const char *t = luaT_typenames[ttype(o)]; - const char *kind = (isinstack(L->ci, o)) ? - getobjname(L, L->ci, cast_int(o - L->base), &name) : - NULL; - if (kind) - luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", - op, kind, name, t); - else - luaG_runerror(L, "attempt to %s a %s value", op, t); -} - - -void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { - if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; - lua_assert(!ttisstring(p1) && !ttisnumber(p1)); - luaG_typeerror(L, p1, "concatenate"); +static int isinstack(CallInfo *ci, const TValue *o) +{ + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) + return 1; + return 0; +} + +void luaG_typeerror(lua_State *L, const TValue *o, const char *op) +{ + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? getobjname(L, L->ci, cast_int(o - L->base), &name) : NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); } - -void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { - TValue temp; - if (luaV_tonumber(p1, &temp) == NULL) - p2 = p1; /* first operand is wrong */ - luaG_typeerror(L, p2, "perform arithmetic on"); +void luaG_concaterror(lua_State *L, StkId p1, StkId p2) +{ + if (ttisstring(p1) || ttisnumber(p1)) + p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); } - -int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { - const char *t1 = luaT_typenames[ttype(p1)]; - const char *t2 = luaT_typenames[ttype(p2)]; - if (t1[2] == t2[2]) - luaG_runerror(L, "attempt to compare two %s values", t1); - else - luaG_runerror(L, "attempt to compare %s with %s", t1, t2); - return 0; +void luaG_aritherror(lua_State *L, const TValue *p1, const TValue *p2) +{ + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); } - -static void addinfo (lua_State *L, const char *msg) { - CallInfo *ci = L->ci; - if (isLua(ci)) { /* is Lua code? */ - char buff[LUA_IDSIZE]; /* add file:line information */ - int line = currentline(L, ci); - luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); - luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); - } +int luaG_ordererror(lua_State *L, const TValue *p1, const TValue *p2) +{ + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + +static void addinfo(lua_State *L, const char *msg) +{ + CallInfo *ci = L->ci; + if (isLua(ci)) + { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(L, ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } } - -void luaG_errormsg (lua_State *L) { - if (L->errfunc != 0) { /* is there an error handling function? */ - StkId errfunc = restorestack(L, L->errfunc); - if (!ttisfunction(errfunc) && !ttislightfunction(errfunc)) luaD_throw(L, LUA_ERRERR); - setobjs2s(L, L->top, L->top - 1); /* move argument */ - setobjs2s(L, L->top - 1, errfunc); /* push function */ - incr_top(L); - luaD_call(L, L->top - 2, 1); /* call it */ - } - luaD_throw(L, LUA_ERRRUN); +void luaG_errormsg(lua_State *L) +{ + if (L->errfunc != 0) + { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc) && !ttislightfunction(errfunc)) + luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); } - -void luaG_runerror (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - addinfo(L, luaO_pushvfstring(L, fmt, argp)); - va_end(argp); - luaG_errormsg(L); +void luaG_runerror(lua_State *L, const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ldo.c b/LuaNode_Esp32/LuaNode32/components/lua/ldo.c index 9a2ddd0..d2785b5 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ldo.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ldo.c @@ -29,508 +29,519 @@ #include "lvm.h" #include "lzio.h" - - - /* ** {====================================================== ** Error-recovery functions ** ======================================================= */ - /* chain list of long jump buffers */ -struct lua_longjmp { - struct lua_longjmp *previous; - luai_jmpbuf b; - volatile int status; /* error code */ +struct lua_longjmp +{ + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ }; - -void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { - switch (errcode) { - case LUA_ERRMEM: { - ptrdiff_t oldtopr = savestack(L, oldtop); - setsvalue2s(L, restorestack(L, oldtopr), luaS_newliteral(L, MEMERRMSG)); - break; - } - case LUA_ERRERR: { - ptrdiff_t oldtopr = savestack(L, oldtop); - setsvalue2s(L, restorestack(L, oldtopr), luaS_newliteral(L, "error in error handling")); - break; +void luaD_seterrorobj(lua_State *L, int errcode, StkId oldtop) +{ + switch (errcode) + { + case LUA_ERRMEM: + { + ptrdiff_t oldtopr = savestack(L, oldtop); + setsvalue2s(L, restorestack(L, oldtopr), luaS_newliteral(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: + { + ptrdiff_t oldtopr = savestack(L, oldtop); + setsvalue2s(L, restorestack(L, oldtopr), luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: + { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } } - case LUA_ERRSYNTAX: - case LUA_ERRRUN: { - setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ - break; - } - } - L->top = oldtop + 1; + L->top = oldtop + 1; } - -static void restore_stack_limit (lua_State *L) { - lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); - if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ - int inuse = cast_int(L->ci - L->base_ci); - if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ - luaD_reallocCI(L, LUAI_MAXCALLS); - } +static void restore_stack_limit(lua_State *L) +{ + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + if (L->size_ci > LUAI_MAXCALLS) + { /* there was an overflow? */ + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); + } } - -static void resetstack (lua_State *L, int status) { - L->ci = L->base_ci; - L->base = L->ci->base; - luaF_close(L, L->base); /* close eventual pending closures */ - luaD_seterrorobj(L, status, L->base); - L->nCcalls = L->baseCcalls; - L->allowhook = 1; - restore_stack_limit(L); - L->errfunc = 0; - L->errorJmp = NULL; +static void resetstack(lua_State *L, int status) +{ + L->ci = L->base_ci; + L->base = L->ci->base; + luaF_close(L, L->base); /* close eventual pending closures */ + luaD_seterrorobj(L, status, L->base); + L->nCcalls = L->baseCcalls; + L->allowhook = 1; + restore_stack_limit(L); + L->errfunc = 0; + L->errorJmp = NULL; } - -void luaD_throw (lua_State *L, int errcode) { - unfixedstack(L); /* make sure the fixedstack & block_gc flags get reset. */ - unset_block_gc(L); - if (L->errorJmp) { - L->errorJmp->status = errcode; - LUAI_THROW(L, L->errorJmp); - } - else { - L->status = cast_byte(errcode); - if (G(L)->panic) { - resetstack(L, errcode); - lua_unlock(L); - G(L)->panic(L); +void luaD_throw(lua_State *L, int errcode) +{ + unfixedstack(L); /* make sure the fixedstack & block_gc flags get reset. */ + unset_block_gc(L); + if (L->errorJmp) + { + L->errorJmp->status = errcode; + LUAI_THROW(L, L->errorJmp); + } + else + { + L->status = cast_byte(errcode); + if (G(L)->panic) + { + resetstack(L, errcode); + lua_unlock(L); + G(L)->panic(L); + } + // c_exit(EXIT_FAILURE); } - // c_exit(EXIT_FAILURE); - } } - -int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { - struct lua_longjmp lj; - lj.status = 0; - lj.previous = L->errorJmp; /* chain new error handler */ - L->errorJmp = &lj; - LUAI_TRY(L, &lj, - (*f)(L, ud); - ); - L->errorJmp = lj.previous; /* restore old error handler */ - return lj.status; +int luaD_rawrunprotected(lua_State *L, Pfunc f, void *ud) +{ + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, (*f)(L, ud);); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; } /* }====================================================== */ - -static void correctstack (lua_State *L, TValue *oldstack) { - CallInfo *ci; - GCObject *up; - L->top = (L->top - oldstack) + L->stack; - for (up = L->openupval; up != NULL; up = up->gch.next) - gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; - for (ci = L->base_ci; ci <= L->ci; ci++) { - ci->top = (ci->top - oldstack) + L->stack; - ci->base = (ci->base - oldstack) + L->stack; - ci->func = (ci->func - oldstack) + L->stack; - } - L->base = (L->base - oldstack) + L->stack; -} - - -void luaD_reallocstack (lua_State *L, int newsize) { - TValue *oldstack = L->stack; - int realsize = newsize + 1 + EXTRA_STACK; - lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); - luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); - L->stacksize = realsize; - L->stack_last = L->stack+newsize; - correctstack(L, oldstack); +static void correctstack(lua_State *L, TValue *oldstack) +{ + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) + { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; } - -void luaD_reallocCI (lua_State *L, int newsize) { - CallInfo *oldci = L->base_ci; - luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); - L->size_ci = newsize; - L->ci = (L->ci - oldci) + L->base_ci; - L->end_ci = L->base_ci + L->size_ci - 1; +void luaD_reallocstack(lua_State *L, int newsize) +{ + TValue *oldstack = L->stack; + int realsize = newsize + 1 + EXTRA_STACK; + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); + L->stacksize = realsize; + L->stack_last = L->stack + newsize; + correctstack(L, oldstack); } - -void luaD_growstack (lua_State *L, int n) { - if (n <= L->stacksize) /* double size is enough? */ - luaD_reallocstack(L, 2*L->stacksize); - else - luaD_reallocstack(L, L->stacksize + n); +void luaD_reallocCI(lua_State *L, int newsize) +{ + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; } - -static CallInfo *growCI (lua_State *L) { - if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ - luaD_throw(L, LUA_ERRERR); - else { - luaD_reallocCI(L, 2*L->size_ci); - if (L->size_ci > LUAI_MAXCALLS) - luaG_runerror(L, "stack overflow"); - } - return ++L->ci; +void luaD_growstack(lua_State *L, int n) +{ + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2 * L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n); } - -void luaD_callhook (lua_State *L, int event, int line) { - lua_Hook hook = L->hook; - if (hook && L->allowhook) { - ptrdiff_t top = savestack(L, L->top); - ptrdiff_t ci_top = savestack(L, L->ci->top); - lua_Debug ar; - ar.event = event; - ar.currentline = line; - if (event == LUA_HOOKTAILRET) - ar.i_ci = 0; /* tail call; no debug information about it */ +static CallInfo *growCI(lua_State *L) +{ + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); else - ar.i_ci = cast_int(L->ci - L->base_ci); - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - L->ci->top = L->top + LUA_MINSTACK; - lua_assert(L->ci->top <= L->stack_last); - L->allowhook = 0; /* cannot call hooks inside a hook */ - lua_unlock(L); - (*hook)(L, &ar); - lua_lock(L); - lua_assert(!L->allowhook); - L->allowhook = 1; - L->ci->top = restorestack(L, ci_top); - L->top = restorestack(L, top); - } + { + luaD_reallocCI(L, 2 * L->size_ci); + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } + return ++L->ci; } +void luaD_callhook(lua_State *L, int event, int line) +{ + lua_Hook hook = L->hook; + if (hook && L->allowhook) + { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = cast_int(L->ci - L->base_ci); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + lua_assert(L->ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} -static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { - int i; - int nfixargs = p->numparams; +static StkId adjust_varargs(lua_State *L, Proto *p, int actual) +{ + int i; + int nfixargs = p->numparams; #if defined(LUA_COMPAT_VARARG) - Table *htab = NULL; + Table *htab = NULL; #endif - StkId base, fixed; - for (; actual < nfixargs; ++actual) - setnilvalue(L->top++); + StkId base, fixed; + for (; actual < nfixargs; ++actual) setnilvalue(L->top++); #if defined(LUA_COMPAT_VARARG) - if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ - int nvar = actual - nfixargs; /* number of extra arguments */ - lua_assert(p->is_vararg & VARARG_HASARG); - luaC_checkGC(L); - htab = luaH_new(L, nvar, 1); /* create `arg' table */ - sethvalue2s(L, L->top, htab); /* put table on stack */ - incr_top(L); - fixedstack(L); - for (i=0; itop - 1 - nvar + i); - unfixedstack(L); - /* store counter in field `n' */ - setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); - L->top--; /* remove table from stack */ - } + if (p->is_vararg & VARARG_NEEDSARG) + { /* compat. with old-style vararg? */ + int nvar = actual - nfixargs; /* number of extra arguments */ + lua_assert(p->is_vararg & VARARG_HASARG); + luaC_checkGC(L); + htab = luaH_new(L, nvar, 1); /* create `arg' table */ + sethvalue2s(L, L->top, htab); /* put table on stack */ + incr_top(L); + fixedstack(L); + for (i = 0; i < nvar; i++) /* put extra arguments into `arg' table */ + setobj2n(L, luaH_setnum(L, htab, i + 1), L->top - 1 - nvar + i); + unfixedstack(L); + /* store counter in field `n' */ + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); + L->top--; /* remove table from stack */ + } #endif - /* move fixed parameters to final position */ - fixed = L->top - actual; /* first fixed argument */ - base = L->top; /* final position of first argument */ - for (i=0; itop++, fixed+i); - setnilvalue(fixed+i); - } + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i = 0; i < nfixargs; i++) + { + setobjs2s(L, L->top++, fixed + i); + setnilvalue(fixed + i); + } #if defined(LUA_COMPAT_VARARG) - /* add `arg' parameter */ - if (htab) { - sethvalue(L, L->top++, htab); - lua_assert(iswhite(obj2gco(htab))); - } + /* add `arg' parameter */ + if (htab) + { + sethvalue(L, L->top++, htab); + lua_assert(iswhite(obj2gco(htab))); + } #endif - return base; + return base; } - -static StkId tryfuncTM (lua_State *L, StkId func) { - const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); - StkId p; - ptrdiff_t funcr = savestack(L, func); - if (!ttisfunction(tm)) - luaG_typeerror(L, func, "call"); - /* Open a hole inside the stack at `func' */ - for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); - incr_top(L); - func = restorestack(L, funcr); /* previous call may change stack */ - setobj2s(L, func, tm); /* tag method is the new function to be called */ - return func; +static StkId tryfuncTM(lua_State *L, StkId func) +{ + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p - 1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; } - - -#define inc_ci(L) \ - ((L->ci == L->end_ci) ? growCI(L) : \ - (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) - - -int luaD_precall (lua_State *L, StkId func, int nresults) { - ptrdiff_t funcr; - LClosure *cl = NULL; - if (!ttisfunction(func) && !ttislightfunction(func)) /* `func' is not a function? */ - func = tryfuncTM(L, func); /* check the `function' tag method */ - funcr = savestack(L, func); - if (ttisfunction(func)) - cl = &clvalue(func)->l; - L->ci->savedpc = L->savedpc; - if (cl && !cl->isC) { /* Lua function? prepare its call */ - CallInfo *ci; - StkId st, base; - Proto *p = cl->p; - luaD_checkstack(L, p->maxstacksize); - func = restorestack(L, funcr); - if (!p->is_vararg) { /* no varargs? */ - base = func + 1; - if (L->top > base + p->numparams) - L->top = base + p->numparams; - } - else { /* vararg function */ - int nargs = cast_int(L->top - func) - 1; - base = adjust_varargs(L, p, nargs); - func = restorestack(L, funcr); /* previous call may change the stack */ - } - ci = inc_ci(L); /* now `enter' new function */ - ci->func = func; - L->base = ci->base = base; - ci->top = L->base + p->maxstacksize; - lua_assert(ci->top <= L->stack_last); - L->savedpc = p->code; /* starting point */ - ci->tailcalls = 0; - ci->nresults = nresults; - for (st = L->top; st < ci->top; st++) - setnilvalue(st); - L->top = ci->top; - if (L->hookmask & LUA_MASKCALL) { - L->savedpc++; /* hooks assume 'pc' is already incremented */ - luaD_callhook(L, LUA_HOOKCALL, -1); - L->savedpc--; /* correct 'pc' */ +#define inc_ci(L) ((L->ci == L->end_ci) ? growCI(L) : (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + +int luaD_precall(lua_State *L, StkId func, int nresults) +{ + ptrdiff_t funcr; + LClosure *cl = NULL; + if (!ttisfunction(func) && !ttislightfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + funcr = savestack(L, func); + if (ttisfunction(func)) + cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; + if (cl && !cl->isC) + { /* Lua function? prepare its call */ + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + if (!p->is_vararg) + { /* no varargs? */ + base = func + 1; + if (L->top > base + p->numparams) + L->top = base + p->numparams; + } + else + { /* vararg function */ + int nargs = cast_int(L->top - func) - 1; + base = adjust_varargs(L, p, nargs); + func = restorestack(L, funcr); /* previous call may change the stack */ + } + ci = inc_ci(L); /* now `enter' new function */ + ci->func = func; + L->base = ci->base = base; + ci->top = L->base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + L->savedpc = p->code; /* starting point */ + ci->tailcalls = 0; + ci->nresults = nresults; + for (st = L->top; st < ci->top; st++) setnilvalue(st); + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) + { + L->savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_callhook(L, LUA_HOOKCALL, -1); + L->savedpc--; /* correct 'pc' */ + } + return PCRLUA; } - return PCRLUA; - } - else { /* if is a C function, call it */ - CallInfo *ci; - int n; - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci = inc_ci(L); /* now `enter' new function */ - ci->func = restorestack(L, funcr); - L->base = ci->base = ci->func + 1; - ci->top = L->top + LUA_MINSTACK; - lua_assert(ci->top <= L->stack_last); - ci->nresults = nresults; - if (L->hookmask & LUA_MASKCALL) - luaD_callhook(L, LUA_HOOKCALL, -1); - lua_unlock(L); - if (ttisfunction(ci->func)) - n = (*curr_func(L)->c.f)(L); /* do the actual call */ else - n = ((lua_CFunction)fvalue(ci->func))(L); /* do the actual call */ - lua_lock(L); - if (n < 0) /* yielding? */ - return PCRYIELD; - else { - luaD_poscall(L, L->top - n); - return PCRC; + { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = inc_ci(L); /* now `enter' new function */ + ci->func = restorestack(L, funcr); + L->base = ci->base = ci->func + 1; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->nresults = nresults; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + if (ttisfunction(ci->func)) + n = (*curr_func(L)->c.f)(L); /* do the actual call */ + else + n = ((lua_CFunction)fvalue(ci->func))(L); /* do the actual call */ + lua_lock(L); + if (n < 0) /* yielding? */ + return PCRYIELD; + else + { + luaD_poscall(L, L->top - n); + return PCRC; + } } - } } - -static StkId callrethooks (lua_State *L, StkId firstResult) { - ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ - luaD_callhook(L, LUA_HOOKRET, -1); - if (f_isLua(L->ci)) { /* Lua function? */ - while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ - luaD_callhook(L, LUA_HOOKTAILRET, -1); - } - return restorestack(L, fr); +static StkId callrethooks(lua_State *L, StkId firstResult) +{ + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (f_isLua(L->ci)) + { /* Lua function? */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); } - -int luaD_poscall (lua_State *L, StkId firstResult) { - StkId res; - int wanted, i; - CallInfo *ci; - if (L->hookmask & LUA_MASKRET) - firstResult = callrethooks(L, firstResult); - ci = L->ci--; - res = ci->func; /* res == final position of 1st result */ - wanted = ci->nresults; - L->base = (ci - 1)->base; /* restore base */ - L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ - /* move results to correct place */ - for (i = wanted; i != 0 && firstResult < L->top; i--) - setobjs2s(L, res++, firstResult++); - while (i-- > 0) - setnilvalue(res++); - L->top = res; - return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +int luaD_poscall(lua_State *L, StkId firstResult) +{ + StkId res; + int wanted, i; + CallInfo *ci; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + ci = L->ci--; + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->base = (ci - 1)->base; /* restore base */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); + while (i-- > 0) setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ } - /* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. ** When returns, all the results are on the stack, starting at the original ** function position. -*/ -void luaD_call (lua_State *L, StkId func, int nResults) { - if (++L->nCcalls >= LUAI_MAXCCALLS) { - if (L->nCcalls == LUAI_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ - } - if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ - luaV_execute(L, 1); /* call it */ - L->nCcalls--; - luaC_checkGC(L); +*/ +void luaD_call(lua_State *L, StkId func, int nResults) +{ + if (++L->nCcalls >= LUAI_MAXCCALLS) + { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ + luaV_execute(L, 1); /* call it */ + L->nCcalls--; + luaC_checkGC(L); } - -static void resume (lua_State *L, void *ud) { - StkId firstArg = cast(StkId, ud); - CallInfo *ci = L->ci; - if (L->status == 0) { /* start coroutine? */ - lua_assert(ci == L->base_ci && firstArg > L->base); - if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) - return; - } - else { /* resuming from previous yield */ - lua_assert(L->status == LUA_YIELD); - L->status = 0; - if (!f_isLua(ci)) { /* `common' yield? */ - /* finish interrupted execution of `OP_CALL' */ - lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || - GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); - if (luaD_poscall(L, firstArg)) /* complete it... */ - L->top = L->ci->top; /* and correct top if not multiple results */ +static void resume(lua_State *L, void *ud) +{ + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (L->status == 0) + { /* start coroutine? */ + lua_assert(ci == L->base_ci && firstArg > L->base); + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + } + else + { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = 0; + if (!f_isLua(ci)) + { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + lua_assert(GET_OPCODE(*((ci - 1)->savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci - 1)->savedpc - 1)) == OP_TAILCALL); + if (luaD_poscall(L, firstArg)) /* complete it... */ + L->top = L->ci->top; /* and correct top if not multiple results */ + } + else /* yielded inside a hook: just continue its execution */ + L->base = L->ci->base; } - else /* yielded inside a hook: just continue its execution */ - L->base = L->ci->base; - } - luaV_execute(L, cast_int(L->ci - L->base_ci)); + luaV_execute(L, cast_int(L->ci - L->base_ci)); } - -static int resume_error (lua_State *L, const char *msg) { - L->top = L->ci->base; - setsvalue2s(L, L->top, luaS_new(L, msg)); - incr_top(L); - lua_unlock(L); - return LUA_ERRRUN; +static int resume_error(lua_State *L, const char *msg) +{ + L->top = L->ci->base; + setsvalue2s(L, L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; } - -LUA_API int lua_resume (lua_State *L, int nargs) { - int status; - lua_lock(L); - if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) - return resume_error(L, "cannot resume non-suspended coroutine"); - if (L->nCcalls >= LUAI_MAXCCALLS) - return resume_error(L, "C stack overflow"); - luai_userstateresume(L, nargs); - lua_assert(L->errfunc == 0); - L->baseCcalls = ++L->nCcalls; - status = luaD_rawrunprotected(L, resume, L->top - nargs); - if (status != 0) { /* error? */ - L->status = cast_byte(status); /* mark thread as `dead' */ - luaD_seterrorobj(L, status, L->top); - L->ci->top = L->top; - } - else { - lua_assert(L->nCcalls == L->baseCcalls); - status = L->status; - } - --L->nCcalls; - lua_unlock(L); - return status; +LUA_API int lua_resume(lua_State *L, int nargs) +{ + int status; + lua_lock(L); + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine"); + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + luai_userstateresume(L, nargs); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status != 0) + { /* error? */ + L->status = cast_byte(status); /* mark thread as `dead' */ + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else + { + lua_assert(L->nCcalls == L->baseCcalls); + status = L->status; + } + --L->nCcalls; + lua_unlock(L); + return status; } - -LUA_API int lua_yield (lua_State *L, int nresults) { - luai_userstateyield(L, nresults); - lua_lock(L); - if (L->nCcalls > L->baseCcalls) - luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); - L->base = L->top - nresults; /* protect stack slots below */ - L->status = LUA_YIELD; - lua_unlock(L); - return -1; +LUA_API int lua_yield(lua_State *L, int nresults) +{ + luai_userstateyield(L, nresults); + lua_lock(L); + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; /* protect stack slots below */ + L->status = LUA_YIELD; + lua_unlock(L); + return -1; } - -int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t old_top, ptrdiff_t ef) { - int status; - unsigned short oldnCcalls = L->nCcalls; - ptrdiff_t old_ci = saveci(L, L->ci); - lu_byte old_allowhooks = L->allowhook; - ptrdiff_t old_errfunc = L->errfunc; - L->errfunc = ef; - status = luaD_rawrunprotected(L, func, u); - if (status != 0) { /* an error occurred? */ - StkId oldtop = restorestack(L, old_top); - luaF_close(L, oldtop); /* close eventual pending closures */ - luaD_seterrorobj(L, status, oldtop); - L->nCcalls = oldnCcalls; - L->ci = restoreci(L, old_ci); - L->base = L->ci->base; - L->savedpc = L->ci->savedpc; - L->allowhook = old_allowhooks; - restore_stack_limit(L); - } - L->errfunc = old_errfunc; - return status; +int luaD_pcall(lua_State *L, Pfunc func, void *u, ptrdiff_t old_top, ptrdiff_t ef) +{ + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) + { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + luaD_seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->savedpc = L->ci->savedpc; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; } - - /* ** Execute a protected parser. */ -struct SParser { /* data to `f_parser' */ - ZIO *z; - Mbuffer buff; /* buffer to be used by the scanner */ - const char *name; +struct SParser +{ /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + const char *name; }; -static void f_parser (lua_State *L, void *ud) { - int i; - Proto *tf; - Closure *cl; - struct SParser *p = cast(struct SParser *, ud); - int c = luaZ_lookahead(p->z); - luaC_checkGC(L); - set_block_gc(L); /* stop collector during parsing */ - tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, - &p->buff, p->name); - cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); - cl->l.p = tf; - for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ - cl->l.upvals[i] = luaF_newupval(L); - setclvalue(L, L->top, cl); - incr_top(L); - unset_block_gc(L); +static void f_parser(lua_State *L, void *ud) +{ + int i; + Proto *tf; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = luaZ_lookahead(p->z); + luaC_checkGC(L); + set_block_gc(L); /* stop collector during parsing */ + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, &p->buff, p->name); + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl->l.p = tf; + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ + cl->l.upvals[i] = luaF_newupval(L); + setclvalue(L, L->top, cl); + incr_top(L); + unset_block_gc(L); } - -int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { - struct SParser p; - int status; - p.z = z; p.name = name; - luaZ_initbuffer(L, &p.buff); - status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); - luaZ_freebuffer(L, &p.buff); - return status; +int luaD_protectedparser(lua_State *L, ZIO *z, const char *name) +{ + struct SParser p; + int status; + p.z = z; + p.name = name; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + return status; } - - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ldump.c b/LuaNode_Esp32/LuaNode32/components/lua/ldump.c index 4f50319..c3da826 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ldump.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ldump.c @@ -15,316 +15,339 @@ #include "lstate.h" #include "lundump.h" -typedef struct { - lua_State* L; - lua_Writer writer; - void* data; - int strip; - int status; - DumpTargetInfo target; - size_t wrote; +typedef struct +{ + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; + DumpTargetInfo target; + size_t wrote; } DumpState; -#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) -#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) +#define DumpMem(b, n, size, D) DumpBlock(b, (n) * (size), D) +#define DumpVar(x, D) DumpMem(&x, 1, sizeof(x), D) static void DumpBlock(const void* b, size_t size, DumpState* D) { - if (D->status==0) - { - lua_unlock(D->L); - D->status=(*D->writer)(D->L,b,size,D->data); - D->wrote+=size; - lua_lock(D->L); - } + if (D->status == 0) + { + lua_unlock(D->L); + D->status = (*D->writer)(D->L, b, size, D->data); + D->wrote += size; + lua_lock(D->L); + } } static void DumpChar(int y, DumpState* D) { - char x=(char)y; - DumpVar(x,D); + char x = (char)y; + DumpVar(x, D); } -static void Align4(DumpState *D) +static void Align4(DumpState* D) { - while(D->wrote&3) - DumpChar(0,D); + while (D->wrote & 3) DumpChar(0, D); } -static void MaybeByteSwap(char *number, size_t numbersize, DumpState *D) +static void MaybeByteSwap(char* number, size_t numbersize, DumpState* D) { - int x=1; - int platform_little_endian = *(char*)&x; - if (platform_little_endian != D->target.little_endian) - { - unsigned long i; - for (i=0; itarget.little_endian) + { + unsigned long i; + for (i = 0; i < numbersize / 2; i++) + { + char temp = number[i]; + number[i] = number[numbersize - 1 - i]; + number[numbersize - 1 - i] = temp; + } + } } static void DumpIntWithSize(int x, int sizeof_int, DumpState* D) { - /* dump signed integer */ - switch(sizeof_int) { - case 1: { - if (x>0x7F || x<(-0x80)) D->status=LUA_ERR_CC_INTOVERFLOW; - DumpChar(x,D); - } break; - case 2: { - if (x>0x7FFF || x<(-0x8000)) D->status=LUA_ERR_CC_INTOVERFLOW; - int16_t y=(int16_t)x; - MaybeByteSwap((char*)&y,2,D); - DumpVar(y,D); - } break; - case 4: { - /* Need to reduce bounds by 1 to avoid messing 32-bit compilers up */ - if (x>0x7FFFFFFE || x<(-0x7FFFFFFF)) D->status=LUA_ERR_CC_INTOVERFLOW; - int32_t y=(int32_t)x; - MaybeByteSwap((char*)&y,4,D); - DumpVar(y,D); - } break; - default: lua_assert(0); - } + /* dump signed integer */ + switch (sizeof_int) + { + case 1: + { + if (x > 0x7F || x < (-0x80)) + D->status = LUA_ERR_CC_INTOVERFLOW; + DumpChar(x, D); + } + break; + case 2: + { + if (x > 0x7FFF || x < (-0x8000)) + D->status = LUA_ERR_CC_INTOVERFLOW; + int16_t y = (int16_t)x; + MaybeByteSwap((char*)&y, 2, D); + DumpVar(y, D); + } + break; + case 4: + { + /* Need to reduce bounds by 1 to avoid messing 32-bit compilers up + */ + if (x > 0x7FFFFFFE || x < (-0x7FFFFFFF)) + D->status = LUA_ERR_CC_INTOVERFLOW; + int32_t y = (int32_t)x; + MaybeByteSwap((char*)&y, 4, D); + DumpVar(y, D); + } + break; + default: + lua_assert(0); + } } -static void DumpInt(int x, DumpState* D) -{ - DumpIntWithSize(x,D->target.sizeof_int,D); -} +static void DumpInt(int x, DumpState* D) { DumpIntWithSize(x, D->target.sizeof_int, D); } static void DumpSize(uint32_t x, DumpState* D) { - /* dump unsigned integer */ - switch(D->target.sizeof_strsize_t) { - case 1: { - if (x>0xFF) D->status=LUA_ERR_CC_INTOVERFLOW; - DumpChar(x,D); - } break; - case 2: { - if (x>0xFFFF) D->status=LUA_ERR_CC_INTOVERFLOW; - uint16_t y=(uint16_t)x; - MaybeByteSwap((char*)&y,2,D); - DumpVar(y,D); - } break; - case 4: { - /* Reduce bounds to avoid messing 32-bit compilers up */ - if (x>0xFFFFFFFE) D->status=LUA_ERR_CC_INTOVERFLOW; - uint32_t y=x; - MaybeByteSwap((char*)&y,4,D); - DumpVar(y,D); - } break; - default: lua_assert(0); - } + /* dump unsigned integer */ + switch (D->target.sizeof_strsize_t) + { + case 1: + { + if (x > 0xFF) + D->status = LUA_ERR_CC_INTOVERFLOW; + DumpChar(x, D); + } + break; + case 2: + { + if (x > 0xFFFF) + D->status = LUA_ERR_CC_INTOVERFLOW; + uint16_t y = (uint16_t)x; + MaybeByteSwap((char*)&y, 2, D); + DumpVar(y, D); + } + break; + case 4: + { + /* Reduce bounds to avoid messing 32-bit compilers up */ + if (x > 0xFFFFFFFE) + D->status = LUA_ERR_CC_INTOVERFLOW; + uint32_t y = x; + MaybeByteSwap((char*)&y, 4, D); + DumpVar(y, D); + } + break; + default: + lua_assert(0); + } } static void DumpNumber(lua_Number x, DumpState* D) { -#if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_CROSS_COMPILER ) - DumpIntWithSize(x,D->target.sizeof_lua_Number,D); -#else // #if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_CROSS_COMPILER ) - if (D->target.lua_Number_integral) - { - if (((float)(int)x)!=x) D->status=LUA_ERR_CC_NOTINTEGER; - DumpIntWithSize(x,D->target.sizeof_lua_Number,D); - } - else - { - switch(D->target.sizeof_lua_Number) - { - /* do we need bounds checking? */ - case 4: { - float y=x; - MaybeByteSwap((char*)&y,4,D); - DumpVar(y,D); - } break; - case 8: { - double y=x; - // ARM FPA mode: keep endianness, but swap high and low parts of the - // memory representation. This is the default compilation mode for ARM - // targets with non-EABI gcc - if(D->target.is_arm_fpa) +#if defined(LUA_NUMBER_INTEGRAL) && !defined(LUA_CROSS_COMPILER) + DumpIntWithSize(x, D->target.sizeof_lua_Number, D); +#else // #if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_CROSS_COMPILER ) + if (D->target.lua_Number_integral) + { + if (((float)(int)x) != x) + D->status = LUA_ERR_CC_NOTINTEGER; + DumpIntWithSize(x, D->target.sizeof_lua_Number, D); + } + else { - char *pnum=(char*)&y, temp[4]; - memcpy(temp,pnum,4); - memcpy(pnum,pnum+4,4); - memcpy(pnum+4,temp,4); + switch (D->target.sizeof_lua_Number) + { + /* do we need bounds checking? */ + case 4: + { + float y = x; + MaybeByteSwap((char*)&y, 4, D); + DumpVar(y, D); + } + break; + case 8: + { + double y = x; + // ARM FPA mode: keep endianness, but swap high and low parts of + // the memory representation. This is the default compilation + // mode for ARM targets with non-EABI gcc + if (D->target.is_arm_fpa) + { + char *pnum = (char*)&y, temp[4]; + memcpy(temp, pnum, 4); + memcpy(pnum, pnum + 4, 4); + memcpy(pnum + 4, temp, 4); + } + MaybeByteSwap((char*)&y, 8, D); + DumpVar(y, D); + } + break; + default: + lua_assert(0); + } } - MaybeByteSwap((char*)&y,8,D); - DumpVar(y,D); - } break; - default: lua_assert(0); - } - } -#endif // #if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_CROSS_COMPILER ) +#endif // #if defined( LUA_NUMBER_INTEGRAL ) && !defined( LUA_CROSS_COMPILER ) } -static void DumpCode(const Proto *f, DumpState* D) +static void DumpCode(const Proto* f, DumpState* D) { - DumpInt(f->sizecode,D); - char buf[10]; - int i; - Align4(D); - for (i=0; isizecode; i++) - { - memcpy(buf,&f->code[i],sizeof(Instruction)); - MaybeByteSwap(buf,sizeof(Instruction),D); - DumpBlock(buf,sizeof(Instruction),D); - } + DumpInt(f->sizecode, D); + char buf[10]; + int i; + Align4(D); + for (i = 0; i < f->sizecode; i++) + { + memcpy(buf, &f->code[i], sizeof(Instruction)); + MaybeByteSwap(buf, sizeof(Instruction), D); + DumpBlock(buf, sizeof(Instruction), D); + } } static void DumpString(const TString* s, DumpState* D) { - if (s==NULL || getstr(s)==NULL) - { - strsize_t size=0; - DumpSize(size,D); - } - else - { - strsize_t size=( strsize_t )s->tsv.len+1; /* include trailing '\0' */ - DumpSize(size,D); - DumpBlock(getstr(s),size,D); - } + if (s == NULL || getstr(s) == NULL) + { + strsize_t size = 0; + DumpSize(size, D); + } + else + { + strsize_t size = (strsize_t)s->tsv.len + 1; /* include trailing '\0' */ + DumpSize(size, D); + DumpBlock(getstr(s), size, D); + } } static void DumpFunction(const Proto* f, const TString* p, DumpState* D); static void DumpConstants(const Proto* f, DumpState* D) { - int i,n=f->sizek; - DumpInt(n,D); - for (i=0; ik[i]; - DumpChar(ttype(o),D); - switch (ttype(o)) - { - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - DumpChar(bvalue(o),D); - break; - case LUA_TNUMBER: - DumpNumber(nvalue(o),D); - break; - case LUA_TSTRING: - DumpString(rawtsvalue(o),D); - break; - default: - lua_assert(0); /* cannot happen */ - break; - } - } - n=f->sizep; - DumpInt(n,D); - for (i=0; ip[i],f->source,D); + int i, n = f->sizek; + DumpInt(n, D); + for (i = 0; i < n; i++) + { + const TValue* o = &f->k[i]; + DumpChar(ttype(o), D); + switch (ttype(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o), D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o), D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o), D); + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + n = f->sizep; + DumpInt(n, D); + for (i = 0; i < n; i++) DumpFunction(f->p[i], f->source, D); } static void DumpDebug(const Proto* f, DumpState* D) { - int i,n; + int i, n; #ifdef LUA_OPTIMIZE_DEBUG - n = (D->strip || f->packedlineinfo == NULL) ? 0: strlen(cast(char *,f->packedlineinfo))+1; - DumpInt(n,D); - Align4(D); - if (n) - { - DumpBlock(f->packedlineinfo, n, D); - } + n = (D->strip || f->packedlineinfo == NULL) ? 0 : strlen(cast(char*, f->packedlineinfo)) + 1; + DumpInt(n, D); + Align4(D); + if (n) + { + DumpBlock(f->packedlineinfo, n, D); + } #else - n= (D->strip) ? 0 : f->sizelineinfo; - DumpInt(n,D); - Align4(D); - for (i=0; ilineinfo[i],D); - } - #endif + n = (D->strip) ? 0 : f->sizelineinfo; + DumpInt(n, D); + Align4(D); + for (i = 0; i < n; i++) { DumpInt(f->lineinfo[i], D); } +#endif - n= (D->strip) ? 0 : f->sizelocvars; - DumpInt(n,D); - for (i=0; ilocvars[i].varname,D); - DumpInt(f->locvars[i].startpc,D); - DumpInt(f->locvars[i].endpc,D); - } + n = (D->strip) ? 0 : f->sizelocvars; + DumpInt(n, D); + for (i = 0; i < n; i++) + { + DumpString(f->locvars[i].varname, D); + DumpInt(f->locvars[i].startpc, D); + DumpInt(f->locvars[i].endpc, D); + } - n= (D->strip) ? 0 : f->sizeupvalues; - DumpInt(n,D); - for (i=0; iupvalues[i],D); + n = (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n, D); + for (i = 0; i < n; i++) DumpString(f->upvalues[i], D); } static void DumpFunction(const Proto* f, const TString* p, DumpState* D) { - DumpString((f->source==p || D->strip) ? NULL : f->source,D); - DumpInt(f->linedefined,D); - DumpInt(f->lastlinedefined,D); - DumpChar(f->nups,D); - DumpChar(f->numparams,D); - DumpChar(f->is_vararg,D); - DumpChar(f->maxstacksize,D); - DumpCode(f,D); - DumpConstants(f,D); - DumpDebug(f,D); + DumpString((f->source == p || D->strip) ? NULL : f->source, D); + DumpInt(f->linedefined, D); + DumpInt(f->lastlinedefined, D); + DumpChar(f->nups, D); + DumpChar(f->numparams, D); + DumpChar(f->is_vararg, D); + DumpChar(f->maxstacksize, D); + DumpCode(f, D); + DumpConstants(f, D); + DumpDebug(f, D); } static void DumpHeader(DumpState* D) { - char buf[LUAC_HEADERSIZE]; - char *h=buf; + char buf[LUAC_HEADERSIZE]; + char* h = buf; - /* This code must be kept in sync wiht luaU_header */ - memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); - h+=sizeof(LUA_SIGNATURE)-1; - *h++=(char)LUAC_VERSION; - *h++=(char)LUAC_FORMAT; - *h++=(char)D->target.little_endian; - *h++=(char)D->target.sizeof_int; - *h++=(char)D->target.sizeof_strsize_t; - *h++=(char)sizeof(Instruction); - *h++=(char)D->target.sizeof_lua_Number; - *h++=(char)D->target.lua_Number_integral; + /* This code must be kept in sync wiht luaU_header */ + memcpy(h, LUA_SIGNATURE, sizeof(LUA_SIGNATURE) - 1); + h += sizeof(LUA_SIGNATURE) - 1; + *h++ = (char)LUAC_VERSION; + *h++ = (char)LUAC_FORMAT; + *h++ = (char)D->target.little_endian; + *h++ = (char)D->target.sizeof_int; + *h++ = (char)D->target.sizeof_strsize_t; + *h++ = (char)sizeof(Instruction); + *h++ = (char)D->target.sizeof_lua_Number; + *h++ = (char)D->target.lua_Number_integral; - DumpBlock(buf,LUAC_HEADERSIZE,D); + DumpBlock(buf, LUAC_HEADERSIZE, D); } /* ** dump Lua function as precompiled chunk with specified target */ -int luaU_dump_crosscompile (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip, DumpTargetInfo target) +int luaU_dump_crosscompile(lua_State* L, const Proto* f, lua_Writer w, void* data, int strip, DumpTargetInfo target) { - DumpState D; - D.L=L; - D.writer=w; - D.data=data; - D.strip=strip; - D.status=0; - D.target=target; - D.wrote=0; - DumpHeader(&D); - DumpFunction(f,NULL,&D); - return D.status; + DumpState D; + D.L = L; + D.writer = w; + D.data = data; + D.strip = strip; + D.status = 0; + D.target = target; + D.wrote = 0; + DumpHeader(&D); + DumpFunction(f, NULL, &D); + return D.status; } /* ** dump Lua function as precompiled chunk with local machine as target */ -int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +int luaU_dump(lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) { - DumpTargetInfo target; - int test=1; - target.little_endian=*(char*)&test; - target.sizeof_int=sizeof(int); - target.sizeof_strsize_t=sizeof(strsize_t); - target.sizeof_lua_Number=sizeof(lua_Number); - target.lua_Number_integral=(((lua_Number)0.5)==0); - target.is_arm_fpa=0; - return luaU_dump_crosscompile(L,f,w,data,strip,target); + DumpTargetInfo target; + int test = 1; + target.little_endian = *(char*)&test; + target.sizeof_int = sizeof(int); + target.sizeof_strsize_t = sizeof(strsize_t); + target.sizeof_lua_Number = sizeof(lua_Number); + target.lua_Number_integral = (((lua_Number)0.5) == 0); + target.is_arm_fpa = 0; + return luaU_dump_crosscompile(L, f, w, data, strip, target); } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/legc.c b/LuaNode_Esp32/LuaNode32/components/lua/legc.c index bbef290..e72e866 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/legc.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/legc.c @@ -1,12 +1,13 @@ // Lua EGC (Emergeny Garbage Collector) interface #include "legc.h" + #include "lstate.h" -void legc_set_mode(lua_State *L, int mode, unsigned limit) { - global_State *g = G(L); - - g->egcmode = mode; - g->memlimit = limit; -} +void legc_set_mode(lua_State *L, int mode, unsigned limit) +{ + global_State *g = G(L); + g->egcmode = mode; + g->memlimit = limit; +} diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lfunc.c b/LuaNode_Esp32/LuaNode32/components/lua/lfunc.c index 104643f..4afeeac 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lfunc.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lfunc.c @@ -17,169 +17,174 @@ #include "lobject.h" #include "lstate.h" - - -Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { - Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); - luaC_link(L, obj2gco(c), LUA_TFUNCTION); - c->c.isC = 1; - c->c.env = e; - c->c.nupvalues = cast_byte(nelems); - return c; +Closure *luaF_newCclosure(lua_State *L, int nelems, Table *e) +{ + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.env = e; + c->c.nupvalues = cast_byte(nelems); + return c; } - -Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { - Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); - luaC_link(L, obj2gco(c), LUA_TFUNCTION); - c->l.isC = 0; - c->l.env = e; - c->l.nupvalues = cast_byte(nelems); - while (nelems--) c->l.upvals[nelems] = NULL; - return c; +Closure *luaF_newLclosure(lua_State *L, int nelems, Table *e) +{ + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.env = e; + c->l.nupvalues = cast_byte(nelems); + while (nelems--) c->l.upvals[nelems] = NULL; + return c; } - -UpVal *luaF_newupval (lua_State *L) { - UpVal *uv = luaM_new(L, UpVal); - luaC_link(L, obj2gco(uv), LUA_TUPVAL); - uv->v = &uv->u.value; - setnilvalue(uv->v); - return uv; +UpVal *luaF_newupval(lua_State *L) +{ + UpVal *uv = luaM_new(L, UpVal); + luaC_link(L, obj2gco(uv), LUA_TUPVAL); + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; } - -UpVal *luaF_findupval (lua_State *L, StkId level) { - global_State *g = G(L); - GCObject **pp = &L->openupval; - UpVal *p; - UpVal *uv; - while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { - lua_assert(p->v != &p->u.value); - if (p->v == level) { /* found a corresponding upvalue? */ - if (isdead(g, obj2gco(p))) /* is it dead? */ - changewhite(obj2gco(p)); /* ressurect it */ - return p; +UpVal *luaF_findupval(lua_State *L, StkId level) +{ + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) + { + lua_assert(p->v != &p->u.value); + if (p->v == level) + { /* found a corresponding upvalue? */ + if (isdead(g, obj2gco(p))) /* is it dead? */ + changewhite(obj2gco(p)); /* ressurect it */ + return p; + } + pp = &p->next; } - pp = &p->next; - } - uv = luaM_new(L, UpVal); /* not found: create a new one */ - uv->tt = LUA_TUPVAL; - uv->v = level; /* current value lives in the stack */ - uv->next = *pp; /* chain it in the proper position */ - *pp = obj2gco(uv); - uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ - uv->u.l.next = g->uvhead.u.l.next; - uv->u.l.next->u.l.prev = uv; - g->uvhead.u.l.next = uv; - luaC_marknew(L, obj2gco(uv)); - lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); - return uv; + uv = luaM_new(L, UpVal); /* not found: create a new one */ + uv->tt = LUA_TUPVAL; + uv->v = level; /* current value lives in the stack */ + uv->next = *pp; /* chain it in the proper position */ + *pp = obj2gco(uv); + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + luaC_marknew(L, obj2gco(uv)); + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; } - -static void unlinkupval (UpVal *uv) { - lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); - uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ - uv->u.l.prev->u.l.next = uv->u.l.next; +static void unlinkupval(UpVal *uv) +{ + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; } - -void luaF_freeupval (lua_State *L, UpVal *uv) { - if (uv->v != &uv->u.value) /* is it open? */ - unlinkupval(uv); /* remove from open list */ - luaM_free(L, uv); /* free upvalue */ +void luaF_freeupval(lua_State *L, UpVal *uv) +{ + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ } - -void luaF_close (lua_State *L, StkId level) { - UpVal *uv; - global_State *g = G(L); - while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { - GCObject *o = obj2gco(uv); - lua_assert(!isblack(o) && uv->v != &uv->u.value); - L->openupval = uv->next; /* remove from `open' list */ - if (isdead(g, o)) - luaF_freeupval(L, uv); /* free upvalue */ - else { - unlinkupval(uv); - setobj(L, &uv->u.value, uv->v); - uv->v = &uv->u.value; /* now current value lives here */ - luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ +void luaF_close(lua_State *L, StkId level) +{ + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) + { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else + { + unlinkupval(uv); + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; /* now current value lives here */ + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + } } - } } - -Proto *luaF_newproto (lua_State *L) { - Proto *f = luaM_new(L, Proto); - luaC_link(L, obj2gco(f), LUA_TPROTO); - f->k = NULL; - f->sizek = 0; - f->p = NULL; - f->sizep = 0; - f->code = NULL; - f->sizecode = 0; - f->sizeupvalues = 0; - f->nups = 0; - f->upvalues = NULL; - f->numparams = 0; - f->is_vararg = 0; - f->maxstacksize = 0; +Proto *luaF_newproto(lua_State *L) +{ + Proto *f = luaM_new(L, Proto); + luaC_link(L, obj2gco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; #ifdef LUA_OPTIMIZE_DEBUG - f->packedlineinfo = NULL; + f->packedlineinfo = NULL; #else - f->sizelineinfo = 0; - f->lineinfo = NULL; + f->sizelineinfo = 0; + f->lineinfo = NULL; #endif - f->sizelocvars = 0; - f->locvars = NULL; - f->linedefined = 0; - f->lastlinedefined = 0; - f->source = NULL; - return f; + f->sizelocvars = 0; + f->locvars = NULL; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; } - -void luaF_freeproto (lua_State *L, Proto *f) { - luaM_freearray(L, f->p, f->sizep, Proto *); - luaM_freearray(L, f->k, f->sizek, TValue); - luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); - luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); - if (!proto_is_readonly(f)) { - luaM_freearray(L, f->code, f->sizecode, Instruction); +void luaF_freeproto(lua_State *L, Proto *f) +{ + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TValue); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + if (!proto_is_readonly(f)) + { + luaM_freearray(L, f->code, f->sizecode, Instruction); #ifdef LUA_OPTIMIZE_DEBUG - if (f->packedlineinfo) { - luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo))+1, unsigned char); - } + if (f->packedlineinfo) + { + luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo)) + 1, unsigned char); + } #else - luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); #endif - } - luaM_free(L, f); + } + luaM_free(L, f); } - -void luaF_freeclosure (lua_State *L, Closure *c) { - int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : - sizeLclosure(c->l.nupvalues); - luaM_freemem(L, c, size); +void luaF_freeclosure(lua_State *L, Closure *c) +{ + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : sizeLclosure(c->l.nupvalues); + luaM_freemem(L, c, size); } - /* ** Look for n-th local variable at line `line' in function `func'. ** Returns NULL if not found. */ -const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { - int i; - for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { - if (pc < f->locvars[i].endpc) { /* is variable active? */ - local_number--; - if (local_number == 0) - return getstr(f->locvars[i].varname); +const char *luaF_getlocalname(const Proto *f, int local_number, int pc) +{ + int i; + for (i = 0; i < f->sizelocvars && f->locvars[i].startpc <= pc; i++) + { + if (pc < f->locvars[i].endpc) + { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } } - } - return NULL; /* not found */ + return NULL; /* not found */ } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lgc.c b/LuaNode_Esp32/LuaNode32/components/lua/lgc.c index c1da493..20b7787 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lgc.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lgc.c @@ -17,327 +17,355 @@ #include "lgc.h" #include "lmem.h" #include "lobject.h" +#include "lrotable.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" -#include "lrotable.h" - -#define GCSTEPSIZE 1024u -#define GCSWEEPMAX 40 -#define GCSWEEPCOST 10 -#define GCFINALIZECOST 100 - - -#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) - -#define makewhite(g,x) \ - ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) - -#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) -#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) - -#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) - - -#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) -#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) - - -#define KEYWEAK bitmask(KEYWEAKBIT) -#define VALUEWEAK bitmask(VALUEWEAKBIT) +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 +#define maskmarks cast_byte(~(bitmask(BLACKBIT) | WHITEBITS)) -#define markvalue(g,o) { checkconsistency(o); \ - if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } +#define makewhite(g, x) ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) -#define markobject(g,t) { if (iswhite(obj2gco(t))) \ - reallymarkobject(g, obj2gco(t)); } +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) -#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) +#define KEYWEAK bitmask(KEYWEAKBIT) +#define VALUEWEAK bitmask(VALUEWEAKBIT) -static void removeentry (Node *n) { - lua_assert(ttisnil(gval(n))); - if (iscollectable(gkey(n))) - setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ -} - - -static void reallymarkobject (global_State *g, GCObject *o) { - lua_assert(iswhite(o) && !isdead(g, o)); - white2gray(o); - switch (o->gch.tt) { - case LUA_TSTRING: { - return; - } - case LUA_TUSERDATA: { - Table *mt = gco2u(o)->metatable; - gray2black(o); /* udata are never gray */ - if (mt && !luaR_isrotable(mt)) markobject(g, mt); - markobject(g, gco2u(o)->env); - return; - } - case LUA_TUPVAL: { - UpVal *uv = gco2uv(o); - markvalue(g, uv->v); - if (uv->v == &uv->u.value) /* closed? */ - gray2black(o); /* open upvalues are never black */ - return; - } - case LUA_TFUNCTION: { - gco2cl(o)->c.gclist = g->gray; - g->gray = o; - break; +#define markvalue(g, o) \ + { \ + checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) \ + reallymarkobject(g, gcvalue(o)); \ } - case LUA_TTABLE: { - gco2h(o)->gclist = g->gray; - g->gray = o; - break; - } - case LUA_TTHREAD: { - gco2th(o)->gclist = g->gray; - g->gray = o; - break; + +#define markobject(g, t) \ + { \ + if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); \ } - case LUA_TPROTO: { - gco2p(o)->gclist = g->gray; - g->gray = o; - break; + +#define setthreshold(g) (g->GCthreshold = (g->estimate / 100) * g->gcpause) + +static void removeentry(Node *n) +{ + lua_assert(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ +} + +static void reallymarkobject(global_State *g, GCObject *o) +{ + lua_assert(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) + { + case LUA_TSTRING: + { + return; + } + case LUA_TUSERDATA: + { + Table *mt = gco2u(o)->metatable; + gray2black(o); /* udata are never gray */ + if (mt && !luaR_isrotable(mt)) + markobject(g, mt); + markobject(g, gco2u(o)->env); + return; + } + case LUA_TUPVAL: + { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v == &uv->u.value) /* closed? */ + gray2black(o); /* open upvalues are never black */ + return; + } + case LUA_TFUNCTION: + { + gco2cl(o)->c.gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: + { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: + { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TPROTO: + { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: + lua_assert(0); } - default: lua_assert(0); - } } - -static void marktmu (global_State *g) { - GCObject *u = g->tmudata; - if (u) { - do { - u = u->gch.next; - makewhite(g, u); /* may be marked, if left from previous GC */ - reallymarkobject(g, u); - } while (u != g->tmudata); - } +static void marktmu(global_State *g) +{ + GCObject *u = g->tmudata; + if (u) + { + do + { + u = u->gch.next; + makewhite(g, u); /* may be marked, if left from previous GC */ + reallymarkobject(g, u); + } while (u != g->tmudata); + } } - /* move `dead' udata that need finalization to list `tmudata' */ -size_t luaC_separateudata (lua_State *L, int all) { - global_State *g = G(L); - size_t deadmem = 0; - GCObject **p = &g->mainthread->next; - GCObject *curr; - while ((curr = *p) != NULL) { - if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) - p = &curr->gch.next; /* don't bother with them */ - else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { - markfinalized(gco2u(curr)); /* don't need finalization */ - p = &curr->gch.next; +size_t luaC_separateudata(lua_State *L, int all) +{ + global_State *g = G(L); + size_t deadmem = 0; + GCObject **p = &g->mainthread->next; + GCObject *curr; + while ((curr = *p) != NULL) + { + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) + p = &curr->gch.next; /* don't bother with them */ + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) + { + markfinalized(gco2u(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else + { /* must call its gc method */ + deadmem += sizeudata(gco2u(curr)); + markfinalized(gco2u(curr)); + *p = curr->gch.next; + /* link `curr' at the end of `tmudata' list */ + if (g->tmudata == NULL) /* list is empty? */ + g->tmudata = curr->gch.next = curr; /* creates a circular list */ + else + { + curr->gch.next = g->tmudata->gch.next; + g->tmudata->gch.next = curr; + g->tmudata = curr; + } + } } - else { /* must call its gc method */ - deadmem += sizeudata(gco2u(curr)); - markfinalized(gco2u(curr)); - *p = curr->gch.next; - /* link `curr' at the end of `tmudata' list */ - if (g->tmudata == NULL) /* list is empty? */ - g->tmudata = curr->gch.next = curr; /* creates a circular list */ - else { - curr->gch.next = g->tmudata->gch.next; - g->tmudata->gch.next = curr; - g->tmudata = curr; - } + return deadmem; +} + +static int traversetable(global_State *g, Table *h) +{ + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + if (h->metatable && !luaR_isrotable(h->metatable)) + markobject(g, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) + { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) + { /* is really weak? */ + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast_byte((weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT)); + h->gclist = g->weak; /* must be cleared after GC, ... */ + g->weak = obj2gco(h); /* ... so put in the appropriate list */ + } } - } - return deadmem; -} - - -static int traversetable (global_State *g, Table *h) { - int i; - int weakkey = 0; - int weakvalue = 0; - const TValue *mode; - if (h->metatable && !luaR_isrotable(h->metatable)) - markobject(g, h->metatable); - mode = gfasttm(g, h->metatable, TM_MODE); - if (mode && ttisstring(mode)) { /* is there a weak mode? */ - weakkey = (strchr(svalue(mode), 'k') != NULL); - weakvalue = (strchr(svalue(mode), 'v') != NULL); - if (weakkey || weakvalue) { /* is really weak? */ - h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ - h->marked |= cast_byte((weakkey << KEYWEAKBIT) | - (weakvalue << VALUEWEAKBIT)); - h->gclist = g->weak; /* must be cleared after GC, ... */ - g->weak = obj2gco(h); /* ... so put in the appropriate list */ + if (weakkey && weakvalue) + return 1; + if (!weakvalue) + { + i = h->sizearray; + while (i--) markvalue(g, &h->array[i]); } - } - if (weakkey && weakvalue) return 1; - if (!weakvalue) { - i = h->sizearray; + i = sizenode(h); while (i--) - markvalue(g, &h->array[i]); - } - i = sizenode(h); - while (i--) { - Node *n = gnode(h, i); - lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); - if (ttisnil(gval(n))) - removeentry(n); /* remove empty entries */ - else { - lua_assert(!ttisnil(gkey(n))); - if (!weakkey) markvalue(g, gkey(n)); - if (!weakvalue) markvalue(g, gval(n)); + { + Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); /* remove empty entries */ + else + { + lua_assert(!ttisnil(gkey(n))); + if (!weakkey) + markvalue(g, gkey(n)); + if (!weakvalue) + markvalue(g, gval(n)); + } } - } - return weakkey || weakvalue; + return weakkey || weakvalue; } - /* ** All marks are conditional because a GC may happen while the ** prototype is still being created */ -static void traverseproto (global_State *g, Proto *f) { - int i; - if (f->source) stringmark(f->source); - for (i=0; isizek; i++) /* mark literals */ - markvalue(g, &f->k[i]); - for (i=0; isizeupvalues; i++) { /* mark upvalue names */ - if (f->upvalues[i]) - stringmark(f->upvalues[i]); - } - for (i=0; isizep; i++) { /* mark nested protos */ - if (f->p[i]) - markobject(g, f->p[i]); - } - for (i=0; isizelocvars; i++) { /* mark local-variable names */ - if (f->locvars[i].varname) - stringmark(f->locvars[i].varname); - } -} - - - -static void traverseclosure (global_State *g, Closure *cl) { - markobject(g, cl->c.env); - if (cl->c.isC) { +static void traverseproto(global_State *g, Proto *f) +{ int i; - for (i=0; ic.nupvalues; i++) /* mark its upvalues */ - markvalue(g, &cl->c.upvalue[i]); - } - else { - int i; - lua_assert(cl->l.nupvalues == cl->l.p->nups); - markobject(g, cl->l.p); - for (i=0; il.nupvalues; i++) { /* mark its upvalues */ - if(cl->l.upvals[i]) - markobject(g, cl->l.upvals[i]); + if (f->source) + stringmark(f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) + { /* mark upvalue names */ + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i = 0; i < f->sizep; i++) + { /* mark nested protos */ + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i = 0; i < f->sizelocvars; i++) + { /* mark local-variable names */ + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); } - } } - -static void checkstacksizes (lua_State *L, StkId max) { - int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ - int s_used = cast_int(max - L->stack); /* part of stack in use */ - if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ - return; /* do not touch the stacks */ - if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) - luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ - condhardstacktests(luaD_reallocCI(L, ci_used + 1)); - if (4*s_used < L->stacksize && - 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) - luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ - condhardstacktests(luaD_reallocstack(L, s_used)); +static void traverseclosure(global_State *g, Closure *cl) +{ + markobject(g, cl->c.env); + if (cl->c.isC) + { + int i; + for (i = 0; i < cl->c.nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->c.upvalue[i]); + } + else + { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markobject(g, cl->l.p); + for (i = 0; i < cl->l.nupvalues; i++) + { /* mark its upvalues */ + if (cl->l.upvals[i]) + markobject(g, cl->l.upvals[i]); + } + } } - -static void traversestack (global_State *g, lua_State *l) { - StkId o, lim; - CallInfo *ci; - markvalue(g, gt(l)); - lim = l->top; - if(l->stack == NULL) return; /* no stack to traverse */ - for (ci = l->base_ci; ci <= l->ci; ci++) { - lua_assert(ci->top <= l->stack_last); - if (lim < ci->top) lim = ci->top; - } - for (o = l->stack; o < l->top; o++) - markvalue(g, o); - for (; o <= lim; o++) - setnilvalue(o); - if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */ - checkstacksizes(l, lim); +static void checkstacksizes(lua_State *L, StkId max) +{ + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ + int s_used = cast_int(max - L->stack); /* part of stack in use */ + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ + return; /* do not touch the stacks */ + if (4 * ci_used < L->size_ci && 2 * BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci / 2); /* still big enough... */ + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + if (4 * s_used < L->stacksize && 2 * (BASIC_STACK_SIZE + EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize / 2); /* still big enough... */ + condhardstacktests(luaD_reallocstack(L, s_used)); +} + +static void traversestack(global_State *g, lua_State *l) +{ + StkId o, lim; + CallInfo *ci; + markvalue(g, gt(l)); + lim = l->top; + if (l->stack == NULL) + return; /* no stack to traverse */ + for (ci = l->base_ci; ci <= l->ci; ci++) + { + lua_assert(ci->top <= l->stack_last); + if (lim < ci->top) + lim = ci->top; + } + for (o = l->stack; o < l->top; o++) markvalue(g, o); + for (; o <= lim; o++) setnilvalue(o); + if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */ + checkstacksizes(l, lim); } - /* ** traverse one gray object, turning it to black. ** Returns `quantity' traversed. */ -static l_mem propagatemark (global_State *g) { - GCObject *o = g->gray; - lua_assert(isgray(o)); - gray2black(o); - switch (o->gch.tt) { - case LUA_TTABLE: { - Table *h = gco2h(o); - g->gray = h->gclist; - if (traversetable(g, h)) /* table is weak? */ - black2gray(o); /* keep it gray */ - return sizeof(Table) + sizeof(TValue) * h->sizearray + - sizeof(Node) * sizenode(h); - } - case LUA_TFUNCTION: { - Closure *cl = gco2cl(o); - g->gray = cl->c.gclist; - traverseclosure(g, cl); - return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : - sizeLclosure(cl->l.nupvalues); - } - case LUA_TTHREAD: { - lua_State *th = gco2th(o); - g->gray = th->gclist; - th->gclist = g->grayagain; - g->grayagain = o; - black2gray(o); - traversestack(g, th); - return sizeof(lua_State) + sizeof(TValue) * th->stacksize + - sizeof(CallInfo) * th->size_ci; - } - case LUA_TPROTO: { - Proto *p = gco2p(o); - g->gray = p->gclist; - traverseproto(g, p); - - return sizeof(Proto) + sizeof(Proto *) * p->sizep + - sizeof(TValue) * p->sizek + - sizeof(LocVar) * p->sizelocvars + - sizeof(TString *) * p->sizeupvalues + - (proto_is_readonly(p) ? 0 : sizeof(Instruction) * p->sizecode + +static l_mem propagatemark(global_State *g) +{ + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->gch.tt) + { + case LUA_TTABLE: + { + Table *h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) /* table is weak? */ + black2gray(o); /* keep it gray */ + return sizeof(Table) + sizeof(TValue) * h->sizearray + sizeof(Node) * sizenode(h); + } + case LUA_TFUNCTION: + { + Closure *cl = gco2cl(o); + g->gray = cl->c.gclist; + traverseclosure(g, cl); + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : sizeLclosure(cl->l.nupvalues); + } + case LUA_TTHREAD: + { + lua_State *th = gco2th(o); + g->gray = th->gclist; + th->gclist = g->grayagain; + g->grayagain = o; + black2gray(o); + traversestack(g, th); + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: + { + Proto *p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + + return sizeof(Proto) + sizeof(Proto *) * p->sizep + sizeof(TValue) * p->sizek + + sizeof(LocVar) * p->sizelocvars + sizeof(TString *) * p->sizeupvalues + + (proto_is_readonly(p) ? 0 + : sizeof(Instruction) * p->sizecode + #ifdef LUA_OPTIMIZE_DEBUG - (p->packedlineinfo ? - strlen(cast(char *, p->packedlineinfo))+1 : - 0)); + (p->packedlineinfo ? strlen(cast(char *, p->packedlineinfo)) + 1 : 0)); #else - sizeof(int) * p->sizelineinfo); + sizeof(int) * p->sizelineinfo); #endif + } + default: + lua_assert(0); + return 0; } - default: lua_assert(0); return 0; - } } - -static size_t propagateall (global_State *g) { - size_t m = 0; - while (g->gray) m += propagatemark(g); - return m; +static size_t propagateall(global_State *g) +{ + size_t m = 0; + while (g->gray) m += propagatemark(g); + return m; } - /* ** The next function tells whether a key or value can be cleared from ** a weak table. Non-collectable objects are never removed from weak @@ -345,406 +373,453 @@ static size_t propagateall (global_State *g) { ** other objects: if really collected, cannot keep them; for userdata ** being finalized, keep them in keys, but not in values */ -static int iscleared (const TValue *o, int iskey) { - if (!iscollectable(o)) return 0; - if (ttisstring(o)) { - stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ - return 0; - } - return iswhite(gcvalue(o)) || - (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); +static int iscleared(const TValue *o, int iskey) +{ + if (!iscollectable(o)) + return 0; + if (ttisstring(o)) + { + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + return iswhite(gcvalue(o)) || (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); } - /* ** clear collected entries from weaktables */ -static void cleartable (GCObject *l) { - while (l) { - Table *h = gco2h(l); - int i = h->sizearray; - lua_assert(testbit(h->marked, VALUEWEAKBIT) || - testbit(h->marked, KEYWEAKBIT)); - if (testbit(h->marked, VALUEWEAKBIT)) { - while (i--) { - TValue *o = &h->array[i]; - if (iscleared(o, 0)) /* value was collected? */ - setnilvalue(o); /* remove value */ - } - } - i = sizenode(h); - while (i--) { - Node *n = gnode(h, i); - if (!ttisnil(gval(n)) && /* non-empty entry? */ - (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { - setnilvalue(gval(n)); /* remove value ... */ - removeentry(n); /* remove entry from table */ - } +static void cleartable(GCObject *l) +{ + while (l) + { + Table *h = gco2h(l); + int i = h->sizearray; + lua_assert(testbit(h->marked, VALUEWEAKBIT) || testbit(h->marked, KEYWEAKBIT)); + if (testbit(h->marked, VALUEWEAKBIT)) + { + while (i--) + { + TValue *o = &h->array[i]; + if (iscleared(o, 0)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + } + i = sizenode(h); + while (i--) + { + Node *n = gnode(h, i); + if (!ttisnil(gval(n)) && /* non-empty entry? */ + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) + { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* remove entry from table */ + } + } + l = h->gclist; } - l = h->gclist; - } } - -static void freeobj (lua_State *L, GCObject *o) { - switch (o->gch.tt) { - case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; - case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; - case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; - case LUA_TTABLE: luaH_free(L, gco2h(o)); break; - case LUA_TTHREAD: { - lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); - luaE_freethread(L, gco2th(o)); - break; - } - case LUA_TSTRING: { - G(L)->strt.nuse--; - luaM_freemem(L, o, sizestring(gco2ts(o))); - break; +static void freeobj(lua_State *L, GCObject *o) +{ + switch (o->gch.tt) + { + case LUA_TPROTO: + luaF_freeproto(L, gco2p(o)); + break; + case LUA_TFUNCTION: + luaF_freeclosure(L, gco2cl(o)); + break; + case LUA_TUPVAL: + luaF_freeupval(L, gco2uv(o)); + break; + case LUA_TTABLE: + luaH_free(L, gco2h(o)); + break; + case LUA_TTHREAD: + { + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); + luaE_freethread(L, gco2th(o)); + break; + } + case LUA_TSTRING: + { + G(L)->strt.nuse--; + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + case LUA_TUSERDATA: + { + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + } + default: + lua_assert(0); } - case LUA_TUSERDATA: { - luaM_freemem(L, o, sizeudata(gco2u(o))); - break; - } - default: lua_assert(0); - } } - - -#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) - - -static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { - GCObject *curr; - global_State *g = G(L); - int deadmask = otherwhite(g); - while ((curr = *p) != NULL && count-- > 0) { - if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ - sweepwholelist(L, &gco2th(curr)->openupval); - if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ - lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); - makewhite(g, curr); /* make it white (for next cycle) */ - p = &curr->gch.next; +#define sweepwholelist(L, p) sweeplist(L, p, MAX_LUMEM) + +static GCObject **sweeplist(lua_State *L, GCObject **p, lu_mem count) +{ + GCObject *curr; + global_State *g = G(L); + int deadmask = otherwhite(g); + while ((curr = *p) != NULL && count-- > 0) + { + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ + sweepwholelist(L, &gco2th(curr)->openupval); + if ((curr->gch.marked ^ WHITEBITS) & deadmask) + { /* not dead? */ + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); + makewhite(g, curr); /* make it white (for next cycle) */ + p = &curr->gch.next; + } + else + { /* must erase `curr' */ + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); + *p = curr->gch.next; + freeobj(L, curr); + } } - else { /* must erase `curr' */ - lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); - *p = curr->gch.next; - freeobj(L, curr); + return p; +} + +static void checkSizes(lua_State *L) +{ + global_State *g = G(L); + /* check size of string hash */ + if (g->strt.nuse < cast(lu_int32, g->strt.size / 4) && g->strt.size > MINSTRTABSIZE * 2) + luaS_resize(L, g->strt.size / 2); /* table is too big */ + /* it is not safe to re-size the buffer if it is in use. */ + if (luaZ_bufflen(&g->buff) > 0) + return; + /* check size of buffer */ + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER * 2) + { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&g->buff) / 2; + luaZ_resizebuffer(L, &g->buff, newsize); } - } - return p; -} - - -static void checkSizes (lua_State *L) { - global_State *g = G(L); - /* check size of string hash */ - if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && - g->strt.size > MINSTRTABSIZE*2) - luaS_resize(L, g->strt.size/2); /* table is too big */ - /* it is not safe to re-size the buffer if it is in use. */ - if (luaZ_bufflen(&g->buff) > 0) return; - /* check size of buffer */ - if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ - size_t newsize = luaZ_sizebuffer(&g->buff) / 2; - luaZ_resizebuffer(L, &g->buff, newsize); - } -} - - -static void GCTM (lua_State *L) { - global_State *g = G(L); - GCObject *o = g->tmudata->gch.next; /* get first element */ - Udata *udata = rawgco2u(o); - const TValue *tm; - /* remove udata from `tmudata' */ - if (o == g->tmudata) /* last element? */ - g->tmudata = NULL; - else - g->tmudata->gch.next = udata->uv.next; - udata->uv.next = g->mainthread->next; /* return it to `root' list */ - g->mainthread->next = o; - makewhite(g, o); - tm = fasttm(L, udata->uv.metatable, TM_GC); - if (tm != NULL) { - lu_byte oldah = L->allowhook; - lu_mem oldt = g->GCthreshold; - L->allowhook = 0; /* stop debug hooks during GC tag method */ - g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ - setobj2s(L, L->top, tm); - setuvalue(L, L->top+1, udata); - L->top += 2; - luaD_call(L, L->top - 2, 0); - L->allowhook = oldah; /* restore hooks */ - g->GCthreshold = oldt; /* restore threshold */ - } } +static void GCTM(lua_State *L) +{ + global_State *g = G(L); + GCObject *o = g->tmudata->gch.next; /* get first element */ + Udata *udata = rawgco2u(o); + const TValue *tm; + /* remove udata from `tmudata' */ + if (o == g->tmudata) /* last element? */ + g->tmudata = NULL; + else + g->tmudata->gch.next = udata->uv.next; + udata->uv.next = g->mainthread->next; /* return it to `root' list */ + g->mainthread->next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) + { + lu_byte oldah = L->allowhook; + lu_mem oldt = g->GCthreshold; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + g->GCthreshold = 2 * g->totalbytes; /* avoid GC steps */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top + 1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + L->allowhook = oldah; /* restore hooks */ + g->GCthreshold = oldt; /* restore threshold */ + } +} /* ** Call all GC tag methods */ -void luaC_callGCTM (lua_State *L) { - while (G(L)->tmudata) - GCTM(L); +void luaC_callGCTM(lua_State *L) +{ + while (G(L)->tmudata) GCTM(L); } - -void luaC_freeall (lua_State *L) { - global_State *g = G(L); - int i; - g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ - sweepwholelist(L, &g->rootgc); - for (i = 0; i < g->strt.size; i++) /* free all string lists */ - sweepwholelist(L, &g->strt.hash[i]); +void luaC_freeall(lua_State *L) +{ + global_State *g = G(L); + int i; + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ + sweepwholelist(L, &g->rootgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); } - -static void markmt (global_State *g) { - int i; - for (i=0; imt[i] && !luaR_isrotable(g->mt[i])) markobject(g, g->mt[i]); +static void markmt(global_State *g) +{ + int i; + for (i = 0; i < NUM_TAGS; i++) + if (g->mt[i] && !luaR_isrotable(g->mt[i])) + markobject(g, g->mt[i]); } - /* mark root set */ -static void markroot (lua_State *L) { - global_State *g = G(L); - g->gray = NULL; - g->grayagain = NULL; - g->weak = NULL; - markobject(g, g->mainthread); - /* make global table be traversed before main stack */ - markvalue(g, gt(g->mainthread)); - markvalue(g, registry(L)); - markmt(g); - g->gcstate = GCSpropagate; -} - - -static void remarkupvals (global_State *g) { - UpVal *uv; - for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { - lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); - if (isgray(obj2gco(uv))) - markvalue(g, uv->v); - } -} - - -static void atomic (lua_State *L) { - global_State *g = G(L); - size_t udsize; /* total size of userdata to be finalized */ - /* remark occasional upvalues of (maybe) dead threads */ - remarkupvals(g); - /* traverse objects cautch by write barrier and by 'remarkupvals' */ - propagateall(g); - /* remark weak tables */ - g->gray = g->weak; - g->weak = NULL; - lua_assert(!iswhite(obj2gco(g->mainthread))); - markobject(g, L); /* mark running thread */ - markmt(g); /* mark basic metatables (again) */ - propagateall(g); - /* remark gray again */ - g->gray = g->grayagain; - g->grayagain = NULL; - propagateall(g); - udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ - marktmu(g); /* mark `preserved' userdata */ - udsize += propagateall(g); /* remark, to propagate `preserveness' */ - cleartable(g->weak); /* remove collected objects from weak tables */ - /* flip current white */ - g->currentwhite = cast_byte(otherwhite(g)); - g->sweepstrgc = 0; - g->sweepgc = &g->rootgc; - g->gcstate = GCSsweepstring; - g->estimate = g->totalbytes - udsize; /* first estimate */ -} - -static void sweepstrstep (global_State *g, lua_State *L) { - lu_mem old = g->totalbytes; - sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); - if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ - g->gcstate = GCSsweep; /* end sweep-string phase */ - lua_assert(old >= g->totalbytes); - g->estimate -= old - g->totalbytes; -} - - -static l_mem singlestep (lua_State *L) { - global_State *g = G(L); - /*lua_checkmemory(L);*/ - switch (g->gcstate) { - case GCSpause: { - markroot(L); /* start a new collection */ - return 0; - } - case GCSpropagate: { - if (g->gray) - return propagatemark(g); - else { /* no more `gray' objects */ - atomic(L); /* finish mark phase */ - return 0; - } - } - case GCSsweepstring: { - sweepstrstep(g, L); - return GCSWEEPCOST; +static void markroot(lua_State *L) +{ + global_State *g = G(L); + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + /* make global table be traversed before main stack */ + markvalue(g, gt(g->mainthread)); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + +static void remarkupvals(global_State *g) +{ + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) + { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); } - case GCSsweep: { - lu_mem old = g->totalbytes; - g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); - if (*g->sweepgc == NULL) { /* nothing more to sweep? */ - checkSizes(L); - g->gcstate = GCSfinalize; /* end sweep phase */ - } - lua_assert(old >= g->totalbytes); - g->estimate -= old - g->totalbytes; - return GCSWEEPMAX*GCSWEEPCOST; +} + +static void atomic(lua_State *L) +{ + global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + /* traverse objects cautch by write barrier and by 'remarkupvals' */ + propagateall(g); + /* remark weak tables */ + g->gray = g->weak; + g->weak = NULL; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ + propagateall(g); + /* remark gray again */ + g->gray = g->grayagain; + g->grayagain = NULL; + propagateall(g); + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ + marktmu(g); /* mark `preserved' userdata */ + udsize += propagateall(g); /* remark, to propagate `preserveness' */ + cleartable(g->weak); /* remove collected objects from weak tables */ + /* flip current white */ + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gcstate = GCSsweepstring; + g->estimate = g->totalbytes - udsize; /* first estimate */ +} + +static void sweepstrstep(global_State *g, lua_State *L) +{ + lu_mem old = g->totalbytes; + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ + g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; +} + +static l_mem singlestep(lua_State *L) +{ + global_State *g = G(L); + /*lua_checkmemory(L);*/ + switch (g->gcstate) + { + case GCSpause: + { + markroot(L); /* start a new collection */ + return 0; + } + case GCSpropagate: + { + if (g->gray) + return propagatemark(g); + else + { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + return 0; + } + } + case GCSsweepstring: + { + sweepstrstep(g, L); + return GCSWEEPCOST; + } + case GCSsweep: + { + lu_mem old = g->totalbytes; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (*g->sweepgc == NULL) + { /* nothing more to sweep? */ + checkSizes(L); + g->gcstate = GCSfinalize; /* end sweep phase */ + } + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPMAX * GCSWEEPCOST; + } + case GCSfinalize: + { + if (g->tmudata) + { + GCTM(L); + if (g->estimate > GCFINALIZECOST) + g->estimate -= GCFINALIZECOST; + return GCFINALIZECOST; + } + else + { + g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; + return 0; + } + } + default: + lua_assert(0); + return 0; } - case GCSfinalize: { - if (g->tmudata) { - GCTM(L); - if (g->estimate > GCFINALIZECOST) - g->estimate -= GCFINALIZECOST; - return GCFINALIZECOST; - } - else { - g->gcstate = GCSpause; /* end collection */ - g->gcdept = 0; - return 0; - } +} + +void luaC_step(lua_State *L) +{ + global_State *g = G(L); + if (is_block_gc(L)) + return; + set_block_gc(L); + l_mem lim = (GCSTEPSIZE / 100) * g->gcstepmul; + if (lim == 0) + lim = (MAX_LUMEM - 1) / 2; /* no limit */ + g->gcdept += g->totalbytes - g->GCthreshold; + if (g->estimate > g->totalbytes) + g->estimate = g->totalbytes; + do + { + lim -= singlestep(L); + if (g->gcstate == GCSpause) + break; + } while (lim > 0); + if (g->gcstate != GCSpause) + { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else + { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } } - default: lua_assert(0); return 0; - } -} - - -void luaC_step (lua_State *L) { - global_State *g = G(L); - if(is_block_gc(L)) return; - set_block_gc(L); - l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; - if (lim == 0) - lim = (MAX_LUMEM-1)/2; /* no limit */ - g->gcdept += g->totalbytes - g->GCthreshold; - if (g->estimate > g->totalbytes) - g->estimate = g->totalbytes; - do { - lim -= singlestep(L); - if (g->gcstate == GCSpause) - break; - } while (lim > 0); - if (g->gcstate != GCSpause) { - if (g->gcdept < GCSTEPSIZE) - g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ - else { - g->gcdept -= GCSTEPSIZE; - g->GCthreshold = g->totalbytes; + else + { + lua_assert(g->totalbytes >= g->estimate); + setthreshold(g); } - } - else { - lua_assert(g->totalbytes >= g->estimate); - setthreshold(g); - } - unset_block_gc(L); + unset_block_gc(L); } -int luaC_sweepstrgc (lua_State *L) { - global_State *g = G(L); - if (g->gcstate == GCSsweepstring) { - sweepstrstep(g, L); - return (g->gcstate == GCSsweepstring) ? 1 : 0; - } - return 0; +int luaC_sweepstrgc(lua_State *L) +{ + global_State *g = G(L); + if (g->gcstate == GCSsweepstring) + { + sweepstrstep(g, L); + return (g->gcstate == GCSsweepstring) ? 1 : 0; + } + return 0; } -void luaC_fullgc (lua_State *L) { - global_State *g = G(L); - if(is_block_gc(L)) return; - set_block_gc(L); - if (g->gcstate <= GCSpropagate) { - /* reset sweep marks to sweep all elements (returning them to white) */ - g->sweepstrgc = 0; - g->sweepgc = &g->rootgc; - /* reset other collector lists */ - g->gray = NULL; - g->grayagain = NULL; - g->weak = NULL; - g->gcstate = GCSsweepstring; - } - lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); - /* finish any pending sweep phase */ - while (g->gcstate != GCSfinalize) { - lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); - singlestep(L); - } - markroot(L); - while (g->gcstate != GCSpause) { - singlestep(L); - } - setthreshold(g); - unset_block_gc(L); -} - - -void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { - global_State *g = G(L); - lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); - lua_assert(ttype(&o->gch) != LUA_TTABLE); - /* must keep invariant? */ - if (g->gcstate == GCSpropagate) - reallymarkobject(g, v); /* restore invariant */ - else /* don't mind */ - makewhite(g, o); /* mark as white just to avoid other barriers */ -} - - -void luaC_barrierback (lua_State *L, Table *t) { - global_State *g = G(L); - GCObject *o = obj2gco(t); - lua_assert(isblack(o) && !isdead(g, o)); - lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); - black2gray(o); /* make table gray (again) */ - t->gclist = g->grayagain; - g->grayagain = o; -} - - -void luaC_marknew (lua_State *L, GCObject *o) { - global_State *g = G(L); - o->gch.marked = luaC_white(g); - if (g->gcstate == GCSpropagate) - reallymarkobject(g, o); /* mark new objects as gray during propagate state. */ -} - - -void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { - global_State *g = G(L); - o->gch.next = g->rootgc; - g->rootgc = o; - o->gch.marked = luaC_white(g); - o->gch.tt = tt; -} - - -void luaC_linkupval (lua_State *L, UpVal *uv) { - global_State *g = G(L); - GCObject *o = obj2gco(uv); - o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ - g->rootgc = o; - if (isgray(o)) { - if (g->gcstate == GCSpropagate) { - gray2black(o); /* closed upvalues need barrier */ - luaC_barrier(L, uv, uv->v); +void luaC_fullgc(lua_State *L) +{ + global_State *g = G(L); + if (is_block_gc(L)) + return; + set_block_gc(L); + if (g->gcstate <= GCSpropagate) + { + /* reset sweep marks to sweep all elements (returning them to white) */ + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + /* reset other collector lists */ + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweepstring; } - else { /* sweep phase: sweep it (turning it into white) */ - makewhite(g, o); - lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); + /* finish any pending sweep phase */ + while (g->gcstate != GCSfinalize) + { + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); + singlestep(L); + } + markroot(L); + while (g->gcstate != GCSpause) { singlestep(L); } + setthreshold(g); + unset_block_gc(L); +} + +void luaC_barrierf(lua_State *L, GCObject *o, GCObject *v) +{ + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ +} + +void luaC_barrierback(lua_State *L, Table *t) +{ + global_State *g = G(L); + GCObject *o = obj2gco(t); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + black2gray(o); /* make table gray (again) */ + t->gclist = g->grayagain; + g->grayagain = o; +} + +void luaC_marknew(lua_State *L, GCObject *o) +{ + global_State *g = G(L); + o->gch.marked = luaC_white(g); + if (g->gcstate == GCSpropagate) + reallymarkobject(g, o); /* mark new objects as gray during propagate state. */ +} + +void luaC_link(lua_State *L, GCObject *o, lu_byte tt) +{ + global_State *g = G(L); + o->gch.next = g->rootgc; + g->rootgc = o; + o->gch.marked = luaC_white(g); + o->gch.tt = tt; +} + +void luaC_linkupval(lua_State *L, UpVal *uv) +{ + global_State *g = G(L); + GCObject *o = obj2gco(uv); + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ + g->rootgc = o; + if (isgray(o)) + { + if (g->gcstate == GCSpropagate) + { + gray2black(o); /* closed upvalues need barrier */ + luaC_barrier(L, uv, uv->v); + } + else + { /* sweep phase: sweep it (turning it into white) */ + makewhite(g, o); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + } } - } } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/liolib.c b/LuaNode_Esp32/LuaNode32/components/lua/liolib.c index 2d3d56b..6b5883e 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/liolib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/liolib.c @@ -4,33 +4,31 @@ ** See Copyright Notice in lua.h */ - // #include #include #include #include + #include "vfs.h" #define liolib_c #define LUA_LIB -#include "lua.h" - #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lua.h" +#include "lualib.h" - -#define IO_INPUT 1 -#define IO_OUTPUT 2 -#define IO_STDERR 0 +#define IO_INPUT 1 +#define IO_OUTPUT 2 +#define IO_STDERR 0 #if LUA_OPTIMIZE_MEMORY != 2 -#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_ENVIRONINDEX, f) -#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_ENVIRONINDEX, f) +#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_ENVIRONINDEX, f) +#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_ENVIRONINDEX, f) #else -#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX, liolib_keys[f]) -#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[f]) +#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX, liolib_keys[f]) +#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[f]) /* "Pseudo-random" keys for the registry */ static const int liolib_keys[] = {(int)&luaL_callmeta, (int)&luaL_typerror, (int)&luaL_argerror}; @@ -38,79 +36,80 @@ static const int liolib_keys[] = {(int)&luaL_callmeta, (int)&luaL_typerror, (int static const char *const fnames[] = {"input", "output"}; -static int pushresult (lua_State *L, int i, const char *filename) { - int en = vfs_ferrno(0); /* calls to Lua API may change this value */ - if (i) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - if (filename) - lua_pushfstring(L, "%s: err(%d)", filename, en); +static int pushresult(lua_State *L, int i, const char *filename) +{ + int en = vfs_ferrno(0); /* calls to Lua API may change this value */ + if (i) + { + lua_pushboolean(L, 1); + return 1; + } else - lua_pushfstring(L, "err(%d)", en); - lua_pushinteger(L, en); - return 3; - } + { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: err(%d)", filename, en); + else + lua_pushfstring(L, "err(%d)", en); + lua_pushinteger(L, en); + return 3; + } } - -static void fileerror (lua_State *L, int arg, const char *filename) { - lua_pushfstring(L, "%s: err(%d)", filename, vfs_ferrno(0)); - luaL_argerror(L, arg, lua_tostring(L, -1)); +static void fileerror(lua_State *L, int arg, const char *filename) +{ + lua_pushfstring(L, "%s: err(%d)", filename, vfs_ferrno(0)); + luaL_argerror(L, arg, lua_tostring(L, -1)); } +#define tofilep(L) ((int *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) -#define tofilep(L) ((int *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) - - -static int io_type (lua_State *L) { - void *ud; - luaL_checkany(L, 1); - ud = lua_touserdata(L, 1); - lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); - if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) - lua_pushnil(L); /* not a file */ - else if (*((int *)ud) < FS_OPEN_OK) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; +static int io_type(lua_State *L) +{ + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((int *)ud) < FS_OPEN_OK) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; } - -static int tofile (lua_State *L) { - int *f = tofilep(L); - if (*f < FS_OPEN_OK) - luaL_error(L, "attempt to use a closed file"); - return *f; +static int tofile(lua_State *L) +{ + int *f = tofilep(L); + if (*f < FS_OPEN_OK) + luaL_error(L, "attempt to use a closed file"); + return *f; } - - /* ** When creating file handles, always creates a `closed' file handle ** before opening the actual file; so, if there is a memory error, the ** file is not left opened. */ -static int *newfile (lua_State *L) { - int *pf = (int *)lua_newuserdata(L, sizeof(int)); - *pf = FS_OPEN_OK - 1; /* file handle is currently `closed' */ - luaL_getmetatable(L, LUA_FILEHANDLE); - lua_setmetatable(L, -2); - return pf; +static int *newfile(lua_State *L) +{ + int *pf = (int *)lua_newuserdata(L, sizeof(int)); + *pf = FS_OPEN_OK - 1; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; } - #if LUA_OPTIMIZE_MEMORY != 2 /* ** function to (not) close the standard files stdin, stdout, and stderr */ -static int io_noclose (lua_State *L) { - lua_pushnil(L); - lua_pushliteral(L, "cannot close standard file"); - return 2; +static int io_noclose(lua_State *L) +{ + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; } #if 0 @@ -128,70 +127,71 @@ static int io_pclose (lua_State *L) { /* ** function to close regular files */ -static int io_fclose (lua_State *L) { - int *p = tofilep(L); - int ok = (vfs_close(*p) == 0); - *p = FS_OPEN_OK - 1; - return pushresult(L, ok, NULL); +static int io_fclose(lua_State *L) +{ + int *p = tofilep(L); + int ok = (vfs_close(*p) == 0); + *p = FS_OPEN_OK - 1; + return pushresult(L, ok, NULL); } #endif -static int aux_close (lua_State *L) { +static int aux_close(lua_State *L) +{ #if LUA_OPTIMIZE_MEMORY != 2 - lua_getfenv(L, 1); - lua_getfield(L, -1, "__close"); - return (lua_tocfunction(L, -1))(L); + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); #else - int *p = tofilep(L); - if(*p == fileno(stdin) || *p == fileno(stdout) || *p == fileno(stderr)) - { - lua_pushnil(L); - lua_pushliteral(L, "cannot close standard file"); - return 2; - } - int ok = (vfs_close(*p) == 0); - *p = FS_OPEN_OK - 1; - return pushresult(L, ok, NULL); -#endif + int *p = tofilep(L); + if (*p == fileno(stdin) || *p == fileno(stdout) || *p == fileno(stderr)) + { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; + } + int ok = (vfs_close(*p) == 0); + *p = FS_OPEN_OK - 1; + return pushresult(L, ok, NULL); +#endif } - -static int io_close (lua_State *L) { - if (lua_isnone(L, 1)) - LUA_IO_GETFIELD(IO_OUTPUT); - tofile(L); /* make sure argument is a file */ - return aux_close(L); +static int io_close(lua_State *L) +{ + if (lua_isnone(L, 1)) + LUA_IO_GETFIELD(IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); } - -static int io_gc (lua_State *L) { - int f = *tofilep(L); - /* ignore closed files */ - if (f != FS_OPEN_OK - 1) - aux_close(L); - return 0; +static int io_gc(lua_State *L) +{ + int f = *tofilep(L); + /* ignore closed files */ + if (f != FS_OPEN_OK - 1) + aux_close(L); + return 0; } - -static int io_tostring (lua_State *L) { - int f = *tofilep(L); - if (f == FS_OPEN_OK - 1) - lua_pushliteral(L, "file (closed)"); - else - lua_pushfstring(L, "file (%i)", f); - return 1; +static int io_tostring(lua_State *L) +{ + int f = *tofilep(L); + if (f == FS_OPEN_OK - 1) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%i)", f); + return 1; } - -static int io_open (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - int *pf = newfile(L); - *pf = vfs_open(filename, mode); - return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, filename) : 1; +static int io_open(lua_State *L) +{ + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + int *pf = newfile(L); + *pf = vfs_open(filename, mode); + return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, filename) : 1; } - /* ** this function has a separated environment, which defines the ** correct __close for 'popen' files @@ -213,83 +213,82 @@ static int io_tmpfile (lua_State *L) { } #endif -static int getiofile (lua_State *L, int findex) { - int *pf; - LUA_IO_GETFIELD(findex); - pf = (int *)lua_touserdata(L, -1); - if (pf == NULL || *pf == FS_OPEN_OK - 1){ - luaL_error(L, "default %s file is closed", fnames[findex - 1]); - return FS_OPEN_OK - 1; - } - return *pf; -} - - -static int g_iofile (lua_State *L, int f, const char *mode) { - if (!lua_isnoneornil(L, 1)) { - const char *filename = lua_tostring(L, 1); - if (filename) { - int *pf = newfile(L); - *pf = vfs_open(filename, mode); - if (*pf == FS_OPEN_OK - 1) - fileerror(L, 1, filename); - } - else { - tofile(L); /* check that it's a valid file handle */ - lua_pushvalue(L, 1); +static int getiofile(lua_State *L, int findex) +{ + int *pf; + LUA_IO_GETFIELD(findex); + pf = (int *)lua_touserdata(L, -1); + if (pf == NULL || *pf == FS_OPEN_OK - 1) + { + luaL_error(L, "default %s file is closed", fnames[findex - 1]); + return FS_OPEN_OK - 1; } - LUA_IO_SETFIELD(f); - } - /* return current value */ - LUA_IO_GETFIELD(f); - return 1; + return *pf; } - -static int io_input (lua_State *L) { - return g_iofile(L, IO_INPUT, "r"); -} - - -static int io_output (lua_State *L) { - return g_iofile(L, IO_OUTPUT, "w"); +static int g_iofile(lua_State *L, int f, const char *mode) +{ + if (!lua_isnoneornil(L, 1)) + { + const char *filename = lua_tostring(L, 1); + if (filename) + { + int *pf = newfile(L); + *pf = vfs_open(filename, mode); + if (*pf == FS_OPEN_OK - 1) + fileerror(L, 1, filename); + } + else + { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + LUA_IO_SETFIELD(f); + } + /* return current value */ + LUA_IO_GETFIELD(f); + return 1; } +static int io_input(lua_State *L) { return g_iofile(L, IO_INPUT, "r"); } -static int io_readline (lua_State *L); +static int io_output(lua_State *L) { return g_iofile(L, IO_OUTPUT, "w"); } +static int io_readline(lua_State *L); -static void aux_lines (lua_State *L, int idx, int toclose) { - lua_pushvalue(L, idx); - lua_pushboolean(L, toclose); /* close/not close file when finished */ - lua_pushcclosure(L, io_readline, 2); -} - - -static int f_lines (lua_State *L) { - tofile(L); /* check that it's a valid file handle */ - aux_lines(L, 1, 0); - return 1; +static void aux_lines(lua_State *L, int idx, int toclose) +{ + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); } - -static int io_lines (lua_State *L) { - if (lua_isnoneornil(L, 1)) { /* no arguments? */ - /* will iterate over default input */ - LUA_IO_GETFIELD(IO_INPUT); - return f_lines(L); - } - else { - const char *filename = luaL_checkstring(L, 1); - int *pf = newfile(L); - *pf = vfs_open(filename, "r"); - if (*pf == FS_OPEN_OK - 1) - fileerror(L, 1, filename); - aux_lines(L, lua_gettop(L), 1); +static int f_lines(lua_State *L) +{ + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); return 1; - } } +static int io_lines(lua_State *L) +{ + if (lua_isnoneornil(L, 1)) + { /* no arguments? */ + /* will iterate over default input */ + LUA_IO_GETFIELD(IO_INPUT); + return f_lines(L); + } + else + { + const char *filename = luaL_checkstring(L, 1); + int *pf = newfile(L); + *pf = vfs_open(filename, "r"); + if (*pf == FS_OPEN_OK - 1) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} /* ** {====================================================== @@ -311,11 +310,12 @@ static int read_number (lua_State *L, int f) { } #endif -static int test_eof (lua_State *L, int f) { - int c = vfs_getc(f); - vfs_ungetc(c, f); - lua_pushlstring(L, NULL, 0); - return (c != EOF); +static int test_eof(lua_State *L, int f) +{ + int c = vfs_getc(f); + vfs_ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); } #if 0 @@ -340,180 +340,188 @@ static int read_line (lua_State *L, int f) { } } #else -static int read_line (lua_State *L, int f) { - luaL_Buffer b; - luaL_buffinit(L, &b); - char *p = luaL_prepbuffer(&b); - signed char c = EOF; - int i = 0; - do{ - c = (signed char)vfs_getc(f); - if(c==EOF){ - break; - } - p[i++] = c; - }while((c!=EOF) && (c!='\n') && (i0 && p[i-1] == '\n') - i--; /* do not include `eol' */ + if (i > 0 && p[i - 1] == '\n') + i--; /* do not include `eol' */ - if(i==0){ - luaL_pushresult(&b); /* close buffer */ - return (lua_objlen(L, -1) > 0); /* check whether read something */ - } + if (i == 0) + { + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } - luaL_addsize(&b, i); - luaL_pushresult(&b); /* close buffer */ - return 1; /* read at least an `eol' */ + luaL_addsize(&b, i); + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ } #endif -static int read_chars (lua_State *L, int f, size_t n) { - size_t rlen; /* how much to read */ - size_t nr; /* number of chars actually read */ - luaL_Buffer b; - luaL_buffinit(L, &b); - rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ - do { - char *p = luaL_prepbuffer(&b); - if (rlen > n) rlen = n; /* cannot read more than asked */ - nr = vfs_read(f, p, rlen); - luaL_addsize(&b, nr); - n -= nr; /* still have to read `n' chars */ - } while (n > 0 && nr == rlen); /* until end of count or eof */ - luaL_pushresult(&b); /* close buffer */ - return (n == 0 || lua_objlen(L, -1) > 0); -} - - -static int g_read (lua_State *L, int f, int first) { - int nargs = lua_gettop(L) - 1; - int success; - int n; - //vfs_clearerr(f); - if (nargs == 0) { /* no arguments? */ - success = read_line(L, f); - n = first+1; /* to return 1 result */ - } - else { /* ensure stack space for all results and for auxlib's buffer */ - luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); - success = 1; - for (n = first; nargs-- && success; n++) { - if (lua_type(L, n) == LUA_TNUMBER) { - size_t l = (size_t)lua_tointeger(L, n); - success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); - } - else { - const char *p = lua_tostring(L, n); - luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); - switch (p[1]) { +static int read_chars(lua_State *L, int f, size_t n) +{ + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do + { + char *p = luaL_prepbuffer(&b); + if (rlen > n) + rlen = n; /* cannot read more than asked */ + nr = vfs_read(f, p, rlen); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + +static int g_read(lua_State *L, int f, int first) +{ + int nargs = lua_gettop(L) - 1; + int success; + int n; + // vfs_clearerr(f); + if (nargs == 0) + { /* no arguments? */ + success = read_line(L, f); + n = first + 1; /* to return 1 result */ + } + else + { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs + LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) + { + if (lua_type(L, n) == LUA_TNUMBER) + { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else + { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) + { #if 0 case 'n': /* number */ success = read_number(L, f); break; #endif - case 'l': /* line */ - success = read_line(L, f); - break; - case 'a': /* file */ - read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ - success = 1; /* always success */ - break; - default: - return luaL_argerror(L, n, "invalid format"); + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } } - } } - } - if (vfs_ferrno(f)) - return pushresult(L, 0, NULL); - if (!success) { - lua_pop(L, 1); /* remove last result */ - lua_pushnil(L); /* push nil instead */ - } - return n - first; -} - - -static int io_read (lua_State *L) { - return g_read(L, getiofile(L, IO_INPUT), 1); + if (vfs_ferrno(f)) + return pushresult(L, 0, NULL); + if (!success) + { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; } +static int io_read(lua_State *L) { return g_read(L, getiofile(L, IO_INPUT), 1); } -static int f_read (lua_State *L) { - return g_read(L, tofile(L), 2); -} - +static int f_read(lua_State *L) { return g_read(L, tofile(L), 2); } -static int io_readline (lua_State *L) { - int *pf = (int *)lua_touserdata(L, lua_upvalueindex(1)); - int sucess; - if (pf == NULL || *pf == FS_OPEN_OK - 1){ /* file is already closed? */ - luaL_error(L, "file is already closed"); - return 0; - } - sucess = read_line(L, *pf); - if (vfs_ferrno(*pf)) - return luaL_error(L, "err(%d)", vfs_ferrno(*pf)); - if (sucess) return 1; - else { /* EOF */ - if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ - lua_settop(L, 0); - lua_pushvalue(L, lua_upvalueindex(1)); - aux_close(L); /* close it */ +static int io_readline(lua_State *L) +{ + int *pf = (int *)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (pf == NULL || *pf == FS_OPEN_OK - 1) + { /* file is already closed? */ + luaL_error(L, "file is already closed"); + return 0; + } + sucess = read_line(L, *pf); + if (vfs_ferrno(*pf)) + return luaL_error(L, "err(%d)", vfs_ferrno(*pf)); + if (sucess) + return 1; + else + { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) + { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; } - return 0; - } } /* }====================================================== */ - -static int g_write (lua_State *L, int f, int arg) { - int nargs = lua_gettop(L) - 1; - int status = 1; - for (; nargs--; arg++) { +static int g_write(lua_State *L, int f, int arg) +{ + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) + { #if 0 if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ status = status && vfs_printf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; } - else + else #endif - { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - status = status && (vfs_write(f, s, l) == l); + { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (vfs_write(f, s, l) == l); + } } - } - return pushresult(L, status, NULL); -} - - -static int io_write (lua_State *L) { - return g_write(L, getiofile(L, IO_OUTPUT), 1); + return pushresult(L, status, NULL); } +static int io_write(lua_State *L) { return g_write(L, getiofile(L, IO_OUTPUT), 1); } -static int f_write (lua_State *L) { - return g_write(L, tofile(L), 2); -} - +static int f_write(lua_State *L) { return g_write(L, tofile(L), 2); } -static int f_seek (lua_State *L) { - static const int mode[] = {VFS_SEEK_SET, VFS_SEEK_CUR, VFS_SEEK_END}; - static const char *const modenames[] = {"set", "cur", "end", NULL}; - int f = tofile(L); - int op = luaL_checkoption(L, 2, "cur", modenames); - long offset = luaL_optlong(L, 3, 0); - op = vfs_lseek(f, offset, mode[op]); - if (op) - return pushresult(L, 0, NULL); /* error */ - else { - lua_pushinteger(L, vfs_tell(f)); - return 1; - } +static int f_seek(lua_State *L) +{ + static const int mode[] = {VFS_SEEK_SET, VFS_SEEK_CUR, VFS_SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + int f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = vfs_lseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else + { + lua_pushinteger(L, vfs_tell(f)); + return 1; + } } #if 0 @@ -528,15 +536,9 @@ static int f_setvbuf (lua_State *L) { } #endif +static int io_flush(lua_State *L) { return pushresult(L, vfs_flush(getiofile(L, IO_OUTPUT)) == 0, NULL); } -static int io_flush (lua_State *L) { - return pushresult(L, vfs_flush(getiofile(L, IO_OUTPUT)) == 0, NULL); -} - - -static int f_flush (lua_State *L) { - return pushresult(L, vfs_flush(tofile(L)) == 0, NULL); -} +static int f_flush(lua_State *L) { return pushresult(L, vfs_flush(tofile(L)) == 0, NULL); } #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 2 @@ -546,101 +548,97 @@ const LUA_REG_TYPE iolib_funcs[] = { #else const LUA_REG_TYPE iolib[] = { #endif - {LSTRKEY("close"), LFUNCVAL(io_close)}, - {LSTRKEY("flush"), LFUNCVAL(io_flush)}, - {LSTRKEY("input"), LFUNCVAL(io_input)}, - {LSTRKEY("lines"), LFUNCVAL(io_lines)}, - {LSTRKEY("open"), LFUNCVAL(io_open)}, - {LSTRKEY("output"), LFUNCVAL(io_output)}, - // {LSTRKEY("popen"), LFUNCVAL(io_popen)}, - {LSTRKEY("read"), LFUNCVAL(io_read)}, - // {LSTRKEY("tmpfile"), LFUNCVAL(io_tmpfile)}, - {LSTRKEY("type"), LFUNCVAL(io_type)}, - {LSTRKEY("write"), LFUNCVAL(io_write)}, - {LNILKEY, LNILVAL} -}; + {LSTRKEY("close"), LFUNCVAL(io_close)}, + {LSTRKEY("flush"), LFUNCVAL(io_flush)}, + {LSTRKEY("input"), LFUNCVAL(io_input)}, + {LSTRKEY("lines"), LFUNCVAL(io_lines)}, + {LSTRKEY("open"), LFUNCVAL(io_open)}, + {LSTRKEY("output"), LFUNCVAL(io_output)}, + // {LSTRKEY("popen"), LFUNCVAL(io_popen)}, + {LSTRKEY("read"), LFUNCVAL(io_read)}, + // {LSTRKEY("tmpfile"), LFUNCVAL(io_tmpfile)}, + {LSTRKEY("type"), LFUNCVAL(io_type)}, + {LSTRKEY("write"), LFUNCVAL(io_write)}, + {LNILKEY, LNILVAL}}; #if LUA_OPTIMIZE_MEMORY == 2 -static int luaL_index(lua_State *L) -{ - return luaR_findfunction(L, iolib_funcs); -} - -const luaL_Reg iolib[] = { - {"__index", luaL_index}, - {NULL, NULL} -}; +static int luaL_index(lua_State *L) { return luaR_findfunction(L, iolib_funcs); } + +const luaL_Reg iolib[] = {{"__index", luaL_index}, {NULL, NULL}}; #endif #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 1 #include "lrodefs.h" -const LUA_REG_TYPE flib[] = { - {LSTRKEY("close"), LFUNCVAL(io_close)}, - {LSTRKEY("flush"), LFUNCVAL(f_flush)}, - {LSTRKEY("lines"), LFUNCVAL(f_lines)}, - {LSTRKEY("read"), LFUNCVAL(f_read)}, - {LSTRKEY("seek"), LFUNCVAL(f_seek)}, - // {LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)}, - {LSTRKEY("write"), LFUNCVAL(f_write)}, - {LSTRKEY("__gc"), LFUNCVAL(io_gc)}, - {LSTRKEY("__tostring"), LFUNCVAL(io_tostring)}, +const LUA_REG_TYPE flib[] = {{LSTRKEY("close"), LFUNCVAL(io_close)}, + {LSTRKEY("flush"), LFUNCVAL(f_flush)}, + {LSTRKEY("lines"), LFUNCVAL(f_lines)}, + {LSTRKEY("read"), LFUNCVAL(f_read)}, + {LSTRKEY("seek"), LFUNCVAL(f_seek)}, + // {LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)}, + {LSTRKEY("write"), LFUNCVAL(f_write)}, + {LSTRKEY("__gc"), LFUNCVAL(io_gc)}, + {LSTRKEY("__tostring"), LFUNCVAL(io_tostring)}, #if LUA_OPTIMIZE_MEMORY > 0 - {LSTRKEY("__index"), LROVAL(flib)}, + {LSTRKEY("__index"), LROVAL(flib)}, #endif - {LNILKEY, LNILVAL} -}; + {LNILKEY, LNILVAL}}; -static void createmeta (lua_State *L) { +static void createmeta(lua_State *L) +{ #if LUA_OPTIMIZE_MEMORY == 0 - luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_register(L, NULL, flib); /* file methods */ + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ #else - luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */ + luaL_rometatable(L, LUA_FILEHANDLE, (void *)flib); /* create metatable for file handles */ #endif } - -static void createstdfile (lua_State *L, int f, int k, const char *fname) { - *newfile(L) = f; +static void createstdfile(lua_State *L, int f, int k, const char *fname) +{ + *newfile(L) = f; #if LUA_OPTIMIZE_MEMORY != 2 - if (k > 0) { - lua_pushvalue(L, -1); - lua_rawseti(L, LUA_ENVIRONINDEX, k); - } - lua_pushvalue(L, -2); /* copy environment */ - lua_setfenv(L, -2); /* set it */ - lua_setfield(L, -3, fname); + if (k > 0) + { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); #else - lua_pushvalue(L, -1); - lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[k]); - lua_setfield(L, -2, fname); + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[k]); + lua_setfield(L, -2, fname); #endif } #if LUA_OPTIMIZE_MEMORY != 2 -static void newfenv (lua_State *L, lua_CFunction cls) { - lua_createtable(L, 0, 1); - lua_pushcfunction(L, cls); - lua_setfield(L, -2, "__close"); +static void newfenv(lua_State *L, lua_CFunction cls) +{ + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); } #endif -LUALIB_API int luaopen_io (lua_State *L) { - createmeta(L); +LUALIB_API int luaopen_io(lua_State *L) +{ + createmeta(L); #if LUA_OPTIMIZE_MEMORY != 2 - /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ - newfenv(L, io_fclose); - lua_replace(L, LUA_ENVIRONINDEX); - /* open library */ - luaL_register(L, LUA_IOLIBNAME, iolib); - newfenv(L, io_noclose); /* close function for default files */ + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) + */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + newfenv(L, io_noclose); /* close function for default files */ #else - luaL_register_light(L, LUA_IOLIBNAME, iolib); - lua_pushvalue(L, -1); - lua_setmetatable(L, -2); + luaL_register_light(L, LUA_IOLIBNAME, iolib); + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); #endif #if 0 /* create (and set) default files */ @@ -656,5 +654,5 @@ LUALIB_API int luaopen_io (lua_State *L) { lua_pop(L, 1); /* pop 'popen' */ #endif #endif - return 1; + return 1; } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/llex.c b/LuaNode_Esp32/LuaNode32/components/lua/llex.c index 538a822..e5feb88 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/llex.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/llex.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define llex_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -23,436 +22,502 @@ #include "ltable.h" #include "lzio.h" - - #define next(ls) (ls->current = zgetc(ls->z)) - - - -#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') - +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') /* ORDER RESERVED */ -const char *const luaX_tokens [] = { - "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "if", - "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while", - "..", "...", "==", ">=", "<=", "~=", - "", "", "", "", - NULL -}; - +const char *const luaX_tokens[] = { + "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", + "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", "..", + "...", "==", ">=", "<=", "~=", "", "", "", "", NULL}; #define save_and_next(ls) (save(ls, ls->current), next(ls)) - -static void save (LexState *ls, int c) { - Mbuffer *b = ls->buff; - if (b->n + 1 > b->buffsize) { - size_t newsize; - if (b->buffsize >= MAX_SIZET/2) - luaX_lexerror(ls, "lexical element too long", 0); - newsize = b->buffsize * 2; - luaZ_resizebuffer(ls->L, b, newsize); - } - b->buffer[b->n++] = cast(char, c); -} - - -void luaX_init (lua_State *L) { +static void save(LexState *ls, int c) +{ + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) + { + size_t newsize; + if (b->buffsize >= MAX_SIZET / 2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); } +void luaX_init(lua_State *L) {} -#define MAXSRC 80 - - -const char *luaX_token2str (LexState *ls, int token) { - if (token < FIRST_RESERVED) { - lua_assert(token == cast(unsigned char, token)); - return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : - luaO_pushfstring(ls->L, "%c", token); - } - else - return luaX_tokens[token-FIRST_RESERVED]; -} - +#define MAXSRC 80 -static const char *txtToken (LexState *ls, int token) { - switch (token) { - case TK_NAME: - case TK_STRING: - case TK_NUMBER: - save(ls, '\0'); - return luaZ_buffer(ls->buff); - default: - return luaX_token2str(ls, token); - } +const char *luaX_token2str(LexState *ls, int token) +{ + if (token < FIRST_RESERVED) + { + lua_assert(token == cast(unsigned char, token)); + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : luaO_pushfstring(ls->L, "%c", token); + } + else + return luaX_tokens[token - FIRST_RESERVED]; } - -void luaX_lexerror (LexState *ls, const char *msg, int token) { - char buff[MAXSRC]; - luaO_chunkid(buff, getstr(ls->source), MAXSRC); - msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); - if (token) - luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); - luaD_throw(ls->L, LUA_ERRSYNTAX); +static const char *txtToken(LexState *ls, int token) +{ + switch (token) + { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaZ_buffer(ls->buff); + default: + return luaX_token2str(ls, token); + } } - -void luaX_syntaxerror (LexState *ls, const char *msg) { - luaX_lexerror(ls, msg, ls->t.token); +void luaX_lexerror(LexState *ls, const char *msg, int token) +{ + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); } - -TString *luaX_newstring (LexState *ls, const char *str, size_t l) { - lua_State *L = ls->L; - TString *ts = luaS_newlstr(L, str, l); - TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ - if (ttisnil(o)) { - setbvalue(o, 1); /* make sure `str' will not be collected */ - luaC_checkGC(L); - } - return ts; +void luaX_syntaxerror(LexState *ls, const char *msg) { luaX_lexerror(ls, msg, ls->t.token); } + +TString *luaX_newstring(LexState *ls, const char *str, size_t l) +{ + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ + if (ttisnil(o)) + { + setbvalue(o, 1); /* make sure `str' will not be collected */ + luaC_checkGC(L); + } + return ts; } - -static void inclinenumber (LexState *ls) { - int old = ls->current; - lua_assert(currIsNewline(ls)); - next(ls); /* skip `\n' or `\r' */ - if (currIsNewline(ls) && ls->current != old) - next(ls); /* skip `\n\r' or `\r\n' */ - if (++ls->linenumber >= MAX_INT) - luaX_syntaxerror(ls, "chunk has too many lines"); +static void inclinenumber(LexState *ls) +{ + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); } - -void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { - ls->decpoint = '.'; - ls->L = L; - ls->lookahead.token = TK_EOS; /* no look-ahead token */ - ls->z = z; - ls->fs = NULL; - ls->linenumber = 1; - ls->lastline = 1; - ls->source = source; - luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ - next(ls); /* read first char */ +void luaX_setinput(lua_State *L, LexState *ls, ZIO *z, TString *source) +{ + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ + next(ls); /* read first char */ } - - /* ** ======================================================= ** LEXICAL ANALYZER ** ======================================================= */ - - -static int check_next (LexState *ls, const char *set) { - if (!strchr(set, ls->current)) - return 0; - save_and_next(ls); - return 1; +static int check_next(LexState *ls, const char *set) +{ + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; } - -static void buffreplace (LexState *ls, char from, char to) { - size_t n = luaZ_bufflen(ls->buff); - char *p = luaZ_buffer(ls->buff); - while (n--) - if (p[n] == from) p[n] = to; +static void buffreplace(LexState *ls, char from, char to) +{ + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) + p[n] = to; } - -static void trydecpoint (LexState *ls, SemInfo *seminfo) { - /* format error: try to update decimal point separator */ - struct lconv *cv = localeconv(); - char old = ls->decpoint; - ls->decpoint = (cv ? cv->decimal_point[0] : '.'); - buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { - /* format error with correct decimal point: no more options */ - buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ - luaX_lexerror(ls, "malformed number", TK_NUMBER); - } +static void trydecpoint(LexState *ls, SemInfo *seminfo) +{ + /* format error: try to update decimal point separator */ + struct lconv *cv = localeconv(); + char old = ls->decpoint; + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) + { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + luaX_lexerror(ls, "malformed number", TK_NUMBER); + } } - /* LUA_NUMBER */ -static void read_numeral (LexState *ls, SemInfo *seminfo) { - lua_assert(isdigit(ls->current)); - do { - save_and_next(ls); - } while (isdigit(ls->current) || ls->current == '.'); - if (check_next(ls, "Ee")) /* `E'? */ - check_next(ls, "+-"); /* optional exponent sign */ - while (isalnum(ls->current) || ls->current == '_') - save_and_next(ls); - save(ls, '\0'); - buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ - trydecpoint(ls, seminfo); /* try to update decimal point separator */ +static void read_numeral(LexState *ls, SemInfo *seminfo) +{ + lua_assert(isdigit(ls->current)); + do + { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + while (isalnum(ls->current) || ls->current == '_') save_and_next(ls); + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ } - -static int skip_sep (LexState *ls) { - int count = 0; - int s = ls->current; - lua_assert(s == '[' || s == ']'); - save_and_next(ls); - while (ls->current == '=') { +static int skip_sep(LexState *ls) +{ + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); save_and_next(ls); - count++; - } - return (ls->current == s) ? count : (-count) - 1; + while (ls->current == '=') + { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; } - -static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { - int cont = 0; - (void)(cont); /* avoid warnings when `cont' is not used */ - save_and_next(ls); /* skip 2nd `[' */ - if (currIsNewline(ls)) /* string starts with a newline? */ - inclinenumber(ls); /* skip it */ - for (;;) { - switch (ls->current) { - case EOZ: - luaX_lexerror(ls, (seminfo) ? "unfinished long string" : - "unfinished long comment", TK_EOS); - break; /* to avoid warnings */ +static void read_long_string(LexState *ls, SemInfo *seminfo, int sep) +{ + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) + { + switch (ls->current) + { + case EOZ: + luaX_lexerror(ls, (seminfo) ? "unfinished long string" : "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ #if defined(LUA_COMPAT_LSTR) - case '[': { - if (skip_sep(ls) == sep) { - save_and_next(ls); /* skip 2nd `[' */ - cont++; + case '[': + { + if (skip_sep(ls) == sep) + { + save_and_next(ls); /* skip 2nd `[' */ + cont++; #if LUA_COMPAT_LSTR == 1 - if (sep == 0) - luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); #endif - } - break; - } + } + break; + } #endif - case ']': { - if (skip_sep(ls) == sep) { - save_and_next(ls); /* skip 2nd `]' */ + case ']': + { + if (skip_sep(ls) == sep) + { + save_and_next(ls); /* skip 2nd `]' */ #if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 - cont--; - if (sep == 0 && cont >= 0) break; + cont--; + if (sep == 0 && cont >= 0) + break; #endif - goto endloop; + goto endloop; + } + break; + } + case '\n': + case '\r': + { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) + luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: + { + if (seminfo) + save_and_next(ls); + else + next(ls); + } } - break; - } - case '\n': - case '\r': { - save(ls, '\n'); - inclinenumber(ls); - if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ - break; - } - default: { - if (seminfo) save_and_next(ls); - else next(ls); - } } - } endloop: - if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), - luaZ_bufflen(ls->buff) - 2*(2 + sep)); +endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), luaZ_bufflen(ls->buff) - 2 * (2 + sep)); } - -static void read_string (LexState *ls, int del, SemInfo *seminfo) { - save_and_next(ls); - while (ls->current != del) { - switch (ls->current) { - case EOZ: - luaX_lexerror(ls, "unfinished string", TK_EOS); - continue; /* to avoid warnings */ - case '\n': - case '\r': - luaX_lexerror(ls, "unfinished string", TK_STRING); - continue; /* to avoid warnings */ - case '\\': { - int c; - next(ls); /* do not save the `\' */ - switch (ls->current) { - case 'a': c = '\a'; break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - case '\n': /* go through */ - case '\r': save(ls, '\n'); inclinenumber(ls); continue; - case EOZ: continue; /* will raise an error next loop */ - default: { - if (!isdigit(ls->current)) - save_and_next(ls); /* handles \\, \", \', and \? */ - else { /* \xxx */ - int i = 0; - c = 0; - do { - c = 10*c + (ls->current-'0'); +static void read_string(LexState *ls, int del, SemInfo *seminfo) +{ + save_and_next(ls); + while (ls->current != del) + { + switch (ls->current) + { + case EOZ: + luaX_lexerror(ls, "unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + luaX_lexerror(ls, "unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': + { + int c; + next(ls); /* do not save the `\' */ + switch (ls->current) + { + case 'a': + c = '\a'; + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case '\n': /* go through */ + case '\r': + save(ls, '\n'); + inclinenumber(ls); + continue; + case EOZ: + continue; /* will raise an error next loop */ + default: + { + if (!isdigit(ls->current)) + save_and_next(ls); /* handles \\, \", \', and \? */ + else + { /* \xxx */ + int i = 0; + c = 0; + do + { + c = 10 * c + (ls->current - '0'); + next(ls); + } while (++i < 3 && isdigit(ls->current)); + if (c > UCHAR_MAX) + luaX_lexerror(ls, "escape sequence too large", TK_STRING); + save(ls, c); + } + continue; + } + } + save(ls, c); next(ls); - } while (++i<3 && isdigit(ls->current)); - if (c > UCHAR_MAX) - luaX_lexerror(ls, "escape sequence too large", TK_STRING); - save(ls, c); + continue; } - continue; - } + default: + save_and_next(ls); } - save(ls, c); - next(ls); - continue; - } - default: - save_and_next(ls); } - } - save_and_next(ls); /* skip delimiter */ - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, - luaZ_bufflen(ls->buff) - 2); + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, luaZ_bufflen(ls->buff) - 2); } - -static int llex (LexState *ls, SemInfo *seminfo) { - luaZ_resetbuffer(ls->buff); - for (;;) { - switch (ls->current) { - case '\n': - case '\r': { - inclinenumber(ls); - continue; - } - case '-': { - next(ls); - if (ls->current != '-') return '-'; - /* else is a comment */ - next(ls); - if (ls->current == '[') { - int sep = skip_sep(ls); - luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ - if (sep >= 0) { - read_long_string(ls, NULL, sep); /* long comment */ - luaZ_resetbuffer(ls->buff); - continue; - } - } - /* else short comment */ - while (!currIsNewline(ls) && ls->current != EOZ) - next(ls); - continue; - } - case '[': { - int sep = skip_sep(ls); - if (sep >= 0) { - read_long_string(ls, seminfo, sep); - return TK_STRING; - } - else if (sep == -1) return '['; - else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); - } - case '=': { - next(ls); - if (ls->current != '=') return '='; - else { next(ls); return TK_EQ; } - } - case '<': { - next(ls); - if (ls->current != '=') return '<'; - else { next(ls); return TK_LE; } - } - case '>': { - next(ls); - if (ls->current != '=') return '>'; - else { next(ls); return TK_GE; } - } - case '~': { - next(ls); - if (ls->current != '=') return '~'; - else { next(ls); return TK_NE; } - } - case '"': - case '\'': { - read_string(ls, ls->current, seminfo); - return TK_STRING; - } - case '.': { - save_and_next(ls); - if (check_next(ls, ".")) { - if (check_next(ls, ".")) - return TK_DOTS; /* ... */ - else return TK_CONCAT; /* .. */ - } - else if (!isdigit(ls->current)) return '.'; - else { - read_numeral(ls, seminfo); - return TK_NUMBER; - } - } - case EOZ: { - return TK_EOS; - } - default: { - if (isspace(ls->current)) { - lua_assert(!currIsNewline(ls)); - next(ls); - continue; - } - else if (isdigit(ls->current)) { - read_numeral(ls, seminfo); - return TK_NUMBER; - } - else if (isalpha(ls->current) || ls->current == '_') { - /* identifier or reserved word */ - TString *ts; - int i; - do { - save_and_next(ls); - } while (isalnum(ls->current) || ls->current == '_'); - /* look for reserved word */ - save(ls, '\0'); - for (i = 0; i < NUM_RESERVED; i++) - if (!strcmp(luaX_tokens[i], luaZ_buffer(ls->buff))) - return i + FIRST_RESERVED; - ts = luaX_newstring(ls, luaZ_buffer(ls->buff), - luaZ_bufflen(ls->buff) - 1); - seminfo->ts = ts; - return TK_NAME; - } - else { - int c = ls->current; - next(ls); - return c; /* single-char tokens (+ - / ...) */ +static int llex(LexState *ls, SemInfo *seminfo) +{ + luaZ_resetbuffer(ls->buff); + for (;;) + { + switch (ls->current) + { + case '\n': + case '\r': + { + inclinenumber(ls); + continue; + } + case '-': + { + next(ls); + if (ls->current != '-') + return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') + { + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) + { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) next(ls); + continue; + } + case '[': + { + int sep = skip_sep(ls); + if (sep >= 0) + { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) + return '['; + else + luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': + { + next(ls); + if (ls->current != '=') + return '='; + else + { + next(ls); + return TK_EQ; + } + } + case '<': + { + next(ls); + if (ls->current != '=') + return '<'; + else + { + next(ls); + return TK_LE; + } + } + case '>': + { + next(ls); + if (ls->current != '=') + return '>'; + else + { + next(ls); + return TK_GE; + } + } + case '~': + { + next(ls); + if (ls->current != '=') + return '~'; + else + { + next(ls); + return TK_NE; + } + } + case '"': + case '\'': + { + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': + { + save_and_next(ls); + if (check_next(ls, ".")) + { + if (check_next(ls, ".")) + return TK_DOTS; /* ... */ + else + return TK_CONCAT; /* .. */ + } + else if (!isdigit(ls->current)) + return '.'; + else + { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + } + case EOZ: + { + return TK_EOS; + } + default: + { + if (isspace(ls->current)) + { + lua_assert(!currIsNewline(ls)); + next(ls); + continue; + } + else if (isdigit(ls->current)) + { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + else if (isalpha(ls->current) || ls->current == '_') + { + /* identifier or reserved word */ + TString *ts; + int i; + do + { + save_and_next(ls); + } while (isalnum(ls->current) || ls->current == '_'); + /* look for reserved word */ + save(ls, '\0'); + for (i = 0; i < NUM_RESERVED; i++) + if (!strcmp(luaX_tokens[i], luaZ_buffer(ls->buff))) + return i + FIRST_RESERVED; + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), luaZ_bufflen(ls->buff) - 1); + seminfo->ts = ts; + return TK_NAME; + } + else + { + int c = ls->current; + next(ls); + return c; /* single-char tokens (+ - / ...) */ + } + } } - } } - } } - -void luaX_next (LexState *ls) { - ls->lastline = ls->linenumber; - if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ - ls->t = ls->lookahead; /* use this one */ - ls->lookahead.token = TK_EOS; /* and discharge it */ - } - else - ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +void luaX_next(LexState *ls) +{ + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) + { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ } - -void luaX_lookahead (LexState *ls) { - lua_assert(ls->lookahead.token == TK_EOS); - ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); +void luaX_lookahead(LexState *ls) +{ + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lmathlib.c b/LuaNode_Esp32/LuaNode32/components/lua/lmathlib.c index 342df2e..c077b12 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lmathlib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lmathlib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define lmathlib_c #define LUA_LIB #define LUAC_CROSS_FILE @@ -14,24 +13,24 @@ #include C_HEADER_MATH #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lualib.h" #undef PI #define PI (3.14159265358979323846) -#define RADIANS_PER_DEGREE (PI/180.0) - +#define RADIANS_PER_DEGREE (PI / 180.0) - -static int math_abs (lua_State *L) { +static int math_abs(lua_State *L) +{ #ifdef LUA_NUMBER_INTEGRAL - lua_Number x = luaL_checknumber(L, 1); - if (x < 0) x = -x; //fails for -2^31 - lua_pushnumber(L, x); + lua_Number x = luaL_checknumber(L, 1); + if (x < 0) + x = -x; // fails for -2^31 + lua_pushnumber(L, x); #else - lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); #endif - return 1; + return 1; } #ifndef LUA_NUMBER_INTEGRAL @@ -87,14 +86,16 @@ static int math_atan2 (lua_State *L) { } #endif -static int math_ceil (lua_State *L) { - lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); - return 1; +static int math_ceil(lua_State *L) +{ + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; } -static int math_floor (lua_State *L) { - lua_pushnumber(L, floor(luaL_checknumber(L, 1))); - return 1; +static int math_floor(lua_State *L) +{ + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; } #if 0 static int math_fmod (lua_State *L) { @@ -118,62 +119,67 @@ static int math_modf (lua_State *L) { // works in both integer and floating point versions of Lua. // This identity function is used for them. -static int math_identity (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1)); - return 1; +static int math_identity(lua_State *L) +{ + lua_pushnumber(L, luaL_checknumber(L, 1)); + return 1; } -#endif // #ifndef LUA_NUMBER_INTEGRAL +#endif // #ifndef LUA_NUMBER_INTEGRAL #ifdef LUA_NUMBER_INTEGRAL // Integer square root for integer version static lua_Number isqrt(lua_Number x) { - lua_Number op, res, one; - - op = x; res = 0; - - /* "one" starts at the highest power of four <= than the argument. */ - one = 1 << 30; /* second-to-top bit set */ - while (one > op) one >>= 2; - - while (one != 0) { - if (op >= res + one) { - op = op - (res + one); - res = res + 2 * one; + lua_Number op, res, one; + + op = x; + res = 0; + + /* "one" starts at the highest power of four <= than the argument. */ + one = 1 << 30; /* second-to-top bit set */ + while (one > op) one >>= 2; + + while (one != 0) + { + if (op >= res + one) + { + op = op - (res + one); + res = res + 2 * one; + } + res >>= 1; + one >>= 2; } - res >>= 1; - one >>= 2; - } - return(res); + return (res); } #endif -static int math_sqrt (lua_State *L) { +static int math_sqrt(lua_State *L) +{ #ifdef LUA_NUMBER_INTEGRAL - lua_Number x = luaL_checknumber(L, 1); - luaL_argcheck(L, 0<=x, 1, "negative"); - lua_pushnumber(L, isqrt(x)); + lua_Number x = luaL_checknumber(L, 1); + luaL_argcheck(L, 0 <= x, 1, "negative"); + lua_pushnumber(L, isqrt(x)); #else - lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); #endif - return 1; + return 1; } #ifdef LUA_NUMBER_INTEGRAL -# define pow(a,b) luai_ipow(a,b) +#define pow(a, b) luai_ipow(a, b) #endif -static int math_pow (lua_State *L) { - lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); - return 1; +static int math_pow(lua_State *L) +{ + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; } #ifdef LUA_NUMBER_INTEGRAL -# undef pow +#undef pow #endif - #ifndef LUA_NUMBER_INTEGRAL #if 0 static int math_log (lua_State *L) { @@ -214,187 +220,198 @@ static int math_ldexp (lua_State *L) { } #endif -#endif // #ifdef LUA_NUMBER_INTEGRAL - -static int math_min (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - lua_Number dmin = luaL_checknumber(L, 1); - int i; - for (i=2; i<=n; i++) { - lua_Number d = luaL_checknumber(L, i); - if (d < dmin) - dmin = d; - } - lua_pushnumber(L, dmin); - return 1; -} - +#endif // #ifdef LUA_NUMBER_INTEGRAL -static int math_max (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - lua_Number dmax = luaL_checknumber(L, 1); - int i; - for (i=2; i<=n; i++) { - lua_Number d = luaL_checknumber(L, i); - if (d > dmax) - dmax = d; - } - lua_pushnumber(L, dmax); - return 1; +static int math_min(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i = 2; i <= n; i++) + { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; } +static int math_max(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i = 2; i <= n; i++) + { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} #ifdef LUA_NUMBER_INTEGRAL -static int math_random (lua_State *L) { - lua_Number r = (lua_Number)(rand()%RAND_MAX); - - switch (lua_gettop(L)) { /* check number of arguments */ - case 0: { /* no arguments */ - lua_pushnumber(L, 0); /* Number between 0 and 1 - always 0 with ints */ - break; - } - case 1: { /* only upper limit */ - int u = luaL_checkint(L, 1); - luaL_argcheck(L, 1<=u, 1, "interval is empty"); - lua_pushnumber(L, (r % u)+1); /* int between 1 and `u' */ - break; - } - case 2: { /* lower and upper limits */ - int l = luaL_checkint(L, 1); - int u = luaL_checkint(L, 2); - luaL_argcheck(L, l<=u, 2, "interval is empty"); - lua_pushnumber(L, (r%(u-l+1))+l); /* int between `l' and `u' */ - break; +static int math_random(lua_State *L) +{ + lua_Number r = (lua_Number)(rand() % RAND_MAX); + + switch (lua_gettop(L)) + { /* check number of arguments */ + case 0: + { /* no arguments */ + lua_pushnumber(L, 0); /* Number between 0 and 1 - always 0 with ints */ + break; + } + case 1: + { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1 <= u, 1, "interval is empty"); + lua_pushnumber(L, (r % u) + 1); /* int between 1 and `u' */ + break; + } + case 2: + { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l <= u, 2, "interval is empty"); + lua_pushnumber(L, (r % (u - l + 1)) + l); /* int between `l' and `u' */ + break; + } + default: + return luaL_error(L, "wrong number of arguments"); } - default: return luaL_error(L, "wrong number of arguments"); - } - return 1; + return 1; } #else -static int math_random (lua_State *L) { - /* the `%' avoids the (rare) case of r==1, and is needed also because on - some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ - lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; - switch (lua_gettop(L)) { /* check number of arguments */ - case 0: { /* no arguments */ - lua_pushnumber(L, r); /* Number between 0 and 1 */ - break; - } - case 1: { /* only upper limit */ - int u = luaL_checkint(L, 1); - luaL_argcheck(L, 1<=u, 1, "interval is empty"); - lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ - break; - } - case 2: { /* lower and upper limits */ - int l = luaL_checkint(L, 1); - int u = luaL_checkint(L, 2); - luaL_argcheck(L, l<=u, 2, "interval is empty"); - lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ - break; +static int math_random(lua_State *L) +{ + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand() % RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) + { /* check number of arguments */ + case 0: + { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: + { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1 <= u, 1, "interval is empty"); + lua_pushnumber(L, floor(r * u) + 1); /* int between 1 and `u' */ + break; + } + case 2: + { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l <= u, 2, "interval is empty"); + lua_pushnumber(L, floor(r * (u - l + 1)) + l); /* int between `l' and `u' */ + break; + } + default: + return luaL_error(L, "wrong number of arguments"); } - default: return luaL_error(L, "wrong number of arguments"); - } - return 1; + return 1; } #endif - -static int math_randomseed (lua_State *L) { - srand(luaL_checkint(L, 1)); - return 0; +static int math_randomseed(lua_State *L) +{ + srand(luaL_checkint(L, 1)); + return 0; } - - #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 1 #include "lrodefs.h" const LUA_REG_TYPE math_map[] = { #ifdef LUA_NUMBER_INTEGRAL - {LSTRKEY("abs"), LFUNCVAL(math_abs)}, - {LSTRKEY("ceil"), LFUNCVAL(math_identity)}, - {LSTRKEY("floor"), LFUNCVAL(math_identity)}, - {LSTRKEY("max"), LFUNCVAL(math_max)}, - {LSTRKEY("min"), LFUNCVAL(math_min)}, - {LSTRKEY("pow"), LFUNCVAL(math_pow)}, - {LSTRKEY("random"), LFUNCVAL(math_random)}, - {LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, - {LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, + {LSTRKEY("abs"), LFUNCVAL(math_abs)}, + {LSTRKEY("ceil"), LFUNCVAL(math_identity)}, + {LSTRKEY("floor"), LFUNCVAL(math_identity)}, + {LSTRKEY("max"), LFUNCVAL(math_max)}, + {LSTRKEY("min"), LFUNCVAL(math_min)}, + {LSTRKEY("pow"), LFUNCVAL(math_pow)}, + {LSTRKEY("random"), LFUNCVAL(math_random)}, + {LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, + {LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, #if LUA_OPTIMIZE_MEMORY > 0 - {LSTRKEY("huge"), LNUMVAL(LONG_MAX)}, + {LSTRKEY("huge"), LNUMVAL(LONG_MAX)}, #endif #else - {LSTRKEY("abs"), LFUNCVAL(math_abs)}, - // {LSTRKEY("acos"), LFUNCVAL(math_acos)}, - // {LSTRKEY("asin"), LFUNCVAL(math_asin)}, - // {LSTRKEY("atan2"), LFUNCVAL(math_atan2)}, - // {LSTRKEY("atan"), LFUNCVAL(math_atan)}, - {LSTRKEY("ceil"), LFUNCVAL(math_ceil)}, - // {LSTRKEY("cosh"), LFUNCVAL(math_cosh)}, - // {LSTRKEY("cos"), LFUNCVAL(math_cos)}, - // {LSTRKEY("deg"), LFUNCVAL(math_deg)}, - // {LSTRKEY("exp"), LFUNCVAL(math_exp)}, - {LSTRKEY("floor"), LFUNCVAL(math_floor)}, - // {LSTRKEY("fmod"), LFUNCVAL(math_fmod)}, + {LSTRKEY("abs"), LFUNCVAL(math_abs)}, + // {LSTRKEY("acos"), LFUNCVAL(math_acos)}, + // {LSTRKEY("asin"), LFUNCVAL(math_asin)}, + // {LSTRKEY("atan2"), LFUNCVAL(math_atan2)}, + // {LSTRKEY("atan"), LFUNCVAL(math_atan)}, + {LSTRKEY("ceil"), LFUNCVAL(math_ceil)}, + // {LSTRKEY("cosh"), LFUNCVAL(math_cosh)}, + // {LSTRKEY("cos"), LFUNCVAL(math_cos)}, + // {LSTRKEY("deg"), LFUNCVAL(math_deg)}, + // {LSTRKEY("exp"), LFUNCVAL(math_exp)}, + {LSTRKEY("floor"), LFUNCVAL(math_floor)}, +// {LSTRKEY("fmod"), LFUNCVAL(math_fmod)}, #if LUA_OPTIMIZE_MEMORY > 0 && defined(LUA_COMPAT_MOD) - // {LSTRKEY("mod"), LFUNCVAL(math_fmod)}, +// {LSTRKEY("mod"), LFUNCVAL(math_fmod)}, #endif - // {LSTRKEY("frexp"), LFUNCVAL(math_frexp)}, - // {LSTRKEY("ldexp"), LFUNCVAL(math_ldexp)}, - // {LSTRKEY("log10"), LFUNCVAL(math_log10)}, - // {LSTRKEY("log"), LFUNCVAL(math_log)}, - {LSTRKEY("max"), LFUNCVAL(math_max)}, - {LSTRKEY("min"), LFUNCVAL(math_min)}, - // {LSTRKEY("modf"), LFUNCVAL(math_modf)}, - {LSTRKEY("pow"), LFUNCVAL(math_pow)}, - // {LSTRKEY("rad"), LFUNCVAL(math_rad)}, - {LSTRKEY("random"), LFUNCVAL(math_random)}, - {LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, - // {LSTRKEY("sinh"), LFUNCVAL(math_sinh)}, - // {LSTRKEY("sin"), LFUNCVAL(math_sin)}, - {LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, - // {LSTRKEY("tanh"), LFUNCVAL(math_tanh)}, - // {LSTRKEY("tan"), LFUNCVAL(math_tan)}, + // {LSTRKEY("frexp"), LFUNCVAL(math_frexp)}, + // {LSTRKEY("ldexp"), LFUNCVAL(math_ldexp)}, + // {LSTRKEY("log10"), LFUNCVAL(math_log10)}, + // {LSTRKEY("log"), LFUNCVAL(math_log)}, + {LSTRKEY("max"), LFUNCVAL(math_max)}, + {LSTRKEY("min"), LFUNCVAL(math_min)}, + // {LSTRKEY("modf"), LFUNCVAL(math_modf)}, + {LSTRKEY("pow"), LFUNCVAL(math_pow)}, + // {LSTRKEY("rad"), LFUNCVAL(math_rad)}, + {LSTRKEY("random"), LFUNCVAL(math_random)}, + {LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, + // {LSTRKEY("sinh"), LFUNCVAL(math_sinh)}, + // {LSTRKEY("sin"), LFUNCVAL(math_sin)}, + {LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, +// {LSTRKEY("tanh"), LFUNCVAL(math_tanh)}, +// {LSTRKEY("tan"), LFUNCVAL(math_tan)}, #if LUA_OPTIMIZE_MEMORY > 0 - {LSTRKEY("pi"), LNUMVAL(PI)}, - {LSTRKEY("huge"), LNUMVAL(HUGE_VAL)}, -#endif // #if LUA_OPTIMIZE_MEMORY > 0 -#endif // #ifdef LUA_NUMBER_INTEGRAL - {LNILKEY, LNILVAL} -}; - + {LSTRKEY("pi"), LNUMVAL(PI)}, + {LSTRKEY("huge"), LNUMVAL(HUGE_VAL)}, +#endif // #if LUA_OPTIMIZE_MEMORY > 0 +#endif // #ifdef LUA_NUMBER_INTEGRAL + {LNILKEY, LNILVAL}}; /* ** Open math library */ #if defined LUA_NUMBER_INTEGRAL -# include /* for LONG_MAX */ +#include /* for LONG_MAX */ #endif -LUALIB_API int luaopen_math (lua_State *L) { +LUALIB_API int luaopen_math(lua_State *L) +{ #if LUA_OPTIMIZE_MEMORY > 0 - return 0; + return 0; #else - luaL_register(L, LUA_MATHLIBNAME, math_map); -# if defined LUA_NUMBER_INTEGRAL - lua_pushnumber(L, LONG_MAX); - lua_setfield(L, -2, "huge"); -# else - lua_pushnumber(L, PI); - lua_setfield(L, -2, "pi"); - lua_pushnumber(L, HUGE_VAL); - lua_setfield(L, -2, "huge"); -# if defined(LUA_COMPAT_MOD) - lua_getfield(L, -1, "fmod"); - lua_setfield(L, -2, "mod"); -# endif -# endif - return 1; + luaL_register(L, LUA_MATHLIBNAME, math_map); +#if defined LUA_NUMBER_INTEGRAL + lua_pushnumber(L, LONG_MAX); + lua_setfield(L, -2, "huge"); +#else + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); +#if defined(LUA_COMPAT_MOD) + lua_getfield(L, -1, "fmod"); + lua_setfield(L, -2, "mod"); +#endif +#endif + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lmem.c b/LuaNode_Esp32/LuaNode32/components/lua/lmem.c index 9886b77..fa5fe7e 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lmem.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lmem.c @@ -4,20 +4,17 @@ ** See Copyright Notice in lua.h */ - #define lmem_c #define LUA_CORE #define LUAC_CROSS_FILE -#include "lua.h" +#include "lmem.h" #include "ldebug.h" #include "ldo.h" -#include "lmem.h" #include "lobject.h" #include "lstate.h" - - +#include "lua.h" /* ** About the realloc function: @@ -37,49 +34,46 @@ ** (any reallocation to an equal or smaller size cannot fail!) */ - - -#define MINSIZEARRAY 4 - - -void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, - int limit, const char *errormsg) { - void *newblock; - int newsize; - if (*size >= limit/2) { /* cannot double it? */ - if (*size >= limit) /* cannot grow even a little? */ - luaG_runerror(L, errormsg); - newsize = limit; /* still have at least one free place */ - } - else { - newsize = (*size)*2; - if (newsize < MINSIZEARRAY) - newsize = MINSIZEARRAY; /* minimum size */ - } - newblock = luaM_reallocv(L, block, *size, newsize, size_elems); - *size = newsize; /* update only when everything else is OK */ - return newblock; +#define MINSIZEARRAY 4 + +void *luaM_growaux_(lua_State *L, void *block, int *size, size_t size_elems, int limit, const char *errormsg) +{ + void *newblock; + int newsize; + if (*size >= limit / 2) + { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, errormsg); + newsize = limit; /* still have at least one free place */ + } + else + { + newsize = (*size) * 2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; } - -void *luaM_toobig (lua_State *L) { - luaG_runerror(L, "memory allocation error: block too big"); - return NULL; /* to avoid warnings */ +void *luaM_toobig(lua_State *L) +{ + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ } - - /* ** generic allocation routine. */ -void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { - global_State *g = G(L); - lua_assert((osize == 0) == (block == NULL)); - block = (*g->frealloc)(g->ud, block, osize, nsize); - if (block == NULL && nsize > 0) - luaD_throw(L, LUA_ERRMEM); - lua_assert((nsize == 0) == (block == NULL)); - g->totalbytes = (g->totalbytes - osize) + nsize; - return block; +void *luaM_realloc_(lua_State *L, void *block, size_t osize, size_t nsize) +{ + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + block = (*g->frealloc)(g->ud, block, osize, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + lua_assert((nsize == 0) == (block == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + return block; } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/loadlib.c b/LuaNode_Esp32/LuaNode32/components/lua/loadlib.c index 63ceb59..e5d9b05 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/loadlib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/loadlib.c @@ -8,50 +8,45 @@ ** implementation for Windows, and a stub for other systems. */ - #define loadlib_c #define LUA_LIB #define LUAC_CROSS_FILE -#include "lua.h" +#include #include #include -#include + +#include "lua.h" #ifndef LUA_CROSS_COMPILER +#include "c_stdlib.h" // for c_getenv #include "vfs.h" -#include "c_stdlib.h" // for c_getenv #endif #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lualib.h" /* prefix for open functions in C libraries */ -#define LUA_POF "luaopen_" +#define LUA_POF "luaopen_" /* separator for open functions in C libraries */ -#define LUA_OFSEP "_" +#define LUA_OFSEP "_" +#define LIBPREFIX "LOADLIB: " -#define LIBPREFIX "LOADLIB: " - -#define POF LUA_POF -#define LIB_FAIL "open" - +#define POF LUA_POF +#define LIB_FAIL "open" /* error codes for ll_loadfunc */ -#define ERRLIB 1 -#define ERRFUNC 2 - -#define setprogdir(L) ((void)0) - - -static void ll_unloadlib (void *lib); -static void *ll_load (lua_State *L, const char *path); -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); +#define ERRLIB 1 +#define ERRFUNC 2 +#define setprogdir(L) ((void)0) +static void ll_unloadlib(void *lib); +static void *ll_load(lua_State *L, const char *path); +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym); #if defined(LUA_DL_DLOPEN) /* @@ -65,28 +60,26 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); #include -static void ll_unloadlib (void *lib) { - dlclose(lib); -} - +static void ll_unloadlib(void *lib) { dlclose(lib); } -static void *ll_load (lua_State *L, const char *path) { - void *lib = dlopen(path, RTLD_NOW); - if (lib == NULL) lua_pushstring(L, dlerror()); - return lib; +static void *ll_load(lua_State *L, const char *path) +{ + void *lib = dlopen(path, RTLD_NOW); + if (lib == NULL) + lua_pushstring(L, dlerror()); + return lib; } - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = (lua_CFunction)dlsym(lib, sym); - if (f == NULL) lua_pushstring(L, dlerror()); - return f; +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) + lua_pushstring(L, dlerror()); + return f; } /* }====================================================== */ - - #elif defined(LUA_DL_DLL) /* ** {====================================================================== @@ -96,56 +89,55 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #include - #undef setprogdir -static void setprogdir (lua_State *L) { - char buff[MAX_PATH + 1]; - char *lb; - DWORD nsize = sizeof(buff)/sizeof(char); - DWORD n = GetModuleFileNameA(NULL, buff, nsize); - if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) - luaL_error(L, "unable to get ModuleFileName"); - else { - *lb = '\0'; - luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); - lua_remove(L, -2); /* remove original string */ - } -} - - -static void pusherror (lua_State *L) { - int error = GetLastError(); - char buffer[128]; - if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error, 0, buffer, sizeof(buffer), NULL)) - lua_pushstring(L, buffer); - else - lua_pushfstring(L, "system error %d\n", error); -} - -static void ll_unloadlib (void *lib) { - FreeLibrary((HINSTANCE)lib); +static void setprogdir(lua_State *L) +{ + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff) / sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else + { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + +static void pusherror(lua_State *L) +{ + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buffer, + sizeof(buffer), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); } +static void ll_unloadlib(void *lib) { FreeLibrary((HINSTANCE)lib); } -static void *ll_load (lua_State *L, const char *path) { - HINSTANCE lib = LoadLibraryA(path); - if (lib == NULL) pusherror(L); - return lib; +static void *ll_load(lua_State *L, const char *path) +{ + HINSTANCE lib = LoadLibraryA(path); + if (lib == NULL) + pusherror(L); + return lib; } - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); - if (f == NULL) pusherror(L); - return f; +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + if (f == NULL) + pusherror(L); + return f; } /* }====================================================== */ - - #elif defined(LUA_DL_DYLD) /* ** {====================================================================== @@ -155,78 +147,76 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #include - /* Mac appends a `_' before C function names */ #undef POF -#define POF "_" LUA_POF - - -static void pusherror (lua_State *L) { - const char *err_str; - const char *err_file; - NSLinkEditErrors err; - int err_num; - NSLinkEditError(&err, &err_num, &err_file, &err_str); - lua_pushstring(L, err_str); -} - - -static const char *errorfromcode (NSObjectFileImageReturnCode ret) { - switch (ret) { - case NSObjectFileImageInappropriateFile: - return "file is not a bundle"; - case NSObjectFileImageArch: - return "library is for wrong CPU type"; - case NSObjectFileImageFormat: - return "bad format"; - case NSObjectFileImageAccess: - return "cannot access file"; - case NSObjectFileImageFailure: - default: - return "unable to load library"; - } -} - - -static void ll_unloadlib (void *lib) { - NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +#define POF "_" LUA_POF + +static void pusherror(lua_State *L) +{ + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + +static const char *errorfromcode(NSObjectFileImageReturnCode ret) +{ + switch (ret) + { + case NSObjectFileImageInappropriateFile: + return "file is not a bundle"; + case NSObjectFileImageArch: + return "library is for wrong CPU type"; + case NSObjectFileImageFormat: + return "bad format"; + case NSObjectFileImageAccess: + return "cannot access file"; + case NSObjectFileImageFailure: + default: + return "unable to load library"; + } +} + +static void ll_unloadlib(void *lib) { NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); } + +static void *ll_load(lua_State *L, const char *path) +{ + NSObjectFileImage img; + NSObjectFileImageReturnCode ret; + /* this would be a rare case, but prevents crashing if it happens */ + if (!_dyld_present()) + { + lua_pushliteral(L, "dyld not present"); + return NULL; + } + ret = NSCreateObjectFileImageFromFile(path, &img); + if (ret == NSObjectFileImageSuccess) + { + NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(img); + if (mod == NULL) + pusherror(L); + return mod; + } + lua_pushstring(L, errorfromcode(ret)); + return NULL; } - -static void *ll_load (lua_State *L, const char *path) { - NSObjectFileImage img; - NSObjectFileImageReturnCode ret; - /* this would be a rare case, but prevents crashing if it happens */ - if(!_dyld_present()) { - lua_pushliteral(L, "dyld not present"); - return NULL; - } - ret = NSCreateObjectFileImageFromFile(path, &img); - if (ret == NSObjectFileImageSuccess) { - NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | - NSLINKMODULE_OPTION_RETURN_ON_ERROR); - NSDestroyObjectFileImage(img); - if (mod == NULL) pusherror(L); - return mod; - } - lua_pushstring(L, errorfromcode(ret)); - return NULL; -} - - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); - if (nss == NULL) { - lua_pushfstring(L, "symbol " LUA_QS " not found", sym); - return NULL; - } - return (lua_CFunction)NSAddressOfSymbol(nss); +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); + if (nss == NULL) + { + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); + return NULL; + } + return (lua_CFunction)NSAddressOfSymbol(nss); } /* }====================================================== */ - - #else /* ** {====================================================== @@ -235,468 +225,467 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { */ #undef LIB_FAIL -#define LIB_FAIL "absent" +#define LIB_FAIL "absent" +#define DLMSG "dynamic libraries not enabled; check your Lua installation" -#define DLMSG "dynamic libraries not enabled; check your Lua installation" +static void ll_unloadlib(void *lib) { (void)lib; /* to avoid warnings */ } - -static void ll_unloadlib (void *lib) { - (void)lib; /* to avoid warnings */ -} - - -static void * ll_load (lua_State *L, const char *path) { - (void)path; /* to avoid warnings */ - lua_pushliteral(L, DLMSG); - return NULL; +static void *ll_load(lua_State *L, const char *path) +{ + (void)path; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; } - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - (void)lib; (void)sym; /* to avoid warnings */ - lua_pushliteral(L, DLMSG); - return NULL; +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + (void)lib; + (void)sym; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; } /* }====================================================== */ #endif - - -static void ** ll_register (lua_State *L, const char *path) { - void **plib; - lua_pushfstring(L, "%s%s", LIBPREFIX, path); - lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ - if (!lua_isnil(L, -1)) /* is there an entry? */ - plib = (void **)lua_touserdata(L, -1); - else { /* no entry yet; create one */ - lua_pop(L, 1); - plib = (void **)lua_newuserdata(L, sizeof(const void *)); - *plib = NULL; - luaL_getmetatable(L, "_LOADLIB"); - lua_setmetatable(L, -2); +static void **ll_register(lua_State *L, const char *path) +{ + void **plib; lua_pushfstring(L, "%s%s", LIBPREFIX, path); - lua_pushvalue(L, -2); - lua_settable(L, LUA_REGISTRYINDEX); - } - return plib; + lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ + if (!lua_isnil(L, -1)) /* is there an entry? */ + plib = (void **)lua_touserdata(L, -1); + else + { /* no entry yet; create one */ + lua_pop(L, 1); + plib = (void **)lua_newuserdata(L, sizeof(const void *)); + *plib = NULL; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_pushvalue(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); + } + return plib; } - /* ** __gc tag method: calls library's `ll_unloadlib' function with the lib ** handle */ -static int gctm (lua_State *L) { - void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); - if (*lib) ll_unloadlib(*lib); - *lib = NULL; /* mark library as closed */ - return 0; -} - - -static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { - void **reg = ll_register(L, path); - if (*reg == NULL) *reg = ll_load(L, path); - if (*reg == NULL) - return ERRLIB; /* unable to load library */ - else { - lua_CFunction f = ll_sym(L, *reg, sym); - if (f == NULL) - return ERRFUNC; /* unable to find function */ - lua_pushcfunction(L, f); - return 0; /* return function */ - } +static int gctm(lua_State *L) +{ + void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); + if (*lib) + ll_unloadlib(*lib); + *lib = NULL; /* mark library as closed */ + return 0; } - -static int ll_loadlib (lua_State *L) { - const char *path = luaL_checkstring(L, 1); - const char *init = luaL_checkstring(L, 2); - int stat = ll_loadfunc(L, path, init); - if (stat == 0) /* no errors? */ - return 1; /* return the loaded function */ - else { /* error; error message is on stack top */ - lua_pushnil(L); - lua_insert(L, -2); - lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); - return 3; /* return nil, error message, and where */ - } +static int ll_loadfunc(lua_State *L, const char *path, const char *sym) +{ + void **reg = ll_register(L, path); + if (*reg == NULL) + *reg = ll_load(L, path); + if (*reg == NULL) + return ERRLIB; /* unable to load library */ + else + { + lua_CFunction f = ll_sym(L, *reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); + return 0; /* return function */ + } +} + +static int ll_loadlib(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else + { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } } - - /* ** {====================================================== ** 'require' function ** ======================================================= */ #ifdef LUA_CROSS_COMPILER -static int readable (const char *filename) { - FILE *f = c_fopen(filename, "r"); /* try to open file */ - if (f == NULL) return 0; /* open failed */ - c_fclose(f); - return 1; +static int readable(const char *filename) +{ + FILE *f = c_fopen(filename, "r"); /* try to open file */ + if (f == NULL) + return 0; /* open failed */ + c_fclose(f); + return 1; } #else -static int readable (const char *filename) { - int f = vfs_open(filename, "r"); /* try to open file */ - if (!f) return 0; /* open failed */ - vfs_close(f); - return 1; +static int readable(const char *filename) +{ + int f = vfs_open(filename, "r"); /* try to open file */ + if (!f) + return 0; /* open failed */ + vfs_close(f); + return 1; } #endif -static const char * pushnexttemplate (lua_State *L, const char *path) { - const char *l; - while (*path == *LUA_PATHSEP) path++; /* skip separators */ - if (*path == '\0') return NULL; /* no more templates */ - l = strchr(path, *LUA_PATHSEP); /* find next separator */ - if (l == NULL) l = path + strlen(path); - lua_pushlstring(L, path, l - path); /* template */ - return l; -} - - -static const char * findfile (lua_State *L, const char *name, - const char *pname) { - const char *path; - name = luaL_gsub(L, name, ".", LUA_DIRSEP); - lua_getfield(L, LUA_ENVIRONINDEX, pname); - path = lua_tostring(L, -1); - if (path == NULL) - luaL_error(L, LUA_QL("package.%s") " must be a string", pname); - lua_pushliteral(L, ""); /* error accumulator */ - while ((path = pushnexttemplate(L, path)) != NULL) { +static const char *pushnexttemplate(lua_State *L, const char *path) +{ + const char *l; + while (*path == *LUA_PATHSEP) path++; /* skip separators */ + if (*path == '\0') + return NULL; /* no more templates */ + l = strchr(path, *LUA_PATHSEP); /* find next separator */ + if (l == NULL) + l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + +static const char *findfile(lua_State *L, const char *name, const char *pname) +{ + const char *path; + name = luaL_gsub(L, name, ".", LUA_DIRSEP); + lua_getfield(L, LUA_ENVIRONINDEX, pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + lua_pushliteral(L, ""); /* error accumulator */ + while ((path = pushnexttemplate(L, path)) != NULL) + { + const char *filename; + filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + lua_concat(L, 2); /* add entry to possible error message */ + } + return NULL; /* not found */ +} + +static void loaderror(lua_State *L, const char *filename) +{ + luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", lua_tostring(L, 1), filename, + lua_tostring(L, -1)); +} + +static int loader_Lua(lua_State *L) +{ const char *filename; - filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); - lua_remove(L, -2); /* remove path template */ - if (readable(filename)) /* does file exist and is readable? */ - return filename; /* return that file name */ - lua_pushfstring(L, "\n\tno file " LUA_QS, filename); - lua_remove(L, -2); /* remove file name */ - lua_concat(L, 2); /* add entry to possible error message */ - } - return NULL; /* not found */ -} - - -static void loaderror (lua_State *L, const char *filename) { - luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", - lua_tostring(L, 1), filename, lua_tostring(L, -1)); -} - - -static int loader_Lua (lua_State *L) { - const char *filename; - const char *name = luaL_checkstring(L, 1); - filename = findfile(L, name, "path"); - if (filename == NULL) return 1; /* library not found in this path */ + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path"); + if (filename == NULL) + return 1; /* library not found in this path */ #ifdef LUA_CROSS_COMPILER - if (luaL_loadfile(L, filename) != 0) + if (luaL_loadfile(L, filename) != 0) #else - if (luaL_loadfsfile(L, filename) != 0) + if (luaL_loadfsfile(L, filename) != 0) #endif - loaderror(L, filename); - return 1; /* library loaded successfully */ -} - - -static const char *mkfuncname (lua_State *L, const char *modname) { - const char *funcname; - const char *mark = strchr(modname, *LUA_IGMARK); - if (mark) modname = mark + 1; - funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); - funcname = lua_pushfstring(L, POF"%s", funcname); - lua_remove(L, -2); /* remove 'gsub' result */ - return funcname; -} - - -static int loader_C (lua_State *L) { - const char *funcname; - const char *name = luaL_checkstring(L, 1); - const char *filename = findfile(L, name, "cpath"); - if (filename == NULL) return 1; /* library not found in this path */ - funcname = mkfuncname(L, name); - if (ll_loadfunc(L, filename, funcname) != 0) - loaderror(L, filename); - return 1; /* library loaded successfully */ -} - - -static int loader_Croot (lua_State *L) { - const char *funcname; - const char *filename; - const char *name = luaL_checkstring(L, 1); - const char *p = strchr(name, '.'); - int stat; - if (p == NULL) return 0; /* is root */ - lua_pushlstring(L, name, p - name); - filename = findfile(L, lua_tostring(L, -1), "cpath"); - if (filename == NULL) return 1; /* root not found */ - funcname = mkfuncname(L, name); - if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { - if (stat != ERRFUNC) loaderror(L, filename); /* real error */ - lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, - name, filename); - return 1; /* function not found */ - } - return 1; + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + +static const char *mkfuncname(lua_State *L, const char *modname) +{ + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); + if (mark) + modname = mark + 1; + funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); + funcname = lua_pushfstring(L, POF "%s", funcname); + lua_remove(L, -2); /* remove 'gsub' result */ + return funcname; +} + +static int loader_C(lua_State *L) +{ + const char *funcname; + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath"); + if (filename == NULL) + return 1; /* library not found in this path */ + funcname = mkfuncname(L, name); + if (ll_loadfunc(L, filename, funcname) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + +static int loader_Croot(lua_State *L) +{ + const char *funcname; + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) + return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath"); + if (filename == NULL) + return 1; /* root not found */ + funcname = mkfuncname(L, name); + if ((stat = ll_loadfunc(L, filename, funcname)) != 0) + { + if (stat != ERRFUNC) + loaderror(L, filename); /* real error */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, name, filename); + return 1; /* function not found */ + } + return 1; } - -static int loader_preload (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - lua_getfield(L, LUA_ENVIRONINDEX, "preload"); - if (!lua_istable(L, -1)) - luaL_error(L, LUA_QL("package.preload") " must be a table"); - lua_getfield(L, -1, name); - if (lua_isnil(L, -1)) /* not found? */ - lua_pushfstring(L, "\n\tno field package.preload['%s']", name); - return 1; +static int loader_preload(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_ENVIRONINDEX, "preload"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; } - static const int sentinel_ = 0; -#define sentinel ((void *)&sentinel_) - - -static int ll_require (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - int i; - lua_settop(L, 1); /* _LOADED table will be at index 2 */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, 2, name); - if (lua_toboolean(L, -1)) { /* is it there? */ - if (lua_touserdata(L, -1) == sentinel) /* check loops */ - luaL_error(L, "loop or previous error loading module " LUA_QS, name); - return 1; /* package is already loaded */ - } - /* Is this a readonly table? */ - void *res = luaR_findglobal(name, strlen(name)); - if (res) { - lua_pushrotable(L, res); +#define sentinel ((void *)&sentinel_) + +static int ll_require(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + int i; + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) + { /* is it there? */ + if (lua_touserdata(L, -1) == sentinel) /* check loops */ + luaL_error(L, "loop or previous error loading module " LUA_QS, name); + return 1; /* package is already loaded */ + } + /* Is this a readonly table? */ + void *res = luaR_findglobal(name, strlen(name)); + if (res) + { + lua_pushrotable(L, res); + return 1; + } + /* else must load it; iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i = 1;; i++) + { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) /* did it find module? */ + break; /* module loaded successfully */ + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_pushlightuserdata(L, sentinel); + lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ + lua_pushstring(L, name); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_touserdata(L, -1) == sentinel) + { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } return 1; - } - /* else must load it; iterate over available loaders */ - lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); - if (!lua_istable(L, -1)) - luaL_error(L, LUA_QL("package.loaders") " must be a table"); - lua_pushliteral(L, ""); /* error message accumulator */ - for (i=1; ; i++) { - lua_rawgeti(L, -2, i); /* get a loader */ - if (lua_isnil(L, -1)) - luaL_error(L, "module " LUA_QS " not found:%s", - name, lua_tostring(L, -2)); - lua_pushstring(L, name); - lua_call(L, 1, 1); /* call it */ - if (lua_isfunction(L, -1)) /* did it find module? */ - break; /* module loaded successfully */ - else if (lua_isstring(L, -1)) /* loader returned error message? */ - lua_concat(L, 2); /* accumulate it */ - else - lua_pop(L, 1); - } - lua_pushlightuserdata(L, sentinel); - lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ - lua_pushstring(L, name); /* pass name as argument to module */ - lua_call(L, 1, 1); /* run loaded module */ - if (!lua_isnil(L, -1)) /* non-nil return? */ - lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ - lua_getfield(L, 2, name); - if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ - lua_pushboolean(L, 1); /* use true as result */ - lua_pushvalue(L, -1); /* extra copy to be returned */ - lua_setfield(L, 2, name); /* _LOADED[name] = true */ - } - return 1; } /* }====================================================== */ - - /* ** {====================================================== ** 'module' function ** ======================================================= */ - -static void setfenv (lua_State *L) { - lua_Debug ar; - if (lua_getstack(L, 1, &ar) == 0 || - lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ - lua_iscfunction(L, -1)) - luaL_error(L, LUA_QL("module") " not called from a Lua function"); - lua_pushvalue(L, -2); - lua_setfenv(L, -2); - lua_pop(L, 1); +static void setfenv(lua_State *L) +{ + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); + lua_pop(L, 1); } - -static void dooptions (lua_State *L, int n) { - int i; - for (i = 2; i <= n; i++) { - lua_pushvalue(L, i); /* get option (a function) */ - lua_pushvalue(L, -2); /* module */ - lua_call(L, 1, 0); - } +static void dooptions(lua_State *L, int n) +{ + int i; + for (i = 2; i <= n; i++) + { + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } } - -static void modinit (lua_State *L, const char *modname) { - const char *dot; - lua_pushvalue(L, -1); - lua_setfield(L, -2, "_M"); /* module._M = module */ - lua_pushstring(L, modname); - lua_setfield(L, -2, "_NAME"); - dot = strrchr(modname, '.'); /* look for last dot in module name */ - if (dot == NULL) dot = modname; - else dot++; - /* set _PACKAGE as package name (full module name minus last part) */ - lua_pushlstring(L, modname, dot - modname); - lua_setfield(L, -2, "_PACKAGE"); -} - - -static int ll_module (lua_State *L) { - const char *modname = luaL_checkstring(L, 1); - if (luaR_findglobal(modname, strlen(modname))) - return 0; - int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) - return luaL_error(L, "name conflict for module " LUA_QS, modname); +static void modinit(lua_State *L, const char *modname) +{ + const char *dot; lua_pushvalue(L, -1); - lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ - } - /* check whether table already has a _NAME field */ - lua_getfield(L, -1, "_NAME"); - if (!lua_isnil(L, -1)) /* is table an initialized module? */ - lua_pop(L, 1); - else { /* no; initialize it */ - lua_pop(L, 1); - modinit(L, modname); - } - lua_pushvalue(L, -1); - setfenv(L); - dooptions(L, loaded - 1); - return 0; -} - - -static int ll_seeall (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - if (!lua_getmetatable(L, 1)) { - lua_createtable(L, 0, 1); /* create new metatable */ + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) + dot = modname; + else + dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + +static int ll_module(lua_State *L) +{ + const char *modname = luaL_checkstring(L, 1); + if (luaR_findglobal(modname, strlen(modname))) + return 0; + int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) + { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ + } + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else + { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } lua_pushvalue(L, -1); - lua_setmetatable(L, 1); - } - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setfield(L, -2, "__index"); /* mt.__index = _G */ - return 0; + setfenv(L); + dooptions(L, loaded - 1); + return 0; } +static int ll_seeall(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) + { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} /* }====================================================== */ - - /* auxiliary mark (for internal use) */ -#define AUXMARK "\1" +#define AUXMARK "\1" -static void setpath (lua_State *L, const char *fieldname, const char *envname, - const char *def) { - const char *path = c_getenv(envname); - if (path == NULL) /* no environment variable? */ - lua_pushstring(L, def); /* use default */ - else { - /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ - path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, - LUA_PATHSEP AUXMARK LUA_PATHSEP); - luaL_gsub(L, path, AUXMARK, def); - lua_remove(L, -2); - } - setprogdir(L); - lua_setfield(L, -2, fieldname); +static void setpath(lua_State *L, const char *fieldname, const char *envname, const char *def) +{ + const char *path = c_getenv(envname); + if (path == NULL) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else + { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, LUA_PATHSEP AUXMARK LUA_PATHSEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); } +static const luaL_Reg pk_funcs[] = {{"loadlib", ll_loadlib}, {"seeall", ll_seeall}, {NULL, NULL}}; -static const luaL_Reg pk_funcs[] = { - {"loadlib", ll_loadlib}, - {"seeall", ll_seeall}, - {NULL, NULL} -}; - - -static const luaL_Reg ll_funcs[] = { - {"module", ll_module}, - {"require", ll_require}, - {NULL, NULL} -}; - +static const luaL_Reg ll_funcs[] = {{"module", ll_module}, {"require", ll_require}, {NULL, NULL}}; -static const lua_CFunction loaders[] = - {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; +static const lua_CFunction loaders[] = {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; #if LUA_OPTIMIZE_MEMORY > 0 #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 1 #include "lrodefs.h" -const LUA_REG_TYPE lmt[] = { - {LRO_STRKEY("__gc"), LRO_FUNCVAL(gctm)}, - {LRO_NILKEY, LRO_NILVAL} -}; +const LUA_REG_TYPE lmt[] = {{LRO_STRKEY("__gc"), LRO_FUNCVAL(gctm)}, {LRO_NILKEY, LRO_NILVAL}}; #endif -LUALIB_API int luaopen_package (lua_State *L) { - int i; - /* create new type _LOADLIB */ +LUALIB_API int luaopen_package(lua_State *L) +{ + int i; + /* create new type _LOADLIB */ #if LUA_OPTIMIZE_MEMORY == 0 - luaL_newmetatable(L, "_LOADLIB"); - lua_pushlightfunction(L, gctm); - lua_setfield(L, -2, "__gc"); + luaL_newmetatable(L, "_LOADLIB"); + lua_pushlightfunction(L, gctm); + lua_setfield(L, -2, "__gc"); #else - luaL_rometatable(L, "_LOADLIB", (void*)lmt); + luaL_rometatable(L, "_LOADLIB", (void *)lmt); #endif - /* create `package' table */ - luaL_register_light(L, LUA_LOADLIBNAME, pk_funcs); -#if defined(LUA_COMPAT_LOADLIB) - lua_getfield(L, -1, "loadlib"); - lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); + /* create `package' table */ + luaL_register_light(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); #endif - lua_pushvalue(L, -1); - lua_replace(L, LUA_ENVIRONINDEX); - /* create `loaders' table */ - lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); - /* fill it with pre-defined loaders */ - for (i=0; loaders[i] != NULL; i++) { - lua_pushcfunction(L, loaders[i]); - lua_rawseti(L, -2, i+1); - } - lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ - setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ - setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ - /* store config information */ - lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" - LUA_EXECDIR "\n" LUA_IGMARK); - lua_setfield(L, -2, "config"); - /* set field `loaded' */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); - lua_setfield(L, -2, "loaded"); - /* set field `preload' */ - lua_newtable(L); - lua_setfield(L, -2, "preload"); - lua_pushvalue(L, LUA_GLOBALSINDEX); - luaL_register(L, NULL, ll_funcs); /* open lib into global table */ - lua_pop(L, 1); - return 1; /* return 'package' table */ + lua_pushvalue(L, -1); + lua_replace(L, LUA_ENVIRONINDEX); + /* create `loaders' table */ + lua_createtable(L, sizeof(loaders) / sizeof(loaders[0]) - 1, 0); + /* fill it with pre-defined loaders */ + for (i = 0; loaders[i] != NULL; i++) + { + lua_pushcfunction(L, loaders[i]); + lua_rawseti(L, -2, i + 1); + } + lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ + setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ + setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" LUA_EXECDIR "\n" LUA_IGMARK); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_newtable(L); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, ll_funcs); /* open lib into global table */ + lua_pop(L, 1); + return 1; /* return 'package' table */ } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lobject.c b/LuaNode_Esp32/LuaNode32/components/lua/lobject.c index 7504ac1..68be2c8 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lobject.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lobject.c @@ -4,21 +4,21 @@ ** See Copyright Notice in lua.h */ - #define lobject_c #define LUA_CORE #define LUAC_CROSS_FILE -#include "lua.h" +#include "lobject.h" + #include -#include #include +#include #include "ldo.h" #include "lmem.h" -#include "lobject.h" #include "lstate.h" #include "lstring.h" +#include "lua.h" #include "lvm.h" #ifndef LUA_CROSS_COMPILER #include "flash_api.h" @@ -28,206 +28,236 @@ const TValue luaO_nilobject_ = {LUA_TVALUE_NIL}; - /* ** converts an integer to a "floating point byte", represented as ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if ** eeeee != 0 and (xxx) otherwise. */ -int luaO_int2fb (unsigned int x) { - int e = 0; /* expoent */ - while (x >= 16) { - x = (x+1) >> 1; - e++; - } - if (x < 8) return x; - else return ((e+1) << 3) | (cast_int(x) - 8); +int luaO_int2fb(unsigned int x) +{ + int e = 0; /* expoent */ + while (x >= 16) + { + x = (x + 1) >> 1; + e++; + } + if (x < 8) + return x; + else + return ((e + 1) << 3) | (cast_int(x) - 8); } - /* converts back */ -int luaO_fb2int (int x) { - int e = (x >> 3) & 31; - if (e == 0) return x; - else return ((x & 7)+8) << (e - 1); +int luaO_fb2int(int x) +{ + int e = (x >> 3) & 31; + if (e == 0) + return x; + else + return ((x & 7) + 8) << (e - 1); } - -int luaO_log2 (unsigned int x) { - static const lu_byte log_2[256] = { - 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 - }; - int l = -1; - while (x >= 256) { l += 8; x >>= 8; } - return l + log_2[x]; +int luaO_log2(unsigned int x) +{ + static const lu_byte log_2[256] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; + int l = -1; + while (x >= 256) + { + l += 8; + x >>= 8; + } + return l + log_2[x]; } - -int luaO_rawequalObj (const TValue *t1, const TValue *t2) { - if (ttype(t1) != ttype(t2)) return 0; - else switch (ttype(t1)) { - case LUA_TNIL: - return 1; - case LUA_TNUMBER: - return luai_numeq(nvalue(t1), nvalue(t2)); - case LUA_TBOOLEAN: - return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ - case LUA_TLIGHTUSERDATA: - return pvalue(t1) == pvalue(t2); - case LUA_TROTABLE: - return rvalue(t1) == rvalue(t2); - case LUA_TLIGHTFUNCTION: - return fvalue(t1) == fvalue(t2); - default: - lua_assert(iscollectable(t1)); - return gcvalue(t1) == gcvalue(t2); - } +int luaO_rawequalObj(const TValue *t1, const TValue *t2) +{ + if (ttype(t1) != ttype(t2)) + return 0; + else + switch (ttype(t1)) + { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + case LUA_TROTABLE: + return rvalue(t1) == rvalue(t2); + case LUA_TLIGHTFUNCTION: + return fvalue(t1) == fvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } } - -int luaO_str2d (const char *s, lua_Number *result) { - char *endptr; - *result = lua_str2number(s, &endptr); - if (endptr == s) return 0; /* conversion failed */ - if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ -#if defined(LUA_CROSS_COMPILER) +int luaO_str2d(const char *s, lua_Number *result) +{ + char *endptr; + *result = lua_str2number(s, &endptr); + if (endptr == s) + return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ +#if defined(LUA_CROSS_COMPILER) { - long lres = strtoul(s, &endptr, 16); + long lres = strtoul(s, &endptr, 16); #if LONG_MAX != 2147483647L - if (lres & ~0xffffffffL) - *result = cast_num(-1); - else if (lres & 0x80000000L) - *result = cast_num(lres | ~0x7fffffffL); - else + if (lres & ~0xffffffffL) + *result = cast_num(-1); + else if (lres & 0x80000000L) + *result = cast_num(lres | ~0x7fffffffL); + else #endif - *result = cast_num(lres); + *result = cast_num(lres); } #else - *result = cast_num(strtoul(s, &endptr, 16)); + *result = cast_num(strtoul(s, &endptr, 16)); #endif - if (*endptr == '\0') return 1; /* most common case */ - while (isspace(cast(unsigned char, *endptr))) endptr++; - if (*endptr != '\0') return 0; /* invalid trailing characters? */ - return 1; + if (*endptr == '\0') + return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; + if (*endptr != '\0') + return 0; /* invalid trailing characters? */ + return 1; } - - -static void pushstr (lua_State *L, const char *str) { - setsvalue2s(L, L->top, luaS_new(L, str)); - incr_top(L); +static void pushstr(lua_State *L, const char *str) +{ + setsvalue2s(L, L->top, luaS_new(L, str)); + incr_top(L); } - /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ -const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { - int n = 1; - pushstr(L, ""); - for (;;) { - const char *e = strchr(fmt, '%'); - if (e == NULL) break; - setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); - incr_top(L); - switch (*(e+1)) { - case 's': { - const char *s = va_arg(argp, char *); - if (s == NULL) s = "(null)"; - pushstr(L, s); - break; - } - case 'c': { - char buff[2]; - buff[0] = cast(char, va_arg(argp, int)); - buff[1] = '\0'; - pushstr(L, buff); - break; - } - case 'd': { - setnvalue(L->top, cast_num(va_arg(argp, int))); - incr_top(L); - break; - } - case 'f': { - setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); +const char *luaO_pushvfstring(lua_State *L, const char *fmt, va_list argp) +{ + int n = 1; + pushstr(L, ""); + for (;;) + { + const char *e = strchr(fmt, '%'); + if (e == NULL) + break; + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e - fmt)); incr_top(L); - break; - } - case 'p': { - char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ - sprintf(buff, "%p", va_arg(argp, void *)); - pushstr(L, buff); - break; - } - case '%': { - pushstr(L, "%"); - break; - } - default: { - char buff[3]; - buff[0] = '%'; - buff[1] = *(e+1); - buff[2] = '\0'; - pushstr(L, buff); - break; - } + switch (*(e + 1)) + { + case 's': + { + const char *s = va_arg(argp, char *); + if (s == NULL) + s = "(null)"; + pushstr(L, s); + break; + } + case 'c': + { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': + { + setnvalue(L->top, cast_num(va_arg(argp, int))); + incr_top(L); + break; + } + case 'f': + { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + incr_top(L); + break; + } + case 'p': + { + char buff[4 * sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': + { + pushstr(L, "%"); + break; + } + default: + { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e + 1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } + } + n += 2; + fmt = e + 2; } - n += 2; - fmt = e+2; - } - pushstr(L, fmt); - luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); - L->top -= n; - return svalue(L->top - 1); + pushstr(L, fmt); + luaV_concat(L, n + 1, cast_int(L->top - L->base) - 1); + L->top -= n; + return svalue(L->top - 1); } - -const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { - const char *msg; - va_list argp; - va_start(argp, fmt); - msg = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - return msg; +const char *luaO_pushfstring(lua_State *L, const char *fmt, ...) +{ + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; } - -void luaO_chunkid (char *out, const char *source, size_t bufflen) { - if (*source == '=') { - strncpy(out, source+1, bufflen); /* remove first char */ - out[bufflen-1] = '\0'; /* ensures null termination */ - } - else { /* out = "source", or "...source" */ - if (*source == '@') { - size_t l; - source++; /* skip the `@' */ - bufflen -= sizeof(" '...' "); - l = strlen(source); - strcpy(out, ""); - if (l > bufflen) { - source += (l-bufflen); /* get last part of file name */ - strcat(out, "..."); - } - strcat(out, source); +void luaO_chunkid(char *out, const char *source, size_t bufflen) +{ + if (*source == '=') + { + strncpy(out, source + 1, bufflen); /* remove first char */ + out[bufflen - 1] = '\0'; /* ensures null termination */ } - else { /* out = [string "string"] */ - size_t len = strcspn(source, "\n\r"); /* stop at first newline */ - bufflen -= sizeof(" [string \"...\"] "); - if (len > bufflen) len = bufflen; - strcpy(out, "[string \""); - if (source[len] != '\0') { /* must truncate? */ - strncat(out, source, len); - strcat(out, "..."); - } - else - strcat(out, source); - strcat(out, "\"]"); + else + { /* out = "source", or "...source" */ + if (*source == '@') + { + size_t l; + source++; /* skip the `@' */ + bufflen -= sizeof(" '...' "); + l = strlen(source); + strcpy(out, ""); + if (l > bufflen) + { + source += (l - bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else + { /* out = [string "string"] */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) + len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') + { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } } - } } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lopcodes.c b/LuaNode_Esp32/LuaNode32/components/lua/lopcodes.c index f6ecd06..a91af3c 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lopcodes.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lopcodes.c @@ -3,100 +3,100 @@ ** See Copyright Notice in lua.h */ - #define lopcodes_c #define LUA_CORE #define LUAC_CROSS_FILE -#include "luac_cross.h" #include "lopcodes.h" -/* ORDER OP */ +#include "luac_cross.h" -const char *const luaP_opnames[NUM_OPCODES+1] = { - "MOVE", - "LOADK", - "LOADBOOL", - "LOADNIL", - "GETUPVAL", - "GETGLOBAL", - "GETTABLE", - "SETGLOBAL", - "SETUPVAL", - "SETTABLE", - "NEWTABLE", - "SELF", - "ADD", - "SUB", - "MUL", - "DIV", - "MOD", - "POW", - "UNM", - "NOT", - "LEN", - "CONCAT", - "JMP", - "EQ", - "LT", - "LE", - "TEST", - "TESTSET", - "CALL", - "TAILCALL", - "RETURN", - "FORLOOP", - "FORPREP", - "TFORLOOP", - "SETLIST", - "CLOSE", - "CLOSURE", - "VARARG", - NULL -}; +/* ORDER OP */ +const char *const luaP_opnames[NUM_OPCODES + 1] = { + "MOVE", "LOADK", "LOADBOOL", "LOADNIL", "GETUPVAL", "GETGLOBAL", "GETTABLE", "SETGLOBAL", + "SETUPVAL", "SETTABLE", "NEWTABLE", "SELF", "ADD", "SUB", "MUL", "DIV", + "MOD", "POW", "UNM", "NOT", "LEN", "CONCAT", "JMP", "EQ", + "LT", "LE", "TEST", "TESTSET", "CALL", "TAILCALL", "RETURN", "FORLOOP", + "FORPREP", "TFORLOOP", "SETLIST", "CLOSE", "CLOSURE", "VARARG", NULL}; -#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) +#define opmode(t, a, b, c, m) (((t) << 7) | ((a) << 6) | ((b) << 4) | ((c) << 2) | (m)) const lu_byte luaP_opmodes[NUM_OPCODES] = { -/* T A B C mode opcode */ - opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ - ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ - ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ - ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ - ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ - ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ - ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ - ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ - ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ - ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ - ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ - ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ - ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ - ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ - ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ - ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ - ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + /* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + , + opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + , + opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + , + opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + , + opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + , + opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + , + opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + , + opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + , + opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + , + opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + , + opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + , + opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + , + opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + , + opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + , + opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + , + opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + , + opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + , + opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + , + opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + , + opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + , + opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + , + opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + , + opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + , + opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ }; - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lparser.c b/LuaNode_Esp32/LuaNode32/components/lua/lparser.c index 7b14c3d..f0ec6f8 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lparser.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lparser.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define lparser_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -25,1352 +24,1465 @@ #include "lstring.h" #include "ltable.h" +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) -#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) - -#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) - -#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) - +#define luaY_checklimit(fs, v, l, m) \ + if ((v) > (l)) \ + errorlimit(fs, l, m) /* ** nodes for block list (list of active blocks) */ -typedef struct BlockCnt { - struct BlockCnt *previous; /* chain */ - int breaklist; /* list of jumps out of this loop */ - lu_byte nactvar; /* # active locals outside the breakable structure */ - lu_byte upval; /* true if some variable in the block is an upvalue */ - lu_byte isbreakable; /* true if `block' is a loop */ +typedef struct BlockCnt +{ + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + lu_byte nactvar; /* # active locals outside the breakable structure */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isbreakable; /* true if `block' is a loop */ } BlockCnt; - - /* ** prototypes for recursive non-terminal functions */ -static void chunk (LexState *ls); -static void expr (LexState *ls, expdesc *v); - - -static void anchor_token (LexState *ls) { - if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { - TString *ts = ls->t.seminfo.ts; - luaX_newstring(ls, getstr(ts), ts->tsv.len); - } +static void chunk(LexState *ls); +static void expr(LexState *ls, expdesc *v); + +static void anchor_token(LexState *ls) +{ + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) + { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } } - -static void error_expected (LexState *ls, int token) { - luaX_syntaxerror(ls, - luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +static void error_expected(LexState *ls, int token) +{ + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); } - -static void errorlimit (FuncState *fs, int limit, const char *what) { - const char *msg = (fs->f->linedefined == 0) ? - luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : - luaO_pushfstring(fs->L, "function at line %d has more than %d %s", - fs->f->linedefined, limit, what); - luaX_lexerror(fs->ls, msg, 0); +static void errorlimit(FuncState *fs, int limit, const char *what) +{ + const char *msg = + (fs->f->linedefined == 0) + ? luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) + : luaO_pushfstring(fs->L, "function at line %d has more than %d %s", fs->f->linedefined, limit, what); + luaX_lexerror(fs->ls, msg, 0); } - -static int testnext (LexState *ls, int c) { - if (ls->t.token == c) { - luaX_next(ls); - return 1; - } - else return 0; +static int testnext(LexState *ls, int c) +{ + if (ls->t.token == c) + { + luaX_next(ls); + return 1; + } + else + return 0; } - -static void check (LexState *ls, int c) { - if (ls->t.token != c) - error_expected(ls, c); +static void check(LexState *ls, int c) +{ + if (ls->t.token != c) + error_expected(ls, c); } -static void checknext (LexState *ls, int c) { - check(ls, c); - luaX_next(ls); +static void checknext(LexState *ls, int c) +{ + check(ls, c); + luaX_next(ls); } +#define check_condition(ls, c, msg) \ + { \ + if (!(c)) \ + luaX_syntaxerror(ls, msg); \ + } -#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } - - - -static void check_match (LexState *ls, int what, int who, int where) { - if (!testnext(ls, what)) { - if (where == ls->linenumber) - error_expected(ls, what); - else { - luaX_syntaxerror(ls, luaO_pushfstring(ls->L, - LUA_QS " expected (to close " LUA_QS " at line %d)", - luaX_token2str(ls, what), luaX_token2str(ls, who), where)); +static void check_match(LexState *ls, int what, int who, int where) +{ + if (!testnext(ls, what)) + { + if (where == ls->linenumber) + error_expected(ls, what); + else + { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, LUA_QS " expected (to close " LUA_QS " at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } } - } } - -static TString *str_checkname (LexState *ls) { - TString *ts; - check(ls, TK_NAME); - ts = ls->t.seminfo.ts; - luaX_next(ls); - return ts; +static TString *str_checkname(LexState *ls) +{ + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; } - -static void init_exp (expdesc *e, expkind k, int i) { - e->f = e->t = NO_JUMP; - e->k = k; - e->u.s.info = i; +static void init_exp(expdesc *e, expkind k, int i) +{ + e->f = e->t = NO_JUMP; + e->k = k; + e->u.s.info = i; } +static void codestring(LexState *ls, expdesc *e, TString *s) { init_exp(e, VK, luaK_stringK(ls->fs, s)); } -static void codestring (LexState *ls, expdesc *e, TString *s) { - init_exp(e, VK, luaK_stringK(ls->fs, s)); -} - +static void checkname(LexState *ls, expdesc *e) { codestring(ls, e, str_checkname(ls)); } -static void checkname(LexState *ls, expdesc *e) { - codestring(ls, e, str_checkname(ls)); +static int registerlocalvar(LexState *ls, TString *varname) +{ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, LocVar, SHRT_MAX, "too many local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; } +#define new_localvarliteral(ls, v, n) new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v) / sizeof(char)) - 1), n) -static int registerlocalvar (LexState *ls, TString *varname) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - int oldsize = f->sizelocvars; - luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, - LocVar, SHRT_MAX, "too many local variables"); - while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; - f->locvars[fs->nlocvars].varname = varname; - luaC_objbarrier(ls->L, f, varname); - return fs->nlocvars++; +static void new_localvar(LexState *ls, TString *name, int n) +{ + FuncState *fs = ls->fs; + luaY_checklimit(fs, fs->nactvar + n + 1, LUAI_MAXVARS, "local variables"); + fs->actvar[fs->nactvar + n] = cast(unsigned short, registerlocalvar(ls, name)); } - -#define new_localvarliteral(ls,v,n) \ - new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) - - -static void new_localvar (LexState *ls, TString *name, int n) { - FuncState *fs = ls->fs; - luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); - fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); +static void adjustlocalvars(LexState *ls, int nvars) +{ + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; } } - -static void adjustlocalvars (LexState *ls, int nvars) { - FuncState *fs = ls->fs; - fs->nactvar = cast_byte(fs->nactvar + nvars); - for (; nvars; nvars--) { - getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; - } +static void removevars(LexState *ls, int tolevel) +{ + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) getlocvar(fs, --fs->nactvar).endpc = fs->pc; } - -static void removevars (LexState *ls, int tolevel) { - FuncState *fs = ls->fs; - while (fs->nactvar > tolevel) - getlocvar(fs, --fs->nactvar).endpc = fs->pc; +static int indexupvalue(FuncState *fs, TString *name, expdesc *v) +{ + int i; + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + for (i = 0; i < f->nups; i++) + { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) + { + lua_assert(f->upvalues[i] == name); + return i; + } + } + /* new one */ + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, TString *, MAX_INT, ""); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; + f->upvalues[f->nups] = name; + luaC_objbarrier(fs->L, f, name); + lua_assert(v->k == VLOCAL || v->k == VUPVAL); + fs->upvalues[f->nups].k = cast_byte(v->k); + fs->upvalues[f->nups].info = cast_byte(v->u.s.info); + return f->nups++; +} + +static int searchvar(FuncState *fs, TString *n) +{ + int i; + for (i = fs->nactvar - 1; i >= 0; i--) + { + if (n == getlocvar(fs, i).varname) + return i; + } + return -1; /* not found */ } +static void markupval(FuncState *fs, int level) +{ + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) + bl->upval = 1; +} -static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { - int i; - Proto *f = fs->f; - int oldsize = f->sizeupvalues; - for (i=0; inups; i++) { - if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { - lua_assert(f->upvalues[i] == name); - return i; - } - } - /* new one */ - luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); - luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, - TString *, MAX_INT, ""); - while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; - f->upvalues[f->nups] = name; - luaC_objbarrier(fs->L, f, name); - lua_assert(v->k == VLOCAL || v->k == VUPVAL); - fs->upvalues[f->nups].k = cast_byte(v->k); - fs->upvalues[f->nups].info = cast_byte(v->u.s.info); - return f->nups++; -} - - -static int searchvar (FuncState *fs, TString *n) { - int i; - for (i=fs->nactvar-1; i >= 0; i--) { - if (n == getlocvar(fs, i).varname) - return i; - } - return -1; /* not found */ -} - - -static void markupval (FuncState *fs, int level) { - BlockCnt *bl = fs->bl; - while (bl && bl->nactvar > level) bl = bl->previous; - if (bl) bl->upval = 1; -} - - -static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { - if (fs == NULL) { /* no more levels? */ - init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ - return VGLOBAL; - } - else { - int v = searchvar(fs, n); /* look up at current level */ - if (v >= 0) { - init_exp(var, VLOCAL, v); - if (!base) - markupval(fs, v); /* local will be used as an upval */ - return VLOCAL; - } - else { /* not found at current level; try upper one */ - if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) +static int singlevaraux(FuncState *fs, TString *n, expdesc *var, int base) +{ + if (fs == NULL) + { /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ return VGLOBAL; - var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ - var->k = VUPVAL; /* upvalue in this level */ - return VUPVAL; } - } + else + { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) + { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else + { /* not found at current level; try upper one */ + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) + return VGLOBAL; + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->k = VUPVAL; /* upvalue in this level */ + return VUPVAL; + } + } } - -static void singlevar (LexState *ls, expdesc *var) { - TString *varname = str_checkname(ls); - FuncState *fs = ls->fs; - if (singlevaraux(fs, varname, var, 1) == VGLOBAL) - var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +static void singlevar(LexState *ls, expdesc *var) +{ + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VGLOBAL) + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +} + +static void adjust_assign(LexState *ls, int nvars, int nexps, expdesc *e) +{ + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) + { + extra++; /* includes call itself */ + if (extra < 0) + extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) + luaK_reserveregs(fs, extra - 1); + } + else + { + if (e->k != VVOID) + luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) + { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } } - -static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { - FuncState *fs = ls->fs; - int extra = nvars - nexps; - if (hasmultret(e->k)) { - extra++; /* includes call itself */ - if (extra < 0) extra = 0; - luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ - if (extra > 1) luaK_reserveregs(fs, extra-1); - } - else { - if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ - if (extra > 0) { - int reg = fs->freereg; - luaK_reserveregs(fs, extra); - luaK_nil(fs, reg, extra); +static void enterlevel(LexState *ls) +{ + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + +#define leavelevel(ls) ((ls)->L->nCcalls--) + +static void enterblock(FuncState *fs, BlockCnt *bl, lu_byte isbreakable) +{ + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + +static void leaveblock(FuncState *fs) +{ + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + /* a block either controls scope or breaks (never both) */ + lua_assert(!bl->isbreakable || !bl->upval); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + +static void pushclosure(LexState *ls, FuncState *func, expdesc *v) +{ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizep; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + f->p[fs->np++] = func->f; + luaC_objbarrier(ls->L, f, func->f); + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + for (i = 0; i < func->f->nups; i++) + { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); } - } -} - - -static void enterlevel (LexState *ls) { - if (++ls->L->nCcalls > LUAI_MAXCCALLS) - luaX_lexerror(ls, "chunk has too many syntax levels", 0); -} - - -#define leavelevel(ls) ((ls)->L->nCcalls--) - - -static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { - bl->breaklist = NO_JUMP; - bl->isbreakable = isbreakable; - bl->nactvar = fs->nactvar; - bl->upval = 0; - bl->previous = fs->bl; - fs->bl = bl; - lua_assert(fs->freereg == fs->nactvar); -} - - -static void leaveblock (FuncState *fs) { - BlockCnt *bl = fs->bl; - fs->bl = bl->previous; - removevars(fs->ls, bl->nactvar); - if (bl->upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); - /* a block either controls scope or breaks (never both) */ - lua_assert(!bl->isbreakable || !bl->upval); - lua_assert(bl->nactvar == fs->nactvar); - fs->freereg = fs->nactvar; /* free registers */ - luaK_patchtohere(fs, bl->breaklist); -} - - -static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - int oldsize = f->sizep; - int i; - luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, - MAXARG_Bx, "constant table overflow"); - while (oldsize < f->sizep) f->p[oldsize++] = NULL; - f->p[fs->np++] = func->f; - luaC_objbarrier(ls->L, f, func->f); - init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); - for (i=0; if->nups; i++) { - OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; - luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); - } -} - - -static void open_func (LexState *ls, FuncState *fs) { - lua_State *L = ls->L; - Proto *f = luaF_newproto(L); - fs->f = f; - fs->prev = ls->fs; /* linked list of funcstates */ - fs->ls = ls; - fs->L = L; - ls->fs = fs; - fs->pc = 0; - fs->lasttarget = -1; - fs->jpc = NO_JUMP; - fs->freereg = 0; - fs->nk = 0; - fs->np = 0; - fs->nlocvars = 0; - fs->nactvar = 0; - fs->bl = NULL; - f->source = ls->source; - f->maxstacksize = 2; /* registers 0/1 are always valid */ +} + +static void open_func(LexState *ls, FuncState *fs) +{ + lua_State *L = ls->L; + Proto *f = luaF_newproto(L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = -1; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ #ifdef LUA_OPTIMIZE_DEBUG - fs->packedlineinfoSize = 0; - fs->lastline = 0; - fs->lastlineOffset = 0; - fs->lineinfoLastPC = -1; + fs->packedlineinfoSize = 0; + fs->lastline = 0; + fs->lastlineOffset = 0; + fs->lineinfoLastPC = -1; #endif - fs->h = luaH_new(L, 0, 0); - /* anchor table of constants and prototype (to avoid being collected) */ - sethvalue2s(L, L->top, fs->h); - incr_top(L); - setptvalue2s(L, L->top, f); - incr_top(L); -} - - -static void close_func (LexState *ls) { - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Proto *f = fs->f; - removevars(ls, 0); - luaK_ret(fs, 0, 0); /* final return */ - luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); - f->sizecode = fs->pc; + fs->h = luaH_new(L, 0, 0); + /* anchor table of constants and prototype (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + setptvalue2s(L, L->top, f); + incr_top(L); +} + +static void close_func(LexState *ls) +{ + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_ret(fs, 0, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; #ifdef LUA_OPTIMIZE_DEBUG - f->packedlineinfo[fs->lastlineOffset+1]=0; - luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize, - fs->lastlineOffset+2, unsigned char); + f->packedlineinfo[fs->lastlineOffset + 1] = 0; + luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize, fs->lastlineOffset + 2, unsigned char); #else - luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); - f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; #endif - luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); - f->sizek = fs->nk; - luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); - f->sizep = fs->np; - luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); - f->sizelocvars = fs->nlocvars; - luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); - f->sizeupvalues = f->nups; - lua_assert(luaG_checkcode(f)); - lua_assert(fs->bl == NULL); - ls->fs = fs->prev; - /* last token read was anchored in defunct function; must reanchor it */ - if (fs) anchor_token(ls); - L->top -= 2; /* remove table and prototype from the stack */ + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + /* last token read was anchored in defunct function; must reanchor it */ + if (fs) + anchor_token(ls); + L->top -= 2; /* remove table and prototype from the stack */ } #ifdef LUA_OPTIMIZE_DEBUG -static void compile_stripdebug(lua_State *L, Proto *f) { - int level; - lua_pushlightuserdata(L, &luaG_stripdebug ); - lua_gettable(L, LUA_REGISTRYINDEX); - level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1); - lua_pop(L, 1); - - if (level > 1) { - int len = luaG_stripdebug(L, f, level, 1); - UNUSED(len); - } +static void compile_stripdebug(lua_State *L, Proto *f) +{ + int level; + lua_pushlightuserdata(L, &luaG_stripdebug); + lua_gettable(L, LUA_REGISTRYINDEX); + level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1); + lua_pop(L, 1); + + if (level > 1) + { + int len = luaG_stripdebug(L, f, level, 1); + UNUSED(len); + } } #endif - -Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { - struct LexState lexstate; - struct FuncState funcstate; - TString *tname = luaS_new(L, name); - setsvalue2s(L, L->top, tname); /* protect name */ - incr_top(L); - lexstate.buff = buff; - luaX_setinput(L, &lexstate, z, tname); - open_func(&lexstate, &funcstate); - funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ - luaX_next(&lexstate); /* read first token */ - chunk(&lexstate); - check(&lexstate, TK_EOS); - close_func(&lexstate); +Proto *luaY_parser(lua_State *L, ZIO *z, Mbuffer *buff, const char *name) +{ + struct LexState lexstate; + struct FuncState funcstate; + TString *tname = luaS_new(L, name); + setsvalue2s(L, L->top, tname); /* protect name */ + incr_top(L); + lexstate.buff = buff; + luaX_setinput(L, &lexstate, z, tname); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); #ifdef LUA_OPTIMIZE_DEBUG - compile_stripdebug(L, funcstate.f); + compile_stripdebug(L, funcstate.f); #endif - L->top--; /* remove 'name' from stack */ - lua_assert(funcstate.prev == NULL); - lua_assert(funcstate.f->nups == 0); - lua_assert(lexstate.fs == NULL); - return funcstate.f; + L->top--; /* remove 'name' from stack */ + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); + return funcstate.f; } - - /*============================================================*/ /* GRAMMAR RULES */ /*============================================================*/ - -static void field (LexState *ls, expdesc *v) { - /* field -> ['.' | ':'] NAME */ - FuncState *fs = ls->fs; - expdesc key; - luaK_exp2anyreg(fs, v); - luaX_next(ls); /* skip the dot or colon */ - checkname(ls, &key); - luaK_indexed(fs, v, &key); +static void field(LexState *ls, expdesc *v) +{ + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); } - -static void yindex (LexState *ls, expdesc *v) { - /* index -> '[' expr ']' */ - luaX_next(ls); /* skip the '[' */ - expr(ls, v); - luaK_exp2val(ls->fs, v); - checknext(ls, ']'); +static void yindex(LexState *ls, expdesc *v) +{ + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); } - /* ** {====================================================================== ** Rules for Constructors ** ======================================================================= */ - -struct ConsControl { - expdesc v; /* last list item read */ - expdesc *t; /* table descriptor */ - int nh; /* total number of `record' elements */ - int na; /* total number of array elements */ - int tostore; /* number of array elements pending to be stored */ +struct ConsControl +{ + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ }; - -static void recfield (LexState *ls, struct ConsControl *cc) { - /* recfield -> (NAME | `['exp1`]') = exp1 */ - FuncState *fs = ls->fs; - int reg = ls->fs->freereg; - expdesc key, val; - int rkkey; - if (ls->t.token == TK_NAME) { - luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); - checkname(ls, &key); - } - else /* ls->t.token == '[' */ - yindex(ls, &key); - cc->nh++; - checknext(ls, '='); - rkkey = luaK_exp2RK(fs, &key); - expr(ls, &val); - luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); - fs->freereg = reg; /* free registers */ -} - - -static void closelistfield (FuncState *fs, struct ConsControl *cc) { - if (cc->v.k == VVOID) return; /* there is no list item */ - luaK_exp2nextreg(fs, &cc->v); - cc->v.k = VVOID; - if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ - cc->tostore = 0; /* no more items pending */ - } -} - - -static void lastlistfield (FuncState *fs, struct ConsControl *cc) { - if (cc->tostore == 0) return; - if (hasmultret(cc->v.k)) { - luaK_setmultret(fs, &cc->v); - luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); - cc->na--; /* do not count last expression (unknown number of elements) */ - } - else { - if (cc->v.k != VVOID) - luaK_exp2nextreg(fs, &cc->v); - luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); - } -} - - -static void listfield (LexState *ls, struct ConsControl *cc) { - expr(ls, &cc->v); - luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); - cc->na++; - cc->tostore++; -} - - -static void constructor (LexState *ls, expdesc *t) { - /* constructor -> ?? */ - FuncState *fs = ls->fs; - int line = ls->linenumber; - int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); - struct ConsControl cc; - cc.na = cc.nh = cc.tostore = 0; - cc.t = t; - init_exp(t, VRELOCABLE, pc); - init_exp(&cc.v, VVOID, 0); /* no value (yet) */ - luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ - checknext(ls, '{'); - do { - lua_assert(cc.v.k == VVOID || cc.tostore > 0); - if (ls->t.token == '}') break; - closelistfield(fs, &cc); - switch(ls->t.token) { - case TK_NAME: { /* may be listfields or recfields */ - luaX_lookahead(ls); - if (ls->lookahead.token != '=') /* expression? */ - listfield(ls, &cc); - else - recfield(ls, &cc); - break; - } - case '[': { /* constructor_item -> recfield */ - recfield(ls, &cc); - break; - } - default: { /* constructor_part -> listfield */ - listfield(ls, &cc); - break; - } +static void recfield(LexState *ls, struct ConsControl *cc) +{ + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) + { + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + +static void closelistfield(FuncState *fs, struct ConsControl *cc) +{ + if (cc->v.k == VVOID) + return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) + { + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ } - } while (testnext(ls, ',') || testnext(ls, ';')); - check_match(ls, '}', '{', line); - lastlistfield(fs, &cc); - SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ - SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ } -/* }====================================================================== */ +static void lastlistfield(FuncState *fs, struct ConsControl *cc) +{ + if (cc->tostore == 0) + return; + if (hasmultret(cc->v.k)) + { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) + */ + } + else + { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + } +} +static void listfield(LexState *ls, struct ConsControl *cc) +{ + expr(ls, &cc->v); + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + +static void constructor(LexState *ls, expdesc *t) +{ + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + checknext(ls, '{'); + do + { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') + break; + closelistfield(fs, &cc); + switch (ls->t.token) + { + case TK_NAME: + { /* may be listfields or recfields */ + luaX_lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': + { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: + { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} +/* }====================================================================== */ -static void parlist (LexState *ls) { - /* parlist -> [ param { `,' param } ] */ - FuncState *fs = ls->fs; - Proto *f = fs->f; - int nparams = 0; - f->is_vararg = 0; - if (ls->t.token != ')') { /* is `parlist' not empty? */ - do { - switch (ls->t.token) { - case TK_NAME: { /* param -> NAME */ - new_localvar(ls, str_checkname(ls), nparams++); - break; - } - case TK_DOTS: { /* param -> `...' */ - luaX_next(ls); +static void parlist(LexState *ls) +{ + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') + { /* is `parlist' not empty? */ + do + { + switch (ls->t.token) + { + case TK_NAME: + { /* param -> NAME */ + new_localvar(ls, str_checkname(ls), nparams++); + break; + } + case TK_DOTS: + { /* param -> `...' */ + luaX_next(ls); #if defined(LUA_COMPAT_VARARG) - /* use `arg' as default name */ - new_localvarliteral(ls, "arg", nparams++); - f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; + /* use `arg' as default name */ + new_localvarliteral(ls, "arg", nparams++); + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; #endif - f->is_vararg |= VARARG_ISVARARG; - break; - } - default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); - } - } while (!f->is_vararg && testnext(ls, ',')); - } - adjustlocalvars(ls, nparams); - f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); - luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ -} - - -static void body (LexState *ls, expdesc *e, int needself, int line) { - /* body -> `(' parlist `)' chunk END */ - FuncState new_fs; - open_func(ls, &new_fs); - new_fs.f->linedefined = line; - checknext(ls, '('); - if (needself) { - new_localvarliteral(ls, "self", 0); - adjustlocalvars(ls, 1); - } - parlist(ls); - checknext(ls, ')'); - chunk(ls); - new_fs.f->lastlinedefined = ls->linenumber; - check_match(ls, TK_END, TK_FUNCTION, line); - close_func(ls); - pushclosure(ls, &new_fs, e); -} - - -static int explist1 (LexState *ls, expdesc *v) { - /* explist1 -> expr { `,' expr } */ - int n = 1; /* at least one expression */ - expr(ls, v); - while (testnext(ls, ',')) { - luaK_exp2nextreg(ls->fs, v); - expr(ls, v); - n++; - } - return n; -} - - -static void funcargs (LexState *ls, expdesc *f) { - FuncState *fs = ls->fs; - expdesc args; - int base, nparams; - int line = ls->linenumber; - switch (ls->t.token) { - case '(': { /* funcargs -> `(' [ explist1 ] `)' */ - if (line != ls->lastline) - luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); - luaX_next(ls); - if (ls->t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - explist1(ls, &args); - luaK_setmultret(fs, &args); - } - check_match(ls, ')', '(', line); - break; + f->is_vararg |= VARARG_ISVARARG; + break; + } + default: + luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); } - case '{': { /* funcargs -> constructor */ - constructor(ls, &args); - break; + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + +static void body(LexState *ls, expdesc *e, int needself, int line) +{ + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->linedefined = line; + checknext(ls, '('); + if (needself) + { + new_localvarliteral(ls, "self", 0); + adjustlocalvars(ls, 1); } - case TK_STRING: { /* funcargs -> STRING */ - codestring(ls, &args, ls->t.seminfo.ts); - luaX_next(ls); /* must use `seminfo' before `next' */ - break; + parlist(ls); + checknext(ls, ')'); + chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + +static int explist1(LexState *ls, expdesc *v) +{ + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) + { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + +static void funcargs(LexState *ls, expdesc *f) +{ + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) + { + case '(': + { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls, "ambiguous syntax (function call x new statement)"); + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else + { + explist1(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': + { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: + { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: + { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } } - default: { - luaX_syntaxerror(ls, "function arguments expected"); - return; + lua_assert(f->k == VNONRELOC); + base = f->u.s.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else + { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base + 1); } - } - lua_assert(f->k == VNONRELOC); - base = f->u.s.info; /* base register for call */ - if (hasmultret(args.k)) - nparams = LUA_MULTRET; /* open call */ - else { - if (args.k != VVOID) - luaK_exp2nextreg(fs, &args); /* close last argument */ - nparams = fs->freereg - (base+1); - } - init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); - luaK_fixline(fs, line); - fs->freereg = base+1; /* call remove function and arguments and leaves - (unless changed) one result */ + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams + 1, 2)); + luaK_fixline(fs, line); + fs->freereg = base + 1; /* call remove function and arguments and leaves + (unless changed) one result */ } - - - /* ** {====================================================================== ** Expression parsing ** ======================================================================= */ - -static void prefixexp (LexState *ls, expdesc *v) { - /* prefixexp -> NAME | '(' expr ')' */ - switch (ls->t.token) { - case '(': { - int line = ls->linenumber; - luaX_next(ls); - expr(ls, v); - check_match(ls, ')', '(', line); - luaK_dischargevars(ls->fs, v); - return; - } - case TK_NAME: { - singlevar(ls, v); - return; - } - default: { - luaX_syntaxerror(ls, "unexpected symbol"); - return; +static void prefixexp(LexState *ls, expdesc *v) +{ + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) + { + case '(': + { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: + { + singlevar(ls, v); + return; + } + default: + { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } } - } } - -static void primaryexp (LexState *ls, expdesc *v) { - /* primaryexp -> - prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ - FuncState *fs = ls->fs; - prefixexp(ls, v); - for (;;) { - switch (ls->t.token) { - case '.': { /* field */ - field(ls, v); - break; - } - case '[': { /* `[' exp1 `]' */ - expdesc key; - luaK_exp2anyreg(fs, v); - yindex(ls, &key); - luaK_indexed(fs, v, &key); - break; - } - case ':': { /* `:' NAME funcargs */ - expdesc key; - luaX_next(ls); - checkname(ls, &key); - luaK_self(fs, v, &key); - funcargs(ls, v); - break; - } - case '(': case TK_STRING: case '{': { /* funcargs */ - luaK_exp2nextreg(fs, v); - funcargs(ls, v); - break; - } - default: return; +static void primaryexp(LexState *ls, expdesc *v) +{ + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) + { + switch (ls->t.token) + { + case '.': + { /* field */ + field(ls, v); + break; + } + case '[': + { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': + { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': + case TK_STRING: + case '{': + { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: + return; + } } - } } - -static void simpleexp (LexState *ls, expdesc *v) { - /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | - constructor | FUNCTION body | primaryexp */ - switch (ls->t.token) { - case TK_NUMBER: { - init_exp(v, VKNUM, 0); - v->u.nval = ls->t.seminfo.r; - break; - } - case TK_STRING: { - codestring(ls, v, ls->t.seminfo.ts); - break; - } - case TK_NIL: { - init_exp(v, VNIL, 0); - break; - } - case TK_TRUE: { - init_exp(v, VTRUE, 0); - break; - } - case TK_FALSE: { - init_exp(v, VFALSE, 0); - break; - } - case TK_DOTS: { /* vararg */ - FuncState *fs = ls->fs; - check_condition(ls, fs->f->is_vararg, - "cannot use " LUA_QL("...") " outside a vararg function"); - fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ - init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); - break; - } - case '{': { /* constructor */ - constructor(ls, v); - return; +static void simpleexp(LexState *ls, expdesc *v) +{ + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ + switch (ls->t.token) + { + case TK_NUMBER: + { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: + { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: + { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: + { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: + { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: + { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, "cannot use " LUA_QL("...") " outside a vararg function"); + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': + { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: + { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: + { + primaryexp(ls, v); + return; + } } - case TK_FUNCTION: { - luaX_next(ls); - body(ls, v, 0, ls->linenumber); - return; + luaX_next(ls); +} + +static UnOpr getunopr(int op) +{ + switch (op) + { + case TK_NOT: + return OPR_NOT; + case '-': + return OPR_MINUS; + case '#': + return OPR_LEN; + default: + return OPR_NOUNOPR; } - default: { - primaryexp(ls, v); - return; +} + +static BinOpr getbinopr(int op) +{ + switch (op) + { + case '+': + return OPR_ADD; + case '-': + return OPR_SUB; + case '*': + return OPR_MUL; + case '/': + return OPR_DIV; + case '%': + return OPR_MOD; + case '^': + return OPR_POW; + case TK_CONCAT: + return OPR_CONCAT; + case TK_NE: + return OPR_NE; + case TK_EQ: + return OPR_EQ; + case '<': + return OPR_LT; + case TK_LE: + return OPR_LE; + case '>': + return OPR_GT; + case TK_GE: + return OPR_GE; + case TK_AND: + return OPR_AND; + case TK_OR: + return OPR_OR; + default: + return OPR_NOBINOPR; } - } - luaX_next(ls); -} - - -static UnOpr getunopr (int op) { - switch (op) { - case TK_NOT: return OPR_NOT; - case '-': return OPR_MINUS; - case '#': return OPR_LEN; - default: return OPR_NOUNOPR; - } -} - - -static BinOpr getbinopr (int op) { - switch (op) { - case '+': return OPR_ADD; - case '-': return OPR_SUB; - case '*': return OPR_MUL; - case '/': return OPR_DIV; - case '%': return OPR_MOD; - case '^': return OPR_POW; - case TK_CONCAT: return OPR_CONCAT; - case TK_NE: return OPR_NE; - case TK_EQ: return OPR_EQ; - case '<': return OPR_LT; - case TK_LE: return OPR_LE; - case '>': return OPR_GT; - case TK_GE: return OPR_GE; - case TK_AND: return OPR_AND; - case TK_OR: return OPR_OR; - default: return OPR_NOBINOPR; - } -} - - -static const struct { - lu_byte left; /* left priority for each binary operator */ - lu_byte right; /* right priority */ -} priority[] = { /* ORDER OPR */ - {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ - {10, 9}, {5, 4}, /* power and concat (right associative) */ - {3, 3}, {3, 3}, /* equality and inequality */ - {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ - {2, 2}, {1, 1} /* logical (and/or) */ -}; +} -#define UNARY_PRIORITY 8 /* priority for unary operators */ +static const struct +{ + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { + /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality and inequality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; +#define UNARY_PRIORITY 8 /* priority for unary operators */ /* ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } ** where `binop' is any binary operator with a priority higher than `limit' */ -static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { - BinOpr op; - UnOpr uop; - enterlevel(ls); - uop = getunopr(ls->t.token); - if (uop != OPR_NOUNOPR) { - luaX_next(ls); - subexpr(ls, v, UNARY_PRIORITY); - luaK_prefix(ls->fs, uop, v); - } - else simpleexp(ls, v); - /* expand while operators have priorities higher than `limit' */ - op = getbinopr(ls->t.token); - while (op != OPR_NOBINOPR && priority[op].left > limit) { - expdesc v2; - BinOpr nextop; - luaX_next(ls); - luaK_infix(ls->fs, op, v); - /* read sub-expression with higher priority */ - nextop = subexpr(ls, &v2, priority[op].right); - luaK_posfix(ls->fs, op, v, &v2); - op = nextop; - } - leavelevel(ls); - return op; /* return first untreated operator */ +static BinOpr subexpr(LexState *ls, expdesc *v, unsigned int limit) +{ + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) + { + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else + simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) + { + expdesc v2; + BinOpr nextop; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ } - -static void expr (LexState *ls, expdesc *v) { - subexpr(ls, v, 0); -} +static void expr(LexState *ls, expdesc *v) { subexpr(ls, v, 0); } /* }==================================================================== */ - - /* ** {====================================================================== ** Rules for Statements ** ======================================================================= */ - -static int block_follow (int token) { - switch (token) { - case TK_ELSE: case TK_ELSEIF: case TK_END: - case TK_UNTIL: case TK_EOS: - return 1; - default: return 0; - } +static int block_follow(int token) +{ + switch (token) + { + case TK_ELSE: + case TK_ELSEIF: + case TK_END: + case TK_UNTIL: + case TK_EOS: + return 1; + default: + return 0; + } } - -static void block (LexState *ls) { - /* block -> chunk */ - FuncState *fs = ls->fs; - BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt)); - enterblock(fs, pbl, 0); - chunk(ls); - lua_assert(pbl->breaklist == NO_JUMP); - leaveblock(fs); - luaM_free(ls->L,pbl); +static void block(LexState *ls) +{ + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt *pbl = (BlockCnt *)luaM_malloc(ls->L, sizeof(BlockCnt)); + enterblock(fs, pbl, 0); + chunk(ls); + lua_assert(pbl->breaklist == NO_JUMP); + leaveblock(fs); + luaM_free(ls->L, pbl); } - /* ** structure to chain all variables in the left-hand side of an ** assignment */ -struct LHS_assign { - struct LHS_assign *prev; - expdesc v; /* variable (global, local, upvalue, or indexed) */ +struct LHS_assign +{ + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ }; - /* ** check whether, in an assignment to a local variable, the local variable ** is needed in a previous assignment (to a table). If so, save original ** local value in a safe place and use this safe copy in the previous ** assignment. */ -static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { - FuncState *fs = ls->fs; - int extra = fs->freereg; /* eventual position to save local variable */ - int conflict = 0; - for (; lh; lh = lh->prev) { - if (lh->v.k == VINDEXED) { - if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ - conflict = 1; - lh->v.u.s.info = extra; /* previous assignment will use safe copy */ - } - if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ - conflict = 1; - lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ - } +static void check_conflict(LexState *ls, struct LHS_assign *lh, expdesc *v) +{ + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) + { + if (lh->v.k == VINDEXED) + { + if (lh->v.u.s.info == v->u.s.info) + { /* conflict? */ + conflict = 1; + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.u.s.aux == v->u.s.info) + { /* conflict? */ + conflict = 1; + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + } + } } - } - if (conflict) { - luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ - luaK_reserveregs(fs, 1); - } -} - - -static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { - expdesc e; - check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, - "syntax error"); - if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ - struct LHS_assign nv; - nv.prev = lh; - primaryexp(ls, &nv.v); - if (nv.v.k == VLOCAL) - check_conflict(ls, lh, &nv.v); - luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, - "variables in assignment"); - assignment(ls, &nv, nvars+1); - } - else { /* assignment -> `=' explist1 */ - int nexps; - checknext(ls, '='); - nexps = explist1(ls, &e); - if (nexps != nvars) { - adjust_assign(ls, nvars, nexps, &e); - if (nexps > nvars) - ls->fs->freereg -= nexps - nvars; /* remove extra values */ + if (conflict) + { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + +static void assignment(LexState *ls, struct LHS_assign *lh, int nvars) +{ + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); + if (testnext(ls, ',')) + { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); + assignment(ls, &nv, nvars + 1); } - else { - luaK_setoneret(ls->fs, &e); /* close last expression */ - luaK_storevar(ls->fs, &lh->v, &e); - return; /* avoid default */ + else + { /* assignment -> `=' explist1 */ + int nexps; + checknext(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) + { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else + { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } } - } - init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ - luaK_storevar(ls->fs, &lh->v, &e); -} - - -static int cond (LexState *ls) { - /* cond -> exp */ - expdesc v; - expr(ls, &v); /* read condition */ - if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ - luaK_goiftrue(ls->fs, &v); - return v.f; -} - - -static void breakstat (LexState *ls) { - FuncState *fs = ls->fs; - BlockCnt *bl = fs->bl; - int upval = 0; - while (bl && !bl->isbreakable) { - upval |= bl->upval; - bl = bl->previous; - } - if (!bl) - luaX_syntaxerror(ls, "no loop to break"); - if (upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); - luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); -} - - -static void whilestat (LexState *ls, int line) { - /* whilestat -> WHILE cond DO block END */ - FuncState *fs = ls->fs; - int whileinit; - int condexit; - BlockCnt bl; - luaX_next(ls); /* skip WHILE */ - whileinit = luaK_getlabel(fs); - condexit = cond(ls); - enterblock(fs, &bl, 1); - checknext(ls, TK_DO); - block(ls); - luaK_patchlist(fs, luaK_jump(fs), whileinit); - check_match(ls, TK_END, TK_WHILE, line); - leaveblock(fs); - luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ -} - - -static void repeatstat (LexState *ls, int line) { - /* repeatstat -> REPEAT block UNTIL cond */ - int condexit; - FuncState *fs = ls->fs; - int repeat_init = luaK_getlabel(fs); - BlockCnt bl1, bl2; - enterblock(fs, &bl1, 1); /* loop block */ - enterblock(fs, &bl2, 0); /* scope block */ - luaX_next(ls); /* skip REPEAT */ - chunk(ls); - check_match(ls, TK_UNTIL, TK_REPEAT, line); - condexit = cond(ls); /* read condition (inside scope block) */ - if (!bl2.upval) { /* no upvalues? */ - leaveblock(fs); /* finish scope */ - luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ - } - else { /* complete semantics when there are upvalues */ - breakstat(ls); /* if condition then break */ - luaK_patchtohere(ls->fs, condexit); /* else... */ - leaveblock(fs); /* finish scope... */ - luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ - } - leaveblock(fs); /* finish loop */ -} - - -static int exp1 (LexState *ls) { - expdesc e; - int k; - expr(ls, &e); - k = e.k; - luaK_exp2nextreg(ls->fs, &e); - return k; -} - - -static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { - /* forbody -> DO block */ - BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt)); - FuncState *fs = ls->fs; - int prep, endfor; - adjustlocalvars(ls, 3); /* control variables */ - checknext(ls, TK_DO); - prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); - enterblock(fs, pbl, 0); /* scope for declared variables */ - adjustlocalvars(ls, nvars); - luaK_reserveregs(fs, nvars); - block(ls); - leaveblock(fs); /* end of scope for declared variables */ - luaK_patchtohere(fs, prep); - endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : - luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); - luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ - luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); - luaM_free(ls->L,pbl); -} - - -static void fornum (LexState *ls, TString *varname, int line) { - /* fornum -> NAME = exp1,exp1[,exp1] forbody */ - FuncState *fs = ls->fs; - int base = fs->freereg; - new_localvarliteral(ls, "(for index)", 0); - new_localvarliteral(ls, "(for limit)", 1); - new_localvarliteral(ls, "(for step)", 2); - new_localvar(ls, varname, 3); - checknext(ls, '='); - exp1(ls); /* initial value */ - checknext(ls, ','); - exp1(ls); /* limit */ - if (testnext(ls, ',')) - exp1(ls); /* optional step */ - else { /* default step = 1 */ - luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); - luaK_reserveregs(fs, 1); - } - forbody(ls, base, line, 1, 1); -} - - -static void forlist (LexState *ls, TString *indexname) { - /* forlist -> NAME {,NAME} IN explist1 forbody */ - FuncState *fs = ls->fs; - expdesc e; - int nvars = 0; - int line; - int base = fs->freereg; - /* create control variables */ - new_localvarliteral(ls, "(for generator)", nvars++); - new_localvarliteral(ls, "(for state)", nvars++); - new_localvarliteral(ls, "(for control)", nvars++); - /* create declared variables */ - new_localvar(ls, indexname, nvars++); - while (testnext(ls, ',')) - new_localvar(ls, str_checkname(ls), nvars++); - checknext(ls, TK_IN); - line = ls->linenumber; - adjust_assign(ls, 3, explist1(ls, &e), &e); - luaK_checkstack(fs, 3); /* extra space to call generator */ - forbody(ls, base, line, nvars - 3, 0); -} - - -static void forstat (LexState *ls, int line) { - /* forstat -> FOR (fornum | forlist) END */ - FuncState *fs = ls->fs; - TString *varname; - BlockCnt bl; - enterblock(fs, &bl, 1); /* scope for loop and control variables */ - luaX_next(ls); /* skip `for' */ - varname = str_checkname(ls); /* first variable name */ - switch (ls->t.token) { - case '=': fornum(ls, varname, line); break; - case ',': case TK_IN: forlist(ls, varname); break; - default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); - } - check_match(ls, TK_END, TK_FOR, line); - leaveblock(fs); /* loop scope (`break' jumps to this point) */ -} - - -static int test_then_block (LexState *ls) { - /* test_then_block -> [IF | ELSEIF] cond THEN block */ - int condexit; - luaX_next(ls); /* skip IF or ELSEIF */ - condexit = cond(ls); - checknext(ls, TK_THEN); - block(ls); /* `then' part */ - return condexit; -} - - -static void ifstat (LexState *ls, int line) { - /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ - FuncState *fs = ls->fs; - int flist; - int escapelist = NO_JUMP; - flist = test_then_block(ls); /* IF cond THEN block */ - while (ls->t.token == TK_ELSEIF) { - luaK_concat(fs, &escapelist, luaK_jump(fs)); - luaK_patchtohere(fs, flist); - flist = test_then_block(ls); /* ELSEIF cond THEN block */ - } - if (ls->t.token == TK_ELSE) { - luaK_concat(fs, &escapelist, luaK_jump(fs)); - luaK_patchtohere(fs, flist); - luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ - block(ls); /* `else' part */ - } - else - luaK_concat(fs, &escapelist, flist); - luaK_patchtohere(fs, escapelist); - check_match(ls, TK_END, TK_IF, line); -} - - -static void localfunc (LexState *ls) { - expdesc v, b; - FuncState *fs = ls->fs; - new_localvar(ls, str_checkname(ls), 0); - init_exp(&v, VLOCAL, fs->freereg); - luaK_reserveregs(fs, 1); - adjustlocalvars(ls, 1); - body(ls, &b, 0, ls->linenumber); - luaK_storevar(fs, &v, &b); - /* debug information will only see the variable after this point! */ - getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; -} - - -static void localstat (LexState *ls) { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ - int nvars = 0; - int nexps; - expdesc e; - do { - new_localvar(ls, str_checkname(ls), nvars++); - } while (testnext(ls, ',')); - if (testnext(ls, '=')) - nexps = explist1(ls, &e); - else { - e.k = VVOID; - nexps = 0; - } - adjust_assign(ls, nvars, nexps, &e); - adjustlocalvars(ls, nvars); -} - - -static int funcname (LexState *ls, expdesc *v) { - /* funcname -> NAME {field} [`:' NAME] */ - int needself = 0; - singlevar(ls, v); - while (ls->t.token == '.') - field(ls, v); - if (ls->t.token == ':') { - needself = 1; - field(ls, v); - } - return needself; -} - - -static void funcstat (LexState *ls, int line) { - /* funcstat -> FUNCTION funcname body */ - int needself; - expdesc v, b; - luaX_next(ls); /* skip FUNCTION */ - needself = funcname(ls, &v); - body(ls, &b, needself, line); - luaK_storevar(ls->fs, &v, &b); - luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ -} - - -static void exprstat (LexState *ls) { - /* stat -> func | assignment */ - FuncState *fs = ls->fs; - struct LHS_assign v; - primaryexp(ls, &v.v); - if (v.v.k == VCALL) /* stat -> func */ - SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ - else { /* stat -> assignment */ - v.prev = NULL; - assignment(ls, &v, 1); - } -} - - -static void retstat (LexState *ls) { - /* stat -> RETURN explist */ - FuncState *fs = ls->fs; - expdesc e; - int first, nret; /* registers with returned values */ - luaX_next(ls); /* skip RETURN */ - if (block_follow(ls->t.token) || ls->t.token == ';') - first = nret = 0; /* return no values */ - else { - nret = explist1(ls, &e); /* optional return values */ - if (hasmultret(e.k)) { - luaK_setmultret(fs, &e); - if (e.k == VCALL && nret == 1) { /* tail call? */ - SET_OPCODE(getcode(fs,&e), OP_TAILCALL); - lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); - } - first = fs->nactvar; - nret = LUA_MULTRET; /* return all values */ + init_exp(&e, VNONRELOC, ls->fs->freereg - 1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + +static int cond(LexState *ls) +{ + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) + v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + +static void breakstat(LexState *ls) +{ + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + while (bl && !bl->isbreakable) + { + upval |= bl->upval; + bl = bl->previous; } - else { - if (nret == 1) /* only one single value? */ - first = luaK_exp2anyreg(fs, &e); - else { - luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ - first = fs->nactvar; /* return all `active' values */ - lua_assert(nret == fs->freereg - first); - } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + +static void whilestat(LexState *ls, int line) +{ + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + +static void repeatstat(LexState *ls, int line) +{ + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + chunk(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (!bl2.upval) + { /* no upvalues? */ + leaveblock(fs); /* finish scope */ + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ } - } - luaK_ret(fs, first, nret); -} - - -static int statement (LexState *ls) { - int line = ls->linenumber; /* may be needed for error messages */ - switch (ls->t.token) { - case TK_IF: { /* stat -> ifstat */ - ifstat(ls, line); - return 0; + else + { /* complete semantics when there are upvalues */ + breakstat(ls); /* if condition then break */ + luaK_patchtohere(ls->fs, condexit); /* else... */ + leaveblock(fs); /* finish scope... */ + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ } - case TK_WHILE: { /* stat -> whilestat */ - whilestat(ls, line); - return 0; + leaveblock(fs); /* finish loop */ +} + +static int exp1(LexState *ls) +{ + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + +static void forbody(LexState *ls, int base, int line, int nvars, int isnum) +{ + /* forbody -> DO block */ + BlockCnt *pbl = (BlockCnt *)luaM_malloc(ls->L, sizeof(BlockCnt)); + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, pbl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); + luaM_free(ls->L, pbl); +} + +static void fornum(LexState *ls, TString *varname, int line) +{ + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)", 0); + new_localvarliteral(ls, "(for limit)", 1); + new_localvarliteral(ls, "(for step)", 2); + new_localvar(ls, varname, 3); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else + { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); } - case TK_DO: { /* stat -> DO block END */ - luaX_next(ls); /* skip DO */ - block(ls); - check_match(ls, TK_END, TK_DO, line); - return 0; + forbody(ls, base, line, 1, 1); +} + +static void forlist(LexState *ls, TString *indexname) +{ + /* forlist -> NAME {,NAME} IN explist1 forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)", nvars++); + new_localvarliteral(ls, "(for state)", nvars++); + new_localvarliteral(ls, "(for control)", nvars++); + /* create declared variables */ + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) new_localvar(ls, str_checkname(ls), nvars++); + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + +static void forstat(LexState *ls, int line) +{ + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) + { + case '=': + fornum(ls, varname, line); + break; + case ',': + case TK_IN: + forlist(ls, varname); + break; + default: + luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); } - case TK_FOR: { /* stat -> forstat */ - forstat(ls, line); - return 0; + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + +static int test_then_block(LexState *ls) +{ + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + int condexit; + luaX_next(ls); /* skip IF or ELSEIF */ + condexit = cond(ls); + checknext(ls, TK_THEN); + block(ls); /* `then' part */ + return condexit; +} + +static void ifstat(LexState *ls, int line) +{ + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int flist; + int escapelist = NO_JUMP; + flist = test_then_block(ls); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + flist = test_then_block(ls); /* ELSEIF cond THEN block */ } - case TK_REPEAT: { /* stat -> repeatstat */ - repeatstat(ls, line); - return 0; + if (ls->t.token == TK_ELSE) + { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, flist); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + +static void localfunc(LexState *ls) +{ + expdesc v, b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, fs->freereg); + luaK_reserveregs(fs, 1); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(fs, &v, &b); + /* debug information will only see the variable after this point! */ + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; +} + +static void localstat(LexState *ls) +{ + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do + { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else + { + e.k = VVOID; + nexps = 0; } - case TK_FUNCTION: { - funcstat(ls, line); /* stat -> funcstat */ - return 0; + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + +static int funcname(LexState *ls, expdesc *v) +{ + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v); + while (ls->t.token == '.') field(ls, v); + if (ls->t.token == ':') + { + needself = 1; + field(ls, v); } - case TK_LOCAL: { /* stat -> localstat */ - luaX_next(ls); /* skip LOCAL */ - if (testnext(ls, TK_FUNCTION)) /* local function? */ - localfunc(ls); - else - localstat(ls); - return 0; + return needself; +} + +static void funcstat(LexState *ls, int line) +{ + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + +static void exprstat(LexState *ls) +{ + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) /* stat -> func */ + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + else + { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); } - case TK_RETURN: { /* stat -> retstat */ - retstat(ls); - return 1; /* must be last statement */ +} + +static void retstat(LexState *ls) +{ + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + luaX_next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else + { + nret = explist1(ls, &e); /* optional return values */ + if (hasmultret(e.k)) + { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) + { /* tail call? */ + SET_OPCODE(getcode(fs, &e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs, &e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else + { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else + { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } } - case TK_BREAK: { /* stat -> breakstat */ - luaX_next(ls); /* skip BREAK */ - breakstat(ls); - return 1; /* must be last statement */ + luaK_ret(fs, first, nret); +} + +static int statement(LexState *ls) +{ + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) + { + case TK_IF: + { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: + { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: + { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: + { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: + { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: + { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: + { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: + { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: + { /* stat -> breakstat */ + luaX_next(ls); /* skip BREAK */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: + { + exprstat(ls); + return 0; /* to avoid warnings */ + } } - default: { - exprstat(ls); - return 0; /* to avoid warnings */ +} + +static void chunk(LexState *ls) +{ + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) + { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ } - } -} - - -static void chunk (LexState *ls) { - /* chunk -> { stat [`;'] } */ - int islast = 0; - enterlevel(ls); - while (!islast && !block_follow(ls->t.token)) { - islast = statement(ls); - testnext(ls, ';'); - lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && - ls->fs->freereg >= ls->fs->nactvar); - ls->fs->freereg = ls->fs->nactvar; /* free registers */ - } - leavelevel(ls); + leavelevel(ls); } /* }====================================================================== */ diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lrotable.c b/LuaNode_Esp32/LuaNode32/components/lua/lrotable.c index 250f143..a2afef5 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lrotable.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lrotable.c @@ -3,126 +3,143 @@ #include "lua.h" #include C_HEADER_STRING -#include "lrotable.h" +#include "lapi.h" #include "lauxlib.h" -#include "lstring.h" #include "lobject.h" -#include "lapi.h" +#include "lrotable.h" +#include "lstring.h" /* Local defines */ -#define LUAR_FINDFUNCTION 0 -#define LUAR_FINDVALUE 1 +#define LUAR_FINDFUNCTION 0 +#define LUAR_FINDVALUE 1 /* Externally defined read-only table array */ extern const luaR_table lua_rotable[]; /* Find a global "read only table" in the constant lua_rotable array */ -void* luaR_findglobal(const char *name, unsigned len) { - unsigned i; +void *luaR_findglobal(const char *name, unsigned len) +{ + unsigned i; - if (strlen(name) > LUA_MAX_ROTABLE_NAME) + if (strlen(name) > LUA_MAX_ROTABLE_NAME) + return NULL; + for (i = 0; lua_rotable[i].name; i++) + if (*lua_rotable[i].name != '\0' && strlen(lua_rotable[i].name) == len && + !strncmp(lua_rotable[i].name, name, len)) + { + return (void *)(lua_rotable[i].pentries); + } return NULL; - for (i=0; lua_rotable[i].name; i ++) - if (*lua_rotable[i].name != '\0' && strlen(lua_rotable[i].name) == len && !strncmp(lua_rotable[i].name, name, len)) { - return (void*)(lua_rotable[i].pentries); - } - return NULL; } /* Find an entry in a rotable and return it */ -static const TValue* luaR_auxfind(const luaR_entry *pentry, const char *strkey, luaR_numkey numkey, unsigned *ppos) { - const TValue *res = NULL; - unsigned i = 0; - - if (pentry == NULL) - return NULL; - while(pentry->key.type != LUA_TNIL) { - if ((strkey && (pentry->key.type == LUA_TSTRING) && (!strcmp(pentry->key.id.strkey, strkey))) || - (!strkey && (pentry->key.type == LUA_TNUMBER) && ((luaR_numkey)pentry->key.id.numkey == numkey))) { - res = &pentry->value; - break; +static const TValue *luaR_auxfind(const luaR_entry *pentry, const char *strkey, luaR_numkey numkey, unsigned *ppos) +{ + const TValue *res = NULL; + unsigned i = 0; + + if (pentry == NULL) + return NULL; + while (pentry->key.type != LUA_TNIL) + { + if ((strkey && (pentry->key.type == LUA_TSTRING) && (!strcmp(pentry->key.id.strkey, strkey))) || + (!strkey && (pentry->key.type == LUA_TNUMBER) && ((luaR_numkey)pentry->key.id.numkey == numkey))) + { + res = &pentry->value; + break; + } + i++; + pentry++; } - i ++; pentry ++; - } - if (res && ppos) - *ppos = i; - return res; + if (res && ppos) + *ppos = i; + return res; } -int luaR_findfunction(lua_State *L, const luaR_entry *ptable) { - const TValue *res = NULL; - const char *key = luaL_checkstring(L, 2); - - res = luaR_auxfind(ptable, key, 0, NULL); - if (res && ttislightfunction(res)) { - luaA_pushobject(L, res); - return 1; - } - else - return 0; +int luaR_findfunction(lua_State *L, const luaR_entry *ptable) +{ + const TValue *res = NULL; + const char *key = luaL_checkstring(L, 2); + + res = luaR_auxfind(ptable, key, 0, NULL); + if (res && ttislightfunction(res)) + { + luaA_pushobject(L, res); + return 1; + } + else + return 0; } -/* Find an entry in a rotable and return its type +/* Find an entry in a rotable and return its type If "strkey" is not NULL, the function will look for a string key, otherwise it will look for a number key */ -const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos) { - return luaR_auxfind((const luaR_entry*)data, strkey, numkey, ppos); +const TValue *luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos) +{ + return luaR_auxfind((const luaR_entry *)data, strkey, numkey, ppos); } /* Find the metatable of a given table */ -void* luaR_getmeta(void *data) { +void *luaR_getmeta(void *data) +{ #ifdef LUA_META_ROTABLES - const TValue *res = luaR_auxfind((const luaR_entry*)data, "__metatable", 0, NULL); - return res && ttisrotable(res) ? rvalue(res) : NULL; + const TValue *res = luaR_auxfind((const luaR_entry *)data, "__metatable", 0, NULL); + return res && ttisrotable(res) ? rvalue(res) : NULL; #else - return NULL; + return NULL; #endif } -static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos, TValue *key, TValue *val) { - setnilvalue(key); - setnilvalue(val); - if (pentries[pos].key.type != LUA_TNIL) { - /* Found an entry */ - if (pentries[pos].key.type == LUA_TSTRING) - setsvalue(L, key, luaS_newro(L, pentries[pos].key.id.strkey)) - else - setnvalue(key, (lua_Number)pentries[pos].key.id.numkey) - setobj2s(L, val, &pentries[pos].value); - } +static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos, TValue *key, TValue *val) +{ + setnilvalue(key); + setnilvalue(val); + if (pentries[pos].key.type != LUA_TNIL) + { + /* Found an entry */ + if (pentries[pos].key.type == LUA_TSTRING) + setsvalue(L, key, luaS_newro(L, pentries[pos].key.id.strkey)) else setnvalue( + key, (lua_Number)pentries[pos].key.id.numkey) setobj2s(L, val, &pentries[pos].value); + } } /* next (used for iteration) */ -void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) { - const luaR_entry* pentries = (const luaR_entry*)data; - char strkey[LUA_MAX_ROTABLE_NAME + 1], *pstrkey = NULL; - luaR_numkey numkey = 0; - unsigned keypos; - - /* Special case: if key is nil, return the first element of the rotable */ - if (ttisnil(key)) - luaR_next_helper(L, pentries, 0, key, val); - else if (ttisstring(key) || ttisnumber(key)) { - /* Find the previoud key again */ - if (ttisstring(key)) { - luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME); - pstrkey = strkey; - } else - numkey = (luaR_numkey)nvalue(key); - luaR_findentry(data, pstrkey, numkey, &keypos); - /* Advance to next key */ - keypos ++; - luaR_next_helper(L, pentries, keypos, key, val); - } +void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) +{ + const luaR_entry *pentries = (const luaR_entry *)data; + char strkey[LUA_MAX_ROTABLE_NAME + 1], *pstrkey = NULL; + luaR_numkey numkey = 0; + unsigned keypos; + + /* Special case: if key is nil, return the first element of the rotable */ + if (ttisnil(key)) + luaR_next_helper(L, pentries, 0, key, val); + else if (ttisstring(key) || ttisnumber(key)) + { + /* Find the previoud key again */ + if (ttisstring(key)) + { + luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME); + pstrkey = strkey; + } + else + numkey = (luaR_numkey)nvalue(key); + luaR_findentry(data, pstrkey, numkey, &keypos); + /* Advance to next key */ + keypos++; + luaR_next_helper(L, pentries, keypos, key, val); + } } /* Convert a Lua string to a C string */ -void luaR_getcstr(char *dest, const TString *src, size_t maxsize) { - if (src->tsv.len+1 > maxsize) - dest[0] = '\0'; - else { - memcpy(dest, getstr(src), src->tsv.len); - dest[src->tsv.len] = '\0'; - } +void luaR_getcstr(char *dest, const TString *src, size_t maxsize) +{ + if (src->tsv.len + 1 > maxsize) + dest[0] = '\0'; + else + { + memcpy(dest, getstr(src), src->tsv.len); + dest[src->tsv.len] = '\0'; + } } /* Return 1 if the given pointer is a rotable */ @@ -130,7 +147,5 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) { #include "compiler.h" -int luaR_isrotable(void *p) { - return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS; -} +int luaR_isrotable(void *p) { return RODATA_START_ADDRESS <= (char *)p && (char *)p <= RODATA_END_ADDRESS; } #endif diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lstate.c b/LuaNode_Esp32/LuaNode32/components/lua/lstate.c index b428974..0662ff8 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lstate.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lstate.c @@ -4,12 +4,11 @@ ** See Copyright Notice in lua.h */ - #define lstate_c #define LUA_CORE #define LUAC_CROSS_FILE -#include "lua.h" +#include "lstate.h" #include "ldebug.h" #include "ldo.h" @@ -17,229 +16,230 @@ #include "lgc.h" #include "llex.h" #include "lmem.h" -#include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" +#include "lua.h" -#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) -#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) -#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) - +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) /* ** Main thread combines a thread state and the global state */ -typedef struct LG { - lua_State l; - global_State g; +typedef struct LG +{ + lua_State l; + global_State g; } LG; - - - -static void stack_init (lua_State *L1, lua_State *L) { - /* initialize CallInfo array */ - L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); - L1->ci = L1->base_ci; - L1->size_ci = BASIC_CI_SIZE; - L1->end_ci = L1->base_ci + L1->size_ci - 1; - /* initialize stack array */ - L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); - L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; - L1->top = L1->stack; - L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; - /* initialize first ci */ - L1->ci->func = L1->top; - setnilvalue(L1->top++); /* `function' entry for this `ci' */ - L1->base = L1->ci->base = L1->top; - L1->ci->top = L1->top + LUA_MINSTACK; -} - -static void freestack (lua_State *L, lua_State *L1) { - luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); - luaM_freearray(L, L1->stack, L1->stacksize, TValue); +static void stack_init(lua_State *L1, lua_State *L) +{ + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack + (L1->stacksize - EXTRA_STACK) - 1; + /* initialize first ci */ + L1->ci->func = L1->top; + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; } +static void freestack(lua_State *L, lua_State *L1) +{ + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TValue); +} /* ** open parts that may cause memory-allocation errors */ -static void f_luaopen (lua_State *L, void *ud) { - global_State *g = G(L); - UNUSED(ud); - stack_init(L, L); /* init stack */ - sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ - sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ - luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ - luaT_init(L); - luaX_init(L); - luaS_fix(luaS_newliteral(L, MEMERRMSG)); - g->GCthreshold = 4*g->totalbytes; +static void f_luaopen(lua_State *L, void *ud) +{ + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4 * g->totalbytes; } - -static void preinit_state (lua_State *L, global_State *g) { - G(L) = g; - L->stack = NULL; - L->stacksize = 0; - L->errorJmp = NULL; - L->hook = NULL; - L->hookmask = 0; - L->basehookcount = 0; - L->allowhook = 1; - resethookcount(L); - L->openupval = NULL; - L->size_ci = 0; - L->nCcalls = L->baseCcalls = 0; - L->status = 0; - L->base_ci = L->ci = NULL; - L->savedpc = NULL; - L->errfunc = 0; - setnilvalue(gt(L)); +static void preinit_state(lua_State *L, global_State *g) +{ + G(L) = g; + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->savedpc = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); } - -static void close_state (lua_State *L) { - global_State *g = G(L); - luaF_close(L, L->stack); /* close all upvalues for this thread */ - luaC_freeall(L); /* collect all objects */ - lua_assert(g->rootgc == obj2gco(L)); - lua_assert(g->strt.nuse == 0); - luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); - luaZ_freebuffer(L, &g->buff); - freestack(L, L); - lua_assert(g->totalbytes == sizeof(LG)); - (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); +static void close_state(lua_State *L) +{ + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeall(L); /* collect all objects */ + lua_assert(g->rootgc == obj2gco(L)); + lua_assert(g->strt.nuse == 0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaZ_freebuffer(L, &g->buff); + freestack(L, L); + lua_assert(g->totalbytes == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); } - -lua_State *luaE_newthread (lua_State *L) { - lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); - luaC_link(L, obj2gco(L1), LUA_TTHREAD); - setthvalue(L, L->top, L1); /* put thread on stack */ - incr_top(L); - preinit_state(L1, G(L)); - stack_init(L1, L); /* init stack */ - setobj2n(L, gt(L1), gt(L)); /* share table of globals */ - L1->hookmask = L->hookmask; - L1->basehookcount = L->basehookcount; - L1->hook = L->hook; - resethookcount(L1); - lua_assert(!isdead(G(L), obj2gco(L1))); - L->top--; /* remove thread from stack */ - return L1; +lua_State *luaE_newthread(lua_State *L) +{ + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); + luaC_link(L, obj2gco(L1), LUA_TTHREAD); + setthvalue(L, L->top, L1); /* put thread on stack */ + incr_top(L); + preinit_state(L1, G(L)); + stack_init(L1, L); /* init stack */ + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + lua_assert(!isdead(G(L), obj2gco(L1))); + L->top--; /* remove thread from stack */ + return L1; } - -void luaE_freethread (lua_State *L, lua_State *L1) { - luaF_close(L1, L1->stack); /* close all upvalues for this thread */ - lua_assert(L1->openupval == NULL); - luai_userstatefree(L1); - freestack(L, L1); - luaM_freemem(L, fromstate(L1), state_size(lua_State)); +void luaE_freethread(lua_State *L, lua_State *L1) +{ + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L1); + freestack(L, L1); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); } - -LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { - int i; - lua_State *L; - global_State *g; - void *l = (*f)(ud, NULL, 0, state_size(LG)); - if (l == NULL) return NULL; - L = tostate(l); - g = &((LG *)L)->g; - L->next = NULL; - L->tt = LUA_TTHREAD; - g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); - L->marked = luaC_white(g); - set2bits(L->marked, FIXEDBIT, SFIXEDBIT); - preinit_state(L, g); - g->frealloc = f; - g->ud = ud; - g->mainthread = L; - g->uvhead.u.l.prev = &g->uvhead; - g->uvhead.u.l.next = &g->uvhead; - g->GCthreshold = 0; /* mark it as unfinished state */ - g->estimate = 0; - g->strt.size = 0; - g->strt.nuse = 0; - g->strt.hash = NULL; - setnilvalue(registry(L)); - luaZ_initbuffer(L, &g->buff); - g->panic = NULL; - g->gcstate = GCSpause; - g->gcflags = GCFlagsNone; - g->rootgc = obj2gco(L); - g->sweepstrgc = 0; - g->sweepgc = &g->rootgc; - g->gray = NULL; - g->grayagain = NULL; - g->weak = NULL; - g->tmudata = NULL; - g->totalbytes = sizeof(LG); - g->memlimit = 0; - g->gcpause = LUAI_GCPAUSE; - g->gcstepmul = LUAI_GCMUL; - g->gcdept = 0; +LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) +{ + int i; + lua_State *L; + global_State *g; + void *l = (*f)(ud, NULL, 0, state_size(LG)); + if (l == NULL) + return NULL; + L = tostate(l); + g = &((LG *)L)->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->estimate = 0; + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->gcstate = GCSpause; + g->gcflags = GCFlagsNone; + g->rootgc = obj2gco(L); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->tmudata = NULL; + g->totalbytes = sizeof(LG); + g->memlimit = 0; + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + g->gcdept = 0; #ifdef EGC_INITIAL_MODE - g->egcmode = EGC_INITIAL_MODE; + g->egcmode = EGC_INITIAL_MODE; #else - g->egcmode = 0; + g->egcmode = 0; #endif #ifdef EGC_INITIAL_MEMLIMIT - g->memlimit = EGC_INITIAL_MEMLIMIT; + g->memlimit = EGC_INITIAL_MEMLIMIT; #else - g->memlimit = 0; + g->memlimit = 0; #endif - for (i=0; imt[i] = NULL; - if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { - /* memory allocation error: free partial state */ - close_state(L); - L = NULL; - } - else - luai_userstateopen(L); - return L; + for (i = 0; i < NUM_TAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) + { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + else + luai_userstateopen(L); + return L; } - -static void callallgcTM (lua_State *L, void *ud) { - UNUSED(ud); - luaC_callGCTM(L); /* call GC metamethods for all udata */ +static void callallgcTM(lua_State *L, void *ud) +{ + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ } // BogdanM: modified for eLua interrupt support -extern lua_State *luaL_newstate (void); +extern lua_State *luaL_newstate(void); static lua_State *lua_crtstate; -lua_State *lua_open(void) { - lua_crtstate = luaL_newstate(); - return lua_crtstate; +lua_State *lua_open(void) +{ + lua_crtstate = luaL_newstate(); + return lua_crtstate; } -lua_State *lua_getstate(void) { - return lua_crtstate; -} -LUA_API void lua_close (lua_State *L) { -#ifndef LUA_CROSS_COMPILER - lua_sethook( L, NULL, 0, 0 ); - lua_crtstate = NULL; - lua_pushnil( L ); +lua_State *lua_getstate(void) { return lua_crtstate; } +LUA_API void lua_close(lua_State *L) +{ +#ifndef LUA_CROSS_COMPILER + lua_sethook(L, NULL, 0, 0); + lua_crtstate = NULL; + lua_pushnil(L); // lua_rawseti( L, LUA_REGISTRYINDEX, LUA_INT_HANDLER_KEY ); -#endif - L = G(L)->mainthread; /* only the main thread can be closed */ - lua_lock(L); - luaF_close(L, L->stack); /* close all upvalues for this thread */ - luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ - L->errfunc = 0; /* no error function during GC metamethods */ - do { /* repeat until no more errors */ - L->ci = L->base_ci; - L->base = L->top = L->ci->base; - L->nCcalls = L->baseCcalls = 0; - } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); - lua_assert(G(L)->tmudata == NULL); - luai_userstateclose(L); - close_state(L); +#endif + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do + { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + luai_userstateclose(L); + close_state(L); } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lstring.c b/LuaNode_Esp32/LuaNode32/components/lua/lstring.c index b7877eb..3eeea52 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lstring.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lstring.c @@ -4,8 +4,6 @@ ** See Copyright Notice in lua.h */ - - #define lstring_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -18,131 +16,142 @@ #include "lstate.h" #include "lstring.h" -#define LUAS_READONLY_STRING 1 -#define LUAS_REGULAR_STRING 0 - -void luaS_resize (lua_State *L, int newsize) { - stringtable *tb; - int i; - tb = &G(L)->strt; - if (luaC_sweepstrgc(L) || newsize == tb->size || is_resizing_strings_gc(L)) - return; /* cannot resize during GC traverse or doesn't need to be resized */ - set_resizing_strings_gc(L); - if (newsize > tb->size) { - luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); - for (i=tb->size; ihash[i] = NULL; - } - /* rehash */ - for (i=0; isize; i++) { - GCObject *p = tb->hash[i]; - tb->hash[i] = NULL; - while (p) { /* for each node in the list */ - GCObject *next = p->gch.next; /* save next */ - unsigned int h = gco2ts(p)->hash; - int h1 = lmod(h, newsize); /* new position */ - lua_assert(cast_int(h%newsize) == lmod(h, newsize)); - p->gch.next = tb->hash[h1]; /* chain it */ - tb->hash[h1] = p; - p = next; +#define LUAS_READONLY_STRING 1 +#define LUAS_REGULAR_STRING 0 + +void luaS_resize(lua_State *L, int newsize) +{ + stringtable *tb; + int i; + tb = &G(L)->strt; + if (luaC_sweepstrgc(L) || newsize == tb->size || is_resizing_strings_gc(L)) + return; /* cannot resize during GC traverse or doesn't need to be + resized */ + set_resizing_strings_gc(L); + if (newsize > tb->size) + { + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; } - } - if (newsize < tb->size) - luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); - tb->size = newsize; - unset_resizing_strings_gc(L); + /* rehash */ + for (i = 0; i < tb->size; i++) + { + GCObject *p = tb->hash[i]; + tb->hash[i] = NULL; + while (p) + { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + unsigned int h = gco2ts(p)->hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast_int(h % newsize) == lmod(h, newsize)); + p->gch.next = tb->hash[h1]; /* chain it */ + tb->hash[h1] = p; + p = next; + } + } + if (newsize < tb->size) + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + tb->size = newsize; + unset_resizing_strings_gc(L); } -static TString *newlstr (lua_State *L, const char *str, size_t l, - unsigned int h, int readonly) { - TString *ts; - stringtable *tb; - if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) - luaM_toobig(L); - tb = &G(L)->strt; - if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) - luaS_resize(L, tb->size*2); /* too crowded */ - ts = cast(TString *, luaM_malloc(L, readonly ? sizeof(char**)+sizeof(TString) : (l+1)*sizeof(char)+sizeof(TString))); - ts->tsv.len = l; - ts->tsv.hash = h; - ts->tsv.marked = luaC_white(G(L)); - ts->tsv.tt = LUA_TSTRING; - if (!readonly) { - memcpy(ts+1, str, l*sizeof(char)); - ((char *)(ts+1))[l] = '\0'; /* ending 0 */ - } else { - *(char **)(ts+1) = (char *)str; - luaS_readonly(ts); - } - h = lmod(h, tb->size); - ts->tsv.next = tb->hash[h]; /* chain new entry */ - tb->hash[h] = obj2gco(ts); - tb->nuse++; - return ts; +static TString *newlstr(lua_State *L, const char *str, size_t l, unsigned int h, int readonly) +{ + TString *ts; + stringtable *tb; + if (l + 1 > (MAX_SIZET - sizeof(TString)) / sizeof(char)) + luaM_toobig(L); + tb = &G(L)->strt; + if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT / 2) + luaS_resize(L, tb->size * 2); /* too crowded */ + ts = cast(TString *, + luaM_malloc(L, readonly ? sizeof(char **) + sizeof(TString) : (l + 1) * sizeof(char) + sizeof(TString))); + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.marked = luaC_white(G(L)); + ts->tsv.tt = LUA_TSTRING; + if (!readonly) + { + memcpy(ts + 1, str, l * sizeof(char)); + ((char *)(ts + 1))[l] = '\0'; /* ending 0 */ + } + else + { + *(char **)(ts + 1) = (char *)str; + luaS_readonly(ts); + } + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = obj2gco(ts); + tb->nuse++; + return ts; } - -static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, int readonly) { - GCObject *o; - unsigned int h = cast(unsigned int, l); /* seed */ - size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ - size_t l1; - for (l1=l; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); - for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; - o != NULL; - o = o->gch.next) { - TString *ts = rawgco2ts(o); - if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { - /* string may be dead */ - if (isdead(G(L), o)) changewhite(o); - return ts; +static TString *luaS_newlstr_helper(lua_State *L, const char *str, size_t l, int readonly) +{ + GCObject *o; + unsigned int h = cast(unsigned int, l); /* seed */ + size_t step = (l >> 5) + 1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1 = l; l1 >= step; l1 -= step) /* compute hash */ + h = h ^ ((h << 5) + (h >> 2) + cast(unsigned char, str[l1 - 1])); + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next) + { + TString *ts = rawgco2ts(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) + { + /* string may be dead */ + if (isdead(G(L), o)) + changewhite(o); + return ts; + } } - } - return newlstr(L, str, l, h, readonly); /* not found */ + return newlstr(L, str, l, h, readonly); /* not found */ } -static int lua_is_ptr_in_ro_area(const char *p) { +static int lua_is_ptr_in_ro_area(const char *p) +{ #ifdef LUA_CROSS_COMPILER - return 0; + return 0; #else #include "compiler.h" - return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS; + return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS; #endif } -TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { - // If the pointer is in a read-only memory and the string is at least 4 chars in length, - // create it as a read-only string instead - if(lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) && l == strlen(str)) - return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING); - else - return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING); +TString *luaS_newlstr(lua_State *L, const char *str, size_t l) +{ + // If the pointer is in a read-only memory and the string is at least 4 + // chars in length, create it as a read-only string instead + if (lua_is_ptr_in_ro_area(str) && l + 1 > sizeof(char **) && l == strlen(str)) + return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING); + else + return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING); } - -LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l) { - if(l+1 > sizeof(char**) && l == strlen(str)) - return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING); - else // no point in creating a RO string, as it would actually be larger - return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING); +LUAI_FUNC TString *luaS_newrolstr(lua_State *L, const char *str, size_t l) +{ + if (l + 1 > sizeof(char **) && l == strlen(str)) + return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING); + else // no point in creating a RO string, as it would actually be larger + return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING); } - -Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { - Udata *u; - if (s > MAX_SIZET - sizeof(Udata)) - luaM_toobig(L); - u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); - u->uv.marked = luaC_white(G(L)); /* is not finalized */ - u->uv.tt = LUA_TUSERDATA; - u->uv.len = s; - u->uv.metatable = NULL; - u->uv.env = e; - /* chain it on udata list (after main thread) */ - u->uv.next = G(L)->mainthread->next; - G(L)->mainthread->next = obj2gco(u); - return u; +Udata *luaS_newudata(lua_State *L, size_t s, Table *e) +{ + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); + u->uv.marked = luaC_white(G(L)); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + /* chain it on udata list (after main thread) */ + u->uv.next = G(L)->mainthread->next; + G(L)->mainthread->next = obj2gco(u); + return u; } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lstrlib.c b/LuaNode_Esp32/LuaNode32/components/lua/lstrlib.c index 340a86f..0620640 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lstrlib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lstrlib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define lstrlib_c #define LUA_LIB #define LUAC_CROSS_FILE @@ -14,878 +13,999 @@ #include C_HEADER_STRING #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lualib.h" /* macro to `unsign' a character */ -#define uchar(c) ((unsigned char)(c)) - - - -static int str_len (lua_State *L) { - size_t l; - luaL_checklstring(L, 1, &l); - lua_pushinteger(L, l); - return 1; -} - - -static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { - /* relative string position: negative means back from end */ - if (pos < 0) pos += (ptrdiff_t)len + 1; - return (pos >= 0) ? pos : 0; -} - - -static int str_sub (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); - ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); - if (start < 1) start = 1; - if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; - if (start <= end) - lua_pushlstring(L, s+start-1, end-start+1); - else lua_pushliteral(L, ""); - return 1; -} - - -static int str_reverse (lua_State *L) { - size_t l; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - luaL_buffinit(L, &b); - while (l--) luaL_addchar(&b, s[l]); - luaL_pushresult(&b); - return 1; -} - - -static int str_lower (lua_State *L) { - size_t l; - size_t i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - luaL_buffinit(L, &b); - for (i=0; i 0) - luaL_addlstring(&b, s, l); - luaL_pushresult(&b); - return 1; -} - - -static int str_byte (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); - ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); - int n, i; - if (posi <= 0) posi = 1; - if ((size_t)pose > l) pose = l; - if (posi > pose) return 0; /* empty interval; return no values */ - n = (int)(pose - posi + 1); - if (posi + n <= pose) /* overflow? */ - luaL_error(L, "string slice too long"); - luaL_checkstack(L, n, "string slice too long"); - for (i=0; i= 0) ? pos : 0; +} + +static int str_sub(lua_State *L) +{ + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) + start = 1; + if (end > (ptrdiff_t)l) + end = (ptrdiff_t)l; + if (start <= end) + lua_pushlstring(L, s + start - 1, end - start + 1); + else + lua_pushliteral(L, ""); + return 1; +} + +static int str_reverse(lua_State *L) +{ + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_addchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + +static int str_lower(lua_State *L) +{ + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i = 0; i < l; i++) luaL_addchar(&b, tolower(uchar(s[i]))); + luaL_pushresult(&b); + return 1; +} + +static int str_upper(lua_State *L) +{ + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i = 0; i < l; i++) luaL_addchar(&b, toupper(uchar(s[i]))); + luaL_pushresult(&b); + return 1; +} + +static int str_rep(lua_State *L) +{ + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + int n = luaL_checkint(L, 2); + luaL_buffinit(L, &b); + while (n-- > 0) luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + +static int str_byte(lua_State *L) +{ + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) + posi = 1; + if ((size_t)pose > l) + pose = l; + if (posi > pose) + return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* overflow? */ + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i = 0; i < n; i++) lua_pushinteger(L, uchar(s[posi + i - 1])); + return n; +} + +static int str_char(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_Buffer b; + luaL_buffinit(L, &b); + for (i = 1; i <= n; i++) + { + int c = luaL_checkint(L, i); + luaL_argcheck(L, uchar(c) == c, i, "invalid value"); + luaL_addchar(&b, uchar(c)); + } + luaL_pushresult(&b); + return 1; } - -static int str_char (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - luaL_Buffer b; - luaL_buffinit(L, &b); - for (i=1; i<=n; i++) { - int c = luaL_checkint(L, i); - luaL_argcheck(L, uchar(c) == c, i, "invalid value"); - luaL_addchar(&b, uchar(c)); - } - luaL_pushresult(&b); - return 1; +static int writer(lua_State *L, const void *b, size_t size, void *B) +{ + (void)L; + luaL_addlstring((luaL_Buffer *)B, (const char *)b, size); + return 0; } - -static int writer (lua_State *L, const void* b, size_t size, void* B) { - (void)L; - luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); - return 0; -} - - -static int str_dump (lua_State *L) { - luaL_Buffer b; - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, 1); - luaL_buffinit(L,&b); - if (lua_dump(L, writer, &b) != 0) - luaL_error(L, "unable to dump given function"); - luaL_pushresult(&b); - return 1; +static int str_dump(lua_State *L) +{ + luaL_Buffer b; + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 1); + luaL_buffinit(L, &b); + if (lua_dump(L, writer, &b) != 0) + luaL_error(L, "unable to dump given function"); + luaL_pushresult(&b); + return 1; } - - /* ** {====================================================== ** PATTERN MATCHING ** ======================================================= */ - -#define CAP_UNFINISHED (-1) -#define CAP_POSITION (-2) - -typedef struct MatchState { - const char *src_init; /* init of source string */ - const char *src_end; /* end (`\0') of source string */ - lua_State *L; - int level; /* total number of captures (finished or unfinished) */ - struct { - const char *init; - ptrdiff_t len; - } capture[LUA_MAXCAPTURES]; +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) + +typedef struct MatchState +{ + const char *src_init; /* init of source string */ + const char *src_end; /* end (`\0') of source string */ + lua_State *L; + int level; /* total number of captures (finished or unfinished) */ + struct + { + const char *init; + ptrdiff_t len; + } capture[LUA_MAXCAPTURES]; } MatchState; - -#define L_ESC '%' -#define SPECIALS "^$*+?.([%-" - - -static int check_capture (MatchState *ms, int l) { - l -= '1'; - if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) - return luaL_error(ms->L, "invalid capture index"); - return l; +#define L_ESC '%' +#define SPECIALS "^$*+?.([%-" + +static int check_capture(MatchState *ms, int l) +{ + l -= '1'; + if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + +static int capture_to_close(MatchState *ms) +{ + int level = ms->level; + for (level--; level >= 0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) + return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + +static const char *classend(MatchState *ms, const char *p) +{ + switch (*p++) + { + case L_ESC: + { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p + 1; + } + case '[': + { + if (*p == '^') + p++; + do + { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p + 1; + } + default: + { + return p; + } + } } - -static int capture_to_close (MatchState *ms) { - int level = ms->level; - for (level--; level>=0; level--) - if (ms->capture[level].len == CAP_UNFINISHED) return level; - return luaL_error(ms->L, "invalid pattern capture"); +static int match_class(int c, int cl) +{ + int res; + switch (tolower(cl)) + { + case 'a': + res = isalpha(c); + break; + case 'c': + res = iscntrl(c); + break; + case 'd': + res = isdigit(c); + break; + case 'l': + res = islower(c); + break; + case 'p': + res = ispunct(c); + break; + case 's': + res = isspace(c); + break; + case 'u': + res = isupper(c); + break; + case 'w': + res = isalnum(c); + break; + case 'x': + res = isxdigit(c); + break; + case 'z': + res = (c == 0); + break; + default: + return (cl == c); + } + return (islower(cl) ? res : !res); } - -static const char *classend (MatchState *ms, const char *p) { - switch (*p++) { - case L_ESC: { - if (*p == '\0') - luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); - return p+1; - } - case '[': { - if (*p == '^') p++; - do { /* look for a `]' */ - if (*p == '\0') - luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); - if (*(p++) == L_ESC && *p != '\0') - p++; /* skip escapes (e.g. `%]') */ - } while (*p != ']'); - return p+1; +static int matchbracketclass(int c, const char *p, const char *ec) +{ + int sig = 1; + if (*(p + 1) == '^') + { + sig = 0; + p++; /* skip the `^' */ } - default: { - return p; - } - } -} - - -static int match_class (int c, int cl) { - int res; - switch (tolower(cl)) { - case 'a' : res = isalpha(c); break; - case 'c' : res = iscntrl(c); break; - case 'd' : res = isdigit(c); break; - case 'l' : res = islower(c); break; - case 'p' : res = ispunct(c); break; - case 's' : res = isspace(c); break; - case 'u' : res = isupper(c); break; - case 'w' : res = isalnum(c); break; - case 'x' : res = isxdigit(c); break; - case 'z' : res = (c == 0); break; - default: return (cl == c); - } - return (islower(cl) ? res : !res); -} - - -static int matchbracketclass (int c, const char *p, const char *ec) { - int sig = 1; - if (*(p+1) == '^') { - sig = 0; - p++; /* skip the `^' */ - } - while (++p < ec) { - if (*p == L_ESC) { - p++; - if (match_class(c, uchar(*p))) - return sig; + while (++p < ec) + { + if (*p == L_ESC) + { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p + 1) == '-') && (p + 2 < ec)) + { + p += 2; + if (uchar(*(p - 2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) + return sig; } - else if ((*(p+1) == '-') && (p+2 < ec)) { - p+=2; - if (uchar(*(p-2)) <= c && c <= uchar(*p)) - return sig; + return !sig; +} + +static int singlematch(int c, const char *p, const char *ep) +{ + switch (*p) + { + case '.': + return 1; /* matches any char */ + case L_ESC: + return match_class(c, uchar(*(p + 1))); + case '[': + return matchbracketclass(c, p, ep - 1); + default: + return (uchar(*p) == c); } - else if (uchar(*p) == c) return sig; - } - return !sig; -} - - -static int singlematch (int c, const char *p, const char *ep) { - switch (*p) { - case '.': return 1; /* matches any char */ - case L_ESC: return match_class(c, uchar(*(p+1))); - case '[': return matchbracketclass(c, p, ep-1); - default: return (uchar(*p) == c); - } } +static const char *match(MatchState *ms, const char *s, const char *p); -static const char *match (MatchState *ms, const char *s, const char *p); - - -static const char *matchbalance (MatchState *ms, const char *s, - const char *p) { - if (*p == 0 || *(p+1) == 0) - luaL_error(ms->L, "unbalanced pattern"); - if (*s != *p) return NULL; - else { - int b = *p; - int e = *(p+1); - int cont = 1; - while (++s < ms->src_end) { - if (*s == e) { - if (--cont == 0) return s+1; - } - else if (*s == b) cont++; - } - } - return NULL; /* string ends out of balance */ -} - - -static const char *max_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - ptrdiff_t i = 0; /* counts maximum expand for item */ - while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) - i++; - /* keeps trying to match with the maximum repetitions */ - while (i>=0) { - const char *res = match(ms, (s+i), ep+1); - if (res) return res; - i--; /* else didn't match; reduce 1 repetition to try again */ - } - return NULL; -} - - -static const char *min_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - for (;;) { - const char *res = match(ms, s, ep+1); - if (res != NULL) - return res; - else if (ssrc_end && singlematch(uchar(*s), p, ep)) - s++; /* try with one more repetition */ - else return NULL; - } -} - - -static const char *start_capture (MatchState *ms, const char *s, - const char *p, int what) { - const char *res; - int level = ms->level; - if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); - ms->capture[level].init = s; - ms->capture[level].len = what; - ms->level = level+1; - if ((res=match(ms, s, p)) == NULL) /* match failed? */ - ms->level--; /* undo capture */ - return res; -} - - -static const char *end_capture (MatchState *ms, const char *s, - const char *p) { - int l = capture_to_close(ms); - const char *res; - ms->capture[l].len = s - ms->capture[l].init; /* close capture */ - if ((res = match(ms, s, p)) == NULL) /* match failed? */ - ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ - return res; -} - - -static const char *match_capture (MatchState *ms, const char *s, int l) { - size_t len; - l = check_capture(ms, l); - len = ms->capture[l].len; - if ((size_t)(ms->src_end-s) >= len && - memcmp(ms->capture[l].init, s, len) == 0) - return s+len; - else return NULL; -} - - -static const char *match (MatchState *ms, const char *s, const char *p) { - init: /* using goto's to optimize tail recursion */ - switch (*p) { - case '(': { /* start capture */ - if (*(p+1) == ')') /* position capture? */ - return start_capture(ms, s, p+2, CAP_POSITION); - else - return start_capture(ms, s, p+1, CAP_UNFINISHED); - } - case ')': { /* end capture */ - return end_capture(ms, s, p+1); - } - case L_ESC: { - switch (*(p+1)) { - case 'b': { /* balanced string? */ - s = matchbalance(ms, s, p+2); - if (s == NULL) return NULL; - p+=4; goto init; /* else return match(ms, s, p+4); */ - } - case 'f': { /* frontier? */ - const char *ep; char previous; - p += 2; - if (*p != '[') - luaL_error(ms->L, "missing " LUA_QL("[") " after " - LUA_QL("%%f") " in pattern"); - ep = classend(ms, p); /* points to what is next */ - previous = (s == ms->src_init) ? '\0' : *(s-1); - if (matchbracketclass(uchar(previous), p, ep-1) || - !matchbracketclass(uchar(*s), p, ep-1)) return NULL; - p=ep; goto init; /* else return match(ms, s, ep); */ - } - default: { - if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ - s = match_capture(ms, s, uchar(*(p+1))); - if (s == NULL) return NULL; - p+=2; goto init; /* else return match(ms, s, p+2) */ - } - goto dflt; /* case default */ +static const char *matchbalance(MatchState *ms, const char *s, const char *p) +{ + if (*p == 0 || *(p + 1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) + return NULL; + else + { + int b = *p; + int e = *(p + 1); + int cont = 1; + while (++s < ms->src_end) + { + if (*s == e) + { + if (--cont == 0) + return s + 1; + } + else if (*s == b) + cont++; } - } } - case '\0': { /* end of pattern */ - return s; /* match succeeded */ - } - case '$': { - if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ - return (s == ms->src_end) ? s : NULL; /* check end of string */ - else goto dflt; + return NULL; /* string ends out of balance */ +} + +static const char *max_expand(MatchState *ms, const char *s, const char *p, const char *ep) +{ + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s + i) < ms->src_end && singlematch(uchar(*(s + i)), p, ep)) i++; + /* keeps trying to match with the maximum repetitions */ + while (i >= 0) + { + const char *res = match(ms, (s + i), ep + 1); + if (res) + return res; + i--; /* else didn't match; reduce 1 repetition to try again */ } - default: dflt: { /* it is a pattern item */ - const char *ep = classend(ms, p); /* points to what is next */ - int m = ssrc_end && singlematch(uchar(*s), p, ep); - switch (*ep) { - case '?': { /* optional */ - const char *res; - if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return NULL; +} + +static const char *min_expand(MatchState *ms, const char *s, const char *p, const char *ep) +{ + for (;;) + { + const char *res = match(ms, s, ep + 1); + if (res != NULL) return res; - p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + else if (s < ms->src_end && singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else + return NULL; + } +} + +static const char *start_capture(MatchState *ms, const char *s, const char *p, int what) +{ + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) + luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level + 1; + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + +static const char *end_capture(MatchState *ms, const char *s, const char *p) +{ + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + +static const char *match_capture(MatchState *ms, const char *s, int l) +{ + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end - s) >= len && memcmp(ms->capture[l].init, s, len) == 0) + return s + len; + else + return NULL; +} + +static const char *match(MatchState *ms, const char *s, const char *p) +{ +init: /* using goto's to optimize tail recursion */ + switch (*p) + { + case '(': + { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + return start_capture(ms, s, p + 2, CAP_POSITION); + else + return start_capture(ms, s, p + 1, CAP_UNFINISHED); } - case '*': { /* 0 or more repetitions */ - return max_expand(ms, s, p, ep); + case ')': + { /* end capture */ + return end_capture(ms, s, p + 1); } - case '+': { /* 1 or more repetitions */ - return (m ? max_expand(ms, s+1, p, ep) : NULL); + case L_ESC: + { + switch (*(p + 1)) + { + case 'b': + { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s == NULL) + return NULL; + p += 4; + goto init; /* else return match(ms, s, p+4); */ + } + case 'f': + { /* frontier? */ + const char *ep; + char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (matchbracketclass(uchar(previous), p, ep - 1) || !matchbracketclass(uchar(*s), p, ep - 1)) + return NULL; + p = ep; + goto init; /* else return match(ms, s, ep); */ + } + default: + { + if (isdigit(uchar(*(p + 1)))) + { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s == NULL) + return NULL; + p += 2; + goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } } - case '-': { /* 0 or more repetitions (minimum) */ - return min_expand(ms, s, p, ep); + case '\0': + { /* end of pattern */ + return s; /* match succeeded */ } - default: { - if (!m) return NULL; - s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + case '$': + { + if (*(p + 1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else + goto dflt; + } + default: + dflt: + { /* it is a pattern item */ + const char *ep = classend(ms, p); /* points to what is next */ + int m = s < ms->src_end && singlematch(uchar(*s), p, ep); + switch (*ep) + { + case '?': + { /* optional */ + const char *res; + if (m && ((res = match(ms, s + 1, ep + 1)) != NULL)) + return res; + p = ep + 1; + goto init; /* else return match(ms, s, ep+1); */ + } + case '*': + { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': + { /* 1 or more repetitions */ + return (m ? max_expand(ms, s + 1, p, ep) : NULL); + } + case '-': + { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: + { + if (!m) + return NULL; + s++; + p = ep; + goto init; /* else return match(ms, s+1, ep); */ + } + } } - } - } - } -} - - - -static const char *lmemfind (const char *s1, size_t l1, - const char *s2, size_t l2) { - if (l2 == 0) return s1; /* empty strings are everywhere */ - else if (l2 > l1) return NULL; /* avoids a negative `l1' */ - else { - const char *init; /* to search for a `*s2' inside `s1' */ - l2--; /* 1st char will be checked by `memchr' */ - l1 = l1-l2; /* `s2' cannot be found after that */ - while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { - init++; /* 1st char is already checked */ - if (memcmp(init, s2+1, l2) == 0) - return init-1; - else { /* correct `l1' and `s1' to try again */ - l1 -= init-s1; - s1 = init; - } } - return NULL; /* not found */ - } } - -static void push_onecapture (MatchState *ms, int i, const char *s, - const char *e) { - if (i >= ms->level) { - if (i == 0) /* ms->level == 0, too */ - lua_pushlstring(ms->L, s, e - s); /* add whole match */ - else - luaL_error(ms->L, "invalid capture index"); - } - else { - ptrdiff_t l = ms->capture[i].len; - if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); - if (l == CAP_POSITION) - lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); +static const char *lmemfind(const char *s1, size_t l1, const char *s2, size_t l2) +{ + if (l2 == 0) + return s1; /* empty strings are everywhere */ + else if (l2 > l1) + return NULL; /* avoids a negative `l1' */ else - lua_pushlstring(ms->L, ms->capture[i].init, l); - } -} - - -static int push_captures (MatchState *ms, const char *s, const char *e) { - int i; - int nlevels = (ms->level == 0 && s) ? 1 : ms->level; - luaL_checkstack(ms->L, nlevels, "too many captures"); - for (i = 0; i < nlevels; i++) - push_onecapture(ms, i, s, e); - return nlevels; /* number of strings pushed */ -} - - -static int str_find_aux (lua_State *L, int find) { - size_t l1, l2; - const char *s = luaL_checklstring(L, 1, &l1); - const char *p = luaL_checklstring(L, 2, &l2); - ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; - if (init < 0) init = 0; - else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; - if (find && (lua_toboolean(L, 4) || /* explicit request? */ - strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ - /* do a plain search */ - const char *s2 = lmemfind(s+init, l1-init, p, l2); - if (s2) { - lua_pushinteger(L, s2-s+1); - lua_pushinteger(L, s2-s+l2); - return 2; - } - } - else { - MatchState ms; - int anchor = (*p == '^') ? (p++, 1) : 0; - const char *s1=s+init; - ms.L = L; - ms.src_init = s; - ms.src_end = s+l1; - do { - const char *res; - ms.level = 0; - if ((res=match(&ms, s1, p)) != NULL) { - if (find) { - lua_pushinteger(L, s1-s+1); /* start */ - lua_pushinteger(L, res-s); /* end */ - return push_captures(&ms, NULL, 0) + 2; + { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1 - l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) + { + init++; /* 1st char is already checked */ + if (memcmp(init, s2 + 1, l2) == 0) + return init - 1; + else + { /* correct `l1' and `s1' to try again */ + l1 -= init - s1; + s1 = init; + } } - else - return push_captures(&ms, s1, res); - } - } while (s1++ < ms.src_end && !anchor); - } - lua_pushnil(L); /* not found */ - return 1; + return NULL; /* not found */ + } } - -static int str_find (lua_State *L) { - return str_find_aux(L, 1); +static void push_onecapture(MatchState *ms, int i, const char *s, const char *e) +{ + if (i >= ms->level) + { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else + { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) + luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } } - -static int str_match (lua_State *L) { - return str_find_aux(L, 0); +static int push_captures(MatchState *ms, const char *s, const char *e) +{ + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + +static int str_find_aux(lua_State *L, int find) +{ + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + if (init < 0) + init = 0; + else if ((size_t)(init) > l1) + init = (ptrdiff_t)l1; + if (find && (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL)) + { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s + init, l1 - init, p, l2); + if (s2) + { + lua_pushinteger(L, s2 - s + 1); + lua_pushinteger(L, s2 - s + l2); + return 2; + } + } + else + { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1 = s + init; + ms.L = L; + ms.src_init = s; + ms.src_end = s + l1; + do + { + const char *res; + ms.level = 0; + if ((res = match(&ms, s1, p)) != NULL) + { + if (find) + { + lua_pushinteger(L, s1 - s + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; } +static int str_find(lua_State *L) { return str_find_aux(L, 1); } -static int gmatch_aux (lua_State *L) { - MatchState ms; - size_t ls; - const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); - const char *p = lua_tostring(L, lua_upvalueindex(2)); - const char *src; - ms.L = L; - ms.src_init = s; - ms.src_end = s+ls; - for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); - src <= ms.src_end; - src++) { - const char *e; - ms.level = 0; - if ((e = match(&ms, src, p)) != NULL) { - lua_Integer newstart = e-s; - if (e == src) newstart++; /* empty match? go at least one position */ - lua_pushinteger(L, newstart); - lua_replace(L, lua_upvalueindex(3)); - return push_captures(&ms, src, e); +static int str_match(lua_State *L) { return str_find_aux(L, 0); } + +static int gmatch_aux(lua_State *L) +{ + MatchState ms; + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *src; + ms.L = L; + ms.src_init = s; + ms.src_end = s + ls; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); src <= ms.src_end; src++) + { + const char *e; + ms.level = 0; + if ((e = match(&ms, src, p)) != NULL) + { + lua_Integer newstart = e - s; + if (e == src) + newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } } - } - return 0; /* not found */ + return 0; /* not found */ } - -static int gmatch (lua_State *L) { - luaL_checkstring(L, 1); - luaL_checkstring(L, 2); - lua_settop(L, 2); - lua_pushinteger(L, 0); - lua_pushcclosure(L, gmatch_aux, 3); - return 1; +static int gmatch(lua_State *L) +{ + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; } #if LUA_OPTIMIZE_MEMORY == 0 || !defined(LUA_COMPAT_GFIND) -static int gfind_nodef (lua_State *L) { - return luaL_error(L, LUA_QL("string.gfind") " was renamed to " - LUA_QL("string.gmatch")); +static int gfind_nodef(lua_State *L) +{ + return luaL_error(L, LUA_QL("string.gfind") " was renamed to " LUA_QL("string.gmatch")); } #endif -static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { - size_t l, i; - const char *news = lua_tolstring(ms->L, 3, &l); - for (i = 0; i < l; i++) { - if (news[i] != L_ESC) - luaL_addchar(b, news[i]); - else { - i++; /* skip ESC */ - if (!isdigit(uchar(news[i]))) - luaL_addchar(b, news[i]); - else if (news[i] == '0') - luaL_addlstring(b, s, e - s); - else { - push_onecapture(ms, news[i] - '1', s, e); - luaL_addvalue(b); /* add capture to accumulated result */ - } +static void add_s(MatchState *ms, luaL_Buffer *b, const char *s, const char *e) +{ + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) + { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else + { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + luaL_addchar(b, news[i]); + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else + { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } } - } } - -static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { - lua_State *L = ms->L; - switch (lua_type(L, 3)) { - case LUA_TNUMBER: - case LUA_TSTRING: { - add_s(ms, b, s, e); - return; - } - case LUA_TFUNCTION: - case LUA_TLIGHTFUNCTION: { - int n; - lua_pushvalue(L, 3); - n = push_captures(ms, s, e); - lua_call(L, n, 1); - break; +static void add_value(MatchState *ms, luaL_Buffer *b, const char *s, const char *e) +{ + lua_State *L = ms->L; + switch (lua_type(L, 3)) + { + case LUA_TNUMBER: + case LUA_TSTRING: + { + add_s(ms, b, s, e); + return; + } + case LUA_TFUNCTION: + case LUA_TLIGHTFUNCTION: + { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: + { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } } - case LUA_TTABLE: { - push_onecapture(ms, 0, s, e); - lua_gettable(L, 3); - break; + if (!lua_toboolean(L, -1)) + { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ } - } - if (!lua_toboolean(L, -1)) { /* nil or false? */ - lua_pop(L, 1); - lua_pushlstring(L, s, e - s); /* keep original text */ - } - else if (!lua_isstring(L, -1)) - luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); - luaL_addvalue(b); /* add result to accumulator */ -} - - -static int str_gsub (lua_State *L) { - size_t srcl; - const char *src = luaL_checklstring(L, 1, &srcl); - const char *p = luaL_checkstring(L, 2); - int tr = lua_type(L, 3); - int max_s = luaL_optint(L, 4, srcl+1); - int anchor = (*p == '^') ? (p++, 1) : 0; - int n = 0; - MatchState ms; - luaL_Buffer b; - luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || - tr == LUA_TFUNCTION || tr == LUA_TTABLE || - tr == LUA_TLIGHTFUNCTION, 3, - "string/function/table/lightfunction expected"); - luaL_buffinit(L, &b); - ms.L = L; - ms.src_init = src; - ms.src_end = src+srcl; - while (n < max_s) { - const char *e; - ms.level = 0; - e = match(&ms, src, p); - if (e) { - n++; - add_value(&ms, &b, src, e); + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + +static int str_gsub(lua_State *L) +{ + size_t srcl; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl + 1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck( + L, + tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE || tr == LUA_TLIGHTFUNCTION, + 3, "string/function/table/lightfunction expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src + srcl; + while (n < max_s) + { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) + { + n++; + add_value(&ms, &b, src, e); + } + if (e && e > src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else + break; + if (anchor) + break; } - if (e && e>src) /* non empty match? */ - src = e; /* skip it */ - else if (src < ms.src_end) - luaL_addchar(&b, *src++); - else break; - if (anchor) break; - } - luaL_addlstring(&b, src, ms.src_end-src); - luaL_pushresult(&b); - lua_pushinteger(L, n); /* number of substitutions */ - return 2; + luaL_addlstring(&b, src, ms.src_end - src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; } /* }====================================================== */ - /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ /* was 512, modified to 128 for eLua */ -#define MAX_ITEM 128 +#define MAX_ITEM 128 /* valid flags in a format specification */ -#define FLAGS "-+ #0" +#define FLAGS "-+ #0" /* ** maximum size of each format specification (such as '%-099.99d') ** (+10 accounts for %99.99x plus margin of error) */ -#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) - - -static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - luaL_addchar(b, '"'); - while (l--) { - switch (*s) { - case '"': case '\\': case '\n': { - luaL_addchar(b, '\\'); - luaL_addchar(b, *s); - break; - } - case '\r': { - luaL_addlstring(b, "\\r", 2); - break; - } - case '\0': { - luaL_addlstring(b, "\\000", 4); - break; - } - default: { - luaL_addchar(b, *s); - break; - } - } - s++; - } - luaL_addchar(b, '"'); -} - -static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { - const char *p = strfrmt; - while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ - if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) - luaL_error(L, "invalid format (repeated flags)"); - if (isdigit(uchar(*p))) p++; /* skip width */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - if (*p == '.') { - p++; - if (isdigit(uchar(*p))) p++; /* skip precision */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - } - if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); - *(form++) = '%'; - strncpy(form, strfrmt, p - strfrmt + 1); - form += p - strfrmt + 1; - *form = '\0'; - return p; -} - - -static void addintlen (char *form) { - size_t l = strlen(form); - char spec = form[l - 1]; - strcpy(form + l - 1, LUA_INTFRMLEN); - form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; - form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; -} - - -static int str_format (lua_State *L) { - int top = lua_gettop(L); - int arg = 1; - size_t sfl; - const char *strfrmt = luaL_checklstring(L, arg, &sfl); - const char *strfrmt_end = strfrmt+sfl; - luaL_Buffer b; - luaL_buffinit(L, &b); - while (strfrmt < strfrmt_end) { - if (*strfrmt != L_ESC) - luaL_addchar(&b, *strfrmt++); - else if (*++strfrmt == L_ESC) - luaL_addchar(&b, *strfrmt++); /* %% */ - else { /* format item */ - char form[MAX_FORMAT]; /* to store the format (`%...') */ - char buff[MAX_ITEM]; /* to store the formatted item */ - if (++arg > top) - luaL_argerror(L, arg, "no value"); - strfrmt = scanformat(L, strfrmt, form); - switch (*strfrmt++) { - case 'c': { - sprintf(buff, form, (int)luaL_checknumber(L, arg)); - break; - } - case 'd': case 'i': { - addintlen(form); - sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); - break; - } - case 'o': case 'u': case 'x': case 'X': { - addintlen(form); - sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); - break; - } -#if !defined LUA_NUMBER_INTEGRAL - case 'e': case 'E': case 'f': - case 'g': case 'G': { - sprintf(buff, form, (double)luaL_checknumber(L, arg)); - break; +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + +static void addquoted(lua_State *L, luaL_Buffer *b, int arg) +{ + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) + { + switch (*s) + { + case '"': + case '\\': + case '\n': + { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': + { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': + { + luaL_addlstring(b, "\\000", 4); + break; + } + default: + { + luaL_addchar(b, *s); + break; + } } + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat(lua_State *L, const char *strfrmt, char *form) +{ + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) + p++; /* skip width */ + if (isdigit(uchar(*p))) + p++; /* (2 digits at most) */ + if (*p == '.') + { + p++; + if (isdigit(uchar(*p))) + p++; /* skip precision */ + if (isdigit(uchar(*p))) + p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + strncpy(form, strfrmt, p - strfrmt + 1); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + +static void addintlen(char *form) +{ + size_t l = strlen(form); + char spec = form[l - 1]; + strcpy(form + l - 1, LUA_INTFRMLEN); + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; +} + +static int str_format(lua_State *L) +{ + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt + sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) + { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else + { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) + { + case 'c': + { + sprintf(buff, form, (int)luaL_checknumber(L, arg)); + break; + } + case 'd': + case 'i': + { + addintlen(form); + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'o': + case 'u': + case 'x': + case 'X': + { + addintlen(form); + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } +#if !defined LUA_NUMBER_INTEGRAL + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + { + sprintf(buff, form, (double)luaL_checknumber(L, arg)); + break; + } #endif - case 'q': { - addquoted(L, &b, arg); - continue; /* skip the 'addsize' at the end */ - } - case 's': { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - if (!strchr(form, '.') && l >= 100) { - /* no precision and string is too long to be formatted; - keep original string */ - lua_pushvalue(L, arg); - luaL_addvalue(&b); - continue; /* skip the `addsize' at the end */ - } - else { - sprintf(buff, form, s); - break; - } + case 'q': + { + addquoted(L, &b, arg); + continue; /* skip the 'addsize' at the end */ + } + case 's': + { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) + { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else + { + sprintf(buff, form, s); + break; + } + } + default: + { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); } - default: { /* also treat cases `pnLlh' */ - return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " - LUA_QL("format"), *(strfrmt - 1)); - } - } - luaL_addlstring(&b, buff, strlen(buff)); } - } - luaL_pushresult(&b); - return 1; + luaL_pushresult(&b); + return 1; } #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 1 #include "lrodefs.h" -const LUA_REG_TYPE strlib[] = { - {LSTRKEY("byte"), LFUNCVAL(str_byte)}, - {LSTRKEY("char"), LFUNCVAL(str_char)}, - {LSTRKEY("dump"), LFUNCVAL(str_dump)}, - {LSTRKEY("find"), LFUNCVAL(str_find)}, - {LSTRKEY("format"), LFUNCVAL(str_format)}, +const LUA_REG_TYPE strlib[] = {{LSTRKEY("byte"), LFUNCVAL(str_byte)}, + {LSTRKEY("char"), LFUNCVAL(str_char)}, + {LSTRKEY("dump"), LFUNCVAL(str_dump)}, + {LSTRKEY("find"), LFUNCVAL(str_find)}, + {LSTRKEY("format"), LFUNCVAL(str_format)}, #if LUA_OPTIMIZE_MEMORY > 0 && defined(LUA_COMPAT_GFIND) - {LSTRKEY("gfind"), LFUNCVAL(gmatch)}, + {LSTRKEY("gfind"), LFUNCVAL(gmatch)}, #else - {LSTRKEY("gfind"), LFUNCVAL(gfind_nodef)}, + {LSTRKEY("gfind"), LFUNCVAL(gfind_nodef)}, #endif - {LSTRKEY("gmatch"), LFUNCVAL(gmatch)}, - {LSTRKEY("gsub"), LFUNCVAL(str_gsub)}, - {LSTRKEY("len"), LFUNCVAL(str_len)}, - {LSTRKEY("lower"), LFUNCVAL(str_lower)}, - {LSTRKEY("match"), LFUNCVAL(str_match)}, - {LSTRKEY("rep"), LFUNCVAL(str_rep)}, - {LSTRKEY("reverse"), LFUNCVAL(str_reverse)}, - {LSTRKEY("sub"), LFUNCVAL(str_sub)}, - {LSTRKEY("upper"), LFUNCVAL(str_upper)}, + {LSTRKEY("gmatch"), LFUNCVAL(gmatch)}, + {LSTRKEY("gsub"), LFUNCVAL(str_gsub)}, + {LSTRKEY("len"), LFUNCVAL(str_len)}, + {LSTRKEY("lower"), LFUNCVAL(str_lower)}, + {LSTRKEY("match"), LFUNCVAL(str_match)}, + {LSTRKEY("rep"), LFUNCVAL(str_rep)}, + {LSTRKEY("reverse"), LFUNCVAL(str_reverse)}, + {LSTRKEY("sub"), LFUNCVAL(str_sub)}, + {LSTRKEY("upper"), LFUNCVAL(str_upper)}, #if LUA_OPTIMIZE_MEMORY > 0 - {LSTRKEY("__index"), LROVAL(strlib)}, + {LSTRKEY("__index"), LROVAL(strlib)}, #endif - {LNILKEY, LNILVAL} -}; - + {LNILKEY, LNILVAL}}; #if LUA_OPTIMIZE_MEMORY != 2 -static void createmetatable (lua_State *L) { - lua_createtable(L, 0, 1); /* create metatable for strings */ - lua_pushliteral(L, ""); /* dummy string */ - lua_pushvalue(L, -2); - lua_setmetatable(L, -2); /* set string metatable */ - lua_pop(L, 1); /* pop dummy string */ - lua_pushvalue(L, -2); /* string library... */ - lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ - lua_pop(L, 1); /* pop metatable */ +static void createmetatable(lua_State *L) +{ + lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pop(L, 1); /* pop metatable */ } #endif /* ** Open string library */ -LUALIB_API int luaopen_string (lua_State *L) { +LUALIB_API int luaopen_string(lua_State *L) +{ #if LUA_OPTIMIZE_MEMORY == 0 - luaL_register(L, LUA_STRLIBNAME, strlib); + luaL_register(L, LUA_STRLIBNAME, strlib); #if defined(LUA_COMPAT_GFIND) - lua_getfield(L, -1, "gmatch"); - lua_setfield(L, -2, "gfind"); + lua_getfield(L, -1, "gmatch"); + lua_setfield(L, -2, "gfind"); #endif - createmetatable(L); - return 1; + createmetatable(L); + return 1; #else - lua_pushliteral(L,""); - lua_pushrotable(L, (void*)strlib); - lua_setmetatable(L, -2); - lua_pop(L,1); - return 0; + lua_pushliteral(L, ""); + lua_pushrotable(L, (void *)strlib); + lua_setmetatable(L, -2); + lua_pop(L, 1); + return 0; #endif } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ltable.c b/LuaNode_Esp32/LuaNode32/components/lua/ltable.c index 6624888..9df67a2 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ltable.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ltable.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - /* ** Implementation of tables (aka arrays, objects, or hash tables). ** Tables keep its elements in two parts: an array part and a hash part. @@ -31,729 +30,805 @@ #include "lgc.h" #include "lmem.h" #include "lobject.h" +#include "lrotable.h" #include "lstate.h" #include "ltable.h" -#include "lrotable.h" /* ** max size of array part is 2^MAXBITS */ #if LUAI_BITSINT > 26 -#define MAXBITS 26 +#define MAXBITS 26 #else -#define MAXBITS (LUAI_BITSINT-2) +#define MAXBITS (LUAI_BITSINT - 2) #endif -#define MAXASIZE (1 << MAXBITS) +#define MAXASIZE (1 << MAXBITS) +#define hashpow2(t, n) (gnode(t, lmod((n), sizenode(t)))) -#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) - -#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) -#define hashboolean(t,p) hashpow2(t, p) - +#define hashstr(t, str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t, p) hashpow2(t, p) /* ** for some types, it is better to avoid modulus by power of 2, as ** they tend to have many 2 factors. */ -#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) - - -#define hashpointer(t,p) hashmod(t, IntPoint(p)) +#define hashmod(t, n) (gnode(t, ((n) % ((sizenode(t) - 1) | 1)))) +#define hashpointer(t, p) hashmod(t, IntPoint(p)) /* ** number of ints inside a lua_Number */ -#define numints cast_int(sizeof(lua_Number)/sizeof(int)) +#define numints cast_int(sizeof(lua_Number) / sizeof(int)) - - -#define dummynode (&dummynode_) +#define dummynode (&dummynode_) static const Node dummynode_ = { - {LUA_TVALUE_NIL}, /* value */ - {LUA_TKEY_NIL} /* key */ + {LUA_TVALUE_NIL}, /* value */ + {LUA_TKEY_NIL} /* key */ }; - /* ** hash for lua_Numbers */ -static Node *hashnum (const Table *t, lua_Number n) { - unsigned int a[numints]; - int i; - if (luai_numeq(n, 0)) /* avoid problems with -0 */ - return gnode(t, 0); - memcpy(a, &n, sizeof(a)); - for (i = 1; i < numints; i++) a[0] += a[i]; - return hashmod(t, a[0]); +static Node *hashnum(const Table *t, lua_Number n) +{ + unsigned int a[numints]; + int i; + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, a[0]); } - - /* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) */ -static Node *mainposition (const Table *t, const TValue *key) { - switch (ttype(key)) { - case LUA_TNUMBER: - return hashnum(t, nvalue(key)); - case LUA_TSTRING: - return hashstr(t, rawtsvalue(key)); - case LUA_TBOOLEAN: - return hashboolean(t, bvalue(key)); - case LUA_TLIGHTUSERDATA: - case LUA_TROTABLE: - case LUA_TLIGHTFUNCTION: - return hashpointer(t, pvalue(key)); - default: - return hashpointer(t, gcvalue(key)); - } +static Node *mainposition(const Table *t, const TValue *key) +{ + switch (ttype(key)) + { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + case LUA_TROTABLE: + case LUA_TLIGHTFUNCTION: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } } - /* ** returns the index for `key' if `key' is an appropriate key to live in ** the array part of the table, -1 otherwise. */ -static int arrayindex (const TValue *key) { - if (ttisnumber(key)) { - lua_Number n = nvalue(key); - int k; - lua_number2int(k, n); - if (luai_numeq(cast_num(k), n)) - return k; - } - return -1; /* `key' did not match some condition */ +static int arrayindex(const TValue *key) +{ + if (ttisnumber(key)) + { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ } - /* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The ** beginning of a traversal is signalled by -1. */ -static int findindex (lua_State *L, Table *t, StkId key) { - int i; - if (ttisnil(key)) return -1; /* first iteration */ - i = arrayindex(key); - if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ - return i-1; /* yes; that's the index (corrected to C) */ - else { - Node *n = mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ - /* key may be dead already, but it is ok to use it in `next' */ - if (luaO_rawequalObj(key2tval(n), key) || - (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && - gcvalue(gkey(n)) == gcvalue(key))) { - i = cast_int(n - gnode(t, 0)); /* key index in hash table */ - /* hash elements are numbered after array ones */ - return i + t->sizearray; - } - else n = gnext(n); - } while (n); - luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ - return 0; /* to avoid warnings */ - } +static int findindex(lua_State *L, Table *t, StkId key) +{ + int i; + if (ttisnil(key)) + return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i - 1; /* yes; that's the index (corrected to C) */ + else + { + Node *n = mainposition(t, key); + do + { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaO_rawequalObj(key2tval(n), key) || + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && gcvalue(gkey(n)) == gcvalue(key))) + { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else + n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + return 0; /* to avoid warnings */ + } } - -int luaH_next (lua_State *L, Table *t, StkId key) { - int i = findindex(L, t, key); /* find original element */ - for (i++; i < t->sizearray; i++) { /* try first array part */ - if (!ttisnil(&t->array[i])) { /* a non-nil value? */ - setnvalue(key, cast_num(i+1)); - setobj2s(L, key+1, &t->array[i]); - return 1; +int luaH_next(lua_State *L, Table *t, StkId key) +{ + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) + { /* try first array part */ + if (!ttisnil(&t->array[i])) + { /* a non-nil value? */ + setnvalue(key, cast_num(i + 1)); + setobj2s(L, key + 1, &t->array[i]); + return 1; + } } - } - for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ - if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ - setobj2s(L, key, key2tval(gnode(t, i))); - setobj2s(L, key+1, gval(gnode(t, i))); - return 1; + for (i -= t->sizearray; i < sizenode(t); i++) + { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) + { /* a non-nil value? */ + setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key + 1, gval(gnode(t, i))); + return 1; + } } - } - return 0; /* no more elements */ + return 0; /* no more elements */ } - -int luaH_next_ro (lua_State *L, void *t, StkId key) { - luaR_next(L, t, key, key+1); - return ttisnil(key) ? 0 : 1; +int luaH_next_ro(lua_State *L, void *t, StkId key) +{ + luaR_next(L, t, key, key + 1); + return ttisnil(key) ? 0 : 1; } - /* ** {============================================================= ** Rehash ** ============================================================== */ - -static int computesizes (int nums[], int *narray) { - int i; - int twotoi; /* 2^i */ - int a = 0; /* number of elements smaller than 2^i */ - int na = 0; /* number of elements to go to array part */ - int n = 0; /* optimal size for array part */ - for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { - if (nums[i] > 0) { - a += nums[i]; - if (a > twotoi/2) { /* more than half elements present? */ - n = twotoi; /* optimal size (till now) */ - na = a; /* all elements smaller than n will go to array part */ - } +static int computesizes(int nums[], int *narray) +{ + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi / 2 < *narray; i++, twotoi *= 2) + { + if (nums[i] > 0) + { + a += nums[i]; + if (a > twotoi / 2) + { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) + break; /* all elements already counted */ } - if (a == *narray) break; /* all elements already counted */ - } - *narray = n; - lua_assert(*narray/2 <= na && na <= *narray); - return na; -} - - -static int countint (const TValue *key, int *nums) { - int k = arrayindex(key); - if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ - nums[ceillog2(k)]++; /* count as such */ - return 1; - } - else - return 0; -} - - -static int numusearray (const Table *t, int *nums) { - int lg; - int ttlg; /* 2^lg */ - int ause = 0; /* summation of `nums' */ - int i = 1; /* count to traverse all array keys */ - for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ - int lc = 0; /* counter */ - int lim = ttlg; - if (lim > t->sizearray) { - lim = t->sizearray; /* adjust upper limit */ - if (i > lim) - break; /* no more elements to count */ + *narray = n; + lua_assert(*narray / 2 <= na && na <= *narray); + return na; +} + +static int countint(const TValue *key, int *nums) +{ + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) + { /* is `key' an appropriate array index? */ + nums[ceillog2(k)]++; /* count as such */ + return 1; } - /* count elements in range (2^(lg-1), 2^lg] */ - for (; i <= lim; i++) { - if (!ttisnil(&t->array[i-1])) - lc++; + else + return 0; +} + +static int numusearray(const Table *t, int *nums) +{ + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg = 0, ttlg = 1; lg <= MAXBITS; lg++, ttlg *= 2) + { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) + { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) + { + if (!ttisnil(&t->array[i - 1])) + lc++; + } + nums[lg] += lc; + ause += lc; } - nums[lg] += lc; - ause += lc; - } - return ause; -} - - -static int numusehash (const Table *t, int *nums, int *pnasize) { - int totaluse = 0; /* total number of elements */ - int ause = 0; /* summation of `nums' */ - int i = sizenode(t); - while (i--) { - Node *n = &t->node[i]; - if (!ttisnil(gval(n))) { - ause += countint(key2tval(n), nums); - totaluse++; + return ause; +} + +static int numusehash(const Table *t, int *nums, int *pnasize) +{ + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) + { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) + { + ause += countint(key2tval(n), nums); + totaluse++; + } } - } - *pnasize += ause; - return totaluse; + *pnasize += ause; + return totaluse; } - -static void setarrayvector (lua_State *L, Table *t, int size) { - int i; - luaM_reallocvector(L, t->array, t->sizearray, size, TValue); - for (i=t->sizearray; iarray[i]); - t->sizearray = size; +static void setarrayvector(lua_State *L, Table *t, int size) +{ + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i = t->sizearray; i < size; i++) setnilvalue(&t->array[i]); + t->sizearray = size; } - -static Node *getfreepos (Table *t) { - while (t->lastfree-- > t->node) { - if (ttisnil(gkey(t->lastfree))) - return t->lastfree; - } - return NULL; /* could not find a free place */ +static Node *getfreepos(Table *t) +{ + while (t->lastfree-- > t->node) + { + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ } - -static void resizenodevector (lua_State *L, Table *t, int oldsize, int newsize) { - int lsize; - if (newsize == 0) { /* no elements to hash part? */ - t->node = cast(Node *, dummynode); /* use common `dummynode' */ - lsize = 0; - } - else { - Node *node = t->node; - int i; - lsize = ceillog2(newsize); - if (lsize > MAXBITS) - luaG_runerror(L, "table overflow"); - newsize = twoto(lsize); - if (node == dummynode) { - oldsize = 0; - node = NULL; /* don't try to realloc `dummynode' pointer. */ +static void resizenodevector(lua_State *L, Table *t, int oldsize, int newsize) +{ + int lsize; + if (newsize == 0) + { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; } - luaM_reallocvector(L, node, oldsize, newsize, Node); - t->node = node; - for (i=oldsize; inode; + int i; + lsize = ceillog2(newsize); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + newsize = twoto(lsize); + if (node == dummynode) + { + oldsize = 0; + node = NULL; /* don't try to realloc `dummynode' pointer. */ + } + luaM_reallocvector(L, node, oldsize, newsize, Node); + t->node = node; + for (i = oldsize; i < newsize; i++) + { + Node *n = gnode(t, i); + gnext(n) = NULL; + setnilvalue(gkey(n)); + setnilvalue(gval(n)); + } } - } - t->lsizenode = cast_byte(lsize); - t->lastfree = gnode(t, newsize); /* reset lastfree to end of table. */ + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, newsize); /* reset lastfree to end of table. */ } - -static Node *find_prev_node(Node *mp, Node *next) { - Node *prev = mp; - while (prev != NULL && gnext(prev) != next) prev = gnext(prev); - return prev; +static Node *find_prev_node(Node *mp, Node *next) +{ + Node *prev = mp; + while (prev != NULL && gnext(prev) != next) prev = gnext(prev); + return prev; } - /* ** move a node from it's old position to it's new position during a rehash; -** first, check whether the moving node's main position is free. If not, check whether +** first, check whether the moving node's main position is free. If not, check +*whether ** colliding node is in its main position or not: if it is not, move colliding ** node to an empty place and put moving node in its main position; otherwise -** (colliding node is in its main position), moving node goes to an empty position. +** (colliding node is in its main position), moving node goes to an empty +*position. */ -static int move_node (lua_State *L, Table *t, Node *node) { - Node *mp = mainposition(t, key2tval(node)); - /* if node is in it's main position, don't need to move node. */ - if (mp == node) return 1; - /* if node is in it's main position's chain, don't need to move node. */ - if (find_prev_node(mp, node) != NULL) return 1; - /* is main position is free? */ - if (!ttisnil(gval(mp)) || mp == dummynode) { - /* no; move main position node if it is out of its main position */ - Node *othermp; - othermp = mainposition(t, key2tval(mp)); - if (othermp != mp) { /* is colliding node out of its main position? */ - /* yes; swap colliding node with the node that is being moved. */ - Node *prev; - Node tmp; - tmp = *node; - prev = find_prev_node(othermp, mp); /* find previous */ - if (prev != NULL) gnext(prev) = node; /* redo the chain with `n' in place of `mp' */ - *node = *mp; /* copy colliding node into free pos. (mp->next also goes) */ - *mp = tmp; - return (prev != NULL) ? 1 : 0; /* is colliding node part of its main position chain? */ +static int move_node(lua_State *L, Table *t, Node *node) +{ + Node *mp = mainposition(t, key2tval(node)); + /* if node is in it's main position, don't need to move node. */ + if (mp == node) + return 1; + /* if node is in it's main position's chain, don't need to move node. */ + if (find_prev_node(mp, node) != NULL) + return 1; + /* is main position is free? */ + if (!ttisnil(gval(mp)) || mp == dummynode) + { + /* no; move main position node if it is out of its main position */ + Node *othermp; + othermp = mainposition(t, key2tval(mp)); + if (othermp != mp) + { /* is colliding node out of its main position? */ + /* yes; swap colliding node with the node that is being moved. */ + Node *prev; + Node tmp; + tmp = *node; + prev = find_prev_node(othermp, mp); /* find previous */ + if (prev != NULL) + gnext(prev) = node; /* redo the chain with `n' in place of `mp' */ + *node = *mp; /* copy colliding node into free pos. (mp->next also + goes) */ + *mp = tmp; + return (prev != NULL) ? 1 : 0; /* is colliding node part of its main + position chain? */ + } + else + { /* colliding node is in its own main position */ + /* add node to main position's chain. */ + gnext(node) = gnext(mp); /* chain new position */ + gnext(mp) = node; + } } - else { /* colliding node is in its own main position */ - /* add node to main position's chain. */ - gnext(node) = gnext(mp); /* chain new position */ - gnext(mp) = node; + else + { /* main position is free, move node */ + *mp = *node; + gnext(node) = NULL; + setnilvalue(gkey(node)); + setnilvalue(gval(node)); } - } - else { /* main position is free, move node */ - *mp = *node; - gnext(node) = NULL; - setnilvalue(gkey(node)); - setnilvalue(gval(node)); - } - return 1; -} - - -static int move_number (lua_State *L, Table *t, Node *node) { - int key; - lua_Number n = nvalue(key2tval(node)); - lua_number2int(key, n); - if (luai_numeq(cast_num(key), nvalue(key2tval(node)))) {/* index is int? */ - /* (1 <= key && key <= t->sizearray) */ - if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) { - setobjt2t(L, &t->array[key-1], gval(node)); - setnilvalue(gkey(node)); - setnilvalue(gval(node)); - return 1; - } - } - return 0; -} - - -static void resize_hashpart (lua_State *L, Table *t, int nhsize) { - int i; - int lsize=0; - int oldhsize = (t->node != dummynode) ? twoto(t->lsizenode) : 0; - if (nhsize > 0) { /* round new hashpart size up to next power of two. */ - lsize=ceillog2(nhsize); - if (lsize > MAXBITS) - luaG_runerror(L, "table overflow"); - } - nhsize = twoto(lsize); - /* grow hash part to new size. */ - if (oldhsize < nhsize) - resizenodevector(L, t, oldhsize, nhsize); - else { /* hash part might be shrinking */ - if (nhsize > 0) { - t->lsizenode = cast_byte(lsize); - t->lastfree = gnode(t, nhsize); /* reset lastfree back to end of table. */ - } - else { /* new hashpart size is zero. */ - resizenodevector(L, t, oldhsize, nhsize); - return; + return 1; +} + +static int move_number(lua_State *L, Table *t, Node *node) +{ + int key; + lua_Number n = nvalue(key2tval(node)); + lua_number2int(key, n); + if (luai_numeq(cast_num(key), nvalue(key2tval(node)))) + { /* index is int? */ + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key - 1) < cast(unsigned int, t->sizearray)) + { + setobjt2t(L, &t->array[key - 1], gval(node)); + setnilvalue(gkey(node)); + setnilvalue(gval(node)); + return 1; + } } - } - /* break old chains, try moving int keys to array part and compact keys into new hashpart */ - for (i = 0; i < oldhsize; i++) { - Node *old = gnode(t, i); - gnext(old) = NULL; - if (ttisnil(gval(old))) { /* clear nodes with nil values. */ - setnilvalue(gkey(old)); - continue; + return 0; +} + +static void resize_hashpart(lua_State *L, Table *t, int nhsize) +{ + int i; + int lsize = 0; + int oldhsize = (t->node != dummynode) ? twoto(t->lsizenode) : 0; + if (nhsize > 0) + { /* round new hashpart size up to next power of two. */ + lsize = ceillog2(nhsize); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); } - if (ttisnumber(key2tval(old))) { /* try moving the int keys into array part. */ - if(move_number(L, t, old)) - continue; + nhsize = twoto(lsize); + /* grow hash part to new size. */ + if (oldhsize < nhsize) + resizenodevector(L, t, oldhsize, nhsize); + else + { /* hash part might be shrinking */ + if (nhsize > 0) + { + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, nhsize); /* reset lastfree back to end of table. */ + } + else + { /* new hashpart size is zero. */ + resizenodevector(L, t, oldhsize, nhsize); + return; + } } - if (i >= nhsize) { /* move all valid keys to indices < nhsize. */ - Node *n = getfreepos(t); /* get a free place */ - lua_assert(n != dummynode && n != NULL); - *n = *old; + /* break old chains, try moving int keys to array part and compact keys into + * new hashpart */ + for (i = 0; i < oldhsize; i++) + { + Node *old = gnode(t, i); + gnext(old) = NULL; + if (ttisnil(gval(old))) + { /* clear nodes with nil values. */ + setnilvalue(gkey(old)); + continue; + } + if (ttisnumber(key2tval(old))) + { /* try moving the int keys into array part. */ + if (move_number(L, t, old)) + continue; + } + if (i >= nhsize) + { /* move all valid keys to indices < nhsize. */ + Node *n = getfreepos(t); /* get a free place */ + lua_assert(n != dummynode && n != NULL); + *n = *old; + } } - } - /* shrink hash part */ - if (oldhsize > nhsize) - resizenodevector(L, t, oldhsize, nhsize); - /* move nodes to their new mainposition and re-create node chains */ - for (i = 0; i < nhsize; i++) { - Node *curr = gnode(t, i); - if (!ttisnil(gval(curr))) - while (move_node(L, t, curr) == 0); - } -} - - -static void resize (lua_State *L, Table *t, int nasize, int nhsize) { - int i; - int oldasize = t->sizearray; - if (nasize > oldasize) /* array part must grow? */ - setarrayvector(L, t, nasize); - resize_hashpart(L, t, nhsize); - if (nasize < oldasize) { /* array part must shrink? */ - t->sizearray = nasize; - /* re-insert elements from vanishing slice */ - for (i=nasize; iarray[i])) - setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + /* shrink hash part */ + if (oldhsize > nhsize) + resizenodevector(L, t, oldhsize, nhsize); + /* move nodes to their new mainposition and re-create node chains */ + for (i = 0; i < nhsize; i++) + { + Node *curr = gnode(t, i); + if (!ttisnil(gval(curr))) + while (move_node(L, t, curr) == 0) + ; } - /* shrink array */ - luaM_reallocvector(L, t->array, oldasize, nasize, TValue); - } } - -void luaH_resizearray (lua_State *L, Table *t, int nasize) { - int nsize = (t->node == dummynode) ? 0 : sizenode(t); - resize(L, t, nasize, nsize); +static void resize(lua_State *L, Table *t, int nasize, int nhsize) +{ + int i; + int oldasize = t->sizearray; + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + resize_hashpart(L, t, nhsize); + if (nasize < oldasize) + { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i = nasize; i < oldasize; i++) + { + if (!ttisnil(&t->array[i])) + setobjt2t(L, luaH_setnum(L, t, i + 1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } } - -static void rehash (lua_State *L, Table *t, const TValue *ek) { - int nasize, na; - int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ - int i; - int totaluse; - for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ - nasize = numusearray(t, nums); /* count keys in array part */ - totaluse = nasize; /* all those keys are integer keys */ - totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ - /* count extra key */ - nasize += countint(ek, nums); - totaluse++; - /* compute new size for array part */ - na = computesizes(nums, &nasize); - /* resize the table to new computed sizes */ - resize(L, t, nasize, totaluse - na); +void luaH_resizearray(lua_State *L, Table *t, int nasize) +{ + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + resize(L, t, nasize, nsize); } - +static void rehash(lua_State *L, Table *t, const TValue *ek) +{ + int nasize, na; + int nums[MAXBITS + 1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int i; + int totaluse; + for (i = 0; i <= MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + resize(L, t, nasize, totaluse - na); +} /* ** }============================================================= */ - -Table *luaH_new (lua_State *L, int narray, int nhash) { - Table *t = luaM_new(L, Table); - luaC_link(L, obj2gco(t), LUA_TTABLE); - sethvalue2s(L, L->top, t); /* put table on stack */ - incr_top(L); - t->metatable = NULL; - t->flags = cast_byte(~0); - /* temporary values (kept only if some malloc fails) */ - t->array = NULL; - t->sizearray = 0; - t->lsizenode = 0; - t->node = cast(Node *, dummynode); - setarrayvector(L, t, narray); - resizenodevector(L, t, 0, nhash); - L->top--; /* remove table from stack */ - return t; -} - - -void luaH_free (lua_State *L, Table *t) { - if (t->node != dummynode) - luaM_freearray(L, t->node, sizenode(t), Node); - luaM_freearray(L, t->array, t->sizearray, TValue); - luaM_free(L, t); +Table *luaH_new(lua_State *L, int narray, int nhash) +{ + Table *t = luaM_new(L, Table); + luaC_link(L, obj2gco(t), LUA_TTABLE); + sethvalue2s(L, L->top, t); /* put table on stack */ + incr_top(L); + t->metatable = NULL; + t->flags = cast_byte(~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = cast(Node *, dummynode); + setarrayvector(L, t, narray); + resizenodevector(L, t, 0, nhash); + L->top--; /* remove table from stack */ + return t; +} + +void luaH_free(lua_State *L, Table *t) +{ + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TValue); + luaM_free(L, t); } - - /* -** inserts a new key into a hash table; first, check whether key's main -** position is free. If not, check whether colliding node is in its main -** position or not: if it is not, move colliding node to an empty place and -** put new key in its main position; otherwise (colliding node is in its main -** position), new key goes to an empty position. +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. */ -static TValue *newkey (lua_State *L, Table *t, const TValue *key) { - Node *mp = mainposition(t, key); - if (!ttisnil(gval(mp)) || mp == dummynode) { - Node *othern; - Node *n = getfreepos(t); /* get a free place */ - if (n == NULL) { /* cannot find a free place? */ - rehash(L, t, key); /* grow table */ - return luaH_set(L, t, key); /* re-insert key into grown table */ +static TValue *newkey(lua_State *L, Table *t, const TValue *key) +{ + Node *mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) + { + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) + { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + return luaH_set(L, t, key); /* re-insert key into grown table */ + } + lua_assert(n != dummynode); + othern = mainposition(t, key2tval(mp)); + if (othern != mp) + { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) + */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else + { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } } - lua_assert(n != dummynode); - othern = mainposition(t, key2tval(mp)); - if (othern != mp) { /* is colliding node out of its main position? */ - /* yes; move colliding node into free position */ - while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ - gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ - *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ - gnext(mp) = NULL; /* now `mp' is free */ - setnilvalue(gval(mp)); - } - else { /* colliding node is in its own main position */ - /* new node will go into free position */ - gnext(n) = gnext(mp); /* chain new position */ - gnext(mp) = n; - mp = n; - } - } - setobj2t(L, gkey(mp), key); - luaC_barriert(L, t, key); - lua_assert(ttisnil(gval(mp))); - return gval(mp); + setobj2t(L, gkey(mp), key); + luaC_barriert(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); } - /* ** search function for integers */ -const TValue *luaH_getnum (Table *t, int key) { - /* (1 <= key && key <= t->sizearray) */ - if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) - return &t->array[key-1]; - else { - lua_Number nk = cast_num(key); - Node *n = hashnum(t, nk); - do { /* check whether `key' is somewhere in the chain */ - if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) - return gval(n); /* that's it */ - else n = gnext(n); - } while (n); - return luaO_nilobject; - } +const TValue *luaH_getnum(Table *t, int key) +{ + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key - 1) < cast(unsigned int, t->sizearray)) + return &t->array[key - 1]; + else + { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do + { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else + n = gnext(n); + } while (n); + return luaO_nilobject; + } } /* same thing for rotables */ -const TValue *luaH_getnum_ro (void *t, int key) { - const TValue *res = luaR_findentry(t, NULL, key, NULL); - return res ? res : luaO_nilobject; +const TValue *luaH_getnum_ro(void *t, int key) +{ + const TValue *res = luaR_findentry(t, NULL, key, NULL); + return res ? res : luaO_nilobject; } - /* ** search function for strings */ -const TValue *luaH_getstr (Table *t, TString *key) { - Node *n = hashstr(t, key); - do { /* check whether `key' is somewhere in the chain */ - if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) - return gval(n); /* that's it */ - else n = gnext(n); - } while (n); - return luaO_nilobject; +const TValue *luaH_getstr(Table *t, TString *key) +{ + Node *n = hashstr(t, key); + do + { /* check whether `key' is somewhere in the chain */ + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) + return gval(n); /* that's it */ + else + n = gnext(n); + } while (n); + return luaO_nilobject; } /* same thing for rotables */ -const TValue *luaH_getstr_ro (void *t, TString *key) { - char keyname[LUA_MAX_ROTABLE_NAME + 1]; - const TValue *res; - if (!t) - return luaO_nilobject; - luaR_getcstr(keyname, key, LUA_MAX_ROTABLE_NAME); - res = luaR_findentry(t, keyname, 0, NULL); - return res ? res : luaO_nilobject; +const TValue *luaH_getstr_ro(void *t, TString *key) +{ + char keyname[LUA_MAX_ROTABLE_NAME + 1]; + const TValue *res; + if (!t) + return luaO_nilobject; + luaR_getcstr(keyname, key, LUA_MAX_ROTABLE_NAME); + res = luaR_findentry(t, keyname, 0, NULL); + return res ? res : luaO_nilobject; } - /* ** main search function */ -const TValue *luaH_get (Table *t, const TValue *key) { - switch (ttype(key)) { - case LUA_TNIL: return luaO_nilobject; - case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); - case LUA_TNUMBER: { - int k; - lua_Number n = nvalue(key); - lua_number2int(k, n); - if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ - return luaH_getnum(t, k); /* use specialized version */ - /* else go through */ - } - default: { - Node *n = mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ - if (luaO_rawequalObj(key2tval(n), key)) - return gval(n); /* that's it */ - else n = gnext(n); - } while (n); - return luaO_nilobject; +const TValue *luaH_get(Table *t, const TValue *key) +{ + switch (ttype(key)) + { + case LUA_TNIL: + return luaO_nilobject; + case LUA_TSTRING: + return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMBER: + { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: + { + Node *n = mainposition(t, key); + do + { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else + n = gnext(n); + } while (n); + return luaO_nilobject; + } } - } } /* same thing for rotables */ -const TValue *luaH_get_ro (void *t, const TValue *key) { - switch (ttype(key)) { - case LUA_TNIL: return luaO_nilobject; - case LUA_TSTRING: return luaH_getstr_ro(t, rawtsvalue(key)); - case LUA_TNUMBER: { - int k; - lua_Number n = nvalue(key); - lua_number2int(k, n); - if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ - return luaH_getnum_ro(t, k); /* use specialized version */ - /* else go through */ +const TValue *luaH_get_ro(void *t, const TValue *key) +{ + switch (ttype(key)) + { + case LUA_TNIL: + return luaO_nilobject; + case LUA_TSTRING: + return luaH_getstr_ro(t, rawtsvalue(key)); + case LUA_TNUMBER: + { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum_ro(t, k); /* use specialized version */ + /* else go through */ + } + default: + { + return luaO_nilobject; + } + } +} + +TValue *luaH_set(lua_State *L, Table *t, const TValue *key) +{ + const TValue *p = luaH_get(t, key); + t->flags = 0; + if (p != luaO_nilobject) + return cast(TValue *, p); + else + { + if (ttisnil(key)) + luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); } - default: { - return luaO_nilobject; +} + +TValue *luaH_setnum(lua_State *L, Table *t, int key) +{ + const TValue *p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else + { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); } - } -} - - -TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { - const TValue *p = luaH_get(t, key); - t->flags = 0; - if (p != luaO_nilobject) - return cast(TValue *, p); - else { - if (ttisnil(key)) luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && luai_numisnan(nvalue(key))) - luaG_runerror(L, "table index is NaN"); - return newkey(L, t, key); - } -} - - -TValue *luaH_setnum (lua_State *L, Table *t, int key) { - const TValue *p = luaH_getnum(t, key); - if (p != luaO_nilobject) - return cast(TValue *, p); - else { - TValue k; - setnvalue(&k, cast_num(key)); - return newkey(L, t, &k); - } -} - - -TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { - const TValue *p = luaH_getstr(t, key); - if (p != luaO_nilobject) - return cast(TValue *, p); - else { - TValue k; - setsvalue(L, &k, key); - return newkey(L, t, &k); - } -} - - -static int unbound_search (Table *t, unsigned int j) { - unsigned int i = j; /* i is zero or a present index */ - j++; - /* find `i' and `j' such that i is present and j is not */ - while (!ttisnil(luaH_getnum(t, j))) { - i = j; - j *= 2; - if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ - /* table was built with bad purposes: resort to linear search */ - i = 1; - while (!ttisnil(luaH_getnum(t, i))) i++; - return i - 1; +} + +TValue *luaH_setstr(lua_State *L, Table *t, TString *key) +{ + const TValue *p = luaH_getstr(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else + { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); } - } - /* now do a binary search between them */ - while (j - i > 1) { - unsigned int m = (i+j)/2; - if (ttisnil(luaH_getnum(t, m))) j = m; - else i = m; - } - return i; } +static int unbound_search(Table *t, unsigned int j) +{ + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) + { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) + { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) + { + unsigned int m = (i + j) / 2; + if (ttisnil(luaH_getnum(t, m))) + j = m; + else + i = m; + } + return i; +} /* ** Try to find a boundary in table `t'. A `boundary' is an integer index ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). */ -int luaH_getn (Table *t) { - unsigned int j = t->sizearray; - if (j > 0 && ttisnil(&t->array[j - 1])) { - /* there is a boundary in the array part: (binary) search for it */ - unsigned int i = 0; - while (j - i > 1) { - unsigned int m = (i+j)/2; - if (ttisnil(&t->array[m - 1])) j = m; - else i = m; +int luaH_getn(Table *t) +{ + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) + { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) + { + unsigned int m = (i + j) / 2; + if (ttisnil(&t->array[m - 1])) + j = m; + else + i = m; + } + return i; } - return i; - } - /* else must find a boundary in hash part */ - else if (t->node == dummynode) /* hash part is empty? */ - return j; /* that is easy... */ - else return unbound_search(t, j); + /* else must find a boundary in hash part */ + else if (t->node == dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else + return unbound_search(t, j); } /* same thing for rotables */ -int luaH_getn_ro (void *t) { - int i = 1, len=0; - - while(luaR_findentry(t, NULL, i ++, NULL)) - len ++; - return len; +int luaH_getn_ro(void *t) +{ + int i = 1, len = 0; + + while (luaR_findentry(t, NULL, i++, NULL)) len++; + return len; } #if defined(LUA_DEBUG) -Node *luaH_mainposition (const Table *t, const TValue *key) { - return mainposition(t, key); -} +Node *luaH_mainposition(const Table *t, const TValue *key) { return mainposition(t, key); } -int luaH_isdummy (Node *n) { return n == dummynode; } +int luaH_isdummy(Node *n) { return n == dummynode; } #endif diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ltablib.c b/LuaNode_Esp32/LuaNode32/components/lua/ltablib.c index 8b0a810..5f971b0 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ltablib.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ltablib.c @@ -4,164 +4,171 @@ ** See Copyright Notice in lua.h */ - #define ltablib_c #define LUA_LIB #define LUAC_CROSS_FILE -#include "lua.h" - #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lua.h" +#include "lualib.h" - -#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) - - -static int foreachi (lua_State *L) { - int i; - int n = aux_getn(L, 1); - luaL_checkanyfunction(L, 2); - for (i=1; i <= n; i++) { - lua_pushvalue(L, 2); /* function */ - lua_pushinteger(L, i); /* 1st argument */ - lua_rawgeti(L, 1, i); /* 2nd argument */ - lua_call(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 1); /* remove nil result */ - } - return 0; +#define aux_getn(L, n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + +static int foreachi(lua_State *L) +{ + int i; + int n = aux_getn(L, 1); + luaL_checkanyfunction(L, 2); + for (i = 1; i <= n; i++) + { + lua_pushvalue(L, 2); /* function */ + lua_pushinteger(L, i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; } - -static int foreach (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkanyfunction(L, 2); - lua_pushnil(L); /* first key */ - while (lua_next(L, 1)) { - lua_pushvalue(L, 2); /* function */ - lua_pushvalue(L, -3); /* key */ - lua_pushvalue(L, -3); /* value */ - lua_call(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 2); /* remove value and result */ - } - return 0; +static int foreach (lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkanyfunction(L, 2); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) + { + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } + return 0; } - -static int maxn (lua_State *L) { - lua_Number max = 0; - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushnil(L); /* first key */ - while (lua_next(L, 1)) { - lua_pop(L, 1); /* remove value */ - if (lua_type(L, -1) == LUA_TNUMBER) { - lua_Number v = lua_tonumber(L, -1); - if (v > max) max = v; +static int maxn(lua_State *L) +{ + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) + { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) + { + lua_Number v = lua_tonumber(L, -1); + if (v > max) + max = v; + } } - } - lua_pushnumber(L, max); - return 1; + lua_pushnumber(L, max); + return 1; } - -static int getn (lua_State *L) { - lua_pushinteger(L, aux_getn(L, 1)); - return 1; +static int getn(lua_State *L) +{ + lua_pushinteger(L, aux_getn(L, 1)); + return 1; } - -static int setn (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); +static int setn(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); #ifndef luaL_setn - luaL_setn(L, 1, luaL_checkint(L, 2)); + luaL_setn(L, 1, luaL_checkint(L, 2)); #else - luaL_error(L, LUA_QL("setn") " is obsolete"); + luaL_error(L, LUA_QL("setn") " is obsolete"); #endif - lua_pushvalue(L, 1); - return 1; + lua_pushvalue(L, 1); + return 1; } - -static int tinsert (lua_State *L) { - int e = aux_getn(L, 1) + 1; /* first empty element */ - int pos; /* where to insert new element */ - switch (lua_gettop(L)) { - case 2: { /* called with only 2 arguments */ - pos = e; /* insert new element at the end */ - break; - } - case 3: { - int i; - pos = luaL_checkint(L, 2); /* 2nd argument is the position */ - if (pos > e) e = pos; /* `grow' array if necessary */ - for (i = e; i > pos; i--) { /* move up elements */ - lua_rawgeti(L, 1, i-1); - lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ - } - break; - } - default: { - return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); +static int tinsert(lua_State *L) +{ + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) + { + case 2: + { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: + { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) + e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) + { /* move up elements */ + lua_rawgeti(L, 1, i - 1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: + { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } } - } - luaL_setn(L, 1, e); /* new size */ - lua_rawseti(L, 1, pos); /* t[pos] = v */ - return 0; + luaL_setn(L, 1, e); /* new size */ + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; } - -static int tremove (lua_State *L) { - int e = aux_getn(L, 1); - int pos = luaL_optint(L, 2, e); - if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ - return 0; /* nothing to remove */ - luaL_setn(L, 1, e - 1); /* t.n = n-1 */ - lua_rawgeti(L, 1, pos); /* result = t[pos] */ - for ( ;pos= P */ - while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i>u) luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* repeat --j until a[j] <= P */ - while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { - if (j= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) + { + if (i > u) + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) + { + if (j < l) + luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + if (j < i) + { + lua_pop(L, 3); /* pop pivot, a[i], a[j] */ + break; + } + set2(L, i, j); + } + lua_rawgeti(L, 1, u - 1); + lua_rawgeti(L, 1, i); + set2(L, u - 1, i); /* swap pivot (a[u-1]) with a[i] */ + /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ + /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ + if (i - l < u - i) + { + j = l; + i = i - 1; + l = i + 2; + } + else + { + j = i + 1; + i = u; + u = j - 2; + } + auxsort(L, j, i); /* call recursively the smaller one */ + } /* repeat the routine for the larger one */ } -static int sort (lua_State *L) { - int n = aux_getn(L, 1); - luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ - if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_settop(L, 2); /* make sure there is two arguments */ - auxsort(L, 1, n); - return 0; +static int sort(lua_State *L) +{ + int n = aux_getn(L, 1); + luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_settop(L, 2); /* make sure there is two arguments */ + auxsort(L, 1, n); + return 0; } /* }====================================================== */ - #undef MIN_OPT_LEVEL #define MIN_OPT_LEVEL 1 #include "lrodefs.h" -const LUA_REG_TYPE tab_funcs[] = { - {LSTRKEY("concat"), LFUNCVAL(tconcat)}, - {LSTRKEY("foreach"), LFUNCVAL(foreach)}, - {LSTRKEY("foreachi"), LFUNCVAL(foreachi)}, - {LSTRKEY("getn"), LFUNCVAL(getn)}, - {LSTRKEY("maxn"), LFUNCVAL(maxn)}, - {LSTRKEY("insert"), LFUNCVAL(tinsert)}, - {LSTRKEY("remove"), LFUNCVAL(tremove)}, - {LSTRKEY("setn"), LFUNCVAL(setn)}, - {LSTRKEY("sort"), LFUNCVAL(sort)}, - {LNILKEY, LNILVAL} -}; +const LUA_REG_TYPE tab_funcs[] = {{LSTRKEY("concat"), LFUNCVAL(tconcat)}, {LSTRKEY("foreach"), LFUNCVAL(foreach)}, + {LSTRKEY("foreachi"), LFUNCVAL(foreachi)}, {LSTRKEY("getn"), LFUNCVAL(getn)}, + {LSTRKEY("maxn"), LFUNCVAL(maxn)}, {LSTRKEY("insert"), LFUNCVAL(tinsert)}, + {LSTRKEY("remove"), LFUNCVAL(tremove)}, {LSTRKEY("setn"), LFUNCVAL(setn)}, + {LSTRKEY("sort"), LFUNCVAL(sort)}, {LNILKEY, LNILVAL}}; -LUALIB_API int luaopen_table (lua_State *L) { - LREGISTER(L, LUA_TABLIBNAME, tab_funcs); -} +LUALIB_API int luaopen_table(lua_State *L) { LREGISTER(L, LUA_TABLIBNAME, tab_funcs); } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/ltm.c b/LuaNode_Esp32/LuaNode32/components/lua/ltm.c index bdbf4b9..b5c4f7c 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/ltm.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/ltm.c @@ -4,81 +4,77 @@ ** See Copyright Notice in lua.h */ - #define ltm_c #define LUA_CORE #define LUAC_CROSS_FILE -#include "lua.h" +#include "ltm.h" + #include #include "lobject.h" +#include "lrotable.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" -#include "ltm.h" -#include "lrotable.h" - - - -const char *const luaT_typenames[] = { - "nil", "boolean", "romtable", "lightfunction", "userdata", "number", - "string", "table", "function", "userdata", "thread", - "proto", "upval" -}; +#include "lua.h" +const char *const luaT_typenames[] = {"nil", "boolean", "romtable", "lightfunction", "userdata", "number", "string", + "table", "function", "userdata", "thread", "proto", "upval"}; -void luaT_init (lua_State *L) { - static const char *const luaT_eventname[] = { /* ORDER TM */ - "__index", "__newindex", - "__gc", "__mode", "__eq", - "__add", "__sub", "__mul", "__div", "__mod", - "__pow", "__unm", "__len", "__lt", "__le", - "__concat", "__call" - }; - int i; - for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); - luaS_fix(G(L)->tmname[i]); /* never collect these names */ - } +void luaT_init(lua_State *L) +{ + static const char *const luaT_eventname[] = {/* ORDER TM */ + "__index", "__newindex", "__gc", "__mode", "__eq", "__add", + "__sub", "__mul", "__div", "__mod", "__pow", "__unm", + "__len", "__lt", "__le", "__concat", "__call"}; + int i; + for (i = 0; i < TM_N; i++) + { + G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } } - /* ** function to be used with macro "fasttm": optimized for absence of ** tag methods */ -const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { - const TValue *tm = luaR_isrotable(events) ? luaH_getstr_ro(events, ename) : luaH_getstr(events, ename); - lua_assert(event <= TM_EQ); - if (ttisnil(tm)) { /* no tag method? */ - if (!luaR_isrotable(events)) - events->flags |= cast_byte(1u<flags |= cast_byte(1u << event); /* cache this fact */ + return NULL; + } + else + return tm; } - -const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { - Table *mt; - switch (ttype(o)) { - case LUA_TTABLE: - mt = hvalue(o)->metatable; - break; - case LUA_TROTABLE: - mt = (Table*)luaR_getmeta(rvalue(o)); - break; - case LUA_TUSERDATA: - mt = uvalue(o)->metatable; - break; - default: - mt = G(L)->mt[ttype(o)]; - } - if (!mt) - return luaO_nilobject; - else if (luaR_isrotable(mt)) - return luaH_getstr_ro(mt, G(L)->tmname[event]); - else - return luaH_getstr(mt, G(L)->tmname[event]); +const TValue *luaT_gettmbyobj(lua_State *L, const TValue *o, TMS event) +{ + Table *mt; + switch (ttype(o)) + { + case LUA_TTABLE: + mt = hvalue(o)->metatable; + break; + case LUA_TROTABLE: + mt = (Table *)luaR_getmeta(rvalue(o)); + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + if (!mt) + return luaO_nilobject; + else if (luaR_isrotable(mt)) + return luaH_getstr_ro(mt, G(L)->tmname[event]); + else + return luaH_getstr(mt, G(L)->tmname[event]); } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lua.c b/LuaNode_Esp32/LuaNode32/components/lua/lua.c index cbe435c..43bdf98 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lua.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lua.c @@ -4,22 +4,21 @@ ** See Copyright Notice in lua.h */ - #include #include + #include "c_stdlib.h" #include "c_string.h" #define lua_c -#include "lua.h" - #include "lauxlib.h" -#include "lualib.h" #include "legc.h" +#include "lua.h" +#include "lualib.h" #include "my_uart.h" -#include "rom/uart.h" #include "rom/ets_sys.h" +#include "rom/uart.h" char line_buffer[LUA_MAXINPUT]; @@ -31,20 +30,23 @@ extern RcvMsgBuff rcvMsgBuff; static const char *progname = LUA_PROGNAME; -static void lstop (lua_State *L, lua_Debug *ar) { - (void)ar; /* unused arg. */ - lua_sethook(L, NULL, 0, 0); - luaL_error(L, "interrupted!"); +static void lstop(lua_State *L, lua_Debug *ar) +{ + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); } -static void laction (int i) { - signal(i, SIG_DFL); /* if another SIGINT happens before lstop, - terminate process (default action) */ - lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +static void laction(int i) +{ + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); } -static void print_usage (void) { - fprintf(stderr, +static void print_usage(void) +{ + fprintf(stderr, "usage: %s [options] [script [args]].\n" "Available options are:\n" " -e stat execute string " LUA_QL("stat") "\n" @@ -56,162 +58,171 @@ static void print_usage (void) { " - execute stdin and stop handling options\n" , progname); - fflush(stderr); + fflush(stderr); } -//doit -void l_message (const char *pname, const char *msg) { - /*if (pname) fprintf(stderr, "%s: ", pname); - fprintf(stderr, "%s\n", msg); - fflush(stderr); - */ - if (pname) luai_writestringerror("%s: ", pname); - luai_writestringerror("%s\r\n", msg); +// doit +void l_message(const char *pname, const char *msg) +{ + /*if (pname) fprintf(stderr, "%s: ", pname); + fprintf(stderr, "%s\n", msg); + fflush(stderr); + */ + if (pname) + luai_writestringerror("%s: ", pname); + luai_writestringerror("%s\r\n", msg); } - -static int report (lua_State *L, int status) { - if (status && !lua_isnil(L, -1)) { - const char *msg = lua_tostring(L, -1); - if (msg == NULL) msg = "(error object is not a string)"; - l_message(progname, msg); - lua_pop(L, 1); - } - return status; +static int report(lua_State *L, int status) +{ + if (status && !lua_isnil(L, -1)) + { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) + msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; } - -static int traceback (lua_State *L) { - if (!lua_isstring(L, 1)) /* 'message' not a string? */ - return 1; /* keep it intact */ - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); - if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) { - lua_pop(L, 1); - return 1; - } - lua_getfield(L, -1, "traceback"); - if (!lua_isfunction(L, -1) && !lua_islightfunction(L, -1)) { - lua_pop(L, 2); +static int traceback(lua_State *L) +{ + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) + { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1) && !lua_islightfunction(L, -1)) + { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ return 1; - } - lua_pushvalue(L, 1); /* pass error message */ - lua_pushinteger(L, 2); /* skip this function and traceback */ - lua_call(L, 2, 1); /* call debug.traceback */ - return 1; -} - - -static int docall (lua_State *L, int narg, int clear) { - int status; - int base = lua_gettop(L) - narg; /* function index */ - lua_pushcfunction(L, traceback); /* push traceback function */ - lua_insert(L, base); /* put it under chunk and args */ - //signal(SIGINT, laction); - status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); - //signal(SIGINT, SIG_DFL); - lua_remove(L, base); /* remove traceback function */ - /* force a complete garbage collection in case of errors */ - if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); - return status; } - -static void print_version (void) { - +static int docall(lua_State *L, int narg, int clear) +{ + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + // signal(SIGINT, laction); + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + // signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) + lua_gc(L, LUA_GCCOLLECT, 0); + return status; } +static void print_version(void) {} -static int getargs (lua_State *L, char **argv, int n) { - int narg; - int i; - int argc = 0; - while (argv[argc]) argc++; /* count total number of arguments */ - narg = argc - (n + 1); /* number of arguments to the script */ - luaL_checkstack(L, narg + 3, "too many arguments to script"); - for (i=n+1; i < argc; i++) - lua_pushstring(L, argv[i]); - lua_createtable(L, narg, n + 1); - for (i=0; i < argc; i++) { - lua_pushstring(L, argv[i]); - lua_rawseti(L, -2, i - n); - } - return narg; +static int getargs(lua_State *L, char **argv, int n) +{ + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i = n + 1; i < argc; i++) lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i = 0; i < argc; i++) + { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; } - -static int dostring (lua_State *L, const char *s, const char *name) { - int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); - return report(L, status); +static int dostring(lua_State *L, const char *s, const char *name) +{ + int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + return report(L, status); } - -static int dolibrary (lua_State *L, const char *name) { - lua_getglobal(L, "require"); - lua_pushstring(L, name); - return report(L, docall(L, 1, 1)); +static int dolibrary(lua_State *L, const char *name) +{ + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, docall(L, 1, 1)); } - -static const char *get_prompt (lua_State *L, int firstline) { - const char *p; - lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); - p = lua_tostring(L, -1); - if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); - lua_pop(L, 1); /* remove global */ - return p; +static const char *get_prompt(lua_State *L, int firstline) +{ + const char *p; + lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) + p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; } - -static int incomplete (lua_State *L, int status) { - if (status == LUA_ERRSYNTAX) { - size_t lmsg; - const char *msg = lua_tolstring(L, -1, &lmsg); - const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); - if (strstr(msg, LUA_QL("")) == tp) { - lua_pop(L, 1); - return 1; +static int incomplete(lua_State *L, int status) +{ + if (status == LUA_ERRSYNTAX) + { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); + if (strstr(msg, LUA_QL("")) == tp) + { + lua_pop(L, 1); + return 1; + } } - } - return 0; /* else... */ + return 0; /* else... */ } - -static int pushline (lua_State *L, int firstline) { - char buffer[LUA_MAXINPUT]; - char *b = buffer; - size_t l; - const char *prmt = get_prompt(L, firstline); - if (lua_readline(L, b, prmt) == 0) - return 0; /* no input */ - l = strlen(b); - if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ - b[l-1] = '\0'; /* remove it */ - if (firstline && b[0] == '=') /* first line starts with `=' ? */ - lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ - else - lua_pushstring(L, b); - lua_freeline(L, b); - return 1; +static int pushline(lua_State *L, int firstline) +{ + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */ + b[l - 1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b + 1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; } - -static int loadline (lua_State *L) { - int status; - lua_settop(L, 0); - if (!pushline(L, 1)) - return -1; /* no input */ - for (;;) { /* repeat until gets a complete line */ - status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); - if (!incomplete(L, status)) break; /* cannot try to add lines? */ - if (!pushline(L, 0)) /* no more input? */ - return -1; - lua_pushliteral(L, "\n"); /* add a new line... */ - lua_insert(L, -2); /* ...between the two lines */ - lua_concat(L, 3); /* join them */ - } - lua_saveline(L, 1); - lua_remove(L, 1); /* remove line */ - return status; +static int loadline(lua_State *L) +{ + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) + { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) + break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; } #if 0 //doit @@ -289,133 +300,162 @@ static int handle_script (lua_State *L, char **argv, int n) { #endif /* check that argument has no extra characters at the end */ -#define notail(x) {if ((x)[2] != '\0') return -1;} - - -static int collectargs (char **argv, int *pi, int *pv, int *pe) { - int i; - for (i = 1; argv[i] != NULL; i++) { - if (argv[i][0] != '-') /* not an option? */ - return i; - switch (argv[i][1]) { /* option */ - case '-': - notail(argv[i]); - return (argv[i+1] != NULL ? i+1 : 0); - case '\0': - return i; - case 'i': - notail(argv[i]); - *pi = 1; /* go through */ - case 'v': - notail(argv[i]); - *pv = 1; - break; - case 'e': - *pe = 1; /* go through */ - case 'm': /* go through */ - case 'l': - if (argv[i][2] == '\0') { - i++; - if (argv[i] == NULL) return -1; +#define notail(x) \ + { \ + if ((x)[2] != '\0') \ + return -1; \ + } + +static int collectargs(char **argv, int *pi, int *pv, int *pe) +{ + int i; + for (i = 1; argv[i] != NULL; i++) + { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) + { /* option */ + case '-': + notail(argv[i]); + return (argv[i + 1] != NULL ? i + 1 : 0); + case '\0': + return i; + case 'i': + notail(argv[i]); + *pi = 1; /* go through */ + case 'v': + notail(argv[i]); + *pv = 1; + break; + case 'e': + *pe = 1; /* go through */ + case 'm': /* go through */ + case 'l': + if (argv[i][2] == '\0') + { + i++; + if (argv[i] == NULL) + return -1; + } + break; + default: + return -1; /* invalid option */ } - break; - default: return -1; /* invalid option */ } - } - return 0; + return 0; } - -static int runargs (lua_State *L, char **argv, int n) { - int i; - for (i = 1; i < n; i++) { - if (argv[i] == NULL) continue; - lua_assert(argv[i][0] == '-'); - switch (argv[i][1]) { /* option */ - case 'e': { - const char *chunk = argv[i] + 2; - if (*chunk == '\0') chunk = argv[++i]; - lua_assert(chunk != NULL); - if (dostring(L, chunk, "=(command line)") != 0) - return 1; - break; - } - case 'm': { - const char *limit = argv[i] + 2; - int memlimit=0; - if (*limit == '\0') limit = argv[++i]; - lua_assert(limit != NULL); - memlimit = atoi(limit); - lua_gc(L, LUA_GCSETMEMLIMIT, memlimit); - break; - } - case 'l': { - const char *filename = argv[i] + 2; - if (*filename == '\0') filename = argv[++i]; - lua_assert(filename != NULL); - if (dolibrary(L, filename)) - return 1; /* stop if file fails */ - break; - } - default: break; +static int runargs(lua_State *L, char **argv, int n) +{ + int i; + for (i = 1; i < n; i++) + { + if (argv[i] == NULL) + continue; + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) + { /* option */ + case 'e': + { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') + chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != 0) + return 1; + break; + } + case 'm': + { + const char *limit = argv[i] + 2; + int memlimit = 0; + if (*limit == '\0') + limit = argv[++i]; + lua_assert(limit != NULL); + memlimit = atoi(limit); + lua_gc(L, LUA_GCSETMEMLIMIT, memlimit); + break; + } + case 'l': + { + const char *filename = argv[i] + 2; + if (*filename == '\0') + filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename)) + return 1; /* stop if file fails */ + break; + } + default: + break; + } } - } - return 0; + return 0; } -static int dofsfile (lua_State *L, const char *name) { - int status = luaL_loadfsfile(L, name) || docall(L, 0, 1); - return report(L, status); +static int dofsfile(lua_State *L, const char *name) +{ + int status = luaL_loadfsfile(L, name) || docall(L, 0, 1); + return report(L, status); } -static int handle_luainit (lua_State *L) { - const char *init = c_getenv(LUA_INIT); - if (init == NULL) { - return 0; /* status OK */ - } else if (init[0] == '@') { +static int handle_luainit(lua_State *L) +{ + const char *init = c_getenv(LUA_INIT); + if (init == NULL) + { + return 0; /* status OK */ + } + else if (init[0] == '@') + { #if 0 return dofile(L, init+1); #else - return dofsfile(L, init+1); + return dofsfile(L, init + 1); #endif - } else { - return dostring(L, init, "=" LUA_INIT); - } + } + else + { + return dostring(L, init, "=" LUA_INIT); + } } - -struct Smain { - int argc; - char **argv; - int status; +struct Smain +{ + int argc; + char **argv; + int status; }; - -static int pmain (lua_State *L) { - struct Smain *s = (struct Smain *)lua_touserdata(L, 1); - char **argv = s->argv; - int script; - int has_i = 0, has_v = 0, has_e = 0; - globalL = L; - if (argv[0] && argv[0][0]) progname = argv[0]; - lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ - luaL_openlibs(L); /* open libraries */ - lua_gc(L, LUA_GCRESTART, 0); - s->status = handle_luainit(L); +static int pmain(lua_State *L) +{ + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + char **argv = s->argv; + int script; + int has_i = 0, has_v = 0, has_e = 0; + globalL = L; + if (argv[0] && argv[0][0]) + progname = argv[0]; + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + s->status = handle_luainit(L); #if 0 if (s->status != 0) return 0; #endif - script = collectargs(argv, &has_i, &has_v, &has_e); - if (script < 0) { /* invalid args? */ + script = collectargs(argv, &has_i, &has_v, &has_e); + if (script < 0) + { /* invalid args? */ #if 0 print_usage(); #endif - s->status = 1; - return 0; - } - //if (has_v) print_version(); - s->status = runargs(L, argv, (script > 0) ? script : s->argc); - if (s->status != 0) return 0; + s->status = 1; + return 0; + } + // if (has_v) print_version(); + s->status = runargs(L, argv, (script > 0) ? script : s->argc); + if (s->status != 0) + return 0; #if 0 if (script) s->status = handle_script(L, argv, script); @@ -430,184 +470,213 @@ static int pmain (lua_State *L) { else dofile(L, NULL); /* executes stdin as a file */ } #endif - return 0; + return 0; } -int do_luainit (void) { - lua_State *L = gLoad.L; - return dofsfile(L, "init.lua"); +int do_luainit(void) +{ + lua_State *L = gLoad.L; + return dofsfile(L, "init.lua"); } static void dojob(lua_Load *load); static bool readline(lua_Load *load); -void lua_handle_input (bool force) +void lua_handle_input(bool force) { - if (force || readline (&gLoad)) { - dojob (&gLoad); - } + if (force || readline(&gLoad)) + { + dojob(&gLoad); + } } -bool uart_getc(char *c){ +bool uart_getc(char *c) +{ RcvMsgBuff *pRxBuff = &rcvMsgBuff; - if(pRxBuff->pWritePos == pRxBuff->pReadPos){ // empty + if (pRxBuff->pWritePos == pRxBuff->pReadPos) + { // empty return false; } - //ets_intr_lock(); + // ets_intr_lock(); *c = (char)*(pRxBuff->pReadPos); - if (pRxBuff->pReadPos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE)) { - pRxBuff->pReadPos = pRxBuff->pRcvMsgBuff ; - } else { + if (pRxBuff->pReadPos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE)) + { + pRxBuff->pReadPos = pRxBuff->pRcvMsgBuff; + } + else + { pRxBuff->pReadPos++; } - //ets_intr_unlock(); + // ets_intr_unlock(); return true; } -static void dojob(lua_Load *load) { - size_t l; - int status; - char *b = load->line; - lua_State *L = load->L; - - const char *oldprogname = progname; - progname = NULL; +static void dojob(lua_Load *load) +{ + size_t l; + int status; + char *b = load->line; + lua_State *L = load->L; - do{ - if(load->done == 1){ - l = c_strlen(b); - if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ - b[l-1] = '\0'; /* remove it */ - if (load->firstline && b[0] == '=') { /* first line starts with `=' ? */ - lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ - } else { - lua_pushstring(L, b); - } - if(load->firstline != 1) { - lua_pushliteral(L, "\n"); /* add a new line... */ - lua_insert(L, -2); /* ...between the two lines */ - lua_concat(L, 3); /* join them */ - } - - status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); - if (!incomplete(L, status)) { /* cannot try to add lines? */ - lua_remove(L, 1); /* remove line */ - if (status == 0) { - status = docall(L, 0, 0); - } - report(L, status); - if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ - lua_getglobal(L, "print"); - lua_insert(L, 1); - if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) - l_message(progname, lua_pushfstring(L, - "error calling " LUA_QL("print") " (%s)", - lua_tostring(L, -1))); + const char *oldprogname = progname; + progname = NULL; + + do + { + if (load->done == 1) + { + l = c_strlen(b); + if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */ + b[l - 1] = '\0'; /* remove it */ + if (load->firstline && b[0] == '=') + { /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b + 1); /* change it to `return' */ + } + else + { + lua_pushstring(L, b); + } + if (load->firstline != 1) + { + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) + { /* cannot try to add lines? */ + lua_remove(L, 1); /* remove line */ + if (status == 0) + { + status = docall(L, 0, 0); + } + report(L, status); + if (status == 0 && lua_gettop(L) > 0) + { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != 0) + l_message(progname, + lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)", lua_tostring(L, -1))); + } + load->firstline = 1; + load->prmt = get_prompt(L, 1); + lua_settop(L, 0); + /* force a complete garbage collection in case of errors */ + if (status != 0) + lua_gc(L, LUA_GCCOLLECT, 0); + } + else + { + load->firstline = 0; + load->prmt = get_prompt(L, 0); + } + /*if (status) { + uart_sendStr(lua_tostring(L, -1)); + lua_pop(L, 1); + }*/ } - load->firstline = 1; - load->prmt = get_prompt(L, 1); - lua_settop(L, 0); - /* force a complete garbage collection in case of errors */ - if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); - } else { - load->firstline = 0; - load->prmt = get_prompt(L, 0); - } - /*if (status) { - uart_sendStr(lua_tostring(L, -1)); - lua_pop(L, 1); - }*/ - } - }while(0); - - load->done = 0; - load->line_position = 0; - memset(load->line, 0, load->len); - uart_sendStr(load->prmt); + } while (0); + + load->done = 0; + load->line_position = 0; + memset(load->line, 0, load->len); + uart_sendStr(load->prmt); } static char last_nl_char = '\0'; -static bool readline(lua_Load *load){ - int need_dojob = false; - char ch; - while (uart_getc(&ch)) { - char tmp_last_nl_char = last_nl_char; - // reset marker, will be finally set below when newline is processed - last_nl_char = '\0'; - - /* handle CR & LF characters - filters second char of LF&CR (\n\r) or CR&LF (\r\n) sequences */ - if ((ch == '\r' && tmp_last_nl_char == '\n') || // \n\r sequence -> skip \r - (ch == '\n' && tmp_last_nl_char == '\r')) // \r\n sequence -> skip \n +static bool readline(lua_Load *load) +{ + int need_dojob = false; + char ch; + while (uart_getc(&ch)) { - continue; - } - - if (ch == 0x7f || ch == 0x08) { - if (load->line_position > 0) { - uart_tx_one_char(0x08); - uart_tx_one_char(' '); - uart_tx_one_char(0x08); - load->line_position--; - } - line_buffer[load->line_position] = 0; - continue; - } - - /* end of line */ - if (ch == '\r' || ch == '\n') { - last_nl_char = ch; - line_buffer[load->line_position] = 0; - printf("\r\n"); - if (load->line_position == 0){ - /* Get a empty line, then go to get a new line */ - uart_sendStr(load->prmt); - } else { - load->done = 1; - need_dojob = true; - } - continue; - } - - uart_tx_one_char(ch); + char tmp_last_nl_char = last_nl_char; + // reset marker, will be finally set below when newline is processed + last_nl_char = '\0'; + + /* handle CR & LF characters + filters second char of LF&CR (\n\r) or CR&LF (\r\n) sequences */ + if ((ch == '\r' && tmp_last_nl_char == '\n') || // \n\r sequence -> skip \r + (ch == '\n' && tmp_last_nl_char == '\r')) // \r\n sequence -> skip \n + { + continue; + } + + if (ch == 0x7f || ch == 0x08) + { + if (load->line_position > 0) + { + uart_tx_one_char(0x08); + uart_tx_one_char(' '); + uart_tx_one_char(0x08); + load->line_position--; + } + line_buffer[load->line_position] = 0; + continue; + } - /* it's a large line, discard it */ - if ( load->line_position + 1 >= LUA_MAXINPUT ){ - load->line_position = 0; + /* end of line */ + if (ch == '\r' || ch == '\n') + { + last_nl_char = ch; + line_buffer[load->line_position] = 0; + printf("\r\n"); + if (load->line_position == 0) + { + /* Get a empty line, then go to get a new line */ + uart_sendStr(load->prmt); + } + else + { + load->done = 1; + need_dojob = true; + } + continue; + } + + uart_tx_one_char(ch); + + /* it's a large line, discard it */ + if (load->line_position + 1 >= LUA_MAXINPUT) + { + load->line_position = 0; + } + + line_buffer[load->line_position] = ch; + load->line_position++; } - - line_buffer[load->line_position] = ch; - load->line_position++; - } - return need_dojob; + return need_dojob; } -int lua_main (int argc, char **argv) { - lua_State *L = lua_open(); - if (L == NULL) { - printf("lua failed\n"); - return 1; - } +int lua_main(int argc, char **argv) +{ + lua_State *L = lua_open(); + if (L == NULL) + { + printf("lua failed\n"); + return 1; + } - //luaL_openlibs(L); + // luaL_openlibs(L); - int status; - struct Smain s; - s.argc = argc; - s.argv = argv; - status = lua_cpcall(L, &pmain, &s); - //report(L, status); - - gLoad.L = L; - gLoad.firstline = 1; - gLoad.done = 0; - gLoad.line = line_buffer; - gLoad.len = LUA_MAXINPUT; - gLoad.line_position = 0; - gLoad.prmt = get_prompt(L, 1); - - dojob(&gLoad); - - return 0; -} + int status; + struct Smain s; + s.argc = argc; + s.argv = argv; + status = lua_cpcall(L, &pmain, &s); + // report(L, status); + gLoad.L = L; + gLoad.firstline = 1; + gLoad.done = 0; + gLoad.line = line_buffer; + gLoad.len = LUA_MAXINPUT; + gLoad.line_position = 0; + gLoad.prmt = get_prompt(L, 1); + + dojob(&gLoad); + + return 0; +} diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lundump.c b/LuaNode_Esp32/LuaNode32/components/lua/lundump.c index 14ff1c3..3b3f575 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lundump.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lundump.c @@ -20,332 +20,379 @@ #include "lundump.h" #include "lzio.h" -typedef struct { - lua_State* L; - ZIO* Z; - Mbuffer* b; - const char* name; - int swap; - int numsize; - int toflt; - size_t total; +typedef struct +{ + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; + int swap; + int numsize; + int toflt; + size_t total; } LoadState; #ifdef LUAC_TRUST_BINARIES -#define IF(c,s) -#define error(S,s) +#define IF(c, s) +#define error(S, s) #else -#define IF(c,s) if (c) error(S,s) +#define IF(c, s) \ + if (c) \ + error(S, s) static void error(LoadState* S, const char* why) { - luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); - luaD_throw(S->L,LUA_ERRSYNTAX); + luaO_pushfstring(S->L, "%s: %s in precompiled chunk", S->name, why); + luaD_throw(S->L, LUA_ERRSYNTAX); } #endif -#define LoadByte(S) (lu_byte)LoadChar(S) -#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) -#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) +#define LoadByte(S) (lu_byte) LoadChar(S) +#define LoadVar(S, x) LoadMem(S, &x, 1, sizeof(x)) +#define LoadVector(S, b, n, size) LoadMem(S, b, n, size) static void LoadBlock(LoadState* S, void* b, size_t size) { - size_t r=luaZ_read(S->Z,b,size); - IF (r!=0, "unexpected end"); - S->total+=size; + size_t r = luaZ_read(S->Z, b, size); + IF(r != 0, "unexpected end"); + S->total += size; } -static void LoadMem (LoadState* S, void* b, int n, size_t size) +static void LoadMem(LoadState* S, void* b, int n, size_t size) { - LoadBlock(S,b,n*size); - if (S->swap && b) - { - char* p=(char*) b; - char c; - switch (size) + LoadBlock(S, b, n * size); + if (S->swap && b) { - case 1: - break; - case 2: - while (n--) - { - c=p[0]; p[0]=p[1]; p[1]=c; - p+=2; - } - break; - case 4: - while (n--) - { - c=p[0]; p[0]=p[3]; p[3]=c; - c=p[1]; p[1]=p[2]; p[2]=c; - p+=4; - } - break; - case 8: - while (n--) - { - c=p[0]; p[0]=p[7]; p[7]=c; - c=p[1]; p[1]=p[6]; p[6]=c; - c=p[2]; p[2]=p[5]; p[5]=c; - c=p[3]; p[3]=p[4]; p[4]=c; - p+=8; + char* p = (char*)b; + char c; + switch (size) + { + case 1: + break; + case 2: + while (n--) + { + c = p[0]; + p[0] = p[1]; + p[1] = c; + p += 2; + } + break; + case 4: + while (n--) + { + c = p[0]; + p[0] = p[3]; + p[3] = c; + c = p[1]; + p[1] = p[2]; + p[2] = c; + p += 4; + } + break; + case 8: + while (n--) + { + c = p[0]; + p[0] = p[7]; + p[7] = c; + c = p[1]; + p[1] = p[6]; + p[6] = c; + c = p[2]; + p[2] = p[5]; + p[5] = c; + c = p[3]; + p[3] = p[4]; + p[4] = c; + p += 8; + } + break; + default: + IF(1, "bad size"); + break; } - break; - default: - IF(1, "bad size"); - break; } - } } static int LoadChar(LoadState* S) { - char x; - LoadVar(S,x); - return x; + char x; + LoadVar(S, x); + return x; } static void Align4(LoadState* S) { - while(S->total&3) - LoadChar(S); + while (S->total & 3) LoadChar(S); } static int LoadInt(LoadState* S) { - int x; - LoadVar(S,x); - IF (x<0, "bad integer"); - return x; + int x; + LoadVar(S, x); + IF(x < 0, "bad integer"); + return x; } static lua_Number LoadNumber(LoadState* S) { - lua_Number x; - if(S->toflt) - { - switch(S->numsize) - { - case 1: { - int8_t y; - LoadVar(S,y); - x = (lua_Number)y; - } break; - case 2: { - int16_t y; - LoadVar(S,y); - x = (lua_Number)y; - } break; - case 4: { - int32_t y; - LoadVar(S,y); - x = (lua_Number)y; - } break; - case 8: { - int64_t y; - LoadVar(S,y); - x = (lua_Number)y; - } break; - default: lua_assert(0); - } - } - else - { - LoadVar(S,x); /* should probably handle more cases for float here... */ - } - return x; + lua_Number x; + if (S->toflt) + { + switch (S->numsize) + { + case 1: + { + int8_t y; + LoadVar(S, y); + x = (lua_Number)y; + } + break; + case 2: + { + int16_t y; + LoadVar(S, y); + x = (lua_Number)y; + } + break; + case 4: + { + int32_t y; + LoadVar(S, y); + x = (lua_Number)y; + } + break; + case 8: + { + int64_t y; + LoadVar(S, y); + x = (lua_Number)y; + } + break; + default: + lua_assert(0); + } + } + else + { + LoadVar(S, x); /* should probably handle more cases for float here... */ + } + return x; } static TString* LoadString(LoadState* S) { - int32_t size; - LoadVar(S,size); - if (size==0) - return NULL; - else - { - char* s; - if (!luaZ_direct_mode(S->Z)) { - s = luaZ_openspace(S->L,S->b,size); - LoadBlock(S,s,size); - return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */ - } else { - s = (char*)luaZ_get_crt_address(S->Z); - LoadBlock(S,NULL,size); - return luaS_newrolstr(S->L,s,size-1); - } - } + int32_t size; + LoadVar(S, size); + if (size == 0) + return NULL; + else + { + char* s; + if (!luaZ_direct_mode(S->Z)) + { + s = luaZ_openspace(S->L, S->b, size); + LoadBlock(S, s, size); + return luaS_newlstr(S->L, s, size - 1); /* remove trailing zero */ + } + else + { + s = (char*)luaZ_get_crt_address(S->Z); + LoadBlock(S, NULL, size); + return luaS_newrolstr(S->L, s, size - 1); + } + } } static void LoadCode(LoadState* S, Proto* f) { - int n=LoadInt(S); - Align4(S); - if (!luaZ_direct_mode(S->Z)) { - f->code=luaM_newvector(S->L,n,Instruction); - LoadVector(S,f->code,n,sizeof(Instruction)); - } else { - f->code=(Instruction*)luaZ_get_crt_address(S->Z); - LoadVector(S,NULL,n,sizeof(Instruction)); - } - f->sizecode=n; + int n = LoadInt(S); + Align4(S); + if (!luaZ_direct_mode(S->Z)) + { + f->code = luaM_newvector(S->L, n, Instruction); + LoadVector(S, f->code, n, sizeof(Instruction)); + } + else + { + f->code = (Instruction*)luaZ_get_crt_address(S->Z); + LoadVector(S, NULL, n, sizeof(Instruction)); + } + f->sizecode = n; } static Proto* LoadFunction(LoadState* S, TString* p); static void LoadConstants(LoadState* S, Proto* f) { - int i,n; - n=LoadInt(S); - f->k=luaM_newvector(S->L,n,TValue); - f->sizek=n; - for (i=0; ik[i]); - for (i=0; ik[i]; - int t=LoadChar(S); - switch (t) - { - case LUA_TNIL: - setnilvalue(o); - break; - case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)!=0); - break; - case LUA_TNUMBER: - setnvalue(o,LoadNumber(S)); - break; - case LUA_TSTRING: - setsvalue2n(S->L,o,LoadString(S)); - break; - default: - error(S,"bad constant"); - break; - } - } - n=LoadInt(S); - f->p=luaM_newvector(S->L,n,Proto*); - f->sizep=n; - for (i=0; ip[i]=NULL; - for (i=0; ip[i]=LoadFunction(S,f->source); + int i, n; + n = LoadInt(S); + f->k = luaM_newvector(S->L, n, TValue); + f->sizek = n; + for (i = 0; i < n; i++) setnilvalue(&f->k[i]); + for (i = 0; i < n; i++) + { + TValue* o = &f->k[i]; + int t = LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o, LoadChar(S) != 0); + break; + case LUA_TNUMBER: + setnvalue(o, LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L, o, LoadString(S)); + break; + default: + error(S, "bad constant"); + break; + } + } + n = LoadInt(S); + f->p = luaM_newvector(S->L, n, Proto*); + f->sizep = n; + for (i = 0; i < n; i++) f->p[i] = NULL; + for (i = 0; i < n; i++) f->p[i] = LoadFunction(S, f->source); } static void LoadDebug(LoadState* S, Proto* f) { - int i,n; - n=LoadInt(S); - Align4(S); + int i, n; + n = LoadInt(S); + Align4(S); #ifdef LUA_OPTIMIZE_DEBUG - if(n) { - if (!luaZ_direct_mode(S->Z)) { - f->packedlineinfo=luaM_newvector(S->L,n,unsigned char); - LoadBlock(S,f->packedlineinfo,n); - } else { - f->packedlineinfo=(unsigned char*)luaZ_get_crt_address(S->Z); - LoadBlock(S,NULL,n); - } - } else { - f->packedlineinfo=NULL; - } + if (n) + { + if (!luaZ_direct_mode(S->Z)) + { + f->packedlineinfo = luaM_newvector(S->L, n, unsigned char); + LoadBlock(S, f->packedlineinfo, n); + } + else + { + f->packedlineinfo = (unsigned char*)luaZ_get_crt_address(S->Z); + LoadBlock(S, NULL, n); + } + } + else + { + f->packedlineinfo = NULL; + } #else - if (!luaZ_direct_mode(S->Z)) { - f->lineinfo=luaM_newvector(S->L,n,int); - LoadVector(S,f->lineinfo,n,sizeof(int)); - } else { - f->lineinfo=(int*)luaZ_get_crt_address(S->Z); - LoadVector(S,NULL,n,sizeof(int)); - } - f->sizelineinfo=n; - #endif - n=LoadInt(S); - f->locvars=luaM_newvector(S->L,n,LocVar); - f->sizelocvars=n; - for (i=0; ilocvars[i].varname=NULL; - for (i=0; ilocvars[i].varname=LoadString(S); - f->locvars[i].startpc=LoadInt(S); - f->locvars[i].endpc=LoadInt(S); - } - n=LoadInt(S); - f->upvalues=luaM_newvector(S->L,n,TString*); - f->sizeupvalues=n; - for (i=0; iupvalues[i]=NULL; - for (i=0; iupvalues[i]=LoadString(S); + if (!luaZ_direct_mode(S->Z)) + { + f->lineinfo = luaM_newvector(S->L, n, int); + LoadVector(S, f->lineinfo, n, sizeof(int)); + } + else + { + f->lineinfo = (int*)luaZ_get_crt_address(S->Z); + LoadVector(S, NULL, n, sizeof(int)); + } + f->sizelineinfo = n; +#endif + n = LoadInt(S); + f->locvars = luaM_newvector(S->L, n, LocVar); + f->sizelocvars = n; + for (i = 0; i < n; i++) f->locvars[i].varname = NULL; + for (i = 0; i < n; i++) + { + f->locvars[i].varname = LoadString(S); + f->locvars[i].startpc = LoadInt(S); + f->locvars[i].endpc = LoadInt(S); + } + n = LoadInt(S); + f->upvalues = luaM_newvector(S->L, n, TString*); + f->sizeupvalues = n; + for (i = 0; i < n; i++) f->upvalues[i] = NULL; + for (i = 0; i < n; i++) f->upvalues[i] = LoadString(S); } static Proto* LoadFunction(LoadState* S, TString* p) { - Proto* f; - if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); - f=luaF_newproto(S->L); - if (luaZ_direct_mode(S->Z)) proto_readonly(f); - setptvalue2s(S->L,S->L->top,f); incr_top(S->L); - f->source=LoadString(S); if (f->source==NULL) f->source=p; - f->linedefined=LoadInt(S); - f->lastlinedefined=LoadInt(S); - f->nups=LoadByte(S); - f->numparams=LoadByte(S); - f->is_vararg=LoadByte(S); - f->maxstacksize=LoadByte(S); - LoadCode(S,f); - LoadConstants(S,f); - LoadDebug(S,f); - IF (!luaG_checkcode(f), "bad code"); - S->L->top--; - S->L->nCcalls--; - return f; + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) + error(S, "code too deep"); + f = luaF_newproto(S->L); + if (luaZ_direct_mode(S->Z)) + proto_readonly(f); + setptvalue2s(S->L, S->L->top, f); + incr_top(S->L); + f->source = LoadString(S); + if (f->source == NULL) + f->source = p; + f->linedefined = LoadInt(S); + f->lastlinedefined = LoadInt(S); + f->nups = LoadByte(S); + f->numparams = LoadByte(S); + f->is_vararg = LoadByte(S); + f->maxstacksize = LoadByte(S); + LoadCode(S, f); + LoadConstants(S, f); + LoadDebug(S, f); + IF(!luaG_checkcode(f), "bad code"); + S->L->top--; + S->L->nCcalls--; + return f; } static void LoadHeader(LoadState* S) { - char h[LUAC_HEADERSIZE]; - char s[LUAC_HEADERSIZE]; - int intck = (((lua_Number)0.5)==0); /* 0=float, 1=int */ - luaU_header(h); - LoadBlock(S,s,LUAC_HEADERSIZE); - S->swap=(s[6]!=h[6]); s[6]=h[6]; /* Check if byte-swapping is needed */ - S->numsize=h[10]=s[10]; /* length of lua_Number */ - S->toflt=(s[11]>intck); /* check if conversion from int lua_Number to flt is needed */ - if(S->toflt) s[11]=h[11]; - IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); + char h[LUAC_HEADERSIZE]; + char s[LUAC_HEADERSIZE]; + int intck = (((lua_Number)0.5) == 0); /* 0=float, 1=int */ + luaU_header(h); + LoadBlock(S, s, LUAC_HEADERSIZE); + S->swap = (s[6] != h[6]); + s[6] = h[6]; /* Check if byte-swapping is needed */ + S->numsize = h[10] = s[10]; /* length of lua_Number */ + S->toflt = (s[11] > intck); /* check if conversion from int lua_Number to flt is needed */ + if (S->toflt) + s[11] = h[11]; + IF(memcmp(h, s, LUAC_HEADERSIZE) != 0, "bad header"); } /* ** load precompiled chunk */ -Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +Proto* luaU_undump(lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) { - LoadState S; - if (*name=='@' || *name=='=') - S.name=name+1; - else if (*name==LUA_SIGNATURE[0]) - S.name="binary string"; - else - S.name=name; - S.L=L; - S.Z=Z; - S.b=buff; - LoadHeader(&S); - S.total=0; - return LoadFunction(&S,luaS_newliteral(L,"=?")); + LoadState S; + if (*name == '@' || *name == '=') + S.name = name + 1; + else if (*name == LUA_SIGNATURE[0]) + S.name = "binary string"; + else + S.name = name; + S.L = L; + S.Z = Z; + S.b = buff; + LoadHeader(&S); + S.total = 0; + return LoadFunction(&S, luaS_newliteral(L, "=?")); } /* -* make header -*/ -void luaU_header (char* h) + * make header + */ +void luaU_header(char* h) { - int x=1; - memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); - h+=sizeof(LUA_SIGNATURE)-1; - *h++=(char)LUAC_VERSION; - *h++=(char)LUAC_FORMAT; - *h++=(char)*(char*)&x; /* endianness */ - *h++=(char)sizeof(int); - *h++=(char)sizeof(int32_t); - *h++=(char)sizeof(Instruction); - *h++=(char)sizeof(lua_Number); - *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ + int x = 1; + memcpy(h, LUA_SIGNATURE, sizeof(LUA_SIGNATURE) - 1); + h += sizeof(LUA_SIGNATURE) - 1; + *h++ = (char)LUAC_VERSION; + *h++ = (char)LUAC_FORMAT; + *h++ = (char)*(char*)&x; /* endianness */ + *h++ = (char)sizeof(int); + *h++ = (char)sizeof(int32_t); + *h++ = (char)sizeof(Instruction); + *h++ = (char)sizeof(lua_Number); + *h++ = (char)(((lua_Number)0.5) == 0); /* is lua_Number integral? */ } diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lvm.c b/LuaNode_Esp32/LuaNode32/components/lua/lvm.c index c7e11de..b77bfc3 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lvm.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lvm.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define lvm_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -20,809 +19,947 @@ #include "lgc.h" #include "lobject.h" #include "lopcodes.h" +#include "lrotable.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lvm.h" -#include "lrotable.h" - /* limit for table tag-method chains (to avoid loops) */ -#define MAXTAGLOOP 100 +#define MAXTAGLOOP 100 #if defined LUA_NUMBER_INTEGRAL -LUA_NUMBER luai_ipow(LUA_NUMBER a, LUA_NUMBER b) { - if (b < 0) - return 0; - else if (b == 0) - return 1; - else { - LUA_NUMBER c = 1; - for (;;) { - if (b & 1) - c *= a; - b = b >> 1; - if (b == 0) - return c; - a *= a; +LUA_NUMBER luai_ipow(LUA_NUMBER a, LUA_NUMBER b) +{ + if (b < 0) + return 0; + else if (b == 0) + return 1; + else + { + LUA_NUMBER c = 1; + for (;;) + { + if (b & 1) + c *= a; + b = b >> 1; + if (b == 0) + return c; + a *= a; + } } - } } #endif -const TValue *luaV_tonumber (const TValue *obj, TValue *n) { - lua_Number num; - if (ttisnumber(obj)) return obj; - if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { - setnvalue(n, num); - return n; - } - else - return NULL; +const TValue *luaV_tonumber(const TValue *obj, TValue *n) +{ + lua_Number num; + if (ttisnumber(obj)) + return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) + { + setnvalue(n, num); + return n; + } + else + return NULL; } - -int luaV_tostring (lua_State *L, StkId obj) { - if (!ttisnumber(obj)) - return 0; - else { - char s[LUAI_MAXNUMBER2STR]; - ptrdiff_t objr = savestack(L, obj); - lua_Number n = nvalue(obj); - lua_number2str(s, n); - setsvalue2s(L, restorestack(L, objr), luaS_new(L, s)); - return 1; - } +int luaV_tostring(lua_State *L, StkId obj) +{ + if (!ttisnumber(obj)) + return 0; + else + { + char s[LUAI_MAXNUMBER2STR]; + ptrdiff_t objr = savestack(L, obj); + lua_Number n = nvalue(obj); + lua_number2str(s, n); + setsvalue2s(L, restorestack(L, objr), luaS_new(L, s)); + return 1; + } } - -static void traceexec (lua_State *L, const Instruction *pc) { - lu_byte mask = L->hookmask; - const Instruction *oldpc = L->savedpc; - L->savedpc = pc; - if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { - resethookcount(L); - luaD_callhook(L, LUA_HOOKCOUNT, -1); - } - if (mask & LUA_MASKLINE) { - Proto *p = ci_func(L->ci)->l.p; - int npc = pcRel(pc, p); - int newline = getline(p, npc); - /* call linehook when enter a new function, when jump back (loop), - or when enter a new line */ - if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) - luaD_callhook(L, LUA_HOOKLINE, newline); - } +static void traceexec(lua_State *L, const Instruction *pc) +{ + lu_byte mask = L->hookmask; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) + { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + } + if (mask & LUA_MASKLINE) + { + Proto *p = ci_func(L->ci)->l.p; + int npc = pcRel(pc, p); + int newline = getline(p, npc); + /* call linehook when enter a new function, when jump back (loop), + or when enter a new line */ + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) + luaD_callhook(L, LUA_HOOKLINE, newline); + } } - -static void callTMres (lua_State *L, StkId res, const TValue *f, - const TValue *p1, const TValue *p2) { - ptrdiff_t result = savestack(L, res); - setobj2s(L, L->top, f); /* push function */ - setobj2s(L, L->top+1, p1); /* 1st argument */ - setobj2s(L, L->top+2, p2); /* 2nd argument */ - luaD_checkstack(L, 3); - L->top += 3; - luaD_call(L, L->top - 3, 1); - res = restorestack(L, result); - L->top--; - setobjs2s(L, res, L->top); +static void callTMres(lua_State *L, StkId res, const TValue *f, const TValue *p1, const TValue *p2) +{ + ptrdiff_t result = savestack(L, res); + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top + 1, p1); /* 1st argument */ + setobj2s(L, L->top + 2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobjs2s(L, res, L->top); } - - -static void callTM (lua_State *L, const TValue *f, const TValue *p1, - const TValue *p2, const TValue *p3) { - setobj2s(L, L->top, f); /* push function */ - setobj2s(L, L->top+1, p1); /* 1st argument */ - setobj2s(L, L->top+2, p2); /* 2nd argument */ - setobj2s(L, L->top+3, p3); /* 3th argument */ - luaD_checkstack(L, 4); - L->top += 4; - luaD_call(L, L->top - 4, 0); +static void callTM(lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3) +{ + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top + 1, p1); /* 1st argument */ + setobj2s(L, L->top + 2, p2); /* 2nd argument */ + setobj2s(L, L->top + 3, p3); /* 3th argument */ + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); } - -void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { - int loop; - TValue temp; - for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; - if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */ - void *h = ttistable(t) ? hvalue(t) : rvalue(t); - const TValue *res = ttistable(t) ? luaH_get((Table*)h, key) : luaH_get_ro(h, key); /* do a primitive get */ - if (!ttisnil(res) || /* result is no nil? */ - (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */ - setobj2s(L, val, res); - return; - } - /* else will try the tag method */ - } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) - luaG_typeerror(L, t, "index"); - if (ttisfunction(tm) || ttislightfunction(tm)) { - callTMres(L, val, tm, t, key); - return; +void luaV_gettable(lua_State *L, const TValue *t, TValue *key, StkId val) +{ + int loop; + TValue temp; + for (loop = 0; loop < MAXTAGLOOP; loop++) + { + const TValue *tm; + if (ttistable(t) || ttisrotable(t)) + { /* `t' is a table? */ + void *h = ttistable(t) ? hvalue(t) : rvalue(t); + const TValue *res = ttistable(t) ? luaH_get((Table *)h, key) : luaH_get_ro(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is no nil? */ + (tm = fasttm(L, ttistable(t) ? ((Table *)h)->metatable : (Table *)luaR_getmeta(h), TM_INDEX)) == NULL) + { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm) || ttislightfunction(tm)) + { + callTMres(L, val, tm, t, key); + return; + } + /* else repeat with `tm' */ + setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ + t = &temp; } - /* else repeat with `tm' */ - setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ - t = &temp; - } - luaG_runerror(L, "loop in gettable"); + luaG_runerror(L, "loop in gettable"); } - -void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { - int loop; - TValue temp; - setnilvalue(L->top); - L->top++; - fixedstack(L); - for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; - if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */ - void *h = ttistable(t) ? hvalue(t) : rvalue(t); - TValue *oldval = ttistable(t) ? luaH_set(L, (Table*)h, key) : NULL; /* do a primitive set */ - if ((oldval && !ttisnil(oldval)) || /* result is no nil? */ - (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */ - if(oldval) { - L->top--; - unfixedstack(L); - setobj2t(L, oldval, val); - ((Table *)h)->flags = 0; - luaC_barriert(L, (Table*)h, val); +void luaV_settable(lua_State *L, const TValue *t, TValue *key, StkId val) +{ + int loop; + TValue temp; + setnilvalue(L->top); + L->top++; + fixedstack(L); + for (loop = 0; loop < MAXTAGLOOP; loop++) + { + const TValue *tm; + if (ttistable(t) || ttisrotable(t)) + { /* `t' is a table? */ + void *h = ttistable(t) ? hvalue(t) : rvalue(t); + TValue *oldval = ttistable(t) ? luaH_set(L, (Table *)h, key) : NULL; /* do a primitive set */ + if ((oldval && !ttisnil(oldval)) || /* result is no nil? */ + (tm = fasttm(L, ttistable(t) ? ((Table *)h)->metatable : (Table *)luaR_getmeta(h), TM_NEWINDEX)) == + NULL) + { /* or no TM? */ + if (oldval) + { + L->top--; + unfixedstack(L); + setobj2t(L, oldval, val); + ((Table *)h)->flags = 0; + luaC_barriert(L, (Table *)h, val); + } + return; + } + /* else will try the tag method */ } - return; - } - /* else will try the tag method */ - } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) - luaG_typeerror(L, t, "index"); - if (ttisfunction(tm) || ttislightfunction(tm)) { - L->top--; - unfixedstack(L); - callTM(L, tm, t, key, val); - return; + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm) || ttislightfunction(tm)) + { + L->top--; + unfixedstack(L); + callTM(L, tm, t, key, val); + return; + } + /* else repeat with `tm' */ + setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ + t = &temp; + setobj2s(L, L->top - 1, t); /* need to protect value from EGC. */ } - /* else repeat with `tm' */ - setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ - t = &temp; - setobj2s(L, L->top-1, t); /* need to protect value from EGC. */ - } - luaG_runerror(L, "loop in settable"); + luaG_runerror(L, "loop in settable"); } - -static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, - StkId res, TMS event) { - const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ - if (ttisnil(tm)) - tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ - if (ttisnil(tm)) return 0; - callTMres(L, res, tm, p1, p2); - return 1; +static int call_binTM(lua_State *L, const TValue *p1, const TValue *p2, StkId res, TMS event) +{ + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) + return 0; + callTMres(L, res, tm, p1, p2); + return 1; } - -static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, - TMS event) { - const TValue *tm1 = fasttm(L, mt1, event); - const TValue *tm2; - if (tm1 == NULL) return NULL; /* no metamethod */ - if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ - tm2 = fasttm(L, mt2, event); - if (tm2 == NULL) return NULL; /* no metamethod */ - if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ - return tm1; - return NULL; +static const TValue *get_compTM(lua_State *L, Table *mt1, Table *mt2, TMS event) +{ + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) + return NULL; /* no metamethod */ + if (mt1 == mt2) + return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) + return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; } - -static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, - TMS event) { - const TValue *tm1 = luaT_gettmbyobj(L, p1, event); - const TValue *tm2; - if (ttisnil(tm1)) return -1; /* no metamethod? */ - tm2 = luaT_gettmbyobj(L, p2, event); - if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ - return -1; - callTMres(L, L->top, tm1, p1, p2); - return !l_isfalse(L->top); +static int call_orderTM(lua_State *L, const TValue *p1, const TValue *p2, TMS event) +{ + const TValue *tm1 = luaT_gettmbyobj(L, p1, event); + const TValue *tm2; + if (ttisnil(tm1)) + return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); } - -static int l_strcmp (const TString *ls, const TString *rs) { - const char *l = getstr(ls); - size_t ll = ls->tsv.len; - const char *r = getstr(rs); - size_t lr = rs->tsv.len; - for (;;) { - int temp = strcoll(l, r); - if (temp != 0) return temp; - else { /* strings are equal up to a `\0' */ - size_t len = strlen(l); /* index of first `\0' in both strings */ - if (len == lr) /* r is finished? */ - return (len == ll) ? 0 : 1; - else if (len == ll) /* l is finished? */ - return -1; /* l is smaller than r (because r is not finished) */ - /* both strings longer than `len'; go on comparing (after the `\0') */ - len++; - l += len; ll -= len; r += len; lr -= len; +static int l_strcmp(const TString *ls, const TString *rs) +{ + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) + { + int temp = strcoll(l, r); + if (temp != 0) + return temp; + else + { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') + */ + len++; + l += len; + ll -= len; + r += len; + lr -= len; + } } - } } - -int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { - int res; - if (ttype(l) != ttype(r)) +int luaV_lessthan(lua_State *L, const TValue *l, const TValue *r) +{ + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; return luaG_ordererror(L, l, r); - else if (ttisnumber(l)) - return luai_numlt(nvalue(l), nvalue(r)); - else if (ttisstring(l)) - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; - else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) - return res; - return luaG_ordererror(L, l, r); } - -static int lessequal (lua_State *L, const TValue *l, const TValue *r) { - int res; - if (ttype(l) != ttype(r)) +static int lessequal(lua_State *L, const TValue *l, const TValue *r) +{ + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; return luaG_ordererror(L, l, r); - else if (ttisnumber(l)) - return luai_numle(nvalue(l), nvalue(r)); - else if (ttisstring(l)) - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; - else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ - return res; - else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ - return !res; - return luaG_ordererror(L, l, r); } - -int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { - const TValue *tm; - lua_assert(ttype(t1) == ttype(t2)); - switch (ttype(t1)) { - case LUA_TNIL: return 1; - case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); - case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ - case LUA_TLIGHTUSERDATA: - case LUA_TROTABLE: - case LUA_TLIGHTFUNCTION: - return pvalue(t1) == pvalue(t2); - case LUA_TUSERDATA: { - if (uvalue(t1) == uvalue(t2)) return 1; - tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, - TM_EQ); - break; /* will try TM */ - } - case LUA_TTABLE: { - if (hvalue(t1) == hvalue(t2)) return 1; - tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); - break; /* will try TM */ +int luaV_equalval(lua_State *L, const TValue *t1, const TValue *t2) +{ + const TValue *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) + { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + case LUA_TROTABLE: + case LUA_TLIGHTFUNCTION: + return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: + { + if (uvalue(t1) == uvalue(t2)) + return 1; + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: + { + if (hvalue(t1) == hvalue(t2)) + return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: + return gcvalue(t1) == gcvalue(t2); } - default: return gcvalue(t1) == gcvalue(t2); - } - if (tm == NULL) return 0; /* no TM? */ - callTMres(L, L->top, tm, t1, t2); /* call TM */ - return !l_isfalse(L->top); + if (tm == NULL) + return 0; /* no TM? */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); } - -void luaV_concat (lua_State *L, int total, int last) { - lu_mem max_sizet = MAX_SIZET; - if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit; - do { - /* Any call which does a memory allocation may trim the stack, - invalidating top unless the stack is fixed duri ng the allocation */ - StkId top = L->base + last + 1; - fixedstack(L); - int n = 2; /* number of elements handled in this pass (at least 2) */ - if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { - unfixedstack(L); - if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) { - /* restore 'top' pointer, since stack might have been reallocted */ - top = L->base + last + 1; - luaG_concaterror(L, top-2, top-1); - } - } else if (tsvalue(top-1)->len == 0) { /* second op is empty? */ - (void)tostring(L, top - 2); /* result is first op (as string) */ - } else { - /* at least two string values; get as many as possible */ - size_t tl = tsvalue(top-1)->len; - char *buffer; - int i; - /* collect total length */ - for (n = 1; n < total && tostring(L, top-n-1); n++) { - size_t l = tsvalue(top-n-1)->len; - if (l >= max_sizet - tl) luaG_runerror(L, "string length overflow"); - tl += l; - } - G(L)->buff.n = tl; - buffer = luaZ_openspace(L, &G(L)->buff, tl); - tl = 0; - for (i=n; i>0; i--) { /* concat all strings */ - size_t l = tsvalue(top-i)->len; - memcpy(buffer+tl, svalue(top-i), l); - tl += l; - } - setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); - luaZ_resetbuffer(&G(L)->buff); - } - total -= n-1; /* got `n' strings to create 1 new */ - last -= n-1; - unfixedstack(L); - } while (total > 1); /* repeat until only 1 result left */ +void luaV_concat(lua_State *L, int total, int last) +{ + lu_mem max_sizet = MAX_SIZET; + if (G(L)->memlimit < max_sizet) + max_sizet = G(L)->memlimit; + do + { + /* Any call which does a memory allocation may trim the stack, + invalidating top unless the stack is fixed duri ng the allocation */ + StkId top = L->base + last + 1; + fixedstack(L); + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top - 2) || ttisnumber(top - 2)) || !tostring(L, top - 1)) + { + unfixedstack(L); + if (!call_binTM(L, top - 2, top - 1, top - 2, TM_CONCAT)) + { + /* restore 'top' pointer, since stack might have been reallocted + */ + top = L->base + last + 1; + luaG_concaterror(L, top - 2, top - 1); + } + } + else if (tsvalue(top - 1)->len == 0) + { /* second op is empty? */ + (void)tostring(L, top - 2); /* result is first op (as string) */ + } + else + { + /* at least two string values; get as many as possible */ + size_t tl = tsvalue(top - 1)->len; + char *buffer; + int i; + /* collect total length */ + for (n = 1; n < total && tostring(L, top - n - 1); n++) + { + size_t l = tsvalue(top - n - 1)->len; + if (l >= max_sizet - tl) + luaG_runerror(L, "string length overflow"); + tl += l; + } + G(L)->buff.n = tl; + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i = n; i > 0; i--) + { /* concat all strings */ + size_t l = tsvalue(top - i)->len; + memcpy(buffer + tl, svalue(top - i), l); + tl += l; + } + setsvalue2s(L, top - n, luaS_newlstr(L, buffer, tl)); + luaZ_resetbuffer(&G(L)->buff); + } + total -= n - 1; /* got `n' strings to create 1 new */ + last -= n - 1; + unfixedstack(L); + } while (total > 1); /* repeat until only 1 result left */ } - -static void Arith (lua_State *L, StkId ra, const TValue *rb, - const TValue *rc, TMS op) { - TValue tempb, tempc; - const TValue *b, *c; - if ((b = luaV_tonumber(rb, &tempb)) != NULL && - (c = luaV_tonumber(rc, &tempc)) != NULL) { - lua_Number nb = nvalue(b), nc = nvalue(c); - switch (op) { - case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; - case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; - case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; - case TM_DIV: setnvalue(ra, luai_lnumdiv(nb, nc)); break; - case TM_MOD: setnvalue(ra, luai_lnummod(nb, nc)); break; - case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; - case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; - default: lua_assert(0); break; +static void Arith(lua_State *L, StkId ra, const TValue *rb, const TValue *rc, TMS op) +{ + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && (c = luaV_tonumber(rc, &tempc)) != NULL) + { + lua_Number nb = nvalue(b), nc = nvalue(c); + switch (op) + { + case TM_ADD: + setnvalue(ra, luai_numadd(nb, nc)); + break; + case TM_SUB: + setnvalue(ra, luai_numsub(nb, nc)); + break; + case TM_MUL: + setnvalue(ra, luai_nummul(nb, nc)); + break; + case TM_DIV: + setnvalue(ra, luai_lnumdiv(nb, nc)); + break; + case TM_MOD: + setnvalue(ra, luai_lnummod(nb, nc)); + break; + case TM_POW: + setnvalue(ra, luai_numpow(nb, nc)); + break; + case TM_UNM: + setnvalue(ra, luai_numunm(nb)); + break; + default: + lua_assert(0); + break; + } } - } - else { - ptrdiff_t br = savestack(L, rb); - ptrdiff_t cr = savestack(L, rc); - if (!call_binTM(L, rb, rc, ra, op)) { - luaG_aritherror(L, restorestack(L, br), restorestack(L, cr)); + else + { + ptrdiff_t br = savestack(L, rb); + ptrdiff_t cr = savestack(L, rc); + if (!call_binTM(L, rb, rc, ra, op)) + { + luaG_aritherror(L, restorestack(L, br), restorestack(L, cr)); + } } - } } - - /* ** some macros for common tasks in `luaV_execute' */ -#define runtime_check(L, c) { if (!(c)) break; } +#define runtime_check(L, c) \ + { \ + if (!(c)) \ + break; \ + } -#define RA(i) (base+GETARG_A(i)) +#define RA(i) (base + GETARG_A(i)) /* to be used after possible stack reallocation */ -#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) -#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) -#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ - ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) -#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ - ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) -#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) - - -#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} - - -#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } - - -#define arith_op(op,tm) { \ - TValue *rb = RKB(i); \ - TValue *rc = RKC(i); \ - if (ttisnumber(rb) && ttisnumber(rc)) { \ - lua_Number nb = nvalue(rb), nc = nvalue(rc); \ - setnvalue(ra, op(nb, nc)); \ - } \ - else \ - Protect(Arith(L, ra, rb, rc, tm)); \ - } - +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base + GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base + GETARG_C(i)) +#define RKB(i) \ + check_exp(getBMode(GET_OPCODE(i)) == OpArgK, ISK(GETARG_B(i)) ? k + INDEXK(GETARG_B(i)) : base + GETARG_B(i)) +#define RKC(i) \ + check_exp(getCMode(GET_OPCODE(i)) == OpArgK, ISK(GETARG_C(i)) ? k + INDEXK(GETARG_C(i)) : base + GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k + GETARG_Bx(i)) + +#define dojump(L, pc, i) \ + { \ + (pc) += (i); \ + luai_threadyield(L); \ + } +#define Protect(x) \ + { \ + L->savedpc = pc; \ + { \ + x; \ + }; \ + base = L->base; \ + } -void luaV_execute (lua_State *L, int nexeccalls) { - LClosure *cl; - StkId base; - TValue *k; - const Instruction *pc; - reentry: /* entry point */ - lua_assert(isLua(L->ci)); - pc = L->savedpc; - cl = &clvalue(L->ci->func)->l; - base = L->base; - k = cl->p->k; - /* main loop of interpreter */ - for (;;) { - const Instruction i = *pc++; - StkId ra; - if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && - (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { - traceexec(L, pc); - if (L->status == LUA_YIELD) { /* did hook yield? */ - L->savedpc = pc - 1; - return; - } - base = L->base; +#define arith_op(op, tm) \ + { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) \ + { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(nb, nc)); \ + } \ + else \ + Protect(Arith(L, ra, rb, rc, tm)); \ } - /* warning!! several calls may realloc the stack and invalidate `ra' */ - ra = RA(i); - lua_assert(base == L->base && L->base == L->ci->base); - lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); - lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); - switch (GET_OPCODE(i)) { - case OP_MOVE: { - setobjs2s(L, ra, RB(i)); - continue; - } - case OP_LOADK: { - setobj2s(L, ra, KBx(i)); - continue; - } - case OP_LOADBOOL: { - setbvalue(ra, GETARG_B(i)); - if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ - continue; - } - case OP_LOADNIL: { - TValue *rb = RB(i); - do { - setnilvalue(rb--); - } while (rb >= ra); - continue; - } - case OP_GETUPVAL: { - int b = GETARG_B(i); - setobj2s(L, ra, cl->upvals[b]->v); - continue; - } - case OP_GETGLOBAL: { - TValue g; - TValue *rb = KBx(i); - sethvalue(L, &g, cl->env); - lua_assert(ttisstring(rb)); - Protect(luaV_gettable(L, &g, rb, ra)); - continue; - } - case OP_GETTABLE: { - Protect(luaV_gettable(L, RB(i), RKC(i), ra)); - continue; - } - case OP_SETGLOBAL: { - TValue g; - sethvalue(L, &g, cl->env); - lua_assert(ttisstring(KBx(i))); - Protect(luaV_settable(L, &g, KBx(i), ra)); - continue; - } - case OP_SETUPVAL: { - UpVal *uv = cl->upvals[GETARG_B(i)]; - setobj(L, uv->v, ra); - luaC_barrier(L, uv, ra); - continue; - } - case OP_SETTABLE: { - Protect(luaV_settable(L, ra, RKB(i), RKC(i))); - continue; - } - case OP_NEWTABLE: { - int b = GETARG_B(i); - int c = GETARG_C(i); - Table *h; - Protect(h = luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); - sethvalue(L, RA(i), h); - Protect(luaC_checkGC(L)); - continue; - } - case OP_SELF: { - StkId rb = RB(i); - setobjs2s(L, ra+1, rb); - Protect(luaV_gettable(L, rb, RKC(i), ra)); - continue; - } - case OP_ADD: { - arith_op(luai_numadd, TM_ADD); - continue; - } - case OP_SUB: { - arith_op(luai_numsub, TM_SUB); - continue; - } - case OP_MUL: { - arith_op(luai_nummul, TM_MUL); - continue; - } - case OP_DIV: { - arith_op(luai_lnumdiv, TM_DIV); - continue; - } - case OP_MOD: { - arith_op(luai_lnummod, TM_MOD); - continue; - } - case OP_POW: { - arith_op(luai_numpow, TM_POW); - continue; - } - case OP_UNM: { - TValue *rb = RB(i); - if (ttisnumber(rb)) { - lua_Number nb = nvalue(rb); - setnvalue(ra, luai_numunm(nb)); - } - else { - Protect(Arith(L, ra, rb, rb, TM_UNM)); - } - continue; - } - case OP_NOT: { - int res = l_isfalse(RB(i)); /* next assignment may change this value */ - setbvalue(ra, res); - continue; - } - case OP_LEN: { - const TValue *rb = RB(i); - switch (ttype(rb)) { - case LUA_TTABLE: - case LUA_TROTABLE: { - setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb)))); - break; - } - case LUA_TSTRING: { - setnvalue(ra, cast_num(tsvalue(rb)->len)); - break; - } - default: { /* try metamethod */ - ptrdiff_t br = savestack(L, rb); - Protect( - if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) - luaG_typeerror(L, restorestack(L, br), "get length of"); - ) - } - } - continue; - } - case OP_CONCAT: { - int b = GETARG_B(i); - int c = GETARG_C(i); - Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); - setobjs2s(L, RA(i), base+b); - continue; - } - case OP_JMP: { - dojump(L, pc, GETARG_sBx(i)); - continue; - } - case OP_EQ: { - TValue *rb = RKB(i); - TValue *rc = RKC(i); - Protect( - if (equalobj(L, rb, rc) == GETARG_A(i)) - dojump(L, pc, GETARG_sBx(*pc)); - ) - pc++; - continue; - } - case OP_LT: { - Protect( - if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) - dojump(L, pc, GETARG_sBx(*pc)); - ) - pc++; - continue; - } - case OP_LE: { - Protect( - if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) - dojump(L, pc, GETARG_sBx(*pc)); - ) - pc++; - continue; - } - case OP_TEST: { - if (l_isfalse(ra) != GETARG_C(i)) - dojump(L, pc, GETARG_sBx(*pc)); - pc++; - continue; - } - case OP_TESTSET: { - TValue *rb = RB(i); - if (l_isfalse(rb) != GETARG_C(i)) { - setobjs2s(L, ra, rb); - dojump(L, pc, GETARG_sBx(*pc)); - } - pc++; - continue; - } - case OP_CALL: { - int b = GETARG_B(i); - int nresults = GETARG_C(i) - 1; - if (b != 0) L->top = ra+b; /* else previous instruction set top */ - L->savedpc = pc; - switch (luaD_precall(L, ra, nresults)) { - case PCRLUA: { - nexeccalls++; - goto reentry; /* restart luaV_execute over new Lua function */ - } - case PCRC: { - /* it was a C function (`precall' called it); adjust results */ - if (nresults >= 0) L->top = L->ci->top; - base = L->base; - continue; - } - default: { - return; /* yield */ - } - } - } - case OP_TAILCALL: { - int b = GETARG_B(i); - if (b != 0) L->top = ra+b; /* else previous instruction set top */ - L->savedpc = pc; - lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); - switch (luaD_precall(L, ra, LUA_MULTRET)) { - case PCRLUA: { - /* tail call: put new frame in place of previous one */ - CallInfo *ci = L->ci - 1; /* previous frame */ - int aux; - StkId func = ci->func; - StkId pfunc = (ci+1)->func; /* previous function index */ - if (L->openupval) luaF_close(L, ci->base); - L->base = ci->base = ci->func + ((ci+1)->base - pfunc); - for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ - setobjs2s(L, func+aux, pfunc+aux); - ci->top = L->top = func+aux; /* correct top */ - lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); - ci->savedpc = L->savedpc; - ci->tailcalls++; /* one more call lost */ - L->ci--; /* remove new frame */ - goto reentry; - } - case PCRC: { /* it was a C function (`precall' called it) */ + +void luaV_execute(lua_State *L, int nexeccalls) +{ + LClosure *cl; + StkId base; + TValue *k; + const Instruction *pc; +reentry: /* entry point */ + lua_assert(isLua(L->ci)); + pc = L->savedpc; + cl = &clvalue(L->ci->func)->l; + base = L->base; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) + { + const Instruction i = *pc++; + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) + { + traceexec(L, pc); + if (L->status == LUA_YIELD) + { /* did hook yield? */ + L->savedpc = pc - 1; + return; + } base = L->base; - continue; - } - default: { - return; /* yield */ - } - } - } - case OP_RETURN: { - int b = GETARG_B(i); - if (b != 0) L->top = ra+b-1; - if (L->openupval) luaF_close(L, base); - L->savedpc = pc; - b = luaD_poscall(L, ra); - if (--nexeccalls == 0) /* was previous function running `here'? */ - return; /* no: return */ - else { /* yes: continue its execution */ - if (b) L->top = L->ci->top; - lua_assert(isLua(L->ci)); - lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); - goto reentry; - } - } - case OP_FORLOOP: { - lua_Number step = nvalue(ra+2); - lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ - lua_Number limit = nvalue(ra+1); - if (luai_numlt(0, step) ? luai_numle(idx, limit) - : luai_numle(limit, idx)) { - dojump(L, pc, GETARG_sBx(i)); /* jump back */ - setnvalue(ra, idx); /* update internal index... */ - setnvalue(ra+3, idx); /* ...and external index */ } - continue; - } - case OP_FORPREP: { - const TValue *init = ra; - const TValue *plimit = ra+1; - const TValue *pstep = ra+2; - L->savedpc = pc; /* next steps may throw errors */ - if (!tonumber(init, ra)) - luaG_runerror(L, LUA_QL("for") " initial value must be a number"); - else if (!tonumber(plimit, ra+1)) - luaG_runerror(L, LUA_QL("for") " limit must be a number"); - else if (!tonumber(pstep, ra+2)) - luaG_runerror(L, LUA_QL("for") " step must be a number"); - setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); - dojump(L, pc, GETARG_sBx(i)); - continue; - } - case OP_TFORLOOP: { - StkId cb = ra + 3; /* call base */ - setobjs2s(L, cb+2, ra+2); - setobjs2s(L, cb+1, ra+1); - setobjs2s(L, cb, ra); - L->top = cb+3; /* func. + 2 args (state and index) */ - Protect(luaD_call(L, cb, GETARG_C(i))); - L->top = L->ci->top; - cb = RA(i) + 3; /* previous call may change the stack */ - if (!ttisnil(cb)) { /* continue loop? */ - setobjs2s(L, cb-1, cb); /* save control variable */ - dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + /* warning!! several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == L->base && L->base == L->ci->base); + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); + switch (GET_OPCODE(i)) + { + case OP_MOVE: + { + setobjs2s(L, ra, RB(i)); + continue; + } + case OP_LOADK: + { + setobj2s(L, ra, KBx(i)); + continue; + } + case OP_LOADBOOL: + { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) + pc++; /* skip next instruction (if C) */ + continue; + } + case OP_LOADNIL: + { + TValue *rb = RB(i); + do + { + setnilvalue(rb--); + } while (rb >= ra); + continue; + } + case OP_GETUPVAL: + { + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + continue; + } + case OP_GETGLOBAL: + { + TValue g; + TValue *rb = KBx(i); + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(rb)); + Protect(luaV_gettable(L, &g, rb, ra)); + continue; + } + case OP_GETTABLE: + { + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + continue; + } + case OP_SETGLOBAL: + { + TValue g; + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(KBx(i))); + Protect(luaV_settable(L, &g, KBx(i), ra)); + continue; + } + case OP_SETUPVAL: + { + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + continue; + } + case OP_SETTABLE: + { + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + continue; + } + case OP_NEWTABLE: + { + int b = GETARG_B(i); + int c = GETARG_C(i); + Table *h; + Protect(h = luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); + sethvalue(L, RA(i), h); + Protect(luaC_checkGC(L)); + continue; + } + case OP_SELF: + { + StkId rb = RB(i); + setobjs2s(L, ra + 1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + continue; + } + case OP_ADD: + { + arith_op(luai_numadd, TM_ADD); + continue; + } + case OP_SUB: + { + arith_op(luai_numsub, TM_SUB); + continue; + } + case OP_MUL: + { + arith_op(luai_nummul, TM_MUL); + continue; + } + case OP_DIV: + { + arith_op(luai_lnumdiv, TM_DIV); + continue; + } + case OP_MOD: + { + arith_op(luai_lnummod, TM_MOD); + continue; + } + case OP_POW: + { + arith_op(luai_numpow, TM_POW); + continue; + } + case OP_UNM: + { + TValue *rb = RB(i); + if (ttisnumber(rb)) + { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); + } + else + { + Protect(Arith(L, ra, rb, rb, TM_UNM)); + } + continue; + } + case OP_NOT: + { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + continue; + } + case OP_LEN: + { + const TValue *rb = RB(i); + switch (ttype(rb)) + { + case LUA_TTABLE: + case LUA_TROTABLE: + { + setnvalue(ra, + ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb)))); + break; + } + case LUA_TSTRING: + { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + break; + } + default: + { /* try metamethod */ + ptrdiff_t br = savestack(L, rb); + Protect(if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) + luaG_typeerror(L, restorestack(L, br), "get length of");) + } + } + continue; + } + case OP_CONCAT: + { + int b = GETARG_B(i); + int c = GETARG_C(i); + Protect(luaV_concat(L, c - b + 1, c); luaC_checkGC(L)); + setobjs2s(L, RA(i), base + b); + continue; + } + case OP_JMP: + { + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_EQ: + { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect(if (equalobj(L, rb, rc) == GETARG_A(i)) dojump(L, pc, GETARG_sBx(*pc));) pc++; + continue; + } + case OP_LT: + { + Protect(if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) dojump(L, pc, GETARG_sBx(*pc));) pc++; + continue; + } + case OP_LE: + { + Protect(if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) dojump(L, pc, GETARG_sBx(*pc));) pc++; + continue; + } + case OP_TEST: + { + if (l_isfalse(ra) != GETARG_C(i)) + dojump(L, pc, GETARG_sBx(*pc)); + pc++; + continue; + } + case OP_TESTSET: + { + TValue *rb = RB(i); + if (l_isfalse(rb) != GETARG_C(i)) + { + setobjs2s(L, ra, rb); + dojump(L, pc, GETARG_sBx(*pc)); + } + pc++; + continue; + } + case OP_CALL: + { + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) + L->top = ra + b; /* else previous instruction set top */ + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) + { + case PCRLUA: + { + nexeccalls++; + goto reentry; /* restart luaV_execute over new Lua + function */ + } + case PCRC: + { + /* it was a C function (`precall' called it); adjust + * results */ + if (nresults >= 0) + L->top = L->ci->top; + base = L->base; + continue; + } + default: + { + return; /* yield */ + } + } + } + case OP_TAILCALL: + { + int b = GETARG_B(i); + if (b != 0) + L->top = ra + b; /* else previous instruction set top */ + L->savedpc = pc; + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + switch (luaD_precall(L, ra, LUA_MULTRET)) + { + case PCRLUA: + { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci + 1)->func; /* previous function index */ + if (L->openupval) + luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci + 1)->base - pfunc); + for (aux = 0; pfunc + aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func + aux, pfunc + aux); + ci->top = L->top = func + aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto reentry; + } + case PCRC: + { /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: + { + return; /* yield */ + } + } + } + case OP_RETURN: + { + int b = GETARG_B(i); + if (b != 0) + L->top = ra + b - 1; + if (L->openupval) + luaF_close(L, base); + L->savedpc = pc; + b = luaD_poscall(L, ra); + if (--nexeccalls == 0) /* was previous function running `here'? */ + return; /* no: return */ + else + { /* yes: continue its execution */ + if (b) + L->top = L->ci->top; + lua_assert(isLua(L->ci)); + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); + goto reentry; + } + } + case OP_FORLOOP: + { + lua_Number step = nvalue(ra + 2); + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra + 1); + if (luai_numlt(0, step) ? luai_numle(idx, limit) : luai_numle(limit, idx)) + { + dojump(L, pc, GETARG_sBx(i)); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra + 3, idx); /* ...and external index */ + } + continue; + } + case OP_FORPREP: + { + const TValue *init = ra; + const TValue *plimit = ra + 1; + const TValue *pstep = ra + 2; + L->savedpc = pc; /* next steps may throw errors */ + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra + 1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra + 2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_TFORLOOP: + { + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb + 2, ra + 2); + setobjs2s(L, cb + 1, ra + 1); + setobjs2s(L, cb, ra); + L->top = cb + 3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i))); + L->top = L->ci->top; + cb = RA(i) + 3; /* previous call may change the stack */ + if (!ttisnil(cb)) + { /* continue loop? */ + setobjs2s(L, cb - 1, cb); /* save control variable */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + } + pc++; + continue; + } + case OP_SETLIST: + { + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + fixedstack(L); + if (n == 0) + { + n = cast_int(L->top - ra) - 1; + } + if (c == 0) + c = cast_int(*pc++); + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c - 1) * LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-alloc it at once */ + for (; n > 0; n--) + { + TValue *val = ra + n; + setobj2t(L, luaH_setnum(L, h, last--), val); + luaC_barriert(L, h, val); + } + L->top = L->ci->top; + unfixedstack(L); + continue; + } + case OP_CLOSE: + { + luaF_close(L, ra); + continue; + } + case OP_CLOSURE: + { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + fixedstack(L); + ncl = luaF_newLclosure(L, nup, cl->env); + setclvalue(L, ra, ncl); + ncl->l.p = p; + for (j = 0; j < nup; j++, pc++) + { + if (GET_OPCODE(*pc) == OP_GETUPVAL) + ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else + { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + unfixedstack(L); + Protect(luaC_checkGC(L)); + continue; + } + case OP_VARARG: + { + int b = GETARG_B(i) - 1; + int j; + CallInfo *ci = L->ci; + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; + if (b == LUA_MULTRET) + { + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + b = n; + L->top = ra + n; + } + for (j = 0; j < b; j++) + { + if (j < n) + { + setobjs2s(L, ra + j, ci->base - n + j); + } + else + { + setnilvalue(ra + j); + } + } + continue; + } } - pc++; - continue; - } - case OP_SETLIST: { - int n = GETARG_B(i); - int c = GETARG_C(i); - int last; - Table *h; - fixedstack(L); - if (n == 0) { - n = cast_int(L->top - ra) - 1; - } - if (c == 0) c = cast_int(*pc++); - runtime_check(L, ttistable(ra)); - h = hvalue(ra); - last = ((c-1)*LFIELDS_PER_FLUSH) + n; - if (last > h->sizearray) /* needs more space? */ - luaH_resizearray(L, h, last); /* pre-alloc it at once */ - for (; n > 0; n--) { - TValue *val = ra+n; - setobj2t(L, luaH_setnum(L, h, last--), val); - luaC_barriert(L, h, val); - } - L->top = L->ci->top; - unfixedstack(L); - continue; - } - case OP_CLOSE: { - luaF_close(L, ra); - continue; - } - case OP_CLOSURE: { - Proto *p; - Closure *ncl; - int nup, j; - p = cl->p->p[GETARG_Bx(i)]; - nup = p->nups; - fixedstack(L); - ncl = luaF_newLclosure(L, nup, cl->env); - setclvalue(L, ra, ncl); - ncl->l.p = p; - for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; - else { - lua_assert(GET_OPCODE(*pc) == OP_MOVE); - ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); - } - } - unfixedstack(L); - Protect(luaC_checkGC(L)); - continue; - } - case OP_VARARG: { - int b = GETARG_B(i) - 1; - int j; - CallInfo *ci = L->ci; - int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; - if (b == LUA_MULTRET) { - Protect(luaD_checkstack(L, n)); - ra = RA(i); /* previous call may change the stack */ - b = n; - L->top = ra + n; - } - for (j = 0; j < b; j++) { - if (j < n) { - setobjs2s(L, ra + j, ci->base - n + j); - } - else { - setnilvalue(ra + j); - } - } - continue; - } } - } } - diff --git a/LuaNode_Esp32/LuaNode32/components/lua/lzio.c b/LuaNode_Esp32/LuaNode32/components/lua/lzio.c index d4df1f1..d5a27dd 100644 --- a/LuaNode_Esp32/LuaNode32/components/lua/lzio.c +++ b/LuaNode_Esp32/LuaNode32/components/lua/lzio.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #define lzio_c #define LUA_CORE #define LUAC_CROSS_FILE @@ -17,69 +16,74 @@ #include "lstate.h" #include "lzio.h" - -int luaZ_fill (ZIO *z) { - size_t size; - lua_State *L = z->L; - const char *buff; - lua_unlock(L); - buff = z->reader(L, z->data, &size); - lua_lock(L); - if (buff == NULL || size == 0) return EOZ; - z->n = size - 1; - z->p = buff; - return char2int(*(z->p++)); +int luaZ_fill(ZIO *z) +{ + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); } - -int luaZ_lookahead (ZIO *z) { - if (z->n == 0) { - if (luaZ_fill(z) == EOZ) - return EOZ; - else { - z->n++; /* luaZ_fill removed first byte; put back it */ - z->p--; +int luaZ_lookahead(ZIO *z) +{ + if (z->n == 0) + { + if (luaZ_fill(z) == EOZ) + return EOZ; + else + { + z->n++; /* luaZ_fill removed first byte; put back it */ + z->p--; + } } - } - return char2int(*z->p); + return char2int(*z->p); } - -void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { - z->L = L; - z->reader = reader; - z->data = data; - z->n = z->i = 0; - z->p = NULL; +void luaZ_init(lua_State *L, ZIO *z, lua_Reader reader, void *data) +{ + z->L = L; + z->reader = reader; + z->data = data; + z->n = z->i = 0; + z->p = NULL; } - /* --------------------------------------------------------------- read --- */ -size_t luaZ_read (ZIO *z, void *b, size_t n) { - while (n) { - size_t m; - if (luaZ_lookahead(z) == EOZ) - return n; /* return number of missing bytes */ - m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ - if (b) - memcpy(b, z->p, m); - z->n -= m; - z->i += m; - z->p += m; - if (b) - b = (char *)b + m; - n -= m; - } - return 0; +size_t luaZ_read(ZIO *z, void *b, size_t n) +{ + while (n) + { + size_t m; + if (luaZ_lookahead(z) == EOZ) + return n; /* return number of missing bytes */ + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + if (b) + memcpy(b, z->p, m); + z->n -= m; + z->i += m; + z->p += m; + if (b) + b = (char *)b + m; + n -= m; + } + return 0; } /* ------------------------------------------------------------------------ */ -char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { - if (n > buff->buffsize) { - if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; - luaZ_resizebuffer(L, buff, n); - } - return buff->buffer; +char *luaZ_openspace(lua_State *L, Mbuffer *buff, size_t n) +{ + if (n > buff->buffsize) + { + if (n < LUA_MINBUFFER) + n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; } - - diff --git a/LuaNode_Esp32/LuaNode32/components/modules/file.c b/LuaNode_Esp32/LuaNode32/components/modules/file.c index 2a36f86..84c794c 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/file.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/file.c @@ -1,127 +1,133 @@ // Module for interfacing with file system -#include "modules.h" +#include "c_string.h" +#include "c_types.h" +#include "flash_fs.h" #include "lauxlib.h" #include "lualib.h" +#include "modules.h" #include "platform.h" - -#include "c_types.h" -#include "flash_fs.h" -#include "c_string.h" #include "vfs.h" static volatile int file_fd = FS_OPEN_OK - 1; // Lua: open(filename, mode) -static int file_open( lua_State* L ) +static int file_open(lua_State *L) { - size_t len; - if(file_fd){ - vfs_close(file_fd); - file_fd = 0; - } - - const char *fname = luaL_checklstring( L, 1, &len ); - const char *basename = vfs_basename( fname ); - luaL_argcheck(L, strlen(basename) <= 32 && strlen(fname) == len, 1, "filename invalid"); - - const char *mode = luaL_optstring(L, 2, "r"); - - file_fd = vfs_open(fname, mode); - - if(!file_fd){ - lua_pushnil(L); - } else { - lua_pushboolean(L, 1); - } - return 1; + size_t len; + if (file_fd) + { + vfs_close(file_fd); + file_fd = 0; + } + + const char *fname = luaL_checklstring(L, 1, &len); + const char *basename = vfs_basename(fname); + luaL_argcheck(L, strlen(basename) <= 32 && strlen(fname) == len, 1, "filename invalid"); + + const char *mode = luaL_optstring(L, 2, "r"); + + file_fd = vfs_open(fname, mode); + + if (!file_fd) + { + lua_pushnil(L); + } + else + { + lua_pushboolean(L, 1); + } + return 1; } // Lua: close() -static int file_close( lua_State* L ) +static int file_close(lua_State *L) { - if(file_fd){ - vfs_close(file_fd); - file_fd = 0; - NODE_DBG("file close successfully\n"); - } - return 0; + if (file_fd) + { + vfs_close(file_fd); + file_fd = 0; + NODE_DBG("file close successfully\n"); + } + return 0; } // Lua: format() -static int file_format( lua_State* L ) +static int file_format(lua_State *L) { - file_close(L); - if( !vfs_format() ) - { - NODE_ERR( "\n*** ERROR ***: unable to format. FS might be compromised.\n" ); - NODE_ERR( "It is advised to re-flash the NodeMCU image.\n" ); - luaL_error(L, "Failed to format file system"); - } - else{ - NODE_ERR( "format done.\n" ); - } - return 0; + file_close(L); + if (!vfs_format()) + { + NODE_ERR("\n*** ERROR ***: unable to format. FS might be compromised.\n"); + NODE_ERR("It is advised to re-flash the NodeMCU image.\n"); + luaL_error(L, "Failed to format file system"); + } + else + { + NODE_ERR("format done.\n"); + } + return 0; } - // Lua: list() -static int file_list( lua_State* L ) +static int file_list(lua_State *L) { - vfs_dir *dir; - vfs_item *item; - - if ((dir = vfs_opendir(""))) { - lua_newtable( L ); - while ((item = vfs_readdir(dir))) { - lua_pushinteger(L, vfs_item_size(item)); - lua_setfield(L, -2, vfs_item_name(item)); - vfs_closeitem(item); + vfs_dir *dir; + vfs_item *item; + + if ((dir = vfs_opendir(""))) + { + lua_newtable(L); + while ((item = vfs_readdir(dir))) + { + lua_pushinteger(L, vfs_item_size(item)); + lua_setfield(L, -2, vfs_item_name(item)); + vfs_closeitem(item); + } + vfs_closedir(dir); + return 1; } - vfs_closedir(dir); - return 1; - } - return 0; + return 0; } -static int file_seek (lua_State *L) +static int file_seek(lua_State *L) { - static const int mode[] = {VFS_SEEK_SET, VFS_SEEK_CUR, VFS_SEEK_END}; - static const char *const modenames[] = {"set", "cur", "end", NULL}; - if(!file_fd) - return luaL_error(L, "open a file first"); - int op = luaL_checkoption(L, 1, "cur", modenames); - long offset = luaL_optlong(L, 2, 0); - op = vfs_lseek(file_fd, offset, mode[op]); - if (op < 0) - lua_pushnil(L); /* error */ - else - lua_pushinteger(L, vfs_tell(file_fd)); - return 1; + static const int mode[] = {VFS_SEEK_SET, VFS_SEEK_CUR, VFS_SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + if (!file_fd) + return luaL_error(L, "open a file first"); + int op = luaL_checkoption(L, 1, "cur", modenames); + long offset = luaL_optlong(L, 2, 0); + op = vfs_lseek(file_fd, offset, mode[op]); + if (op < 0) + lua_pushnil(L); /* error */ + else + lua_pushinteger(L, vfs_tell(file_fd)); + return 1; } // Lua: remove(filename) -static int file_remove( lua_State* L ) +static int file_remove(lua_State *L) { - size_t len; - const char *fname = luaL_checklstring( L, 1, &len ); - const char *basename = vfs_basename( fname ); - luaL_argcheck(L, strlen(basename) <= 32 && strlen(fname) == len, 1, "filename invalid"); - file_close(L); - vfs_remove((char *)fname); - return 0; + size_t len; + const char *fname = luaL_checklstring(L, 1, &len); + const char *basename = vfs_basename(fname); + luaL_argcheck(L, strlen(basename) <= 32 && strlen(fname) == len, 1, "filename invalid"); + file_close(L); + vfs_remove((char *)fname); + return 0; } // Lua: flush() -static int file_flush( lua_State* L ) +static int file_flush(lua_State *L) { - if(!file_fd) - return luaL_error(L, "open a file first"); - if(vfs_flush(file_fd) == 0) - lua_pushboolean(L, 1); - else - lua_pushnil(L); - return 1; + if (!file_fd) + return luaL_error(L, "open a file first"); + if (vfs_flush(file_fd) == 0) + lua_pushboolean(L, 1); + else + lua_pushnil(L); + return 1; } #if 0 // Lua: check() @@ -134,180 +140,185 @@ static int file_check( lua_State* L ) #endif // Lua: rename("oldname", "newname") -static int file_rename( lua_State* L ) +static int file_rename(lua_State *L) { - size_t len; - if(file_fd){ - vfs_close(file_fd); - file_fd = 0; - } - - const char *oldname = luaL_checklstring( L, 1, &len ); - const char *basename = vfs_basename( oldname ); - luaL_argcheck(L, strlen(basename) <= 32 && strlen(oldname) == len, 1, "filename invalid"); - - const char *newname = luaL_checklstring( L, 2, &len ); - basename = vfs_basename( newname ); - luaL_argcheck(L, strlen(basename) <= 32 && strlen(newname) == len, 2, "filename invalid"); - - if(0 <= vfs_rename( oldname, newname )){ - lua_pushboolean(L, 1); - } else { - lua_pushboolean(L, 0); - } - return 1; + size_t len; + if (file_fd) + { + vfs_close(file_fd); + file_fd = 0; + } + + const char *oldname = luaL_checklstring(L, 1, &len); + const char *basename = vfs_basename(oldname); + luaL_argcheck(L, strlen(basename) <= 32 && strlen(oldname) == len, 1, "filename invalid"); + + const char *newname = luaL_checklstring(L, 2, &len); + basename = vfs_basename(newname); + luaL_argcheck(L, strlen(basename) <= 32 && strlen(newname) == len, 2, "filename invalid"); + + if (0 <= vfs_rename(oldname, newname)) + { + lua_pushboolean(L, 1); + } + else + { + lua_pushboolean(L, 0); + } + return 1; } // Lua: fsinfo() -static int file_fsinfo( lua_State* L ) +static int file_fsinfo(lua_State *L) { - u32_t total, used; - if (vfs_fsinfo("", &total, &used)) { - return luaL_error(L, "file system failed"); - } - NODE_DBG("total: %d, used:%d\n", total, used); - if(total>0x7FFFFFFF || used>0x7FFFFFFF || used > total) - { - return luaL_error(L, "file system error"); - } - lua_pushinteger(L, total-used); - lua_pushinteger(L, used); - lua_pushinteger(L, total); - return 3; + u32_t total, used; + if (vfs_fsinfo("", &total, &used)) + { + return luaL_error(L, "file system failed"); + } + NODE_DBG("total: %d, used:%d\n", total, used); + if (total > 0x7FFFFFFF || used > 0x7FFFFFFF || used > total) + { + return luaL_error(L, "file system error"); + } + lua_pushinteger(L, total - used); + lua_pushinteger(L, used); + lua_pushinteger(L, total); + return 3; } // g_read() -static int file_g_read( lua_State* L, int n, int16_t end_char ) +static int file_g_read(lua_State *L, int n, int16_t end_char) { - if(n <= 0 || n > LUAL_BUFFERSIZE) - n = LUAL_BUFFERSIZE; - if(end_char < 0 || end_char >255) - end_char = EOF; - - luaL_Buffer b; - if(!file_fd) - return luaL_error(L, "open a file first"); - - luaL_buffinit(L, &b); - char *p = luaL_prepbuffer(&b); - int i; - - n = vfs_read(file_fd, p, n); - for (i = 0; i < n; ++i) - if (p[i] == end_char) + if (n <= 0 || n > LUAL_BUFFERSIZE) + n = LUAL_BUFFERSIZE; + if (end_char < 0 || end_char > 255) + end_char = EOF; + + luaL_Buffer b; + if (!file_fd) + return luaL_error(L, "open a file first"); + + luaL_buffinit(L, &b); + char *p = luaL_prepbuffer(&b); + int i; + + n = vfs_read(file_fd, p, n); + for (i = 0; i < n; ++i) + if (p[i] == end_char) + { + ++i; + break; + } + + if (i == 0) { - ++i; - break; + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ } - if(i==0){ - luaL_pushresult(&b); /* close buffer */ - return (lua_objlen(L, -1) > 0); /* check whether read something */ - } - - vfs_lseek(file_fd, -(n - i), VFS_SEEK_CUR); - luaL_addsize(&b, i); - luaL_pushresult(&b); /* close buffer */ - return 1; /* read at least an `eol' */ + vfs_lseek(file_fd, -(n - i), VFS_SEEK_CUR); + luaL_addsize(&b, i); + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ } // Lua: read() // file.read() will read all byte in file // file.read(10) will read 10 byte from file, or EOF is reached. -// file.read('q') will read until 'q' or EOF is reached. -static int file_read( lua_State* L ) +// file.read('q') will read until 'q' or EOF is reached. +static int file_read(lua_State *L) { - unsigned need_len = LUAL_BUFFERSIZE; - int16_t end_char = EOF; - size_t el; - if( lua_type( L, 1 ) == LUA_TNUMBER ) - { - need_len = ( unsigned )luaL_checkinteger( L, 1 ); - if( need_len > LUAL_BUFFERSIZE ){ - need_len = LUAL_BUFFERSIZE; + unsigned need_len = LUAL_BUFFERSIZE; + int16_t end_char = EOF; + size_t el; + if (lua_type(L, 1) == LUA_TNUMBER) + { + need_len = (unsigned)luaL_checkinteger(L, 1); + if (need_len > LUAL_BUFFERSIZE) + { + need_len = LUAL_BUFFERSIZE; + } } - } - else if(lua_isstring(L, 1)) - { - const char *end = luaL_checklstring( L, 1, &el ); - if(el!=1){ - return luaL_error( L, "wrong arg range" ); + else if (lua_isstring(L, 1)) + { + const char *end = luaL_checklstring(L, 1, &el); + if (el != 1) + { + return luaL_error(L, "wrong arg range"); + } + end_char = (int16_t)end[0]; } - end_char = (int16_t)end[0]; - } - return file_g_read(L, need_len, end_char); + return file_g_read(L, need_len, end_char); } // Lua: readline() -static int file_readline( lua_State* L ) -{ - return file_g_read(L, LUAL_BUFFERSIZE, '\n'); -} +static int file_readline(lua_State *L) { return file_g_read(L, LUAL_BUFFERSIZE, '\n'); } // Lua: write("string") -static int file_write( lua_State* L ) +static int file_write(lua_State *L) { - if(!file_fd) - return luaL_error(L, "open a file first"); - size_t l, rl; - const char *s = luaL_checklstring(L, 1, &l); - rl = vfs_write(file_fd, s, l); - if(rl==l) - lua_pushboolean(L, 1); - else - lua_pushnil(L); - return 1; + if (!file_fd) + return luaL_error(L, "open a file first"); + size_t l, rl; + const char *s = luaL_checklstring(L, 1, &l); + rl = vfs_write(file_fd, s, l); + if (rl == l) + lua_pushboolean(L, 1); + else + lua_pushnil(L); + return 1; } // Lua: writeline("string") -static int file_writeline( lua_State* L ) +static int file_writeline(lua_State *L) { - if(!file_fd) - return luaL_error(L, "open a file first"); - size_t l, rl; - const char *s = luaL_checklstring(L, 1, &l); - rl = vfs_write(file_fd, s, l); - if(rl==l){ - rl = vfs_write(file_fd, "\n", 1); - if(rl==1) - lua_pushboolean(L, 1); + if (!file_fd) + return luaL_error(L, "open a file first"); + size_t l, rl; + const char *s = luaL_checklstring(L, 1, &l); + rl = vfs_write(file_fd, s, l); + if (rl == l) + { + rl = vfs_write(file_fd, "\n", 1); + if (rl == 1) + lua_pushboolean(L, 1); + else + lua_pushnil(L); + } else - lua_pushnil(L); - } - else{ - lua_pushnil(L); - } - return 1; + { + lua_pushnil(L); + } + return 1; } // Module function map -const LUA_REG_TYPE file_map[] = { - { LSTRKEY( "list" ), LFUNCVAL( file_list ) }, - { LSTRKEY( "open" ), LFUNCVAL( file_open ) }, - { LSTRKEY( "close" ), LFUNCVAL( file_close ) }, - { LSTRKEY( "write" ), LFUNCVAL( file_write ) }, - { LSTRKEY( "writeline" ), LFUNCVAL( file_writeline ) }, - { LSTRKEY( "read" ), LFUNCVAL( file_read ) }, - { LSTRKEY( "readline" ), LFUNCVAL( file_readline ) }, - { LSTRKEY( "format" ), LFUNCVAL( file_format ) }, +const LUA_REG_TYPE file_map[] = {{LSTRKEY("list"), LFUNCVAL(file_list)}, + {LSTRKEY("open"), LFUNCVAL(file_open)}, + {LSTRKEY("close"), LFUNCVAL(file_close)}, + {LSTRKEY("write"), LFUNCVAL(file_write)}, + {LSTRKEY("writeline"), LFUNCVAL(file_writeline)}, + {LSTRKEY("read"), LFUNCVAL(file_read)}, + {LSTRKEY("readline"), LFUNCVAL(file_readline)}, + {LSTRKEY("format"), LFUNCVAL(file_format)}, #if defined(BUILD_SPIFFS) && !defined(BUILD_WOFS) - { LSTRKEY( "remove" ), LFUNCVAL( file_remove ) }, - { LSTRKEY( "seek" ), LFUNCVAL( file_seek ) }, - { LSTRKEY( "flush" ), LFUNCVAL( file_flush ) }, -//{ LSTRKEY( "check" ), LFUNCVAL( file_check ) }, - { LSTRKEY( "rename" ), LFUNCVAL( file_rename ) }, - { LSTRKEY( "fsinfo" ), LFUNCVAL( file_fsinfo ) }, + {LSTRKEY("remove"), LFUNCVAL(file_remove)}, + {LSTRKEY("seek"), LFUNCVAL(file_seek)}, + {LSTRKEY("flush"), LFUNCVAL(file_flush)}, + //{ LSTRKEY( "check" ), LFUNCVAL( file_check ) }, + {LSTRKEY("rename"), LFUNCVAL(file_rename)}, + {LSTRKEY("fsinfo"), LFUNCVAL(file_fsinfo)}, #endif - { LNILKEY, LNILVAL } -}; + {LNILKEY, LNILVAL}}; LUALIB_API int luaopen_file(lua_State *L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_FILELIBNAME, file_map ); - return 1; +#else + luaL_register(L, LUA_FILELIBNAME, file_map); + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/gpio.c b/LuaNode_Esp32/LuaNode32/components/modules/gpio.c index 99585fe..72092d8 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/gpio.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/gpio.c @@ -1,18 +1,18 @@ // Module for interfacing with GPIO -#include "modules.h" +#include "rom/gpio.h" + +#include "c_string.h" +#include "c_types.h" #include "lauxlib.h" -#include "lualib.h" -#include "lrotable.h" #include "lrodefs.h" -#include "platform.h" +#include "lrotable.h" +#include "lualib.h" +#include "modules.h" +#include "mydriver/gpio.h" #include "pin_map.h" -#include "rom/gpio.h" +#include "platform.h" #include "rom/ets_sys.h" -#include "mydriver/gpio.h" - -#include "c_types.h" -#include "c_string.h" #define PULLUP PLATFORM_GPIO_PULLUP #define FLOAT PLATFORM_GPIO_FLOAT @@ -23,245 +23,267 @@ #define HIGH PLATFORM_GPIO_HIGH #define LOW PLATFORM_GPIO_LOW - #ifdef GPIO_INTERRUPT_ENABLE static int gpio_cb_ref[GPIO_PIN_NUM]; static lua_State* gL = NULL; -void lua_gpio_unref(unsigned pin){ - if(gpio_cb_ref[pin] != LUA_NOREF){ - if(gL!=NULL) - luaL_unref(gL, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); - } - gpio_cb_ref[pin] = LUA_NOREF; +void lua_gpio_unref(unsigned pin) +{ + if (gpio_cb_ref[pin] != LUA_NOREF) + { + if (gL != NULL) + luaL_unref(gL, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); + } + gpio_cb_ref[pin] = LUA_NOREF; } -void gpio_intr_callback( unsigned pin, unsigned level ) +void gpio_intr_callback(unsigned pin, unsigned level) { - NODE_DBG("pin:%d, level:%d \n", pin, level); - if(gpio_cb_ref[pin] == LUA_NOREF) - return; - if(!gL) - return; - lua_rawgeti(gL, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); - lua_pushinteger(gL, level); - lua_call(gL, 1, 0); + NODE_DBG("pin:%d, level:%d \n", pin, level); + if (gpio_cb_ref[pin] == LUA_NOREF) + return; + if (!gL) + return; + lua_rawgeti(gL, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); + lua_pushinteger(gL, level); + lua_call(gL, 1, 0); } // Lua: remove( pin ) -static int lgpio_remove_isr( lua_State* L ) +static int lgpio_remove_isr(lua_State* L) { - unsigned pin; - pin = luaL_checkinteger( L, 1 ); - esp_err_t err = gpio_isr_handler_remove( pin ); - if (err != ESP_OK) { - lua_pushinteger( L, pin ); - return 1; - } - lua_pushinteger( L, ESP_OK ); - return 1; + unsigned pin; + pin = luaL_checkinteger(L, 1); + esp_err_t err = gpio_isr_handler_remove(pin); + if (err != ESP_OK) + { + lua_pushinteger(L, pin); + return 1; + } + lua_pushinteger(L, ESP_OK); + return 1; } // Lua: uninstall() -static int lgpio_uninstall( lua_State* L ) +static int lgpio_uninstall(lua_State* L) { - gpio_uninstall_isr_service(); - platform_gpio_isr_uninstall(); - return 0; + gpio_uninstall_isr_service(); + platform_gpio_isr_uninstall(); + return 0; } #endif // Lua: mode( pin, mode, type, function ) -static int lgpio_mode( lua_State* L ) +static int lgpio_mode(lua_State* L) { - unsigned mode; - unsigned pin; - size_t sl; - int type = GPIO_INTR_DISABLE; + unsigned mode; + unsigned pin; + size_t sl; + int type = GPIO_INTR_DISABLE; - pin = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( gpio, pin ); - mode = luaL_checkinteger( L, 2 ); - if ( mode!=OUTPUT && mode!=INPUT && mode!=PLATFORM_INTERRUPT && mode!= INOUT) - return luaL_error( L, "wrong arg type" ); - if(pin==0 && mode==PLATFORM_INTERRUPT) - return luaL_error( L, "no interrupt for D0" ); - if(lua_gettop(L) > 2) { - const char *str = luaL_checklstring( L, 3, &sl ); - if (str == NULL) { - return luaL_error( L, "wrong arg type" ); - } - if(sl == 2 && strcmp(str, "up") == 0){ - type = GPIO_INTR_POSEDGE; - }else if(sl == 4 && strcmp(str, "down") == 0){ - type = GPIO_INTR_NEGEDGE; - }else if(sl == 4 && strcmp(str, "both") == 0){ - type = GPIO_INTR_ANYEDGE; - }else if(sl == 3 && strcmp(str, "low") == 0){ - type = GPIO_INTR_LOW_LEVEL; - }else if(sl == 4 && strcmp(str, "high") == 0){ - type = GPIO_INTR_HIGH_LEVEL; - }else{ - type = GPIO_INTR_DISABLE; printf("==> 6\n"); - } - } - - if (lua_gettop(L) > 3) { - if (lua_type(L, 4) == LUA_TFUNCTION || lua_type(L, 4) == LUA_TLIGHTFUNCTION){ - lua_pushvalue(L, 4); // copy argument (func) to the top of stack - if(gpio_cb_ref[pin] != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); - gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX); - } - } + pin = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( gpio, pin ); + mode = luaL_checkinteger(L, 2); + if (mode != OUTPUT && mode != INPUT && mode != PLATFORM_INTERRUPT && mode != INOUT) + return luaL_error(L, "wrong arg type"); + if (pin == 0 && mode == PLATFORM_INTERRUPT) + return luaL_error(L, "no interrupt for D0"); + if (lua_gettop(L) > 2) + { + const char* str = luaL_checklstring(L, 3, &sl); + if (str == NULL) + { + return luaL_error(L, "wrong arg type"); + } + if (sl == 2 && strcmp(str, "up") == 0) + { + type = GPIO_INTR_POSEDGE; + } + else if (sl == 4 && strcmp(str, "down") == 0) + { + type = GPIO_INTR_NEGEDGE; + } + else if (sl == 4 && strcmp(str, "both") == 0) + { + type = GPIO_INTR_ANYEDGE; + } + else if (sl == 3 && strcmp(str, "low") == 0) + { + type = GPIO_INTR_LOW_LEVEL; + } + else if (sl == 4 && strcmp(str, "high") == 0) + { + type = GPIO_INTR_HIGH_LEVEL; + } + else + { + type = GPIO_INTR_DISABLE; + printf("==> 6\n"); + } + } + + if (lua_gettop(L) > 3) + { + if (lua_type(L, 4) == LUA_TFUNCTION || lua_type(L, 4) == LUA_TLIGHTFUNCTION) + { + lua_pushvalue(L, 4); // copy argument (func) to the top of stack + if (gpio_cb_ref[pin] != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); + gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX); + } + } #ifdef GPIO_INTERRUPT_ENABLE - gL = L; // save to local gL, for callback function - if (mode!=PLATFORM_INTERRUPT){ // disable interrupt - if(gpio_cb_ref[pin] != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); + gL = L; // save to local gL, for callback function + if (mode != PLATFORM_INTERRUPT) + { // disable interrupt + if (gpio_cb_ref[pin] != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]); + } + gpio_cb_ref[pin] = LUA_NOREF; } - gpio_cb_ref[pin] = LUA_NOREF; - } #endif - int r = platform_gpio_mode( pin, mode, type ); - if( r<0 ) - return luaL_error( L, "wrong pin num." ); + int r = platform_gpio_mode(pin, mode, type); + if (r < 0) + return luaL_error(L, "wrong pin num."); - return 0; + return 0; } // Lua: read( pin ) -static int lgpio_read( lua_State* L ) +static int lgpio_read(lua_State* L) { - unsigned pin; - - pin = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( gpio, pin ); + unsigned pin; - unsigned level = platform_gpio_read( pin ); - lua_pushinteger( L, level ); - return 1; + pin = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( gpio, pin ); + + unsigned level = platform_gpio_read(pin); + lua_pushinteger(L, level); + return 1; } // Lua: write( pin, level ) -static int lgpio_write( lua_State* L ) +static int lgpio_write(lua_State* L) { - unsigned level; - unsigned pin; - - pin = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( gpio, pin ); - level = luaL_checkinteger( L, 2 ); - if ( level!=HIGH && level!=LOW ) - return luaL_error( L, "wrong arg type" ); - platform_gpio_write(pin, level); - return 0; + unsigned level; + unsigned pin; + + pin = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( gpio, pin ); + level = luaL_checkinteger(L, 2); + if (level != HIGH && level != LOW) + return luaL_error(L, "wrong arg type"); + platform_gpio_write(pin, level); + return 0; } #define DELAY_TABLE_MAX_LEN 256 #define noInterrupts ets_intr_lock #define interrupts ets_intr_unlock #define delayMicroseconds os_delay_us -#define DIRECT_WRITE(pin, level) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), level)) +#define DIRECT_WRITE(pin, level) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), level)) // Lua: serout( pin, firstLevel, delay_table, [repeatNum] ) // -- serout( pin, firstLevel, delay_table, [repeatNum] ) // gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) // gpio.serout(1,1,{30,30,60,60,30,30}) -- serial one byte, b10110010 // gpio.serout(1,1,{30,70},8) -- serial 30% pwm 10k, lasts 8 cycles // gpio.serout(1,1,{3,7},8) -- serial 30% pwm 100k, lasts 8 cycles -// gpio.serout(1,1,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 cycles -// gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) -// gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps -// gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles -static int lgpio_serout( lua_State* L ) +// gpio.serout(1,1,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 +// cycles gpio.mode(1,gpio.OUTPUT,gpio.PULLUP) +// gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at +// about 100kbps gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles +static int lgpio_serout(lua_State* L) { - unsigned level; - unsigned pin; - unsigned table_len = 0; - int repeat = 0; - int delay_table[DELAY_TABLE_MAX_LEN]; - - pin = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( gpio, pin ); - level = luaL_checkinteger( L, 2 ); - if ( level!=HIGH && level!=LOW ) - return luaL_error( L, "wrong arg type" ); - if( lua_istable( L, 3 ) ) - { - table_len = lua_objlen( L, 3 ); - if (table_len <= 0 || table_len>DELAY_TABLE_MAX_LEN) - return luaL_error( L, "wrong arg range" ); - int i; - for( i = 0; i < table_len; i ++ ) + unsigned level; + unsigned pin; + unsigned table_len = 0; + int repeat = 0; + int delay_table[DELAY_TABLE_MAX_LEN]; + + pin = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( gpio, pin ); + level = luaL_checkinteger(L, 2); + if (level != HIGH && level != LOW) + return luaL_error(L, "wrong arg type"); + if (lua_istable(L, 3)) { - lua_rawgeti( L, 3, i + 1 ); - delay_table[i] = ( int )luaL_checkinteger( L, -1 ); - lua_pop( L, 1 ); - if( delay_table[i] < 0 || delay_table[i] > 1000000 ) // can not delay more than 1000000 us - return luaL_error( L, "delay must < 1000000 us" ); + table_len = lua_objlen(L, 3); + if (table_len <= 0 || table_len > DELAY_TABLE_MAX_LEN) + return luaL_error(L, "wrong arg range"); + int i; + for (i = 0; i < table_len; i++) + { + lua_rawgeti(L, 3, i + 1); + delay_table[i] = (int)luaL_checkinteger(L, -1); + lua_pop(L, 1); + if (delay_table[i] < 0 || delay_table[i] > 1000000) // can not delay more than 1000000 us + return luaL_error(L, "delay must < 1000000 us"); + } + } + else + { + return luaL_error(L, "wrong arg range"); } - } else { - return luaL_error( L, "wrong arg range" ); - } - if(lua_isnumber(L, 4)) - repeat = lua_tointeger( L, 4 ); - if( repeat < 0 || repeat > DELAY_TABLE_MAX_LEN ) - return luaL_error( L, "delay must < 256" ); + if (lua_isnumber(L, 4)) + repeat = lua_tointeger(L, 4); + if (repeat < 0 || repeat > DELAY_TABLE_MAX_LEN) + return luaL_error(L, "delay must < 256"); - if(repeat==0) - repeat = 1; - int j; - bool skip_loop = true; - do - { - if(skip_loop){ // skip the first loop. - skip_loop = false; - continue; - } - for(j=0;j0); + if (repeat == 0) + repeat = 1; + int j; + bool skip_loop = true; + do + { + if (skip_loop) + { // skip the first loop. + skip_loop = false; + continue; + } + for (j = 0; j < table_len; j++) + { + // noInterrupts(); + // platform_gpio_write(pin, level); + DIRECT_WRITE(pin, level); + // interrupts(); + delayMicroseconds(delay_table[j]); + level = !level; + } + repeat--; + } while (repeat > 0); - return 0; + return 0; } #undef DELAY_TABLE_MAX_LEN // Module function map -const LUA_REG_TYPE gpio_map[] = { - { LSTRKEY( "mode" ), LFUNCVAL( lgpio_mode ) }, - { LSTRKEY( "read" ), LFUNCVAL( lgpio_read ) }, - { LSTRKEY( "write" ), LFUNCVAL( lgpio_write ) }, - { LSTRKEY( "serout" ), LFUNCVAL( lgpio_serout ) }, +const LUA_REG_TYPE gpio_map[] = {{LSTRKEY("mode"), LFUNCVAL(lgpio_mode)}, + {LSTRKEY("read"), LFUNCVAL(lgpio_read)}, + {LSTRKEY("write"), LFUNCVAL(lgpio_write)}, + {LSTRKEY("serout"), LFUNCVAL(lgpio_serout)}, #ifdef GPIO_INTERRUPT_ENABLE - { LSTRKEY( "remove" ), LFUNCVAL( lgpio_remove_isr ) }, - { LSTRKEY( "uninstall" ), LFUNCVAL( lgpio_uninstall ) }, - { LSTRKEY( "INT" ), LNUMVAL( PLATFORM_INTERRUPT ) }, + {LSTRKEY("remove"), LFUNCVAL(lgpio_remove_isr)}, + {LSTRKEY("uninstall"), LFUNCVAL(lgpio_uninstall)}, + {LSTRKEY("INT"), LNUMVAL(PLATFORM_INTERRUPT)}, #endif - { LSTRKEY( "OUTPUT" ), LNUMVAL( OUTPUT ) }, - { LSTRKEY( "INPUT" ), LNUMVAL( INPUT ) }, - { LSTRKEY( "INOUT" ), LNUMVAL( INOUT ) }, - { LSTRKEY( "HIGH" ), LNUMVAL( HIGH ) }, - { LSTRKEY( "LOW" ), LNUMVAL( LOW ) }, - { LSTRKEY( "FLOAT" ), LNUMVAL( FLOAT ) }, - { LSTRKEY( "PULLUP" ), LNUMVAL( PULLUP ) }, - { LNILKEY, LNILVAL } -}; + {LSTRKEY("OUTPUT"), LNUMVAL(OUTPUT)}, + {LSTRKEY("INPUT"), LNUMVAL(INPUT)}, + {LSTRKEY("INOUT"), LNUMVAL(INOUT)}, + {LSTRKEY("HIGH"), LNUMVAL(HIGH)}, + {LSTRKEY("LOW"), LNUMVAL(LOW)}, + {LSTRKEY("FLOAT"), LNUMVAL(FLOAT)}, + {LSTRKEY("PULLUP"), LNUMVAL(PULLUP)}, + {LNILKEY, LNILVAL}}; -LUALIB_API int luaopen_gpio(lua_State *L) +LUALIB_API int luaopen_gpio(lua_State* L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_GPIOLIBNAME, gpio_map ); - return 1; +#else + luaL_register(L, LUA_GPIOLIBNAME, gpio_map); + return 1; #endif } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/components/modules/i2c.c b/LuaNode_Esp32/LuaNode32/components/modules/i2c.c index 92d3149..d0b9233 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/i2c.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/i2c.c @@ -1,210 +1,220 @@ // Module for interfacing with the I2C interface +#include "driver/i2c.h" + #include -#include "modules.h" + #include "lauxlib.h" #include "lualib.h" +#include "modules.h" #include "platform.h" -#include "driver/i2c.h" // Lua: speed = i2c.setup( mode, port, scl, sda ) -static int i2c_setup( lua_State *L ) +static int i2c_setup(lua_State *L) { - unsigned mode = luaL_checkinteger( L, 1 ); - if (mode != I2C_MODE_MASTER && mode != I2C_MODE_SLAVE) { - return luaL_error( L, "invalid mode" ); - } - unsigned port = luaL_checkinteger( L, 2 ); - if (port != I2C_NUM_0 && port != I2C_NUM_1) { - return luaL_error( L, "valid port is 0 or 1" ); - } - unsigned scl = luaL_checkinteger( L, 3 ); - unsigned sda = luaL_checkinteger( L, 4 ); - - if (mode == I2C_MODE_SLAVE && lua_gettop(L) < 5) { - return luaL_error( L, "lack of argument: addr" ); - } - - if (lua_gettop( L ) > 4) { // SLAVE mode - unsigned addr = luaL_checkinteger( L, 5 ); - if (addr < 0 || addr > 127) { - return luaL_error( L, "invalid addr (addr < 127)" ); - } - platform_i2c_setup(mode, port, scl, sda, addr); - printf("I2C %d set as SLAVE\n", port); - } else { - platform_i2c_setup(mode, port, scl, sda, 0); - printf("I2C %d set as MASTER\n", port); - } - - - return 1; + unsigned mode = luaL_checkinteger(L, 1); + if (mode != I2C_MODE_MASTER && mode != I2C_MODE_SLAVE) + { + return luaL_error(L, "invalid mode"); + } + unsigned port = luaL_checkinteger(L, 2); + if (port != I2C_NUM_0 && port != I2C_NUM_1) + { + return luaL_error(L, "valid port is 0 or 1"); + } + unsigned scl = luaL_checkinteger(L, 3); + unsigned sda = luaL_checkinteger(L, 4); + + if (mode == I2C_MODE_SLAVE && lua_gettop(L) < 5) + { + return luaL_error(L, "lack of argument: addr"); + } + + if (lua_gettop(L) > 4) + { // SLAVE mode + unsigned addr = luaL_checkinteger(L, 5); + if (addr < 0 || addr > 127) + { + return luaL_error(L, "invalid addr (addr < 127)"); + } + platform_i2c_setup(mode, port, scl, sda, addr); + printf("I2C %d set as SLAVE\n", port); + } + else + { + platform_i2c_setup(mode, port, scl, sda, 0); + printf("I2C %d set as MASTER\n", port); + } + + return 1; } // Lua: i2c.start( id ) -static int i2c_start( lua_State *L ) +static int i2c_start(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1 ); + unsigned id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID( i2c, id ); - platform_i2c_send_start( id ); - return 0; + // MOD_CHECK_ID( i2c, id ); + platform_i2c_send_start(id); + return 0; } // Lua: i2c.stop( id ) -static int i2c_stop( lua_State *L ) +static int i2c_stop(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1 ); + unsigned id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID( i2c, id ); - platform_i2c_send_stop( id ); - return 0; + // MOD_CHECK_ID( i2c, id ); + platform_i2c_send_stop(id); + return 0; } // Lua: status = i2c.address( id, address, direction ) -static int i2c_address( lua_State *L ) +static int i2c_address(lua_State *L) { - /* unsigned id = luaL_checkinteger( L, 1 ); - int address = luaL_checkinteger( L, 2 ); - int direction = luaL_checkinteger( L, 3 ); - - //MOD_CHECK_ID( i2c, id ); - if ( address < 0 || address > 127 ) - return luaL_error( L, "wrong arg range" ); - lua_pushboolean( L, platform_i2c_send_address( id, (u16)address, direction ) );*/ - return 1; + /* unsigned id = luaL_checkinteger( L, 1 ); + int address = luaL_checkinteger( L, 2 ); + int direction = luaL_checkinteger( L, 3 ); + + //MOD_CHECK_ID( i2c, id ); + if ( address < 0 || address > 127 ) + return luaL_error( L, "wrong arg range" ); + lua_pushboolean( L, platform_i2c_send_address( id, (u16)address, direction + ) );*/ + return 1; } // Lua: wrote = i2c.write( mode, port, addr, data1, [data2], ..., [datan] ) // data can be either a string, a table or an 8-bit number -static int i2c_write( lua_State *L ) +static int i2c_write(lua_State *L) { - unsigned mode = luaL_checkinteger( L, 1 ); - unsigned port = luaL_checkinteger( L, 2 ); - unsigned addr = luaL_checkinteger( L, 3 ); - const char *pdata; - size_t datalen, i; - int numdata = 0; - u32 wrote = 0; - unsigned argn; - unsigned char buf[256]; - memset(buf, 0, 256); - - //MOD_CHECK_ID( i2c, id ); - if( lua_gettop( L ) < 4 ) - return luaL_error( L, "wrong arg type" ); - for( argn = 4; argn <= lua_gettop( L ); argn ++ ) - { - // lua_isnumber() would silently convert a string of digits to an integer - // whereas here strings are handled separately. - if( lua_type( L, argn ) == LUA_TNUMBER ) + unsigned mode = luaL_checkinteger(L, 1); + unsigned port = luaL_checkinteger(L, 2); + unsigned addr = luaL_checkinteger(L, 3); + const char *pdata; + size_t datalen, i; + int numdata = 0; + u32 wrote = 0; + unsigned argn; + unsigned char buf[256]; + memset(buf, 0, 256); + + // MOD_CHECK_ID( i2c, id ); + if (lua_gettop(L) < 4) + return luaL_error(L, "wrong arg type"); + for (argn = 4; argn <= lua_gettop(L); argn++) { - numdata = ( int )luaL_checkinteger( L, argn ); - if( numdata < 0 || numdata > 255 ) - return luaL_error( L, "wrong arg range" ); - //if( platform_i2c_send_byte( mode, port, numdata ) == 0 ) - // break; - buf[wrote] = numdata; - wrote ++; + // lua_isnumber() would silently convert a string of digits to an + // integer whereas here strings are handled separately. + if (lua_type(L, argn) == LUA_TNUMBER) + { + numdata = (int)luaL_checkinteger(L, argn); + if (numdata < 0 || numdata > 255) + return luaL_error(L, "wrong arg range"); + // if( platform_i2c_send_byte( mode, port, numdata ) == 0 ) + // break; + buf[wrote] = numdata; + wrote++; + } + else if (lua_istable(L, argn)) + { + datalen = lua_objlen(L, argn); + for (i = 0; i < datalen; i++) + { + lua_rawgeti(L, argn, i + 1); + numdata = (int)luaL_checkinteger(L, -1); + lua_pop(L, 1); + if (numdata < 0 || numdata > 255) + return luaL_error(L, "wrong arg range"); + buf[wrote] = numdata; + wrote++; + // if( platform_i2c_send_byte( mode, port, numdata ) == 0 ) + // break; + } + } + else + { + pdata = luaL_checklstring(L, argn, &datalen); + for (i = 0; i < datalen; i++) + { + buf[wrote] = pdata[i]; + wrote++; + } + // if( platform_i2c_send_byte( mode, port, pdata[ i ] ) == 0 ) + // break; + } } - else if( lua_istable( L, argn ) ) - { - datalen = lua_objlen( L, argn ); - for( i = 0; i < datalen; i ++ ) - { - lua_rawgeti( L, argn, i + 1 ); - numdata = ( int )luaL_checkinteger( L, -1 ); - lua_pop( L, 1 ); - if( numdata < 0 || numdata > 255 ) - return luaL_error( L, "wrong arg range" ); - buf[wrote] = numdata; - wrote ++; - //if( platform_i2c_send_byte( mode, port, numdata ) == 0 ) - // break; - } - } - else + + int ret = platform_i2c_send_byte(mode, port, addr, buf, wrote); + if (mode == I2C_MODE_MASTER && ret != ESP_OK) { - pdata = luaL_checklstring( L, argn, &datalen ); - for( i = 0; i < datalen; i ++ ) { - buf[wrote] = pdata[i]; - wrote ++; - } - //if( platform_i2c_send_byte( mode, port, pdata[ i ] ) == 0 ) - // break; + printf("Master write slave error, IO not connected....\n"); } - } - - int ret = platform_i2c_send_byte( mode, port, addr, buf, wrote ); - if (mode == I2C_MODE_MASTER && ret != ESP_OK) { - printf("Master write slave error, IO not connected....\n"); - } - lua_pushinteger( L, wrote ); - return 1; + lua_pushinteger(L, wrote); + return 1; } // Lua: read = i2c.read( mode, port, addr, len ) -static int i2c_read( lua_State *L ) +static int i2c_read(lua_State *L) { - unsigned mode = luaL_checkinteger( L, 1 ); - unsigned port = luaL_checkinteger( L, 2 ); - if (port != I2C_NUM_0 && port != I2C_NUM_1) { - return luaL_error( L, "valid port is 0 or 1" ); - } - unsigned addr = luaL_checkinteger( L, 3 ); - unsigned len = luaL_checkinteger( L, 4 ); - if (len < 0) { - return luaL_error( L, "read len must greater than 0" ); - } else if (len == 0) { - luaL_pushresult( 0 ); - return 1; - } - luaL_Buffer b; - - //MOD_CHECK_ID( i2c, id ); - luaL_buffinit( L, &b ); - uint8_t data_rw[1024] = {0}; - int r_size = platform_i2c_recv_byte( mode, port, addr, data_rw, len ); - if (mode == I2C_MODE_MASTER && r_size != ESP_OK) { - printf("Master read slave error....\n"); - } - luaL_addlstring(&b, data_rw, strlen(data_rw)); - luaL_pushresult( &b ); - return 1; + unsigned mode = luaL_checkinteger(L, 1); + unsigned port = luaL_checkinteger(L, 2); + if (port != I2C_NUM_0 && port != I2C_NUM_1) + { + return luaL_error(L, "valid port is 0 or 1"); + } + unsigned addr = luaL_checkinteger(L, 3); + unsigned len = luaL_checkinteger(L, 4); + if (len < 0) + { + return luaL_error(L, "read len must greater than 0"); + } + else if (len == 0) + { + luaL_pushresult(0); + return 1; + } + luaL_Buffer b; + + // MOD_CHECK_ID( i2c, id ); + luaL_buffinit(L, &b); + uint8_t data_rw[1024] = {0}; + int r_size = platform_i2c_recv_byte(mode, port, addr, data_rw, len); + if (mode == I2C_MODE_MASTER && r_size != ESP_OK) + { + printf("Master read slave error....\n"); + } + luaL_addlstring(&b, data_rw, strlen(data_rw)); + luaL_pushresult(&b); + return 1; } // Lua: i2c.uninstall( i2c_num ) static int i2c_uninstall(lua_State *L) { - unsigned num = luaL_checkinteger( L, 1 ); - if (num != I2C_NUM_0 && num != I2C_NUM_1) { - return luaL_error(L, "invalid argument"); - } - platform_i2c_uninstall(num); - return 0; + unsigned num = luaL_checkinteger(L, 1); + if (num != I2C_NUM_0 && num != I2C_NUM_1) + { + return luaL_error(L, "invalid argument"); + } + platform_i2c_uninstall(num); + return 0; } // Module function map const LUA_REG_TYPE i2c_map[] = { - { LSTRKEY( "setup" ), LFUNCVAL( i2c_setup ) }, - { LSTRKEY( "start" ), LFUNCVAL( i2c_start ) }, - { LSTRKEY( "stop" ), LFUNCVAL( i2c_stop ) }, - { LSTRKEY( "address" ), LFUNCVAL( i2c_address ) }, - { LSTRKEY( "write" ), LFUNCVAL( i2c_write ) }, - { LSTRKEY( "read" ), LFUNCVAL( i2c_read ) }, - { LSTRKEY( "uninstall" ), LFUNCVAL( i2c_uninstall ) }, - { LSTRKEY( "MASTER" ), LNUMVAL( I2C_MODE_MASTER ) }, - { LSTRKEY( "SLAVE" ), LNUMVAL( I2C_MODE_SLAVE ) }, - { LSTRKEY( "I2C_0" ), LNUMVAL( I2C_NUM_0 ) }, - { LSTRKEY( "I2C_1" ), LNUMVAL( I2C_NUM_1 ) }, - { LNILKEY, LNILVAL } -}; + {LSTRKEY("setup"), LFUNCVAL(i2c_setup)}, {LSTRKEY("start"), LFUNCVAL(i2c_start)}, + {LSTRKEY("stop"), LFUNCVAL(i2c_stop)}, {LSTRKEY("address"), LFUNCVAL(i2c_address)}, + {LSTRKEY("write"), LFUNCVAL(i2c_write)}, {LSTRKEY("read"), LFUNCVAL(i2c_read)}, + {LSTRKEY("uninstall"), LFUNCVAL(i2c_uninstall)}, {LSTRKEY("MASTER"), LNUMVAL(I2C_MODE_MASTER)}, + {LSTRKEY("SLAVE"), LNUMVAL(I2C_MODE_SLAVE)}, {LSTRKEY("I2C_0"), LNUMVAL(I2C_NUM_0)}, + {LSTRKEY("I2C_1"), LNUMVAL(I2C_NUM_1)}, {LNILKEY, LNILVAL}}; LUALIB_API int luaopen_i2c(lua_State *L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_I2CLIBNAME, i2c_map ); - return 1; +#else + luaL_register(L, LUA_I2CLIBNAME, i2c_map); + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/ip_fmt.c b/LuaNode_Esp32/LuaNode32/components/modules/ip_fmt.c index d3cc1fc..696664e 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/ip_fmt.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/ip_fmt.c @@ -31,34 +31,26 @@ * @author Johny Mattsson */ #include "ip_fmt.h" -#include "lwip/sockets.h" -#include "lwip/ip_addr.h" -#include "lwip/ip4_addr.h" -#include -void macstr (char *str, const uint8_t *mac) -{ - sprintf (str, "%02x:%02x:%02x:%02x:%02x:%02x", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -} +#include +#include "lwip/ip4_addr.h" +#include "lwip/ip_addr.h" +#include "lwip/sockets.h" -void ipstr (char *out, const ip_addr_t *ip) +void macstr(char *str, const uint8_t *mac) { - if (ip->type == IPADDR_TYPE_V4) - ip4str (out, &ip->u_addr.ip4); - else if (ip->type == IPADDR_TYPE_V6) - ip6str (out, &ip->u_addr.ip6); + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } - -void ip4str (char *out, const ip4_addr_t *ip) +void ipstr(char *out, const ip_addr_t *ip) { - ip4addr_ntoa_r (ip, out, IP_STR_SZ); + if (ip->type == IPADDR_TYPE_V4) + ip4str(out, &ip->u_addr.ip4); + else if (ip->type == IPADDR_TYPE_V6) + ip6str(out, &ip->u_addr.ip6); } +void ip4str(char *out, const ip4_addr_t *ip) { ip4addr_ntoa_r(ip, out, IP_STR_SZ); } -void ip6str (char *out, const ip6_addr_t *ip) -{ - ip6addr_ntoa_r (ip, out, IP_STR_SZ); -} +void ip6str(char *out, const ip6_addr_t *ip) { ip6addr_ntoa_r(ip, out, IP_STR_SZ); } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/linit.c b/LuaNode_Esp32/LuaNode32/components/modules/linit.c index d959bb1..a389c19 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/linit.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/linit.c @@ -2,18 +2,16 @@ #define LUA_LIB #define LUAC_CROSS_FILE -#include "lua.h" - -#include "lualib.h" +#include "c_string.h" +#include "esp_misc.h" #include "lauxlib.h" +#include "lrotable.h" +#include "lua.h" #include "luaconf.h" +#include "lualib.h" #include "modules.h" -#include "esp_misc.h" -#include "lrotable.h" #include "user_modules.h" -#include "c_string.h" - extern const LUA_REG_TYPE nvs_map[]; extern const LUA_REG_TYPE mqtt_map[]; extern const LUA_REG_TYPE thread_map[]; @@ -32,117 +30,115 @@ extern const LUA_REG_TYPE tab_funcs[]; extern const LUA_REG_TYPE co_funcs[]; extern const LUA_REG_TYPE math_map[]; - const luaL_Reg lua_libs[] = { - {"base", luaopen_base}, - {"package", luaopen_package}, - {"table", luaopen_table}, - {"string", luaopen_string}, + {"base", luaopen_base}, + {"package", luaopen_package}, + {"table", luaopen_table}, + {"string", luaopen_string}, #ifdef USE_GPIO_MODULE - {LUA_GPIOLIBNAME, luaopen_gpio}, + {LUA_GPIOLIBNAME, luaopen_gpio}, #endif #ifdef USE_PWM_MODULE - {LUA_PWMLIBNAME, luaopen_pwm}, + {LUA_PWMLIBNAME, luaopen_pwm}, #endif #ifdef USE_NODE_MODULE - {LUA_NODELIBNAME, luaopen_node}, + {LUA_NODELIBNAME, luaopen_node}, #endif #ifdef USE_WIFI_MODULE - {LUA_WIFILIBNAME, luaopen_wifi}, + {LUA_WIFILIBNAME, luaopen_wifi}, #endif #ifdef USE_FILE_MODULE - {LUA_FILELIBNAME, luaopen_file}, + {LUA_FILELIBNAME, luaopen_file}, #endif #ifdef USE_TMR_MODULE - {LUA_TMRLIBNAME, luaopen_tmr}, + {LUA_TMRLIBNAME, luaopen_tmr}, #endif #ifdef USE_I2C_MODULE - {LUA_I2CLIBNAME, luaopen_i2c}, + {LUA_I2CLIBNAME, luaopen_i2c}, #endif #ifdef USE_UART_MODULE - {LUA_UARTLIBNAME, luaopen_uart}, + {LUA_UARTLIBNAME, luaopen_uart}, #endif #ifdef USE_UTILS_MODULE - {LUA_UTILSLIBNAME, luaopen_utils}, + {LUA_UTILSLIBNAME, luaopen_utils}, #endif #ifdef USE_LPEG_MODULE - {LUA_LPEGLIBNAME, luaopen_lpeg}, + {LUA_LPEGLIBNAME, luaopen_lpeg}, #endif #ifdef USE_NET_MODULE - {LUA_NETLIBNAME, luaopen_net}, + {LUA_NETLIBNAME, luaopen_net}, #endif #ifdef USE_THREAD_MODULE - {LUA_THREADLIBNAME, luaopen_thread}, + {LUA_THREADLIBNAME, luaopen_thread}, #endif #ifdef USE_MQTT_MODULE - {LUA_MQTTLIBNAME, luaopen_mqtt}, + {LUA_MQTTLIBNAME, luaopen_mqtt}, #endif #ifdef USE_NVS_MODULE - {LUA_NVSLIBNAME, luaopen_nvs}, + {LUA_NVSLIBNAME, luaopen_nvs}, #endif - {NULL, NULL}, + {NULL, NULL}, }; -const luaR_table lua_rotable[] = -{ - {LUA_TABLIBNAME, tab_funcs}, - {LUA_STRLIBNAME, strlib}, - //{LUA_COLIBNAME, co_funcs}, - //{LUA_MATHLIBNAME, math_map}, +const luaR_table lua_rotable[] = {{LUA_TABLIBNAME, tab_funcs}, + {LUA_STRLIBNAME, strlib}, +//{LUA_COLIBNAME, co_funcs}, +//{LUA_MATHLIBNAME, math_map}, #ifdef USE_GPIO_MODULE - {LUA_GPIOLIBNAME, gpio_map}, + {LUA_GPIOLIBNAME, gpio_map}, #endif #ifdef USE_PWM_MODULE - {LUA_PWMLIBNAME, pwm_map}, + {LUA_PWMLIBNAME, pwm_map}, #endif #ifdef USE_NODE_MODULE - {LUA_NODELIBNAME, node_map}, + {LUA_NODELIBNAME, node_map}, #endif #ifdef USE_WIFI_MODULE - {LUA_WIFILIBNAME, wifi_map}, + {LUA_WIFILIBNAME, wifi_map}, #endif #ifdef USE_FILE_MODULE - {LUA_FILELIBNAME, file_map}, + {LUA_FILELIBNAME, file_map}, #endif #ifdef USE_TMR_MODULE - {LUA_TMRLIBNAME, tmr_map}, + {LUA_TMRLIBNAME, tmr_map}, #endif #ifdef USE_I2C_MODULE - {LUA_I2CLIBNAME, i2c_map}, + {LUA_I2CLIBNAME, i2c_map}, #endif #ifdef USE_UART_MODULE - {LUA_UARTLIBNAME, uart_map}, + {LUA_UARTLIBNAME, uart_map}, #endif #ifdef USE_UTILS_MODULE - {LUA_UTILSLIBNAME, utils_map}, + {LUA_UTILSLIBNAME, utils_map}, #endif #ifdef USE_NET_MODULE - {LUA_NETLIBNAME, net_map}, + {LUA_NETLIBNAME, net_map}, #endif #ifdef USE_THREAD_MODULE - {LUA_THREADLIBNAME, thread_map}, + {LUA_THREADLIBNAME, thread_map}, #endif #ifdef USE_MQTT_MODULE - {LUA_MQTTLIBNAME, mqtt_map}, + {LUA_MQTTLIBNAME, mqtt_map}, #endif #ifdef USE_NVS_MODULE - {LUA_NVSLIBNAME, nvs_map}, + {LUA_NVSLIBNAME, nvs_map}, #endif - {NULL, NULL} -}; + {NULL, NULL}}; -void luaL_openlibs (lua_State *L) { - const luaL_Reg *lib = lua_libs; - for (; lib->name; lib++) { - os_printf("load lib: %s\n", lib->name); - if (lib->func) +void luaL_openlibs(lua_State *L) +{ + const luaL_Reg *lib = lua_libs; + for (; lib->name; lib++) { - lua_pushcfunction(L, lib->func); - lua_pushstring(L, lib->name); - lua_call(L, 1, 0); + os_printf("load lib: %s\n", lib->name); + if (lib->func) + { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } } - } - os_printf("other libs:\n"); + os_printf("other libs:\n"); - //luaopen_pwm(L); + // luaopen_pwm(L); } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/mqtt.c b/LuaNode_Esp32/LuaNode32/components/modules/mqtt.c index 516e5b0..84a2c65 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/mqtt.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/mqtt.c @@ -1,43 +1,43 @@ -/** +/** * mqtt module for Lua * * Nicholas3388 * 2017. 02.22 */ -#include "lua.h" +#include "mqtt.h" + #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lua.h" #include "lualib.h" -#include "user_config.h" - #include "platform.h" -#include "mqtt.h" +#include "user_config.h" -#define MQTT_CMD_TIMEOUT 5000 // 5s -#define MQTT_YIELD_TMIE 1000 // 1s +#define MQTT_CMD_TIMEOUT 5000 // 5s +#define MQTT_YIELD_TMIE 1000 // 1s #define MAX_MQTT_NUM 3 -#define TOPIC_BUFF_SIZE 64 -#define DATA_BUFF_SIZE 768 +#define TOPIC_BUFF_SIZE 64 +#define DATA_BUFF_SIZE 768 -#define QOS0 0 -#define QOS1 1 -#define QOS2 2 +#define QOS0 0 +#define QOS1 1 +#define QOS2 2 //#define mqtt_log(M, ...) printf(M, ##__VA_ARGS__) #define mqtt_log(M, ...) -typedef struct { - mqtt_client *pClient; - int cb_ref_data; - int cb_ref_connect; - int cb_ref_disconnect; - int cb_ref_publish; - int cb_ref_reconnect; - int cb_ref_subscribe; -}mqtt_t; +typedef struct +{ + mqtt_client *pClient; + int cb_ref_data; + int cb_ref_connect; + int cb_ref_disconnect; + int cb_ref_publish; + int cb_ref_reconnect; + int cb_ref_subscribe; +} mqtt_t; static mqtt_t handle[MAX_MQTT_NUM]; bool mqtt_thread_is_started = false; @@ -48,94 +48,108 @@ static char data_buf[DATA_BUFF_SIZE] = {0}; static void messageArrived(/*MessageData* md*/) { - /*mqtt_log("messageArrived Called\r\n"); - MQTTMessage* message = md->message; - mqtt_log("messageArrived: [%.*s]\t [%d][%.*s]\r\n", - md->topicName->lenstring.len, md->topicName->lenstring.data, - (int)message->payloadlen, - (int)message->payloadlen, (char*)message->payload); - for(int i=0;icb_ref_message == LUA_NOREF) continue; - lua_rawgeti(gL, LUA_REGISTRYINDEX, pmqtt[i]->cb_ref_message); - lua_pushlstring(gL,(char const*)md->topicName->lenstring.data,md->topicName->lenstring.len); - lua_pushlstring(gL,(char const*)message->payload,(int)message->payloadlen); - lua_call(gL, 2, 0); - }*/ + /*mqtt_log("messageArrived Called\r\n"); + MQTTMessage* message = md->message; + mqtt_log("messageArrived: [%.*s]\t [%d][%.*s]\r\n", + md->topicName->lenstring.len, md->topicName->lenstring.data, + (int)message->payloadlen, + (int)message->payloadlen, (char*)message->payload); + for(int i=0;icb_ref_message == LUA_NOREF) continue; + lua_rawgeti(gL, LUA_REGISTRYINDEX, pmqtt[i]->cb_ref_message); + lua_pushlstring(gL,(char + const*)md->topicName->lenstring.data,md->topicName->lenstring.len); + lua_pushlstring(gL,(char + const*)message->payload,(int)message->payloadlen); lua_call(gL, 2, 0); + }*/ } static void closeMqtt(int id) { - printf("[mqtt:%d]closeMqtt\r\n",id); - if(handle[id].pClient==NULL) return; - + printf("[mqtt:%d]closeMqtt\r\n", id); + if (handle[id].pClient == NULL) + return; } void connected_cb(void *self, void *params) { - int i; - mqtt_client *client = (mqtt_client *)self; - for (i=0; idata_offset == 0) { + if (event_data->data_offset == 0) + { memcpy(topic_buf, event_data->topic, event_data->topic_length); topic_buf[event_data->topic_length] = 0; } @@ -143,308 +157,362 @@ void publish_cb(void *self, void *params) memcpy(data_buf, event_data->data, event_data->data_length); data_buf[event_data->data_length] = 0; - int i; - for (i=0; itopic_length)); - lua_pushlstring(gL,(char const*)data_buf,(int)(event_data->data_length)); - lua_call(gL, 2, 0); - } - return; - } - } + int i; + for (i = 0; i < MAX_MQTT_NUM; i++) + { + if (handle[i].pClient == client) + { + if (handle[i].cb_ref_publish != LUA_NOREF) + { + lua_rawgeti(gL, LUA_REGISTRYINDEX, handle[i].cb_ref_publish); + lua_pushlstring(gL, (char const *)topic_buf, (int)(event_data->topic_length)); + lua_pushlstring(gL, (char const *)data_buf, (int)(event_data->data_length)); + lua_call(gL, 2, 0); + } + return; + } + } } void data_cb(void *self, void *params) { - mqtt_client *client = (mqtt_client *)self; + mqtt_client *client = (mqtt_client *)self; mqtt_event_data_t *event_data = (mqtt_event_data_t *)params; - if (event_data->data_offset == 0) { + if (event_data->data_offset == 0) + { memcpy(topic_buf, event_data->topic, event_data->topic_length); topic_buf[event_data->topic_length] = 0; printf("[APP] Publish topic: %s\n", topic_buf); - } memcpy(data_buf, event_data->data, event_data->data_length); data_buf[event_data->data_length] = 0; - printf("[APP] Publish data[%d/%d bytes], content: %s\n", - event_data->data_length + event_data->data_offset, - event_data->data_total_length, - data_buf); - - int i; - for (i=0; itopic_length)); - lua_pushlstring(gL,(char const*)data_buf,(int)(event_data->data_length)); - lua_call(gL, 2, 0); - } - return; - } - } + printf("[APP] Publish data[%d/%d bytes], content: %s\n", event_data->data_length + event_data->data_offset, + event_data->data_total_length, data_buf); + + int i; + for (i = 0; i < MAX_MQTT_NUM; i++) + { + if (handle[i].pClient == client) + { + if (handle[i].cb_ref_data != LUA_NOREF) + { + lua_rawgeti(gL, LUA_REGISTRYINDEX, handle[i].cb_ref_data); + lua_pushlstring(gL, (char const *)topic_buf, (int)(event_data->topic_length)); + lua_pushlstring(gL, (char const *)data_buf, (int)(event_data->data_length)); + lua_call(gL, 2, 0); + } + return; + } + } } -//mqttClt = mqtt.new(host,client_id,keepalive,connect_cb,[user],[pass]) -static int lmqtt_new( lua_State* L ) +// mqttClt = mqtt.new(host,client_id,keepalive,connect_cb,[user],[pass]) +static int lmqtt_new(lua_State *L) { - int i=0, idx=0; - char *host = NULL; - char *user = NULL; - char *pass = NULL; - size_t sl=0; - host = luaL_checklstring( L, 1, &sl ); - if (host == NULL) return luaL_error( L, "wrong arg 1 type" ); - - char const *clientid = luaL_checklstring( L, 2, &sl ); - if (clientid == NULL) return luaL_error( L, "wrong arg 2 type" ); - - unsigned keepalive; - keepalive = luaL_checkinteger( L, 3 ); - - for (i=0; i= MAX_MQTT_NUM) { - return luaL_error( L, "Max MQTT Number is reached" ); - } - - handle[idx].cb_ref_data = LUA_NOREF; - handle[idx].cb_ref_connect = LUA_NOREF; - handle[idx].cb_ref_disconnect = LUA_NOREF; - handle[idx].cb_ref_publish = LUA_NOREF; - handle[idx].cb_ref_reconnect = LUA_NOREF; - handle[idx].cb_ref_subscribe = LUA_NOREF; - - // get connect callback - if (lua_type(L, 4) == LUA_TFUNCTION || lua_type(L, 4) == LUA_TLIGHTFUNCTION) { - lua_pushvalue(L, 4); - if( handle[idx].cb_ref_connect!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[idx].cb_ref_connect); - } - handle[idx].cb_ref_connect = luaL_ref(L, LUA_REGISTRYINDEX); - } else { - handle[idx].cb_ref_connect = LUA_NOREF; - //return luaL_error( L, "callback function needed" ); - } - - if (lua_gettop(L) > 4) { - user = luaL_checklstring( L, 5, &sl ); - pass = luaL_checklstring( L, 6, &sl ); - } - int k=0; - for(k=0;kport = 8883, // encrypted + int i = 0, idx = 0; + char *host = NULL; + char *user = NULL; + char *pass = NULL; + size_t sl = 0; + host = luaL_checklstring(L, 1, &sl); + if (host == NULL) + return luaL_error(L, "wrong arg 1 type"); + + char const *clientid = luaL_checklstring(L, 2, &sl); + if (clientid == NULL) + return luaL_error(L, "wrong arg 2 type"); + + unsigned keepalive; + keepalive = luaL_checkinteger(L, 3); + + for (i = 0; i < MAX_MQTT_NUM; i++) + { + if (handle[i].pClient == NULL) + { + idx = i; + break; + } + } + if (i >= MAX_MQTT_NUM) + { + return luaL_error(L, "Max MQTT Number is reached"); + } + + handle[idx].cb_ref_data = LUA_NOREF; + handle[idx].cb_ref_connect = LUA_NOREF; + handle[idx].cb_ref_disconnect = LUA_NOREF; + handle[idx].cb_ref_publish = LUA_NOREF; + handle[idx].cb_ref_reconnect = LUA_NOREF; + handle[idx].cb_ref_subscribe = LUA_NOREF; + + // get connect callback + if (lua_type(L, 4) == LUA_TFUNCTION || lua_type(L, 4) == LUA_TLIGHTFUNCTION) + { + lua_pushvalue(L, 4); + if (handle[idx].cb_ref_connect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[idx].cb_ref_connect); + } + handle[idx].cb_ref_connect = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { + handle[idx].cb_ref_connect = LUA_NOREF; + // return luaL_error( L, "callback function needed" ); + } + + if (lua_gettop(L) > 4) + { + user = luaL_checklstring(L, 5, &sl); + pass = luaL_checklstring(L, 6, &sl); + } + int k = 0; + for (k = 0; k < MAX_MQTT_NUM; k++) + { + if (handle[k].pClient == NULL) + break; + } + if (k == MAX_MQTT_NUM) + return luaL_error(L, "Max MQTT Number is reached"); + mqtt_settings *settings = (mqtt_settings *)malloc(sizeof(mqtt_settings)); + memset(settings, 0, sizeof(mqtt_settings)); +#if defined(CONFIG_MQTT_SECURITY_ON) + settings->port = 8883, // encrypted #else - settings->port = 1883, // unencrypted + settings->port = 1883, // unencrypted #endif - settings->clean_session = 0; - settings->keepalive = keepalive; - settings->lwt_qos = QOS0; - settings->lwt_retain = 0; - settings->connected_cb = connected_cb; - settings->disconnected_cb = disconnected_cb; - settings->reconnect_cb = reconnect_cb; - settings->subscribe_cb = subscribe_cb; - settings->publish_cb = publish_cb; - settings->data_cb = data_cb; - - if (strlen(host) <= CONFIG_MQTT_MAX_HOST_LEN) { - memcpy(settings->host, host, CONFIG_MQTT_MAX_HOST_LEN); - } else { - printf( "host too long\n" ); - } - if (clientid != NULL && strlen(clientid) <= CONFIG_MQTT_MAX_CLIENT_LEN) { - memcpy(settings->client_id, clientid, strlen(clientid)); - } else { - - } - if (user != NULL && strlen(user) <= CONFIG_MQTT_MAX_USERNAME_LEN) { - memcpy(settings->username, user, strlen(user)); - } else { - printf( "user name too long\n" ); - } - if (pass != NULL && strlen(pass) <= CONFIG_MQTT_MAX_PASSWORD_LEN) { - memcpy(settings->password, pass, strlen(pass)); - } else { - printf( "password too long\n" ); - } - - gL = L; - handle[idx].pClient = mqtt_start(settings); - - lua_pushinteger(L, idx); - return 1; + settings->clean_session = 0; + settings->keepalive = keepalive; + settings->lwt_qos = QOS0; + settings->lwt_retain = 0; + settings->connected_cb = connected_cb; + settings->disconnected_cb = disconnected_cb; + settings->reconnect_cb = reconnect_cb; + settings->subscribe_cb = subscribe_cb; + settings->publish_cb = publish_cb; + settings->data_cb = data_cb; + + if (strlen(host) <= CONFIG_MQTT_MAX_HOST_LEN) + { + memcpy(settings->host, host, CONFIG_MQTT_MAX_HOST_LEN); + } + else + { + printf("host too long\n"); + } + if (clientid != NULL && strlen(clientid) <= CONFIG_MQTT_MAX_CLIENT_LEN) + { + memcpy(settings->client_id, clientid, strlen(clientid)); + } + else + { + } + if (user != NULL && strlen(user) <= CONFIG_MQTT_MAX_USERNAME_LEN) + { + memcpy(settings->username, user, strlen(user)); + } + else + { + printf("user name too long\n"); + } + if (pass != NULL && strlen(pass) <= CONFIG_MQTT_MAX_PASSWORD_LEN) + { + memcpy(settings->password, pass, strlen(pass)); + } + else + { + printf("password too long\n"); + } + + gL = L; + handle[idx].pClient = mqtt_start(settings); + + lua_pushinteger(L, idx); + return 1; } -//mqtt.close(mqttClt) -static int lmqtt_close( lua_State* L ) +// mqtt.close(mqttClt) +static int lmqtt_close(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1); - if(id>=MAX_MQTT_NUM) - return luaL_error( L, "mqttClt arg is wrong!" ); - if(handle[id].pClient!=NULL) - { - //pmqtt[mqttClt]->reqClose=true; - if(handle[id].cb_ref_data != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_data); - handle[id].cb_ref_data = LUA_NOREF; - } - if(handle[id].cb_ref_disconnect != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_disconnect); - handle[id].cb_ref_disconnect = LUA_NOREF; - } - if(handle[id].cb_ref_reconnect != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_reconnect); - handle[id].cb_ref_reconnect = LUA_NOREF; - } - if(handle[id].cb_ref_publish != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_publish); - handle[id].cb_ref_publish = LUA_NOREF; - } - if(handle[id].cb_ref_connect != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_connect); - handle[id].cb_ref_connect = LUA_NOREF; - } - if(handle[id].cb_ref_subscribe != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_subscribe); - handle[id].cb_ref_subscribe = LUA_NOREF; - } - free((handle[id].pClient)->settings); - mqtt_destroy(handle[id].pClient); - closeMqtt(id); - } - return 0; + unsigned id = luaL_checkinteger(L, 1); + if (id >= MAX_MQTT_NUM) + return luaL_error(L, "mqttClt arg is wrong!"); + if (handle[id].pClient != NULL) + { + // pmqtt[mqttClt]->reqClose=true; + if (handle[id].cb_ref_data != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_data); + handle[id].cb_ref_data = LUA_NOREF; + } + if (handle[id].cb_ref_disconnect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_disconnect); + handle[id].cb_ref_disconnect = LUA_NOREF; + } + if (handle[id].cb_ref_reconnect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_reconnect); + handle[id].cb_ref_reconnect = LUA_NOREF; + } + if (handle[id].cb_ref_publish != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_publish); + handle[id].cb_ref_publish = LUA_NOREF; + } + if (handle[id].cb_ref_connect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_connect); + handle[id].cb_ref_connect = LUA_NOREF; + } + if (handle[id].cb_ref_subscribe != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_subscribe); + handle[id].cb_ref_subscribe = LUA_NOREF; + } + free((handle[id].pClient)->settings); + mqtt_destroy(handle[id].pClient); + closeMqtt(id); + } + return 0; } -//mqtt.subscribe(id, topic, QoS) -static int lmqtt_subscribe( lua_State* L ) +// mqtt.subscribe(id, topic, QoS) +static int lmqtt_subscribe(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1); - if(handle[id].pClient==NULL|| id>=MAX_MQTT_NUM) - return luaL_error( L, "mqttClt arg is wrong!" ); - size_t sl=0; - char const *topic = luaL_checklstring( L, 2, &sl ); - if (topic == NULL) return luaL_error( L, "wrong arg type" ); - - unsigned qos=luaL_checkinteger( L, 3); - if (!(qos == QOS0 || qos == QOS1 ||qos == QOS2)) - return luaL_error( L, "QoS wrong arg type" ); - - mqtt_subscribe(handle[id].pClient, topic, qos); - - return 0; + unsigned id = luaL_checkinteger(L, 1); + if (handle[id].pClient == NULL || id >= MAX_MQTT_NUM) + return luaL_error(L, "mqttClt arg is wrong!"); + size_t sl = 0; + char const *topic = luaL_checklstring(L, 2, &sl); + if (topic == NULL) + return luaL_error(L, "wrong arg type"); + + unsigned qos = luaL_checkinteger(L, 3); + if (!(qos == QOS0 || qos == QOS1 || qos == QOS2)) + return luaL_error(L, "QoS wrong arg type"); + + mqtt_subscribe(handle[id].pClient, topic, qos); + + return 0; } -//mqtt.unsubscribe(id,topic) -static int lmqtt_unsubscribe( lua_State* L ) +// mqtt.unsubscribe(id,topic) +static int lmqtt_unsubscribe(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1); - if(handle[id].pClient==NULL|| id>=MAX_MQTT_NUM) - return luaL_error( L, "mqttClt arg is wrong!" ); - - size_t sl=0; - char const *topic = luaL_checklstring( L, 2, &sl ); - if (topic == NULL) return luaL_error( L, "wrong arg type" ); - - mqtt_unsubscribe(handle[id].pClient, topic); - return 0; + unsigned id = luaL_checkinteger(L, 1); + if (handle[id].pClient == NULL || id >= MAX_MQTT_NUM) + return luaL_error(L, "mqttClt arg is wrong!"); + + size_t sl = 0; + char const *topic = luaL_checklstring(L, 2, &sl); + if (topic == NULL) + return luaL_error(L, "wrong arg type"); + + mqtt_unsubscribe(handle[id].pClient, topic); + return 0; } -//mqtt.publish(id,topic, data) -static int lmqtt_publish( lua_State* L ) +// mqtt.publish(id,topic, data) +static int lmqtt_publish(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1); - if(handle[id].pClient==NULL|| id>=MAX_MQTT_NUM) - return luaL_error( L, "mqttClt arg is wrong!" ); - size_t sl=0; - char const *topic = luaL_checklstring( L, 2, &sl ); - if (topic == NULL) return luaL_error( L, "wrong arg type" ); - - char const *data = luaL_checklstring( L, 3, &sl ); - if (data == NULL) return luaL_error( L, "wrong arg type" ); - - mqtt_publish(handle[id].pClient, topic, data, strlen(data), 0, 0); - return 0; + unsigned id = luaL_checkinteger(L, 1); + if (handle[id].pClient == NULL || id >= MAX_MQTT_NUM) + return luaL_error(L, "mqttClt arg is wrong!"); + size_t sl = 0; + char const *topic = luaL_checklstring(L, 2, &sl); + if (topic == NULL) + return luaL_error(L, "wrong arg type"); + + char const *data = luaL_checklstring(L, 3, &sl); + if (data == NULL) + return luaL_error(L, "wrong arg type"); + + mqtt_publish(handle[id].pClient, topic, data, strlen(data), 0, 0); + return 0; } -//mqtt.on(handle,'connect',function()) -//mqtt.on(handle,'disconnect',function()) -//mqtt.on(handle,'data',function(topic, data)) // the callback is different from the others -//mqtt.on(handle,'reconnect',function()) -//mqtt.on(handle,'subscribe',function()) -//mqtt.on(handle,'publish',function()) +// mqtt.on(handle,'connect',function()) +// mqtt.on(handle,'disconnect',function()) +// mqtt.on(handle,'data',function(topic, data)) // the callback is different +// from the others mqtt.on(handle,'reconnect',function()) +// mqtt.on(handle,'subscribe',function()) +// mqtt.on(handle,'publish',function()) // different topics with same callback -static int lmqtt_on( lua_State* L ) +static int lmqtt_on(lua_State *L) { - unsigned id = luaL_checkinteger( L, 1); - if(handle[id].pClient==NULL|| id>=MAX_MQTT_NUM) - return luaL_error( L, "mqttClt arg is wrong!" ); - size_t sl=0; - char const *method = luaL_checklstring( L, 2, &sl ); - if (method == NULL) return luaL_error( L, "wrong arg type" ); - - if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION) { - lua_pushvalue(L, 3); - } - else { - return luaL_error( L, "callback function needed" ); - } - - if(strcmp(method,"data")==0 && sl==strlen("data")) { - if( handle[id].cb_ref_data!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_data); - } - handle[id].cb_ref_data = luaL_ref(L, LUA_REGISTRYINDEX); - } - else if(strcmp(method,"disconnect")==0&&sl==strlen("disconnect")) { - if( handle[id].cb_ref_disconnect!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_disconnect); - } - handle[id].cb_ref_disconnect = luaL_ref(L, LUA_REGISTRYINDEX); - } - else if(strcmp(method,"publish")==0&&sl==strlen("publish")) { - if( handle[id].cb_ref_publish!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_publish); - } - handle[id].cb_ref_publish = luaL_ref(L, LUA_REGISTRYINDEX); - } - else if(strcmp(method,"reconnect")==0&&sl==strlen("reconnect")) { - if( handle[id].cb_ref_reconnect!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_reconnect); - } - handle[id].cb_ref_reconnect = luaL_ref(L, LUA_REGISTRYINDEX); - } - else if(strcmp(method,"connect")==0&&sl==strlen("connect")) { - if( handle[id].cb_ref_connect!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_connect); - } - handle[id].cb_ref_connect = luaL_ref(L, LUA_REGISTRYINDEX); - } - else if(strcmp(method,"subscribe")==0&&sl==strlen("subscribe")){ - if( handle[id].cb_ref_subscribe!= LUA_NOREF) { - luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_subscribe); - } - handle[id].cb_ref_subscribe = luaL_ref(L, LUA_REGISTRYINDEX); - } - else { - return luaL_error( L, "wrong method" ); - } - return 0; + unsigned id = luaL_checkinteger(L, 1); + if (handle[id].pClient == NULL || id >= MAX_MQTT_NUM) + return luaL_error(L, "mqttClt arg is wrong!"); + size_t sl = 0; + char const *method = luaL_checklstring(L, 2, &sl); + if (method == NULL) + return luaL_error(L, "wrong arg type"); + + if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION) + { + lua_pushvalue(L, 3); + } + else + { + return luaL_error(L, "callback function needed"); + } + + if (strcmp(method, "data") == 0 && sl == strlen("data")) + { + if (handle[id].cb_ref_data != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_data); + } + handle[id].cb_ref_data = luaL_ref(L, LUA_REGISTRYINDEX); + } + else if (strcmp(method, "disconnect") == 0 && sl == strlen("disconnect")) + { + if (handle[id].cb_ref_disconnect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_disconnect); + } + handle[id].cb_ref_disconnect = luaL_ref(L, LUA_REGISTRYINDEX); + } + else if (strcmp(method, "publish") == 0 && sl == strlen("publish")) + { + if (handle[id].cb_ref_publish != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_publish); + } + handle[id].cb_ref_publish = luaL_ref(L, LUA_REGISTRYINDEX); + } + else if (strcmp(method, "reconnect") == 0 && sl == strlen("reconnect")) + { + if (handle[id].cb_ref_reconnect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_reconnect); + } + handle[id].cb_ref_reconnect = luaL_ref(L, LUA_REGISTRYINDEX); + } + else if (strcmp(method, "connect") == 0 && sl == strlen("connect")) + { + if (handle[id].cb_ref_connect != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_connect); + } + handle[id].cb_ref_connect = luaL_ref(L, LUA_REGISTRYINDEX); + } + else if (strcmp(method, "subscribe") == 0 && sl == strlen("subscribe")) + { + if (handle[id].cb_ref_subscribe != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, handle[id].cb_ref_subscribe); + } + handle[id].cb_ref_subscribe = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { + return luaL_error(L, "wrong method"); + } + return 0; } /* mqttClt = mqtt.new(clientid,keepalive,user,pass) @@ -459,27 +527,18 @@ mqtt.subscribe(mqttClt,topic,QoS,cb_messagearrived(topic,message)) mqtt.unsubscribe(mqttClt,topic) */ - - #include "lrodefs.h" -const LUA_REG_TYPE mqtt_map[] = -{ - { LSTRKEY( "new" ), LFUNCVAL( lmqtt_new )}, - { LSTRKEY( "close" ), LFUNCVAL( lmqtt_close )}, - { LSTRKEY( "subscribe" ), LFUNCVAL( lmqtt_subscribe )}, - { LSTRKEY( "unsubscribe" ), LFUNCVAL( lmqtt_unsubscribe )}, - { LSTRKEY( "publish" ), LFUNCVAL( lmqtt_publish )}, - { LSTRKEY( "on" ), LFUNCVAL( lmqtt_on )}, +const LUA_REG_TYPE mqtt_map[] = {{LSTRKEY("new"), LFUNCVAL(lmqtt_new)}, + {LSTRKEY("close"), LFUNCVAL(lmqtt_close)}, + {LSTRKEY("subscribe"), LFUNCVAL(lmqtt_subscribe)}, + {LSTRKEY("unsubscribe"), LFUNCVAL(lmqtt_unsubscribe)}, + {LSTRKEY("publish"), LFUNCVAL(lmqtt_publish)}, + {LSTRKEY("on"), LFUNCVAL(lmqtt_on)}, #if LUA_OPTIMIZE_MEMORY > 0 - { LSTRKEY( "QOS0" ), LNUMVAL( QOS0 ) }, - { LSTRKEY( "QOS1" ), LNUMVAL( QOS1 ) }, - { LSTRKEY( "QOS2" ), LNUMVAL( QOS2 ) }, -#endif - {LNILKEY, LNILVAL} -}; - -int luaopen_mqtt(lua_State *L) -{ - return 0; -} + {LSTRKEY("QOS0"), LNUMVAL(QOS0)}, + {LSTRKEY("QOS1"), LNUMVAL(QOS1)}, + {LSTRKEY("QOS2"), LNUMVAL(QOS2)}, +#endif + {LNILKEY, LNILVAL}}; +int luaopen_mqtt(lua_State *L) { return 0; } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/net.c b/LuaNode_Esp32/LuaNode32/components/modules/net.c index 927367a..9f6d5ae 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/net.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/net.c @@ -1,42 +1,37 @@ // Module for network -#include "modules.h" -#include "lauxlib.h" -#include "platform.h" -#include "lmem.h" -#include "ip_fmt.h" -#include "task/task.h" -#include "user_config.h" - -#include #include #include +#include "ip_fmt.h" +#include "lauxlib.h" +#include "lmem.h" +#include "lwip/dns.h" #include "lwip/err.h" -#include "lwip/ip_addr.h" -#include "lwip/dns.h" #include "lwip/igmp.h" +#include "lwip/ip_addr.h" #include "lwip/tcp.h" #include "lwip/udp.h" +#include "modules.h" +#include "platform.h" +#include "task/task.h" +#include "user_config.h" // Some LWIP macros cause complaints with ptr NULL checks, so shut them off :( #pragma GCC diagnostic ignored "-Waddress" static int myref; -typedef enum net_type { - TYPE_TCP_SERVER = 0, - TYPE_TCP_CLIENT, - TYPE_UDP_SOCKET +typedef enum net_type +{ + TYPE_TCP_SERVER = 0, + TYPE_TCP_CLIENT, + TYPE_UDP_SOCKET } net_type; typedef const char net_table_name[14]; -static const net_table_name NET_TABLES[] = { - "net.tcpserver", - "net.tcpsocket", - "net.udpsocket" -}; +static const net_table_name NET_TABLES[] = {"net.tcpserver", "net.tcpsocket", "net.udpsocket"}; #define NET_TABLE_TCP_SERVER NET_TABLES[0] #define NET_TABLE_TCP_CLIENT NET_TABLES[1] #define NET_TABLE_UDP_SOCKET NET_TABLES[2] @@ -44,1069 +39,1276 @@ static const net_table_name NET_TABLES[] = { #define TYPE_TCP TYPE_TCP_CLIENT #define TYPE_UDP TYPE_UDP_SOCKET -typedef struct lnet_userdata { - enum net_type type; - int self_ref; - union { - struct tcp_pcb *tcp_pcb; - struct udp_pcb *udp_pcb; - void *pcb; - }; - union { - struct { - int cb_accept_ref; - } server; - struct { - int wait_dns; - int cb_dns_ref; - int cb_receive_ref; - int cb_sent_ref; - // Only for TCP: - int hold; - int cb_connect_ref; - int cb_disconnect_ref; - int cb_reconnect_ref; - } client; - }; +typedef struct lnet_userdata +{ + enum net_type type; + int self_ref; + union { + struct tcp_pcb *tcp_pcb; + struct udp_pcb *udp_pcb; + void *pcb; + }; + union { + struct + { + int cb_accept_ref; + } server; + struct + { + int wait_dns; + int cb_dns_ref; + int cb_receive_ref; + int cb_sent_ref; + // Only for TCP: + int hold; + int cb_connect_ref; + int cb_disconnect_ref; + int cb_reconnect_ref; + } client; + }; } lnet_userdata; - - // --- Event handling -typedef struct { - ip_addr_t src_ip; - uint16_t src_port; - uint16_t payload_len; - char payload[0]; +typedef struct +{ + ip_addr_t src_ip; + uint16_t src_port; + uint16_t payload_len; + char payload[0]; } lnet_recvdata; - -typedef struct { - enum { - DNSFOUND, - DNSSTATIC, - CONNECTED, - ACCEPT, - RECVDATA, - SENTDATA, - ERR - } event; - union { - lnet_userdata *ud; - int cb_ref; - }; - union { - struct tcp_pcb *accept_newpcb; - lnet_recvdata recvdata; - ip_addr_t resolved_ip; - int err; - }; +typedef struct +{ + enum + { + DNSFOUND, + DNSSTATIC, + CONNECTED, + ACCEPT, + RECVDATA, + SENTDATA, + ERR + } event; + union { + lnet_userdata *ud; + int cb_ref; + }; + union { + struct tcp_pcb *accept_newpcb; + lnet_recvdata recvdata; + ip_addr_t resolved_ip; + int err; + }; } lnet_event; static task_handle_t net_event; -int net_mycall(lua_State *L) { - if(myref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, myref); - lua_pcall(L,0,0,0); - } - printf("myref = 0\n"); - return 0; +int net_mycall(lua_State *L) +{ + if (myref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, myref); + lua_pcall(L, 0, 0, 0); + } + printf("myref = 0\n"); + return 0; } -int net_myregistrer(lua_State *L) { - int argc = lua_gettop(L); - lua_pushvalue(L,1); - myref = luaL_ref(L, LUA_REGISTRYINDEX); - return 0; +int net_myregistrer(lua_State *L) +{ + int argc = lua_gettop(L); + lua_pushvalue(L, 1); + myref = luaL_ref(L, LUA_REGISTRYINDEX); + return 0; } // --- LWIP errors -int lwip_lua_checkerr (lua_State *L, err_t err) { - switch (err) { - case ERR_OK: return 0; - case ERR_MEM: return luaL_error(L, "out of memory"); - case ERR_BUF: return luaL_error(L, "buffer error"); - case ERR_TIMEOUT: return luaL_error(L, "timeout"); - case ERR_RTE: return luaL_error(L, "routing problem"); - case ERR_INPROGRESS: return luaL_error(L, "in progress"); - case ERR_VAL: return luaL_error(L, "illegal value"); - case ERR_WOULDBLOCK: return luaL_error(L, "would block"); - case ERR_ABRT: return luaL_error(L, "connection aborted"); - case ERR_RST: return luaL_error(L, "connection reset"); - case ERR_CLSD: return luaL_error(L, "connection closed"); - case ERR_CONN: return luaL_error(L, "not connected"); - case ERR_ARG: return luaL_error(L, "illegal argument"); - case ERR_USE: return luaL_error(L, "address in use"); - case ERR_IF: return luaL_error(L, "netif error"); - case ERR_ISCONN: return luaL_error(L, "already connected"); - default: return luaL_error(L, "unknown error"); - } +int lwip_lua_checkerr(lua_State *L, err_t err) +{ + switch (err) + { + case ERR_OK: + return 0; + case ERR_MEM: + return luaL_error(L, "out of memory"); + case ERR_BUF: + return luaL_error(L, "buffer error"); + case ERR_TIMEOUT: + return luaL_error(L, "timeout"); + case ERR_RTE: + return luaL_error(L, "routing problem"); + case ERR_INPROGRESS: + return luaL_error(L, "in progress"); + case ERR_VAL: + return luaL_error(L, "illegal value"); + case ERR_WOULDBLOCK: + return luaL_error(L, "would block"); + case ERR_ABRT: + return luaL_error(L, "connection aborted"); + case ERR_RST: + return luaL_error(L, "connection reset"); + case ERR_CLSD: + return luaL_error(L, "connection closed"); + case ERR_CONN: + return luaL_error(L, "not connected"); + case ERR_ARG: + return luaL_error(L, "illegal argument"); + case ERR_USE: + return luaL_error(L, "address in use"); + case ERR_IF: + return luaL_error(L, "netif error"); + case ERR_ISCONN: + return luaL_error(L, "already connected"); + default: + return luaL_error(L, "unknown error"); + } } // --- Create -lnet_userdata *net_create( lua_State *L, enum net_type type ) { - const char *mt = NET_TABLES[type]; - lnet_userdata *ud = (lnet_userdata *)lua_newuserdata(L, sizeof(lnet_userdata)); - if (!ud) return NULL; - luaL_getmetatable(L, mt); - lua_setmetatable(L, -2); - - ud->type = type; - ud->self_ref = LUA_NOREF; - ud->pcb = NULL; - - switch (type) { - case TYPE_TCP_CLIENT: - ud->client.cb_connect_ref = LUA_NOREF; - ud->client.cb_reconnect_ref = LUA_NOREF; - ud->client.cb_disconnect_ref = LUA_NOREF; - ud->client.hold = 0; - case TYPE_UDP_SOCKET: - ud->client.wait_dns = 0; - ud->client.cb_dns_ref = LUA_NOREF; - ud->client.cb_receive_ref = LUA_NOREF; - ud->client.cb_sent_ref = LUA_NOREF; - break; - case TYPE_TCP_SERVER: - ud->server.cb_accept_ref = LUA_NOREF; - break; - } - return ud; +lnet_userdata *net_create(lua_State *L, enum net_type type) +{ + const char *mt = NET_TABLES[type]; + lnet_userdata *ud = (lnet_userdata *)lua_newuserdata(L, sizeof(lnet_userdata)); + if (!ud) + return NULL; + luaL_getmetatable(L, mt); + lua_setmetatable(L, -2); + + ud->type = type; + ud->self_ref = LUA_NOREF; + ud->pcb = NULL; + + switch (type) + { + case TYPE_TCP_CLIENT: + ud->client.cb_connect_ref = LUA_NOREF; + ud->client.cb_reconnect_ref = LUA_NOREF; + ud->client.cb_disconnect_ref = LUA_NOREF; + ud->client.hold = 0; + case TYPE_UDP_SOCKET: + ud->client.wait_dns = 0; + ud->client.cb_dns_ref = LUA_NOREF; + ud->client.cb_receive_ref = LUA_NOREF; + ud->client.cb_sent_ref = LUA_NOREF; + break; + case TYPE_TCP_SERVER: + ud->server.cb_accept_ref = LUA_NOREF; + break; + } + return ud; } // --- LWIP callbacks and task_post helpers -static bool post_net_err (lnet_userdata *ud, err_t err) { - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event)); - if (!ev) - return false; - ev->event = ERR; - ev->ud = ud; - ev->err = err; - if (!task_post_medium (net_event, (task_param_t)ev)) { - free (ev); - return false; - } - return true; +static bool post_net_err(lnet_userdata *ud, err_t err) +{ + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event)); + if (!ev) + return false; + ev->event = ERR; + ev->ud = ud; + ev->err = err; + if (!task_post_medium(net_event, (task_param_t)ev)) + { + free(ev); + return false; + } + return true; } -static void net_err_cb(void *arg, err_t err) { - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud || ud->type != TYPE_TCP_CLIENT || ud->self_ref == LUA_NOREF) return; - ud->pcb = NULL; // Will be freed at LWIP level +static void net_err_cb(void *arg, err_t err) +{ + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud || ud->type != TYPE_TCP_CLIENT || ud->self_ref == LUA_NOREF) + return; + ud->pcb = NULL; // Will be freed at LWIP level - post_net_err (ud, err); + post_net_err(ud, err); } - -static bool post_net_connected (lnet_userdata *ud) { - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event)); - if (!ev) - return false; - ev->event = CONNECTED; - ev->ud = ud; - if (!task_post_medium (net_event, (task_param_t)ev)) { - free (ev); - return false; - } - return true; +static bool post_net_connected(lnet_userdata *ud) +{ + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event)); + if (!ev) + return false; + ev->event = CONNECTED; + ev->ud = ud; + if (!task_post_medium(net_event, (task_param_t)ev)) + { + free(ev); + return false; + } + return true; } -static err_t net_connected_cb(void *arg, struct tcp_pcb *tpcb, err_t err) { - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud || ud->pcb != tpcb) return ERR_ABRT; - if (err != ERR_OK) { - net_err_cb(arg, err); - return ERR_ABRT; - } - post_net_connected (ud); - return ERR_OK; +static err_t net_connected_cb(void *arg, struct tcp_pcb *tpcb, err_t err) +{ + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud || ud->pcb != tpcb) + return ERR_ABRT; + if (err != ERR_OK) + { + net_err_cb(arg, err); + return ERR_ABRT; + } + post_net_connected(ud); + return ERR_OK; } - -static bool post_net_dns (lnet_userdata *ud, const char *name, const ip_addr_t *ipaddr) +static bool post_net_dns(lnet_userdata *ud, const char *name, const ip_addr_t *ipaddr) { - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event)); - if (!ev || !ipaddr) - return false; - ev->event = DNSFOUND; - ev->ud = ud; - ev->resolved_ip = *ipaddr; - if (!task_post_medium (net_event, (task_param_t)ev)) { - free (ev); - return false; - } - return true; + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event)); + if (!ev || !ipaddr) + return false; + ev->event = DNSFOUND; + ev->ud = ud; + ev->resolved_ip = *ipaddr; + if (!task_post_medium(net_event, (task_param_t)ev)) + { + free(ev); + return false; + } + return true; } -static void net_dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) { - ip_addr_t addr; - if (ipaddr != NULL) addr = *ipaddr; - else addr = ip_addr_any; - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud) return; - - post_net_dns (ud, name, &addr); +static void net_dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) +{ + ip_addr_t addr; + if (ipaddr != NULL) + addr = *ipaddr; + else + addr = ip_addr_any; + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud) + return; + + post_net_dns(ud, name, &addr); } - -static bool post_net_recv (lnet_userdata *ud, struct pbuf *p, const ip_addr_t *ip, u16_t port) +static bool post_net_recv(lnet_userdata *ud, struct pbuf *p, const ip_addr_t *ip, u16_t port) { - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event) + p->len); - if (!ev) - return false; - - ev->event = RECVDATA; - ev->ud = ud; - - if (ip) - ev->recvdata.src_ip = *ip; - ev->recvdata.src_port = port; - ev->recvdata.payload_len = p->len; - pbuf_copy_partial (p, &ev->recvdata.payload, p->len, 0); - - if (!task_post_high (net_event, (task_param_t)ev)) - { - free (ev); - return false; - } - return true; + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event) + p->len); + if (!ev) + return false; + + ev->event = RECVDATA; + ev->ud = ud; + + if (ip) + ev->recvdata.src_ip = *ip; + ev->recvdata.src_port = port; + ev->recvdata.payload_len = p->len; + pbuf_copy_partial(p, &ev->recvdata.payload, p->len, 0); + + if (!task_post_high(net_event, (task_param_t)ev)) + { + free(ev); + return false; + } + return true; } -static void net_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud || !ud->pcb || ud->type != TYPE_UDP_SOCKET || ud->self_ref == LUA_NOREF) { - if (p) pbuf_free(p); - return; - } - post_net_recv (ud, p, addr, port); +static void net_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud || !ud->pcb || ud->type != TYPE_UDP_SOCKET || ud->self_ref == LUA_NOREF) + { + if (p) + pbuf_free(p); + return; + } + post_net_recv(ud, p, addr, port); } -static err_t net_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud || !ud->pcb || ud->type != TYPE_TCP_CLIENT || ud->self_ref == LUA_NOREF) - return ERR_ABRT; - if (!p) { - net_err_cb(arg, err); - return tcp_close(tpcb); - } +static err_t net_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) +{ + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud || !ud->pcb || ud->type != TYPE_TCP_CLIENT || ud->self_ref == LUA_NOREF) + return ERR_ABRT; + if (!p) + { + net_err_cb(arg, err); + return tcp_close(tpcb); + } - if (post_net_recv (ud, p, 0, 0)) - tcp_recved(tpcb, p->len); + if (post_net_recv(ud, p, 0, 0)) + tcp_recved(tpcb, p->len); - return ERR_OK; + return ERR_OK; } - -static bool post_net_sent (lnet_userdata *ud) { - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event)); - if (!ev) - return false; - ev->event = SENTDATA; - ev->ud = ud; - if (!task_post_medium (net_event, (task_param_t)ev)) { - free (ev); - return false; - } - return true; +static bool post_net_sent(lnet_userdata *ud) +{ + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event)); + if (!ev) + return false; + ev->event = SENTDATA; + ev->ud = ud; + if (!task_post_medium(net_event, (task_param_t)ev)) + { + free(ev); + return false; + } + return true; } -static err_t net_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len) { - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud || !ud->pcb || ud->type != TYPE_TCP_CLIENT || ud->self_ref == LUA_NOREF) return ERR_ABRT; - if (ud->client.cb_sent_ref == LUA_NOREF) return ERR_OK; - - post_net_sent (ud); - // TODO: if we can't post this, we effectively stall this socket, how to fix? - return ERR_OK; +static err_t net_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud || !ud->pcb || ud->type != TYPE_TCP_CLIENT || ud->self_ref == LUA_NOREF) + return ERR_ABRT; + if (ud->client.cb_sent_ref == LUA_NOREF) + return ERR_OK; + + post_net_sent(ud); + // TODO: if we can't post this, we effectively stall this socket, how to + // fix? + return ERR_OK; } - -static bool post_net_accept (lnet_userdata *ud, struct tcp_pcb *newpcb) { - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event)); - if (!ev) - return false; - ev->event = SENTDATA; - ev->ud = ud; - ev->accept_newpcb = newpcb; - if (!task_post_medium (net_event, (task_param_t)ev)) { - free (ev); - return false; - } - return true; +static bool post_net_accept(lnet_userdata *ud, struct tcp_pcb *newpcb) +{ + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event)); + if (!ev) + return false; + ev->event = SENTDATA; + ev->ud = ud; + ev->accept_newpcb = newpcb; + if (!task_post_medium(net_event, (task_param_t)ev)) + { + free(ev); + return false; + } + return true; } +static err_t net_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + lnet_userdata *ud = (lnet_userdata *)arg; + if (!ud || ud->type != TYPE_TCP_SERVER || !ud->pcb) + return ERR_ABRT; + if (ud->self_ref == LUA_NOREF || ud->server.cb_accept_ref == LUA_NOREF) + return ERR_ABRT; -static err_t net_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { - lnet_userdata *ud = (lnet_userdata*)arg; - if (!ud || ud->type != TYPE_TCP_SERVER || !ud->pcb) return ERR_ABRT; - if (ud->self_ref == LUA_NOREF || ud->server.cb_accept_ref == LUA_NOREF) return ERR_ABRT; - - return post_net_accept (ud, newpcb) ? ERR_OK : ERR_ABRT; + return post_net_accept(ud, newpcb) ? ERR_OK : ERR_ABRT; } // --- Lua API - create -extern int tls_socket_create( lua_State *L ); +extern int tls_socket_create(lua_State *L); // Lua: net.createUDPSocket() -int net_createUDPSocket( lua_State *L ) { - net_create(L, TYPE_UDP_SOCKET); - return 1; +int net_createUDPSocket(lua_State *L) +{ + net_create(L, TYPE_UDP_SOCKET); + return 1; } // Lua: net.createServer(type, timeout) -int net_createServer( lua_State *L ) { - int type, timeout; +int net_createServer(lua_State *L) +{ + int type, timeout; - type = luaL_optlong(L, 1, TYPE_TCP); - timeout = luaL_optlong(L, 2, 30); + type = luaL_optlong(L, 1, TYPE_TCP); + timeout = luaL_optlong(L, 2, 30); - if (type == TYPE_UDP) return net_createUDPSocket( L ); - if (type != TYPE_TCP) return luaL_error(L, "invalid type"); + if (type == TYPE_UDP) + return net_createUDPSocket(L); + if (type != TYPE_TCP) + return luaL_error(L, "invalid type"); - net_create(L, TYPE_TCP_SERVER); - // TODO: timeout - (void)timeout; - return 1; + net_create(L, TYPE_TCP_SERVER); + // TODO: timeout + (void)timeout; + return 1; } // Lua: net.createConnection(type, secure) -int net_createConnection( lua_State *L ) { - int type, secure; +int net_createConnection(lua_State *L) +{ + int type, secure; - type = luaL_optlong(L, 1, TYPE_TCP); - secure = luaL_optlong(L, 2, 0); + type = luaL_optlong(L, 1, TYPE_TCP); + secure = luaL_optlong(L, 2, 0); - if (type == TYPE_UDP) return net_createUDPSocket( L ); - if (type != TYPE_TCP) return luaL_error(L, "invalid type"); - if (secure) { + if (type == TYPE_UDP) + return net_createUDPSocket(L); + if (type != TYPE_TCP) + return luaL_error(L, "invalid type"); + if (secure) + { #ifdef CLIENT_SSL_ENABLE - return tls_socket_create( L ); + return tls_socket_create(L); #else - return luaL_error(L, "secure connections not enabled"); + return luaL_error(L, "secure connections not enabled"); #endif - } - net_create(L, TYPE_TCP_CLIENT); - return 1; + } + net_create(L, TYPE_TCP_CLIENT); + return 1; } // --- Get & check userdata -lnet_userdata *net_get_udata_s( lua_State *L, int stack ) { - if (!lua_isuserdata(L, stack)) return NULL; - lnet_userdata *ud = (lnet_userdata *)lua_touserdata(L, stack); - switch (ud->type) { - case TYPE_TCP_CLIENT: - case TYPE_TCP_SERVER: - case TYPE_UDP_SOCKET: - break; - default: return NULL; - } - const char *mt = NET_TABLES[ud->type]; - ud = luaL_checkudata(L, stack, mt); - return ud; +lnet_userdata *net_get_udata_s(lua_State *L, int stack) +{ + if (!lua_isuserdata(L, stack)) + return NULL; + lnet_userdata *ud = (lnet_userdata *)lua_touserdata(L, stack); + switch (ud->type) + { + case TYPE_TCP_CLIENT: + case TYPE_TCP_SERVER: + case TYPE_UDP_SOCKET: + break; + default: + return NULL; + } + const char *mt = NET_TABLES[ud->type]; + ud = luaL_checkudata(L, stack, mt); + return ud; } #define net_get_udata(L) net_get_udata_s(L, 1) // --- Lua API // Lua: server:listen(port, addr, function(c)), socket:listen(port, addr) -int net_listen( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type == TYPE_TCP_CLIENT) - return luaL_error(L, "invalid user data"); - if (ud->pcb) - return luaL_error(L, "already listening"); - int stack = 2; - uint16_t port = 0; - const char *domain = "0.0.0.0"; - if (lua_isnumber(L, stack)) - port = lua_tointeger(L, stack++); - if (lua_isstring(L, stack)) { - size_t dl = 0; - domain = luaL_checklstring(L, stack++, &dl); - } - ip_addr_t addr; - if (!ipaddr_aton(domain, &addr)) - return luaL_error(L, "invalid IP address"); - if (ud->type == TYPE_TCP_SERVER) { - if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) { - lua_pushvalue(L, stack++); - luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); - ud->server.cb_accept_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } else { - return luaL_error(L, "need callback"); - } - } - err_t err = ERR_OK; - switch (ud->type) { - case TYPE_TCP_SERVER: - ud->tcp_pcb = tcp_new(); - if (!ud->tcp_pcb) - return luaL_error(L, "cannot allocate PCB"); - err = tcp_bind(ud->tcp_pcb, &addr, port); - if (err == ERR_OK) { - tcp_arg(ud->tcp_pcb, ud); - struct tcp_pcb *pcb = tcp_listen(ud->tcp_pcb); - if (!pcb) { - err = ERR_MEM; - } else { - ud->tcp_pcb = pcb; - tcp_accept(ud->tcp_pcb, net_accept_cb); +int net_listen(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type == TYPE_TCP_CLIENT) + return luaL_error(L, "invalid user data"); + if (ud->pcb) + return luaL_error(L, "already listening"); + int stack = 2; + uint16_t port = 0; + const char *domain = "0.0.0.0"; + if (lua_isnumber(L, stack)) + port = lua_tointeger(L, stack++); + if (lua_isstring(L, stack)) + { + size_t dl = 0; + domain = luaL_checklstring(L, stack++, &dl); + } + ip_addr_t addr; + if (!ipaddr_aton(domain, &addr)) + return luaL_error(L, "invalid IP address"); + if (ud->type == TYPE_TCP_SERVER) + { + if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) + { + lua_pushvalue(L, stack++); + luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); + ud->server.cb_accept_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { + return luaL_error(L, "need callback"); } - } - break; - case TYPE_UDP_SOCKET: - ud->udp_pcb = udp_new(); - if (!ud->udp_pcb) - return luaL_error(L, "cannot allocate PCB"); - udp_recv(ud->udp_pcb, net_udp_recv_cb, ud); - err = udp_bind(ud->udp_pcb, &addr, port); - break; - default: break; - } - if (err != ERR_OK) { - switch (ud->type) { - case TYPE_TCP_SERVER: - tcp_close(ud->tcp_pcb); - ud->tcp_pcb = NULL; - break; - case TYPE_UDP_SOCKET: - udp_remove(ud->udp_pcb); - ud->udp_pcb = NULL; - break; - default: break; } - return lwip_lua_checkerr(L, err); - } - if (ud->self_ref == LUA_NOREF) { - lua_pushvalue(L, 1); - ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - return 0; + err_t err = ERR_OK; + switch (ud->type) + { + case TYPE_TCP_SERVER: + ud->tcp_pcb = tcp_new(); + if (!ud->tcp_pcb) + return luaL_error(L, "cannot allocate PCB"); + err = tcp_bind(ud->tcp_pcb, &addr, port); + if (err == ERR_OK) + { + tcp_arg(ud->tcp_pcb, ud); + struct tcp_pcb *pcb = tcp_listen(ud->tcp_pcb); + if (!pcb) + { + err = ERR_MEM; + } + else + { + ud->tcp_pcb = pcb; + tcp_accept(ud->tcp_pcb, net_accept_cb); + } + } + break; + case TYPE_UDP_SOCKET: + ud->udp_pcb = udp_new(); + if (!ud->udp_pcb) + return luaL_error(L, "cannot allocate PCB"); + udp_recv(ud->udp_pcb, net_udp_recv_cb, ud); + err = udp_bind(ud->udp_pcb, &addr, port); + break; + default: + break; + } + if (err != ERR_OK) + { + switch (ud->type) + { + case TYPE_TCP_SERVER: + tcp_close(ud->tcp_pcb); + ud->tcp_pcb = NULL; + break; + case TYPE_UDP_SOCKET: + udp_remove(ud->udp_pcb); + ud->udp_pcb = NULL; + break; + default: + break; + } + return lwip_lua_checkerr(L, err); + } + if (ud->self_ref == LUA_NOREF) + { + lua_pushvalue(L, 1); + ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + return 0; } // Lua: client:connect(port, addr) -int net_connect( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type != TYPE_TCP_CLIENT) - return luaL_error(L, "invalid user data"); - if (ud->pcb) - return luaL_error(L, "already connected"); - uint16_t port = luaL_checkinteger(L, 2); - if (port == 0) - return luaL_error(L, "specify port"); - const char *domain = "127.0.0.1"; - if (lua_isstring(L, 3)) { - size_t dl = 0; - domain = luaL_checklstring(L, 3, &dl); - } - ud->tcp_pcb = tcp_new(); - if (!ud->tcp_pcb) - return luaL_error(L, "cannot allocate PCB"); - tcp_arg(ud->tcp_pcb, ud); - tcp_err(ud->tcp_pcb, net_err_cb); - tcp_recv(ud->tcp_pcb, net_tcp_recv_cb); - tcp_sent(ud->tcp_pcb, net_sent_cb); - ud->tcp_pcb->remote_port = port; - ip_addr_t addr; - ud->client.wait_dns ++; - int unref = 0; - if (ud->self_ref == LUA_NOREF) { - unref = 1; - lua_pushvalue(L, 1); - ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - err_t err = dns_gethostbyname(domain, &addr, net_dns_cb, ud); - if (err == ERR_OK) { - net_dns_cb(domain, &addr, ud); - } else if (err != ERR_INPROGRESS) { - ud->client.wait_dns --; - if (unref) { - luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); - ud->self_ref = LUA_NOREF; - } - tcp_abort(ud->tcp_pcb); - ud->tcp_pcb = NULL; - return lwip_lua_checkerr(L, err); - } - return 0; +int net_connect(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type != TYPE_TCP_CLIENT) + return luaL_error(L, "invalid user data"); + if (ud->pcb) + return luaL_error(L, "already connected"); + uint16_t port = luaL_checkinteger(L, 2); + if (port == 0) + return luaL_error(L, "specify port"); + const char *domain = "127.0.0.1"; + if (lua_isstring(L, 3)) + { + size_t dl = 0; + domain = luaL_checklstring(L, 3, &dl); + } + ud->tcp_pcb = tcp_new(); + if (!ud->tcp_pcb) + return luaL_error(L, "cannot allocate PCB"); + tcp_arg(ud->tcp_pcb, ud); + tcp_err(ud->tcp_pcb, net_err_cb); + tcp_recv(ud->tcp_pcb, net_tcp_recv_cb); + tcp_sent(ud->tcp_pcb, net_sent_cb); + ud->tcp_pcb->remote_port = port; + ip_addr_t addr; + ud->client.wait_dns++; + int unref = 0; + if (ud->self_ref == LUA_NOREF) + { + unref = 1; + lua_pushvalue(L, 1); + ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + err_t err = dns_gethostbyname(domain, &addr, net_dns_cb, ud); + if (err == ERR_OK) + { + net_dns_cb(domain, &addr, ud); + } + else if (err != ERR_INPROGRESS) + { + ud->client.wait_dns--; + if (unref) + { + luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); + ud->self_ref = LUA_NOREF; + } + tcp_abort(ud->tcp_pcb); + ud->tcp_pcb = NULL; + return lwip_lua_checkerr(L, err); + } + return 0; } // Lua: client/socket:on(name, callback) -int net_on( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type == TYPE_TCP_SERVER) - return luaL_error(L, "invalid user data"); - int *refptr = NULL; - const char *name = luaL_checkstring(L, 2); - if (!name) return luaL_error(L, "need callback name"); - switch (ud->type) { - case TYPE_TCP_CLIENT: - if (strcmp("connection",name)==0) - { refptr = &ud->client.cb_connect_ref; break; } - if (strcmp("disconnection",name)==0) - { refptr = &ud->client.cb_disconnect_ref; break; } - if (strcmp("reconnection",name)==0) - { refptr = &ud->client.cb_reconnect_ref; break; } - case TYPE_UDP_SOCKET: - if (strcmp("dns",name)==0) - { refptr = &ud->client.cb_dns_ref; break; } - if (strcmp("receive",name)==0) - { refptr = &ud->client.cb_receive_ref; break; } - if (strcmp("sent",name)==0) - { refptr = &ud->client.cb_sent_ref; break; } - break; - default: return luaL_error(L, "invalid user data"); - } - if (refptr == NULL) - return luaL_error(L, "invalid callback name"); - if (lua_isfunction(L, 3) || lua_islightfunction(L, 3)) { - lua_pushvalue(L, 3); - luaL_unref(L, LUA_REGISTRYINDEX, *refptr); - *refptr = luaL_ref(L, LUA_REGISTRYINDEX); - } else if (lua_isnil(L, 3)) { - luaL_unref(L, LUA_REGISTRYINDEX, *refptr); - *refptr = LUA_NOREF; - } else { - return luaL_error(L, "invalid callback function"); - } - return 0; +int net_on(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type == TYPE_TCP_SERVER) + return luaL_error(L, "invalid user data"); + int *refptr = NULL; + const char *name = luaL_checkstring(L, 2); + if (!name) + return luaL_error(L, "need callback name"); + switch (ud->type) + { + case TYPE_TCP_CLIENT: + if (strcmp("connection", name) == 0) + { + refptr = &ud->client.cb_connect_ref; + break; + } + if (strcmp("disconnection", name) == 0) + { + refptr = &ud->client.cb_disconnect_ref; + break; + } + if (strcmp("reconnection", name) == 0) + { + refptr = &ud->client.cb_reconnect_ref; + break; + } + case TYPE_UDP_SOCKET: + if (strcmp("dns", name) == 0) + { + refptr = &ud->client.cb_dns_ref; + break; + } + if (strcmp("receive", name) == 0) + { + refptr = &ud->client.cb_receive_ref; + break; + } + if (strcmp("sent", name) == 0) + { + refptr = &ud->client.cb_sent_ref; + break; + } + break; + default: + return luaL_error(L, "invalid user data"); + } + if (refptr == NULL) + return luaL_error(L, "invalid callback name"); + if (lua_isfunction(L, 3) || lua_islightfunction(L, 3)) + { + lua_pushvalue(L, 3); + luaL_unref(L, LUA_REGISTRYINDEX, *refptr); + *refptr = luaL_ref(L, LUA_REGISTRYINDEX); + } + else if (lua_isnil(L, 3)) + { + luaL_unref(L, LUA_REGISTRYINDEX, *refptr); + *refptr = LUA_NOREF; + } + else + { + return luaL_error(L, "invalid callback function"); + } + return 0; } // Lua: client:send(data, function(c)), socket:send(port, ip, data, function(s)) -int net_send( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type == TYPE_TCP_SERVER) - return luaL_error(L, "invalid user data"); - ip_addr_t addr; - uint16_t port = 0; - const char *data; - size_t datalen = 0; - int stack = 2; - if (ud->type == TYPE_UDP_SOCKET) { - size_t dl = 0; - port = luaL_checkinteger(L, stack++); - if (port == 0) return luaL_error(L, "need port"); - const char *domain = luaL_checklstring(L, stack++, &dl); - if (!domain) return luaL_error(L, "need IP address"); - if (!ipaddr_aton(domain, &addr)) return luaL_error(L, "invalid IP address"); - } - data = luaL_checklstring(L, stack++, &datalen); - if (!data || datalen == 0) return luaL_error(L, "no data to send"); - if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) { - lua_pushvalue(L, stack++); - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); - ud->client.cb_sent_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - if (ud->type == TYPE_UDP_SOCKET && !ud->pcb) { - ud->udp_pcb = udp_new(); - if (!ud->udp_pcb) - return luaL_error(L, "cannot allocate PCB"); - udp_recv(ud->udp_pcb, net_udp_recv_cb, ud); - ip_addr_t laddr = IPADDR_ANY_TYPE_INIT; - err_t err = udp_bind(ud->udp_pcb, &laddr, 0); - if (err != ERR_OK) { - udp_remove(ud->udp_pcb); - ud->udp_pcb = NULL; - return lwip_lua_checkerr(L, err); - } - if (ud->self_ref == LUA_NOREF) { - lua_pushvalue(L, 1); - ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - } - if (!ud->pcb || ud->self_ref == LUA_NOREF) - return luaL_error(L, "not connected"); - err_t err; - if (ud->type == TYPE_UDP_SOCKET) { - struct pbuf *pb = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); - if (!pb) - return luaL_error(L, "cannot allocate message buffer"); - pbuf_take(pb, data, datalen); - err = udp_sendto(ud->udp_pcb, pb, &addr, port); - pbuf_free(pb); - if (ud->client.cb_sent_ref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); - lua_call(L, 1, 0); - } - } else if (ud->type == TYPE_TCP_CLIENT) { - err = tcp_write(ud->tcp_pcb, data, datalen, TCP_WRITE_FLAG_COPY); - } - else { - err = ERR_VAL; - } - return lwip_lua_checkerr(L, err); +int net_send(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type == TYPE_TCP_SERVER) + return luaL_error(L, "invalid user data"); + ip_addr_t addr; + uint16_t port = 0; + const char *data; + size_t datalen = 0; + int stack = 2; + if (ud->type == TYPE_UDP_SOCKET) + { + size_t dl = 0; + port = luaL_checkinteger(L, stack++); + if (port == 0) + return luaL_error(L, "need port"); + const char *domain = luaL_checklstring(L, stack++, &dl); + if (!domain) + return luaL_error(L, "need IP address"); + if (!ipaddr_aton(domain, &addr)) + return luaL_error(L, "invalid IP address"); + } + data = luaL_checklstring(L, stack++, &datalen); + if (!data || datalen == 0) + return luaL_error(L, "no data to send"); + if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) + { + lua_pushvalue(L, stack++); + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); + ud->client.cb_sent_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + if (ud->type == TYPE_UDP_SOCKET && !ud->pcb) + { + ud->udp_pcb = udp_new(); + if (!ud->udp_pcb) + return luaL_error(L, "cannot allocate PCB"); + udp_recv(ud->udp_pcb, net_udp_recv_cb, ud); + ip_addr_t laddr = IPADDR_ANY_TYPE_INIT; + err_t err = udp_bind(ud->udp_pcb, &laddr, 0); + if (err != ERR_OK) + { + udp_remove(ud->udp_pcb); + ud->udp_pcb = NULL; + return lwip_lua_checkerr(L, err); + } + if (ud->self_ref == LUA_NOREF) + { + lua_pushvalue(L, 1); + ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + } + if (!ud->pcb || ud->self_ref == LUA_NOREF) + return luaL_error(L, "not connected"); + err_t err; + if (ud->type == TYPE_UDP_SOCKET) + { + struct pbuf *pb = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); + if (!pb) + return luaL_error(L, "cannot allocate message buffer"); + pbuf_take(pb, data, datalen); + err = udp_sendto(ud->udp_pcb, pb, &addr, port); + pbuf_free(pb); + if (ud->client.cb_sent_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + lua_call(L, 1, 0); + } + } + else if (ud->type == TYPE_TCP_CLIENT) + { + err = tcp_write(ud->tcp_pcb, data, datalen, TCP_WRITE_FLAG_COPY); + } + else + { + err = ERR_VAL; + } + return lwip_lua_checkerr(L, err); } // Lua: client:hold() -int net_hold( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type != TYPE_TCP_CLIENT) - return luaL_error(L, "invalid user data"); - ud->client.hold = 1; - return 0; +int net_hold(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type != TYPE_TCP_CLIENT) + return luaL_error(L, "invalid user data"); + ud->client.hold = 1; + return 0; } // Lua: client:unhold() -int net_unhold( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type != TYPE_TCP_CLIENT) - return luaL_error(L, "invalid user data"); - ud->client.hold = 0; - return 0; +int net_unhold(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type != TYPE_TCP_CLIENT) + return luaL_error(L, "invalid user data"); + ud->client.hold = 0; + return 0; } // Lua: client/socket:dns(domain, callback(socket, addr)) -int net_dns( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type == TYPE_TCP_SERVER) - return luaL_error(L, "invalid user data"); - size_t dl = 0; - const char *domain = luaL_checklstring(L, 2, &dl); - if (!domain) - return luaL_error(L, "no domain specified"); - if (lua_isfunction(L, 3) || lua_islightfunction(L, 3)) { - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_dns_ref); - lua_pushvalue(L, 3); - ud->client.cb_dns_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - if (ud->client.cb_dns_ref == LUA_NOREF) - return luaL_error(L, "no callback specified"); - ud->client.wait_dns ++; - int unref = 0; - if (ud->self_ref == LUA_NOREF) { - unref = 1; - lua_pushvalue(L, 1); - ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } - ip_addr_t addr; - err_t err = dns_gethostbyname(domain, &addr, net_dns_cb, ud); - if (err == ERR_OK) { - net_dns_cb(domain, &addr, ud); - } else if (err != ERR_INPROGRESS) { - ud->client.wait_dns --; - if (unref) { - luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); - ud->self_ref = LUA_NOREF; +int net_dns(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type == TYPE_TCP_SERVER) + return luaL_error(L, "invalid user data"); + size_t dl = 0; + const char *domain = luaL_checklstring(L, 2, &dl); + if (!domain) + return luaL_error(L, "no domain specified"); + if (lua_isfunction(L, 3) || lua_islightfunction(L, 3)) + { + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_dns_ref); + lua_pushvalue(L, 3); + ud->client.cb_dns_ref = luaL_ref(L, LUA_REGISTRYINDEX); } - return lwip_lua_checkerr(L, err); - } - return 0; + if (ud->client.cb_dns_ref == LUA_NOREF) + return luaL_error(L, "no callback specified"); + ud->client.wait_dns++; + int unref = 0; + if (ud->self_ref == LUA_NOREF) + { + unref = 1; + lua_pushvalue(L, 1); + ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + ip_addr_t addr; + err_t err = dns_gethostbyname(domain, &addr, net_dns_cb, ud); + if (err == ERR_OK) + { + net_dns_cb(domain, &addr, ud); + } + else if (err != ERR_INPROGRESS) + { + ud->client.wait_dns--; + if (unref) + { + luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); + ud->self_ref = LUA_NOREF; + } + return lwip_lua_checkerr(L, err); + } + return 0; } // Lua: client:getpeer() -int net_getpeer( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud || ud->type != TYPE_TCP_CLIENT) - return luaL_error(L, "invalid user data"); - if (!ud->pcb) { - lua_pushnil(L); - lua_pushnil(L); - return 2; - } - uint16_t port = ud->tcp_pcb->remote_port; - ip_addr_t addr = ud->tcp_pcb->remote_ip; - if (port == 0) { - lua_pushnil(L); - lua_pushnil(L); +int net_getpeer(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud || ud->type != TYPE_TCP_CLIENT) + return luaL_error(L, "invalid user data"); + if (!ud->pcb) + { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + uint16_t port = ud->tcp_pcb->remote_port; + ip_addr_t addr = ud->tcp_pcb->remote_ip; + if (port == 0) + { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + char addr_str[IP_STR_SZ]; + ipstr(addr_str, &addr); + lua_pushinteger(L, port); + lua_pushstring(L, addr_str); return 2; - } - char addr_str[IP_STR_SZ]; - ipstr (addr_str, &addr); - lua_pushinteger(L, port); - lua_pushstring(L, addr_str); - return 2; } // Lua: client/server/socket:getaddr() -int net_getaddr( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud) return luaL_error(L, "invalid user data"); - if (!ud->pcb) { - lua_pushnil(L); - lua_pushnil(L); - return 2; - } - uint16_t port = 0; - ip_addr_t addr; - switch (ud->type) { - case TYPE_TCP_CLIENT: - case TYPE_TCP_SERVER: - addr = ud->tcp_pcb->local_ip; - port = ud->tcp_pcb->local_port; - break; - case TYPE_UDP_SOCKET: - addr = ud->udp_pcb->local_ip; - port = ud->udp_pcb->local_port; - break; - } - if (port == 0) { - lua_pushnil(L); - lua_pushnil(L); +int net_getaddr(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud) + return luaL_error(L, "invalid user data"); + if (!ud->pcb) + { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + uint16_t port = 0; + ip_addr_t addr; + switch (ud->type) + { + case TYPE_TCP_CLIENT: + case TYPE_TCP_SERVER: + addr = ud->tcp_pcb->local_ip; + port = ud->tcp_pcb->local_port; + break; + case TYPE_UDP_SOCKET: + addr = ud->udp_pcb->local_ip; + port = ud->udp_pcb->local_port; + break; + } + if (port == 0) + { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + char addr_str[IP_STR_SZ]; + ipstr(addr_str, &addr); + lua_pushinteger(L, port); + lua_pushstring(L, addr_str); return 2; - } - char addr_str[IP_STR_SZ]; - ipstr (addr_str, &addr); - lua_pushinteger(L, port); - lua_pushstring(L, addr_str); - return 2; } // Lua: client/server/socket:close() -int net_close( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud) return luaL_error(L, "invalid user data"); - if (ud->pcb) { - switch (ud->type) { - case TYPE_TCP_CLIENT: - if (ERR_OK != tcp_close(ud->tcp_pcb)) { - tcp_arg(ud->tcp_pcb, NULL); - tcp_abort(ud->tcp_pcb); +int net_close(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud) + return luaL_error(L, "invalid user data"); + if (ud->pcb) + { + switch (ud->type) + { + case TYPE_TCP_CLIENT: + if (ERR_OK != tcp_close(ud->tcp_pcb)) + { + tcp_arg(ud->tcp_pcb, NULL); + tcp_abort(ud->tcp_pcb); + } + ud->tcp_pcb = NULL; + break; + case TYPE_TCP_SERVER: + tcp_close(ud->tcp_pcb); + ud->tcp_pcb = NULL; + break; + case TYPE_UDP_SOCKET: + udp_remove(ud->udp_pcb); + ud->udp_pcb = NULL; + break; } - ud->tcp_pcb = NULL; - break; - case TYPE_TCP_SERVER: - tcp_close(ud->tcp_pcb); - ud->tcp_pcb = NULL; - break; - case TYPE_UDP_SOCKET: - udp_remove(ud->udp_pcb); - ud->udp_pcb = NULL; - break; - } - } else { - return luaL_error(L, "not connected"); - } - if (ud->type == TYPE_TCP_SERVER || - (ud->pcb == NULL && ud->client.wait_dns == 0)) { + } + else + { + return luaL_error(L, "not connected"); + } + if (ud->type == TYPE_TCP_SERVER || (ud->pcb == NULL && ud->client.wait_dns == 0)) + { + lua_gc(L, LUA_GCSTOP, 0); + luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); + ud->self_ref = LUA_NOREF; + lua_gc(L, LUA_GCRESTART, 0); + } + return 0; +} + +int net_delete(lua_State *L) +{ + lnet_userdata *ud = net_get_udata(L); + if (!ud) + return luaL_error(L, "no user data"); + if (ud->pcb) + { + switch (ud->type) + { + case TYPE_TCP_CLIENT: + tcp_arg(ud->tcp_pcb, NULL); + tcp_abort(ud->tcp_pcb); + ud->tcp_pcb = NULL; + break; + case TYPE_TCP_SERVER: + tcp_close(ud->tcp_pcb); + ud->tcp_pcb = NULL; + break; + case TYPE_UDP_SOCKET: + udp_remove(ud->udp_pcb); + ud->udp_pcb = NULL; + break; + } + } + switch (ud->type) + { + case TYPE_TCP_CLIENT: + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_connect_ref); + ud->client.cb_connect_ref = LUA_NOREF; + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_disconnect_ref); + ud->client.cb_disconnect_ref = LUA_NOREF; + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_reconnect_ref); + ud->client.cb_reconnect_ref = LUA_NOREF; + case TYPE_UDP_SOCKET: + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_dns_ref); + ud->client.cb_dns_ref = LUA_NOREF; + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_receive_ref); + ud->client.cb_receive_ref = LUA_NOREF; + luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); + ud->client.cb_sent_ref = LUA_NOREF; + break; + case TYPE_TCP_SERVER: + luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); + ud->server.cb_accept_ref = LUA_NOREF; + break; + } lua_gc(L, LUA_GCSTOP, 0); luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); ud->self_ref = LUA_NOREF; lua_gc(L, LUA_GCRESTART, 0); - } - return 0; -} - -int net_delete( lua_State *L ) { - lnet_userdata *ud = net_get_udata(L); - if (!ud) return luaL_error(L, "no user data"); - if (ud->pcb) { - switch (ud->type) { - case TYPE_TCP_CLIENT: - tcp_arg(ud->tcp_pcb, NULL); - tcp_abort(ud->tcp_pcb); - ud->tcp_pcb = NULL; - break; - case TYPE_TCP_SERVER: - tcp_close(ud->tcp_pcb); - ud->tcp_pcb = NULL; - break; - case TYPE_UDP_SOCKET: - udp_remove(ud->udp_pcb); - ud->udp_pcb = NULL; - break; - } - } - switch (ud->type) { - case TYPE_TCP_CLIENT: - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_connect_ref); - ud->client.cb_connect_ref = LUA_NOREF; - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_disconnect_ref); - ud->client.cb_disconnect_ref = LUA_NOREF; - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_reconnect_ref); - ud->client.cb_reconnect_ref = LUA_NOREF; - case TYPE_UDP_SOCKET: - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_dns_ref); - ud->client.cb_dns_ref = LUA_NOREF; - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_receive_ref); - ud->client.cb_receive_ref = LUA_NOREF; - luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); - ud->client.cb_sent_ref = LUA_NOREF; - break; - case TYPE_TCP_SERVER: - luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); - ud->server.cb_accept_ref = LUA_NOREF; - break; - } - lua_gc(L, LUA_GCSTOP, 0); - luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); - ud->self_ref = LUA_NOREF; - lua_gc(L, LUA_GCRESTART, 0); - return 0; + return 0; } // --- Multicast -static int net_multicastJoinLeave( lua_State *L, int join) { - size_t il; - ip4_addr_t multicast_addr; - ip4_addr_t if_addr; - const char *multicast_ip; - const char *if_ip; - - NODE_DBG("net_multicastJoin is called.\n"); - if(! lua_isstring(L,1) ) return luaL_error( L, "wrong arg type" ); - if_ip = luaL_checklstring( L, 1, &il ); - if (if_ip != NULL) - if ( if_ip[0] == '\0' || strcasecmp(if_ip,"any") == 0) - { - if_ip = "0.0.0.0"; - il = 7; - } - if (if_ip == NULL || il > 15 || il < 7) return luaL_error( L, "invalid if ip" ); - ip4addr_aton (if_ip, &if_addr); - - if(! lua_isstring(L,2) ) return luaL_error( L, "wrong arg type" ); - multicast_ip = luaL_checklstring( L, 2, &il ); - if (multicast_ip == NULL || il > 15 || il < 7) return luaL_error( L, "invalid multicast ip" ); - ip4addr_aton (multicast_ip, &multicast_addr); - if (join) - { - igmp_joingroup(&if_addr, &multicast_addr); - } - else - { - igmp_leavegroup(&if_addr, &multicast_addr); - } - return 0; +static int net_multicastJoinLeave(lua_State *L, int join) +{ + size_t il; + ip4_addr_t multicast_addr; + ip4_addr_t if_addr; + const char *multicast_ip; + const char *if_ip; + + NODE_DBG("net_multicastJoin is called.\n"); + if (!lua_isstring(L, 1)) + return luaL_error(L, "wrong arg type"); + if_ip = luaL_checklstring(L, 1, &il); + if (if_ip != NULL) + if (if_ip[0] == '\0' || strcasecmp(if_ip, "any") == 0) + { + if_ip = "0.0.0.0"; + il = 7; + } + if (if_ip == NULL || il > 15 || il < 7) + return luaL_error(L, "invalid if ip"); + ip4addr_aton(if_ip, &if_addr); + + if (!lua_isstring(L, 2)) + return luaL_error(L, "wrong arg type"); + multicast_ip = luaL_checklstring(L, 2, &il); + if (multicast_ip == NULL || il > 15 || il < 7) + return luaL_error(L, "invalid multicast ip"); + ip4addr_aton(multicast_ip, &multicast_addr); + if (join) + { + igmp_joingroup(&if_addr, &multicast_addr); + } + else + { + igmp_leavegroup(&if_addr, &multicast_addr); + } + return 0; } // Lua: net.multicastJoin(ifip, multicastip) // if ifip "" or "any" all interfaces are affected -static int net_multicastJoin( lua_State* L ) { - return net_multicastJoinLeave(L,1); -} +static int net_multicastJoin(lua_State *L) { return net_multicastJoinLeave(L, 1); } // Lua: net.multicastLeave(ifip, multicastip) // if ifip "" or "any" all interfaces are affected -static int net_multicastLeave( lua_State* L ) { - return net_multicastJoinLeave(L,0); -} +static int net_multicastLeave(lua_State *L) { return net_multicastJoinLeave(L, 0); } // --- DNS -static void net_dns_static_cb(const char *name, const ip_addr_t *ipaddr, void *callback_arg) { - lnet_event *ev = (lnet_event *)callback_arg; +static void net_dns_static_cb(const char *name, const ip_addr_t *ipaddr, void *callback_arg) +{ + lnet_event *ev = (lnet_event *)callback_arg; - ev->resolved_ip = ipaddr ? *ipaddr : ip_addr_any; + ev->resolved_ip = ipaddr ? *ipaddr : ip_addr_any; - if (!task_post_medium (net_event, (task_param_t)ev)) - free (ev); + if (!task_post_medium(net_event, (task_param_t)ev)) + free(ev); } // Lua: net.dns.resolve( domain, function(ip) ) -static int net_dns_static( lua_State* L ) { - size_t dl; - const char* domain = luaL_checklstring(L, 1, &dl); - if (!domain && dl > 128) { - return luaL_error(L, "wrong domain"); - } - - // Note: this will be free'd using regular free(), so can't luaM_malloc() - lnet_event *ev = (lnet_event *)malloc (sizeof (lnet_event)); - if (!ev) - return luaL_error (L, "out of memory"); - - ev->event = DNSSTATIC; - - luaL_checkanyfunction(L, 2); - lua_pushvalue(L, 2); // copy argument (func) to the top of stack - ev->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); - - err_t err = dns_gethostbyname( - domain, &ev->resolved_ip, net_dns_static_cb, ev); - if (err == ERR_OK) { - net_dns_static_cb(domain, &ev->resolved_ip, ev); - return 0; - } else if (err == ERR_INPROGRESS) { +static int net_dns_static(lua_State *L) +{ + size_t dl; + const char *domain = luaL_checklstring(L, 1, &dl); + if (!domain && dl > 128) + { + return luaL_error(L, "wrong domain"); + } + + // Note: this will be free'd using regular free(), so can't luaM_malloc() + lnet_event *ev = (lnet_event *)malloc(sizeof(lnet_event)); + if (!ev) + return luaL_error(L, "out of memory"); + + ev->event = DNSSTATIC; + + luaL_checkanyfunction(L, 2); + lua_pushvalue(L, 2); // copy argument (func) to the top of stack + ev->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + err_t err = dns_gethostbyname(domain, &ev->resolved_ip, net_dns_static_cb, ev); + if (err == ERR_OK) + { + net_dns_static_cb(domain, &ev->resolved_ip, ev); + return 0; + } + else if (err == ERR_INPROGRESS) + { + return 0; + } + else + { + int e = lwip_lua_checkerr(L, err); + free(ev); + return e; + } return 0; - } else { - int e = lwip_lua_checkerr(L, err); - free(ev); - return e; - } - return 0; } // Lua: s = net.dns.setdnsserver(ip_addr, [index]) -static int net_setdnsserver( lua_State* L ) { - size_t l; - ip_addr_t ipaddr; +static int net_setdnsserver(lua_State *L) +{ + size_t l; + ip_addr_t ipaddr; - const char *server = luaL_checklstring( L, 1, &l ); - if (l>16 || server == NULL || - !ipaddr_aton (server, &ipaddr) || ip_addr_isany (&ipaddr)) - return luaL_error( L, "invalid dns server ip" ); + const char *server = luaL_checklstring(L, 1, &l); + if (l > 16 || server == NULL || !ipaddr_aton(server, &ipaddr) || ip_addr_isany(&ipaddr)) + return luaL_error(L, "invalid dns server ip"); - int numdns = luaL_optint(L, 2, 0); - if (numdns >= DNS_MAX_SERVERS) - return luaL_error( L, "server index out of range [0-%d]", DNS_MAX_SERVERS - 1); + int numdns = luaL_optint(L, 2, 0); + if (numdns >= DNS_MAX_SERVERS) + return luaL_error(L, "server index out of range [0-%d]", DNS_MAX_SERVERS - 1); - dns_setserver(numdns,&ipaddr); + dns_setserver(numdns, &ipaddr); - return 0; + return 0; } // Lua: s = net.dns.getdnsserver([index]) -static int net_getdnsserver( lua_State* L ) { - int numdns = luaL_optint(L, 1, 0); - if (numdns >= DNS_MAX_SERVERS) - return luaL_error( L, "server index out of range [0-%d]", DNS_MAX_SERVERS - 1); - - // ip_addr_t ipaddr; - // dns_getserver(numdns,&ipaddr); - // Bug fix by @md5crypt https://github.com/nodemcu/nodemcu-firmware/pull/500 - ip_addr_t ipaddr = dns_getserver(numdns); - - if ( ip_addr_isany(&ipaddr) ) { - lua_pushnil( L ); - } else { - char temp[IP_STR_SZ]; - ipstr (temp, &ipaddr); - lua_pushstring( L, temp ); - } - - return 1; +static int net_getdnsserver(lua_State *L) +{ + int numdns = luaL_optint(L, 1, 0); + if (numdns >= DNS_MAX_SERVERS) + return luaL_error(L, "server index out of range [0-%d]", DNS_MAX_SERVERS - 1); + + // ip_addr_t ipaddr; + // dns_getserver(numdns,&ipaddr); + // Bug fix by @md5crypt https://github.com/nodemcu/nodemcu-firmware/pull/500 + ip_addr_t ipaddr = dns_getserver(numdns); + + if (ip_addr_isany(&ipaddr)) + { + lua_pushnil(L); + } + else + { + char temp[IP_STR_SZ]; + ipstr(temp, &ipaddr); + lua_pushstring(L, temp); + } + + return 1; } // --- Lua event dispatch -static void ldnsfound_cb (lua_State *L, lnet_userdata *ud, ip_addr_t *addr) { - if (ud->self_ref != LUA_NOREF && ud->client.cb_dns_ref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_dns_ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); - if (!ip_addr_isany (addr)) { - char iptmp[IP_STR_SZ]; - ipstr (iptmp, addr); - lua_pushstring(L, iptmp); - } else { - lua_pushnil(L); - } - lua_call(L, 2, 0); - } - ud->client.wait_dns --; - if (ud->pcb && ud->type == TYPE_TCP_CLIENT && ud->tcp_pcb->state == CLOSED) { - tcp_connect(ud->tcp_pcb, addr, ud->tcp_pcb->remote_port, net_connected_cb); - } else if (!ud->pcb && ud->client.wait_dns == 0) { - lua_gc(L, LUA_GCSTOP, 0); - luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); - ud->self_ref = LUA_NOREF; - lua_gc(L, LUA_GCRESTART, 0); - } +static void ldnsfound_cb(lua_State *L, lnet_userdata *ud, ip_addr_t *addr) +{ + if (ud->self_ref != LUA_NOREF && ud->client.cb_dns_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_dns_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + if (!ip_addr_isany(addr)) + { + char iptmp[IP_STR_SZ]; + ipstr(iptmp, addr); + lua_pushstring(L, iptmp); + } + else + { + lua_pushnil(L); + } + lua_call(L, 2, 0); + } + ud->client.wait_dns--; + if (ud->pcb && ud->type == TYPE_TCP_CLIENT && ud->tcp_pcb->state == CLOSED) + { + tcp_connect(ud->tcp_pcb, addr, ud->tcp_pcb->remote_port, net_connected_cb); + } + else if (!ud->pcb && ud->client.wait_dns == 0) + { + lua_gc(L, LUA_GCSTOP, 0); + luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); + ud->self_ref = LUA_NOREF; + lua_gc(L, LUA_GCRESTART, 0); + } } -static void ldnsstatic_cb (lua_State *L, int cb_ref, ip_addr_t *addr) { - if (cb_ref == LUA_NOREF) - return; - - lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref); - luaL_unref (L, LUA_REGISTRYINDEX, cb_ref); - - if (!ip_addr_isany (addr)) { - char iptmp[IP_STR_SZ]; - ipstr (iptmp, addr); - lua_pushstring(L, iptmp); - } else { - lua_pushnil(L); - } - lua_call(L, 1, 0); -} +static void ldnsstatic_cb(lua_State *L, int cb_ref, ip_addr_t *addr) +{ + if (cb_ref == LUA_NOREF) + return; -static void lconnected_cb (lua_State *L, lnet_userdata *ud) { - if (ud->self_ref != LUA_NOREF && ud->client.cb_connect_ref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_connect_ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref); + luaL_unref(L, LUA_REGISTRYINDEX, cb_ref); + + if (!ip_addr_isany(addr)) + { + char iptmp[IP_STR_SZ]; + ipstr(iptmp, addr); + lua_pushstring(L, iptmp); + } + else + { + lua_pushnil(L); + } lua_call(L, 1, 0); - } } -static void laccept_cb (lua_State *L, lnet_userdata *ud, struct tcp_pcb *newpcb) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); +static void lconnected_cb(lua_State *L, lnet_userdata *ud) +{ + if (ud->self_ref != LUA_NOREF && ud->client.cb_connect_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_connect_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + lua_call(L, 1, 0); + } +} + +static void laccept_cb(lua_State *L, lnet_userdata *ud, struct tcp_pcb *newpcb) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); - lnet_userdata *nud = net_create(L, TYPE_TCP_CLIENT); - lua_pushvalue(L, 2); - nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); - nud->tcp_pcb = newpcb; - tcp_arg(nud->tcp_pcb, nud); - tcp_err(nud->tcp_pcb, net_err_cb); - tcp_recv(nud->tcp_pcb, net_tcp_recv_cb); - tcp_sent(nud->tcp_pcb, net_sent_cb); + lnet_userdata *nud = net_create(L, TYPE_TCP_CLIENT); + lua_pushvalue(L, 2); + nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); + nud->tcp_pcb = newpcb; + tcp_arg(nud->tcp_pcb, nud); + tcp_err(nud->tcp_pcb, net_err_cb); + tcp_recv(nud->tcp_pcb, net_tcp_recv_cb); + tcp_sent(nud->tcp_pcb, net_sent_cb); - tcp_accepted(ud->tcp_pcb); + tcp_accepted(ud->tcp_pcb); - lua_call(L, 1, 0); + lua_call(L, 1, 0); } -static void lrecv_cb (lua_State *L, lnet_userdata *ud, const lnet_recvdata *rd) { - if (ud->client.cb_receive_ref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_receive_ref); - int num_args = 2; - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); - lua_pushlstring(L, rd->payload, rd->payload_len); - if (ud->type == TYPE_UDP_SOCKET) { - num_args += 2; - char iptmp[IP_STR_SZ]; - ipstr (iptmp, &rd->src_ip); - lua_pushinteger(L, rd->src_port); - lua_pushstring(L, iptmp); - } - lua_call(L, num_args, 0); - } +static void lrecv_cb(lua_State *L, lnet_userdata *ud, const lnet_recvdata *rd) +{ + if (ud->client.cb_receive_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_receive_ref); + int num_args = 2; + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + lua_pushlstring(L, rd->payload, rd->payload_len); + if (ud->type == TYPE_UDP_SOCKET) + { + num_args += 2; + char iptmp[IP_STR_SZ]; + ipstr(iptmp, &rd->src_ip); + lua_pushinteger(L, rd->src_port); + lua_pushstring(L, iptmp); + } + lua_call(L, num_args, 0); + } } -static void lsent_cb (lua_State *L, lnet_userdata *ud) { - if (ud->client.cb_sent_ref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); - lua_call(L, 1, 0); - } +static void lsent_cb(lua_State *L, lnet_userdata *ud) +{ + if (ud->client.cb_sent_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + lua_call(L, 1, 0); + } } -static void lerr_cb (lua_State *L, lnet_userdata *ud, err_t err) +static void lerr_cb(lua_State *L, lnet_userdata *ud, err_t err) { - int ref; - if (err != ERR_OK && ud->client.cb_reconnect_ref != LUA_NOREF) - ref = ud->client.cb_reconnect_ref; - else ref = ud->client.cb_disconnect_ref; - if (ref != LUA_NOREF) { - lua_rawgeti(L, LUA_REGISTRYINDEX, ref); - lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); - lua_pushinteger(L, err); - lua_call(L, 2, 0); - } - if (ud->client.wait_dns == 0) { - lua_gc(L, LUA_GCSTOP, 0); - luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); - ud->self_ref = LUA_NOREF; - lua_gc(L, LUA_GCRESTART, 0); - } + int ref; + if (err != ERR_OK && ud->client.cb_reconnect_ref != LUA_NOREF) + ref = ud->client.cb_reconnect_ref; + else + ref = ud->client.cb_disconnect_ref; + if (ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); + lua_pushinteger(L, err); + lua_call(L, 2, 0); + } + if (ud->client.wait_dns == 0) + { + lua_gc(L, LUA_GCSTOP, 0); + luaL_unref(L, LUA_REGISTRYINDEX, ud->self_ref); + ud->self_ref = LUA_NOREF; + lua_gc(L, LUA_GCRESTART, 0); + } } -static void handle_net_event (task_param_t param, task_prio_t prio) +static void handle_net_event(task_param_t param, task_prio_t prio) { - lnet_event *ev = (lnet_event *)param; - (void)prio; - - lua_State *L = lua_getstate(); - switch (ev->event) - { - case DNSFOUND: ldnsfound_cb (L, ev->ud, &ev->resolved_ip); break; - case DNSSTATIC: ldnsstatic_cb (L, ev->cb_ref, &ev->resolved_ip); break; - case CONNECTED: lconnected_cb (L, ev->ud); break; - case ACCEPT: laccept_cb (L, ev->ud, ev->accept_newpcb); break; - case RECVDATA: lrecv_cb (L, ev->ud, &ev->recvdata); break; - case SENTDATA: lsent_cb (L, ev->ud); break; - case ERR: lerr_cb (L, ev->ud, ev->err); break; - } - - free (ev); + lnet_event *ev = (lnet_event *)param; + (void)prio; + + lua_State *L = lua_getstate(); + switch (ev->event) + { + case DNSFOUND: + ldnsfound_cb(L, ev->ud, &ev->resolved_ip); + break; + case DNSSTATIC: + ldnsstatic_cb(L, ev->cb_ref, &ev->resolved_ip); + break; + case CONNECTED: + lconnected_cb(L, ev->ud); + break; + case ACCEPT: + laccept_cb(L, ev->ud, ev->accept_newpcb); + break; + case RECVDATA: + lrecv_cb(L, ev->ud, &ev->recvdata); + break; + case SENTDATA: + lsent_cb(L, ev->ud); + break; + case ERR: + lerr_cb(L, ev->ud, ev->err); + break; + } + + free(ev); } // --- Tables @@ -1115,77 +1317,65 @@ extern const LUA_REG_TYPE tls_cert_map[]; // Module function map static const LUA_REG_TYPE net_tcpserver_map[] = { - { LSTRKEY( "listen" ), LFUNCVAL( net_listen ) }, - { LSTRKEY( "getaddr" ), LFUNCVAL( net_getaddr ) }, - { LSTRKEY( "close" ), LFUNCVAL( net_close ) }, - { LSTRKEY( "__gc" ), LFUNCVAL( net_delete ) }, - { LSTRKEY( "__index" ), LROVAL( net_tcpserver_map ) }, - { LNILKEY, LNILVAL } -}; - -static const LUA_REG_TYPE net_tcpsocket_map[] = { - { LSTRKEY( "connect" ), LFUNCVAL( net_connect ) }, - { LSTRKEY( "close" ), LFUNCVAL( net_close ) }, - { LSTRKEY( "on" ), LFUNCVAL( net_on ) }, - { LSTRKEY( "send" ), LFUNCVAL( net_send ) }, - { LSTRKEY( "hold" ), LFUNCVAL( net_hold ) }, - { LSTRKEY( "unhold" ), LFUNCVAL( net_unhold ) }, - { LSTRKEY( "dns" ), LFUNCVAL( net_dns ) }, - { LSTRKEY( "getpeer" ), LFUNCVAL( net_getpeer ) }, - { LSTRKEY( "getaddr" ), LFUNCVAL( net_getaddr ) }, - { LSTRKEY( "__gc" ), LFUNCVAL( net_delete ) }, - { LSTRKEY( "__index" ), LROVAL( net_tcpsocket_map ) }, - { LNILKEY, LNILVAL } -}; - -static const LUA_REG_TYPE net_udpsocket_map[] = { - { LSTRKEY( "listen" ), LFUNCVAL( net_listen ) }, - { LSTRKEY( "close" ), LFUNCVAL( net_close ) }, - { LSTRKEY( "on" ), LFUNCVAL( net_on ) }, - { LSTRKEY( "send" ), LFUNCVAL( net_send ) }, - { LSTRKEY( "dns" ), LFUNCVAL( net_dns ) }, - { LSTRKEY( "getaddr" ), LFUNCVAL( net_getaddr ) }, - { LSTRKEY( "__gc" ), LFUNCVAL( net_delete ) }, - { LSTRKEY( "__index" ), LROVAL( net_udpsocket_map ) }, - { LNILKEY, LNILVAL } -}; - -static const LUA_REG_TYPE net_dns_map[] = { - { LSTRKEY( "setdnsserver" ), LFUNCVAL( net_setdnsserver ) }, - { LSTRKEY( "getdnsserver" ), LFUNCVAL( net_getdnsserver ) }, - { LSTRKEY( "resolve" ), LFUNCVAL( net_dns_static ) }, - { LNILKEY, LNILVAL } -}; - -const LUA_REG_TYPE net_map[] = { - { LSTRKEY( "createServer" ), LFUNCVAL( net_createServer ) }, - { LSTRKEY( "createConnection" ), LFUNCVAL( net_createConnection ) }, - { LSTRKEY( "createUDPSocket" ), LFUNCVAL( net_createUDPSocket ) }, - { LSTRKEY( "multicastJoin"), LFUNCVAL( net_multicastJoin ) }, - { LSTRKEY( "multicastLeave"), LFUNCVAL( net_multicastLeave ) }, - { LSTRKEY( "mycall" ), LFUNCVAL( net_mycall ) }, - { LSTRKEY( "myregister" ), LFUNCVAL( net_myregistrer ) }, - - { LSTRKEY( "dns" ), LROVAL( net_dns_map ) }, + {LSTRKEY("listen"), LFUNCVAL(net_listen)}, {LSTRKEY("getaddr"), LFUNCVAL(net_getaddr)}, + {LSTRKEY("close"), LFUNCVAL(net_close)}, {LSTRKEY("__gc"), LFUNCVAL(net_delete)}, + {LSTRKEY("__index"), LROVAL(net_tcpserver_map)}, {LNILKEY, LNILVAL}}; + +static const LUA_REG_TYPE net_tcpsocket_map[] = {{LSTRKEY("connect"), LFUNCVAL(net_connect)}, + {LSTRKEY("close"), LFUNCVAL(net_close)}, + {LSTRKEY("on"), LFUNCVAL(net_on)}, + {LSTRKEY("send"), LFUNCVAL(net_send)}, + {LSTRKEY("hold"), LFUNCVAL(net_hold)}, + {LSTRKEY("unhold"), LFUNCVAL(net_unhold)}, + {LSTRKEY("dns"), LFUNCVAL(net_dns)}, + {LSTRKEY("getpeer"), LFUNCVAL(net_getpeer)}, + {LSTRKEY("getaddr"), LFUNCVAL(net_getaddr)}, + {LSTRKEY("__gc"), LFUNCVAL(net_delete)}, + {LSTRKEY("__index"), LROVAL(net_tcpsocket_map)}, + {LNILKEY, LNILVAL}}; + +static const LUA_REG_TYPE net_udpsocket_map[] = {{LSTRKEY("listen"), LFUNCVAL(net_listen)}, + {LSTRKEY("close"), LFUNCVAL(net_close)}, + {LSTRKEY("on"), LFUNCVAL(net_on)}, + {LSTRKEY("send"), LFUNCVAL(net_send)}, + {LSTRKEY("dns"), LFUNCVAL(net_dns)}, + {LSTRKEY("getaddr"), LFUNCVAL(net_getaddr)}, + {LSTRKEY("__gc"), LFUNCVAL(net_delete)}, + {LSTRKEY("__index"), LROVAL(net_udpsocket_map)}, + {LNILKEY, LNILVAL}}; + +static const LUA_REG_TYPE net_dns_map[] = {{LSTRKEY("setdnsserver"), LFUNCVAL(net_setdnsserver)}, + {LSTRKEY("getdnsserver"), LFUNCVAL(net_getdnsserver)}, + {LSTRKEY("resolve"), LFUNCVAL(net_dns_static)}, + {LNILKEY, LNILVAL}}; + +const LUA_REG_TYPE net_map[] = {{LSTRKEY("createServer"), LFUNCVAL(net_createServer)}, + {LSTRKEY("createConnection"), LFUNCVAL(net_createConnection)}, + {LSTRKEY("createUDPSocket"), LFUNCVAL(net_createUDPSocket)}, + {LSTRKEY("multicastJoin"), LFUNCVAL(net_multicastJoin)}, + {LSTRKEY("multicastLeave"), LFUNCVAL(net_multicastLeave)}, + {LSTRKEY("mycall"), LFUNCVAL(net_mycall)}, + {LSTRKEY("myregister"), LFUNCVAL(net_myregistrer)}, + + {LSTRKEY("dns"), LROVAL(net_dns_map)}, #ifdef CLIENT_SSL_ENABLE - { LSTRKEY( "cert" ), LROVAL( tls_cert_map ) }, + {LSTRKEY("cert"), LROVAL(tls_cert_map)}, #endif - { LSTRKEY( "TCP" ), LNUMVAL( TYPE_TCP ) }, - { LSTRKEY( "UDP" ), LNUMVAL( TYPE_UDP ) }, - { LSTRKEY( "__metatable" ), LROVAL( net_map ) }, - { LNILKEY, LNILVAL } -}; + {LSTRKEY("TCP"), LNUMVAL(TYPE_TCP)}, + {LSTRKEY("UDP"), LNUMVAL(TYPE_UDP)}, + {LSTRKEY("__metatable"), LROVAL(net_map)}, + {LNILKEY, LNILVAL}}; -int luaopen_net( lua_State *L ) { - //printf("net init\n"); - igmp_init(); +int luaopen_net(lua_State *L) +{ + // printf("net init\n"); + igmp_init(); - luaL_rometatable(L, NET_TABLE_TCP_SERVER, (void *)net_tcpserver_map); - luaL_rometatable(L, NET_TABLE_TCP_CLIENT, (void *)net_tcpsocket_map); - luaL_rometatable(L, NET_TABLE_UDP_SOCKET, (void *)net_udpsocket_map); + luaL_rometatable(L, NET_TABLE_TCP_SERVER, (void *)net_tcpserver_map); + luaL_rometatable(L, NET_TABLE_TCP_CLIENT, (void *)net_tcpsocket_map); + luaL_rometatable(L, NET_TABLE_UDP_SOCKET, (void *)net_udpsocket_map); - net_event = task_get_id (handle_net_event); + net_event = task_get_id(handle_net_event); - return 0; + return 0; } - diff --git a/LuaNode_Esp32/LuaNode32/components/modules/node.c b/LuaNode_Esp32/LuaNode32/components/modules/node.c index e83a602..1c492fa 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/node.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/node.c @@ -1,55 +1,50 @@ // Module for interfacing with system -#include "modules.h" +#include "c_types.h" #include "lauxlib.h" - #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lmem.h" #include "lobject.h" -#include "lstate.h" -#include "lualib.h" - #include "lopcodes.h" +#include "lrodefs.h" +#include "lrotable.h" +#include "lstate.h" #include "lstring.h" +#include "lualib.h" #include "lundump.h" - +#include "modules.h" #include "platform.h" -#include "lrotable.h" -#include "lrodefs.h" - -#include "c_types.h" //#include "romfs.h" #include "c_string.h" #include "rom/uart.h" #include "user_interface.h" //#include "flash_api.h" -#include "flash_fs.h" -#include "user_version.h" #include "esp_misc.h" #include "esp_system.h" +#include "flash_fs.h" +#include "user_version.h" #include "vfs.h" #define CPU80MHZ 80 #define CPU160MHZ 160 // Lua: restart() -static int node_restart( lua_State* L ) +static int node_restart(lua_State *L) { - system_restart(); - return 0; + system_restart(); + return 0; } // Lua: dsleep( us, option ) -static int node_dsleep( lua_State* L ) +static int node_dsleep(lua_State *L) { - uint64_t us = luaL_optinteger (L, 1, 0); - system_deep_sleep (us); - return 0; + uint64_t us = luaL_optinteger(L, 1, 0); + system_deep_sleep(us); + return 0; } - // Lua: dsleep_set_options // Combined to dsleep( us, option ) // static int node_deepsleep_setoption( lua_State* L ) @@ -64,52 +59,58 @@ static int node_dsleep( lua_State* L ) // } // Lua: info() - -static int node_info( lua_State* L ) +static int node_info(lua_State *L) { - //uint32_t fs = system_get_flash_size(); - uint32_t fs = 2; - uint8 id = 0; - //bool succeed = system_get_chip_id(&id); - uint32_t hs = system_get_free_heap_size(); - lua_getglobal(L, "print"); - switch(fs) { - case 0: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "1MB", id, hs); - break; - case 1: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "2MB", id, hs); - break; - case 2: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "4MB", id, hs); - break; - case 3: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "8MB", id, hs); - break; - case 4: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "16MB", id, hs); - break; - default: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "32MB", id, hs); - break; - } - int err = lua_pcall(L, 1, 1, 0); - if (err != 0) { os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); } - lua_pop(L, 1) ; - return 0; + // uint32_t fs = system_get_flash_size(); + uint32_t fs = 2; + uint8 id = 0; + // bool succeed = system_get_chip_id(&id); + uint32_t hs = system_get_free_heap_size(); + lua_getglobal(L, "print"); + switch (fs) + { + case 0: + lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "1MB", id, hs); + break; + case 1: + lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "2MB", id, hs); + break; + case 2: + lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "4MB", id, hs); + break; + case 3: + lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "8MB", id, hs); + break; + case 4: + lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "16MB", id, hs); + break; + default: + lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "32MB", id, hs); + break; + } + int err = lua_pcall(L, 1, 1, 0); + if (err != 0) + { + os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 0; } // Lua: chipid() -static int node_chipid( lua_State* L ) +static int node_chipid(lua_State *L) { - uint8 id = 0; - //bool succeed = system_get_chip_id(&id); - lua_getglobal(L, "print"); - lua_pushinteger(L, id); - int err = lua_pcall(L, 1, 1, 0); - if (err != 0) { os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); } - lua_pop(L, 1) ; - return 0; + uint8 id = 0; + // bool succeed = system_get_chip_id(&id); + lua_getglobal(L, "print"); + lua_pushinteger(L, id); + int err = lua_pcall(L, 1, 1, 0); + if (err != 0) + { + os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 0; } // deprecated, moved to adc module @@ -122,72 +123,85 @@ static int node_chipid( lua_State* L ) // } // Lua: flashid() -static int node_flashid( lua_State* L ) +static int node_flashid(lua_State *L) { - //uint32_t id = spi_flash_get_id(); - //lua_pushinteger( L, id ); - lua_getglobal(L, "print"); - lua_pushinteger(L, 0); - int err = lua_pcall(L, 1, 1, 0); - if (err != 0) { os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); } - lua_pop(L, 1) ; - return 0; + // uint32_t id = spi_flash_get_id(); + // lua_pushinteger( L, id ); + lua_getglobal(L, "print"); + lua_pushinteger(L, 0); + int err = lua_pcall(L, 1, 1, 0); + if (err != 0) + { + os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 0; } // Lua: flashsize() -static int node_flashsize( lua_State* L ) +static int node_flashsize(lua_State *L) { - //uint32_t sz = system_get_flash_size(); - uint32_t sz = 2; - lua_getglobal(L, "print"); - switch(sz) { - case 0: - lua_pushstring(L, "1MB"); - break; - case 1: - lua_pushstring(L, "2MB"); - break; - case 2: - lua_pushstring(L, "4MB"); - break; - case 3: - lua_pushstring(L, "8MB"); - break; - case 4: - lua_pushstring(L, "16MB"); - break; - default: - lua_pushstring(L, "32MB"); - break; - } - //lua_pushinteger(L, sz); - int err = lua_pcall(L, 1, 1, 0); - if (err != 0) { os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); } - lua_pop(L, 1) ; - return 0; + // uint32_t sz = system_get_flash_size(); + uint32_t sz = 2; + lua_getglobal(L, "print"); + switch (sz) + { + case 0: + lua_pushstring(L, "1MB"); + break; + case 1: + lua_pushstring(L, "2MB"); + break; + case 2: + lua_pushstring(L, "4MB"); + break; + case 3: + lua_pushstring(L, "8MB"); + break; + case 4: + lua_pushstring(L, "16MB"); + break; + default: + lua_pushstring(L, "32MB"); + break; + } + // lua_pushinteger(L, sz); + int err = lua_pcall(L, 1, 1, 0); + if (err != 0) + { + os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 0; } // Lua: heap() -static int node_heap( lua_State* L ) +static int node_heap(lua_State *L) { - uint32_t sz = system_get_free_heap_size(); - lua_getglobal(L, "print"); - lua_pushinteger(L, sz); - int err = lua_pcall(L, 1, 1, 0); - if (err != 0) { os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); } - lua_pop(L, 1) ; - return 0; + uint32_t sz = system_get_free_heap_size(); + lua_getglobal(L, "print"); + lua_pushinteger(L, sz); + int err = lua_pcall(L, 1, 1, 0); + if (err != 0) + { + os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 0; } -static int node_memusage( lua_State* L ) +static int node_memusage(lua_State *L) { - uint32_t usage = lua_gc(L, LUA_GCCOUNT, 0); - lua_getglobal(L, "print"); - lua_pushinteger(L, usage); - int err = lua_pcall(L, 1, 1, 0); - if (err != 0) { os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); } - lua_pop(L, 1) ; - return 0; + uint32_t usage = lua_gc(L, LUA_GCCOUNT, 0); + lua_getglobal(L, "print"); + lua_pushinteger(L, usage); + int err = lua_pcall(L, 1, 1, 0); + if (err != 0) + { + os_printf("lua_pcall failed:%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return 0; } static lua_State *gL = NULL; @@ -203,298 +217,346 @@ static os_timer_t keyled_timer; static int long_key_ref = LUA_NOREF; static int short_key_ref = LUA_NOREF; -static void default_long_press(void *arg) { - if (led_high_count == 12 && led_low_count == 12) { - led_low_count = led_high_count = 6; - } else { - led_low_count = led_high_count = 12; - } - // led_high_count = 1000 / READLINE_INTERVAL; - // led_low_count = 1000 / READLINE_INTERVAL; - // NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", led_high_count, led_low_count); +static void default_long_press(void *arg) +{ + if (led_high_count == 12 && led_low_count == 12) + { + led_low_count = led_high_count = 6; + } + else + { + led_low_count = led_high_count = 12; + } + // led_high_count = 1000 / READLINE_INTERVAL; + // led_low_count = 1000 / READLINE_INTERVAL; + // NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", + // led_high_count, led_low_count); } -static void default_short_press(void *arg) { - system_restart(); -} +static void default_short_press(void *arg) { system_restart(); } -static void key_long_press(void *arg) { - NODE_DBG("key_long_press is called.\n"); - if (long_key_ref == LUA_NOREF) { - default_long_press(arg); - return; - } - if (!gL) - return; - lua_rawgeti(gL, LUA_REGISTRYINDEX, long_key_ref); - lua_call(gL, 0, 0); +static void key_long_press(void *arg) +{ + NODE_DBG("key_long_press is called.\n"); + if (long_key_ref == LUA_NOREF) + { + default_long_press(arg); + return; + } + if (!gL) + return; + lua_rawgeti(gL, LUA_REGISTRYINDEX, long_key_ref); + lua_call(gL, 0, 0); } -static void key_short_press(void *arg) { - NODE_DBG("key_short_press is called.\n"); - if (short_key_ref == LUA_NOREF) { - default_short_press(arg); - return; - } - if (!gL) - return; - lua_rawgeti(gL, LUA_REGISTRYINDEX, short_key_ref); - lua_call(gL, 0, 0); +static void key_short_press(void *arg) +{ + NODE_DBG("key_short_press is called.\n"); + if (short_key_ref == LUA_NOREF) + { + default_short_press(arg); + return; + } + if (!gL) + return; + lua_rawgeti(gL, LUA_REGISTRYINDEX, short_key_ref); + lua_call(gL, 0, 0); } -static void update_key_led (void *p) +static void update_key_led(void *p) { - (void)p; - uint8_t temp = 1, level = 1; - led_count++; - if(led_count>led_low_count+led_high_count){ - led_count = 0; // reset led_count, the level still high - } else if(led_count>led_low_count && led_count <=led_high_count+led_low_count){ - level = 1; // output high level - } else if(led_count<=led_low_count){ - level = 0; // output low level - } - temp = platform_key_led(level); - if(temp == 0){ // key is pressed - key_press_count++; - if(key_press_count>=KEY_LONG_COUNT){ - // key_long_press(NULL); - key_long_pressed = true; - key_short_pressed = false; - // key_press_count = 0; - } else if(key_press_count>=KEY_SHORT_COUNT){ // < KEY_LONG_COUNT - // key_short_press(NULL); - key_short_pressed = true; - } - }else{ // key is released - key_press_count = 0; - if(key_long_pressed){ - key_long_press(NULL); - key_long_pressed = false; - } - if(key_short_pressed){ - key_short_press(NULL); - key_short_pressed = false; + (void)p; + uint8_t temp = 1, level = 1; + led_count++; + if (led_count > led_low_count + led_high_count) + { + led_count = 0; // reset led_count, the level still high + } + else if (led_count > led_low_count && led_count <= led_high_count + led_low_count) + { + level = 1; // output high level + } + else if (led_count <= led_low_count) + { + level = 0; // output low level + } + temp = platform_key_led(level); + if (temp == 0) + { // key is pressed + key_press_count++; + if (key_press_count >= KEY_LONG_COUNT) + { + // key_long_press(NULL); + key_long_pressed = true; + key_short_pressed = false; + // key_press_count = 0; + } + else if (key_press_count >= KEY_SHORT_COUNT) + { // < KEY_LONG_COUNT + // key_short_press(NULL); + key_short_pressed = true; + } + } + else + { // key is released + key_press_count = 0; + if (key_long_pressed) + { + key_long_press(NULL); + key_long_pressed = false; + } + if (key_short_pressed) + { + key_short_press(NULL); + key_short_pressed = false; + } } - } } -static void prime_keyled_timer (void) +static void prime_keyled_timer(void) { - os_timer_disarm (&keyled_timer); - os_timer_setfn (&keyled_timer, update_key_led, 0); - os_timer_arm (&keyled_timer, KEYLED_INTERVAL, 1); + os_timer_disarm(&keyled_timer); + os_timer_setfn(&keyled_timer, update_key_led, 0); + os_timer_arm(&keyled_timer, KEYLED_INTERVAL, 1); } // Lua: led(low, high) -static int node_led( lua_State* L ) +static int node_led(lua_State *L) { - int low, high; - if ( lua_isnumber(L, 1) ) - { - low = lua_tointeger(L, 1); - if ( low < 0 ) { - return luaL_error( L, "wrong arg type" ); + int low, high; + if (lua_isnumber(L, 1)) + { + low = lua_tointeger(L, 1); + if (low < 0) + { + return luaL_error(L, "wrong arg type"); + } } - } else { - low = LED_LOW_COUNT_DEFAULT; // default to LED_LOW_COUNT_DEFAULT - } - if ( lua_isnumber(L, 2) ) - { - high = lua_tointeger(L, 2); - if ( high < 0 ) { - return luaL_error( L, "wrong arg type" ); + else + { + low = LED_LOW_COUNT_DEFAULT; // default to LED_LOW_COUNT_DEFAULT } - } else { - high = LED_HIGH_COUNT_DEFAULT; // default to LED_HIGH_COUNT_DEFAULT - } - led_high_count = (uint32_t)high / READLINE_INTERVAL; - led_low_count = (uint32_t)low / READLINE_INTERVAL; - prime_keyled_timer(); - return 0; + if (lua_isnumber(L, 2)) + { + high = lua_tointeger(L, 2); + if (high < 0) + { + return luaL_error(L, "wrong arg type"); + } + } + else + { + high = LED_HIGH_COUNT_DEFAULT; // default to LED_HIGH_COUNT_DEFAULT + } + led_high_count = (uint32_t)high / READLINE_INTERVAL; + led_low_count = (uint32_t)low / READLINE_INTERVAL; + prime_keyled_timer(); + return 0; } // Lua: key(type, function) -static int node_key( lua_State* L ) +static int node_key(lua_State *L) { - int *ref = NULL; - size_t sl; + int *ref = NULL; + size_t sl; - const char *str = luaL_checklstring( L, 1, &sl ); - if (str == NULL) - return luaL_error( L, "wrong arg type" ); + const char *str = luaL_checklstring(L, 1, &sl); + if (str == NULL) + return luaL_error(L, "wrong arg type"); - if (sl == 5 && c_strcmp(str, "short") == 0) { - ref = &short_key_ref; - } else if (sl == 4 && c_strcmp(str, "long") == 0) { - ref = &long_key_ref; - } else { - ref = &short_key_ref; - } - gL = L; - // luaL_checkanyfunction(L, 2); - if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) { - lua_pushvalue(L, 2); // copy argument (func) to the top of stack - if (*ref != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, *ref); - *ref = luaL_ref(L, LUA_REGISTRYINDEX); - } else { // unref the key press function - if (*ref != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, *ref); - *ref = LUA_NOREF; - } + if (sl == 5 && c_strcmp(str, "short") == 0) + { + ref = &short_key_ref; + } + else if (sl == 4 && c_strcmp(str, "long") == 0) + { + ref = &long_key_ref; + } + else + { + ref = &short_key_ref; + } + gL = L; + // luaL_checkanyfunction(L, 2); + if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) + { + lua_pushvalue(L, 2); // copy argument (func) to the top of stack + if (*ref != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, *ref); + *ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { // unref the key press function + if (*ref != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, *ref); + *ref = LUA_NOREF; + } - prime_keyled_timer(); - return 0; + prime_keyled_timer(); + return 0; } #endif extern lua_Load gLoad; // Lua: input("string") -static int node_input( lua_State* L ) +static int node_input(lua_State *L) { - size_t l = 0; - const char *s = luaL_checklstring(L, 1, &l); - if (s != NULL && l > 0 && l < LUA_MAXINPUT - 1) - { - lua_Load *load = &gLoad; - if (load->line_position == 0) { - c_memcpy(load->line, s, l); - load->line[l + 1] = '\0'; - load->line_position = c_strlen(load->line) + 1; - load->done = 1; - NODE_DBG("Get command:\n"); - NODE_DBG(load->line); // buggy here - NODE_DBG("\nResult(if any):\n"); - //system_os_post (LUA_TASK_PRIO, LUA_PROCESS_LINE_SIG, 0); + size_t l = 0; + const char *s = luaL_checklstring(L, 1, &l); + if (s != NULL && l > 0 && l < LUA_MAXINPUT - 1) + { + lua_Load *load = &gLoad; + if (load->line_position == 0) + { + c_memcpy(load->line, s, l); + load->line[l + 1] = '\0'; + load->line_position = c_strlen(load->line) + 1; + load->done = 1; + NODE_DBG("Get command:\n"); + NODE_DBG(load->line); // buggy here + NODE_DBG("\nResult(if any):\n"); + // system_os_post (LUA_TASK_PRIO, LUA_PROCESS_LINE_SIG, 0); + } } - } - return 0; + return 0; } static int output_redir_ref = LUA_NOREF; static int serial_debug = 1; -void output_redirect(const char *str) { - // if(c_strlen(str)>=TX_BUFF_SIZE){ - // NODE_ERR("output too long.\n"); - // return; - // } - - if (output_redir_ref == LUA_NOREF || !gL) { - os_printf(str); - return; - } +void output_redirect(const char *str) +{ + // if(c_strlen(str)>=TX_BUFF_SIZE){ + // NODE_ERR("output too long.\n"); + // return; + // } + + if (output_redir_ref == LUA_NOREF || !gL) + { + os_printf(str); + return; + } - if (serial_debug != 0) { - os_printf(str); - } + if (serial_debug != 0) + { + os_printf(str); + } - lua_rawgeti(gL, LUA_REGISTRYINDEX, output_redir_ref); - lua_pushstring(gL, str); - lua_call(gL, 1, 0); // this call back function should never user output. + lua_rawgeti(gL, LUA_REGISTRYINDEX, output_redir_ref); + lua_pushstring(gL, str); + lua_call(gL, 1, 0); // this call back function should never user output. } // Lua: output(function(c), debug) -static int node_output( lua_State* L ) +static int node_output(lua_State *L) { - gL = L; - // luaL_checkanyfunction(L, 1); - if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION) { - lua_pushvalue(L, 1); // copy argument (func) to the top of stack - if (output_redir_ref != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, output_redir_ref); - output_redir_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } else { // unref the key press function - if (output_redir_ref != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, output_redir_ref); - output_redir_ref = LUA_NOREF; - serial_debug = 1; - return 0; - } + gL = L; + // luaL_checkanyfunction(L, 1); + if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION) + { + lua_pushvalue(L, 1); // copy argument (func) to the top of stack + if (output_redir_ref != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, output_redir_ref); + output_redir_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { // unref the key press function + if (output_redir_ref != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, output_redir_ref); + output_redir_ref = LUA_NOREF; + serial_debug = 1; + return 0; + } - if ( lua_isnumber(L, 2) ) - { - serial_debug = lua_tointeger(L, 2); - if (serial_debug != 0) - serial_debug = 1; - } else { - serial_debug = 1; // default to 1 - } + if (lua_isnumber(L, 2)) + { + serial_debug = lua_tointeger(L, 2); + if (serial_debug != 0) + serial_debug = 1; + } + else + { + serial_debug = 1; // default to 1 + } - return 0; + return 0; } -static int writer(lua_State* L, const void* p, size_t size, void* u) +static int writer(lua_State *L, const void *p, size_t size, void *u) { - UNUSED(L); - int file_fd = *( (int *)u ); - if ((FS_OPEN_OK - 1) == file_fd) - return 1; - NODE_DBG("get fd:%d,size:%d\n", file_fd, size); - - if (size != 0 && (size != vfs_write(file_fd, (const char *)p, size)) ) - return 1; - NODE_DBG("write fd:%d,size:%d\n", file_fd, size); - return 0; + UNUSED(L); + int file_fd = *((int *)u); + if ((FS_OPEN_OK - 1) == file_fd) + return 1; + NODE_DBG("get fd:%d,size:%d\n", file_fd, size); + + if (size != 0 && (size != vfs_write(file_fd, (const char *)p, size))) + return 1; + NODE_DBG("write fd:%d,size:%d\n", file_fd, size); + return 0; } -#define toproto(L,i) (clvalue(L->top+(i))->l.p) +#define toproto(L, i) (clvalue(L->top + (i))->l.p) // Lua: compile(filename) -- compile lua file into lua bytecode, and save to .lc -static int node_compile( lua_State* L ) +static int node_compile(lua_State *L) { - Proto* f; - int file_fd = FS_OPEN_OK - 1; - size_t len; - const char *fname = luaL_checklstring( L, 1, &len ); - if ( len > FS_NAME_MAX_LENGTH ) - return luaL_error(L, "filename too long"); - - char output[FS_NAME_MAX_LENGTH]; - c_strcpy(output, fname); - // check here that filename end with ".lua". - if (len < 4 || (c_strcmp( output + len - 4, ".lua") != 0) ) - return luaL_error(L, "not a .lua file"); - - output[c_strlen(output) - 2] = 'c'; - output[c_strlen(output) - 1] = '\0'; - NODE_DBG(output); - NODE_DBG("\n"); - if (luaL_loadfsfile(L, fname) != 0) { - return luaL_error(L, lua_tostring(L, -1)); - } + Proto *f; + int file_fd = FS_OPEN_OK - 1; + size_t len; + const char *fname = luaL_checklstring(L, 1, &len); + if (len > FS_NAME_MAX_LENGTH) + return luaL_error(L, "filename too long"); + + char output[FS_NAME_MAX_LENGTH]; + c_strcpy(output, fname); + // check here that filename end with ".lua". + if (len < 4 || (c_strcmp(output + len - 4, ".lua") != 0)) + return luaL_error(L, "not a .lua file"); + + output[c_strlen(output) - 2] = 'c'; + output[c_strlen(output) - 1] = '\0'; + NODE_DBG(output); + NODE_DBG("\n"); + if (luaL_loadfsfile(L, fname) != 0) + { + return luaL_error(L, lua_tostring(L, -1)); + } - f = toproto(L, -1); + f = toproto(L, -1); - int stripping = 1; /* strip debug information? */ + int stripping = 1; /* strip debug information? */ - file_fd = vfs_open(output, "w+"); - if (file_fd < FS_OPEN_OK) - { - return luaL_error(L, "cannot open/write to file"); - } + file_fd = vfs_open(output, "w+"); + if (file_fd < FS_OPEN_OK) + { + return luaL_error(L, "cannot open/write to file"); + } - lua_lock(L); - int result = luaU_dump(L, f, writer, &file_fd, stripping); - lua_unlock(L); + lua_lock(L); + int result = luaU_dump(L, f, writer, &file_fd, stripping); + lua_unlock(L); - if (vfs_flush(file_fd) < 0) { // result codes aren't propagated by flash_fs.h - // overwrite Lua error, like writer() does in case of a file io error - result = 1; - } - vfs_close(file_fd); - file_fd = FS_OPEN_OK - 1; + if (vfs_flush(file_fd) < 0) + { // result codes aren't propagated by flash_fs.h + // overwrite Lua error, like writer() does in case of a file io error + result = 1; + } + vfs_close(file_fd); + file_fd = FS_OPEN_OK - 1; - if (result == LUA_ERR_CC_INTOVERFLOW) { - return luaL_error(L, "value too big or small for target integer type"); - } - if (result == LUA_ERR_CC_NOTINTEGER) { - return luaL_error(L, "target lua_Number is integral but fractional value found"); - } - if (result == 1) { // result status generated by writer() or fs_flush() fail - return luaL_error(L, "writing to file failed"); - } + if (result == LUA_ERR_CC_INTOVERFLOW) + { + return luaL_error(L, "value too big or small for target integer type"); + } + if (result == LUA_ERR_CC_NOTINTEGER) + { + return luaL_error(L, "target lua_Number is integral but fractional value found"); + } + if (result == 1) + { // result status generated by writer() or fs_flush() fail + return luaL_error(L, "writing to file failed"); + } - return 0; + return 0; } #if 0 @@ -525,16 +587,16 @@ static int node_bootreason (lua_State *L) #endif // Lua: restore() -static int node_restore (lua_State *L) +static int node_restore(lua_State *L) { - //flash_init_data_default(); - //flash_init_data_blank(); - system_restore(); - return 0; + // flash_init_data_default(); + // flash_init_data_blank(); + system_restore(); + return 0; } #ifdef LUA_OPTIMIZE_DEBUG -/* node.stripdebug([level[, function]]). +/* node.stripdebug([level[, function]]). * level: 1 don't discard debug * 2 discard Local and Upvalue debug info * 3 discard Local, Upvalue and lineno debug info. @@ -543,99 +605,107 @@ static int node_restore (lua_State *L) * If function is omitted, this is the default setting for future compiles * The function returns an estimated integer count of the bytes stripped. */ -static int node_stripdebug (lua_State *L) { - int level; - - if (L->top == L->base) { - lua_pushlightuserdata(L, &luaG_stripdebug ); - lua_gettable(L, LUA_REGISTRYINDEX); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_pushinteger(L, LUA_OPTIMIZE_DEBUG); +static int node_stripdebug(lua_State *L) +{ + int level; + + if (L->top == L->base) + { + lua_pushlightuserdata(L, &luaG_stripdebug); + lua_gettable(L, LUA_REGISTRYINDEX); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_pushinteger(L, LUA_OPTIMIZE_DEBUG); + } + return 1; } - return 1; - } - level = luaL_checkint(L, 1); - if ((level <= 0) || (level > 3)) luaL_argerror(L, 1, "must in range 1-3"); - - if (L->top == L->base + 1) { - /* Store the default level in the registry if no function parameter */ - lua_pushlightuserdata(L, &luaG_stripdebug); - lua_pushinteger(L, level); - lua_settable(L, LUA_REGISTRYINDEX); - lua_settop(L,0); - return 0; - } + level = luaL_checkint(L, 1); + if ((level <= 0) || (level > 3)) + luaL_argerror(L, 1, "must in range 1-3"); + + if (L->top == L->base + 1) + { + /* Store the default level in the registry if no function parameter */ + lua_pushlightuserdata(L, &luaG_stripdebug); + lua_pushinteger(L, level); + lua_settable(L, LUA_REGISTRYINDEX); + lua_settop(L, 0); + return 0; + } - if (level == 1) { - lua_settop(L,0); - lua_pushinteger(L, 0); - return 1; - } + if (level == 1) + { + lua_settop(L, 0); + lua_pushinteger(L, 0); + return 1; + } - if (!lua_isfunction(L, 2)) { - int scope = luaL_checkint(L, 2); - if (scope > 0) { - /* if the function parameter is a +ve integer then climb to find function */ - lua_Debug ar; - lua_pop(L, 1); /* pop level as getinfo will replace it by the function */ - if (lua_getstack(L, scope, &ar)) { - lua_getinfo(L, "f", &ar); - } + if (!lua_isfunction(L, 2)) + { + int scope = luaL_checkint(L, 2); + if (scope > 0) + { + /* if the function parameter is a +ve integer then climb to find + * function */ + lua_Debug ar; + lua_pop(L, 1); /* pop level as getinfo will replace it by the function */ + if (lua_getstack(L, scope, &ar)) + { + lua_getinfo(L, "f", &ar); + } + } } - } - if(!lua_isfunction(L, 2) || lua_iscfunction(L, -1)) luaL_argerror(L, 2, "must be a Lua Function"); - // lua_lock(L); - Proto *f = clvalue(L->base + 1)->l.p; - // lua_unlock(L); - lua_settop(L,0); - lua_pushinteger(L, luaG_stripdebug(L, f, level, 1)); - return 1; + if (!lua_isfunction(L, 2) || lua_iscfunction(L, -1)) + luaL_argerror(L, 2, "must be a Lua Function"); + // lua_lock(L); + Proto *f = clvalue(L->base + 1)->l.p; + // lua_unlock(L); + lua_settop(L, 0); + lua_pushinteger(L, luaG_stripdebug(L, f, level, 1)); + return 1; } #endif // Module function map -const LUA_REG_TYPE node_map[] = -{ - { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) }, - { LSTRKEY( "dsleep" ), LFUNCVAL( node_dsleep ) }, - { LSTRKEY( "info" ), LFUNCVAL( node_info ) }, - { LSTRKEY( "chipid" ), LFUNCVAL( node_chipid ) }, - { LSTRKEY( "flashid" ), LFUNCVAL( node_flashid ) }, - { LSTRKEY( "flashsize" ), LFUNCVAL( node_flashsize) }, - { LSTRKEY( "heap" ), LFUNCVAL( node_heap ) }, - { LSTRKEY( "memusage" ), LFUNCVAL( node_memusage ) }, +const LUA_REG_TYPE node_map[] = {{LSTRKEY("restart"), LFUNCVAL(node_restart)}, + {LSTRKEY("dsleep"), LFUNCVAL(node_dsleep)}, + {LSTRKEY("info"), LFUNCVAL(node_info)}, + {LSTRKEY("chipid"), LFUNCVAL(node_chipid)}, + {LSTRKEY("flashid"), LFUNCVAL(node_flashid)}, + {LSTRKEY("flashsize"), LFUNCVAL(node_flashsize)}, + {LSTRKEY("heap"), LFUNCVAL(node_heap)}, + {LSTRKEY("memusage"), LFUNCVAL(node_memusage)}, #ifdef DEVKIT_VERSION_0_9 - { LSTRKEY( "key" ), LFUNCVAL( node_key ) }, - { LSTRKEY( "led" ), LFUNCVAL( node_led ) }, + {LSTRKEY("key"), LFUNCVAL(node_key)}, + {LSTRKEY("led"), LFUNCVAL(node_led)}, #endif - { LSTRKEY( "input" ), LFUNCVAL( node_input ) }, - { LSTRKEY( "output" ), LFUNCVAL( node_output ) }, -// Moved to adc module, use adc.readvdd33() -// { LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) }, - { LSTRKEY( "compile" ), LFUNCVAL( node_compile) }, - //{ LSTRKEY( "CPU80MHZ" ), LNUMVAL( CPU80MHZ ) }, - //{ LSTRKEY( "CPU160MHZ" ), LNUMVAL( CPU160MHZ ) }, - //{ LSTRKEY( "setcpufreq" ), LFUNCVAL( node_setcpufreq) }, - //{ LSTRKEY( "bootreason" ), LFUNCVAL( node_bootreason) }, - { LSTRKEY( "restore" ), LFUNCVAL( node_restore) }, + {LSTRKEY("input"), LFUNCVAL(node_input)}, + {LSTRKEY("output"), LFUNCVAL(node_output)}, + // Moved to adc module, use adc.readvdd33() + // { LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) }, + {LSTRKEY("compile"), LFUNCVAL(node_compile)}, + //{ LSTRKEY( "CPU80MHZ" ), LNUMVAL( CPU80MHZ ) }, + //{ LSTRKEY( "CPU160MHZ" ), LNUMVAL( CPU160MHZ ) }, + //{ LSTRKEY( "setcpufreq" ), LFUNCVAL( node_setcpufreq) }, + //{ LSTRKEY( "bootreason" ), LFUNCVAL( node_bootreason) }, + {LSTRKEY("restore"), LFUNCVAL(node_restore)}, #ifdef LUA_OPTIMIZE_DEBUG - { LSTRKEY( "stripdebug" ), LFUNCVAL( node_stripdebug ) }, + {LSTRKEY("stripdebug"), LFUNCVAL(node_stripdebug)}, #endif -// Combined to dsleep(us, option) -// { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) }, - { LNILKEY, LNILVAL } -}; + // Combined to dsleep(us, option) + // { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) }, + {LNILKEY, LNILVAL}}; LUALIB_API int luaopen_node(lua_State *L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_NODELIBNAME, node_map ); - return 1; +#else + luaL_register(L, LUA_NODELIBNAME, node_map); + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/nvs.c b/LuaNode_Esp32/LuaNode32/components/modules/nvs.c index 6ae5f36..cec73c6 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/nvs.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/nvs.c @@ -1,4 +1,4 @@ -/** +/** * NVS module for Lua * * function is not support now @@ -6,317 +6,341 @@ * Nicholas3388 * 2017. 04.10 */ -#include "lua.h" +#include "nvs.h" + +#include "esp_log.h" +#include "esp_system.h" #include "lauxlib.h" -#include "lualib.h" #include "lrotable.h" +#include "lua.h" #include "lualib.h" -#include "user_config.h" -#include "esp_system.h" -#include "esp_log.h" #include "nvs_flash.h" -#include "nvs.h" +#include "user_config.h" -static const char *TAG = "nvs_lua_mod"; +static const char* TAG = "nvs_lua_mod"; static nvs_handle handle; static int is_open = 0; -static bool key_exist( lua_State* L, const char *key ) +static bool key_exist(lua_State* L, const char* key) { - bool res = false; - int32_t out_value = 4096; - esp_err_t err = nvs_get_i32(handle, key, &out_value); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - res = false; - break; - case ESP_OK: - res = true; - break; - default: - break; - } - - uint8_t out_str[128]; - size_t length = sizeof(out_str); - err = nvs_get_str(handle, key, out_str, &length); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - res = false; - break; - case ESP_OK: - res = true; - break; - default: - break; - } - return res; + bool res = false; + int32_t out_value = 4096; + esp_err_t err = nvs_get_i32(handle, key, &out_value); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + res = false; + break; + case ESP_OK: + res = true; + break; + default: + break; + } + + uint8_t out_str[128]; + size_t length = sizeof(out_str); + err = nvs_get_str(handle, key, out_str, &length); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + res = false; + break; + case ESP_OK: + res = true; + break; + default: + break; + } + return res; } // ret = nvs.exist(key) // ret=1 if key exist, otherwise, ret=0 -static int lnvs_key_exist( lua_State* L ) +static int lnvs_key_exist(lua_State* L) { - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 1) { - return luaL_error( L, "expected 1 args" ); - } - - const char *key = luaL_checklstring( L, 1, &sl ); - if (key == NULL) { - return luaL_error( L, "the key is null" ); - } - - if (key_exist(L, key)) { - lua_pushinteger(L, 1); - return 1; - } - - lua_pushinteger(L, 0); - return 1; + size_t sl = 0; + if (is_open != 1) + { + return luaL_error(L, "call nvs.open first"); + } + + int argc = lua_gettop(L); + if (argc < 1) + { + return luaL_error(L, "expected 1 args"); + } + + const char* key = luaL_checklstring(L, 1, &sl); + if (key == NULL) + { + return luaL_error(L, "the key is null"); + } + + if (key_exist(L, key)) + { + lua_pushinteger(L, 1); + return 1; + } + + lua_pushinteger(L, 0); + return 1; } // res = nvs.open() // res=0 if open successfully, otherwise, failed -static int lnvs_open( lua_State* L ) +static int lnvs_open(lua_State* L) { - int res = 0; - esp_err_t err = nvs_open("storage", NVS_READWRITE, &handle); - if (err != ESP_OK) { - res = 1; - is_open = 0; - } else { - res = 0; - is_open = 1; - } - lua_pushinteger(L, res); - return 1; + int res = 0; + esp_err_t err = nvs_open("storage", NVS_READWRITE, &handle); + if (err != ESP_OK) + { + res = 1; + is_open = 0; + } + else + { + res = 0; + is_open = 1; + } + lua_pushinteger(L, res); + return 1; } // nvs.close() -static int lnvs_close( lua_State* L ) +static int lnvs_close(lua_State* L) { - nvs_close(handle); - is_open = 0; - return 0; + nvs_close(handle); + is_open = 0; + return 0; } // res = nvs.put(key, value) // key: string type // value: table/string/data/boolean -static int lnvs_put( lua_State* L ) +static int lnvs_put(lua_State* L) { - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 2) { - return luaL_error( L, "expected 2 args" ); - } - - const char *key = luaL_checklstring( L, 1, &sl ); - if (key == NULL) { - return luaL_error( L, "the key is null" ); - } - - if (key_exist(L, key)) { - return luaL_error( L, "key exist! call nvs.remove to remove it first" ); - } - - if (lua_type(L, 2) == LUA_TTABLE) { - ESP_LOGE(TAG, "param is table"); - goto ret_err; - } else if (lua_type(L, 2) == LUA_TSTRING) { - const char *val = luaL_checklstring( L, 2, &sl ); - esp_err_t err = nvs_set_str (handle, key, val); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs set error"); - goto ret_err; - } - err = nvs_commit(handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs commit error"); - goto ret_err; - } - } else if (lua_type(L, 2) == LUA_TNUMBER) { - int val = luaL_checknumber( L, 2 ); - esp_err_t err = nvs_set_i32 (handle, key, val); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs set error"); - goto ret_err; - } - err = nvs_commit(handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs commit error"); - goto ret_err; - } - } else if (lua_type(L, 2) == LUA_TBOOLEAN) { - ESP_LOGI(TAG, "param is boolean"); - bool val = (lua_toboolean(L, 2) ? true : false); - int saveVal = (val? 1:0); - esp_err_t err = nvs_set_i32 (handle, key, saveVal); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs set error"); - goto ret_err; - } - err = nvs_commit(handle); - if (err != ESP_OK) { - ESP_LOGE(TAG, "nvs commit error"); - goto ret_err; - } - } else { - ESP_LOGI(TAG, "unknown param type"); - goto ret_err; - } - - lua_pushinteger(L, 0); - return 1; + size_t sl = 0; + if (is_open != 1) + { + return luaL_error(L, "call nvs.open first"); + } + + int argc = lua_gettop(L); + if (argc < 2) + { + return luaL_error(L, "expected 2 args"); + } + + const char* key = luaL_checklstring(L, 1, &sl); + if (key == NULL) + { + return luaL_error(L, "the key is null"); + } + + if (key_exist(L, key)) + { + return luaL_error(L, "key exist! call nvs.remove to remove it first"); + } + + if (lua_type(L, 2) == LUA_TTABLE) + { + ESP_LOGE(TAG, "param is table"); + goto ret_err; + } + else if (lua_type(L, 2) == LUA_TSTRING) + { + const char* val = luaL_checklstring(L, 2, &sl); + esp_err_t err = nvs_set_str(handle, key, val); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs set error"); + goto ret_err; + } + err = nvs_commit(handle); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs commit error"); + goto ret_err; + } + } + else if (lua_type(L, 2) == LUA_TNUMBER) + { + int val = luaL_checknumber(L, 2); + esp_err_t err = nvs_set_i32(handle, key, val); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs set error"); + goto ret_err; + } + err = nvs_commit(handle); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs commit error"); + goto ret_err; + } + } + else if (lua_type(L, 2) == LUA_TBOOLEAN) + { + ESP_LOGI(TAG, "param is boolean"); + bool val = (lua_toboolean(L, 2) ? true : false); + int saveVal = (val ? 1 : 0); + esp_err_t err = nvs_set_i32(handle, key, saveVal); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs set error"); + goto ret_err; + } + err = nvs_commit(handle); + if (err != ESP_OK) + { + ESP_LOGE(TAG, "nvs commit error"); + goto ret_err; + } + } + else + { + ESP_LOGI(TAG, "unknown param type"); + goto ret_err; + } + + lua_pushinteger(L, 0); + return 1; ret_err: - lua_pushinteger(L, 1); - return 1; + lua_pushinteger(L, 1); + return 1; } // value = nvs.get(key) -static int lnvs_get( lua_State* L ) +static int lnvs_get(lua_State* L) { - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 1) { - return luaL_error( L, "expected at least 1 args" ); - } - - int32_t out_value = 4096; - const char *key = luaL_checklstring( L, 1, &sl ); - - - esp_err_t err = nvs_get_i32(handle, key, &out_value); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - //ESP_LOGE(TAG, "value not found"); - break; - case ESP_ERR_NVS_INVALID_HANDLE: - return luaL_error( L, "invalid nvs handle" ); - case ESP_ERR_NVS_INVALID_NAME: - return luaL_error( L, "invalid name" ); - case ESP_ERR_NVS_INVALID_LENGTH: - break; - case ESP_OK: - lua_pushinteger(L, out_value); - return 1; - default: - break; - } - - uint8_t out_str[128]; - size_t length = sizeof(out_str); - err = nvs_get_str(handle, key, out_str, &length); - switch (err) - { - case ESP_ERR_NVS_NOT_FOUND: - ESP_LOGE(TAG, "value not found"); - lua_pushnil(L); - break; - case ESP_ERR_NVS_INVALID_HANDLE: - return luaL_error( L, "invalid nvs handle" ); - case ESP_ERR_NVS_INVALID_NAME: - return luaL_error( L, "invalid name" ); - case ESP_ERR_NVS_INVALID_LENGTH: - break; - case ESP_OK: - lua_pushlstring(L, out_str, length); - return 1; - default: - break; - } - - return 1; + size_t sl = 0; + if (is_open != 1) + { + return luaL_error(L, "call nvs.open first"); + } + + int argc = lua_gettop(L); + if (argc < 1) + { + return luaL_error(L, "expected at least 1 args"); + } + + int32_t out_value = 4096; + const char* key = luaL_checklstring(L, 1, &sl); + + esp_err_t err = nvs_get_i32(handle, key, &out_value); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + // ESP_LOGE(TAG, "value not found"); + break; + case ESP_ERR_NVS_INVALID_HANDLE: + return luaL_error(L, "invalid nvs handle"); + case ESP_ERR_NVS_INVALID_NAME: + return luaL_error(L, "invalid name"); + case ESP_ERR_NVS_INVALID_LENGTH: + break; + case ESP_OK: + lua_pushinteger(L, out_value); + return 1; + default: + break; + } + + uint8_t out_str[128]; + size_t length = sizeof(out_str); + err = nvs_get_str(handle, key, out_str, &length); + switch (err) + { + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGE(TAG, "value not found"); + lua_pushnil(L); + break; + case ESP_ERR_NVS_INVALID_HANDLE: + return luaL_error(L, "invalid nvs handle"); + case ESP_ERR_NVS_INVALID_NAME: + return luaL_error(L, "invalid name"); + case ESP_ERR_NVS_INVALID_LENGTH: + break; + case ESP_OK: + lua_pushlstring(L, out_str, length); + return 1; + default: + break; + } + + return 1; } // res = nvs.remove(key) // res=0 if remove successfully, otherwise, res!=0 -static int lnvs_remove( lua_State* L ) +static int lnvs_remove(lua_State* L) { - size_t sl = 0; - if (is_open != 1) { - return luaL_error( L, "call nvs.open first" ); - } - - int argc = lua_gettop(L); - if (argc < 1) { - return luaL_error( L, "expected 1 args" ); - } - - const char *key = luaL_checklstring( L, 1, &sl ); - if (key == NULL) { - return luaL_error( L, "the key is null" ); - } - - if (!key_exist(L, key)) { - return luaL_error( L, "key doesn't exist!" ); - } - - esp_err_t err = nvs_erase_key(handle, key); - - switch (err) - { - case ESP_OK: - break; - case ESP_ERR_NVS_INVALID_HANDLE: - return luaL_error( L, "invalid handle" ); - case ESP_ERR_NVS_READ_ONLY: - return luaL_error( L, "nvs is readonly" ); - default: - break; - } - - lua_pushinteger(L, 0); - return 1; + size_t sl = 0; + if (is_open != 1) + { + return luaL_error(L, "call nvs.open first"); + } + + int argc = lua_gettop(L); + if (argc < 1) + { + return luaL_error(L, "expected 1 args"); + } + + const char* key = luaL_checklstring(L, 1, &sl); + if (key == NULL) + { + return luaL_error(L, "the key is null"); + } + + if (!key_exist(L, key)) + { + return luaL_error(L, "key doesn't exist!"); + } + + esp_err_t err = nvs_erase_key(handle, key); + + switch (err) + { + case ESP_OK: + break; + case ESP_ERR_NVS_INVALID_HANDLE: + return luaL_error(L, "invalid handle"); + case ESP_ERR_NVS_READ_ONLY: + return luaL_error(L, "nvs is readonly"); + default: + break; + } + + lua_pushinteger(L, 0); + return 1; } // res = nvs.clearall() -static int lnvs_clearall( lua_State* L ) +static int lnvs_clearall(lua_State* L) { - int res = 0; - esp_err_t err = nvs_erase_all(handle); - if (err != ESP_OK) { - res = 1; - } - lua_pushinteger(L, res); - return 1; + int res = 0; + esp_err_t err = nvs_erase_all(handle); + if (err != ESP_OK) + { + res = 1; + } + lua_pushinteger(L, res); + return 1; } - #include "lrodefs.h" -const LUA_REG_TYPE nvs_map[] = -{ - { LSTRKEY( "open" ), LFUNCVAL( lnvs_open ) }, - { LSTRKEY( "close" ), LFUNCVAL( lnvs_close ) }, - { LSTRKEY( "put" ), LFUNCVAL( lnvs_put ) }, - { LSTRKEY( "get" ), LFUNCVAL( lnvs_get ) }, - { LSTRKEY( "remove" ), LFUNCVAL( lnvs_remove ) }, - { LSTRKEY( "clearall" ), LFUNCVAL( lnvs_clearall ) }, - { LSTRKEY( "exist" ), LFUNCVAL( lnvs_key_exist ) }, - {LNILKEY, LNILVAL} -}; - -int luaopen_nvs(lua_State *L) +const LUA_REG_TYPE nvs_map[] = { + {LSTRKEY("open"), LFUNCVAL(lnvs_open)}, {LSTRKEY("close"), LFUNCVAL(lnvs_close)}, + {LSTRKEY("put"), LFUNCVAL(lnvs_put)}, {LSTRKEY("get"), LFUNCVAL(lnvs_get)}, + {LSTRKEY("remove"), LFUNCVAL(lnvs_remove)}, {LSTRKEY("clearall"), LFUNCVAL(lnvs_clearall)}, + {LSTRKEY("exist"), LFUNCVAL(lnvs_key_exist)}, {LNILKEY, LNILVAL}}; + +int luaopen_nvs(lua_State* L) { - // pre-handle - return 0; + // pre-handle + return 0; } - diff --git a/LuaNode_Esp32/LuaNode32/components/modules/pwm.c b/LuaNode_Esp32/LuaNode32/components/modules/pwm.c index 509e341..fca22e9 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/pwm.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/pwm.c @@ -1,150 +1,147 @@ // Module for interfacing with PWM -#include "modules.h" -#include "lauxlib.h" -#include "platform.h" #include "c_types.h" +#include "lauxlib.h" #include "lualib.h" +#include "modules.h" +#include "platform.h" -#define MAX_DUTY (8192-1) +#define MAX_DUTY (8192 - 1) // Lua: realfrequency = setup( id, frequency, duty ) -static int lpwm_setup( lua_State* L ) +static int lpwm_setup(lua_State* L) { - s32 freq; // signed, to error check for negative values - unsigned duty; - unsigned id; - unsigned channel; - - id = luaL_checkinteger( L, 1 ); - if(id==0) - return luaL_error( L, "no pwm for D0" ); - //MOD_CHECK_ID( pwm, id ); - freq = luaL_checkinteger( L, 2 ); - if ( freq <= 0 ) - return luaL_error( L, "wrong arg range" ); - duty = luaL_checkinteger( L, 3 ); - if ( duty > MAX_DUTY ) - // Negative values will turn out > 100, so will also fail. - return luaL_error( L, "duty should lower than 8192" ); - channel = luaL_checkinteger( L, 4 ); - if (channel > 7) - return luaL_error( L, "channel range from 0 to 7" ); - freq = platform_pwm_setup( id, (u32)freq, duty, channel ); - if(freq==0) - return luaL_error( L, "too many pwms." ); - lua_pushinteger( L, freq ); - return 1; + s32 freq; // signed, to error check for negative values + unsigned duty; + unsigned id; + unsigned channel; + + id = luaL_checkinteger(L, 1); + if (id == 0) + return luaL_error(L, "no pwm for D0"); + // MOD_CHECK_ID( pwm, id ); + freq = luaL_checkinteger(L, 2); + if (freq <= 0) + return luaL_error(L, "wrong arg range"); + duty = luaL_checkinteger(L, 3); + if (duty > MAX_DUTY) + // Negative values will turn out > 100, so will also fail. + return luaL_error(L, "duty should lower than 8192"); + channel = luaL_checkinteger(L, 4); + if (channel > 7) + return luaL_error(L, "channel range from 0 to 7"); + freq = platform_pwm_setup(id, (u32)freq, duty, channel); + if (freq == 0) + return luaL_error(L, "too many pwms."); + lua_pushinteger(L, freq); + return 1; } // Lua: close( id ) -static int lpwm_close( lua_State* L ) +static int lpwm_close(lua_State* L) { - unsigned id; - - id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( pwm, id ); - platform_pwm_close( id ); - return 0; + unsigned id; + + id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( pwm, id ); + platform_pwm_close(id); + return 0; } // Lua: start( id ) -static int lpwm_start( lua_State* L ) +static int lpwm_start(lua_State* L) { - //MOD_CHECK_ID( pwm, id ); - platform_pwm_start(); - return 0; + // MOD_CHECK_ID( pwm, id ); + platform_pwm_start(); + return 0; } // Lua: stop( channel ) -static int lpwm_stop( lua_State* L ) +static int lpwm_stop(lua_State* L) { - unsigned id; - - id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( pwm, id ); - platform_pwm_stop( id ); - return 0; + unsigned id; + + id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( pwm, id ); + platform_pwm_stop(id); + return 0; } // Lua: realclock = setfreq( freq ) -static int lpwm_setfreq( lua_State* L ) +static int lpwm_setfreq(lua_State* L) { - unsigned id; - s32 freq; // signed to error-check for negative values - - //id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( pwm, id ); - freq = luaL_checkinteger( L, 1 ); - if ( freq <= 0 ) - return luaL_error( L, "wrong arg range" ); - freq = platform_pwm_set_clock( 0, (u32)freq ); - lua_pushinteger( L, freq ); - return 1; + unsigned id; + s32 freq; // signed to error-check for negative values + + // id = luaL_checkinteger( L, 1 ); + // MOD_CHECK_ID( pwm, id ); + freq = luaL_checkinteger(L, 1); + if (freq <= 0) + return luaL_error(L, "wrong arg range"); + freq = platform_pwm_set_clock(0, (u32)freq); + lua_pushinteger(L, freq); + return 1; } // Lua: clock = getfreq( ) -static int lpwm_getfreq( lua_State* L ) +static int lpwm_getfreq(lua_State* L) { - unsigned id; - u32 clk; - - //id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( pwm, id ); - clk = platform_pwm_get_clock(); - lua_pushinteger( L, clk ); - return 1; + unsigned id; + u32 clk; + + // id = luaL_checkinteger( L, 1 ); + // MOD_CHECK_ID( pwm, id ); + clk = platform_pwm_get_clock(); + lua_pushinteger(L, clk); + return 1; } // Lua: realduty = setduty( channel, duty ) -static int lpwm_setduty( lua_State* L ) +static int lpwm_setduty(lua_State* L) { - unsigned id; - s32 duty; // signed to error-check for negative values - - id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( pwm, id ); - duty = luaL_checkinteger( L, 2 ); - if ( duty > MAX_DUTY ) - return luaL_error( L, "max duty is 8191" ); - duty = platform_pwm_set_duty( id, (u32)duty ); - lua_pushinteger( L, duty ); - return 1; + unsigned id; + s32 duty; // signed to error-check for negative values + + id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( pwm, id ); + duty = luaL_checkinteger(L, 2); + if (duty > MAX_DUTY) + return luaL_error(L, "max duty is 8191"); + duty = platform_pwm_set_duty(id, (u32)duty); + lua_pushinteger(L, duty); + return 1; } // Lua: duty = getduty( id ) -static int lpwm_getduty( lua_State* L ) +static int lpwm_getduty(lua_State* L) { - unsigned id; - u32 duty; - - id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( pwm, id ); - duty = platform_pwm_get_duty( id ); - lua_pushinteger( L, duty ); - return 1; + unsigned id; + u32 duty; + + id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( pwm, id ); + duty = platform_pwm_get_duty(id); + lua_pushinteger(L, duty); + return 1; } // Module function map -const LUA_REG_TYPE pwm_map[] = { - { LSTRKEY( "setup" ), LFUNCVAL( lpwm_setup ) }, - { LSTRKEY( "close" ), LFUNCVAL( lpwm_close ) }, - { LSTRKEY( "start" ), LFUNCVAL( lpwm_start ) }, - { LSTRKEY( "stop" ), LFUNCVAL( lpwm_stop ) }, - { LSTRKEY( "setfreq" ), LFUNCVAL( lpwm_setfreq ) }, - { LSTRKEY( "getfreq" ), LFUNCVAL( lpwm_getfreq ) }, - { LSTRKEY( "setduty" ), LFUNCVAL( lpwm_setduty ) }, - { LSTRKEY( "getduty" ), LFUNCVAL( lpwm_getduty ) }, - { LNILKEY, LNILVAL } -}; - - -LUALIB_API int luaopen_pwm(lua_State *L) +const LUA_REG_TYPE pwm_map[] = {{LSTRKEY("setup"), LFUNCVAL(lpwm_setup)}, + {LSTRKEY("close"), LFUNCVAL(lpwm_close)}, + {LSTRKEY("start"), LFUNCVAL(lpwm_start)}, + {LSTRKEY("stop"), LFUNCVAL(lpwm_stop)}, + {LSTRKEY("setfreq"), LFUNCVAL(lpwm_setfreq)}, + {LSTRKEY("getfreq"), LFUNCVAL(lpwm_getfreq)}, + {LSTRKEY("setduty"), LFUNCVAL(lpwm_setduty)}, + {LSTRKEY("getduty"), LFUNCVAL(lpwm_getduty)}, + {LNILKEY, LNILVAL}}; + +LUALIB_API int luaopen_pwm(lua_State* L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_PWMLIBNAME, pwm_map ); - return 1; +#else + luaL_register(L, LUA_PWMLIBNAME, pwm_map); + return 1; #endif } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/components/modules/tmr.c b/LuaNode_Esp32/LuaNode32/components/modules/tmr.c index 75566a8..285a2fb 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/tmr.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/tmr.c @@ -17,184 +17,192 @@ tmr.alarm() -- not changed tmr.stop() -- changed, see below. use tmr.unregister for old functionality tmr.register(id, interval, mode, function) - bind function with timer and set the interval in ms - the mode can be: - tmr.ALARM_SINGLE for a single run alarm - tmr.ALARM_SEMI for a multiple single run alarm - tmr.ALARM_AUTO for a repating alarm - tmr.register does NOT start the timer - tmr.alarm is a tmr.register & tmr.start macro + bind function with timer and set the interval in ms + the mode can be: + tmr.ALARM_SINGLE for a single run alarm + tmr.ALARM_SEMI for a multiple single run alarm + tmr.ALARM_AUTO for a repating alarm + tmr.register does NOT start the timer + tmr.alarm is a tmr.register & tmr.start macro tmr.unregister(id) - stop alarm, unbind function and clean up memory - not needed for ALARM_SINGLE, as it unregisters itself + stop alarm, unbind function and clean up memory + not needed for ALARM_SINGLE, as it unregisters itself tmr.start(id) - ret: bool - start a alarm, returns true on success + ret: bool + start a alarm, returns true on success tmr.stop(id) - ret: bool - stops a alarm, returns true on success - this call dose not free any memory, to do so use tmr.unregister - stopped alarms can be started with start + ret: bool + stops a alarm, returns true on success + this call dose not free any memory, to do so use tmr.unregister + stopped alarms can be started with start tmr.interval(id, interval) - set alarm interval, running alarm will be restarted + set alarm interval, running alarm will be restarted tmr.state(id) - ret: (bool, int) or nil - returns alarm status (true=started/false=stopped) and mode - nil if timer is unregistered + ret: (bool, int) or nil + returns alarm status (true=started/false=stopped) and mode + nil if timer is unregistered tmr.softwd(int) - set a negative value to stop the timer - any other value starts the timer, when the - countdown reaches zero, the device restarts - the timer units are seconds + set a negative value to stop the timer + any other value starts the timer, when the + countdown reaches zero, the device restarts + the timer units are seconds */ - -#include "lualib.h" -#include "lauxlib.h" -#include "platform.h" -#include "lrotable.h" -#include "lrodefs.h" #include "c_types.h" -#include "lualib.h" -#include "esp_timer.h" +#include "driver/timer.h" #include "esp_misc.h" #include "esp_system.h" +#include "esp_timer.h" +#include "lauxlib.h" +#include "lrodefs.h" +#include "lrotable.h" +#include "lualib.h" #include "modules.h" -#include "driver/timer.h" +#include "platform.h" -#define NUM_TMR 7 +#define NUM_TMR 7 #define TIMER_MODE_OFF 3 #define TIMER_MODE_SINGLE 0 #define TIMER_MODE_SEMI 2 #define TIMER_MODE_AUTO 1 -#define TIMER_IDLE_FLAG (1<<7) +#define TIMER_IDLE_FLAG (1 << 7) -#define TIMER_DIVIDER 16 // Hardware timer clock divider -#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds +#define TIMER_DIVIDER 16 // Hardware timer clock divider +#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds -#define TIMER_INTERVAL0_SEC (3.4179) // sample test interval for the first timer -#define TEST_WITHOUT_RELOAD 0 // testing will be done without auto reload -#define TEST_WITH_RELOAD 1 // testing will be done with auto reload +#define TIMER_INTERVAL0_SEC (3.4179) // sample test interval for the first timer +#define TEST_WITHOUT_RELOAD 0 // testing will be done without auto reload +#define TEST_WITH_RELOAD 1 // testing will be done with auto reload - -//well, the following are my assumptions -//why, oh why is there no good documentation -//chinese companies should learn from Atmel +// well, the following are my assumptions +// why, oh why is there no good documentation +// chinese companies should learn from Atmel extern void ets_delay_us(uint32_t us); extern uint32_t system_get_time(); -//extern uint32_t system_rtc_clock_cali_proc(); +// extern uint32_t system_rtc_clock_cali_proc(); extern uint32_t system_get_rtc_time(); extern void system_soft_wdt_feed(); -//in fact lua_State is constant, it's pointless to pass it around -//but hey, whatever, I'll just pass it, still we waste 28B here -typedef struct{ - //os_timer_t os; - lua_State* L; - sint32_t lua_ref; - uint32_t interval; - uint8_t mode; -}timer_struct_t; +// in fact lua_State is constant, it's pointless to pass it around +// but hey, whatever, I'll just pass it, still we waste 28B here +typedef struct +{ + // os_timer_t os; + lua_State* L; + sint32_t lua_ref; + uint32_t interval; + uint8_t mode; +} timer_struct_t; typedef timer_struct_t* my_timer_t; -typedef struct { +typedef struct +{ int type; // the type of timer's event int timer_group; int timer_idx; uint64_t timer_counter_value; } timer_event_t; -//everybody just love unions! riiiiight? +// everybody just love unions! riiiiight? static union { - uint64_t block; - uint32_t part[2]; + uint64_t block; + uint32_t part[2]; } rtc_time; -static sint32_t soft_watchdog = -1; +static sint32_t soft_watchdog = -1; static timer_struct_t alarm_timers[NUM_TMR]; -//static os_timer_t rtc_timer; +// static os_timer_t rtc_timer; static xQueueHandle timer_queue; -static void alarm_timer_common(void* arg){ - my_timer_t tmr = &alarm_timers[(uint32_t)arg]; - if(tmr->lua_ref == LUA_NOREF || tmr->L == NULL) - return; - lua_rawgeti(tmr->L, LUA_REGISTRYINDEX, tmr->lua_ref); - //if the timer was set to single run we clean up after it - if(tmr->mode == TIMER_MODE_SINGLE){ - luaL_unref(tmr->L, LUA_REGISTRYINDEX, tmr->lua_ref); - tmr->lua_ref = LUA_NOREF; - tmr->mode = TIMER_MODE_OFF; - }else if(tmr->mode == TIMER_MODE_SEMI){ - tmr->mode |= TIMER_IDLE_FLAG; - } - lua_call(tmr->L, 0, 0); +static void alarm_timer_common(void* arg) +{ + my_timer_t tmr = &alarm_timers[(uint32_t)arg]; + if (tmr->lua_ref == LUA_NOREF || tmr->L == NULL) + return; + lua_rawgeti(tmr->L, LUA_REGISTRYINDEX, tmr->lua_ref); + // if the timer was set to single run we clean up after it + if (tmr->mode == TIMER_MODE_SINGLE) + { + luaL_unref(tmr->L, LUA_REGISTRYINDEX, tmr->lua_ref); + tmr->lua_ref = LUA_NOREF; + tmr->mode = TIMER_MODE_OFF; + } + else if (tmr->mode == TIMER_MODE_SEMI) + { + tmr->mode |= TIMER_IDLE_FLAG; + } + lua_call(tmr->L, 0, 0); } -void tmr_delay_msec(int ms) { - vTaskDelay(ms/portTICK_RATE_MS); -} +void tmr_delay_msec(int ms) { vTaskDelay(ms / portTICK_RATE_MS); } // Lua: tmr.delay( s ) delay seconds -static int tmr_delay_s( lua_State *L ) { - uint32_t period = luaL_checkinteger(L, 1); - vTaskDelay(period*(1000/portTICK_RATE_MS)); - return 0; +static int tmr_delay_s(lua_State* L) +{ + uint32_t period = luaL_checkinteger(L, 1); + vTaskDelay(period * (1000 / portTICK_RATE_MS)); + return 0; } // Lua: tmr.delay_ms( ms ) -static int tmr_delay_ms( lua_State *L ) { - uint32_t period = luaL_checkinteger(L, 1); - tmr_delay_msec(period); - return 0; +static int tmr_delay_ms(lua_State* L) +{ + uint32_t period = luaL_checkinteger(L, 1); + tmr_delay_msec(period); + return 0; } // Lua: tmr.delay_us( us ) -static int tmr_delay( lua_State* L ){ - sint32_t us = luaL_checkinteger(L, 1); - if(us <= 0) - return luaL_error(L, "wrong arg range"); - while(us >= 1000000){ - us -= 1000000; - vTaskDelay(1000/portTICK_RATE_MS); - } - uint32_t remain = (uint32_t)(us/1000); - if(remain > 0) { - us = us % 1000; - vTaskDelay(remain/portTICK_RATE_MS); - } - if(us > 0) { - os_delay_us(us); - } - return 0; +static int tmr_delay(lua_State* L) +{ + sint32_t us = luaL_checkinteger(L, 1); + if (us <= 0) + return luaL_error(L, "wrong arg range"); + while (us >= 1000000) + { + us -= 1000000; + vTaskDelay(1000 / portTICK_RATE_MS); + } + uint32_t remain = (uint32_t)(us / 1000); + if (remain > 0) + { + us = us % 1000; + vTaskDelay(remain / portTICK_RATE_MS); + } + if (us > 0) + { + os_delay_us(us); + } + return 0; } // Lua: tmr.now() , return system timer in us -static int tmr_now(lua_State* L){ - uint32_t now = 0x7FFFFFFF & system_get_time(); - lua_pushinteger(L, now); - return 1; +static int tmr_now(lua_State* L) +{ + uint32_t now = 0x7FFFFFFF & system_get_time(); + lua_pushinteger(L, now); + return 1; } /* * Timer group0 ISR handler * * Note: - * We don't call the timer API here because they are not declared with IRAM_ATTR. - * If we're okay with the timer irq not being serviced while SPI flash cache is disabled, - * we can allocate this interrupt without the ESP_INTR_FLAG_IRAM flag and use the normal API. + * We don't call the timer API here because they are not declared with + * IRAM_ATTR. If we're okay with the timer irq not being serviced while SPI + * flash cache is disabled, we can allocate this interrupt without the + * ESP_INTR_FLAG_IRAM flag and use the normal API. */ -void IRAM_ATTR timer_group0_isr(void *para) +void IRAM_ATTR timer_group0_isr(void* para) { - int timer_idx = (int) para; + int timer_idx = (int)para; /* Retrieve the interrupt status and the counter value from the timer that reported the interrupt */ uint32_t intr_status = TIMERG0.int_st_timers.val; TIMERG0.hw_timer[timer_idx].update = 1; - uint64_t timer_counter_value = - ((uint64_t) TIMERG0.hw_timer[timer_idx].cnt_high) << 32 - | TIMERG0.hw_timer[timer_idx].cnt_low; + uint64_t timer_counter_value = + ((uint64_t)TIMERG0.hw_timer[timer_idx].cnt_high) << 32 | TIMERG0.hw_timer[timer_idx].cnt_low; /* Prepare basic event data that will be then sent back to the main program task */ @@ -205,17 +213,22 @@ void IRAM_ATTR timer_group0_isr(void *para) /* Clear the interrupt and update the alarm time for the timer with without reload */ - if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) { + if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) + { evt.type = TEST_WITHOUT_RELOAD; TIMERG0.int_clr_timers.t0 = 1; - timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE); - TIMERG0.hw_timer[timer_idx].alarm_high = (uint32_t) (timer_counter_value >> 32); - TIMERG0.hw_timer[timer_idx].alarm_low = (uint32_t) timer_counter_value; - } else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) { + timer_counter_value += (uint64_t)(TIMER_INTERVAL0_SEC * TIMER_SCALE); + TIMERG0.hw_timer[timer_idx].alarm_high = (uint32_t)(timer_counter_value >> 32); + TIMERG0.hw_timer[timer_idx].alarm_low = (uint32_t)timer_counter_value; + } + else if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_1) + { evt.type = TEST_WITH_RELOAD; TIMERG0.int_clr_timers.t1 = 1; - } else { - evt.type = -1; // not supported even type + } + else + { + evt.type = -1; // not supported even type } /* After the alarm has been triggered @@ -226,7 +239,8 @@ void IRAM_ATTR timer_group0_isr(void *para) xQueueSendFromISR(timer_queue, &evt, NULL); } -static void example_tg0_timer_init(int timer_idx, bool auto_reload, double timer_interval_sec) { +static void example_tg0_timer_init(int timer_idx, bool auto_reload, double timer_interval_sec) +{ /* Select and initialize basic parameters of the timer */ timer_config_t config; config.divider = TIMER_DIVIDER; @@ -238,132 +252,152 @@ static void example_tg0_timer_init(int timer_idx, bool auto_reload, double timer timer_init(TIMER_GROUP_0, timer_idx, &config); /* Timer's counter will initially start from value below. - Also, if auto_reload is set, this value will be automatically reload on alarm */ + Also, if auto_reload is set, this value will be automatically reload on + alarm */ timer_set_counter_value(TIMER_GROUP_0, timer_idx, 0x00000000ULL); /* Configure the alarm value and the interrupt on alarm. */ timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE); timer_enable_intr(TIMER_GROUP_0, timer_idx); - timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, - (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL); + timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr, (void*)timer_idx, ESP_INTR_FLAG_IRAM, NULL); timer_start(TIMER_GROUP_0, timer_idx); } // Lua: tmr.register( id, interval, mode, function ) -static int tmr_register(lua_State* L){ - uint32_t id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID(tmr, id); - sint32_t interval = luaL_checkinteger(L, 2); - uint8_t mode = luaL_checkinteger(L, 3); - //validate arguments - uint8_t args_valid = interval <= 0 - || (mode != TIMER_MODE_SINGLE && mode != TIMER_MODE_SEMI && mode != TIMER_MODE_AUTO) - || (lua_type(L, 4) != LUA_TFUNCTION && lua_type(L, 4) != LUA_TLIGHTFUNCTION); - if(args_valid) - return luaL_error(L, "wrong arg range"); - //get the lua function reference - lua_pushvalue(L, 4); - sint32_t ref = luaL_ref(L, LUA_REGISTRYINDEX); - my_timer_t tmr = &alarm_timers[id]; - if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF) { - //os_timer_disarm(&tmr->os); - } - //there was a bug in this part, the second part of the following condition was missing - if(tmr->lua_ref != LUA_NOREF && tmr->lua_ref != ref) - luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref); - tmr->lua_ref = ref; - tmr->mode = mode|TIMER_IDLE_FLAG; - tmr->interval = interval; - tmr->L = L; - //os_timer_setfn(&tmr->os, alarm_timer_common, (void*)id); - example_tg0_timer_init(TIMER_0, TEST_WITHOUT_RELOAD, interval); - return 0; +static int tmr_register(lua_State* L) +{ + uint32_t id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID(tmr, id); + sint32_t interval = luaL_checkinteger(L, 2); + uint8_t mode = luaL_checkinteger(L, 3); + // validate arguments + uint8_t args_valid = interval <= 0 || + (mode != TIMER_MODE_SINGLE && mode != TIMER_MODE_SEMI && mode != TIMER_MODE_AUTO) || + (lua_type(L, 4) != LUA_TFUNCTION && lua_type(L, 4) != LUA_TLIGHTFUNCTION); + if (args_valid) + return luaL_error(L, "wrong arg range"); + // get the lua function reference + lua_pushvalue(L, 4); + sint32_t ref = luaL_ref(L, LUA_REGISTRYINDEX); + my_timer_t tmr = &alarm_timers[id]; + if (!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF) + { + // os_timer_disarm(&tmr->os); + } + // there was a bug in this part, the second part of the following condition + // was missing + if (tmr->lua_ref != LUA_NOREF && tmr->lua_ref != ref) + luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref); + tmr->lua_ref = ref; + tmr->mode = mode | TIMER_IDLE_FLAG; + tmr->interval = interval; + tmr->L = L; + // os_timer_setfn(&tmr->os, alarm_timer_common, (void*)id); + example_tg0_timer_init(TIMER_0, TEST_WITHOUT_RELOAD, interval); + return 0; } // Lua: tmr.start( id ) -static int tmr_start(lua_State* L){ - uint8_t id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID(tmr,id); - my_timer_t tmr = &alarm_timers[id]; - //we return false if the timer is not idle - if(!(tmr->mode&TIMER_IDLE_FLAG)){ - lua_pushboolean(L, 0); - }else{ - tmr->mode &= ~TIMER_IDLE_FLAG; - //os_timer_arm(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO); - lua_pushboolean(L, 1); - } - return 1; +static int tmr_start(lua_State* L) +{ + uint8_t id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID(tmr,id); + my_timer_t tmr = &alarm_timers[id]; + // we return false if the timer is not idle + if (!(tmr->mode & TIMER_IDLE_FLAG)) + { + lua_pushboolean(L, 0); + } + else + { + tmr->mode &= ~TIMER_IDLE_FLAG; + // os_timer_arm(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO); + lua_pushboolean(L, 1); + } + return 1; } // Lua: tmr.alarm( id, interval, repeat, function ) -static int tmr_alarm(lua_State* L){ - tmr_register(L); - return tmr_start(L); +static int tmr_alarm(lua_State* L) +{ + tmr_register(L); + return tmr_start(L); } // Lua: tmr.stop( id ) -static int tmr_stop(lua_State* L){ - uint8_t id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID(tmr,id); - my_timer_t tmr = &alarm_timers[id]; - //we return false if the timer is idle (of not registered) - if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF){ - tmr->mode |= TIMER_IDLE_FLAG; - //os_timer_disarm(&tmr->os); - lua_pushboolean(L, 1); - }else{ - lua_pushboolean(L, 0); - } - return 1; +static int tmr_stop(lua_State* L) +{ + uint8_t id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID(tmr,id); + my_timer_t tmr = &alarm_timers[id]; + // we return false if the timer is idle (of not registered) + if (!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF) + { + tmr->mode |= TIMER_IDLE_FLAG; + // os_timer_disarm(&tmr->os); + lua_pushboolean(L, 1); + } + else + { + lua_pushboolean(L, 0); + } + return 1; } // Lua: tmr.unregister( id ) -static int tmr_unregister(lua_State* L){ - uint8_t id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID(tmr,id); - my_timer_t tmr = &alarm_timers[id]; - if(!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF) { - //os_timer_disarm(&tmr->os); - } - if(tmr->lua_ref != LUA_NOREF) - luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref); - tmr->lua_ref = LUA_NOREF; - tmr->mode = TIMER_MODE_OFF; - return 0; +static int tmr_unregister(lua_State* L) +{ + uint8_t id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID(tmr,id); + my_timer_t tmr = &alarm_timers[id]; + if (!(tmr->mode & TIMER_IDLE_FLAG) && tmr->mode != TIMER_MODE_OFF) + { + // os_timer_disarm(&tmr->os); + } + if (tmr->lua_ref != LUA_NOREF) + luaL_unref(L, LUA_REGISTRYINDEX, tmr->lua_ref); + tmr->lua_ref = LUA_NOREF; + tmr->mode = TIMER_MODE_OFF; + return 0; } // Lua: tmr.interval( id, interval ) -static int tmr_interval(lua_State* L){ - uint8_t id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID(tmr,id); - my_timer_t tmr = &alarm_timers[id]; - sint32_t interval = luaL_checkinteger(L, 2); - if(interval <= 0) - return luaL_error(L, "wrong arg range"); - if(tmr->mode != TIMER_MODE_OFF){ - tmr->interval = interval; - if(!(tmr->mode&TIMER_IDLE_FLAG)){ - //os_timer_disarm(&tmr->os); - //os_timer_arm(&tmr->os, tmr->interval, tmr->mode==TIMER_MODE_AUTO); - } - } - return 0; +static int tmr_interval(lua_State* L) +{ + uint8_t id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID(tmr,id); + my_timer_t tmr = &alarm_timers[id]; + sint32_t interval = luaL_checkinteger(L, 2); + if (interval <= 0) + return luaL_error(L, "wrong arg range"); + if (tmr->mode != TIMER_MODE_OFF) + { + tmr->interval = interval; + if (!(tmr->mode & TIMER_IDLE_FLAG)) + { + // os_timer_disarm(&tmr->os); + // os_timer_arm(&tmr->os, tmr->interval, + // tmr->mode==TIMER_MODE_AUTO); + } + } + return 0; } // Lua: tmr.state( id ) -static int tmr_state(lua_State* L){ - uint8_t id = luaL_checkinteger(L, 1); - //MOD_CHECK_ID(tmr,id); - my_timer_t tmr = &alarm_timers[id]; - if(tmr->mode == TIMER_MODE_OFF){ - lua_pushnil(L); - return 1; - } - lua_pushboolean(L, (tmr->mode&TIMER_IDLE_FLAG)==0); - lua_pushinteger(L, tmr->mode&(~TIMER_IDLE_FLAG)); - return 2; +static int tmr_state(lua_State* L) +{ + uint8_t id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID(tmr,id); + my_timer_t tmr = &alarm_timers[id]; + if (tmr->mode == TIMER_MODE_OFF) + { + lua_pushnil(L); + return 1; + } + lua_pushboolean(L, (tmr->mode & TIMER_IDLE_FLAG) == 0); + lua_pushinteger(L, tmr->mode & (~TIMER_IDLE_FLAG)); + return 2; } /*I left the led comments 'couse I don't know @@ -371,126 +405,137 @@ why they are here*/ // extern void update_key_led(); // Lua: tmr.wdclr() -static int tmr_wdclr( lua_State* L ){ - //system_soft_wdt_feed (); - // update_key_led(); - return 0; +static int tmr_wdclr(lua_State* L) +{ + // system_soft_wdt_feed (); + // update_key_led(); + return 0; } -//system_rtc_clock_cali_proc() returns -//a fixed point value (12 bit fraction part) -//it tells how many rtc clock ticks represent 1us. -//the high 64 bits of the uint64_t multiplication -//are unnedded (I did the math) -static uint32_t rtc2sec(uint64_t rtc){ - uint64_t aku = system_get_rtc_time(); - aku *= rtc; - return (aku>>12)/1000000; +// system_rtc_clock_cali_proc() returns +// a fixed point value (12 bit fraction part) +// it tells how many rtc clock ticks represent 1us. +// the high 64 bits of the uint64_t multiplication +// are unnedded (I did the math) +static uint32_t rtc2sec(uint64_t rtc) +{ + uint64_t aku = system_get_rtc_time(); + aku *= rtc; + return (aku >> 12) / 1000000; } -//the following function workes, I just wrote it and didn't use it. +// the following function workes, I just wrote it and didn't use it. /*static uint64_t sec2rtc(uint32_t sec){ - uint64_t aku = (1<<20)/system_rtc_clock_cali_proc(); - aku *= sec; - return (aku>>8)*1000000; + uint64_t aku = (1<<20)/system_rtc_clock_cali_proc(); + aku *= sec; + return (aku>>8)*1000000; }*/ -inline static void rtc_timer_update(){ - uint32_t current = system_get_rtc_time(); - if(rtc_time.part[0] > current) //overflow check - rtc_time.part[1]++; - rtc_time.part[0] = current; +inline static void rtc_timer_update() +{ + uint32_t current = system_get_rtc_time(); + if (rtc_time.part[0] > current) // overflow check + rtc_time.part[1]++; + rtc_time.part[0] = current; } -void rtc_callback(void *arg){ - rtc_timer_update(); - if(soft_watchdog > 0){ - soft_watchdog--; - if(soft_watchdog == 0) - esp_restart(); - } +void rtc_callback(void* arg) +{ + rtc_timer_update(); + if (soft_watchdog > 0) + { + soft_watchdog--; + if (soft_watchdog == 0) + esp_restart(); + } } // Lua: tmr.time() , return rtc time in second -static int tmr_time( lua_State* L ){ - rtc_timer_update(); - lua_pushinteger(L, rtc2sec(rtc_time.block)); - return 1; +static int tmr_time(lua_State* L) +{ + rtc_timer_update(); + lua_pushinteger(L, rtc2sec(rtc_time.block)); + return 1; } // Lua: tmr.softwd( value ) -static int tmr_softwd( lua_State* L ){ - soft_watchdog = luaL_checkinteger(L, 1); - return 0; +static int tmr_softwd(lua_State* L) +{ + soft_watchdog = luaL_checkinteger(L, 1); + return 0; } // Module function map -const LUA_REG_TYPE tmr_map[] = { - { LSTRKEY( "delay_us" ), LFUNCVAL( tmr_delay ) }, - { LSTRKEY( "delay_ms" ), LFUNCVAL( tmr_delay_ms ) }, - { LSTRKEY( "delay" ), LFUNCVAL( tmr_delay_s ) }, - { LSTRKEY( "now" ), LFUNCVAL( tmr_now ) }, - { LSTRKEY( "wdclr" ), LFUNCVAL( tmr_wdclr ) }, - { LSTRKEY( "softwd" ), LFUNCVAL( tmr_softwd ) }, - { LSTRKEY( "time" ), LFUNCVAL( tmr_time ) }, - { LSTRKEY( "register" ), LFUNCVAL ( tmr_register ) }, - { LSTRKEY( "alarm" ), LFUNCVAL( tmr_alarm ) }, - { LSTRKEY( "start" ), LFUNCVAL ( tmr_start ) }, - { LSTRKEY( "stop" ), LFUNCVAL ( tmr_stop ) }, - { LSTRKEY( "unregister" ), LFUNCVAL ( tmr_unregister ) }, - { LSTRKEY( "state" ), LFUNCVAL ( tmr_state ) }, - { LSTRKEY( "interval" ), LFUNCVAL ( tmr_interval) }, +const LUA_REG_TYPE tmr_map[] = {{LSTRKEY("delay_us"), LFUNCVAL(tmr_delay)}, + {LSTRKEY("delay_ms"), LFUNCVAL(tmr_delay_ms)}, + {LSTRKEY("delay"), LFUNCVAL(tmr_delay_s)}, + {LSTRKEY("now"), LFUNCVAL(tmr_now)}, + {LSTRKEY("wdclr"), LFUNCVAL(tmr_wdclr)}, + {LSTRKEY("softwd"), LFUNCVAL(tmr_softwd)}, + {LSTRKEY("time"), LFUNCVAL(tmr_time)}, + {LSTRKEY("register"), LFUNCVAL(tmr_register)}, + {LSTRKEY("alarm"), LFUNCVAL(tmr_alarm)}, + {LSTRKEY("start"), LFUNCVAL(tmr_start)}, + {LSTRKEY("stop"), LFUNCVAL(tmr_stop)}, + {LSTRKEY("unregister"), LFUNCVAL(tmr_unregister)}, + {LSTRKEY("state"), LFUNCVAL(tmr_state)}, + {LSTRKEY("interval"), LFUNCVAL(tmr_interval)}, #if LUA_OPTIMIZE_MEMORY > 0 - { LSTRKEY( "ALARM_SINGLE" ), LNUMVAL( TIMER_MODE_SINGLE ) }, - { LSTRKEY( "ALARM_SEMI" ), LNUMVAL( TIMER_MODE_SEMI ) }, - { LSTRKEY( "ALARM_AUTO" ), LNUMVAL( TIMER_MODE_AUTO ) }, + {LSTRKEY("ALARM_SINGLE"), LNUMVAL(TIMER_MODE_SINGLE)}, + {LSTRKEY("ALARM_SEMI"), LNUMVAL(TIMER_MODE_SEMI)}, + {LSTRKEY("ALARM_AUTO"), LNUMVAL(TIMER_MODE_AUTO)}, #endif - { LNILKEY, LNILVAL } -}; + {LNILKEY, LNILVAL}}; - -LUALIB_API int luaopen_tmr(lua_State *L) +LUALIB_API int luaopen_tmr(lua_State* L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_TMRLIBNAME, tmr_map ); - return 1; +#else + luaL_register(L, LUA_TMRLIBNAME, tmr_map); + return 1; #endif } - -static void timer_evt_task(void *arg) { - while (1) { +static void timer_evt_task(void* arg) +{ + while (1) + { timer_event_t evt; xQueueReceive(timer_queue, &evt, portMAX_DELAY); /* Print information that the timer reported an event */ - if (evt.type == TEST_WITHOUT_RELOAD) { + if (evt.type == TEST_WITHOUT_RELOAD) + { printf("\n Example timer without reload\n"); - } else if (evt.type == TEST_WITH_RELOAD) { + } + else if (evt.type == TEST_WITH_RELOAD) + { printf("\n Example timer with auto reload\n"); - } else { + } + else + { printf("\n UNKNOWN EVENT TYPE\n"); } printf("Group[%d], timer[%d] alarm event\n", evt.timer_group, evt.timer_idx); /* Print the timer values passed by event */ printf("------- EVENT TIME --------\n"); - //print_timer_counter(evt.timer_counter_value); + // print_timer_counter(evt.timer_counter_value); /* Print the timer values as visible by this task */ printf("-------- TASK TIME --------\n"); uint64_t task_counter_value; timer_get_counter_value(evt.timer_group, evt.timer_idx, &task_counter_value); - //print_timer_counter(task_counter_value); + // print_timer_counter(task_counter_value); } } -void tmr_init(void) { - // timer task init - printf("timer task init\r\n"); - timer_queue = xQueueCreate(10, sizeof(timer_event_t)); - xTaskCreate(timer_evt_task, "timer_evt_task", 2048, NULL, 5, NULL); +void tmr_init(void) +{ + // timer task init + printf("timer task init\r\n"); + timer_queue = xQueueCreate(10, sizeof(timer_event_t)); + xTaskCreate(timer_evt_task, "timer_evt_task", 2048, NULL, 5, NULL); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/components/modules/uart.c b/LuaNode_Esp32/LuaNode32/components/modules/uart.c index 27d6569..aa00ed1 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/uart.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/uart.c @@ -1,139 +1,158 @@ // Module for interfacing with serial -#include "modules.h" +#include "driver/uart.h" + +#include "c_string.h" +#include "c_types.h" #include "lauxlib.h" +#include "lrodefs.h" +#include "lrotable.h" #include "lualib.h" +#include "modules.h" #include "platform.h" -#include "lrotable.h" -#include "lrodefs.h" -#include "driver/uart.h" -#include "c_types.h" -#include "c_string.h" -#define DEFAULT_TXD (4) -#define DEFAULT_RXD (5) -#define DEFAULT_RTS (18) -#define DEFAULT_CTS (19) +#define DEFAULT_TXD (4) +#define DEFAULT_RXD (5) +#define DEFAULT_RTS (18) +#define DEFAULT_CTS (19) static lua_State *gL = NULL; static int uart_receive_rf = LUA_NOREF; bool run_input = true; -bool uart_on_data_cb(const char *buf, size_t len){ - if(!buf || len==0) - return false; - if(uart_receive_rf == LUA_NOREF) - return false; - if(!gL) - return false; - lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_receive_rf); - lua_pushlstring(gL, buf, len); - lua_call(gL, 1, 0); - return !run_input; +bool uart_on_data_cb(const char *buf, size_t len) +{ + if (!buf || len == 0) + return false; + if (uart_receive_rf == LUA_NOREF) + return false; + if (!gL) + return false; + lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_receive_rf); + lua_pushlstring(gL, buf, len); + lua_call(gL, 1, 0); + return !run_input; } uint16_t need_len = 0; int16_t end_char = -1; // Lua: uart.on("method", [number/char], function, [run_input]) -static int uart_on( lua_State* L ) +static int uart_on(lua_State *L) { - size_t sl, el; - int32_t run = 1; - uint8_t stack = 1; - const char *method = luaL_checklstring( L, stack, &sl ); - stack++; - if (method == NULL) - return luaL_error( L, "wrong arg type" ); - - if( lua_type( L, stack ) == LUA_TNUMBER ) - { - need_len = ( uint16_t )luaL_checkinteger( L, stack ); + size_t sl, el; + int32_t run = 1; + uint8_t stack = 1; + const char *method = luaL_checklstring(L, stack, &sl); stack++; - end_char = -1; - if( need_len > 255 ){ - need_len = 255; - return luaL_error( L, "wrong arg range" ); + if (method == NULL) + return luaL_error(L, "wrong arg type"); + + if (lua_type(L, stack) == LUA_TNUMBER) + { + need_len = (uint16_t)luaL_checkinteger(L, stack); + stack++; + end_char = -1; + if (need_len > 255) + { + need_len = 255; + return luaL_error(L, "wrong arg range"); + } } - } - else if(lua_isstring(L, stack)) - { - const char *end = luaL_checklstring( L, stack, &el ); - stack++; - if(el!=1){ - return luaL_error( L, "wrong arg range" ); + else if (lua_isstring(L, stack)) + { + const char *end = luaL_checklstring(L, stack, &el); + stack++; + if (el != 1) + { + return luaL_error(L, "wrong arg range"); + } + end_char = (int16_t)end[0]; + need_len = 0; } - end_char = (int16_t)end[0]; - need_len = 0; - } - - // luaL_checkanyfunction(L, stack); - if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){ - if ( lua_isnumber(L, stack+1) ){ - run = lua_tointeger(L, stack+1); + + // luaL_checkanyfunction(L, stack); + if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION) + { + if (lua_isnumber(L, stack + 1)) + { + run = lua_tointeger(L, stack + 1); + } + lua_pushvalue(L, stack); // copy argument (func) to the top of stack + } + else + { + lua_pushnil(L); } - lua_pushvalue(L, stack); // copy argument (func) to the top of stack - } else { - lua_pushnil(L); - } - if(sl == 4 && c_strcmp(method, "data") == 0){ - run_input = true; - if(uart_receive_rf != LUA_NOREF){ - luaL_unref(L, LUA_REGISTRYINDEX, uart_receive_rf); - uart_receive_rf = LUA_NOREF; + if (sl == 4 && c_strcmp(method, "data") == 0) + { + run_input = true; + if (uart_receive_rf != LUA_NOREF) + { + luaL_unref(L, LUA_REGISTRYINDEX, uart_receive_rf); + uart_receive_rf = LUA_NOREF; + } + if (!lua_isnil(L, -1)) + { + uart_receive_rf = luaL_ref(L, LUA_REGISTRYINDEX); + gL = L; + if (run == 0) + run_input = false; + } + else + { + lua_pop(L, 1); + } } - if(!lua_isnil(L, -1)){ - uart_receive_rf = luaL_ref(L, LUA_REGISTRYINDEX); - gL = L; - if(run==0) - run_input = false; - } else { - lua_pop(L, 1); + else + { + lua_pop(L, 1); + return luaL_error(L, "method not supported"); } - }else{ - lua_pop(L, 1); - return luaL_error( L, "method not supported" ); - } - return 0; + return 0; } bool uart0_echo = true; -// Lua: actualbaud = setup( id, baud, databits, parity, stopbits, flow_ctl, txd, rxd, rts, cts ) -static int uart_setup( lua_State* L ) +// Lua: actualbaud = setup( id, baud, databits, parity, stopbits, flow_ctl, txd, +// rxd, rts, cts ) +static int uart_setup(lua_State *L) { - unsigned id, databits, parity, stopbits, flow, txd=DEFAULT_TXD, rxd=DEFAULT_RXD, rts=DEFAULT_CTS, cts=DEFAULT_RTS; - u32 baud, res; - - id = luaL_checkinteger( L, 1 ); - MOD_CHECK_ID( uart, id ); - baud = luaL_checkinteger( L, 2 ); - databits = luaL_checkinteger( L, 3 ); - parity = luaL_checkinteger( L, 4 ); - stopbits = luaL_checkinteger( L, 5 ); - flow = luaL_checkinteger( L, 6 ); - int params_num = lua_gettop( L ); - if (params_num > 6) { - int i; - for (i=7; i 6) + { + int i; + for (i = 7; i < params_num; i++) + { + switch (i) + { + case 7: + txd = luaL_checkinteger(L, 7); + break; + case 8: + rxd = luaL_checkinteger(L, 8); + break; + case 9: + rts = luaL_checkinteger(L, 9); + break; + case 10: + cts = luaL_checkinteger(L, 10); + break; + } + } + } + + res = platform_uart_setup(id, baud, databits, parity, stopbits, flow, txd, rxd, rts, cts); + lua_pushinteger(L, res); + return 1; } #if 0 @@ -150,80 +169,78 @@ static int uart_alt( lua_State* L ) #endif // Lua: write( id, string1, [string2], ..., [stringn] ) -static int uart_write( lua_State* L ) +static int uart_write(lua_State *L) { - int id; - const char* buf; - size_t len, i; - int total = lua_gettop( L ), s; - - id = luaL_checkinteger( L, 1 ); - //MOD_CHECK_ID( uart, id ); - for( s = 2; s <= total; s ++ ) - { - if( lua_type( L, s ) == LUA_TNUMBER ) - { - len = lua_tointeger( L, s ); - if( len > 255 ) - return luaL_error( L, "invalid number" ); - platform_uart_send( id, &len, 1 ); - } - else + int id; + const char *buf; + size_t len, i; + int total = lua_gettop(L), s; + + id = luaL_checkinteger(L, 1); + // MOD_CHECK_ID( uart, id ); + for (s = 2; s <= total; s++) { - luaL_checktype( L, s, LUA_TSTRING ); - buf = lua_tolstring( L, s, &len ); - printf("data to write: %s\n", buf); - platform_uart_send( id, buf, len ); + if (lua_type(L, s) == LUA_TNUMBER) + { + len = lua_tointeger(L, s); + if (len > 255) + return luaL_error(L, "invalid number"); + platform_uart_send(id, &len, 1); + } + else + { + luaL_checktype(L, s, LUA_TSTRING); + buf = lua_tolstring(L, s, &len); + printf("data to write: %s\n", buf); + platform_uart_send(id, buf, len); + } } - } - return 0; + return 0; } // Lua: uart.uninstall( uart_num ) static int uart_uninstall(lua_State *L) { - int num; - num = luaL_checkinteger( L, 1 ); - if (num < 0 || num >2) { - return luaL_error( L, "invalid argument" ); - } - platform_uart_uninstall(num); - return 0; + int num; + num = luaL_checkinteger(L, 1); + if (num < 0 || num > 2) + { + return luaL_error(L, "invalid argument"); + } + platform_uart_uninstall(num); + return 0; } // Module function map -const LUA_REG_TYPE uart_map[] = { - { LSTRKEY( "setup" ), LFUNCVAL( uart_setup ) }, - { LSTRKEY( "write" ), LFUNCVAL( uart_write ) }, - { LSTRKEY( "on" ), LFUNCVAL( uart_on ) }, - //{ LSTRKEY( "alt" ), LFUNCVAL( uart_alt ) }, - { LSTRKEY( "uninstall" ), LFUNCVAL( uart_uninstall ) }, - { LSTRKEY( "UART_1" ), LNUMVAL( UART_NUM_1 ) }, - { LSTRKEY( "UART_2" ), LNUMVAL( UART_NUM_2 ) }, - { LSTRKEY( "DATA_5_BITS" ), LNUMVAL( UART_DATA_5_BITS ) }, - { LSTRKEY( "DATA_6_BITS" ), LNUMVAL( UART_DATA_6_BITS ) }, - { LSTRKEY( "DATA_7_BITS" ), LNUMVAL( UART_DATA_7_BITS ) }, - { LSTRKEY( "DATA_8_BITS" ), LNUMVAL( UART_DATA_8_BITS ) }, - { LSTRKEY( "FLOWCTRL_DISABLE" ), LNUMVAL( UART_HW_FLOWCTRL_DISABLE ) }, - { LSTRKEY( "FLOWCTRL_RTS" ), LNUMVAL( UART_HW_FLOWCTRL_RTS ) }, - { LSTRKEY( "FLOWCTRL_CTS" ), LNUMVAL( UART_HW_FLOWCTRL_CTS ) }, - { LSTRKEY( "FLOWCTRL_CTS_RTS" ), LNUMVAL( UART_HW_FLOWCTRL_CTS_RTS ) }, - { LSTRKEY( "STOPBITS_1" ), LNUMVAL( UART_STOP_BITS_1 ) }, - { LSTRKEY( "STOPBITS_1_5" ), LNUMVAL( UART_STOP_BITS_1_5 ) }, - { LSTRKEY( "STOPBITS_2" ), LNUMVAL( UART_STOP_BITS_2 ) }, - { LSTRKEY( "PARITY_NONE" ), LNUMVAL( UART_PARITY_DISABLE ) }, - { LSTRKEY( "PARITY_EVEN" ), LNUMVAL( UART_PARITY_EVEN ) }, - { LSTRKEY( "PARITY_ODD" ), LNUMVAL( UART_PARITY_ODD ) }, - { LNILKEY, LNILVAL } -}; +const LUA_REG_TYPE uart_map[] = {{LSTRKEY("setup"), LFUNCVAL(uart_setup)}, + {LSTRKEY("write"), LFUNCVAL(uart_write)}, + {LSTRKEY("on"), LFUNCVAL(uart_on)}, + //{ LSTRKEY( "alt" ), LFUNCVAL( uart_alt ) }, + {LSTRKEY("uninstall"), LFUNCVAL(uart_uninstall)}, + {LSTRKEY("UART_1"), LNUMVAL(UART_NUM_1)}, + {LSTRKEY("UART_2"), LNUMVAL(UART_NUM_2)}, + {LSTRKEY("DATA_5_BITS"), LNUMVAL(UART_DATA_5_BITS)}, + {LSTRKEY("DATA_6_BITS"), LNUMVAL(UART_DATA_6_BITS)}, + {LSTRKEY("DATA_7_BITS"), LNUMVAL(UART_DATA_7_BITS)}, + {LSTRKEY("DATA_8_BITS"), LNUMVAL(UART_DATA_8_BITS)}, + {LSTRKEY("FLOWCTRL_DISABLE"), LNUMVAL(UART_HW_FLOWCTRL_DISABLE)}, + {LSTRKEY("FLOWCTRL_RTS"), LNUMVAL(UART_HW_FLOWCTRL_RTS)}, + {LSTRKEY("FLOWCTRL_CTS"), LNUMVAL(UART_HW_FLOWCTRL_CTS)}, + {LSTRKEY("FLOWCTRL_CTS_RTS"), LNUMVAL(UART_HW_FLOWCTRL_CTS_RTS)}, + {LSTRKEY("STOPBITS_1"), LNUMVAL(UART_STOP_BITS_1)}, + {LSTRKEY("STOPBITS_1_5"), LNUMVAL(UART_STOP_BITS_1_5)}, + {LSTRKEY("STOPBITS_2"), LNUMVAL(UART_STOP_BITS_2)}, + {LSTRKEY("PARITY_NONE"), LNUMVAL(UART_PARITY_DISABLE)}, + {LSTRKEY("PARITY_EVEN"), LNUMVAL(UART_PARITY_EVEN)}, + {LSTRKEY("PARITY_ODD"), LNUMVAL(UART_PARITY_ODD)}, + {LNILKEY, LNILVAL}}; LUALIB_API int luaopen_uart(lua_State *L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_UARTLIBNAME, uart_map ); - return 1; +#else + luaL_register(L, LUA_UARTLIBNAME, uart_map); + return 1; #endif } - diff --git a/LuaNode_Esp32/LuaNode32/components/modules/utils.c b/LuaNode_Esp32/LuaNode32/components/modules/utils.c index 49aee27..bc1bd2b 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/utils.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/utils.c @@ -1,10 +1,11 @@ // libutils.a #include -#include "modules.h" -#include "lauxlib.h" -#include "c_string.h" + #include "base64.h" +#include "c_string.h" #include "datetime.h" +#include "lauxlib.h" +#include "modules.h" //#include "md5.h" #include "lualib.h" @@ -16,81 +17,83 @@ */ void HexToStr(unsigned char *pbDest, unsigned char *pbSrc, int nLen) { - char ddl,ddh; + char ddl, ddh; int i; - for (i=0; i 57) ddh = ddh + 7; - if (ddl > 57) ddl = ddl + 7; - pbDest[i*2] = ddh; - pbDest[i*2+1] = ddl; + if (ddh > 57) + ddh = ddh + 7; + if (ddl > 57) + ddl = ddl + 7; + pbDest[i * 2] = ddh; + pbDest[i * 2 + 1] = ddl; } - pbDest[nLen*2] = '\0'; + pbDest[nLen * 2] = '\0'; } // return the lenght of encoding string -static int base64_encode0( lua_State* L ) { - int argc = lua_gettop(L); - const char *str = lua_tostring(L, 1); - char *buff = malloc(strlen(str) * 2); - memset(buff, 0, strlen(str)*2); - int num = base64_encode(str, strlen(str), buff, 1); - lua_pushstring(L, buff); - return 1; +static int base64_encode0(lua_State *L) +{ + int argc = lua_gettop(L); + const char *str = lua_tostring(L, 1); + char *buff = malloc(strlen(str) * 2); + memset(buff, 0, strlen(str) * 2); + int num = base64_encode(str, strlen(str), buff, 1); + lua_pushstring(L, buff); + return 1; } // return the length of decoding string -static int base64_decode0( lua_State* L ) { - int argc = lua_gettop(L); - const char *str = lua_tostring(L, 1); - char *buff = malloc(strlen(str) * 2); - memset(buff, 0, strlen(str)*2); - int num = base64_decode(str, buff); - lua_pushstring(L, buff); - return 1; +static int base64_decode0(lua_State *L) +{ + int argc = lua_gettop(L); + const char *str = lua_tostring(L, 1); + char *buff = malloc(strlen(str) * 2); + memset(buff, 0, strlen(str) * 2); + int num = base64_decode(str, buff); + lua_pushstring(L, buff); + return 1; } -static int leapyear0( lua_State* L ) { - int year = lua_tointeger(L, 1); - int isLeap = isLeapyear(year); - lua_pushboolean(L, isLeap); - return 1; +static int leapyear0(lua_State *L) +{ + int year = lua_tointeger(L, 1); + int isLeap = isLeapyear(year); + lua_pushboolean(L, isLeap); + return 1; } // md5 encode, return the encoding string /*static int md5_encode( lua_State* L ) { - unsigned char *str = (unsigned char *)lua_tostring(L, 1); // string to be encoded - char digest[16]; - char ecrypt[32]; - memset(digest, 0, 16); - memset(ecrypt, 0, 32); - MD5_CTX md5; + unsigned char *str = (unsigned char *)lua_tostring(L, 1); // +string to be encoded char digest[16]; char ecrypt[32]; memset(digest, 0, 16); + memset(ecrypt, 0, 32); + MD5_CTX md5; MD5Init(&md5); - MD5Update(&md5, str, strlen(str)); + MD5Update(&md5, str, strlen(str)); MD5Final(&md5, digest); - HexToStr(ecrypt, digest, strlen(digest)); - lua_pushstring(L, ecrypt); - return 1; + HexToStr(ecrypt, digest, strlen(digest)); + lua_pushstring(L, ecrypt); + return 1; }*/ // Module function map -const LUA_REG_TYPE utils_map[] = { - { LSTRKEY( "base64_encode" ), LFUNCVAL( base64_encode0 ) }, - { LSTRKEY( "base64_decode" ), LFUNCVAL( base64_decode0 ) }, - //{ LSTRKEY( "md5_encode" ), LFUNCVAL( md5_encode ) }, - { LSTRKEY( "leapyear" ), LFUNCVAL( leapyear0 ) }, - { LNILKEY, LNILVAL } -}; +const LUA_REG_TYPE utils_map[] = {{LSTRKEY("base64_encode"), LFUNCVAL(base64_encode0)}, + {LSTRKEY("base64_decode"), LFUNCVAL(base64_decode0)}, + //{ LSTRKEY( "md5_encode" ), LFUNCVAL( md5_encode ) }, + {LSTRKEY("leapyear"), LFUNCVAL(leapyear0)}, + {LNILKEY, LNILVAL}}; LUALIB_API int luaopen_utils(lua_State *L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_UTILSLIBNAME, utils_map ); - return 1; +#else + luaL_register(L, LUA_UTILSLIBNAME, utils_map); + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/modules/wifi.c b/LuaNode_Esp32/LuaNode32/components/modules/wifi.c index b7de8b4..b38ddac 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/wifi.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/wifi.c @@ -1,591 +1,554 @@ // Module for interfacing with WIFI -#include "modules.h" -#include "lauxlib.h" -#include "platform.h" -#include "lualib.h" -#include "lua.h" -#include "lrodefs.h" -#include "lrotable.h" - -#include "c_string.h" #include "c_stdlib.h" - +#include "c_string.h" #include "c_types.h" -#include "user_interface.h" -#include "user_config.h" -#include "esp_sta.h" +#include "esp_misc.h" #include "esp_phy.h" -#include "esp_timer.h" #include "esp_softap.h" -#include "esp_misc.h" +#include "esp_sta.h" +#include "esp_timer.h" +#include "lauxlib.h" +#include "lrodefs.h" +#include "lrotable.h" +#include "lua.h" +#include "lualib.h" +#include "modules.h" #include "nodemcu_esp_event.h" +#include "platform.h" +#include "user_config.h" +#include "user_interface.h" //#include "smart.h" //#include "smartconfig.h" #include "c_stdio.h" #include "ip_fmt.h" -typedef void (*fill_cb_arg_fn) (lua_State *L, const system_event_t *evt); +typedef void (*fill_cb_arg_fn)(lua_State *L, const system_event_t *evt); typedef struct { - const char *name; - system_event_id_t event_id; - fill_cb_arg_fn fill_cb_arg; + const char *name; + system_event_id_t event_id; + fill_cb_arg_fn fill_cb_arg; } event_desc_t; - -typedef enum _sta_status { - STA_IDLE = 0, - STA_CONNECTING, - STA_WRONGPWD, - STA_APNOTFOUND, - STA_FAIL, - STA_GOTIP +typedef enum _sta_status +{ + STA_IDLE = 0, + STA_CONNECTING, + STA_WRONGPWD, + STA_APNOTFOUND, + STA_FAIL, + STA_GOTIP } STA_STATUS; -typedef enum _phy_mode { - PHYMODE_B = 0, - PHYMODE_G, - PHYMODE_N +typedef enum _phy_mode +{ + PHYMODE_B = 0, + PHYMODE_G, + PHYMODE_N } PHY_MODE; -#define NULL_MODE 0x00 -#define STATION_MODE 0x01 -#define SOFTAP_MODE 0x02 -#define STATIONAP_MODE 0x03 +#define NULL_MODE 0x00 +#define STATION_MODE 0x01 +#define SOFTAP_MODE 0x02 +#define STATIONAP_MODE 0x03 -#define STATION_IF 0x00 -#define SOFTAP_IF 0x01 +#define STATION_IF 0x00 +#define SOFTAP_IF 0x01 #define DEFAULT_AP_CHANNEL 11 #define DEFAULT_AP_MAXCONNS 4 #define DEFAULT_AP_BEACON 100 static int wifi_smart_succeed = LUA_NOREF; -static uint8 getap_output_format=0; +static uint8 getap_output_format = 0; -//wifi.sleep variables +// wifi.sleep variables #define FPM_SLEEP_MAX_TIME 0xFFFFFFF -static bool FLAG_wifi_force_sleep_enabled=0; +static bool FLAG_wifi_force_sleep_enabled = 0; - -//variables for wifi event monitor -static sint32_t wifi_status_cb_ref[6] = {LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF,LUA_NOREF}; -//static os_timer_t wifi_sta_status_timer; -static uint8 prev_wifi_status=0; +// variables for wifi event monitor +static sint32_t wifi_status_cb_ref[6] = {LUA_NOREF, LUA_NOREF, LUA_NOREF, LUA_NOREF, LUA_NOREF, LUA_NOREF}; +// static os_timer_t wifi_sta_status_timer; +static uint8 prev_wifi_status = 0; // Forward declarations -static void on_event (const system_event_t *evt); - -static void sta_conn (lua_State *L, const system_event_t *evt); -static void sta_disconn (lua_State *L, const system_event_t *evt); -static void sta_authmode (lua_State *L, const system_event_t *evt); -static void sta_got_ip (lua_State *L, const system_event_t *evt); -static void ap_staconn (lua_State *L, const system_event_t *evt); -static void ap_stadisconn (lua_State *L, const system_event_t *evt); -static void ap_probe_req (lua_State *L, const system_event_t *evt); - -static void empty_arg (lua_State *L, const system_event_t *evt) {} - -static const event_desc_t events[] = -{ - { "sta_start", SYSTEM_EVENT_STA_START, empty_arg }, - { "sta_stop", SYSTEM_EVENT_STA_STOP, empty_arg }, - { "sta_connected", SYSTEM_EVENT_STA_CONNECTED, sta_conn }, - { "sta_disconnected", SYSTEM_EVENT_STA_DISCONNECTED, sta_disconn }, - { "sta_authmode_changed", SYSTEM_EVENT_STA_AUTHMODE_CHANGE, sta_authmode }, - { "sta_got_ip", SYSTEM_EVENT_STA_GOT_IP, sta_got_ip }, - - { "ap_start", SYSTEM_EVENT_AP_START, empty_arg }, - { "ap_stop", SYSTEM_EVENT_AP_STOP, empty_arg }, - { "ap_sta_connected", SYSTEM_EVENT_AP_STACONNECTED, ap_staconn }, - { "ap_sta_disconnected", SYSTEM_EVENT_AP_STADISCONNECTED, ap_stadisconn }, - { "ap_probe_req", SYSTEM_EVENT_AP_PROBEREQRECVED, ap_probe_req } -}; +static void on_event(const system_event_t *evt); + +static void sta_conn(lua_State *L, const system_event_t *evt); +static void sta_disconn(lua_State *L, const system_event_t *evt); +static void sta_authmode(lua_State *L, const system_event_t *evt); +static void sta_got_ip(lua_State *L, const system_event_t *evt); +static void ap_staconn(lua_State *L, const system_event_t *evt); +static void ap_stadisconn(lua_State *L, const system_event_t *evt); +static void ap_probe_req(lua_State *L, const system_event_t *evt); + +static void empty_arg(lua_State *L, const system_event_t *evt) {} + +static const event_desc_t events[] = {{"sta_start", SYSTEM_EVENT_STA_START, empty_arg}, + {"sta_stop", SYSTEM_EVENT_STA_STOP, empty_arg}, + {"sta_connected", SYSTEM_EVENT_STA_CONNECTED, sta_conn}, + {"sta_disconnected", SYSTEM_EVENT_STA_DISCONNECTED, sta_disconn}, + {"sta_authmode_changed", SYSTEM_EVENT_STA_AUTHMODE_CHANGE, sta_authmode}, + {"sta_got_ip", SYSTEM_EVENT_STA_GOT_IP, sta_got_ip}, + + {"ap_start", SYSTEM_EVENT_AP_START, empty_arg}, + {"ap_stop", SYSTEM_EVENT_AP_STOP, empty_arg}, + {"ap_sta_connected", SYSTEM_EVENT_AP_STACONNECTED, ap_staconn}, + {"ap_sta_disconnected", SYSTEM_EVENT_AP_STADISCONNECTED, ap_stadisconn}, + {"ap_probe_req", SYSTEM_EVENT_AP_PROBEREQRECVED, ap_probe_req}}; #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) static int event_cb[ARRAY_LEN(events)]; nodemcu_esp_event_reg_t esp_event_cb_table[] = { - {SYSTEM_EVENT_STA_START, on_event}, - {SYSTEM_EVENT_STA_STOP, on_event}, - {SYSTEM_EVENT_STA_CONNECTED, on_event}, - {SYSTEM_EVENT_STA_DISCONNECTED, on_event}, - {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, on_event}, - {SYSTEM_EVENT_STA_GOT_IP, on_event}, - - {SYSTEM_EVENT_AP_START, on_event}, - {SYSTEM_EVENT_AP_STOP, on_event}, - {SYSTEM_EVENT_AP_STACONNECTED, on_event}, - {SYSTEM_EVENT_AP_STADISCONNECTED, on_event}, - {SYSTEM_EVENT_AP_PROBEREQRECVED, on_event}, + {SYSTEM_EVENT_STA_START, on_event}, + {SYSTEM_EVENT_STA_STOP, on_event}, + {SYSTEM_EVENT_STA_CONNECTED, on_event}, + {SYSTEM_EVENT_STA_DISCONNECTED, on_event}, + {SYSTEM_EVENT_STA_AUTHMODE_CHANGE, on_event}, + {SYSTEM_EVENT_STA_GOT_IP, on_event}, + + {SYSTEM_EVENT_AP_START, on_event}, + {SYSTEM_EVENT_AP_STOP, on_event}, + {SYSTEM_EVENT_AP_STACONNECTED, on_event}, + {SYSTEM_EVENT_AP_STADISCONNECTED, on_event}, + {SYSTEM_EVENT_AP_PROBEREQRECVED, on_event}, }; +#define SET_SAVE_MODE(save) \ + do \ + { \ + esp_err_t storage_err = esp_wifi_set_storage(save ? WIFI_STORAGE_FLASH : WIFI_STORAGE_RAM); \ + if (storage_err != ESP_OK) \ + return luaL_error(L, "failed to update wifi storage, code %d", storage_err); \ + } while (0) -#define SET_SAVE_MODE(save) \ - do { esp_err_t storage_err = \ - esp_wifi_set_storage (save ? WIFI_STORAGE_FLASH : WIFI_STORAGE_RAM); \ - if (storage_err != ESP_OK) \ - return luaL_error (L, "failed to update wifi storage, code %d", \ - storage_err); \ - } while(0) - - -bool luaL_optbool (lua_State *L, int idx, bool def) +bool luaL_optbool(lua_State *L, int idx, bool def) { - if (lua_isboolean (L, idx)) - return lua_toboolean (L, idx); - else - return def; + if (lua_isboolean(L, idx)) + return lua_toboolean(L, idx); + else + return def; } - -static lua_State* gL = NULL; +static lua_State *gL = NULL; static int scan_cb_ref = LUA_NOREF; // Lua: realmode = getmode() -static int wifi_getmode( lua_State* L ) +static int wifi_getmode(lua_State *L) { - wifi_mode_t mode; - esp_err_t err = esp_wifi_get_mode (&mode); - if (err != ESP_OK) - return luaL_error (L, "failed to get mode, code %d", err); - lua_pushinteger (L, mode); - return 1; + wifi_mode_t mode; + esp_err_t err = esp_wifi_get_mode(&mode); + if (err != ESP_OK) + return luaL_error(L, "failed to get mode, code %d", err); + lua_pushinteger(L, mode); + return 1; } -static int event_idx_by_name (const char *name) +static int event_idx_by_name(const char *name) { - for (unsigned i = 0; i < ARRAY_LEN(events); ++i) - if (strcmp (events[i].name, name) == 0) - return i; - return -1; + for (unsigned i = 0; i < ARRAY_LEN(events); ++i) + if (strcmp(events[i].name, name) == 0) + return i; + return -1; } - -static int event_idx_by_id (system_event_id_t id) +static int event_idx_by_id(system_event_id_t id) { - for (unsigned i = 0; i < ARRAY_LEN(events); ++i) - if (events[i].event_id == id) - return i; - return -1; + for (unsigned i = 0; i < ARRAY_LEN(events); ++i) + if (events[i].event_id == id) + return i; + return -1; } - -static void sta_conn (lua_State *L, const system_event_t *evt) +static void sta_conn(lua_State *L, const system_event_t *evt) { - lua_pushlstring (L, - (const char *)evt->event_info.connected.ssid, - evt->event_info.connected.ssid_len); - lua_setfield (L, -2, "ssid"); + lua_pushlstring(L, (const char *)evt->event_info.connected.ssid, evt->event_info.connected.ssid_len); + lua_setfield(L, -2, "ssid"); - char bssid_str[MAC_STR_SZ]; - macstr (bssid_str, evt->event_info.connected.bssid); - lua_pushstring (L, bssid_str); - lua_setfield (L, -2, "bssid"); + char bssid_str[MAC_STR_SZ]; + macstr(bssid_str, evt->event_info.connected.bssid); + lua_pushstring(L, bssid_str); + lua_setfield(L, -2, "bssid"); - lua_pushinteger (L, evt->event_info.connected.channel); - lua_setfield (L, -2, "channel"); + lua_pushinteger(L, evt->event_info.connected.channel); + lua_setfield(L, -2, "channel"); - lua_pushinteger (L, evt->event_info.connected.authmode); - lua_setfield (L, -2, "auth"); + lua_pushinteger(L, evt->event_info.connected.authmode); + lua_setfield(L, -2, "auth"); } -static void sta_disconn (lua_State *L, const system_event_t *evt) +static void sta_disconn(lua_State *L, const system_event_t *evt) { - lua_pushlstring (L, - (const char *)evt->event_info.disconnected.ssid, - evt->event_info.disconnected.ssid_len); - lua_setfield (L, -2, "ssid"); - - char bssid_str[MAC_STR_SZ]; - macstr (bssid_str, evt->event_info.disconnected.bssid); - lua_pushstring (L, bssid_str); - lua_setfield (L, -2, "bssid"); - - lua_pushinteger (L, evt->event_info.disconnected.reason); - lua_setfield (L, -2, "reason"); + lua_pushlstring(L, (const char *)evt->event_info.disconnected.ssid, evt->event_info.disconnected.ssid_len); + lua_setfield(L, -2, "ssid"); + + char bssid_str[MAC_STR_SZ]; + macstr(bssid_str, evt->event_info.disconnected.bssid); + lua_pushstring(L, bssid_str); + lua_setfield(L, -2, "bssid"); + + lua_pushinteger(L, evt->event_info.disconnected.reason); + lua_setfield(L, -2, "reason"); } -static void sta_authmode (lua_State *L, const system_event_t *evt) +static void sta_authmode(lua_State *L, const system_event_t *evt) { - lua_pushinteger (L, evt->event_info.auth_change.old_mode); - lua_setfield (L, -2, "old_mode"); - lua_pushinteger (L, evt->event_info.auth_change.new_mode); - lua_setfield (L, -2, "new_mode"); + lua_pushinteger(L, evt->event_info.auth_change.old_mode); + lua_setfield(L, -2, "old_mode"); + lua_pushinteger(L, evt->event_info.auth_change.new_mode); + lua_setfield(L, -2, "new_mode"); } -static void sta_got_ip (lua_State *L, const system_event_t *evt) +static void sta_got_ip(lua_State *L, const system_event_t *evt) { - char ipstr[IP_STR_SZ] = { 0 }; - ip4str (ipstr, &evt->event_info.got_ip.ip_info.ip); - lua_pushstring (L, ipstr); - lua_setfield (L, -2, "ip"); - - ip4str (ipstr, &evt->event_info.got_ip.ip_info.netmask); - lua_pushstring (L, ipstr); - lua_setfield (L, -2, "netmask"); - - ip4str (ipstr, &evt->event_info.got_ip.ip_info.gw); - lua_pushstring (L, ipstr); - lua_setfield (L, -2, "gw"); + char ipstr[IP_STR_SZ] = {0}; + ip4str(ipstr, &evt->event_info.got_ip.ip_info.ip); + lua_pushstring(L, ipstr); + lua_setfield(L, -2, "ip"); + + ip4str(ipstr, &evt->event_info.got_ip.ip_info.netmask); + lua_pushstring(L, ipstr); + lua_setfield(L, -2, "netmask"); + + ip4str(ipstr, &evt->event_info.got_ip.ip_info.gw); + lua_pushstring(L, ipstr); + lua_setfield(L, -2, "gw"); } -static void ap_staconn (lua_State *L, const system_event_t *evt) +static void ap_staconn(lua_State *L, const system_event_t *evt) { - char mac[MAC_STR_SZ]; - macstr (mac, evt->event_info.sta_connected.mac); - lua_pushstring (L, mac); - lua_setfield (L, -2, "mac"); + char mac[MAC_STR_SZ]; + macstr(mac, evt->event_info.sta_connected.mac); + lua_pushstring(L, mac); + lua_setfield(L, -2, "mac"); - lua_pushinteger (L, evt->event_info.sta_connected.aid); - lua_setfield (L, -2, "id"); + lua_pushinteger(L, evt->event_info.sta_connected.aid); + lua_setfield(L, -2, "id"); } -static void ap_stadisconn (lua_State *L, const system_event_t *evt) +static void ap_stadisconn(lua_State *L, const system_event_t *evt) { - char mac[MAC_STR_SZ]; - macstr (mac, evt->event_info.sta_disconnected.mac); - lua_pushstring (L, mac); - lua_setfield (L, -2, "mac"); + char mac[MAC_STR_SZ]; + macstr(mac, evt->event_info.sta_disconnected.mac); + lua_pushstring(L, mac); + lua_setfield(L, -2, "mac"); - lua_pushinteger (L, evt->event_info.sta_disconnected.aid); - lua_setfield (L, -2, "id"); + lua_pushinteger(L, evt->event_info.sta_disconnected.aid); + lua_setfield(L, -2, "id"); } -static void ap_probe_req (lua_State *L, const system_event_t *evt) +static void ap_probe_req(lua_State *L, const system_event_t *evt) { - char str[MAC_STR_SZ]; - macstr (str, evt->event_info.ap_probereqrecved.mac); - lua_pushstring (L, str); - lua_setfield (L, -2, "from"); + char str[MAC_STR_SZ]; + macstr(str, evt->event_info.ap_probereqrecved.mac); + lua_pushstring(L, str); + lua_setfield(L, -2, "from"); - lua_pushinteger (L, evt->event_info.ap_probereqrecved.rssi); - lua_setfield (L, -2, "rssi"); + lua_pushinteger(L, evt->event_info.ap_probereqrecved.rssi); + lua_setfield(L, -2, "rssi"); } -static void on_event (const system_event_t *evt) +static void on_event(const system_event_t *evt) { - int idx = event_idx_by_id (evt->event_id); - if (idx < 0 || event_cb[idx] == LUA_NOREF) - return; - - lua_State *L = lua_getstate (); - lua_rawgeti (L, LUA_REGISTRYINDEX, event_cb[idx]); - lua_pushstring (L, events[idx].name); - lua_createtable (L, 0, 5); - events[idx].fill_cb_arg (L, evt); - lua_call (L, 2, 0); + int idx = event_idx_by_id(evt->event_id); + if (idx < 0 || event_cb[idx] == LUA_NOREF) + return; + + lua_State *L = lua_getstate(); + lua_rawgeti(L, LUA_REGISTRYINDEX, event_cb[idx]); + lua_pushstring(L, events[idx].name); + lua_createtable(L, 0, 5); + events[idx].fill_cb_arg(L, evt); + lua_call(L, 2, 0); } - -static int wifi_eventmon (lua_State *L) +static int wifi_eventmon(lua_State *L) { - const char *event_name = luaL_checkstring (L, 1); - if (!lua_isnoneornil (L, 2)) - luaL_checkanyfunction (L, 2); - lua_settop (L, 2); + const char *event_name = luaL_checkstring(L, 1); + if (!lua_isnoneornil(L, 2)) + luaL_checkanyfunction(L, 2); + lua_settop(L, 2); - int idx = event_idx_by_name (event_name); - if (idx < 0) - return luaL_error (L, "unknown event: %s", event_name); + int idx = event_idx_by_name(event_name); + if (idx < 0) + return luaL_error(L, "unknown event: %s", event_name); - luaL_unref (L, LUA_REGISTRYINDEX, event_cb[idx]); - event_cb[idx] = lua_isnoneornil (L, 2) ? - LUA_NOREF : luaL_ref (L, LUA_REGISTRYINDEX); + luaL_unref(L, LUA_REGISTRYINDEX, event_cb[idx]); + event_cb[idx] = lua_isnoneornil(L, 2) ? LUA_NOREF : luaL_ref(L, LUA_REGISTRYINDEX); - return 0; + return 0; } -static int wifi_setmode (lua_State *L) +static int wifi_setmode(lua_State *L) { - int mode = luaL_checkinteger (L, 1); - wifi_mode_t tmp_mode; - esp_err_t err = esp_wifi_get_mode (&tmp_mode); - if (err == ESP_OK) { - if (tmp_mode == mode) { return 0; } - } - bool save = luaL_optbool (L, 2, false); - SET_SAVE_MODE(save); - switch (mode) - { - case WIFI_MODE_NULL: - case WIFI_MODE_STA: - case WIFI_MODE_AP: - case WIFI_MODE_APSTA: - return ((err = esp_wifi_set_mode (mode)) == ESP_OK) ? - 0 : luaL_error (L, "failed to set mode, code %d", err); - default: - return luaL_error (L, "invalid wifi mode %d", mode); - } + int mode = luaL_checkinteger(L, 1); + wifi_mode_t tmp_mode; + esp_err_t err = esp_wifi_get_mode(&tmp_mode); + if (err == ESP_OK) + { + if (tmp_mode == mode) + { + return 0; + } + } + bool save = luaL_optbool(L, 2, false); + SET_SAVE_MODE(save); + switch (mode) + { + case WIFI_MODE_NULL: + case WIFI_MODE_STA: + case WIFI_MODE_AP: + case WIFI_MODE_APSTA: + return ((err = esp_wifi_set_mode(mode)) == ESP_OK) ? 0 : luaL_error(L, "failed to set mode, code %d", err); + default: + return luaL_error(L, "invalid wifi mode %d", mode); + } } -static int wifi_start (lua_State *L) +static int wifi_start(lua_State *L) { - esp_err_t err = esp_wifi_start (); - return (err == ESP_OK) ? - 0 : luaL_error(L, "failed to start wifi, code %d", err); + esp_err_t err = esp_wifi_start(); + return (err == ESP_OK) ? 0 : luaL_error(L, "failed to start wifi, code %d", err); } -static int wifi_stop (lua_State *L) +static int wifi_stop(lua_State *L) { - esp_err_t err = esp_wifi_stop (); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to stop wifi, code %d", err); + esp_err_t err = esp_wifi_stop(); + return (err == ESP_OK) ? 0 : luaL_error(L, "failed to stop wifi, code %d", err); } - -static int wifi_sta_config (lua_State *L) +static int wifi_sta_config(lua_State *L) { - luaL_checkanytable (L, 1); - bool save = luaL_optbool (L, 2, false); - lua_settop (L, 1); - - wifi_config_t cfg; - memset (&cfg, 0, sizeof (cfg)); - - lua_getfield (L, 1, "ssid"); - size_t len; - const char *str = luaL_checklstring (L, -1, &len); - if (len > sizeof (cfg.sta.ssid)) - len = sizeof (cfg.sta.ssid); - strncpy (cfg.sta.ssid, str, len); - - lua_getfield (L, 1, "pwd"); - str = luaL_optlstring (L, -1, "", &len); - if (len > sizeof (cfg.sta.password)) - len = sizeof (cfg.sta.password); - strncpy (cfg.sta.password, str, len); - - lua_getfield (L, 1, "bssid"); - cfg.sta.bssid_set = false; - if (lua_isstring (L, -1)) - { - const char *bssid = luaL_checklstring (L, -1, &len); - const char *fmts[] = { - "%hhx%hhx%hhx%hhx%hhx%hhx", - "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", - "%hhx %hhx %hhx %hhx %hhx %hhx", - NULL - }; - for (unsigned i = 0; fmts[i]; ++i) + luaL_checkanytable(L, 1); + bool save = luaL_optbool(L, 2, false); + lua_settop(L, 1); + + wifi_config_t cfg; + memset(&cfg, 0, sizeof(cfg)); + + lua_getfield(L, 1, "ssid"); + size_t len; + const char *str = luaL_checklstring(L, -1, &len); + if (len > sizeof(cfg.sta.ssid)) + len = sizeof(cfg.sta.ssid); + strncpy(cfg.sta.ssid, str, len); + + lua_getfield(L, 1, "pwd"); + str = luaL_optlstring(L, -1, "", &len); + if (len > sizeof(cfg.sta.password)) + len = sizeof(cfg.sta.password); + strncpy(cfg.sta.password, str, len); + + lua_getfield(L, 1, "bssid"); + cfg.sta.bssid_set = false; + if (lua_isstring(L, -1)) { - if (sscanf (bssid, fmts[i], - &cfg.sta.bssid[0], &cfg.sta.bssid[1], &cfg.sta.bssid[2], - &cfg.sta.bssid[3], &cfg.sta.bssid[4], &cfg.sta.bssid[5]) == 6) - { - cfg.sta.bssid_set = true; - break; - } + const char *bssid = luaL_checklstring(L, -1, &len); + const char *fmts[] = {"%hhx%hhx%hhx%hhx%hhx%hhx", "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", "%hhx %hhx %hhx %hhx %hhx %hhx", NULL}; + for (unsigned i = 0; fmts[i]; ++i) + { + if (sscanf(bssid, fmts[i], &cfg.sta.bssid[0], &cfg.sta.bssid[1], &cfg.sta.bssid[2], &cfg.sta.bssid[3], + &cfg.sta.bssid[4], &cfg.sta.bssid[5]) == 6) + { + cfg.sta.bssid_set = true; + break; + } + } + if (!cfg.sta.bssid_set) + return luaL_error(L, "invalid BSSID: %s", bssid); } - if (!cfg.sta.bssid_set) - return luaL_error (L, "invalid BSSID: %s", bssid); - } - - lua_getfield (L, 1, "auto"); - bool auto_conn = luaL_optbool (L, -1, true); - - SET_SAVE_MODE(save); - esp_err_t err = esp_wifi_set_config (WIFI_IF_STA, &cfg); - if (err != ESP_OK) - return luaL_error (L, "failed to set wifi config, code %d", err); - - if (auto_conn) - err = esp_wifi_connect (); - if (err != ESP_OK) - return luaL_error (L, "failed to begin connect, code %d", err); - - err = esp_wifi_set_auto_connect (auto_conn); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to set wifi auto-connect, code %d", err); + + lua_getfield(L, 1, "auto"); + bool auto_conn = luaL_optbool(L, -1, true); + + SET_SAVE_MODE(save); + esp_err_t err = esp_wifi_set_config(WIFI_IF_STA, &cfg); + if (err != ESP_OK) + return luaL_error(L, "failed to set wifi config, code %d", err); + + if (auto_conn) + err = esp_wifi_connect(); + if (err != ESP_OK) + return luaL_error(L, "failed to begin connect, code %d", err); + + err = esp_wifi_set_auto_connect(auto_conn); + return (err == ESP_OK) ? 0 : luaL_error(L, "failed to set wifi auto-connect, code %d", err); } -static int wifi_sta_connect (lua_State *L) +static int wifi_sta_connect(lua_State *L) { - esp_err_t err = esp_wifi_connect (); - return (err == ESP_OK) ? 0 : luaL_error (L, "connect failed, code %d", err); + esp_err_t err = esp_wifi_connect(); + return (err == ESP_OK) ? 0 : luaL_error(L, "connect failed, code %d", err); } - -static int wifi_sta_disconnect (lua_State *L) +static int wifi_sta_disconnect(lua_State *L) { - esp_err_t err = esp_wifi_disconnect (); - return (err == ESP_OK) ? 0 : luaL_error(L, "disconnect failed, code %d", err); + esp_err_t err = esp_wifi_disconnect(); + return (err == ESP_OK) ? 0 : luaL_error(L, "disconnect failed, code %d", err); } -static int wifi_sta_getconfig (lua_State *L) +static int wifi_sta_getconfig(lua_State *L) { - wifi_config_t cfg; - esp_err_t err = esp_wifi_get_config (WIFI_IF_STA, &cfg); - if (err != ESP_OK) - return luaL_error (L, "failed to get config, code %d", err); - - lua_createtable (L, 0, 3); - size_t ssid_len = strnlen (cfg.sta.ssid, sizeof (cfg.sta.ssid)); - lua_pushlstring (L, cfg.sta.ssid, ssid_len); - lua_setfield (L, -2, "ssid"); - - size_t pwd_len = strnlen (cfg.sta.password, sizeof (cfg.sta.password)); - lua_pushlstring (L, cfg.sta.password, pwd_len); - lua_setfield (L, -2, "pwd"); - - if (cfg.sta.bssid_set) - { - char bssid_str[MAC_STR_SZ]; - macstr (bssid_str, cfg.sta.bssid); - lua_pushstring (L, bssid_str); - lua_setfield (L, -2, "bssid"); - } + wifi_config_t cfg; + esp_err_t err = esp_wifi_get_config(WIFI_IF_STA, &cfg); + if (err != ESP_OK) + return luaL_error(L, "failed to get config, code %d", err); - bool auto_conn; - err = esp_wifi_get_auto_connect (&auto_conn); - if (err != ESP_OK) - return luaL_error (L, "failed to get auto-connect, code %d", err); + lua_createtable(L, 0, 3); + size_t ssid_len = strnlen(cfg.sta.ssid, sizeof(cfg.sta.ssid)); + lua_pushlstring(L, cfg.sta.ssid, ssid_len); + lua_setfield(L, -2, "ssid"); - lua_pushboolean (L, auto_conn); - lua_setfield (L, -2, "auto"); + size_t pwd_len = strnlen(cfg.sta.password, sizeof(cfg.sta.password)); + lua_pushlstring(L, cfg.sta.password, pwd_len); + lua_setfield(L, -2, "pwd"); - return 1; + if (cfg.sta.bssid_set) + { + char bssid_str[MAC_STR_SZ]; + macstr(bssid_str, cfg.sta.bssid); + lua_pushstring(L, bssid_str); + lua_setfield(L, -2, "bssid"); + } + + bool auto_conn; + err = esp_wifi_get_auto_connect(&auto_conn); + if (err != ESP_OK) + return luaL_error(L, "failed to get auto-connect, code %d", err); + + lua_pushboolean(L, auto_conn); + lua_setfield(L, -2, "auto"); + + return 1; } -static int wifi_sta_scan (lua_State *L) +static int wifi_sta_scan(lua_State *L) { - if (scan_cb_ref != LUA_NOREF) - return luaL_error (L, "scan already in progress"); + if (scan_cb_ref != LUA_NOREF) + return luaL_error(L, "scan already in progress"); - luaL_checkanytable (L, 1); + luaL_checkanytable(L, 1); - wifi_scan_config_t scan_cfg; - memset (&scan_cfg, 0, sizeof (scan_cfg)); + wifi_scan_config_t scan_cfg; + memset(&scan_cfg, 0, sizeof(scan_cfg)); - // TODO: support ssid/bssid/channel/hidden features of wifi_scan_config_t + // TODO: support ssid/bssid/channel/hidden features of wifi_scan_config_t - luaL_checkanyfunction (L, 2); - lua_settop (L, 2); - scan_cb_ref = luaL_ref (L, LUA_REGISTRYINDEX); + luaL_checkanyfunction(L, 2); + lua_settop(L, 2); + scan_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); - esp_err_t err = esp_wifi_scan_start (&scan_cfg, false); - if (err != ESP_OK) - { - luaL_unref (L, LUA_REGISTRYINDEX, scan_cb_ref); - scan_cb_ref = LUA_NOREF; - return luaL_error (L, "failed to start scan, code %d", err); - } - else - return 0; + esp_err_t err = esp_wifi_scan_start(&scan_cfg, false); + if (err != ESP_OK) + { + luaL_unref(L, LUA_REGISTRYINDEX, scan_cb_ref); + scan_cb_ref = LUA_NOREF; + return luaL_error(L, "failed to start scan, code %d", err); + } + else + return 0; } -static int wifi_ap_config (lua_State *L) +static int wifi_ap_config(lua_State *L) { - luaL_checkanytable (L, 1); - bool save = luaL_optbool (L, 2, false); - - wifi_config_t cfg; - memset (&cfg, 0, sizeof (cfg)); - - lua_getfield (L, 1, "ssid"); - size_t len; - const char *str = luaL_checklstring (L, -1, &len); - if (len > sizeof (cfg.ap.ssid)) - len = sizeof (cfg.ap.ssid); - strncpy (cfg.ap.ssid, str, len); - cfg.ap.ssid_len = len; - - lua_getfield (L, 1, "pwd"); - str = luaL_optlstring (L, -1, "", &len); - if (len > sizeof (cfg.ap.password)) - len = sizeof (cfg.ap.password); - strncpy (cfg.ap.password, str, len); - - lua_getfield (L, 1, "auth"); - int authmode = luaL_optint (L, -1, WIFI_AUTH_WPA2_PSK); - if (authmode < 0 || authmode >= WIFI_AUTH_MAX) - return luaL_error (L, "unknown auth mode %d", authmode); - cfg.ap.authmode = authmode; - - lua_getfield (L, 1, "channel"); - cfg.ap.channel = luaL_optint (L, -1, DEFAULT_AP_CHANNEL); - - lua_getfield (L, 1, "hidden"); - cfg.ap.ssid_hidden = luaL_optbool (L, -1, false); - - lua_getfield (L, 1, "max"); - cfg.ap.max_connection = luaL_optint (L, -1, DEFAULT_AP_MAXCONNS); - - lua_getfield (L, 1, "beacon"); - cfg.ap.beacon_interval = luaL_optint (L, -1, DEFAULT_AP_BEACON); - - SET_SAVE_MODE(save); - esp_err_t err = esp_wifi_set_config (WIFI_IF_AP, &cfg); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to set wifi config, code %d", err); + luaL_checkanytable(L, 1); + bool save = luaL_optbool(L, 2, false); + + wifi_config_t cfg; + memset(&cfg, 0, sizeof(cfg)); + + lua_getfield(L, 1, "ssid"); + size_t len; + const char *str = luaL_checklstring(L, -1, &len); + if (len > sizeof(cfg.ap.ssid)) + len = sizeof(cfg.ap.ssid); + strncpy(cfg.ap.ssid, str, len); + cfg.ap.ssid_len = len; + + lua_getfield(L, 1, "pwd"); + str = luaL_optlstring(L, -1, "", &len); + if (len > sizeof(cfg.ap.password)) + len = sizeof(cfg.ap.password); + strncpy(cfg.ap.password, str, len); + + lua_getfield(L, 1, "auth"); + int authmode = luaL_optint(L, -1, WIFI_AUTH_WPA2_PSK); + if (authmode < 0 || authmode >= WIFI_AUTH_MAX) + return luaL_error(L, "unknown auth mode %d", authmode); + cfg.ap.authmode = authmode; + + lua_getfield(L, 1, "channel"); + cfg.ap.channel = luaL_optint(L, -1, DEFAULT_AP_CHANNEL); + + lua_getfield(L, 1, "hidden"); + cfg.ap.ssid_hidden = luaL_optbool(L, -1, false); + + lua_getfield(L, 1, "max"); + cfg.ap.max_connection = luaL_optint(L, -1, DEFAULT_AP_MAXCONNS); + + lua_getfield(L, 1, "beacon"); + cfg.ap.beacon_interval = luaL_optint(L, -1, DEFAULT_AP_BEACON); + + SET_SAVE_MODE(save); + esp_err_t err = esp_wifi_set_config(WIFI_IF_AP, &cfg); + return (err == ESP_OK) ? 0 : luaL_error(L, "failed to set wifi config, code %d", err); } -static int wifi_init (lua_State *L) +static int wifi_init(lua_State *L) { - for (unsigned i = 0; i < ARRAY_LEN(event_cb); ++i) - event_cb[i] = LUA_NOREF; + for (unsigned i = 0; i < ARRAY_LEN(event_cb); ++i) event_cb[i] = LUA_NOREF; - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - esp_err_t err = esp_wifi_init (&cfg); - return (err == ESP_OK) ? - 0 : luaL_error (L, "failed to init wifi, code %d", err); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t err = esp_wifi_init(&cfg); + return (err == ESP_OK) ? 0 : luaL_error(L, "failed to init wifi, code %d", err); } +const LUA_REG_TYPE wifi_sta_map[] = {{LSTRKEY("config"), LFUNCVAL(wifi_sta_config)}, + {LSTRKEY("connect"), LFUNCVAL(wifi_sta_connect)}, + {LSTRKEY("disconnect"), LFUNCVAL(wifi_sta_disconnect)}, + {LSTRKEY("getconfig"), LFUNCVAL(wifi_sta_getconfig)}, + {LSTRKEY("scan"), LFUNCVAL(wifi_sta_scan)}, -const LUA_REG_TYPE wifi_sta_map[] = { - { LSTRKEY( "config" ), LFUNCVAL( wifi_sta_config ) }, - { LSTRKEY( "connect" ), LFUNCVAL( wifi_sta_connect ) }, - { LSTRKEY( "disconnect" ), LFUNCVAL( wifi_sta_disconnect ) }, - { LSTRKEY( "getconfig" ), LFUNCVAL( wifi_sta_getconfig ) }, - { LSTRKEY( "scan" ), LFUNCVAL( wifi_sta_scan ) }, + {LNILKEY, LNILVAL}}; - { LNILKEY, LNILVAL } -}; +const LUA_REG_TYPE wifi_ap_map[] = {{LSTRKEY("config"), LFUNCVAL(wifi_ap_config)}, -const LUA_REG_TYPE wifi_ap_map[] = { - { LSTRKEY( "config" ), LFUNCVAL( wifi_ap_config ) }, + {LSTRKEY("AUTH_OPEN"), LNUMVAL(WIFI_AUTH_OPEN)}, + {LSTRKEY("AUTH_WEP"), LNUMVAL(WIFI_AUTH_WEP)}, + {LSTRKEY("AUTH_WPA_PSK"), LNUMVAL(WIFI_AUTH_WPA_PSK)}, + {LSTRKEY("AUTH_WPA2_PSK"), LNUMVAL(WIFI_AUTH_WPA2_PSK)}, + {LSTRKEY("AUTH_WPA_WPA2_PSK"), LNUMVAL(WIFI_AUTH_WPA_WPA2_PSK)}, - { LSTRKEY( "AUTH_OPEN" ), LNUMVAL( WIFI_AUTH_OPEN ) }, - { LSTRKEY( "AUTH_WEP" ), LNUMVAL( WIFI_AUTH_WEP ) }, - { LSTRKEY( "AUTH_WPA_PSK" ), LNUMVAL( WIFI_AUTH_WPA_PSK ) }, - { LSTRKEY( "AUTH_WPA2_PSK" ), LNUMVAL( WIFI_AUTH_WPA2_PSK ) }, - { LSTRKEY( "AUTH_WPA_WPA2_PSK" ), LNUMVAL( WIFI_AUTH_WPA_WPA2_PSK ) }, - - { LNILKEY, LNILVAL } -}; + {LNILKEY, LNILVAL}}; +const LUA_REG_TYPE wifi_map[] = {{LSTRKEY("getmode"), LFUNCVAL(wifi_getmode)}, + {LSTRKEY("on"), LFUNCVAL(wifi_eventmon)}, + {LSTRKEY("setmode"), LFUNCVAL(wifi_setmode)}, + {LSTRKEY("start"), LFUNCVAL(wifi_start)}, + {LSTRKEY("stop"), LFUNCVAL(wifi_stop)}, -const LUA_REG_TYPE wifi_map[] = { - { LSTRKEY( "getmode" ), LFUNCVAL( wifi_getmode ) }, - { LSTRKEY( "on" ), LFUNCVAL( wifi_eventmon ) }, - { LSTRKEY( "setmode" ), LFUNCVAL( wifi_setmode ) }, - { LSTRKEY( "start" ), LFUNCVAL( wifi_start ) }, - { LSTRKEY( "stop" ), LFUNCVAL( wifi_stop ) }, + {LSTRKEY("sta"), LROVAL(wifi_sta_map)}, + {LSTRKEY("ap"), LROVAL(wifi_ap_map)}, - { LSTRKEY( "sta" ), LROVAL( wifi_sta_map ) }, - { LSTRKEY( "ap" ), LROVAL( wifi_ap_map ) }, - - - { LSTRKEY( "NULLMODE" ), LNUMVAL( WIFI_MODE_NULL ) }, - { LSTRKEY( "STATION" ), LNUMVAL( WIFI_MODE_STA ) }, - { LSTRKEY( "SOFTAP" ), LNUMVAL( WIFI_MODE_AP ) }, - { LSTRKEY( "STATIONAP" ), LNUMVAL( WIFI_MODE_APSTA ) }, - - { LNILKEY, LNILVAL } -}; + {LSTRKEY("NULLMODE"), LNUMVAL(WIFI_MODE_NULL)}, + {LSTRKEY("STATION"), LNUMVAL(WIFI_MODE_STA)}, + {LSTRKEY("SOFTAP"), LNUMVAL(WIFI_MODE_AP)}, + {LSTRKEY("STATIONAP"), LNUMVAL(WIFI_MODE_APSTA)}, + {LNILKEY, LNILVAL}}; LUALIB_API int luaopen_wifi(lua_State *L) { - //printf("wifi init\n"); - wifi_init(L); + // printf("wifi init\n"); + wifi_init(L); #if LUA_OPTIMIZE_MEMORY > 0 return 0; -#else - luaL_register( L, LUA_WIFILIBNAME, wifi_map ); - return 1; +#else + luaL_register(L, LUA_WIFILIBNAME, wifi_map); + return 1; #endif } diff --git a/LuaNode_Esp32/LuaNode32/components/mydriver/gpio.c b/LuaNode_Esp32/LuaNode32/components/mydriver/gpio.c index 9aa8d6d..19295b6 100644 --- a/LuaNode_Esp32/LuaNode32/components/mydriver/gpio.c +++ b/LuaNode_Esp32/LuaNode32/components/mydriver/gpio.c @@ -11,89 +11,94 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +#include "driver/gpio.h" + #include + #include "esp_err.h" #include "esp_intr.h" #include "freertos/FreeRTOS.h" #include "freertos/xtensa_api.h" -#include "driver/gpio.h" #include "soc/soc.h" -//TODO: move debug options to menuconfig -#define GPIO_DBG_ENABLE (0) +// TODO: move debug options to menuconfig +#define GPIO_DBG_ENABLE (0) #define GPIO_WARNING_ENABLE (0) -#define GPIO_ERROR_ENABLE (0) -#define GPIO_INFO_ENABLE (0) -//DBG INFOR +#define GPIO_ERROR_ENABLE (0) +#define GPIO_INFO_ENABLE (0) +// DBG INFOR #if GPIO_INFO_ENABLE #define GPIO_INFO ets_printf #else #define GPIO_INFO(...) #endif #if GPIO_WARNING_ENABLE -#define GPIO_WARNING(format,...) do{\ - ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else +#define GPIO_WARNING(format, ...) \ + do \ + { \ + ets_printf("[waring][%s#%u]", __FUNCTION__, __LINE__); \ + ets_printf(format, ##__VA_ARGS__); \ + } while (0) +#else #define GPIO_WARNING(...) #endif #if GPIO_ERROR_ENABLE -#define GPIO_ERROR(format,...) do{\ - ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\ - ets_printf(format,##__VA_ARGS__);\ -}while(0) -#else +#define GPIO_ERROR(format, ...) \ + do \ + { \ + ets_printf("[error][%s#%u]", __FUNCTION__, __LINE__); \ + ets_printf(format, ##__VA_ARGS__); \ + } while (0) +#else #define GPIO_ERROR(...) -#endif +#endif -const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = { - GPIO_PIN_REG_0, - GPIO_PIN_REG_1, - GPIO_PIN_REG_2, - GPIO_PIN_REG_3, - GPIO_PIN_REG_4, - GPIO_PIN_REG_5, - GPIO_PIN_REG_6, - GPIO_PIN_REG_7, - GPIO_PIN_REG_8, - GPIO_PIN_REG_9, - GPIO_PIN_REG_10, - GPIO_PIN_REG_11, - GPIO_PIN_REG_12, - GPIO_PIN_REG_13, - GPIO_PIN_REG_14, - GPIO_PIN_REG_15, - GPIO_PIN_REG_16, - GPIO_PIN_REG_17, - GPIO_PIN_REG_18, - GPIO_PIN_REG_19, - 0, - GPIO_PIN_REG_21, - GPIO_PIN_REG_22, - GPIO_PIN_REG_23, - 0, - GPIO_PIN_REG_25, - GPIO_PIN_REG_26, - GPIO_PIN_REG_27, - 0, - 0, - 0, - 0, - GPIO_PIN_REG_32, - GPIO_PIN_REG_33, - GPIO_PIN_REG_34, - GPIO_PIN_REG_35, - GPIO_PIN_REG_36, - GPIO_PIN_REG_37, - GPIO_PIN_REG_38, - GPIO_PIN_REG_39 -}; +const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {GPIO_PIN_REG_0, + GPIO_PIN_REG_1, + GPIO_PIN_REG_2, + GPIO_PIN_REG_3, + GPIO_PIN_REG_4, + GPIO_PIN_REG_5, + GPIO_PIN_REG_6, + GPIO_PIN_REG_7, + GPIO_PIN_REG_8, + GPIO_PIN_REG_9, + GPIO_PIN_REG_10, + GPIO_PIN_REG_11, + GPIO_PIN_REG_12, + GPIO_PIN_REG_13, + GPIO_PIN_REG_14, + GPIO_PIN_REG_15, + GPIO_PIN_REG_16, + GPIO_PIN_REG_17, + GPIO_PIN_REG_18, + GPIO_PIN_REG_19, + 0, + GPIO_PIN_REG_21, + GPIO_PIN_REG_22, + GPIO_PIN_REG_23, + 0, + GPIO_PIN_REG_25, + GPIO_PIN_REG_26, + GPIO_PIN_REG_27, + 0, + 0, + 0, + 0, + GPIO_PIN_REG_32, + GPIO_PIN_REG_33, + GPIO_PIN_REG_34, + GPIO_PIN_REG_35, + GPIO_PIN_REG_36, + GPIO_PIN_REG_37, + GPIO_PIN_REG_38, + GPIO_PIN_REG_39}; static int is_valid_gpio(int gpio_num) { - if(gpio_num >= GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[gpio_num] == 0) { - GPIO_ERROR("GPIO io_num=%d does not exist\n",gpio_num); + if (gpio_num >= GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[gpio_num] == 0) + { + GPIO_ERROR("GPIO io_num=%d does not exist\n", gpio_num); return 0; } return 1; @@ -101,11 +106,13 @@ static int is_valid_gpio(int gpio_num) esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - if(intr_type >= GPIO_INTR_MAX) { - GPIO_ERROR("Unknown GPIO intr:%u\n",intr_type); + if (intr_type >= GPIO_INTR_MAX) + { + GPIO_ERROR("Unknown GPIO intr:%u\n", intr_type); return ESP_ERR_INVALID_ARG; } GPIO.pin[gpio_num].int_type = intr_type; @@ -114,34 +121,43 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) esp_err_t gpio_intr_enable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - if(xPortGetCoreID() == 0) { - GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr - } else { - GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr + if (xPortGetCoreID() == 0) + { + GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; // enable pro cpu intr + } + else + { + GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; // enable pro cpu intr } return ESP_OK; } esp_err_t gpio_intr_disable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr + GPIO.pin[gpio_num].int_ena = 0; // disable GPIO intr return ESP_OK; } static esp_err_t gpio_output_disable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - if(gpio_num < 32) { + if (gpio_num < 32) + { GPIO.enable_w1tc = (0x1 << gpio_num); - } else { + } + else + { GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32)); } return ESP_OK; @@ -149,16 +165,21 @@ static esp_err_t gpio_output_disable(gpio_num_t gpio_num) static esp_err_t gpio_output_enable(gpio_num_t gpio_num) { - if(gpio_num >= 34) { - GPIO_ERROR("io_num=%d can only be input\n",gpio_num); + if (gpio_num >= 34) + { + GPIO_ERROR("io_num=%d can only be input\n", gpio_num); return ESP_ERR_INVALID_ARG; } - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - if(gpio_num < 32) { + if (gpio_num < 32) + { GPIO.enable_w1ts = (0x1 << gpio_num); - } else { + } + else + { GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32)); } return ESP_OK; @@ -166,19 +187,29 @@ static esp_err_t gpio_output_enable(gpio_num_t gpio_num) esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level) { - if(!GPIO_IS_VALID_GPIO(gpio_num)) { + if (!GPIO_IS_VALID_GPIO(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - if(level) { - if(gpio_num < 32) { + if (level) + { + if (gpio_num < 32) + { GPIO.out_w1ts = (1 << gpio_num); - } else { + } + else + { GPIO.out1_w1ts.data = (1 << (gpio_num - 32)); } - } else { - if(gpio_num < 32) { + } + else + { + if (gpio_num < 32) + { GPIO.out_w1tc = (1 << gpio_num); - } else { + } + else + { GPIO.out1_w1tc.data = (1 << (gpio_num - 32)); } } @@ -187,20 +218,25 @@ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level) int gpio_get_level(gpio_num_t gpio_num) { - if(gpio_num < 32) { + if (gpio_num < 32) + { return (GPIO.in >> gpio_num) & 0x1; - } else { + } + else + { return (GPIO.in1.data >> (gpio_num - 32)) & 0x1; } } esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; - switch(pull) { + switch (pull) + { case GPIO_PULLUP_ONLY: PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]); PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); @@ -218,7 +254,7 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]); break; default: - GPIO_ERROR("Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull); + GPIO_ERROR("Unknown pull up/down mode,gpio_num=%u,pull=%u\n", gpio_num, pull); ret = ESP_ERR_INVALID_ARG; break; } @@ -227,41 +263,59 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } - if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) { - GPIO_ERROR("io_num=%d can only be input\n",gpio_num); + if (gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) + { + GPIO_ERROR("io_num=%d can only be input\n", gpio_num); return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; - if(mode & GPIO_MODE_DEF_INPUT) { + if (mode & GPIO_MODE_DEF_INPUT) + { PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); - } else { + } + else + { PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); } - if(mode & GPIO_MODE_DEF_OUTPUT) { - if(gpio_num < 32) { + if (mode & GPIO_MODE_DEF_OUTPUT) + { + if (gpio_num < 32) + { GPIO.enable_w1ts = (0x1 << gpio_num); - } else { + } + else + { GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32)); } - } else { - if(gpio_num < 32) { + } + else + { + if (gpio_num < 32) + { GPIO.enable_w1tc = (0x1 << gpio_num); - } else { + } + else + { GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32)); } } - if(mode & GPIO_MODE_DEF_OD) { + if (mode & GPIO_MODE_DEF_OD) + { GPIO.pin[gpio_num].pad_driver = 1; - } else { + } + else + { GPIO.pin[gpio_num].pad_driver = 0; } return ret; } -/*esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg) +/*esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * +arg) { if(fn == NULL) { return ESP_ERR_INVALID_ARG; @@ -276,15 +330,22 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) /*only level interrupt can be used for wake-up function*/ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; - if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) { + if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) + { GPIO.pin[gpio_num].int_type = intr_type; GPIO.pin[gpio_num].wakeup_enable = 0x1; - } else { - GPIO_ERROR("GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num); + } + else + { + GPIO_ERROR( + "GPIO wakeup only support Level mode,but edge mode set. " + "gpio_num:%u\n", + gpio_num); ret = ESP_ERR_INVALID_ARG; } return ret; @@ -292,7 +353,8 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type) esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num) { - if(!is_valid_gpio(gpio_num)) { + if (!is_valid_gpio(gpio_num)) + { return ESP_ERR_INVALID_ARG; } GPIO.pin[gpio_num].wakeup_enable = 0; diff --git a/LuaNode_Esp32/LuaNode32/components/mydriver/gpio16.c b/LuaNode_Esp32/LuaNode32/components/mydriver/gpio16.c index f860c56..ddc2a07 100644 --- a/LuaNode_Esp32/LuaNode32/components/mydriver/gpio16.c +++ b/LuaNode_Esp32/LuaNode32/components/mydriver/gpio16.c @@ -1,45 +1,41 @@ #include "rom/ets_sys.h" //#include "osapi.h" -#include "gpio16.h" -#include "soc/soc.h" #include "extras/soc_ext.h" +#include "gpio16.h" #include "soc/rtc_io_reg.h" +#include "soc/soc.h" -void -gpio16_output_conf(void) +void gpio16_output_conf(void) { WRITE_PERI_REG(PAD_XPD_DCDC_CONF, - (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1); // mux configuration for XPD_DCDC to output rtc_gpio0 + (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | + (uint32)0x1); // mux configuration for XPD_DCDC to output rtc_gpio0 - WRITE_PERI_REG(RTC_GPIO_CONF, - (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); //mux configuration for out enable + WRITE_PERI_REG( + RTC_GPIO_CONF, + (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); // mux configuration for out enable WRITE_PERI_REG(RTC_GPIO_ENABLE, - (READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe) | (uint32)0x1); //out enable + (READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe) | (uint32)0x1); // out enable } -void -gpio16_output_set(uint8 value) +void gpio16_output_set(uint8 value) { - WRITE_PERI_REG(RTC_GPIO_OUT, - (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(value & 1)); + WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(value & 1)); } -void -gpio16_input_conf(void) +void gpio16_input_conf(void) { WRITE_PERI_REG(PAD_XPD_DCDC_CONF, - (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection + (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1); // mux configuration for XPD_DCDC + // and rtc_gpio0 connection - WRITE_PERI_REG(RTC_GPIO_CONF, - (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); //mux configuration for out enable + WRITE_PERI_REG( + RTC_GPIO_CONF, + (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); // mux configuration for out enable WRITE_PERI_REG(RTC_GPIO_ENABLE, - READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe); //out disable + READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe); // out disable } -uint8 -gpio16_input_get(void) -{ - return (uint8)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1); -} +uint8 gpio16_input_get(void) { return (uint8)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1); } diff --git a/LuaNode_Esp32/LuaNode32/components/mydriver/i2c_master.c b/LuaNode_Esp32/LuaNode32/components/mydriver/i2c_master.c index 1f87201..3415240 100644 --- a/LuaNode_Esp32/LuaNode32/components/mydriver/i2c_master.c +++ b/LuaNode_Esp32/LuaNode32/components/mydriver/i2c_master.c @@ -7,13 +7,11 @@ * * Modification history: * 2014/3/12, v1.0 create this file. -*******************************************************************************/ + *******************************************************************************/ #include "rom/ets_sys.h" //#include "osapi.h" -#include "mygpio.h" - #include "i2c_master.h" - +#include "mygpio.h" #include "pin_map.h" LOCAL uint8 m_nLastSDA; @@ -29,22 +27,28 @@ LOCAL uint8 pinSCL = 15; * Parameters : uint8 SDA * uint8 SCL * Returns : NONE -*******************************************************************************/ -LOCAL void -i2c_master_setDC(uint8 SDA, uint8 SCL) + *******************************************************************************/ +LOCAL void i2c_master_setDC(uint8 SDA, uint8 SCL) { - SDA &= 0x01; - SCL &= 0x01; + SDA &= 0x01; + SCL &= 0x01; m_nLastSDA = SDA; m_nLastSCL = SCL; - if ((0 == SDA) && (0 == SCL)) { + if ((0 == SDA) && (0 == SCL)) + { I2C_MASTER_SDA_LOW_SCL_LOW(); - } else if ((0 == SDA) && (1 == SCL)) { + } + else if ((0 == SDA) && (1 == SCL)) + { I2C_MASTER_SDA_LOW_SCL_HIGH(); - } else if ((1 == SDA) && (0 == SCL)) { + } + else if ((1 == SDA) && (0 == SCL)) + { I2C_MASTER_SDA_HIGH_SCL_LOW(); - } else { + } + else + { I2C_MASTER_SDA_HIGH_SCL_HIGH(); } } @@ -55,9 +59,8 @@ i2c_master_setDC(uint8 SDA, uint8 SCL) * get i2c SDA bit value * Parameters : NONE * Returns : uint8 - SDA bit value -*******************************************************************************/ -LOCAL uint8 -i2c_master_getDC(void) + *******************************************************************************/ +LOCAL uint8 i2c_master_getDC(void) { uint8 sda_out; sda_out = GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)); @@ -69,7 +72,7 @@ i2c_master_getDC(void) * Description : initilize I2C bus to enable i2c operations * Parameters : NONE * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ #if 0 void i2c_master_init(void) @@ -99,13 +102,9 @@ i2c_master_init(void) } #endif -uint8 i2c_master_get_pinSDA(){ - return pinSDA; -} +uint8 i2c_master_get_pinSDA() { return pinSDA; } -uint8 i2c_master_get_pinSCL(){ - return pinSCL; -} +uint8 i2c_master_get_pinSCL() { return pinSCL; } /****************************************************************************** * FunctionName : i2c_master_gpio_init @@ -113,7 +112,7 @@ uint8 i2c_master_get_pinSCL(){ * mux and gpio num defined in i2c_master.h * Parameters : NONE * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ #if 0 void i2c_master_gpio_init(uint8 sda, uint8 scl) @@ -146,7 +145,7 @@ i2c_master_gpio_init(uint8 sda, uint8 scl) * Description : set i2c to send state * Parameters : NONE * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ #if 0 void i2c_master_start(void) @@ -184,7 +183,7 @@ i2c_master_stop(void) * Description : set ack to i2c bus as level value * Parameters : uint8 level - 0 or 1 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ #if 0 void i2c_master_setAck(uint8 level) @@ -228,50 +227,44 @@ i2c_master_getAck(void) #endif /****************************************************************************** -* FunctionName : i2c_master_checkAck -* Description : get dev response -* Parameters : NONE -* Returns : true : get ack ; false : get nack -*******************************************************************************/ -bool -i2c_master_checkAck(void) + * FunctionName : i2c_master_checkAck + * Description : get dev response + * Parameters : NONE + * Returns : true : get ack ; false : get nack + *******************************************************************************/ +bool i2c_master_checkAck(void) { - if(i2c_master_getAck()){ + if (i2c_master_getAck()) + { return FALSE; - }else{ + } + else + { return TRUE; } } /****************************************************************************** -* FunctionName : i2c_master_send_ack -* Description : response ack -* Parameters : NONE -* Returns : NONE -*******************************************************************************/ -void -i2c_master_send_ack(void) -{ - i2c_master_setAck(0x0); -} + * FunctionName : i2c_master_send_ack + * Description : response ack + * Parameters : NONE + * Returns : NONE + *******************************************************************************/ +void i2c_master_send_ack(void) { i2c_master_setAck(0x0); } /****************************************************************************** -* FunctionName : i2c_master_send_nack -* Description : response nack -* Parameters : NONE -* Returns : NONE -*******************************************************************************/ -void -i2c_master_send_nack(void) -{ - i2c_master_setAck(0x1); -} + * FunctionName : i2c_master_send_nack + * Description : response nack + * Parameters : NONE + * Returns : NONE + *******************************************************************************/ +void i2c_master_send_nack(void) { i2c_master_setAck(0x1); } /****************************************************************************** * FunctionName : i2c_master_readByte * Description : read Byte from i2c bus * Parameters : NONE * Returns : uint8 - readed value -*******************************************************************************/ + *******************************************************************************/ #if 0 uint8 i2c_master_readByte(void) diff --git a/LuaNode_Esp32/LuaNode32/components/mydriver/mygpio.c b/LuaNode_Esp32/LuaNode32/components/mydriver/mygpio.c index 3fd6c9e..245e6fd 100644 --- a/LuaNode_Esp32/LuaNode32/components/mydriver/mygpio.c +++ b/LuaNode_Esp32/LuaNode32/components/mydriver/mygpio.c @@ -3,90 +3,85 @@ * * Copyright (c) 2015 * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case, - * it is free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in + * which case, it is free of charge, to any person obtaining a copy of this + * software and associated documentation files (the "Software"), to deal in the + * Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * */ +#include "mygpio.h" + +#include + #include "esp_common.h" +#include "extras/gpio_ext.h" +#include "extras/gpio_reg_ext.h" +#include "extras/gpio_sd_reg_ext.h" #include "freertos/portmacro.h" #include "freertos/xtensa_api.h" -#include "rom/gpio.h" -#include "mygpio.h" #include "rom/ets_sys.h" +#include "rom/gpio.h" #include "soc/gpio_reg.h" -#include "extras/gpio_reg_ext.h" -#include "extras/gpio_sd_reg_ext.h" -#include "extras/gpio_ext.h" -#include -const uint32 GPIO_PIN_REG[40] = { - GPIO_PIN_REG_0, - GPIO_PIN_REG_1, - GPIO_PIN_REG_2, - GPIO_PIN_REG_3, - GPIO_PIN_REG_4, - GPIO_PIN_REG_5, - GPIO_PIN_REG_6, - GPIO_PIN_REG_7, - GPIO_PIN_REG_8, - GPIO_PIN_REG_9, - GPIO_PIN_REG_10, - GPIO_PIN_REG_11, - GPIO_PIN_REG_12, - GPIO_PIN_REG_13, - GPIO_PIN_REG_14, - GPIO_PIN_REG_15, - GPIO_PIN_REG_16, - GPIO_PIN_REG_17, - GPIO_PIN_REG_18, - GPIO_PIN_REG_19, - GPIO_PIN_REG_20, - GPIO_PIN_REG_21, - GPIO_PIN_REG_22, - GPIO_PIN_REG_23, - 0, - GPIO_PIN_REG_25, - GPIO_PIN_REG_26, - GPIO_PIN_REG_27, - 0, - 0, - 0, - 0, - GPIO_PIN_REG_32, - GPIO_PIN_REG_33, - GPIO_PIN_REG_34, - GPIO_PIN_REG_35, - GPIO_PIN_REG_36, - GPIO_PIN_REG_37, - GPIO_PIN_REG_38, - GPIO_PIN_REG_39 -}; - -const uint8 intr_gpio_signals[] = { - PCNT_SIG_CH0_IN0_IDX, - PCNT_SIG_CH0_IN1_IDX, - PCNT_SIG_CH0_IN2_IDX, - PCNT_SIG_CH0_IN3_IDX, - PCNT_SIG_CH0_IN4_IDX, - PCNT_SIG_CH0_IN5_IDX, - PCNT_SIG_CH0_IN6_IDX, - PCNT_SIG_CH0_IN7_IDX -}; +const uint32 GPIO_PIN_REG[40] = {GPIO_PIN_REG_0, + GPIO_PIN_REG_1, + GPIO_PIN_REG_2, + GPIO_PIN_REG_3, + GPIO_PIN_REG_4, + GPIO_PIN_REG_5, + GPIO_PIN_REG_6, + GPIO_PIN_REG_7, + GPIO_PIN_REG_8, + GPIO_PIN_REG_9, + GPIO_PIN_REG_10, + GPIO_PIN_REG_11, + GPIO_PIN_REG_12, + GPIO_PIN_REG_13, + GPIO_PIN_REG_14, + GPIO_PIN_REG_15, + GPIO_PIN_REG_16, + GPIO_PIN_REG_17, + GPIO_PIN_REG_18, + GPIO_PIN_REG_19, + GPIO_PIN_REG_20, + GPIO_PIN_REG_21, + GPIO_PIN_REG_22, + GPIO_PIN_REG_23, + 0, + GPIO_PIN_REG_25, + GPIO_PIN_REG_26, + GPIO_PIN_REG_27, + 0, + 0, + 0, + 0, + GPIO_PIN_REG_32, + GPIO_PIN_REG_33, + GPIO_PIN_REG_34, + GPIO_PIN_REG_35, + GPIO_PIN_REG_36, + GPIO_PIN_REG_37, + GPIO_PIN_REG_38, + GPIO_PIN_REG_39}; + +const uint8 intr_gpio_signals[] = {PCNT_SIG_CH0_IN0_IDX, PCNT_SIG_CH0_IN1_IDX, PCNT_SIG_CH0_IN2_IDX, + PCNT_SIG_CH0_IN3_IDX, PCNT_SIG_CH0_IN4_IDX, PCNT_SIG_CH0_IN5_IDX, + PCNT_SIG_CH0_IN6_IDX, PCNT_SIG_CH0_IN7_IDX}; uint8 intr_gpio_nums[8]; @@ -94,17 +89,21 @@ static portMUX_TYPE g_gpio_mux = portMUX_INITIALIZER_UNLOCKED; static void gpio_intr_reset(uint32 intr_num, uint8 reset) { - if (intr_num > 7) { + if (intr_num > 7) + { return; } - //bit PCNT_CNT_PAUSE_U0-7 + // bit PCNT_CNT_PAUSE_U0-7 CLEAR_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2 + 1)); - //bit PCNT_PLUS_CNT_RST_U0-7 - if (reset) { + // bit PCNT_PLUS_CNT_RST_U0-7 + if (reset) + { SET_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2)); - } else { + } + else + { CLEAR_PERI_REG_MASK(PCNT_CTRL, BIT(intr_num * 2)); } } @@ -122,16 +121,23 @@ static void gpio_intr_init(uint32 intr_num, gpio_int_type_t intr_type) SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_LCTRL_MODE_U0, 0, PCNT_CH0_LCTRL_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_HCTRL_MODE_U0, 0, PCNT_CH0_HCTRL_MODE_U0_S); - if (intr_type == GPIO_INTR_NEGEDGE) { + if (intr_type == GPIO_INTR_NEGEDGE) + { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 0, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 1, PCNT_CH0_NEG_MODE_U0_S); - } else if (intr_type == GPIO_INTR_POSEDGE) { + } + else if (intr_type == GPIO_INTR_POSEDGE) + { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 1, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 0, PCNT_CH0_NEG_MODE_U0_S); - } else if (intr_type == GPIO_INTR_ANYEDGE) { + } + else if (intr_type == GPIO_INTR_ANYEDGE) + { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 1, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 1, PCNT_CH0_NEG_MODE_U0_S); - } else { + } + else + { SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_POS_MODE_U0, 0, PCNT_CH0_POS_MODE_U0_S); SET_PERI_REG_BITS(cfg0_addr, PCNT_CH0_NEG_MODE_U0, 0, PCNT_CH0_NEG_MODE_U0_S); } @@ -139,17 +145,18 @@ static void gpio_intr_init(uint32 intr_num, gpio_int_type_t intr_type) SET_PERI_REG_BITS(cfg1_addr, PCNT_CNT_THRES0_U0, 1, PCNT_CNT_THRES0_U0_S); SET_PERI_REG_BITS(cfg2_addr, PCNT_CNT_L_LIM_U0, 10, PCNT_CNT_L_LIM_U0_S); SET_PERI_REG_BITS(cfg2_addr, PCNT_CNT_H_LIM_U0, 10, PCNT_CNT_H_LIM_U0_S); - CLEAR_PERI_REG_MASK(cfg0_addr, (PCNT_THR_THRES1_EN_U0 | PCNT_THR_L_LIM_EN_U0 - | PCNT_THR_H_LIM_EN_U0 | PCNT_THR_ZERO_EN_U0 | PCNT_FILTER_EN_U0)); + CLEAR_PERI_REG_MASK(cfg0_addr, (PCNT_THR_THRES1_EN_U0 | PCNT_THR_L_LIM_EN_U0 | PCNT_THR_H_LIM_EN_U0 | + PCNT_THR_ZERO_EN_U0 | PCNT_FILTER_EN_U0)); SET_PERI_REG_MASK(cfg0_addr, PCNT_THR_THRES0_EN_U0); SET_PERI_REG_MASK(PCNT_INT_ENA, BIT(intr_num)); } -//intr_num only support 0-7 +// intr_num only support 0-7 void gpio_intr_config(uint32 gpio_num, uint32 intr_num, GPIO_INT_TYPE intr_type) { - if (intr_num >= sizeof(intr_gpio_nums)) { + if (intr_num >= sizeof(intr_gpio_nums)) + { return; } @@ -183,12 +190,14 @@ void gpio_intr_process(void) uint8 gpio_num; intr_status = READ_PERI_REG(PCNT_INT_ST); - while ((intr_num = __builtin_ctz(intr_status)) >= 0) { + while ((intr_num = __builtin_ctz(intr_status)) >= 0) + { intr_status &= ~BIT(intr_num); gpio_num = intr_gpio_nums[intr_num]; gpio_intr_clear(intr_num); - switch (gpio_num) { + switch (gpio_num) + { default: printf("gpio %d intr come\n", gpio_num); break; @@ -214,7 +223,8 @@ void gpio_intr_process(void) } do { - bit_valid = (io_num >= 32 ? (gpio_pin_mask_high & (0x1 << (io_num - 32))) : (gpio_pin_mask & (0x1 << io_num))); + bit_valid = (io_num >= 32 ? (gpio_pin_mask_high & (0x1 << (io_num - +32))) : (gpio_pin_mask & (0x1 << io_num))); if (bit_valid && (io_reg = GPIO_PIN_REG[io_num])) { if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Input) { @@ -256,7 +266,8 @@ void gpio_intr_process(void) void gpio_output_sigmadelta_enable(uint32 gpio_num, uint32 sigma_num, uint32 prescale) { - if (sigma_num >= 8) { + if (sigma_num >= 8) + { return; } @@ -264,10 +275,7 @@ void gpio_output_sigmadelta_enable(uint32 gpio_num, uint32 sigma_num, uint32 pre gpio_matrix_out(gpio_num, GPIO_SD0_OUT_IDX + sigma_num, false, false); } -void gpio_output_sigmadelta_disable(uint32 gpio_num) -{ - gpio_matrix_out(gpio_num, 0x80, false, false); -} +void gpio_output_sigmadelta_disable(uint32 gpio_num) { gpio_matrix_out(gpio_num, 0x80, false, false); } /* * Change GPIO pin output by setting, clearing, or disabling pins. @@ -279,7 +287,8 @@ void gpio_output_sigmadelta_disable(uint32 gpio_num) * writes is significant, calling code should divide a single call * into multiple calls. * - * This function only config GPIO0-GPIO31, If you want to config GPIO32-GPIO39, use gpio_output_conf_high + * This function only config GPIO0-GPIO31, If you want to config GPIO32-GPIO39, + * use gpio_output_conf_high * */ void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask) @@ -300,7 +309,8 @@ void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, ui * writes is significant, calling code should divide a single call * into multiple calls. * - * This function only config GPIO32-GPIO39, If you want to config GPIO0-GPIO31, use gpio_output_conf + * This function only config GPIO32-GPIO39, If you want to config GPIO0-GPIO31, + * use gpio_output_conf * */ void gpio_output_conf_high(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask) @@ -316,20 +326,14 @@ void gpio_output_conf_high(uint32 set_mask, uint32 clear_mask, uint32 enable_mas * * Only GPIO0-GPIO31 */ -uint32 gpio_input_get(void) -{ - return GPIO_REG_READ(GPIO_IN); -} +uint32 gpio_input_get(void) { return GPIO_REG_READ(GPIO_IN); } /* * Sample the value of GPIO input pins and returns a bitmask. * * Only GPIO32-GPIO39 */ -uint32 gpio_input_get_high(void) -{ - return GPIO_REG_READ(GPIO_IN1); -} +uint32 gpio_input_get_high(void) { return GPIO_REG_READ(GPIO_IN1); } // we do not support sleep by now #if 0 diff --git a/LuaNode_Esp32/LuaNode32/components/mydriver/pwm.c b/LuaNode_Esp32/LuaNode32/components/mydriver/pwm.c index 7d34047..79bdf78 100644 --- a/LuaNode_Esp32/LuaNode32/components/mydriver/pwm.c +++ b/LuaNode_Esp32/LuaNode32/components/mydriver/pwm.c @@ -3,29 +3,32 @@ * * Copyright (c) 2015 * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in which case, - * it is free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP32 only, in + * which case, it is free of charge, to any person obtaining a copy of this + * software and associated documentation files (the "Software"), to deal in the + * Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. * */ -#include "esp_common.h" #include "pwm.h" -#include "pin_map.h" + +#include "esp_common.h" #include "extras/gpio_reg_ext.h" +#include "pin_map.h" //#include "io_mux_reg.h" LOCAL int8 pwm_out_io_num[PWM_CHANNEL_NUM_MAX] = {-1, -1, -1, -1, -1, -1}; @@ -33,18 +36,19 @@ LOCAL struct pwm_param pwm; LOCAL uint16 pwm_gpio = 0; LOCAL uint8 pwm_channel_num = 0; - /****************************************************************************** * FunctionName : ledc_set_base_hclk * Description : set high_speed channel base clk * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 - uint8 apb_clk_sel: 0-ref_tick, 1-apb_clk + uint8 apb_clk_sel: 0-ref_tick, 1-apb_clk * Returns : NONE *******************************************************************************/ void ledc_set_base_hclk(uint8 timer_sel, uint8 apb_clk_sel) { - if (apb_clk_sel) { //choose apb_clk as base clk - switch (timer_sel) { // + if (apb_clk_sel) + { // choose apb_clk as base clk + switch (timer_sel) + { // case 0: SET_PERI_REG_MASK(LEDC_HSTIMER0_CONF, LEDC_TICK_ALWAYS_ON_HSTIMER0); break; @@ -72,13 +76,15 @@ void ledc_set_base_hclk(uint8 timer_sel, uint8 apb_clk_sel) * FunctionName : ledc_set_base_lclk * Description : set low_speed channel base clk * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 - uint8 apb_clk_sel: 0-ref_tick, 1-apb_clk + uint8 apb_clk_sel: 0-ref_tick, 1-apb_clk * Returns : NONE *******************************************************************************/ void ledc_set_base_lclk(uint8 timer_sel, uint8 apb_clk_sel) { - if (apb_clk_sel) { //choose apb_clk as base clk - switch (timer_sel) { // + if (apb_clk_sel) + { // choose apb_clk as base clk + switch (timer_sel) + { // case 0: SET_PERI_REG_MASK(LEDC_LSTIMER0_CONF, LEDC_TICK_ALWAYS_ON_LSTIMER0); break; @@ -104,15 +110,17 @@ void ledc_set_base_lclk(uint8 timer_sel, uint8 apb_clk_sel) /****************************************************************************** * FunctionName : ledc_set_hperiod - * Description : set high-speed channel frequency=base_clk_frequency*div_num*(2^timer_lim)/256 + * Description : set high-speed channel +frequency=base_clk_frequency*div_num*(2^timer_lim)/256 * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 - uint32 div_num - uint8 timer_lim + uint32 div_num + uint8 timer_lim * Returns : NONE *******************************************************************************/ void ledc_set_hperiod(uint8 timer_sel, uint32 div_num, uint8 timer_lim) { - switch (timer_sel) { + switch (timer_sel) + { case 0: SET_PERI_REG_BITS(LEDC_HSTIMER0_CONF, LEDC_DIV_NUM_HSTIMER0, div_num, LEDC_DIV_NUM_HSTIMER0_S); SET_PERI_REG_BITS(LEDC_HSTIMER0_CONF, LEDC_HSTIMER0_LIM, timer_lim, LEDC_HSTIMER0_LIM_S); @@ -142,15 +150,17 @@ void ledc_set_hperiod(uint8 timer_sel, uint32 div_num, uint8 timer_lim) /****************************************************************************** * FunctionName : ledc_set_lperiod - * Description : set low-speed channel frequency=base_clk_frequency*div_num*(2^timer_lim)/256 + * Description : set low-speed channel +frequency=base_clk_frequency*div_num*(2^timer_lim)/256 * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 - uint32 div_num - uint8 timer_lim + uint32 div_num + uint8 timer_lim * Returns : NONE *******************************************************************************/ void ledc_set_lperiod(uint8 timer_sel, uint32 div_num, uint8 timer_lim) { - switch (timer_sel) { + switch (timer_sel) + { case 0: SET_PERI_REG_BITS(LEDC_LSTIMER0_CONF, LEDC_DIV_NUM_LSTIMER0, div_num, LEDC_DIV_NUM_LSTIMER0_S); SET_PERI_REG_BITS(LEDC_LSTIMER0_CONF, LEDC_LSTIMER0_LIM, timer_lim, LEDC_LSTIMER0_LIM_S); @@ -187,12 +197,14 @@ void ledc_set_lperiod(uint8 timer_sel, uint32 div_num, uint8 timer_lim) * FunctionName : ledc_set_ltimer * Description : low_speed channel x choose timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 - uint8 chan_num: 8 channels in total,value from 0~7 + uint8 chan_num: 8 channels in total,value from +0~7 * Returns : NONE *******************************************************************************/ void ledc_set_ltimer(uint8 chan_num, uint8 timer_sel) { - switch (chan_num) { // + switch (chan_num) + { // case 0: SET_PERI_REG_BITS(LEDC_LSCH0_CONF0, LEDC_TIMER_SEL_LSCH0, timer_sel, LEDC_TIMER_SEL_LSCH0_S); break; @@ -231,17 +243,18 @@ void ledc_set_ltimer(uint8 chan_num, uint8 timer_sel) } } - /****************************************************************************** * FunctionName : ledc_set_htimer * Description : high_speed channel x choose timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 - uint8 chan_num: 8 channels in total,value from 0~7 + uint8 chan_num: 8 channels in total,value from +0~7 * Returns : NONE *******************************************************************************/ void ledc_set_htimer(uint8 chan_num, uint8 timer_sel) { - switch (chan_num) { // + switch (chan_num) + { // case 0: SET_PERI_REG_BITS(LEDC_HSCH0_CONF0, LEDC_TIMER_SEL_HSCH0, timer_sel, LEDC_TIMER_SEL_HSCH0_S); break; @@ -280,18 +293,19 @@ void ledc_set_htimer(uint8 chan_num, uint8 timer_sel) } } - /****************************************************************************** * FunctionName : ledc_set_idle_hlevel * Description : set high speed channel output (as high or low) when idle * Parameters : uint8 chan_num: 8 channels in total,value from 0~7 - uint8 idle_level: 1-output high, 0-output low + uint8 idle_level: 1-output high, 0-output low * Returns : NONE *******************************************************************************/ void ledc_set_idle_hlevel(uint8 chan_num, uint8 idle_level) { - if (idle_level) { - switch (chan_num) { // + if (idle_level) + { + switch (chan_num) + { // case 0: SET_PERI_REG_MASK(LEDC_HSCH0_CONF0, LEDC_IDLE_LV_HSCH0); break; @@ -328,8 +342,11 @@ void ledc_set_idle_hlevel(uint8 chan_num, uint8 idle_level) SET_PERI_REG_MASK(LEDC_HSCH0_CONF0, LEDC_IDLE_LV_HSCH0); break; } - } else { - switch (chan_num) { // + } + else + { + switch (chan_num) + { // case 0: CLEAR_PERI_REG_MASK(LEDC_HSCH0_CONF0, LEDC_IDLE_LV_HSCH0); break; @@ -373,13 +390,15 @@ void ledc_set_idle_hlevel(uint8 chan_num, uint8 idle_level) * FunctionName : ledc_set_idle_llevel * Description : set high speed channel output (as high or low) when idle * Parameters : uint8 chan_num: 8 channels in total,value from 0~7 - uint8 idle_level: 1-output high, 0-output low + uint8 idle_level: 1-output high, 0-output low * Returns : NONE *******************************************************************************/ void ledc_set_idle_llevel(uint8 chan_num, uint8 idle_level) { - if (idle_level) { - switch (chan_num) { // + if (idle_level) + { + switch (chan_num) + { // case 0: SET_PERI_REG_MASK(LEDC_LSCH0_CONF0, LEDC_IDLE_LV_HSCH0); break; @@ -416,8 +435,11 @@ void ledc_set_idle_llevel(uint8 chan_num, uint8 idle_level) SET_PERI_REG_MASK(LEDC_LSCH0_CONF0, LEDC_IDLE_LV_HSCH0); break; } - } else { - switch (chan_num) { // + } + else + { + switch (chan_num) + { // case 0: CLEAR_PERI_REG_MASK(LEDC_LSCH0_CONF0, LEDC_IDLE_LV_HSCH0); break; @@ -461,24 +483,29 @@ void ledc_set_idle_llevel(uint8 chan_num, uint8 idle_level) * FunctionName : ledc_set_hduty * Description : set high_speed channel duty * Parameters : uint8 chan_num: 8 channels in total,value from 0~7 - uint32 hpoint_val:output high when counter equals this value - uint32 duty_val: output low after counter equals this value - uint8 increase: 1-increase duty ratio,0-decrease duty ratio - uint16 duty_num: generate interrupt after duty_num * duty_cycle outputs - uint16 duty_cycle: increase or decrease duty ratio every duty_cycle outputs - uint16 duty_scale: the range of changing on duty ratio + uint32 hpoint_val:output high when counter +equals this value uint32 duty_val: output low after counter equals this value + uint8 increase: 1-increase duty +ratio,0-decrease duty ratio uint16 duty_num: generate interrupt after duty_num * +duty_cycle outputs uint16 duty_cycle: increase or decrease duty ratio every +duty_cycle outputs uint16 duty_scale: the range of changing on duty ratio * Returns : NONE *******************************************************************************/ -void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 increase, uint16 duty_num, uint16 duty_cycle, uint16 duty_scale) +void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 increase, uint16 duty_num, + uint16 duty_cycle, uint16 duty_scale) { - switch (chan_num) { + switch (chan_num) + { case 0: SET_PERI_REG_BITS(LEDC_HSCH0_HPOINT, LEDC_HPOINT_HSCH0, hpoint_val, LEDC_HPOINT_HSCH0_S); SET_PERI_REG_BITS(LEDC_HSCH0_DUTY, LEDC_DUTY_HSCH0, duty_val, LEDC_DUTY_HSCH0_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH0_CONF1, LEDC_DUTY_INC_HSCH0); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH0_CONF1, LEDC_DUTY_INC_HSCH0); } @@ -491,9 +518,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH1_HPOINT, LEDC_HPOINT_HSCH1, hpoint_val, LEDC_HPOINT_HSCH1_S); SET_PERI_REG_BITS(LEDC_HSCH1_DUTY, LEDC_DUTY_HSCH1, duty_val, LEDC_DUTY_HSCH1_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH1_CONF1, LEDC_DUTY_INC_HSCH1); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH1_CONF1, LEDC_DUTY_INC_HSCH1); } @@ -506,9 +536,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH2_HPOINT, LEDC_HPOINT_HSCH2, hpoint_val, LEDC_HPOINT_HSCH2_S); SET_PERI_REG_BITS(LEDC_HSCH2_DUTY, LEDC_DUTY_HSCH2, duty_val, LEDC_DUTY_HSCH2_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH2_CONF1, LEDC_DUTY_INC_HSCH2); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH2_CONF1, LEDC_DUTY_INC_HSCH2); } @@ -521,9 +554,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH3_HPOINT, LEDC_HPOINT_HSCH3, hpoint_val, LEDC_HPOINT_HSCH3_S); SET_PERI_REG_BITS(LEDC_HSCH3_DUTY, LEDC_DUTY_HSCH3, duty_val, LEDC_DUTY_HSCH3_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH3_CONF1, LEDC_DUTY_INC_HSCH3); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH3_CONF1, LEDC_DUTY_INC_HSCH3); } @@ -536,9 +572,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH4_HPOINT, LEDC_HPOINT_HSCH4, hpoint_val, LEDC_HPOINT_HSCH4_S); SET_PERI_REG_BITS(LEDC_HSCH4_DUTY, LEDC_DUTY_HSCH4, duty_val, LEDC_DUTY_HSCH4_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH4_CONF1, LEDC_DUTY_INC_HSCH4); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH4_CONF1, LEDC_DUTY_INC_HSCH4); } @@ -551,9 +590,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH5_HPOINT, LEDC_HPOINT_HSCH5, hpoint_val, LEDC_HPOINT_HSCH5_S); SET_PERI_REG_BITS(LEDC_HSCH5_DUTY, LEDC_DUTY_HSCH5, duty_val, LEDC_DUTY_HSCH5_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH5_CONF1, LEDC_DUTY_INC_HSCH5); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH5_CONF1, LEDC_DUTY_INC_HSCH5); } @@ -566,9 +608,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH6_HPOINT, LEDC_HPOINT_HSCH6, hpoint_val, LEDC_HPOINT_HSCH6_S); SET_PERI_REG_BITS(LEDC_HSCH6_DUTY, LEDC_DUTY_HSCH6, duty_val, LEDC_DUTY_HSCH6_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH6_CONF1, LEDC_DUTY_INC_HSCH6); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH6_CONF1, LEDC_DUTY_INC_HSCH6); } @@ -581,9 +626,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH7_HPOINT, LEDC_HPOINT_HSCH7, hpoint_val, LEDC_HPOINT_HSCH7_S); SET_PERI_REG_BITS(LEDC_HSCH7_DUTY, LEDC_DUTY_HSCH7, duty_val, LEDC_DUTY_HSCH7_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH7_CONF1, LEDC_DUTY_INC_HSCH7); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH7_CONF1, LEDC_DUTY_INC_HSCH7); } @@ -596,9 +644,12 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_HSCH0_HPOINT, LEDC_HPOINT_HSCH0, hpoint_val, LEDC_HPOINT_HSCH0_S); SET_PERI_REG_BITS(LEDC_HSCH0_DUTY, LEDC_DUTY_HSCH0, duty_val, LEDC_DUTY_HSCH0_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_HSCH0_CONF1, LEDC_DUTY_INC_HSCH0); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_HSCH0_CONF1, LEDC_DUTY_INC_HSCH0); } @@ -613,24 +664,29 @@ void ledc_set_hduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in * FunctionName : ledc_set_lduty * Description : set low_speed channel duty * Parameters : uint8 chan_num: 8 channels in total,value from 0~7 - uint32 hpoint_val:output high when counter equals this value - uint32 duty_val: output low after counter equals this value - uint8 increase: 1-increase duty ratio,0-decrease duty ratio - uint16 duty_num: generate interrupt after duty_num * duty_cycle outputs - uint16 duty_cycle: increase or decrease duty ratio every duty_cycle outputs - uint16 duty_scale: the range of changing on duty ratio + uint32 hpoint_val:output high when counter +equals this value uint32 duty_val: output low after counter equals this value + uint8 increase: 1-increase duty +ratio,0-decrease duty ratio uint16 duty_num: generate interrupt after duty_num * +duty_cycle outputs uint16 duty_cycle: increase or decrease duty ratio every +duty_cycle outputs uint16 duty_scale: the range of changing on duty ratio * Returns : NONE *******************************************************************************/ -void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 increase, uint16 duty_num, uint16 duty_cycle, uint16 duty_scale) +void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 increase, uint16 duty_num, + uint16 duty_cycle, uint16 duty_scale) { - switch (chan_num) { + switch (chan_num) + { case 0: SET_PERI_REG_BITS(LEDC_LSCH0_HPOINT, LEDC_HPOINT_LSCH0, hpoint_val, LEDC_HPOINT_LSCH0_S); SET_PERI_REG_BITS(LEDC_LSCH0_DUTY, LEDC_DUTY_LSCH0, duty_val, LEDC_DUTY_LSCH0_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH0_CONF1, LEDC_DUTY_INC_LSCH0); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH0_CONF1, LEDC_DUTY_INC_LSCH0); } @@ -643,9 +699,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH1_HPOINT, LEDC_HPOINT_LSCH1, hpoint_val, LEDC_HPOINT_LSCH1_S); SET_PERI_REG_BITS(LEDC_LSCH1_DUTY, LEDC_DUTY_LSCH1, duty_val, LEDC_DUTY_LSCH1_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH1_CONF1, LEDC_DUTY_INC_LSCH1); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH1_CONF1, LEDC_DUTY_INC_LSCH1); } @@ -658,9 +717,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH2_HPOINT, LEDC_HPOINT_LSCH2, hpoint_val, LEDC_HPOINT_LSCH2_S); SET_PERI_REG_BITS(LEDC_LSCH2_DUTY, LEDC_DUTY_LSCH2, duty_val, LEDC_DUTY_LSCH2_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH2_CONF1, LEDC_DUTY_INC_LSCH2); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH2_CONF1, LEDC_DUTY_INC_LSCH2); } @@ -673,9 +735,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH3_HPOINT, LEDC_HPOINT_LSCH3, hpoint_val, LEDC_HPOINT_LSCH3_S); SET_PERI_REG_BITS(LEDC_LSCH3_DUTY, LEDC_DUTY_LSCH3, duty_val, LEDC_DUTY_LSCH3_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH3_CONF1, LEDC_DUTY_INC_LSCH3); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH3_CONF1, LEDC_DUTY_INC_LSCH3); } @@ -688,9 +753,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH4_HPOINT, LEDC_HPOINT_LSCH4, hpoint_val, LEDC_HPOINT_LSCH4_S); SET_PERI_REG_BITS(LEDC_LSCH4_DUTY, LEDC_DUTY_LSCH4, duty_val, LEDC_DUTY_LSCH4_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH4_CONF1, LEDC_DUTY_INC_LSCH4); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH4_CONF1, LEDC_DUTY_INC_LSCH4); } @@ -703,9 +771,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH5_HPOINT, LEDC_HPOINT_LSCH5, hpoint_val, LEDC_HPOINT_LSCH5_S); SET_PERI_REG_BITS(LEDC_LSCH5_DUTY, LEDC_DUTY_LSCH5, duty_val, LEDC_DUTY_LSCH5_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH5_CONF1, LEDC_DUTY_INC_LSCH5); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH5_CONF1, LEDC_DUTY_INC_LSCH5); } @@ -718,9 +789,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH6_HPOINT, LEDC_HPOINT_LSCH6, hpoint_val, LEDC_HPOINT_LSCH6_S); SET_PERI_REG_BITS(LEDC_LSCH6_DUTY, LEDC_DUTY_LSCH6, duty_val, LEDC_DUTY_LSCH6_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH6_CONF1, LEDC_DUTY_INC_LSCH6); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH6_CONF1, LEDC_DUTY_INC_LSCH6); } @@ -733,9 +807,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH7_HPOINT, LEDC_HPOINT_LSCH7, hpoint_val, LEDC_HPOINT_LSCH7_S); SET_PERI_REG_BITS(LEDC_LSCH7_DUTY, LEDC_DUTY_LSCH7, duty_val, LEDC_DUTY_LSCH7_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH7_CONF1, LEDC_DUTY_INC_LSCH7); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH7_CONF1, LEDC_DUTY_INC_LSCH7); } @@ -748,9 +825,12 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in SET_PERI_REG_BITS(LEDC_LSCH0_HPOINT, LEDC_HPOINT_LSCH0, hpoint_val, LEDC_HPOINT_LSCH0_S); SET_PERI_REG_BITS(LEDC_LSCH0_DUTY, LEDC_DUTY_LSCH0, duty_val, LEDC_DUTY_LSCH0_S); - if (increase == 1) { + if (increase == 1) + { SET_PERI_REG_MASK(LEDC_LSCH0_CONF1, LEDC_DUTY_INC_LSCH0); - } else { + } + else + { CLEAR_PERI_REG_MASK(LEDC_LSCH0_CONF1, LEDC_DUTY_INC_LSCH0); } @@ -766,10 +846,11 @@ void ledc_set_lduty(uint8 chan_num, uint32 hpoint_val, uint32 duty_val, uint8 in * Description : enable one high_speed channel * Parameters : uint8 chan_num: 8 channels in total,value from 0~7 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_hstart(uint8 chan_num) { - switch (chan_num) { // + switch (chan_num) + { // case 0: SET_PERI_REG_MASK(LEDC_HSCH0_CONF1, LEDC_DUTY_START_HSCH0); SET_PERI_REG_MASK(LEDC_HSCH0_CONF0, LEDC_SIG_OUT_EN_HSCH0); @@ -822,10 +903,11 @@ void ledc_hstart(uint8 chan_num) * Description : enable one low_speed channel * Parameters : uint8 chan_num: 8 channels in total,value from 0~7 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_lstart(uint8 chan_num) { - switch (chan_num) { // + switch (chan_num) + { // case 0: SET_PERI_REG_MASK(LEDC_LSCH0_CONF0, LEDC_PARA_UP_LSCH0); SET_PERI_REG_MASK(LEDC_LSCH0_CONF1, LEDC_DUTY_START_LSCH0); @@ -887,10 +969,11 @@ void ledc_lstart(uint8 chan_num) * Description : pause the select high_speed timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_timer_hpause(uint8 timer_sel) { - switch (timer_sel) { + switch (timer_sel) + { case 0: SET_PERI_REG_MASK(LEDC_HSTIMER0_CONF, LEDC_HSTIMER0_PAUSE); break; @@ -918,10 +1001,11 @@ void ledc_timer_hpause(uint8 timer_sel) * Description : pause the select low_speed timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_timer_lpause(uint8 timer_sel) { - switch (timer_sel) { + switch (timer_sel) + { case 0: SET_PERI_REG_MASK(LEDC_LSTIMER0_CONF, LEDC_LSTIMER0_PAUSE); break; @@ -949,10 +1033,11 @@ void ledc_timer_lpause(uint8 timer_sel) * Description : unpause the select high_speed timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_timer_hunpause(uint8 timer_sel) { - switch (timer_sel) { + switch (timer_sel) + { case 0: CLEAR_PERI_REG_MASK(LEDC_HSTIMER0_CONF, LEDC_HSTIMER0_PAUSE); break; @@ -980,10 +1065,11 @@ void ledc_timer_hunpause(uint8 timer_sel) * Description : unpause the select low_speed timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_timer_lunpause(uint8 timer_sel) { - switch (timer_sel) { + switch (timer_sel) + { case 0: CLEAR_PERI_REG_MASK(LEDC_LSTIMER0_CONF, LEDC_LSTIMER0_PAUSE); break; @@ -1011,10 +1097,11 @@ void ledc_timer_lunpause(uint8 timer_sel) * Description : disable the select high_speed timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_timer_hstop(uint8 timer_sel) { - switch (timer_sel) { + switch (timer_sel) + { case 0: SET_PERI_REG_MASK(LEDC_HSTIMER0_CONF, LEDC_HSTIMER0_RST); break; @@ -1042,10 +1129,11 @@ void ledc_timer_hstop(uint8 timer_sel) * Description : disable the select low_speed timer * Parameters : uint8 timer_sel: 0-timer0, 1-timer1, 2-timer2, 3-timer3 * Returns : NONE -*******************************************************************************/ + *******************************************************************************/ void ledc_timer_lstop(uint8 timer_sel) { - switch (timer_sel) { + switch (timer_sel) + { case 0: SET_PERI_REG_MASK(LEDC_LSTIMER0_CONF, LEDC_LSTIMER0_RST); break; @@ -1085,15 +1173,16 @@ void pwm_set_duty(uint32 duty, uint8 channel) { uint8 chan_num; - for (chan_num = 0; chan_num < channel; chan_num++) { - ledc_set_hduty(chan_num,//uint8 chan_num, - 0,//uint32 hpoint_val, - duty,//uint32 duty_val, - 1,//uint8 increase, - 1,//uint16 duty_num, - 1,//uint16 duty_cycle, - 0//uint16 duty_scale - ); + for (chan_num = 0; chan_num < channel; chan_num++) + { + ledc_set_hduty(chan_num, // uint8 chan_num, + 0, // uint32 hpoint_val, + duty, // uint32 duty_val, + 1, // uint8 increase, + 1, // uint16 duty_num, + 1, // uint16 duty_cycle, + 0 // uint16 duty_scale + ); } } @@ -1105,10 +1194,7 @@ uint32 pwm_get_duty(uint8 channel) } /*period = Freq(base_clk)/512/period*256 */ -void pwm_set_period(uint32 period) -{ - ledc_set_hperiod(0, 512, period); -} +void pwm_set_period(uint32 period) { ledc_set_hperiod(0, 512, period); } /*calculate frequency div_num*/ uint32 pwm_get_period(void) @@ -1116,112 +1202,124 @@ uint32 pwm_get_period(void) uint32 div_lv1, div_lv2, div_freq; uint32 timer0_info; timer0_info = READ_PERI_REG(LEDC_HSTIMER0_CONF); - div_lv1 = timer0_info & LEDC_HSTIMER0_LIM ; + div_lv1 = timer0_info & LEDC_HSTIMER0_LIM; div_lv2 = (timer0_info >> LEDC_DIV_NUM_HSTIMER0_S) & LEDC_DIV_NUM_HSTIMER0; div_freq = ((div_lv1 * div_lv2) >> 8); return div_freq; } -void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32(*pin_info_list)[3]) +void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32 (*pin_info_list)[3]) { pwm_set_period(period); pwm_set_duty(*duty, pwm_channel_num); pwm_start(); } -bool -pwm_exist(uint8 channel){ - //PWM_DBG("--Function pwm_exist() is called. channel:%d\n", channel); - //PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num); - //PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]); - //PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]); +bool pwm_exist(uint8 channel) +{ + // PWM_DBG("--Function pwm_exist() is called. channel:%d\n", channel); + // PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num); + // PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]); + // PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]); uint8 i; - for(i=0;i PWM_FREQ_MAX) { + LOCK_PWM(critical); // enter critical + if (freq > PWM_FREQ_MAX) + { pwm.freq = PWM_FREQ_MAX; - } else if (freq < 1) { + } + else if (freq < 1) + { pwm.freq = 1; - } else { + } + else + { pwm.freq = freq; } pwm.period = PWM_1S / pwm.freq; - UNLOCK_PWM(critical); // leave critical + UNLOCK_PWM(critical); // leave critical } -bool -pwm_add(uint8 channel){ - //PWM_DBG("--Function pwm_add() is called. channel:%d\n", channel); - //PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num); - //PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]); - //PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]); +bool pwm_add(uint8 channel) +{ + // PWM_DBG("--Function pwm_add() is called. channel:%d\n", channel); + // PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num); + // PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]); + // PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]); uint8 i; - for(i=0;i 0.0) return (x); - //cmemsg(FP_POWO, &y); - //return(HUGE); + // cmemsg(FP_POWO, &y); + // return(HUGE); } else { - //cmemsg(FP_POWN, &x); + // cmemsg(FP_POWN, &x); x = -x; } } @@ -111,12 +98,12 @@ double pow(double x, double y) } if (iw1 > MAXEXP) { - //cmemsg(FP_POWO, &y); + // cmemsg(FP_POWO, &y); return (HUGE); } if (iw1 < MINEXP) { - //cmemsg(FP_POWU, &y); + // cmemsg(FP_POWU, &y); return (0.0); } m = iw1 / 16; diff --git a/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdio.c b/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdio.c index 5eae37b..7b01678 100644 --- a/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdio.c +++ b/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdio.c @@ -54,22 +54,22 @@ int c_stderr = 1001; // int c_getc(FILE *f){ // } -#if defined( LUA_NUMBER_INTEGRAL ) +#if defined(LUA_NUMBER_INTEGRAL) #else //#define FLOATINGPT 1 #define NEWFP 1 #define ENDIAN_LITTLE 1234 -#define ENDIAN_BIG 4321 -#define ENDIAN_PDP 3412 +#define ENDIAN_BIG 4321 +#define ENDIAN_PDP 3412 #define ENDIAN ENDIAN_LITTLE /* $Id: strichr.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ /* * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -100,16 +100,15 @@ int c_stderr = 1001; //#include #include "c_string.h" -char * -strichr(char *p, int c) +char *strichr(char *p, int c) { char *t; - if (p != NULL) { - for(t = p; *t; t++); - for (; t >= p; t--) { - *(t + 1) = *t; - } + if (p != NULL) + { + for (t = p; *t; t++) + ; + for (; t >= p; t--) { *(t + 1) = *t; } *p = c; } return (p); @@ -119,7 +118,7 @@ strichr(char *p, int c) /* * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -159,33 +158,28 @@ strichr(char *p, int c) * Format string by inserting blanks. */ -void -str_fmt(char *p, int size, int fmt) +void str_fmt(char *p, int size, int fmt) { int n, m, len; - len = strlen (p); - switch (fmt) { - case FMT_RJUST: - for (n = size - len; n > 0; n--) - strichr (p, ' '); - break; - case FMT_LJUST: - for (m = size - len; m > 0; m--) - strcat (p, " "); - break; - case FMT_RJUST0: - for (n = size - len; n > 0; n--) - strichr (p, '0'); - break; - case FMT_CENTER: - m = (size - len) / 2; - n = size - (len + m); - for (; m > 0; m--) - strcat (p, " "); - for (; n > 0; n--) - strichr (p, ' '); - break; + len = strlen(p); + switch (fmt) + { + case FMT_RJUST: + for (n = size - len; n > 0; n--) strichr(p, ' '); + break; + case FMT_LJUST: + for (m = size - len; m > 0; m--) strcat(p, " "); + break; + case FMT_RJUST0: + for (n = size - len; n > 0; n--) strichr(p, '0'); + break; + case FMT_CENTER: + m = (size - len) / 2; + n = size - (len + m); + for (; m > 0; m--) strcat(p, " "); + for (; n > 0; n--) strichr(p, ' '); + break; } } @@ -193,7 +187,7 @@ str_fmt(char *p, int size, int fmt) /* * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -223,24 +217,22 @@ str_fmt(char *p, int size, int fmt) */ //#include //#include -#include "c_string.h" #include "c_ctype.h" +#include "c_string.h" #include "ctype.h" -void -strtoupper(unsigned char *p) +void strtoupper(unsigned char *p) { - if(!p) + if (!p) return; - for (; *p; p++) - *p = toupper (*p); + for (; *p; p++) *p = toupper(*p); } /* $Id: atob.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ /* * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -286,26 +278,28 @@ typedef double rtype; #define __P(args) args #endif -static char * _getbase __P((char *, int *)); +static char *_getbase __P((char *, int *)); static int _atob __P((unsigned long long *, char *p, int)); -static char * -_getbase(char *p, int *basep) +static char *_getbase(char *p, int *basep) { - if (p[0] == '0') { - switch (p[1]) { - case 'x': - *basep = 16; - break; - case 't': case 'n': - *basep = 10; - break; - case 'o': - *basep = 8; - break; - default: - *basep = 10; - return (p); + if (p[0] == '0') + { + switch (p[1]) + { + case 'x': + *basep = 16; + break; + case 't': + case 'n': + *basep = 10; + break; + case 'o': + *basep = 8; + break; + default: + *basep = 10; + return (p); } return (p + 2); } @@ -313,43 +307,44 @@ _getbase(char *p, int *basep) return (p); } - /* * _atob(vp,p,base) */ -static int -_atob (u_quad_t *vp, char *p, int base) +static int _atob(u_quad_t *vp, char *p, int base) { u_quad_t value, v1, v2; char *q, tmp[20]; int digit; - if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) + { base = 16; p += 2; } - if (base == 16 && (q = strchr (p, '.')) != 0) { + if (base == 16 && (q = strchr(p, '.')) != 0) + { if (q - p > sizeof(tmp) - 1) return (0); - strncpy (tmp, p, q - p); + strncpy(tmp, p, q - p); tmp[q - p] = '\0'; - if (!_atob (&v1, tmp, 16)) + if (!_atob(&v1, tmp, 16)) return (0); q++; - if (strchr (q, '.')) + if (strchr(q, '.')) return (0); - if (!_atob (&v2, q, 16)) + if (!_atob(&v2, q, 16)) return (0); *vp = (v1 << 16) + v2; return (1); } value = *vp = 0; - for (; *p; p++) { + for (; *p; p++) + { if (*p >= '0' && *p <= '9') digit = *p - '0'; else if (*p >= 'a' && *p <= 'f') @@ -369,63 +364,63 @@ _atob (u_quad_t *vp, char *p, int base) } /* - * atob(vp,p,base) + * atob(vp,p,base) * converts p to binary result in vp, rtn 1 on success */ -int -atob(u_int32_t *vp, char *p, int base) +int atob(u_int32_t *vp, char *p, int base) { u_quad_t v; if (base == 0) - p = _getbase (p, &base); - if (_atob (&v, p, base)) { + p = _getbase(p, &base); + if (_atob(&v, p, base)) + { *vp = v; return (1); } return (0); } - /* - * llatob(vp,p,base) + * llatob(vp,p,base) * converts p to binary result in vp, rtn 1 on success */ -int -llatob(u_quad_t *vp, char *p, int base) +int llatob(u_quad_t *vp, char *p, int base) { if (base == 0) - p = _getbase (p, &base); + p = _getbase(p, &base); return _atob(vp, p, base); } - /* - * char *btoa(dst,value,base) + * char *btoa(dst,value,base) * converts value to ascii, result in dst */ -char * -btoa(char *dst, u_int value, int base) +char *btoa(char *dst, u_int value, int base) { char buf[34], digit; int i, j, rem, neg; - if (value == 0) { + if (value == 0) + { dst[0] = '0'; dst[1] = 0; return (dst); } neg = 0; - if (base == -10) { + if (base == -10) + { base = 10; - if (value & (1L << 31)) { + if (value & (1L << 31)) + { value = (~value) + 1; neg = 1; } } - for (i = 0; value != 0; i++) { + for (i = 0; value != 0; i++) + { rem = value % base; value /= base; if (rem >= 0 && rem <= 9) @@ -437,41 +432,43 @@ btoa(char *dst, u_int value, int base) buf[i] = 0; if (neg) - strcat (buf, "-"); + strcat(buf, "-"); /* reverse the string */ - for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--) - dst[i] = buf[j]; + for (i = 0, j = strlen(buf) - 1; j >= 0; i++, j--) dst[i] = buf[j]; dst[i] = 0; return (dst); } /* - * char *btoa(dst,value,base) + * char *btoa(dst,value,base) * converts value to ascii, result in dst */ -char * -llbtoa(char *dst, u_quad_t value, int base) +char *llbtoa(char *dst, u_quad_t value, int base) { char buf[66], digit; int i, j, rem, neg; - if (value == 0) { + if (value == 0) + { dst[0] = '0'; dst[1] = 0; return (dst); } neg = 0; - if (base == -10) { + if (base == -10) + { base = 10; - if (value & (1LL << 63)) { + if (value & (1LL << 63)) + { value = (~value) + 1; neg = 1; } } - for (i = 0; value != 0; i++) { + for (i = 0; value != 0; i++) + { rem = value % base; value /= base; if (rem >= 0 && rem <= 9) @@ -483,27 +480,26 @@ llbtoa(char *dst, u_quad_t value, int base) buf[i] = 0; if (neg) - strcat (buf, "-"); + strcat(buf, "-"); /* reverse the string */ - for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--) - dst[i] = buf[j]; + for (i = 0, j = strlen(buf) - 1; j >= 0; i++, j--) dst[i] = buf[j]; dst[i] = 0; return (dst); } /* - * gethex(vp,p,n) - * convert n hex digits from p to binary, result in vp, + * gethex(vp,p,n) + * convert n hex digits from p to binary, result in vp, * rtn 1 on success */ -int -gethex(int32_t *vp, char *p, int n) +int gethex(int32_t *vp, char *p, int n) { u_long v; int digit; - for (v = 0; n > 0; n--) { + for (v = 0; n > 0; n--) + { if (*p == 0) return (0); if (*p >= '0' && *p <= '9') @@ -527,7 +523,7 @@ gethex(int32_t *vp, char *p, int n) /* * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -560,15 +556,14 @@ gethex(int32_t *vp, char *p, int n) //#include //#include //#include +#include "c_ctype.h" #include "c_stdarg.h" #include "c_string.h" -#include "c_ctype.h" /* * int vsprintf(d,s,ap) */ -int -vsprintf (char *d, const char *s, va_list ap) +int vsprintf(char *d, const char *s, va_list ap) { const char *t; char *p, *dst, tmp[40]; @@ -583,12 +578,15 @@ vsprintf (char *d, const char *s, va_list ap) #endif dst = d; - for (; *s;) { - if (*s == '%') { + for (; *s;) + { + if (*s == '%') + { s++; fmt = FMT_RJUST; width = trunc = haddot = longlong = 0; - for (; *s; s++) { + for (; *s; s++) + { if (strchr("bcdefgilopPrRsuxX%", *s)) break; else if (*s == '-') @@ -597,13 +595,17 @@ vsprintf (char *d, const char *s, va_list ap) fmt = FMT_RJUST0; else if (*s == '~') fmt = FMT_CENTER; - else if (*s == '*') { + else if (*s == '*') + { if (haddot) trunc = va_arg(ap, int); else width = va_arg(ap, int); - } else if (*s >= '1' && *s <= '9') { - for (t = s; isdigit(*s); s++); + } + else if (*s >= '1' && *s <= '9') + { + for (t = s; isdigit(*s); s++) + ; strncpy(tmp, t, s - t); tmp[s - t] = '\0'; atob(&n, tmp, 10); @@ -612,62 +614,83 @@ vsprintf (char *d, const char *s, va_list ap) else width = n; s--; - } else if (*s == '.') + } + else if (*s == '.') haddot = 1; } - if (*s == '%') { + if (*s == '%') + { *d++ = '%'; *d = 0; - } else if (*s == 's') { + } + else if (*s == 's') + { p = va_arg(ap, char *); if (p) strcpy(d, p); else strcpy(d, "(null)"); - } else if (*s == 'c') { - n = va_arg (ap, int); + } + else if (*s == 'c') + { + n = va_arg(ap, int); *d = n; d[1] = 0; - } else { - if (*s == 'l') { - if (*++s == 'l') { + } + else + { + if (*s == 'l') + { + if (*++s == 'l') + { longlong = 1; ++s; } } - if (strchr("bdiopPrRxXu", *s)) { + if (strchr("bdiopPrRxXu", *s)) + { if (*s == 'd' || *s == 'i') base = -10; else if (*s == 'u') base = 10; else if (*s == 'x' || *s == 'X') base = 16; - else if(*s == 'p' || *s == 'P') { + else if (*s == 'p' || *s == 'P') + { base = 16; - if (*s == 'p') { + if (*s == 'p') + { *d++ = '0'; *d++ = 'x'; } fmt = FMT_RJUST0; - if (sizeof(long) > 4) { + if (sizeof(long) > 4) + { width = 16; longlong = 1; - } else { + } + else + { width = 8; } } - else if(*s == 'r' || *s == 'R') { + else if (*s == 'r' || *s == 'R') + { base = 16; - if (*s == 'r') { + if (*s == 'r') + { *d++ = '0'; *d++ = 'x'; } fmt = FMT_RJUST0; - if (sizeof(register_t) > 4) { + if (sizeof(register_t) > 4) + { width = 16; longlong = 1; - } else { + } + else + { width = 8; } } @@ -676,18 +699,18 @@ vsprintf (char *d, const char *s, va_list ap) else if (*s == 'b') base = 2; if (longlong) - llbtoa(d, va_arg (ap, quad_t), - base); + llbtoa(d, va_arg(ap, quad_t), base); else - btoa(d, va_arg (ap, int), base); + btoa(d, va_arg(ap, int), base); if (*s == 'X') strtoupper((unsigned char *)d); } #ifdef FLOATINGPT - else if (strchr ("eEfgG", *s)) { -//static void dtoa (char *, double, int, int, int); -void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec); + else if (strchr("eEfgG", *s)) + { + // static void dtoa (char *, double, int, int, int); + void dtoa(char *dbuf, rtype arg, int fmtch, int width, int prec); dbl = va_arg(ap, double); dtoa(d, dbl, *s, width, trunc); trunc = 0; @@ -697,15 +720,17 @@ void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec); if (trunc) d[trunc] = 0; if (width) - str_fmt (d, width, fmt); - for (; *d; d++); + str_fmt(d, width, fmt); + for (; *d; d++) + ; s++; - } else + } + else *d++ = *s++; } *d = 0; return (d - dst); -} +} #ifdef FLOATINGPT /* @@ -746,67 +771,64 @@ void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec); * SUCH DAMAGE. */ - #define MAX_FCONVERSION 512 /* largest possible real conversion */ -#define MAX_EXPT 5 /* largest possible exponent field */ -#define MAX_FRACT 39 /* largest possible fraction field */ +#define MAX_EXPT 5 /* largest possible exponent field */ +#define MAX_FRACT 39 /* largest possible fraction field */ #define TESTFLAG(x) 0 - typedef double rtype; extern double modf(double, double *); -#define to_char(n) ((n) + '0') +#define to_char(n) ((n) + '0') #define to_digit(c) ((c) - '0') #define _isNan(arg) ((arg) != (arg)) -static int cvt (rtype arg, int prec, char *signp, int fmtch, - char *startp, char *endp); -static char *c_round (double fract, int *exp, char *start, char *end, - char ch, char *signp); +static int cvt(rtype arg, int prec, char *signp, int fmtch, char *startp, char *endp); +static char *c_round(double fract, int *exp, char *start, char *end, char ch, char *signp); static char *exponent(char *p, int exp, int fmtch); - /* * _finite arg not Infinity or Nan */ static int _finite(rtype d) { #if ENDIAN == ENDIAN_LITTLE - struct IEEEdp { - unsigned manl:32; - unsigned manh:20; - unsigned exp:11; - unsigned sign:1; - } *ip; + struct IEEEdp + { + unsigned manl : 32; + unsigned manh : 20; + unsigned exp : 11; + unsigned sign : 1; + } * ip; #else - struct IEEEdp { - unsigned sign:1; - unsigned exp:11; - unsigned manh:20; - unsigned manl:32; - } *ip; + struct IEEEdp + { + unsigned sign : 1; + unsigned exp : 11; + unsigned manh : 20; + unsigned manl : 32; + } * ip; #endif ip = (struct IEEEdp *)&d; return (ip->exp != 0x7ff); } - -void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec) +void dtoa(char *dbuf, rtype arg, int fmtch, int width, int prec) { - char buf[MAX_FCONVERSION+1], *cp; - char sign; + char buf[MAX_FCONVERSION + 1], *cp; + char sign; int size; - if( !_finite(arg) ) { - if( _isNan(arg) ) - strcpy (dbuf, "NaN"); - else if( arg < 0) - strcpy (dbuf, "-Infinity"); + if (!_finite(arg)) + { + if (_isNan(arg)) + strcpy(dbuf, "NaN"); + else if (arg < 0) + strcpy(dbuf, "-Infinity"); else - strcpy (dbuf, "Infinity"); + strcpy(dbuf, "Infinity"); return; } @@ -826,7 +848,7 @@ void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec) * no significant digits will be shown. */ *cp = '\0'; - size = cvt (arg, prec, &sign, fmtch, cp, buf + sizeof(buf)); + size = cvt(arg, prec, &sign, fmtch, cp, buf + sizeof(buf)); if (*cp == '\0') cp++; @@ -834,12 +856,10 @@ void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec) *--cp = sign, size++; cp[size] = 0; - memcpy (dbuf, cp, size + 1); + memcpy(dbuf, cp, size + 1); } - -static int -cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp) +static int cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp) { register char *p, *t; register double fract; @@ -847,10 +867,12 @@ cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp) int dotrim, expcnt, gformat; dotrim = expcnt = gformat = 0; - if (number < 0) { + if (number < 0) + { number = -number; *signp = '-'; - } else + } + else *signp = 0; fract = modf(number, &integer); @@ -862,171 +884,191 @@ cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp) * get integer portion of number; put into the end of the buffer; the * .01 is added for modf(356.0 / 10, &integer) returning .59999999... */ - for (p = endp - 1; integer; ++expcnt) { + for (p = endp - 1; integer; ++expcnt) + { tmp = modf(integer / 10, &integer); *p-- = to_char((int)((tmp + .01) * 10)); } - switch (fmtch) { - case 'f': - /* reverse integer into beginning of buffer */ - if (expcnt) - for (; ++p < endp; *t++ = *p); - else - *t++ = '0'; - /* - * if precision required or alternate flag set, add in a - * decimal point. - */ - if (prec || TESTFLAG(ALTERNATE_FORM)) - *t++ = '.'; - /* if requires more precision and some fraction left */ - if (fract) { - if (prec) - do { - fract = modf(fract * 10, &tmp); - *t++ = to_char((int)tmp); - } while (--prec && fract); - if (fract) - startp = c_round(fract, (int *)NULL, startp, - t - 1, (char)0, signp); - } - for (; prec--; *t++ = '0'); - break; - case 'e': - case 'E': -eformat: if (expcnt) { - *t++ = *++p; - if (prec || TESTFLAG(ALTERNATE_FORM)) - *t++ = '.'; - /* if requires more precision and some integer left */ - for (; prec && ++p < endp; --prec) - *t++ = *p; + switch (fmtch) + { + case 'f': + /* reverse integer into beginning of buffer */ + if (expcnt) + for (; ++p < endp; *t++ = *p) + ; + else + *t++ = '0'; /* - * if done precision and more of the integer component, - * round using it; adjust fract so we don't re-round - * later. + * if precision required or alternate flag set, add in a + * decimal point. */ - if (!prec && ++p < endp) { - fract = 0; - startp = c_round((double)0, &expcnt, startp, - t - 1, *p, signp); - } - /* adjust expcnt for digit in front of decimal */ - --expcnt; - } - /* until first fractional digit, decrement exponent */ - else if (fract) { - /* adjust expcnt for digit in front of decimal */ - for (expcnt = -1;; --expcnt) { - fract = modf(fract * 10, &tmp); - if (tmp) - break; - } - *t++ = to_char((int)tmp); - if (prec || TESTFLAG(ALTERNATE_FORM)) - *t++ = '.'; - } - else { - *t++ = '0'; if (prec || TESTFLAG(ALTERNATE_FORM)) *t++ = '.'; - } - /* if requires more precision and some fraction left */ - if (fract) { - if (prec) - do { - fract = modf(fract * 10, &tmp); - *t++ = to_char((int)tmp); - } while (--prec && fract); + /* if requires more precision and some fraction left */ if (fract) - startp = c_round(fract, &expcnt, startp, - t - 1, (char)0, signp); - } - /* if requires more precision */ - for (; prec--; *t++ = '0'); - - /* unless alternate flag, trim any g/G format trailing 0's */ - if (gformat && !TESTFLAG(ALTERNATE_FORM)) { - while (t > startp && *--t == '0'); - if (*t == '.') - --t; - ++t; - } - t = exponent(t, expcnt, fmtch); - break; - case 'g': - case 'G': - /* a precision of 0 is treated as a precision of 1. */ - if (!prec) - ++prec; - /* - * ``The style used depends on the value converted; style e - * will be used only if the exponent resulting from the - * conversion is less than -4 or greater than the precision.'' - * -- ANSI X3J11 - */ - if (expcnt > prec || (!expcnt && fract && fract < .0001)) { - /* - * g/G format counts "significant digits, not digits of - * precision; for the e/E format, this just causes an - * off-by-one problem, i.e. g/G considers the digit - * before the decimal point significant and e/E doesn't - * count it as precision. - */ - --prec; - fmtch -= 2; /* G->E, g->e */ - gformat = 1; - goto eformat; - } - /* - * reverse integer into beginning of buffer, - * note, decrement precision - */ - if (expcnt) - for (; ++p < endp; *t++ = *p, --prec); - else - *t++ = '0'; - /* - * if precision required or alternate flag set, add in a - * decimal point. If no digits yet, add in leading 0. - */ - if (prec || TESTFLAG(ALTERNATE_FORM)) { - dotrim = 1; - *t++ = '.'; - } - else - dotrim = 0; - /* if requires more precision and some fraction left */ - if (fract) { - if (prec) { - do { - fract = modf(fract * 10, &tmp); - *t++ = to_char((int)tmp); - } while(!tmp && !expcnt); - while (--prec && fract) { + { + if (prec) + do + { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (--prec && fract); + if (fract) + startp = c_round(fract, (int *)NULL, startp, t - 1, (char)0, signp); + } + for (; prec--; *t++ = '0') + ; + break; + case 'e': + case 'E': + eformat: + if (expcnt) + { + *t++ = *++p; + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + /* if requires more precision and some integer left */ + for (; prec && ++p < endp; --prec) *t++ = *p; + /* + * if done precision and more of the integer component, + * round using it; adjust fract so we don't re-round + * later. + */ + if (!prec && ++p < endp) + { + fract = 0; + startp = c_round((double)0, &expcnt, startp, t - 1, *p, signp); + } + /* adjust expcnt for digit in front of decimal */ + --expcnt; + } + /* until first fractional digit, decrement exponent */ + else if (fract) + { + /* adjust expcnt for digit in front of decimal */ + for (expcnt = -1;; --expcnt) + { fract = modf(fract * 10, &tmp); - *t++ = to_char((int)tmp); + if (tmp) + break; } + *t++ = to_char((int)tmp); + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + } + else + { + *t++ = '0'; + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; } + /* if requires more precision and some fraction left */ if (fract) - startp = c_round(fract, (int *)NULL, startp, - t - 1, (char)0, signp); - } - /* alternate format, adds 0's for precision, else trim 0's */ - if (TESTFLAG(ALTERNATE_FORM)) - for (; prec--; *t++ = '0'); - else if (dotrim) { - while (t > startp && *--t == '0'); - if (*t != '.') + { + if (prec) + do + { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (--prec && fract); + if (fract) + startp = c_round(fract, &expcnt, startp, t - 1, (char)0, signp); + } + /* if requires more precision */ + for (; prec--; *t++ = '0') + ; + + /* unless alternate flag, trim any g/G format trailing 0's */ + if (gformat && !TESTFLAG(ALTERNATE_FORM)) + { + while (t > startp && *--t == '0') + ; + if (*t == '.') + --t; ++t; - } + } + t = exponent(t, expcnt, fmtch); + break; + case 'g': + case 'G': + /* a precision of 0 is treated as a precision of 1. */ + if (!prec) + ++prec; + /* + * ``The style used depends on the value converted; style e + * will be used only if the exponent resulting from the + * conversion is less than -4 or greater than the precision.'' + * -- ANSI X3J11 + */ + if (expcnt > prec || (!expcnt && fract && fract < .0001)) + { + /* + * g/G format counts "significant digits, not digits of + * precision; for the e/E format, this just causes an + * off-by-one problem, i.e. g/G considers the digit + * before the decimal point significant and e/E doesn't + * count it as precision. + */ + --prec; + fmtch -= 2; /* G->E, g->e */ + gformat = 1; + goto eformat; + } + /* + * reverse integer into beginning of buffer, + * note, decrement precision + */ + if (expcnt) + for (; ++p < endp; *t++ = *p, --prec) + ; + else + *t++ = '0'; + /* + * if precision required or alternate flag set, add in a + * decimal point. If no digits yet, add in leading 0. + */ + if (prec || TESTFLAG(ALTERNATE_FORM)) + { + dotrim = 1; + *t++ = '.'; + } + else + dotrim = 0; + /* if requires more precision and some fraction left */ + if (fract) + { + if (prec) + { + do + { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (!tmp && !expcnt); + while (--prec && fract) + { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } + } + if (fract) + startp = c_round(fract, (int *)NULL, startp, t - 1, (char)0, signp); + } + /* alternate format, adds 0's for precision, else trim 0's */ + if (TESTFLAG(ALTERNATE_FORM)) + for (; prec--; *t++ = '0') + ; + else if (dotrim) + { + while (t > startp && *--t == '0') + ; + if (*t != '.') + ++t; + } } return (t - startp); } - -static char * -c_round(double fract, int *exp, char *start, char *end, char ch, char *signp) +static char *c_round(double fract, int *exp, char *start, char *end, char ch, char *signp) { double tmp; @@ -1035,27 +1077,32 @@ c_round(double fract, int *exp, char *start, char *end, char ch, char *signp) else tmp = to_digit(ch); if (tmp > 4) - for (;; --end) { + for (;; --end) + { if (*end == '.') --end; if (++*end <= '9') break; *end = '0'; - if (end == start) { - if (exp) { /* e/E; increment exponent */ + if (end == start) + { + if (exp) + { /* e/E; increment exponent */ *end = '1'; ++*exp; } - else { /* f; add extra digit */ - *--end = '1'; - --start; + else + { /* f; add extra digit */ + *--end = '1'; + --start; } break; } } /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ else if (*signp == '-') - for (;; --end) { + for (;; --end) + { if (*end == '.') --end; if (*end != '0') @@ -1066,28 +1113,32 @@ c_round(double fract, int *exp, char *start, char *end, char ch, char *signp) return (start); } -static char * -exponent(char *p, int exp, int fmtch) +static char *exponent(char *p, int exp, int fmtch) { char *t; char expbuf[MAX_FCONVERSION]; *p++ = fmtch; - if (exp < 0) { + if (exp < 0) + { exp = -exp; *p++ = '-'; } else *p++ = '+'; t = expbuf + MAX_FCONVERSION; - if (exp > 9) { - do { + if (exp > 9) + { + do + { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); - for (; t < expbuf + MAX_FCONVERSION; *p++ = *t++); + for (; t < expbuf + MAX_FCONVERSION; *p++ = *t++) + ; } - else { + else + { *p++ = '0'; *p++ = to_char(exp); } @@ -1095,7 +1146,6 @@ exponent(char *p, int exp, int fmtch) } #endif /* FLOATINGPT */ - void c_sprintf(char *s, char *fmt, ...) { va_list arg; diff --git a/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdlib.c b/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdlib.c index c54bf4a..6230e23 100644 --- a/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdlib.c +++ b/LuaNode_Esp32/LuaNode32/components/mylibc/c_stdlib.c @@ -3,19 +3,18 @@ #ifdef LUA_CROSS_COMPILER -#include #include +#include #include -#define TRUE 1 +#define TRUE 1 #define FALSE 0 #else -#include "ctype.h" - #include "c_stdlib.h" -#include "c_types.h" #include "c_string.h" +#include "c_types.h" +#include "ctype.h" // const char *lua_init_value = "print(\"Hello world\")"; const char *lua_init_value = "@init.lua"; @@ -33,8 +32,8 @@ const char *c_getenv(const char *__string) } return NULL; } -// make sure there is enough memory before real malloc, otherwise malloc will panic and reset -// void *c_malloc(size_t __size){ +// make sure there is enough memory before real malloc, otherwise malloc will +// panic and reset void *c_malloc(size_t __size){ // if(__size>system_get_free_heap_size()){ // NODE_ERR("malloc: not enough memory\n"); // return NULL; @@ -56,8 +55,6 @@ const char *c_getenv(const char *__string) // // NODE_ERR("-free1: %d\n", system_get_free_heap_size()); // }c_stdlib.s - - // int c_rand(void){ // } // void c_srand(unsigned int __seed){ @@ -69,56 +66,46 @@ const char *c_getenv(const char *__string) //#include //#include "mprec.h" #endif -double powersOf10[] ICACHE_STORE_ATTR = /* Table giving binary powers of 10. Entry */ -{ - 10., /* is 10^2^i. Used to convert decimal */ - 100., /* exponents into floating-point numbers. */ - 1.0e4, - 1.0e8, - 1.0e16, - 1.0e32, - 1.0e64, - 1.0e128, - 1.0e256 -}; +double powersOf10[] ICACHE_STORE_ATTR = /* Table giving binary powers of 10. + Entry */ + {10., /* is 10^2^i. Used to convert decimal */ + 100., /* exponents into floating-point numbers. */ + 1.0e4, 1.0e8, 1.0e16, 1.0e32, 1.0e64, 1.0e128, 1.0e256}; double c_strtod(const char *string, char **endPtr) { - int maxExponent = 511; /* Largest possible base 10 exponent. Any - * exponent larger than this will already - * produce underflow or overflow, so there's - * no need to worry about additional digits. - */ + int maxExponent = 511; /* Largest possible base 10 exponent. Any + * exponent larger than this will already + * produce underflow or overflow, so there's + * no need to worry about additional digits. + */ int sign, expSign = FALSE; double fraction, dblExp, *d; register const char *p; register int c; - int exp = 0; /* Exponent read from "EX" field. */ - int fracExp = 0; /* Exponent that derives from the fractional - * part. Under normal circumstatnces, it is - * the negative of the number of digits in F. - * However, if I is very long, the last digits - * of I get dropped (otherwise a long I with a - * large negative exponent could cause an - * unnecessary overflow on I alone). In this - * case, fracExp is incremented one for each - * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal - * point. */ - const char *pExp; /* Temporarily holds location of exponent - * in string. */ + int exp = 0; /* Exponent read from "EX" field. */ + int fracExp = 0; /* Exponent that derives from the fractional + * part. Under normal circumstatnces, it is + * the negative of the number of digits in F. + * However, if I is very long, the last digits + * of I get dropped (otherwise a long I with a + * large negative exponent could cause an + * unnecessary overflow on I alone). In this + * case, fracExp is incremented one for each + * dropped digit. */ + int mantSize; /* Number of digits in mantissa. */ + int decPt; /* Number of mantissa digits BEFORE decimal + * point. */ + const char *pExp; /* Temporarily holds location of exponent + * in string. */ /* * Strip off leading blanks and check for a sign. */ p = string; - while (isspace((unsigned char)(*p))) - { - p += 1; - } + while (isspace((unsigned char)(*p))) { p += 1; } if (*p == '-') { sign = TRUE; @@ -139,7 +126,7 @@ double c_strtod(const char *string, char **endPtr) */ decPt = -1; - for (mantSize = 0; ; mantSize += 1) + for (mantSize = 0;; mantSize += 1) { c = *p; if (!isdigit(c)) @@ -160,7 +147,7 @@ double c_strtod(const char *string, char **endPtr) * they can't affect the value anyway. */ - pExp = p; + pExp = p; p -= mantSize; if (decPt < 0) { @@ -168,7 +155,7 @@ double c_strtod(const char *string, char **endPtr) } else { - mantSize -= 1; /* One of the digits was the point. */ + mantSize -= 1; /* One of the digits was the point. */ } if (mantSize > 18) { @@ -189,7 +176,7 @@ double c_strtod(const char *string, char **endPtr) { int frac1, frac2; frac1 = 0; - for ( ; mantSize > 9; mantSize -= 1) + for (; mantSize > 9; mantSize -= 1) { c = *p; p += 1; @@ -297,7 +284,7 @@ double c_strtod(const char *string, char **endPtr) done: if (endPtr != NULL) { - *endPtr = (char *) p; + *endPtr = (char *)p; } if (sign) diff --git a/LuaNode_Esp32/LuaNode32/components/platform/flash_api.c b/LuaNode_Esp32/LuaNode32/components/platform/flash_api.c index 2591000..7a521a5 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/flash_api.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/flash_api.c @@ -2,103 +2,106 @@ * Flash api for NodeMCU * NodeMCU Team * 2014-12-31 -*******************************************************************************/ + *******************************************************************************/ #include "flash_api.h" + #include -#include #include -#include "rom/spi_flash.h" +#include -#include "esp_image_format.h" #include "esp_flash_data_types.h" +#include "esp_image_format.h" +#include "rom/spi_flash.h" #include "user_config.h" #define FLASH_HDR_ADDR 0x1000 -static inline esp_image_header_t flash_load_rom_header (void) +static inline esp_image_header_t flash_load_rom_header(void) { - esp_image_header_t hdr; - if (ESP_OK != - spi_flash_read (FLASH_HDR_ADDR, (uint32_t *)&hdr, sizeof (hdr))) - { - NODE_ERR("Failed to load flash header block!\n"); - abort(); - } - return hdr; + esp_image_header_t hdr; + if (ESP_OK != spi_flash_read(FLASH_HDR_ADDR, (uint32_t *)&hdr, sizeof(hdr))) + { + NODE_ERR("Failed to load flash header block!\n"); + abort(); + } + return hdr; } #define IRAM_SECTION __attribute__((section(".iram1"))) -static void IRAM_SECTION update_flash_chip_size (uint32_t sz) +static void IRAM_SECTION update_flash_chip_size(uint32_t sz) { - /*SPIParamCfg ( - g_rom_flashchip.deviceId, - sz, - g_rom_flashchip.block_size, - g_rom_flashchip.sector_size, - g_rom_flashchip.page_size, - g_rom_flashchip.status_mask);*/ - //SPIParamCfg (0x1540ef, sz, 64*1024, 4096, 256, 0xffff); + /*SPIParamCfg ( + g_rom_flashchip.deviceId, + sz, + g_rom_flashchip.block_size, + g_rom_flashchip.sector_size, + g_rom_flashchip.page_size, + g_rom_flashchip.status_mask);*/ + // SPIParamCfg (0x1540ef, sz, 64*1024, 4096, 256, 0xffff); esp_rom_spiflash_config_param(g_rom_flashchip.device_id, sz, 0x10000, 0x1000, 0x100, 0xffff); } static uint32_t __attribute__((section(".iram1"))) flash_detect_size_byte(void) { #define DETECT_SZ 32 - uint32_t detected_size = FLASH_SIZE_1MBYTE; - uint8_t data_orig[DETECT_SZ] PLATFORM_ALIGNMENT = {0}; - uint8_t data_new[DETECT_SZ] PLATFORM_ALIGNMENT = {0}; - // Ensure we read something which isn't just 0xff... - const uint32_t offs = ESP_PARTITION_TABLE_ADDR; - // Detect read failure or wrap-around on flash read to find end of flash - if (ESP_OK == spi_flash_read (offs, (uint32_t *)data_orig, DETECT_SZ)) - { - update_flash_chip_size (FLASH_SIZE_16MBYTE); - while ((detected_size < FLASH_SIZE_16MBYTE) && - (ESP_OK == spi_flash_read ( - detected_size + offs, (uint32_t *)data_new, DETECT_SZ)) && - (0 != memcmp(data_orig, data_new, DETECT_SZ))) + uint32_t detected_size = FLASH_SIZE_1MBYTE; + uint8_t data_orig[DETECT_SZ] PLATFORM_ALIGNMENT = {0}; + uint8_t data_new[DETECT_SZ] PLATFORM_ALIGNMENT = {0}; + // Ensure we read something which isn't just 0xff... + const uint32_t offs = ESP_PARTITION_TABLE_ADDR; + // Detect read failure or wrap-around on flash read to find end of flash + if (ESP_OK == spi_flash_read(offs, (uint32_t *)data_orig, DETECT_SZ)) { - detected_size *= 2; - } - - update_flash_chip_size (detected_size); - }; - return detected_size; + update_flash_chip_size(FLASH_SIZE_16MBYTE); + while ((detected_size < FLASH_SIZE_16MBYTE) && + (ESP_OK == spi_flash_read(detected_size + offs, (uint32_t *)data_new, DETECT_SZ)) && + (0 != memcmp(data_orig, data_new, DETECT_SZ))) + { detected_size *= 2; } + + update_flash_chip_size(detected_size); + }; + return detected_size; #undef FLASH_BUFFER_SIZE_DETECT } uint32_t flash_safe_get_size_byte(void) { - static uint32_t flash_size = 0; - if (flash_size == 0) - { - flash_size = flash_detect_size_byte(); - } - return flash_size; + static uint32_t flash_size = 0; + if (flash_size == 0) + { + flash_size = flash_detect_size_byte(); + } + return flash_size; } - -uint16_t flash_safe_get_sec_num(void) -{ - return (flash_safe_get_size_byte() / (SPI_FLASH_SEC_SIZE)); -} +uint16_t flash_safe_get_sec_num(void) { return (flash_safe_get_size_byte() / (SPI_FLASH_SEC_SIZE)); } uint32_t flash_rom_get_size_byte(void) { - static uint32_t flash_size = 0; - if (flash_size == 0) - { - switch (flash_load_rom_header ().spi_size) + static uint32_t flash_size = 0; + if (flash_size == 0) { - default: // Unknown flash size, fall back mode. - case ESP_IMAGE_FLASH_SIZE_1MB: flash_size = FLASH_SIZE_1MBYTE; break; - case ESP_IMAGE_FLASH_SIZE_2MB: flash_size = FLASH_SIZE_2MBYTE; break; - case ESP_IMAGE_FLASH_SIZE_4MB: flash_size = FLASH_SIZE_4MBYTE; break; - case ESP_IMAGE_FLASH_SIZE_8MB: flash_size = FLASH_SIZE_8MBYTE; break; - case ESP_IMAGE_FLASH_SIZE_16MB: flash_size = FLASH_SIZE_16MBYTE; break; + switch (flash_load_rom_header().spi_size) + { + default: // Unknown flash size, fall back mode. + case ESP_IMAGE_FLASH_SIZE_1MB: + flash_size = FLASH_SIZE_1MBYTE; + break; + case ESP_IMAGE_FLASH_SIZE_2MB: + flash_size = FLASH_SIZE_2MBYTE; + break; + case ESP_IMAGE_FLASH_SIZE_4MB: + flash_size = FLASH_SIZE_4MBYTE; + break; + case ESP_IMAGE_FLASH_SIZE_8MB: + flash_size = FLASH_SIZE_8MBYTE; + break; + case ESP_IMAGE_FLASH_SIZE_16MB: + flash_size = FLASH_SIZE_16MBYTE; + break; + } } - } - return flash_size; + return flash_size; } static bool flash_rom_set_size_type(uint8_t size_code) @@ -107,28 +110,27 @@ static bool flash_rom_set_size_type(uint8_t size_code) // Reboot required!!! // If you don't know what you're doing, your nodemcu may turn into stone ... NODE_DBG("\nBEGIN SET FLASH HEADER\n"); - esp_image_header_t *hdr = (esp_image_header_t *)malloc (SPI_FLASH_SEC_SIZE); + esp_image_header_t *hdr = (esp_image_header_t *)malloc(SPI_FLASH_SEC_SIZE); if (!hdr) - return false; + return false; - if (ESP_OK == spi_flash_read (FLASH_HDR_ADDR, (uint32_t *)hdr, SPI_FLASH_SEC_SIZE)) + if (ESP_OK == spi_flash_read(FLASH_HDR_ADDR, (uint32_t *)hdr, SPI_FLASH_SEC_SIZE)) { - hdr->spi_size = size_code; - if (ESP_OK == spi_flash_erase_sector (FLASH_HDR_ADDR / SPI_FLASH_SEC_SIZE)) - { - NODE_DBG("\nERASE SUCCESS\n"); - } - if (ESP_OK == spi_flash_write(FLASH_HDR_ADDR, (uint32_t *)hdr, SPI_FLASH_SEC_SIZE)) - { - NODE_DBG("\nWRITE SUCCESS, %u\n", size_code); - } + hdr->spi_size = size_code; + if (ESP_OK == spi_flash_erase_sector(FLASH_HDR_ADDR / SPI_FLASH_SEC_SIZE)) + { + NODE_DBG("\nERASE SUCCESS\n"); + } + if (ESP_OK == spi_flash_write(FLASH_HDR_ADDR, (uint32_t *)hdr, SPI_FLASH_SEC_SIZE)) + { + NODE_DBG("\nWRITE SUCCESS, %u\n", size_code); + } } - free (hdr); + free(hdr); NODE_DBG("\nEND SET FLASH HEADER\n"); return true; } - bool flash_rom_set_size_byte(uint32_t size) { // Dangerous, here are dinosaur infested!!!!! @@ -137,40 +139,48 @@ bool flash_rom_set_size_byte(uint32_t size) uint8_t size_code = 0; switch (size) { - case FLASH_SIZE_1MBYTE: size_code = ESP_IMAGE_FLASH_SIZE_1MB; break; - case FLASH_SIZE_2MBYTE: size_code = ESP_IMAGE_FLASH_SIZE_2MB; break; - case FLASH_SIZE_4MBYTE: size_code = ESP_IMAGE_FLASH_SIZE_4MB; break; - case FLASH_SIZE_8MBYTE: size_code = ESP_IMAGE_FLASH_SIZE_8MB; break; - case FLASH_SIZE_16MBYTE: size_code = ESP_IMAGE_FLASH_SIZE_16MB; break; - default: ok = false; break; + case FLASH_SIZE_1MBYTE: + size_code = ESP_IMAGE_FLASH_SIZE_1MB; + break; + case FLASH_SIZE_2MBYTE: + size_code = ESP_IMAGE_FLASH_SIZE_2MB; + break; + case FLASH_SIZE_4MBYTE: + size_code = ESP_IMAGE_FLASH_SIZE_4MB; + break; + case FLASH_SIZE_8MBYTE: + size_code = ESP_IMAGE_FLASH_SIZE_8MB; + break; + case FLASH_SIZE_16MBYTE: + size_code = ESP_IMAGE_FLASH_SIZE_16MB; + break; + default: + ok = false; + break; } if (ok) - ok = flash_rom_set_size_type (size_code); + ok = flash_rom_set_size_type(size_code); return ok; } +uint16_t flash_rom_get_sec_num(void) { return (flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE)); } -uint16_t flash_rom_get_sec_num(void) -{ - return ( flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE) ); -} - - -uint8_t flash_rom_get_mode(void) -{ - return flash_load_rom_header ().spi_mode; -} - +uint8_t flash_rom_get_mode(void) { return flash_load_rom_header().spi_mode; } uint32_t flash_rom_get_speed(void) { - switch (flash_load_rom_header ().spi_speed) - { - case ESP_IMAGE_SPI_SPEED_40M: return 40000000; - case ESP_IMAGE_SPI_SPEED_26M: return 26700000; // TODO: verify 26.7MHz - case ESP_IMAGE_SPI_SPEED_20M: return 20000000; - case ESP_IMAGE_SPI_SPEED_80M: return 80000000; - default: break; - } - return 0; + switch (flash_load_rom_header().spi_speed) + { + case ESP_IMAGE_SPI_SPEED_40M: + return 40000000; + case ESP_IMAGE_SPI_SPEED_26M: + return 26700000; // TODO: verify 26.7MHz + case ESP_IMAGE_SPI_SPEED_20M: + return 20000000; + case ESP_IMAGE_SPI_SPEED_80M: + return 80000000; + default: + break; + } + return 0; } diff --git a/LuaNode_Esp32/LuaNode32/components/platform/flash_fs.c b/LuaNode_Esp32/LuaNode32/components/platform/flash_fs.c index ad0e662..f468532 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/flash_fs.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/flash_fs.c @@ -1,32 +1,39 @@ #include "flash_fs.h" + #include "c_string.h" -#if defined( BUILD_WOFS ) +#if defined(BUILD_WOFS) #include "romfs.h" -#elif defined( BUILD_SPIFFS ) +#elif defined(BUILD_SPIFFS) #include "spiffs.h" #endif -int fs_mode2flag(const char *mode){ - if(c_strlen(mode)==1){ - if(c_strcmp(mode,"w")==0) - return FS_WRONLY|FS_CREAT|FS_TRUNC; - else if(c_strcmp(mode, "r")==0) - return FS_RDONLY; - else if(c_strcmp(mode, "a")==0) - return FS_WRONLY|FS_CREAT|FS_APPEND; - else - return FS_RDONLY; - } else if (c_strlen(mode)==2){ - if(c_strcmp(mode,"r+")==0) - return FS_RDWR; - else if(c_strcmp(mode, "w+")==0) - return FS_RDWR|FS_CREAT|FS_TRUNC; - else if(c_strcmp(mode, "a+")==0) - return FS_RDWR|FS_CREAT|FS_APPEND; - else - return FS_RDONLY; - } else { - return FS_RDONLY; - } +int fs_mode2flag(const char *mode) +{ + if (c_strlen(mode) == 1) + { + if (c_strcmp(mode, "w") == 0) + return FS_WRONLY | FS_CREAT | FS_TRUNC; + else if (c_strcmp(mode, "r") == 0) + return FS_RDONLY; + else if (c_strcmp(mode, "a") == 0) + return FS_WRONLY | FS_CREAT | FS_APPEND; + else + return FS_RDONLY; + } + else if (c_strlen(mode) == 2) + { + if (c_strcmp(mode, "r+") == 0) + return FS_RDWR; + else if (c_strcmp(mode, "w+") == 0) + return FS_RDWR | FS_CREAT | FS_TRUNC; + else if (c_strcmp(mode, "a+") == 0) + return FS_RDWR | FS_CREAT | FS_APPEND; + else + return FS_RDONLY; + } + else + { + return FS_RDONLY; + } } diff --git a/LuaNode_Esp32/LuaNode32/components/platform/pin_map.c b/LuaNode_Esp32/LuaNode32/components/platform/pin_map.c index a0370e2..8424391 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/pin_map.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/pin_map.c @@ -1,7 +1,8 @@ #include "pin_map.h" -#include "soc/soc.h" + #include "extras/soc_ext.h" #include "soc/io_mux_reg.h" +#include "soc/soc.h" #if 0 uint32_t pin_mux[GPIO_PIN_NUM] = {PERIPHS_IO_MUX_MTDI_U, PERIPHS_IO_MUX_MTCK_U, PERIPHS_IO_MUX_MTMS_U, PERIPHS_IO_MUX_MTDO_U, @@ -23,26 +24,22 @@ GPIO_INT_TYPE pin_int_type[GPIO_PIN_NUM] = { GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE}; #endif #else -uint32_t pin_mux[GPIO_PIN_NUM] = {PAD_XPD_DCDC_CONF, PERIPHS_IO_MUX_GPIO5_U, PERIPHS_IO_MUX_GPIO4_U, PERIPHS_IO_MUX_GPIO0_U, - PERIPHS_IO_MUX_GPIO2_U, PERIPHS_IO_MUX_MTMS_U, PERIPHS_IO_MUX_MTDI_U, PERIPHS_IO_MUX_MTCK_U, - PERIPHS_IO_MUX_MTDO_U, PERIPHS_IO_MUX_U0RXD_U, PERIPHS_IO_MUX_U0TXD_U, PERIPHS_IO_MUX_SD_DATA2_U, - PERIPHS_IO_MUX_SD_DATA3_U }; +uint32_t pin_mux[GPIO_PIN_NUM] = {PAD_XPD_DCDC_CONF, PERIPHS_IO_MUX_GPIO5_U, PERIPHS_IO_MUX_GPIO4_U, + PERIPHS_IO_MUX_GPIO0_U, PERIPHS_IO_MUX_GPIO2_U, PERIPHS_IO_MUX_MTMS_U, + PERIPHS_IO_MUX_MTDI_U, PERIPHS_IO_MUX_MTCK_U, PERIPHS_IO_MUX_MTDO_U, + PERIPHS_IO_MUX_U0RXD_U, PERIPHS_IO_MUX_U0TXD_U, PERIPHS_IO_MUX_SD_DATA2_U, + PERIPHS_IO_MUX_SD_DATA3_U}; -uint8_t pin_num[GPIO_PIN_NUM] = {16, 5, 4, 0, - 2, 14, 12, 13, - 15, 3, 1, 9, - 10}; +uint8_t pin_num[GPIO_PIN_NUM] = {16, 5, 4, 0, 2, 14, 12, 13, 15, 3, 1, 9, 10}; -uint8_t pin_func[GPIO_PIN_NUM] = {0, FUNC_GPIO5, FUNC_GPIO4, FUNC_GPIO0, - FUNC_GPIO2, FUNC_GPIO14, FUNC_GPIO12, FUNC_GPIO13, - FUNC_GPIO15, FUNC_GPIO3, FUNC_GPIO1, FUNC_GPIO9, - FUNC_GPIO10}; +uint8_t pin_func[GPIO_PIN_NUM] = {0, FUNC_GPIO5, FUNC_GPIO4, FUNC_GPIO0, FUNC_GPIO2, + FUNC_GPIO14, FUNC_GPIO12, FUNC_GPIO13, FUNC_GPIO15, FUNC_GPIO3, + FUNC_GPIO1, FUNC_GPIO9, FUNC_GPIO10}; #ifdef GPIO_INTERRUPT_ENABLE GPIO_INT_TYPE pin_int_type[GPIO_PIN_NUM] = { - GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, - GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, - GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, - GPIO_PIN_INTR_DISABLE}; + GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, + GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, + GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE, GPIO_PIN_INTR_DISABLE}; #endif #endif diff --git a/LuaNode_Esp32/LuaNode32/components/platform/platform.c b/LuaNode_Esp32/LuaNode32/components/platform/platform.c index 5eb2240..8b85b4a 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/platform.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/platform.c @@ -1,53 +1,54 @@ // Platform-dependent functions #include "platform.h" + #include "c_stdio.h" -#include "c_string.h" #include "c_stdlib.h" -#include "rom/gpio.h" -#include "mygpio.h" -#include "user_config.h" -#include "rom/uart.h" -#include "rom/spi_flash.h" -#include "rom/ets_sys.h" -#include "soc/soc.h" -#include "extras/soc_ext.h" -#include "platform_partition.h" -#include "driver/ledc.h" -#include "driver/i2c.h" +#include "c_string.h" #include "driver/gpio.h" +#include "driver/i2c.h" +#include "driver/ledc.h" #include "driver/timer.h" +#include "esp_log.h" +#include "extras/soc_ext.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/queue.h" -#include "esp_log.h" +#include "freertos/task.h" +#include "mygpio.h" +#include "platform_partition.h" +#include "rom/ets_sys.h" +#include "rom/gpio.h" +#include "rom/spi_flash.h" +#include "rom/uart.h" +#include "soc/soc.h" #include "soc/uart_struct.h" +#include "user_config.h" // Platform specific includes -#include "rom.h" #include "gpio16.h" #include "i2c_master.h" +#include "rom.h" //#include "spi_api.h" -#include "pin_map.h" #include #include +#include "pin_map.h" uint16_t flash_safe_get_sec_num(void); -#define FLASH_SEC_NUM (flash_safe_get_sec_num()) -#define SYS_PARAM_SEC_NUM 4 -#define SYS_PARAM_SEC_START (FLASH_SEC_NUM - SYS_PARAM_SEC_NUM) +#define FLASH_SEC_NUM (flash_safe_get_sec_num()) +#define SYS_PARAM_SEC_NUM 4 +#define SYS_PARAM_SEC_START (FLASH_SEC_NUM - SYS_PARAM_SEC_NUM) -#define DATA_LENGTH 512 /*!= NUM_GPIO) - return -1; - ETS_GPIO_INTR_DISABLE(); - //clear interrupt status - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin])); - pin_int_type[pin] = type; - //enable interrupt - gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), type); - ETS_GPIO_INTR_ENABLE(); - return 0; + if (pin >= NUM_GPIO) + return -1; + ETS_GPIO_INTR_DISABLE(); + // clear interrupt status + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(pin_num[pin])); + pin_int_type[pin] = type; + // enable interrupt + gpio_pin_intr_state_set(GPIO_ID_PIN(pin_num[pin]), type); + ETS_GPIO_INTR_ENABLE(); + return 0; } #endif @@ -198,62 +200,68 @@ int platform_gpio_intr_init( unsigned pin, GPIO_INT_TYPE type ) static void my_uart_task(void *pvParameters) { - int uart_num = (int) pvParameters; + int uart_num = (int)pvParameters; uart_event_t event; size_t buffered_size; - uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE); - for(;;) { - //Waiting for UART event. - if(xQueueReceive(uart1_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + uint8_t *dtmp = (uint8_t *)malloc(BUF_SIZE); + for (;;) + { + // Waiting for UART event. + if (xQueueReceive(uart1_queue, (void *)&event, (portTickType)portMAX_DELAY)) + { ESP_LOGI(TAG, "uart[%d] event:", uart_num); - switch(event.type) { - //Event of UART receving data - /*We'd better handler data event fast, there would be much more data events than - other types of events. If we take too much time on data event, the queue might - be full. - in this example, we don't process data in event, but read data outside.*/ + switch (event.type) + { + // Event of UART receving data + /*We'd better handler data event fast, there would be much more + data events than other types of events. If we take too much time + on data event, the queue might be full. in this example, we + don't process data in event, but read data outside.*/ case UART_DATA: uart_get_buffered_data_len(uart_num, &buffered_size); ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); - uint8_t data[512] = {0}; - int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); - if(len > 0) { - ESP_LOGI(TAG, "uart read : %d", len); - uart_write_bytes(uart_num, (const char*)data, len); - } + uint8_t data[512] = {0}; + int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); + if (len > 0) + { + ESP_LOGI(TAG, "uart read : %d", len); + uart_write_bytes(uart_num, (const char *)data, len); + } break; - //Event of HW FIFO overflow detected + // Event of HW FIFO overflow detected case UART_FIFO_OVF: ESP_LOGI(TAG, "hw fifo overflow\n"); - //If fifo overflow happened, you should consider adding flow control for your application. - //We can read data out out the buffer, or directly flush the rx buffer. + // If fifo overflow happened, you should consider adding + // flow control for your application. We can read data out + // out the buffer, or directly flush the rx buffer. uart_flush(uart_num); break; - //Event of UART ring buffer full + // Event of UART ring buffer full case UART_BUFFER_FULL: ESP_LOGI(TAG, "ring buffer full\n"); - //If buffer full happened, you should consider encreasing your buffer size - //We can read data out out the buffer, or directly flush the rx buffer. + // If buffer full happened, you should consider encreasing + // your buffer size We can read data out out the buffer, or + // directly flush the rx buffer. uart_flush(uart_num); break; - //Event of UART RX break detected + // Event of UART RX break detected case UART_BREAK: ESP_LOGI(TAG, "uart rx break\n"); break; - //Event of UART parity check error + // Event of UART parity check error case UART_PARITY_ERR: ESP_LOGI(TAG, "uart parity error\n"); break; - //Event of UART frame error + // Event of UART frame error case UART_FRAME_ERR: ESP_LOGI(TAG, "uart frame error\n"); break; - //UART_PATTERN_DET + // UART_PATTERN_DET case UART_PATTERN_DET: ESP_LOGI(TAG, "uart pattern detected\n"); break; - //Others + // Others default: ESP_LOGI(TAG, "uart event type: %d\n", event.type); break; @@ -265,63 +273,64 @@ static void my_uart_task(void *pvParameters) vTaskDelete(NULL); } -uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int parity, int stopbits, int flow, int txd, int rxd, int rts, int cts ) +uint32_t platform_uart_setup(unsigned id, uint32_t baud, int databits, int parity, int stopbits, int flow, int txd, + int rxd, int rts, int cts) { - int uart_num = id; - uart_config_t uart_config; + int uart_num = id; + uart_config_t uart_config; - uart_config.baud_rate = baud; - uart_config.data_bits = databits; - uart_config.parity = parity; - uart_config.stop_bits = stopbits; - uart_config.flow_ctrl = flow; - uart_config.rx_flow_ctrl_thresh = 122; + uart_config.baud_rate = baud; + uart_config.data_bits = databits; + uart_config.parity = parity; + uart_config.stop_bits = stopbits; + uart_config.flow_ctrl = flow; + uart_config.rx_flow_ctrl_thresh = 122; - //Configure UART1 parameters - uart_param_config(uart_num, &uart_config); - //Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19) - uart_set_pin(uart_num, txd, rxd, rts, cts); - //Install UART driver( We don't need an event queue here) - //In this example we don't even use a buffer for sending data. - uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart1_queue, 0); + // Configure UART1 parameters + uart_param_config(uart_num, &uart_config); + // Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19) + uart_set_pin(uart_num, txd, rxd, rts, cts); + // Install UART driver( We don't need an event queue here) + // In this example we don't even use a buffer for sending data. + uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart1_queue, 0); - uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); - //Create a task to handler UART event from ISR - xTaskCreate(my_uart_task, "my_uart_task", 2048, (void*)uart_num, 16, &xHandle ); - //xTaskCreate(my_recv_task, "my_recv_task", 2048, (void*)uart_num, 16, &recvHandle ); - //process data + uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); + // Create a task to handler UART event from ISR + xTaskCreate(my_uart_task, "my_uart_task", 2048, (void *)uart_num, 16, &xHandle); + // xTaskCreate(my_recv_task, "my_recv_task", 2048, (void*)uart_num, 16, + // &recvHandle ); process data - return baud; + return baud; } // if set=1, then alternate serial output pins are used. (15=rx, 13=tx) -void platform_uart_alt( int set ) +void platform_uart_alt(int set) { // deprecated return; } - // Send: version with and without mux -void platform_uart_send( unsigned id, u8 *data, unsigned len ) +void platform_uart_send(unsigned id, u8 *data, unsigned len) { - //uart_tx_one_char(data); - uart_write_bytes(id, (const char*)data, len); - //printf("%c", data); + // uart_tx_one_char(data); + uart_write_bytes(id, (const char *)data, len); + // printf("%c", data); } -void platform_uart_uninstall( uint8_t uart_num ) +void platform_uart_uninstall(uint8_t uart_num) { - uart_driver_delete(uart_num); - vTaskDelete( xHandle ); + uart_driver_delete(uart_num); + vTaskDelete(xHandle); } -int platform_uart_exists( unsigned id ) +int platform_uart_exists(unsigned id) { - if (id < 0 || id > 3) { - return 0; - } - return 1; + if (id < 0 || id > 3) + { + return 0; + } + return 1; } // **************************************************************************** @@ -343,128 +352,134 @@ static uint16_t pwms_duty[NUM_PWM] = {0}; // NOTE: Can't find a function to query for the period set for the timer, // therefore using the struct. // This may require adjustment if driver libraries are updated. -uint32_t platform_pwm_get_clock( void ) +uint32_t platform_pwm_get_clock(void) { - // NODE_DBG("Function platform_pwm_get_clock() is called.\n"); - uint32_t freq = ledc_get_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0); - return (uint32_t)freq; + // NODE_DBG("Function platform_pwm_get_clock() is called.\n"); + uint32_t freq = ledc_get_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0); + return (uint32_t)freq; } // Set the PWM clock -uint32_t platform_pwm_set_clock( unsigned pin, uint32_t clock ) +uint32_t platform_pwm_set_clock(unsigned pin, uint32_t clock) { - // NODE_DBG("Function platform_pwm_set_clock() is called.\n"); - ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, clock); - return (uint32_t)clock; + // NODE_DBG("Function platform_pwm_set_clock() is called.\n"); + ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, clock); + return (uint32_t)clock; } -uint32_t platform_pwm_get_duty( unsigned channel ) +uint32_t platform_pwm_get_duty(unsigned channel) { - // NODE_DBG("Function platform_pwm_get_duty() is called.\n"); - int duty = ledc_get_duty(LEDC_HIGH_SPEED_MODE, channel); - if(duty) { - return duty; - } - return 0; + // NODE_DBG("Function platform_pwm_get_duty() is called.\n"); + int duty = ledc_get_duty(LEDC_HIGH_SPEED_MODE, channel); + if (duty) + { + return duty; + } + return 0; } // Set the PWM duty -uint32_t platform_pwm_set_duty( unsigned channel, uint32_t duty ) -{ - // NODE_DBG("Function platform_pwm_set_duty() is called.\n"); - ledc_set_duty(LEDC_HIGH_SPEED_MODE, channel, duty); //the new duty is not valid, until ledc_update_duty is called - ledc_update_duty(LEDC_HIGH_SPEED_MODE, channel); - return duty; -} - -uint32_t platform_pwm_setup( unsigned pin, uint32_t frequency, unsigned duty, unsigned channel ) -{ - ledc_timer_config_t ledc_timer = { - //set timer counter bit number - .bit_num = LEDC_TIMER_13_BIT, - //set frequency of pwm - .freq_hz = frequency, - //timer mode, - .speed_mode = LEDC_HIGH_SPEED_MODE, - //timer index - .timer_num = LEDC_TIMER_0 - }; - ledc_timer_config(&ledc_timer); - - ledc_channel_config_t ledc_channel = { - //set LEDC channel 0 - .channel = channel, - //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) - .duty = duty, - //GPIO number - .gpio_num = pin, - //GPIO INTR TYPE, as an example, we enable fade_end interrupt here. - .intr_type = LEDC_INTR_FADE_END, - //set LEDC mode, from ledc_mode_t - .speed_mode = LEDC_HIGH_SPEED_MODE, - //set LEDC timer source, if different channel use one timer, - //the frequency and bit_num of these channels should be the same - .timer_sel = LEDC_TIMER_0 - }; - //set the configuration - ledc_channel_config(&ledc_channel); - - return frequency; -} - -void platform_pwm_close( unsigned pin ) -{ - // NODE_DBG("Function platform_pwm_stop() is called.\n"); - // deprecated +uint32_t platform_pwm_set_duty(unsigned channel, uint32_t duty) +{ + // NODE_DBG("Function platform_pwm_set_duty() is called.\n"); + ledc_set_duty(LEDC_HIGH_SPEED_MODE, channel, + duty); // the new duty is not valid, until ledc_update_duty is called + ledc_update_duty(LEDC_HIGH_SPEED_MODE, channel); + return duty; +} + +uint32_t platform_pwm_setup(unsigned pin, uint32_t frequency, unsigned duty, unsigned channel) +{ + ledc_timer_config_t ledc_timer = {// set timer counter bit number + .bit_num = LEDC_TIMER_13_BIT, + // set frequency of pwm + .freq_hz = frequency, + // timer mode, + .speed_mode = LEDC_HIGH_SPEED_MODE, + // timer index + .timer_num = LEDC_TIMER_0}; + ledc_timer_config(&ledc_timer); + + ledc_channel_config_t ledc_channel = {// set LEDC channel 0 + .channel = channel, + // set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1) + .duty = duty, + // GPIO number + .gpio_num = pin, + // GPIO INTR TYPE, as an example, we enable fade_end interrupt here. + .intr_type = LEDC_INTR_FADE_END, + // set LEDC mode, from ledc_mode_t + .speed_mode = LEDC_HIGH_SPEED_MODE, + // set LEDC timer source, if different channel use one timer, + // the frequency and bit_num of these channels should be the same + .timer_sel = LEDC_TIMER_0}; + // set the configuration + ledc_channel_config(&ledc_channel); + + return frequency; +} + +void platform_pwm_close(unsigned pin) +{ + // NODE_DBG("Function platform_pwm_stop() is called.\n"); + // deprecated } void platform_pwm_start(void) { - // NODE_DBG("Function platform_pwm_start() is called.\n"); - //deprecated + // NODE_DBG("Function platform_pwm_start() is called.\n"); + // deprecated } -void platform_pwm_stop( unsigned channel ) +void platform_pwm_stop(unsigned channel) { - // NODE_DBG("Function platform_pwm_stop() is called.\n"); - int output_idle_level = 0; - ledc_stop(LEDC_HIGH_SPEED_MODE, channel, output_idle_level); + // NODE_DBG("Function platform_pwm_stop() is called.\n"); + int output_idle_level = 0; + ledc_stop(LEDC_HIGH_SPEED_MODE, channel, output_idle_level); } // ***************************************************************************** // I2C platform interface -void platform_i2c_setup( uint8_t mode, uint8_t port, uint8_t scl, uint8_t sda, uint8_t addr ){ - i2c_config_t conf; - conf.mode = mode; - conf.sda_io_num = sda; - conf.sda_pullup_en = GPIO_PULLUP_ENABLE; - conf.scl_io_num = scl; - conf.scl_pullup_en = GPIO_PULLUP_ENABLE; - if (mode == I2C_MODE_MASTER) { - conf.master.clk_speed = I2C_MASTER_FREQ_HZ; - } else { - conf.slave.addr_10bit_en = 0; - conf.slave.slave_addr = addr; - } - - i2c_param_config(port, &conf); +void platform_i2c_setup(uint8_t mode, uint8_t port, uint8_t scl, uint8_t sda, uint8_t addr) +{ + i2c_config_t conf; + conf.mode = mode; + conf.sda_io_num = sda; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_io_num = scl; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + if (mode == I2C_MODE_MASTER) + { + conf.master.clk_speed = I2C_MASTER_FREQ_HZ; + } + else + { + conf.slave.addr_10bit_en = 0; + conf.slave.slave_addr = addr; + } - if (mode == I2C_MODE_MASTER) { - i2c_driver_install(port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); - } else { - i2c_driver_install(port, conf.mode, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0); - } - + i2c_param_config(port, &conf); + + if (mode == I2C_MODE_MASTER) + { + i2c_driver_install(port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); + } + else + { + i2c_driver_install(port, conf.mode, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0); + } } -void platform_i2c_send_start( unsigned id ){ - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); +void platform_i2c_send_start(unsigned id) +{ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); } -void platform_i2c_send_stop( unsigned id ){ - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_stop(cmd); +void platform_i2c_send_stop(unsigned id) +{ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_stop(cmd); } #if 0 @@ -482,161 +497,170 @@ int platform_i2c_send_address( unsigned id, uint16_t address, int direction ){ } #endif -int platform_i2c_send_byte( unsigned mode, unsigned port, unsigned addr, uint8_t *data, uint32_t len ){ - if (mode == I2C_MODE_SLAVE) { - size_t d_size = i2c_slave_write_buffer(port, data, len, 1000 / portTICK_RATE_MS); - return d_size; - } else { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, ( addr << 1 ) | I2C_MASTER_WRITE, ACK_CHECK_EN); - i2c_master_write(cmd, data, len, ACK_CHECK_EN); - i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin(port, cmd, 1000 / portTICK_RATE_MS); - i2c_cmd_link_delete(cmd); - return ret; - } - return 999; -} - - -int platform_i2c_recv_byte( uint8_t mode, uint8_t port, uint8_t addr, uint8_t * data, uint32_t len ){ - if (mode == I2C_MODE_SLAVE) { - int size = i2c_slave_read_buffer( port, data, len, 1000 / portTICK_RATE_MS); - return size; - } else { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, ( addr << 1 ) | I2C_MASTER_READ, ACK_CHECK_EN); - if (len > 1) { - i2c_master_read(cmd, data, len - 1, ACK_VAL); +int platform_i2c_send_byte(unsigned mode, unsigned port, unsigned addr, uint8_t *data, uint32_t len) +{ + if (mode == I2C_MODE_SLAVE) + { + size_t d_size = i2c_slave_write_buffer(port, data, len, 1000 / portTICK_RATE_MS); + return d_size; } - i2c_master_read_byte(cmd, data + len - 1, NACK_VAL); - i2c_master_stop(cmd); - esp_err_t ret = i2c_master_cmd_begin(port, cmd, 1000 / portTICK_RATE_MS); - i2c_cmd_link_delete(cmd); - return ret; - } - return len; + else + { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN); + i2c_master_write(cmd, data, len, ACK_CHECK_EN); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(port, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + return ret; + } + return 999; } -void platform_i2c_uninstall( uint8_t i2c_num ) +int platform_i2c_recv_byte(uint8_t mode, uint8_t port, uint8_t addr, uint8_t *data, uint32_t len) { - i2c_driver_delete(i2c_num); + if (mode == I2C_MODE_SLAVE) + { + int size = i2c_slave_read_buffer(port, data, len, 1000 / portTICK_RATE_MS); + return size; + } + else + { + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_READ, ACK_CHECK_EN); + if (len > 1) + { + i2c_master_read(cmd, data, len - 1, ACK_VAL); + } + i2c_master_read_byte(cmd, data + len - 1, NACK_VAL); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(port, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + return ret; + } + return len; } +void platform_i2c_uninstall(uint8_t i2c_num) { i2c_driver_delete(i2c_num); } + // ***************************************************************************** // SPI platform interface -uint32_t platform_spi_setup( uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div) +uint32_t platform_spi_setup(uint8_t id, int mode, unsigned cpol, unsigned cpha, uint32_t clock_div) { - //spi_master_init( id, cpol, cpha, clock_div ); - return 1; + // spi_master_init( id, cpol, cpha, clock_div ); + return 1; } -int platform_spi_send( uint8_t id, uint8_t bitlen, spi_data_type data ) +int platform_spi_send(uint8_t id, uint8_t bitlen, spi_data_type data) { - if (bitlen > 32) - return PLATFORM_ERR; + if (bitlen > 32) + return PLATFORM_ERR; - //spi_mast_transaction( id, 0, 0, bitlen, data, 0, 0, 0 ); - return PLATFORM_OK; + // spi_mast_transaction( id, 0, 0, bitlen, data, 0, 0, 0 ); + return PLATFORM_OK; } -spi_data_type platform_spi_send_recv( uint8_t id, uint8_t bitlen, spi_data_type data ) +spi_data_type platform_spi_send_recv(uint8_t id, uint8_t bitlen, spi_data_type data) { - if (bitlen > 32) - return 0; + if (bitlen > 32) + return 0; - //spi_mast_set_mosi( id, 0, bitlen, data ); - //spi_mast_transaction( id, 0, 0, 0, 0, bitlen, 0, -1 ); - //return spi_mast_get_miso( id, 0, bitlen ); - return PLATFORM_OK; + // spi_mast_set_mosi( id, 0, bitlen, data ); + // spi_mast_transaction( id, 0, 0, 0, 0, bitlen, 0, -1 ); + // return spi_mast_get_miso( id, 0, bitlen ); + return PLATFORM_OK; } -int platform_spi_set_mosi( uint8_t id, uint8_t offset, uint8_t bitlen, spi_data_type data ) +int platform_spi_set_mosi(uint8_t id, uint8_t offset, uint8_t bitlen, spi_data_type data) { - if (offset + bitlen > 512) - return PLATFORM_ERR; + if (offset + bitlen > 512) + return PLATFORM_ERR; - //spi_mast_set_mosi( id, offset, bitlen, data ); + // spi_mast_set_mosi( id, offset, bitlen, data ); - return PLATFORM_OK; + return PLATFORM_OK; } -spi_data_type platform_spi_get_miso( uint8_t id, uint8_t offset, uint8_t bitlen ) +spi_data_type platform_spi_get_miso(uint8_t id, uint8_t offset, uint8_t bitlen) { - if (offset + bitlen > 512) - return 0; + if (offset + bitlen > 512) + return 0; - //return spi_mast_get_miso( id, offset, bitlen ); - return PLATFORM_OK; + // return spi_mast_get_miso( id, offset, bitlen ); + return PLATFORM_OK; } -int platform_spi_transaction( uint8_t id, uint8_t cmd_bitlen, spi_data_type cmd_data, - uint8_t addr_bitlen, spi_data_type addr_data, - uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen ) +int platform_spi_transaction(uint8_t id, uint8_t cmd_bitlen, spi_data_type cmd_data, uint8_t addr_bitlen, + spi_data_type addr_data, uint16_t mosi_bitlen, uint8_t dummy_bitlen, int16_t miso_bitlen) { - if ((cmd_bitlen > 16) || - (addr_bitlen > 32) || - (mosi_bitlen > 512) || - (dummy_bitlen > 256) || - (miso_bitlen > 512)) - return PLATFORM_ERR; + if ((cmd_bitlen > 16) || (addr_bitlen > 32) || (mosi_bitlen > 512) || (dummy_bitlen > 256) || (miso_bitlen > 512)) + return PLATFORM_ERR; - //spi_mast_transaction( id, cmd_bitlen, cmd_data, addr_bitlen, addr_data, mosi_bitlen, dummy_bitlen, miso_bitlen ); + // spi_mast_transaction( id, cmd_bitlen, cmd_data, addr_bitlen, addr_data, + // mosi_bitlen, dummy_bitlen, miso_bitlen ); - return PLATFORM_OK; + return PLATFORM_OK; } // **************************************************************************** // Flash access functions uint32_t platform_get_flash_size(uint32_t phy_start_addr) { - return ((SYS_PARAM_SEC_START * INTERNAL_FLASH_SECTOR_SIZE) - phy_start_addr); + return ((SYS_PARAM_SEC_START * INTERNAL_FLASH_SECTOR_SIZE) - phy_start_addr); } -static uint32_t flashh_find_sector( uint32_t address, uint32_t *pstart, uint32_t *pend ) +static uint32_t flashh_find_sector(uint32_t address, uint32_t *pstart, uint32_t *pend) { - // All the sectors in the flash have the same size, so just align the address - uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE; + // All the sectors in the flash have the same size, so just align the + // address + uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE; - if( pstart ) { - *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE ; - } - if( pend ) { - *pend = ( sect_id + 1 ) * INTERNAL_FLASH_SECTOR_SIZE - 1; - } - return sect_id; + if (pstart) + { + *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE; + } + if (pend) + { + *pend = (sect_id + 1) * INTERNAL_FLASH_SECTOR_SIZE - 1; + } + return sect_id; } -uint32_t platform_flash_mapped2phys (uint32_t mapped_addr) +uint32_t platform_flash_mapped2phys(uint32_t mapped_addr) { - uint32_t cache_ctrl = DPORT_READ_PERI_REG(CACHE_FLASH_CTRL_REG); - if (!(cache_ctrl & CACHE_FLASH_ACTIVE)) - return -1; - bool b0 = (cache_ctrl & CACHE_FLASH_MAPPED0) ? 1 : 0; - bool b1 = (cache_ctrl & CACHE_FLASH_MAPPED1) ? 1 : 0; - uint32_t meg = (b1 << 1) | b0; - return mapped_addr - INTERNAL_FLASH_MAPPED_ADDRESS + meg * 0x100000; + uint32_t cache_ctrl = DPORT_READ_PERI_REG(CACHE_FLASH_CTRL_REG); + if (!(cache_ctrl & CACHE_FLASH_ACTIVE)) + return -1; + bool b0 = (cache_ctrl & CACHE_FLASH_MAPPED0) ? 1 : 0; + bool b1 = (cache_ctrl & CACHE_FLASH_MAPPED1) ? 1 : 0; + uint32_t meg = (b1 << 1) | b0; + return mapped_addr - INTERNAL_FLASH_MAPPED_ADDRESS + meg * 0x100000; } -uint32_t platform_flash_get_first_free_block_address( uint32_t *psect ) +uint32_t platform_flash_get_first_free_block_address(uint32_t *psect) { - // Round the total used flash size to the closest flash block address - uint32_t start, end, sect; - uint32_t _flash_used_end = 0x110000; - printf("_flash_used_end:%08x\n", (uint32_t)_flash_used_end); - if(_flash_used_end>0){ // find the used sector - sect = flashh_find_sector( platform_flash_mapped2phys ( (uint32_t)_flash_used_end - 1), NULL, &end ); - if( psect ) { - *psect = sect + 1; + // Round the total used flash size to the closest flash block address + uint32_t start, end, sect; + uint32_t _flash_used_end = 0x110000; + printf("_flash_used_end:%08x\n", (uint32_t)_flash_used_end); + if (_flash_used_end > 0) + { // find the used sector + sect = flashh_find_sector(platform_flash_mapped2phys((uint32_t)_flash_used_end - 1), NULL, &end); + if (psect) + { + *psect = sect + 1; + } + return end + 1; } - return end + 1; - }else{ - sect = flashh_find_sector( 0, &start, NULL ); // find the first free sector - if( psect ) { - *psect = sect; + else + { + sect = flashh_find_sector(0, &start, NULL); // find the first free sector + if (psect) + { + *psect = sect; + } + return start; } - return start; - } } diff --git a/LuaNode_Esp32/LuaNode32/components/platform/platform_flash.c b/LuaNode_Esp32/LuaNode32/components/platform/platform_flash.c index 468b1e0..214f27a 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/platform_flash.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/platform_flash.c @@ -1,211 +1,199 @@ -#include "cpu_esp32.h" -#include "user_config.h" -#include "platform.h" -#include "flash_api.h" #include #include #include +#include "cpu_esp32.h" +#include "flash_api.h" +#include "platform.h" +#include "user_config.h" + // **************************************************************************** // Internal flash support functions // Determine whether an address is in the flash-cache range -static bool is_cache_flash_addr (uint32_t addr) -{ - return addr >= 0x3F400000 && addr < 0x3FC00000; -} +static bool is_cache_flash_addr(uint32_t addr) { return addr >= 0x3F400000 && addr < 0x3FC00000; } // Helper function: find the flash sector in which an address resides // Return the sector number, as well as the start and end address of the sector -static uint32_t flashh_find_sector( uint32_t address, uint32_t *pstart, uint32_t *pend ) +static uint32_t flashh_find_sector(uint32_t address, uint32_t *pstart, uint32_t *pend) { - // All the sectors in the flash have the same size, so just align the address - uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE; - - if( pstart ) - *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE ; - if( pend ) - *pend = ( sect_id + 1 ) * INTERNAL_FLASH_SECTOR_SIZE - 1; - return sect_id; + // All the sectors in the flash have the same size, so just align the + // address + uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE; + + if (pstart) + *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE; + if (pend) + *pend = (sect_id + 1) * INTERNAL_FLASH_SECTOR_SIZE - 1; + return sect_id; } -uint32_t platform_flash_get_sector_of_address( uint32_t addr ) -{ - return flashh_find_sector( addr, NULL, NULL ); -} +uint32_t platform_flash_get_sector_of_address(uint32_t addr) { return flashh_find_sector(addr, NULL, NULL); } -uint32_t platform_flash_get_num_sectors(void) -{ - return flash_safe_get_sec_num (); -} +uint32_t platform_flash_get_num_sectors(void) { return flash_safe_get_sec_num(); } -uint32_t platform_flash_write( const void *from, uint32_t toaddr, uint32_t size ) +uint32_t platform_flash_write(const void *from, uint32_t toaddr, uint32_t size) { #ifndef INTERNAL_FLASH_WRITE_UNIT_SIZE - return platform_s_flash_write( from, toaddr, size ); -#else // #ifindef INTERNAL_FLASH_WRITE_UNIT_SIZE - uint32_t temp, rest, ssize = size; - unsigned i; - char tmpdata[ INTERNAL_FLASH_WRITE_UNIT_SIZE ]; - const uint8_t *pfrom = ( const uint8_t* )from; - const uint32_t blksize = INTERNAL_FLASH_WRITE_UNIT_SIZE; - const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1; - - // Align the start - if( toaddr & blkmask ) - { - rest = toaddr & blkmask; - temp = toaddr & ~blkmask; // this is the actual aligned address - // memcpy( tmpdata, ( const void* )temp, blksize ); - platform_s_flash_read( tmpdata, temp, blksize ); - for( i = rest; size && ( i < blksize ); i ++, size --, pfrom ++ ) - tmpdata[ i ] = *pfrom; - platform_s_flash_write( tmpdata, temp, blksize ); - if( size == 0 ) - return ssize; - toaddr = temp + blksize; - } - // The start address is now a multiple of blksize - // Compute how many bytes we can write as multiples of blksize - rest = size & blkmask; - temp = size & ~blkmask; - // Program the blocks now - if( temp ) - { - platform_s_flash_write( pfrom, toaddr, temp ); - toaddr += temp; - pfrom += temp; - } - // And the final part of a block if needed - if( rest ) - { - // memcpy( tmpdata, ( const void* )toaddr, blksize ); - platform_s_flash_read( tmpdata, toaddr, blksize ); - for( i = 0; size && ( i < rest ); i ++, size --, pfrom ++ ) - tmpdata[ i ] = *pfrom; - platform_s_flash_write( tmpdata, toaddr, blksize ); - } - return ssize; -#endif // #ifndef INTERNAL_FLASH_WRITE_UNIT_SIZE + return platform_s_flash_write(from, toaddr, size); +#else // #ifindef INTERNAL_FLASH_WRITE_UNIT_SIZE + uint32_t temp, rest, ssize = size; + unsigned i; + char tmpdata[INTERNAL_FLASH_WRITE_UNIT_SIZE]; + const uint8_t *pfrom = (const uint8_t *)from; + const uint32_t blksize = INTERNAL_FLASH_WRITE_UNIT_SIZE; + const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1; + + // Align the start + if (toaddr & blkmask) + { + rest = toaddr & blkmask; + temp = toaddr & ~blkmask; // this is the actual aligned address + // memcpy( tmpdata, ( const void* )temp, blksize ); + platform_s_flash_read(tmpdata, temp, blksize); + for (i = rest; size && (i < blksize); i++, size--, pfrom++) tmpdata[i] = *pfrom; + platform_s_flash_write(tmpdata, temp, blksize); + if (size == 0) + return ssize; + toaddr = temp + blksize; + } + // The start address is now a multiple of blksize + // Compute how many bytes we can write as multiples of blksize + rest = size & blkmask; + temp = size & ~blkmask; + // Program the blocks now + if (temp) + { + platform_s_flash_write(pfrom, toaddr, temp); + toaddr += temp; + pfrom += temp; + } + // And the final part of a block if needed + if (rest) + { + // memcpy( tmpdata, ( const void* )toaddr, blksize ); + platform_s_flash_read(tmpdata, toaddr, blksize); + for (i = 0; size && (i < rest); i++, size--, pfrom++) tmpdata[i] = *pfrom; + platform_s_flash_write(tmpdata, toaddr, blksize); + } + return ssize; +#endif // #ifndef INTERNAL_FLASH_WRITE_UNIT_SIZE } -uint32_t platform_flash_read( void *to, uint32_t fromaddr, uint32_t size ) +uint32_t platform_flash_read(void *to, uint32_t fromaddr, uint32_t size) { #ifndef INTERNAL_FLASH_READ_UNIT_SIZE - return platform_s_flash_read( to, fromaddr, size ); -#else // #ifindef INTERNAL_FLASH_READ_UNIT_SIZE - uint32_t temp, rest, ssize = size; - unsigned i; - char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); - uint8_t *pto = ( uint8_t* )to; - const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE; - const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1; - - // Align the start - if( fromaddr & blkmask ) - { - rest = fromaddr & blkmask; - temp = fromaddr & ~blkmask; // this is the actual aligned address - platform_s_flash_read( tmpdata, temp, blksize ); - for( i = rest; size && ( i < blksize ); i ++, size --, pto ++ ) - *pto = tmpdata[ i ]; - - if( size == 0 ) - return ssize; - fromaddr = temp + blksize; - } - // The start address is now a multiple of blksize - // Compute how many bytes we can read as multiples of blksize - rest = size & blkmask; - temp = size & ~blkmask; - // Program the blocks now - if( temp ) - { - platform_s_flash_read( pto, fromaddr, temp ); - fromaddr += temp; - pto += temp; - } - // And the final part of a block if needed - if( rest ) - { - platform_s_flash_read( tmpdata, fromaddr, blksize ); - for( i = 0; size && ( i < rest ); i ++, size --, pto ++ ) - *pto = tmpdata[ i ]; - } - return ssize; -#endif // #ifndef INTERNAL_FLASH_READ_UNIT_SIZE + return platform_s_flash_read(to, fromaddr, size); +#else // #ifindef INTERNAL_FLASH_READ_UNIT_SIZE + uint32_t temp, rest, ssize = size; + unsigned i; + char tmpdata[INTERNAL_FLASH_READ_UNIT_SIZE] __attribute__((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); + uint8_t *pto = (uint8_t *)to; + const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE; + const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1; + + // Align the start + if (fromaddr & blkmask) + { + rest = fromaddr & blkmask; + temp = fromaddr & ~blkmask; // this is the actual aligned address + platform_s_flash_read(tmpdata, temp, blksize); + for (i = rest; size && (i < blksize); i++, size--, pto++) *pto = tmpdata[i]; + + if (size == 0) + return ssize; + fromaddr = temp + blksize; + } + // The start address is now a multiple of blksize + // Compute how many bytes we can read as multiples of blksize + rest = size & blkmask; + temp = size & ~blkmask; + // Program the blocks now + if (temp) + { + platform_s_flash_read(pto, fromaddr, temp); + fromaddr += temp; + pto += temp; + } + // And the final part of a block if needed + if (rest) + { + platform_s_flash_read(tmpdata, fromaddr, blksize); + for (i = 0; size && (i < rest); i++, size--, pto++) *pto = tmpdata[i]; + } + return ssize; +#endif // #ifndef INTERNAL_FLASH_READ_UNIT_SIZE } - /* * Assumptions: * > toaddr is INTERNAL_FLASH_WRITE_UNIT_SIZE aligned * > size is a multiple of INTERNAL_FLASH_WRITE_UNIT_SIZE */ -uint32_t platform_s_flash_write( const void *from, uint32_t toaddr, uint32_t size ) +uint32_t platform_s_flash_write(const void *from, uint32_t toaddr, uint32_t size) { - esp_err_t r; - const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1; - uint32_t *apbuf = NULL; - uint32_t fromaddr = (uint32_t)from; - if( (fromaddr & blkmask ) || is_cache_flash_addr(fromaddr)) { - apbuf = (uint32_t *)malloc(size); - if(!apbuf) - return 0; - memcpy(apbuf, from, size); - } - r = flash_write(toaddr, apbuf?(uint32 *)apbuf:(uint32 *)from, size); - if(apbuf) - free(apbuf); - if(ESP_OK == r) - return size; - else{ - NODE_ERR( "ERROR in flash_write: r=%d at %08X\n", ( int )r, ( unsigned )toaddr); - return 0; - } + esp_err_t r; + const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1; + uint32_t *apbuf = NULL; + uint32_t fromaddr = (uint32_t)from; + if ((fromaddr & blkmask) || is_cache_flash_addr(fromaddr)) + { + apbuf = (uint32_t *)malloc(size); + if (!apbuf) + return 0; + memcpy(apbuf, from, size); + } + r = flash_write(toaddr, apbuf ? (uint32 *)apbuf : (uint32 *)from, size); + if (apbuf) + free(apbuf); + if (ESP_OK == r) + return size; + else + { + NODE_ERR("ERROR in flash_write: r=%d at %08X\n", (int)r, (unsigned)toaddr); + return 0; + } } - /* * Assumptions: * > fromaddr is INTERNAL_FLASH_READ_UNIT_SIZE aligned * > size is a multiple of INTERNAL_FLASH_READ_UNIT_SIZE */ -uint32_t platform_s_flash_read( void *to, uint32_t fromaddr, uint32_t size ) +uint32_t platform_s_flash_read(void *to, uint32_t fromaddr, uint32_t size) { - if (size==0) - return 0; - - esp_err_t r; - - const uint32_t blkmask = (INTERNAL_FLASH_READ_UNIT_SIZE - 1); - if( ((uint32_t)to) & blkmask ) - { - uint32_t size2=size-INTERNAL_FLASH_READ_UNIT_SIZE; - uint32* to2=(uint32*)((((uint32_t)to)&(~blkmask))+INTERNAL_FLASH_READ_UNIT_SIZE); - r = flash_read(fromaddr, to2, size2); - if(ESP_OK == r) + if (size == 0) + return 0; + + esp_err_t r; + + const uint32_t blkmask = (INTERNAL_FLASH_READ_UNIT_SIZE - 1); + if (((uint32_t)to) & blkmask) { - memmove(to,to2,size2); - char back[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); - r=flash_read(fromaddr+size2,(uint32*)back,INTERNAL_FLASH_READ_UNIT_SIZE); - memcpy((uint8_t*)to+size2,back,INTERNAL_FLASH_READ_UNIT_SIZE); + uint32_t size2 = size - INTERNAL_FLASH_READ_UNIT_SIZE; + uint32 *to2 = (uint32 *)((((uint32_t)to) & (~blkmask)) + INTERNAL_FLASH_READ_UNIT_SIZE); + r = flash_read(fromaddr, to2, size2); + if (ESP_OK == r) + { + memmove(to, to2, size2); + char back[INTERNAL_FLASH_READ_UNIT_SIZE] __attribute__((aligned(INTERNAL_FLASH_READ_UNIT_SIZE))); + r = flash_read(fromaddr + size2, (uint32 *)back, INTERNAL_FLASH_READ_UNIT_SIZE); + memcpy((uint8_t *)to + size2, back, INTERNAL_FLASH_READ_UNIT_SIZE); + } } - } - else - r = flash_read(fromaddr, (uint32 *)to, size); - - if(ESP_OK == r) - return size; - else{ - NODE_ERR( "ERROR in flash_read: r=%d at %08X\n", ( int )r, ( unsigned )fromaddr); - return 0; - } -} + else + r = flash_read(fromaddr, (uint32 *)to, size); + if (ESP_OK == r) + return size; + else + { + NODE_ERR("ERROR in flash_read: r=%d at %08X\n", (int)r, (unsigned)fromaddr); + return 0; + } +} -int platform_flash_erase_sector( uint32_t sector_id ) +int platform_flash_erase_sector(uint32_t sector_id) { - return flash_erase( sector_id ) == ESP_OK ? PLATFORM_OK : PLATFORM_ERR; + return flash_erase(sector_id) == ESP_OK ? PLATFORM_OK : PLATFORM_ERR; } - diff --git a/LuaNode_Esp32/LuaNode32/components/platform/platform_partition.c b/LuaNode_Esp32/LuaNode32/components/platform/platform_partition.c index 16d82f0..7e6b745 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/platform_partition.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/platform_partition.c @@ -31,84 +31,79 @@ * @author Johny Mattsson */ -#include "platform.h" #include "platform_partition.h" -#include -#include #include +#include +#include + +#include "platform.h" //#include "../../bootloader/src/main/bootloader_config.h" -#include "esp_spi_flash.h" #include "esp_flash_data_types.h" +#include "esp_spi_flash.h" -#define partition_info_t esp_partition_info_t -#define PARTITION_MAGIC ESP_PARTITION_MAGIC -#define PARTITION_ADD ESP_PARTITION_TABLE_ADDR - -static inline bool possible_idx (uint8_t idx) -{ - return ((idx +1) * sizeof (partition_info_t)) < SPI_FLASH_SEC_SIZE; -} +#define partition_info_t esp_partition_info_t +#define PARTITION_MAGIC ESP_PARTITION_MAGIC +#define PARTITION_ADD ESP_PARTITION_TABLE_ADDR +static inline bool possible_idx(uint8_t idx) { return ((idx + 1) * sizeof(partition_info_t)) < SPI_FLASH_SEC_SIZE; } -bool platform_partition_info (uint8_t idx, platform_partition_t *info) +bool platform_partition_info(uint8_t idx, platform_partition_t *info) { - if (!possible_idx (idx)) - return false; + if (!possible_idx(idx)) + return false; - partition_info_t pi; - esp_err_t err = spi_flash_read ( - PARTITION_ADD + idx * sizeof(pi), (uint32_t *)&pi, sizeof (pi)); - if (err != ESP_OK) { - return false; - } + partition_info_t pi; + esp_err_t err = spi_flash_read(PARTITION_ADD + idx * sizeof(pi), (uint32_t *)&pi, sizeof(pi)); + if (err != ESP_OK) + { + return false; + } - if (pi.magic != PARTITION_MAGIC) { - return false; - } + if (pi.magic != PARTITION_MAGIC) + { + return false; + } - memcpy (info->label, pi.label, sizeof (info->label)); - info->offs = pi.pos.offset; - info->size = pi.pos.size; - info->type = pi.type; - info->subtype = pi.subtype; - return true; + memcpy(info->label, pi.label, sizeof(info->label)); + info->offs = pi.pos.offset; + info->size = pi.pos.size; + info->type = pi.type; + info->subtype = pi.subtype; + return true; } - -bool platform_partition_add (const platform_partition_t *info) +bool platform_partition_add(const platform_partition_t *info) { - partition_info_t *part_table = (partition_info_t *)malloc(SPI_FLASH_SEC_SIZE); - if (!part_table) - return false; - esp_err_t err = - spi_flash_read (PARTITION_ADD, (uint32_t *)part_table, SPI_FLASH_SEC_SIZE); - if (err != ESP_OK) - goto out; + partition_info_t *part_table = (partition_info_t *)malloc(SPI_FLASH_SEC_SIZE); + if (!part_table) + return false; + esp_err_t err = spi_flash_read(PARTITION_ADD, (uint32_t *)part_table, SPI_FLASH_SEC_SIZE); + if (err != ESP_OK) + goto out; - uint8_t idx = 0; - for (; possible_idx (idx); ++idx) - if (part_table[idx].magic != PARTITION_MAGIC) - break; + uint8_t idx = 0; + for (; possible_idx(idx); ++idx) + if (part_table[idx].magic != PARTITION_MAGIC) + break; - if (possible_idx (idx)) - { - partition_info_t *slot = &part_table[idx]; - slot->magic = PARTITION_MAGIC; - slot->type = info->type; - slot->subtype = info->subtype; - slot->pos.offset = info->offs; - slot->pos.size = info->size; - memcpy (slot->label, info->label, sizeof (slot->label)); - //memset (slot->reserved, 0xff, sizeof (slot->reserved)); - slot->flags = 0xffffffff; - err = spi_flash_erase_sector (PARTITION_ADD / SPI_FLASH_SEC_SIZE); - if (err == ESP_OK) - err = spi_flash_write ( - PARTITION_ADD, (uint32_t *)part_table, SPI_FLASH_SEC_SIZE); - } + if (possible_idx(idx)) + { + partition_info_t *slot = &part_table[idx]; + slot->magic = PARTITION_MAGIC; + slot->type = info->type; + slot->subtype = info->subtype; + slot->pos.offset = info->offs; + slot->pos.size = info->size; + memcpy(slot->label, info->label, sizeof(slot->label)); + // memset (slot->reserved, 0xff, sizeof (slot->reserved)); + slot->flags = 0xffffffff; + err = spi_flash_erase_sector(PARTITION_ADD / SPI_FLASH_SEC_SIZE); + if (err == ESP_OK) + err = spi_flash_write(PARTITION_ADD, (uint32_t *)part_table, SPI_FLASH_SEC_SIZE); + } out: - free (part_table); - return err == ESP_OK; + free(part_table); + return err == ESP_OK; } diff --git a/LuaNode_Esp32/LuaNode32/components/platform/vfs.c b/LuaNode_Esp32/LuaNode32/components/platform/vfs.c index b5c2724..b555e17 100644 --- a/LuaNode_Esp32/LuaNode32/components/platform/vfs.c +++ b/LuaNode_Esp32/LuaNode32/components/platform/vfs.c @@ -1,450 +1,505 @@ -#include -#include #include "vfs.h" + +#include +#include + #include "platform.h" #include "user_config.h" #define LDRV_TRAVERSAL 0 - // --------------------------------------------------------------------------- // RTC system interface // -static int32_t (*rtc_cb)( vfs_time *tm ) = NULL; +static int32_t (*rtc_cb)(vfs_time *tm) = NULL; // called by operating system -void vfs_register_rtc_cb( int32_t (*cb)( vfs_time *tm ) ) +void vfs_register_rtc_cb(int32_t (*cb)(vfs_time *tm)) { - // allow NULL pointer to unregister callback function - rtc_cb = cb; + // allow NULL pointer to unregister callback function + rtc_cb = cb; } // called by file system drivers -int32_t vfs_get_rtc( vfs_time *tm ) +int32_t vfs_get_rtc(vfs_time *tm) { - if (rtc_cb) { - return rtc_cb( tm ); - } + if (rtc_cb) + { + return rtc_cb(tm); + } - return VFS_RES_ERR; + return VFS_RES_ERR; } - #if LDRV_TRAVERSAL static int dir_level = 1; #endif -static const char *normalize_path( const char *path ) +static const char *normalize_path(const char *path) { -#if ! LDRV_TRAVERSAL - return path; -#else - const char *temp = path; - size_t len; - - while ((len = strlen( temp )) >= 2) { - if (temp[0] == '.' && temp[1] == '.') { - --dir_level; - if (len >= 4 && dir_level > 0) { - // prepare next step - temp = &(temp[4]); - } else { - // we're at top, the remainder is expected be an absolute path - temp = &(temp[3]); - } - } else { - break; - } - } - - if (dir_level > 0) { - // no traversal on root level +#if !LDRV_TRAVERSAL return path; - } else { - // path traverses via root - return temp; - } +#else + const char *temp = path; + size_t len; + + while ((len = strlen(temp)) >= 2) + { + if (temp[0] == '.' && temp[1] == '.') + { + --dir_level; + if (len >= 4 && dir_level > 0) + { + // prepare next step + temp = &(temp[4]); + } + else + { + // we're at top, the remainder is expected be an absolute path + temp = &(temp[3]); + } + } + else + { + break; + } + } + + if (dir_level > 0) + { + // no traversal on root level + return path; + } + else + { + // path traverses via root + return temp; + } #endif } - // --------------------------------------------------------------------------- // file system functions // -vfs_vol *vfs_mount( const char *name, int num ) +vfs_vol *vfs_mount(const char *name, int num) { - vfs_fs_fns *fs_fns; - const char *normname = normalize_path( name ); - char *outname; + vfs_fs_fns *fs_fns; + const char *normname = normalize_path(name); + char *outname; - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return fs_fns->mount( outname, num ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return fs_fns->mount(outname, num); + } - return NULL; + return NULL; } -int vfs_open( const char *name, const char *mode ) +int vfs_open(const char *name, const char *mode) { - vfs_fs_fns *fs_fns; - const char *normname = normalize_path( name ); - char *outname; + vfs_fs_fns *fs_fns; + const char *normname = normalize_path(name); + char *outname; - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return (int)fs_fns->open( outname, mode ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return (int)fs_fns->open(outname, mode); + } - return 0; + return 0; } -vfs_dir *vfs_opendir( const char *name ) +vfs_dir *vfs_opendir(const char *name) { - vfs_fs_fns *fs_fns; - const char *normname = normalize_path( name ); - char *outname; + vfs_fs_fns *fs_fns; + const char *normname = normalize_path(name); + char *outname; #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return fs_fns->opendir( outname ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return fs_fns->opendir(outname); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - vfs_dir *r = fs_fns->opendir( outname ); - free( outname ); - return r; - } + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + vfs_dir *r = fs_fns->opendir(outname); + free(outname); + return r; + } #endif - return NULL; + return NULL; } -vfs_item *vfs_stat( const char *name ) +vfs_item *vfs_stat(const char *name) { - vfs_fs_fns *fs_fns; - const char *normname = normalize_path( name ); - char *outname; + vfs_fs_fns *fs_fns; + const char *normname = normalize_path(name); + char *outname; #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return fs_fns->stat( outname ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return fs_fns->stat(outname); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - vfs_item *r = fs_fns->stat( outname ); - free( outname ); - return r; - } + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + vfs_item *r = fs_fns->stat(outname); + free(outname); + return r; + } #endif - return NULL; + return NULL; } -int32_t vfs_remove( const char *name ) +int32_t vfs_remove(const char *name) { - vfs_fs_fns *fs_fns; - const char *normname = normalize_path( name ); - char *outname; + vfs_fs_fns *fs_fns; + const char *normname = normalize_path(name); + char *outname; #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return fs_fns->remove( outname ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return fs_fns->remove(outname); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - int32_t r = fs_fns->remove( outname ); - free( outname ); - return r; - } + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + int32_t r = fs_fns->remove(outname); + free(outname); + return r; + } #endif - return VFS_RES_ERR; + return VFS_RES_ERR; } -int32_t vfs_rename( const char *oldname, const char *newname ) +int32_t vfs_rename(const char *oldname, const char *newname) { - vfs_fs_fns *fs_fns; - const char *normoldname = normalize_path( oldname ); - const char *normnewname = normalize_path( newname ); - char *oldoutname, *newoutname; + vfs_fs_fns *fs_fns; + const char *normoldname = normalize_path(oldname); + const char *normnewname = normalize_path(newname); + char *oldoutname, *newoutname; #ifdef CONFIG_BUILD_SPIFFS - if (myspiffs_realm( normoldname, &oldoutname, false )) { - if ((fs_fns = myspiffs_realm( normnewname, &newoutname, false ))) { - return fs_fns->rename( oldoutname, newoutname ); + if (myspiffs_realm(normoldname, &oldoutname, false)) + { + if ((fs_fns = myspiffs_realm(normnewname, &newoutname, false))) + { + return fs_fns->rename(oldoutname, newoutname); + } } - } #endif #ifdef CONFIG_BUILD_FATFS - if (myfatfs_realm( normoldname, &oldoutname, false )) { - if ((fs_fns = myfatfs_realm( normnewname, &newoutname, false ))) { - int32_t r = fs_fns->rename( oldoutname, newoutname ); - free( oldoutname ); - free( newoutname ); - return r; - } - free( oldoutname ); - } + if (myfatfs_realm(normoldname, &oldoutname, false)) + { + if ((fs_fns = myfatfs_realm(normnewname, &newoutname, false))) + { + int32_t r = fs_fns->rename(oldoutname, newoutname); + free(oldoutname); + free(newoutname); + return r; + } + free(oldoutname); + } #endif - return -1; + return -1; } -int32_t vfs_mkdir( const char *name ) +int32_t vfs_mkdir(const char *name) { - vfs_fs_fns *fs_fns; + vfs_fs_fns *fs_fns; #ifdef CONFIG_BUILD_SPIFFS - // not supported + // not supported #endif #ifdef CONFIG_BUILD_FATFS - const char *normname = normalize_path( name ); - char *outname; - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - int32_t r = fs_fns->mkdir( outname ); - free( outname ); - return r; - } + const char *normname = normalize_path(name); + char *outname; + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + int32_t r = fs_fns->mkdir(outname); + free(outname); + return r; + } #endif - return VFS_RES_ERR; + return VFS_RES_ERR; } -int32_t vfs_fsinfo( const char *name, uint32_t *total, uint32_t *used ) +int32_t vfs_fsinfo(const char *name, uint32_t *total, uint32_t *used) { - vfs_fs_fns *fs_fns; - char *outname; + vfs_fs_fns *fs_fns; + char *outname; - if (!name) name = ""; // current drive + if (!name) + name = ""; // current drive - const char *normname = normalize_path( name ); + const char *normname = normalize_path(name); #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return fs_fns->fsinfo( total, used ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return fs_fns->fsinfo(total, used); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - free( outname ); - return fs_fns->fsinfo( total, used ); - } + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + free(outname); + return fs_fns->fsinfo(total, used); + } #endif - return VFS_RES_ERR; + return VFS_RES_ERR; } -int32_t vfs_fscfg( const char *name, uint32_t *phys_addr, uint32_t *phys_size) +int32_t vfs_fscfg(const char *name, uint32_t *phys_addr, uint32_t *phys_size) { - vfs_fs_fns *fs_fns; - char *outname; + vfs_fs_fns *fs_fns; + char *outname; #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( "/FLASH", &outname, false ))) { - return fs_fns->fscfg( phys_addr, phys_size ); - } + if ((fs_fns = myspiffs_realm("/FLASH", &outname, false))) + { + return fs_fns->fscfg(phys_addr, phys_size); + } #endif #ifdef CONFIG_BUILD_FATFS - // not supported + // not supported #endif - // Error - return VFS_RES_ERR; + // Error + return VFS_RES_ERR; } -int32_t vfs_format( void ) +int32_t vfs_format(void) { - vfs_fs_fns *fs_fns; - char *outname; + vfs_fs_fns *fs_fns; + char *outname; #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( "/FLASH", &outname, false ))) { - return fs_fns->format(); - } + if ((fs_fns = myspiffs_realm("/FLASH", &outname, false))) + { + return fs_fns->format(); + } #endif #ifdef CONFIG_BUILD_FATFS - // not supported + // not supported #endif - // Error - return 0; + // Error + return 0; } -int32_t vfs_chdir( const char *path ) +int32_t vfs_chdir(const char *path) { - vfs_fs_fns *fs_fns; - const char *normpath = normalize_path( path ); - char *outname; - int ok = VFS_RES_ERR; + vfs_fs_fns *fs_fns; + const char *normpath = normalize_path(path); + char *outname; + int ok = VFS_RES_ERR; #if LDRV_TRAVERSAL - const char *level; - // track dir level - if (normpath[0] == '/') { - dir_level = 0; - level = &(normpath[1]); - } else { - level = normpath; - } - while (strlen( level ) > 0) { - dir_level++; - if (level = strchr( level, '/' )) { - level++; - } else { - break; - } - } + const char *level; + // track dir level + if (normpath[0] == '/') + { + dir_level = 0; + level = &(normpath[1]); + } + else + { + level = normpath; + } + while (strlen(level) > 0) + { + dir_level++; + if (level = strchr(level, '/')) + { + level++; + } + else + { + break; + } + } #endif #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normpath, &outname, true ))) { - // our SPIFFS integration doesn't support directories - if (strlen( outname ) == 0) { - ok = VFS_RES_OK; + if ((fs_fns = myspiffs_realm(normpath, &outname, true))) + { + // our SPIFFS integration doesn't support directories + if (strlen(outname) == 0) + { + ok = VFS_RES_OK; + } } - } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normpath, &outname, true ))) { - if (strchr( outname, ':' )) { - // need to set FatFS' default drive - fs_fns->chdrive( outname ); - // and force chdir to root in case path points only to root - fs_fns->chdir( "/" ); - } - if (fs_fns->chdir( outname ) == VFS_RES_OK) { - ok = VFS_RES_OK; - } - free( outname ); - } + if ((fs_fns = myfatfs_realm(normpath, &outname, true))) + { + if (strchr(outname, ':')) + { + // need to set FatFS' default drive + fs_fns->chdrive(outname); + // and force chdir to root in case path points only to root + fs_fns->chdir("/"); + } + if (fs_fns->chdir(outname) == VFS_RES_OK) + { + ok = VFS_RES_OK; + } + free(outname); + } #endif - return ok == VFS_RES_OK ? VFS_RES_OK : VFS_RES_ERR; + return ok == VFS_RES_OK ? VFS_RES_OK : VFS_RES_ERR; } -int32_t vfs_errno( const char *name ) +int32_t vfs_errno(const char *name) { - vfs_fs_fns *fs_fns; - const char *normname = normalize_path( name ); - char *outname; + vfs_fs_fns *fs_fns; + const char *normname = normalize_path(name); + char *outname; - if (!name) name = ""; // current drive + if (!name) + name = ""; // current drive #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - return fs_fns->ferrno( ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + return fs_fns->ferrno(); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - int32_t r = fs_fns->ferrno( ); - free( outname ); - return r; - } + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + int32_t r = fs_fns->ferrno(); + free(outname); + return r; + } #endif - return VFS_RES_ERR; + return VFS_RES_ERR; } -int32_t vfs_ferrno( int fd ) +int32_t vfs_ferrno(int fd) { - vfs_file *f = (vfs_file *)fd; + vfs_file *f = (vfs_file *)fd; - if (f) { - return f->fns->ferrno ? f->fns->ferrno( f ) : 0; - } else { - vfs_fs_fns *fs_fns; - const char *name = ""; // current drive - char *outname; + if (f) + { + return f->fns->ferrno ? f->fns->ferrno(f) : 0; + } + else + { + vfs_fs_fns *fs_fns; + const char *name = ""; // current drive + char *outname; #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( name, &outname, false ))) { - return fs_fns->ferrno( ); - } + if ((fs_fns = myspiffs_realm(name, &outname, false))) + { + return fs_fns->ferrno(); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( name, &outname, false ))) { - int32_t r = fs_fns->ferrno( ); - free( outname ); - return r; - } + if ((fs_fns = myfatfs_realm(name, &outname, false))) + { + int32_t r = fs_fns->ferrno(); + free(outname); + return r; + } #endif - } - return 0; + } + return 0; } - -void vfs_clearerr( const char *name ) +void vfs_clearerr(const char *name) { - vfs_fs_fns *fs_fns; - char *outname; + vfs_fs_fns *fs_fns; + char *outname; - if (!name) name = ""; // current drive + if (!name) + name = ""; // current drive - const char *normname = normalize_path( name ); + const char *normname = normalize_path(name); #ifdef CONFIG_BUILD_SPIFFS - if ((fs_fns = myspiffs_realm( normname, &outname, false ))) { - fs_fns->clearerr( ); - } + if ((fs_fns = myspiffs_realm(normname, &outname, false))) + { + fs_fns->clearerr(); + } #endif #ifdef CONFIG_BUILD_FATFS - if ((fs_fns = myfatfs_realm( normname, &outname, false ))) { - fs_fns->clearerr( ); - free( outname ); - } + if ((fs_fns = myfatfs_realm(normname, &outname, false))) + { + fs_fns->clearerr(); + free(outname); + } #endif } -const char *vfs_basename( const char *path ) +const char *vfs_basename(const char *path) { - const char *basename; - - // deduce basename (incl. extension) for length check - if ((basename = strrchr( path, '/' ))) { - basename++; - } else if ((basename = strrchr( path, ':' ))) { - basename++; - } else { - basename = path; - } - - return basename; -} + const char *basename; + // deduce basename (incl. extension) for length check + if ((basename = strrchr(path, '/'))) + { + basename++; + } + else if ((basename = strrchr(path, ':'))) + { + basename++; + } + else + { + basename = path; + } + + return basename; +} // --------------------------------------------------------------------------- // supplementary functions // -int vfs_getc( int fd ) +int vfs_getc(int fd) { - unsigned char c = 0xFF; - if(!vfs_eof( fd )) { - if (1 != vfs_read( fd, &c, 1 )) { - NODE_DBG("getc errno %i\n", vfs_ferrno( fd )); - return VFS_EOF; - } else { - return (int)c; - } - } - return VFS_EOF; + unsigned char c = 0xFF; + if (!vfs_eof(fd)) + { + if (1 != vfs_read(fd, &c, 1)) + { + NODE_DBG("getc errno %i\n", vfs_ferrno(fd)); + return VFS_EOF; + } + else + { + return (int)c; + } + } + return VFS_EOF; } -int vfs_ungetc( int c, int fd ) -{ - return vfs_lseek( fd, -1, VFS_SEEK_CUR ); -} +int vfs_ungetc(int c, int fd) { return vfs_lseek(fd, -1, VFS_SEEK_CUR); } diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs.c b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs.c index 84ded15..7a4d8b4 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs.c @@ -1,50 +1,57 @@ -#include +#include "spiffs.h" + #include +#include #include + +#include "flash_api.h" #include "platform.h" #include "platform_partition.h" -#include "flash_api.h" -#include "spiffs.h" #include "user_config.h" static spiffs fs; -#define LOG_PAGE_SIZE 256 -#define LOG_BLOCK_SIZE (INTERNAL_FLASH_SECTOR_SIZE * 2) -#define LOG_BLOCK_SIZE_SMALL_FS (INTERNAL_FLASH_SECTOR_SIZE) -#define MIN_BLOCKS_FS 4 - -static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2]; -static u8_t spiffs_fds[32*4]; +#define LOG_PAGE_SIZE 256 +#define LOG_BLOCK_SIZE (INTERNAL_FLASH_SECTOR_SIZE * 2) +#define LOG_BLOCK_SIZE_SMALL_FS (INTERNAL_FLASH_SECTOR_SIZE) +#define MIN_BLOCKS_FS 4 + +static u8_t spiffs_work_buf[LOG_PAGE_SIZE * 2]; +static u8_t spiffs_fds[32 * 4]; #if SPIFFS_CACHE -static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*2]; +static u8_t spiffs_cache[(LOG_PAGE_SIZE + 32) * 2]; #endif -static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) { - platform_flash_read(dst, addr, size); - return SPIFFS_OK; +static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) +{ + platform_flash_read(dst, addr, size); + return SPIFFS_OK; } -static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src) { - platform_flash_write(src, addr, size); +static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src) +{ + platform_flash_write(src, addr, size); #if defined(SHOW_WRITE_PROGRESS) - printf("."); + printf("."); #endif - return SPIFFS_OK; + return SPIFFS_OK; +} + +static s32_t my_spiffs_erase(u32_t addr, u32_t size) +{ + u32_t sect_first = platform_flash_get_sector_of_address(addr); + u32_t sect_last = sect_first; + while (sect_first <= sect_last) + if (platform_flash_erase_sector(sect_first++) == PLATFORM_ERR) + return SPIFFS_ERR_INTERNAL; + return SPIFFS_OK; } -static s32_t my_spiffs_erase(u32_t addr, u32_t size) { - u32_t sect_first = platform_flash_get_sector_of_address(addr); - u32_t sect_last = sect_first; - while( sect_first <= sect_last ) - if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR ) - return SPIFFS_ERR_INTERNAL; - return SPIFFS_OK; -} - -void myspiffs_check_callback(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2){ - // if(SPIFFS_CHECK_PROGRESS == report) return; - // NODE_ERR("type: %d, report: %d, arg1: %d, arg2: %d\n", type, report, arg1, arg2); +void myspiffs_check_callback(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2) +{ + // if(SPIFFS_CHECK_PROGRESS == report) return; + // NODE_ERR("type: %d, report: %d, arg1: %d, arg2: %d\n", type, report, + // arg1, arg2); } /******************* @@ -55,138 +62,129 @@ The small 4KB sectors allow for greater flexibility in applications th ********************/ - -static bool get_spiffs_partition (spiffs_config *cfg) +static bool get_spiffs_partition(spiffs_config *cfg) { - platform_partition_t info; - uint32_t next_free_offs = 0; - uint8_t i = 0; - while (platform_partition_info (i, &info)) - { - if (info.type == PLATFORM_PARTITION_TYPE_NODEMCU && - info.subtype == PLATFORM_PARTITION_SUBTYPE_NODEMCU_SPIFFS) + platform_partition_t info; + uint32_t next_free_offs = 0; + uint8_t i = 0; + while (platform_partition_info(i, &info)) + { + if (info.type == PLATFORM_PARTITION_TYPE_NODEMCU && info.subtype == PLATFORM_PARTITION_SUBTYPE_NODEMCU_SPIFFS) + { + cfg->phys_addr = info.offs; + cfg->phys_size = info.size; + return true; + } + else + { + ++i; + if ((info.offs + info.size) > next_free_offs) + next_free_offs = info.offs + info.size; + } + } + // Attempt to append a spiffs partition + NODE_ERR("No filesystem partition found, attempting to create it...\n"); + info.type = PLATFORM_PARTITION_TYPE_NODEMCU; + info.subtype = PLATFORM_PARTITION_SUBTYPE_NODEMCU_SPIFFS; + strcpy((char *)info.label, "spiffs"); + info.offs = cfg->phys_addr = next_free_offs; + info.size = cfg->phys_size = flash_safe_get_size_byte() - info.offs; + if (info.size <= 0) { - cfg->phys_addr = info.offs; - cfg->phys_size = info.size; - return true; + NODE_ERR("No space available at end of flash, can't add fs partition!\n"); + return false; + } + if (platform_partition_add(&info)) + { + NODE_ERR("Ok.\n"); + return true; } else { - ++i; - if ((info.offs + info.size) > next_free_offs) - next_free_offs = info.offs + info.size; + NODE_ERR("Error rewriting partition table!\n"); + return false; } - } - // Attempt to append a spiffs partition - NODE_ERR("No filesystem partition found, attempting to create it...\n"); - info.type = PLATFORM_PARTITION_TYPE_NODEMCU; - info.subtype = PLATFORM_PARTITION_SUBTYPE_NODEMCU_SPIFFS; - strcpy ((char *)info.label, "spiffs"); - info.offs = cfg->phys_addr = next_free_offs; - info.size = cfg->phys_size = flash_safe_get_size_byte () - info.offs; - if (info.size <= 0) - { - NODE_ERR("No space available at end of flash, can't add fs partition!\n"); - return false; - } - if (platform_partition_add (&info)) - { - NODE_ERR("Ok.\n"); - return true; - } - else - { - NODE_ERR("Error rewriting partition table!\n"); - return false; - } } - static bool myspiffs_mount_internal(bool force_mount) { - spiffs_config cfg; - cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet - cfg.log_page_size = LOG_PAGE_SIZE; // as we said - cfg.log_block_size = LOG_BLOCK_SIZE; - cfg.hal_read_f = my_spiffs_read; - cfg.hal_write_f = my_spiffs_write; - cfg.hal_erase_f = my_spiffs_erase; - if (!get_spiffs_partition (&cfg)) - return false; + spiffs_config cfg; + cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet + cfg.log_page_size = LOG_PAGE_SIZE; // as we said + cfg.log_block_size = LOG_BLOCK_SIZE; + cfg.hal_read_f = my_spiffs_read; + cfg.hal_write_f = my_spiffs_write; + cfg.hal_erase_f = my_spiffs_erase; + if (!get_spiffs_partition(&cfg)) + return false; #if SPIFFS_USE_MAGIC - if (!force_mount && SPIFFS_probe_fs (&cfg) != cfg.phys_size) { - return false; - } + if (!force_mount && SPIFFS_probe_fs(&cfg) != cfg.phys_size) + { + return false; + } #endif - fs.err_code = 0; - - int res = SPIFFS_mount(&fs, - &cfg, - spiffs_work_buf, - spiffs_fds, - sizeof(spiffs_fds), - spiffs_cache, - sizeof(spiffs_cache), - // myspiffs_check_callback); - 0); - NODE_DBG("mount res: %d, %d\n", res, fs.err_code); - return res == SPIFFS_OK; -} + fs.err_code = 0; -bool myspiffs_mount() { - return myspiffs_mount_internal(false); + int res = + SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, sizeof(spiffs_fds), spiffs_cache, sizeof(spiffs_cache), + // myspiffs_check_callback); + 0); + NODE_DBG("mount res: %d, %d\n", res, fs.err_code); + return res == SPIFFS_OK; } -void myspiffs_unmount() { - SPIFFS_unmount(&fs); -} +bool myspiffs_mount() { return myspiffs_mount_internal(false); } + +void myspiffs_unmount() { SPIFFS_unmount(&fs); } // FS formatting function // Returns 1 if OK, 0 for error -int myspiffs_format( void ) +int myspiffs_format(void) { - SPIFFS_unmount(&fs); - myspiffs_mount_internal(true); - SPIFFS_unmount(&fs); + SPIFFS_unmount(&fs); + myspiffs_mount_internal(true); + SPIFFS_unmount(&fs); - NODE_DBG("Formatting: size 0x%x, addr 0x%x\n", fs.cfg.phys_size, fs.cfg.phys_addr); - NODE_DBG("Waiting ..."); + NODE_DBG("Formatting: size 0x%x, addr 0x%x\n", fs.cfg.phys_size, fs.cfg.phys_addr); + NODE_DBG("Waiting ..."); - s32_t res = SPIFFS_format (&fs); - if (res < 0) { - printf("format failed myspiffs_format\n"); - return 0; - } - return myspiffs_mount(); + s32_t res = SPIFFS_format(&fs); + if (res < 0) + { + printf("format failed myspiffs_format\n"); + return 0; + } + return myspiffs_mount(); } +void test_spiffs() +{ + char buf[12]; -void test_spiffs() { - char buf[12]; + // Surely, I've mounted spiffs before entering here - // Surely, I've mounted spiffs before entering here - - spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); - printf("fd=%d\n", fd); - if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) NODE_DBG("write errno %i\n", SPIFFS_errno(&fs)); - SPIFFS_close(&fs, fd); + spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); + printf("fd=%d\n", fd); + if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) + NODE_DBG("write errno %i\n", SPIFFS_errno(&fs)); + SPIFFS_close(&fs, fd); - fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0); - printf("fd=%d\n", fd); - if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) NODE_DBG("read errno %i\n", SPIFFS_errno(&fs)); - SPIFFS_close(&fs, fd); + fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0); + printf("fd=%d\n", fd); + if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) + NODE_DBG("read errno %i\n", SPIFFS_errno(&fs)); + SPIFFS_close(&fs, fd); - NODE_DBG("--> %s <--\n", buf); + NODE_DBG("--> %s <--\n", buf); } - - // *************************************************************************** // vfs API // *************************************************************************** #include + #include "vfs_int.h" #define MY_LDRV_ID "FLASH" @@ -195,392 +193,418 @@ void test_spiffs() { static int is_current_drive = true; // forward declarations -static int32_t myspiffs_vfs_close( const struct vfs_file *fd ); -static int32_t myspiffs_vfs_read( const struct vfs_file *fd, void *ptr, size_t len ); -static int32_t myspiffs_vfs_write( const struct vfs_file *fd, const void *ptr, size_t len ); -static int32_t myspiffs_vfs_lseek( const struct vfs_file *fd, int32_t off, int whence ); -static int32_t myspiffs_vfs_eof( const struct vfs_file *fd ); -static int32_t myspiffs_vfs_tell( const struct vfs_file *fd ); -static int32_t myspiffs_vfs_flush( const struct vfs_file *fd ); -static int32_t myspiffs_vfs_ferrno( const struct vfs_file *fd ); - -static int32_t myspiffs_vfs_closedir( const struct vfs_dir *dd ); -static vfs_item *myspiffs_vfs_readdir( const struct vfs_dir *dd ); - -static void myspiffs_vfs_iclose( const struct vfs_item *di ); -static uint32_t myspiffs_vfs_isize( const struct vfs_item *di ); -//static const struct tm *myspiffs_vfs_time( const struct vfs_item *di ); -static const char *myspiffs_vfs_name( const struct vfs_item *di ); - -static vfs_vol *myspiffs_vfs_mount( const char *name, int num ); -static vfs_file *myspiffs_vfs_open( const char *name, const char *mode ); -static vfs_dir *myspiffs_vfs_opendir( const char *name ); -static vfs_item *myspiffs_vfs_stat( const char *name ); -static int32_t myspiffs_vfs_remove( const char *name ); -static int32_t myspiffs_vfs_rename( const char *oldname, const char *newname ); -static int32_t myspiffs_vfs_fsinfo( uint32_t *total, uint32_t *used ); -static int32_t myspiffs_vfs_fscfg( uint32_t *phys_addr, uint32_t *phys_size ); -static int32_t myspiffs_vfs_format( void ); -static int32_t myspiffs_vfs_errno( void ); -static void myspiffs_vfs_clearerr( void ); - -static int32_t myspiffs_vfs_umount( const struct vfs_vol *vol ); +static int32_t myspiffs_vfs_close(const struct vfs_file *fd); +static int32_t myspiffs_vfs_read(const struct vfs_file *fd, void *ptr, size_t len); +static int32_t myspiffs_vfs_write(const struct vfs_file *fd, const void *ptr, size_t len); +static int32_t myspiffs_vfs_lseek(const struct vfs_file *fd, int32_t off, int whence); +static int32_t myspiffs_vfs_eof(const struct vfs_file *fd); +static int32_t myspiffs_vfs_tell(const struct vfs_file *fd); +static int32_t myspiffs_vfs_flush(const struct vfs_file *fd); +static int32_t myspiffs_vfs_ferrno(const struct vfs_file *fd); + +static int32_t myspiffs_vfs_closedir(const struct vfs_dir *dd); +static vfs_item *myspiffs_vfs_readdir(const struct vfs_dir *dd); + +static void myspiffs_vfs_iclose(const struct vfs_item *di); +static uint32_t myspiffs_vfs_isize(const struct vfs_item *di); +// static const struct tm *myspiffs_vfs_time( const struct vfs_item *di ); +static const char *myspiffs_vfs_name(const struct vfs_item *di); + +static vfs_vol *myspiffs_vfs_mount(const char *name, int num); +static vfs_file *myspiffs_vfs_open(const char *name, const char *mode); +static vfs_dir *myspiffs_vfs_opendir(const char *name); +static vfs_item *myspiffs_vfs_stat(const char *name); +static int32_t myspiffs_vfs_remove(const char *name); +static int32_t myspiffs_vfs_rename(const char *oldname, const char *newname); +static int32_t myspiffs_vfs_fsinfo(uint32_t *total, uint32_t *used); +static int32_t myspiffs_vfs_fscfg(uint32_t *phys_addr, uint32_t *phys_size); +static int32_t myspiffs_vfs_format(void); +static int32_t myspiffs_vfs_errno(void); +static void myspiffs_vfs_clearerr(void); + +static int32_t myspiffs_vfs_umount(const struct vfs_vol *vol); // --------------------------------------------------------------------------- // function tables // -static vfs_fs_fns myspiffs_fs_fns = { - .mount = myspiffs_vfs_mount, - .open = myspiffs_vfs_open, - .opendir = myspiffs_vfs_opendir, - .stat = myspiffs_vfs_stat, - .remove = myspiffs_vfs_remove, - .rename = myspiffs_vfs_rename, - .mkdir = NULL, - .fsinfo = myspiffs_vfs_fsinfo, - .fscfg = myspiffs_vfs_fscfg, - .format = myspiffs_vfs_format, - .chdrive = NULL, - .chdir = NULL, - .ferrno = myspiffs_vfs_errno, - .clearerr = myspiffs_vfs_clearerr -}; - -static vfs_file_fns myspiffs_file_fns = { - .close = myspiffs_vfs_close, - .read = myspiffs_vfs_read, - .write = myspiffs_vfs_write, - .lseek = myspiffs_vfs_lseek, - .eof = myspiffs_vfs_eof, - .tell = myspiffs_vfs_tell, - .flush = myspiffs_vfs_flush, - .size = NULL, - .ferrno = myspiffs_vfs_ferrno -}; - -static vfs_item_fns myspiffs_item_fns = { - .close = myspiffs_vfs_iclose, - .size = myspiffs_vfs_isize, - .time = NULL, - .name = myspiffs_vfs_name, - .is_dir = NULL, - .is_rdonly = NULL, - .is_hidden = NULL, - .is_sys = NULL, - .is_arch = NULL -}; - -static vfs_dir_fns myspiffs_dd_fns = { - .close = myspiffs_vfs_closedir, - .readdir = myspiffs_vfs_readdir -}; - +static vfs_fs_fns myspiffs_fs_fns = {.mount = myspiffs_vfs_mount, + .open = myspiffs_vfs_open, + .opendir = myspiffs_vfs_opendir, + .stat = myspiffs_vfs_stat, + .remove = myspiffs_vfs_remove, + .rename = myspiffs_vfs_rename, + .mkdir = NULL, + .fsinfo = myspiffs_vfs_fsinfo, + .fscfg = myspiffs_vfs_fscfg, + .format = myspiffs_vfs_format, + .chdrive = NULL, + .chdir = NULL, + .ferrno = myspiffs_vfs_errno, + .clearerr = myspiffs_vfs_clearerr}; + +static vfs_file_fns myspiffs_file_fns = {.close = myspiffs_vfs_close, + .read = myspiffs_vfs_read, + .write = myspiffs_vfs_write, + .lseek = myspiffs_vfs_lseek, + .eof = myspiffs_vfs_eof, + .tell = myspiffs_vfs_tell, + .flush = myspiffs_vfs_flush, + .size = NULL, + .ferrno = myspiffs_vfs_ferrno}; + +static vfs_item_fns myspiffs_item_fns = {.close = myspiffs_vfs_iclose, + .size = myspiffs_vfs_isize, + .time = NULL, + .name = myspiffs_vfs_name, + .is_dir = NULL, + .is_rdonly = NULL, + .is_hidden = NULL, + .is_sys = NULL, + .is_arch = NULL}; + +static vfs_dir_fns myspiffs_dd_fns = {.close = myspiffs_vfs_closedir, .readdir = myspiffs_vfs_readdir}; // --------------------------------------------------------------------------- // specific struct extensions // -struct myvfs_file { - struct vfs_file vfs_file; - spiffs_file fh; +struct myvfs_file +{ + struct vfs_file vfs_file; + spiffs_file fh; }; -struct myvfs_dir { - struct vfs_dir vfs_dir; - spiffs_DIR d; +struct myvfs_dir +{ + struct vfs_dir vfs_dir; + spiffs_DIR d; }; -struct myvfs_stat { - struct vfs_item vfs_item; - spiffs_stat s; +struct myvfs_stat +{ + struct vfs_item vfs_item; + spiffs_stat s; }; - // --------------------------------------------------------------------------- // stat functions // -#define GET_STAT_S(descr) \ - const struct myvfs_stat *mystat = (const struct myvfs_stat *)descr; \ - spiffs_stat *s = (spiffs_stat *)&(mystat->s); +#define GET_STAT_S(descr) \ + const struct myvfs_stat *mystat = (const struct myvfs_stat *)descr; \ + spiffs_stat *s = (spiffs_stat *)&(mystat->s); -static void myspiffs_vfs_iclose( const struct vfs_item *di ) { - // free descriptor memory - free( (void *)di ); +static void myspiffs_vfs_iclose(const struct vfs_item *di) +{ + // free descriptor memory + free((void *)di); } -static uint32_t myspiffs_vfs_isize( const struct vfs_item *di ) { - GET_STAT_S(di); +static uint32_t myspiffs_vfs_isize(const struct vfs_item *di) +{ + GET_STAT_S(di); - return s->size; + return s->size; } -static const char *myspiffs_vfs_name( const struct vfs_item *di ) { - GET_STAT_S(di); +static const char *myspiffs_vfs_name(const struct vfs_item *di) +{ + GET_STAT_S(di); - return (const char *)s->name; + return (const char *)s->name; } - // --------------------------------------------------------------------------- // volume functions // -static int32_t myspiffs_vfs_umount( const struct vfs_vol *vol ) { - // not implemented +static int32_t myspiffs_vfs_umount(const struct vfs_vol *vol) +{ + // not implemented - return VFS_RES_ERR; + return VFS_RES_ERR; } - // --------------------------------------------------------------------------- // dir functions // -#define GET_DIR_D(descr) \ - const struct myvfs_dir *mydd = (const struct myvfs_dir *)descr; \ - spiffs_DIR *d = (spiffs_DIR *)&(mydd->d); +#define GET_DIR_D(descr) \ + const struct myvfs_dir *mydd = (const struct myvfs_dir *)descr; \ + spiffs_DIR *d = (spiffs_DIR *)&(mydd->d); -static int32_t myspiffs_vfs_closedir( const struct vfs_dir *dd ) { - GET_DIR_D(dd); +static int32_t myspiffs_vfs_closedir(const struct vfs_dir *dd) +{ + GET_DIR_D(dd); - int32_t res = SPIFFS_closedir( d ); + int32_t res = SPIFFS_closedir(d); - // free descriptor memory - free( (void *)dd ); + // free descriptor memory + free((void *)dd); - return res; + return res; } -static vfs_item *myspiffs_vfs_readdir( const struct vfs_dir *dd ) { - GET_DIR_D(dd); - struct myvfs_stat *stat; - struct spiffs_dirent dirent; - - if ((stat = malloc( sizeof( struct myvfs_stat ) ))) { - if (SPIFFS_readdir( d, &dirent )) { - stat->vfs_item.fs_type = VFS_FS_FATFS; - stat->vfs_item.fns = &myspiffs_item_fns; - // copy entries to vfs' directory item - stat->s.size = dirent.size; - strncpy((char *)stat->s.name, (char *)dirent.name, SPIFFS_OBJ_NAME_LEN ); - return (vfs_item *)stat; - } else { - free( stat ); +static vfs_item *myspiffs_vfs_readdir(const struct vfs_dir *dd) +{ + GET_DIR_D(dd); + struct myvfs_stat *stat; + struct spiffs_dirent dirent; + + if ((stat = malloc(sizeof(struct myvfs_stat)))) + { + if (SPIFFS_readdir(d, &dirent)) + { + stat->vfs_item.fs_type = VFS_FS_FATFS; + stat->vfs_item.fns = &myspiffs_item_fns; + // copy entries to vfs' directory item + stat->s.size = dirent.size; + strncpy((char *)stat->s.name, (char *)dirent.name, SPIFFS_OBJ_NAME_LEN); + return (vfs_item *)stat; + } + else + { + free(stat); + } } - } - return NULL; + return NULL; } - // --------------------------------------------------------------------------- // file functions // -#define GET_FILE_FH(descr) \ - const struct myvfs_file *myfd = (const struct myvfs_file *)descr; \ - spiffs_file fh = myfd->fh; +#define GET_FILE_FH(descr) \ + const struct myvfs_file *myfd = (const struct myvfs_file *)descr; \ + spiffs_file fh = myfd->fh; -static int32_t myspiffs_vfs_close( const struct vfs_file *fd ) { - GET_FILE_FH(fd); +static int32_t myspiffs_vfs_close(const struct vfs_file *fd) +{ + GET_FILE_FH(fd); - int32_t res = SPIFFS_close( &fs, fh ); + int32_t res = SPIFFS_close(&fs, fh); - // free descriptor memory - free( (void *)fd ); + // free descriptor memory + free((void *)fd); - return res; + return res; } -static int32_t myspiffs_vfs_read( const struct vfs_file *fd, void *ptr, size_t len ) { - GET_FILE_FH(fd); +static int32_t myspiffs_vfs_read(const struct vfs_file *fd, void *ptr, size_t len) +{ + GET_FILE_FH(fd); - return SPIFFS_read( &fs, fh, ptr, len ); + return SPIFFS_read(&fs, fh, ptr, len); } -static int32_t myspiffs_vfs_write( const struct vfs_file *fd, const void *ptr, size_t len ) { - GET_FILE_FH(fd); +static int32_t myspiffs_vfs_write(const struct vfs_file *fd, const void *ptr, size_t len) +{ + GET_FILE_FH(fd); - return SPIFFS_write( &fs, fh, (void *)ptr, len ); + return SPIFFS_write(&fs, fh, (void *)ptr, len); } -static int32_t myspiffs_vfs_lseek( const struct vfs_file *fd, int32_t off, int whence ) { - GET_FILE_FH(fd); - int spiffs_whence; - - switch (whence) { - default: - case VFS_SEEK_SET: - spiffs_whence = SPIFFS_SEEK_SET; - break; - case VFS_SEEK_CUR: - spiffs_whence = SPIFFS_SEEK_CUR; - break; - case VFS_SEEK_END: - spiffs_whence = SPIFFS_SEEK_END; - break; - } - - return SPIFFS_lseek( &fs, fh, off, spiffs_whence ); -} +static int32_t myspiffs_vfs_lseek(const struct vfs_file *fd, int32_t off, int whence) +{ + GET_FILE_FH(fd); + int spiffs_whence; -static int32_t myspiffs_vfs_eof( const struct vfs_file *fd ) { - GET_FILE_FH(fd); + switch (whence) + { + default: + case VFS_SEEK_SET: + spiffs_whence = SPIFFS_SEEK_SET; + break; + case VFS_SEEK_CUR: + spiffs_whence = SPIFFS_SEEK_CUR; + break; + case VFS_SEEK_END: + spiffs_whence = SPIFFS_SEEK_END; + break; + } - return SPIFFS_eof( &fs, fh ); + return SPIFFS_lseek(&fs, fh, off, spiffs_whence); } -static int32_t myspiffs_vfs_tell( const struct vfs_file *fd ) { - GET_FILE_FH(fd); +static int32_t myspiffs_vfs_eof(const struct vfs_file *fd) +{ + GET_FILE_FH(fd); - return SPIFFS_tell( &fs, fh ); + return SPIFFS_eof(&fs, fh); } -static int32_t myspiffs_vfs_flush( const struct vfs_file *fd ) { - GET_FILE_FH(fd); +static int32_t myspiffs_vfs_tell(const struct vfs_file *fd) +{ + GET_FILE_FH(fd); - return SPIFFS_fflush( &fs, fh ) >= 0 ? VFS_RES_OK : VFS_RES_ERR; + return SPIFFS_tell(&fs, fh); } -static int32_t myspiffs_vfs_ferrno( const struct vfs_file *fd ) { - return SPIFFS_errno( &fs ); +static int32_t myspiffs_vfs_flush(const struct vfs_file *fd) +{ + GET_FILE_FH(fd); + + return SPIFFS_fflush(&fs, fh) >= 0 ? VFS_RES_OK : VFS_RES_ERR; } +static int32_t myspiffs_vfs_ferrno(const struct vfs_file *fd) { return SPIFFS_errno(&fs); } -static int fs_mode2flag(const char *mode){ - if(strlen(mode)==1){ - if(strcmp(mode,"w")==0) - return SPIFFS_WRONLY|SPIFFS_CREAT|SPIFFS_TRUNC; - else if(strcmp(mode, "r")==0) - return SPIFFS_RDONLY; - else if(strcmp(mode, "a")==0) - return SPIFFS_WRONLY|SPIFFS_CREAT|SPIFFS_APPEND; - else - return SPIFFS_RDONLY; - } else if (strlen(mode)==2){ - if(strcmp(mode,"r+")==0) - return SPIFFS_RDWR; - else if(strcmp(mode, "w+")==0) - return SPIFFS_RDWR|SPIFFS_CREAT|SPIFFS_TRUNC; - else if(strcmp(mode, "a+")==0) - return SPIFFS_RDWR|SPIFFS_CREAT|SPIFFS_APPEND; - else - return SPIFFS_RDONLY; - } else { - return SPIFFS_RDONLY; - } +static int fs_mode2flag(const char *mode) +{ + if (strlen(mode) == 1) + { + if (strcmp(mode, "w") == 0) + return SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC; + else if (strcmp(mode, "r") == 0) + return SPIFFS_RDONLY; + else if (strcmp(mode, "a") == 0) + return SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND; + else + return SPIFFS_RDONLY; + } + else if (strlen(mode) == 2) + { + if (strcmp(mode, "r+") == 0) + return SPIFFS_RDWR; + else if (strcmp(mode, "w+") == 0) + return SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC; + else if (strcmp(mode, "a+") == 0) + return SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_APPEND; + else + return SPIFFS_RDONLY; + } + else + { + return SPIFFS_RDONLY; + } } // --------------------------------------------------------------------------- // filesystem functions // -static vfs_file *myspiffs_vfs_open( const char *name, const char *mode ) { - struct myvfs_file *fd; - int flags = fs_mode2flag( mode ); - if ((fd = (struct myvfs_file *)malloc( sizeof( struct myvfs_file ) ))) { - if (0 < (fd->fh = SPIFFS_open( &fs, name, flags, 0 ))) { - fd->vfs_file.fs_type = VFS_FS_SPIFFS; - fd->vfs_file.fns = &myspiffs_file_fns; - return (vfs_file *)fd; - } else { - free( fd ); +static vfs_file *myspiffs_vfs_open(const char *name, const char *mode) +{ + struct myvfs_file *fd; + int flags = fs_mode2flag(mode); + if ((fd = (struct myvfs_file *)malloc(sizeof(struct myvfs_file)))) + { + if (0 < (fd->fh = SPIFFS_open(&fs, name, flags, 0))) + { + fd->vfs_file.fs_type = VFS_FS_SPIFFS; + fd->vfs_file.fns = &myspiffs_file_fns; + return (vfs_file *)fd; + } + else + { + free(fd); + } } - } - //test_spiffs(); + // test_spiffs(); - return NULL; + return NULL; } -static vfs_dir *myspiffs_vfs_opendir( const char *name ){ - struct myvfs_dir *dd; +static vfs_dir *myspiffs_vfs_opendir(const char *name) +{ + struct myvfs_dir *dd; - if ((dd = (struct myvfs_dir *)malloc( sizeof( struct myvfs_dir ) ))) { - if (SPIFFS_opendir( &fs, name, &(dd->d) )) { - dd->vfs_dir.fs_type = VFS_FS_SPIFFS; - dd->vfs_dir.fns = &myspiffs_dd_fns; - return (vfs_dir *)dd; - } else { - free( dd ); + if ((dd = (struct myvfs_dir *)malloc(sizeof(struct myvfs_dir)))) + { + if (SPIFFS_opendir(&fs, name, &(dd->d))) + { + dd->vfs_dir.fs_type = VFS_FS_SPIFFS; + dd->vfs_dir.fns = &myspiffs_dd_fns; + return (vfs_dir *)dd; + } + else + { + free(dd); + } } - } - return NULL; + return NULL; } -static vfs_item *myspiffs_vfs_stat( const char *name ) { - struct myvfs_stat *s; +static vfs_item *myspiffs_vfs_stat(const char *name) +{ + struct myvfs_stat *s; - if ((s = (struct myvfs_stat *)malloc( sizeof( struct myvfs_stat ) ))) { - if (0 <= SPIFFS_stat( &fs, name, &(s->s) )) { - s->vfs_item.fs_type = VFS_FS_SPIFFS; - s->vfs_item.fns = &myspiffs_item_fns; - return (vfs_item *)s; - } else { - free( s ); + if ((s = (struct myvfs_stat *)malloc(sizeof(struct myvfs_stat)))) + { + if (0 <= SPIFFS_stat(&fs, name, &(s->s))) + { + s->vfs_item.fs_type = VFS_FS_SPIFFS; + s->vfs_item.fns = &myspiffs_item_fns; + return (vfs_item *)s; + } + else + { + free(s); + } } - } - return NULL; + return NULL; } -static int32_t myspiffs_vfs_remove( const char *name ) { - return SPIFFS_remove( &fs, name ); -} +static int32_t myspiffs_vfs_remove(const char *name) { return SPIFFS_remove(&fs, name); } -static int32_t myspiffs_vfs_rename( const char *oldname, const char *newname ) { - return SPIFFS_rename( &fs, oldname, newname ); -} - -static int32_t myspiffs_vfs_fsinfo( uint32_t *total, uint32_t *used ) { - return SPIFFS_info( &fs, total, used ); +static int32_t myspiffs_vfs_rename(const char *oldname, const char *newname) +{ + return SPIFFS_rename(&fs, oldname, newname); } -static int32_t myspiffs_vfs_fscfg( uint32_t *phys_addr, uint32_t *phys_size ) { - *phys_addr = fs.cfg.phys_addr; - *phys_size = fs.cfg.phys_size; - return VFS_RES_OK; -} +static int32_t myspiffs_vfs_fsinfo(uint32_t *total, uint32_t *used) { return SPIFFS_info(&fs, total, used); } -static vfs_vol *myspiffs_vfs_mount( const char *name, int num ) { - // volume descriptor not supported, just return true / false - return myspiffs_mount() ? (vfs_vol *)1 : NULL; +static int32_t myspiffs_vfs_fscfg(uint32_t *phys_addr, uint32_t *phys_size) +{ + *phys_addr = fs.cfg.phys_addr; + *phys_size = fs.cfg.phys_size; + return VFS_RES_OK; } -static int32_t myspiffs_vfs_format( void ) { - return myspiffs_format(); +static vfs_vol *myspiffs_vfs_mount(const char *name, int num) +{ + // volume descriptor not supported, just return true / false + return myspiffs_mount() ? (vfs_vol *)1 : NULL; } -static int32_t myspiffs_vfs_errno( void ) { - return SPIFFS_errno( &fs ); -} +static int32_t myspiffs_vfs_format(void) { return myspiffs_format(); } -static void myspiffs_vfs_clearerr( void ) { - SPIFFS_clearerr( &fs ); -} +static int32_t myspiffs_vfs_errno(void) { return SPIFFS_errno(&fs); } +static void myspiffs_vfs_clearerr(void) { SPIFFS_clearerr(&fs); } // --------------------------------------------------------------------------- // VFS interface functions // -vfs_fs_fns *myspiffs_realm( const char *inname, char **outname, int set_current_drive ) { - if (inname[0] == '/') { - size_t idstr_len = strlen( MY_LDRV_ID ); - // logical drive is specified, check if it's our id - if (0 == strncmp( &(inname[1]), MY_LDRV_ID, idstr_len )) { - *outname = (char *)&(inname[1 + idstr_len]); - if (*outname[0] == '/') { - // skip leading / - (*outname)++; - } - - if (set_current_drive) is_current_drive = true; - return &myspiffs_fs_fns; +vfs_fs_fns *myspiffs_realm(const char *inname, char **outname, int set_current_drive) +{ + if (inname[0] == '/') + { + size_t idstr_len = strlen(MY_LDRV_ID); + // logical drive is specified, check if it's our id + if (0 == strncmp(&(inname[1]), MY_LDRV_ID, idstr_len)) + { + *outname = (char *)&(inname[1 + idstr_len]); + if (*outname[0] == '/') + { + // skip leading / + (*outname)++; + } + + if (set_current_drive) + is_current_drive = true; + return &myspiffs_fs_fns; + } } - } else { - // no logical drive in patchspec, are we current drive? - if (is_current_drive) { - *outname = (char *)inname; - return &myspiffs_fs_fns; + else + { + // no logical drive in patchspec, are we current drive? + if (is_current_drive) + { + *outname = (char *)inname; + return &myspiffs_fs_fns; + } } - } - if (set_current_drive) is_current_drive = false; - return NULL; + if (set_current_drive) + is_current_drive = false; + return NULL; } diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_cache.c b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_cache.c index 4e68b9f..0d65089 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_cache.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_cache.c @@ -5,296 +5,325 @@ * Author: petera */ +#include + #include "spiffs.h" #include "spiffs_nucleus.h" -#include #if SPIFFS_CACHE // returns cached page for give page index, or null if no such cached page -static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) { - spiffs_cache *cache = spiffs_get_cache(fs); - if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) return 0; - int i; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && - cp->pix == pix ) { - SPIFFS_CACHE_DBG("CACHE_GET: have cache page %i for %04x\n", i, pix); - cp->last_access = cache->last_access; - return cp; +static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) +{ + spiffs_cache *cache = spiffs_get_cache(fs); + if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) + return 0; + int i; + for (i = 0; i < cache->cpage_count; i++) + { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->cpage_use_map & (1 << i)) && (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && cp->pix == pix) + { + SPIFFS_CACHE_DBG("CACHE_GET: have cache page %i for %04x\n", i, pix); + cp->last_access = cache->last_access; + return cp; + } } - } - //SPIFFS_CACHE_DBG("CACHE_GET: no cache for %04x\n", pix); - return 0; + // SPIFFS_CACHE_DBG("CACHE_GET: no cache for %04x\n", pix); + return 0; } // frees cached page -static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix); - if (cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && - (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { - u8_t *mem = spiffs_get_cache_page(fs, cache, ix); - res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); +static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) +{ + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix); + if (cache->cpage_use_map & (1 << ix)) + { + if (write_back && (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) + { + u8_t *mem = spiffs_get_cache_page(fs, cache, ix); + res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); + } + + cp->flags = 0; + cache->cpage_use_map &= ~(1 << ix); + + if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) + { + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i objid %04x\n", ix, cp->obj_id); + } + else + { + SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i pix %04x\n", ix, cp->pix); + } } - cp->flags = 0; - cache->cpage_use_map &= ~(1 << ix); - - if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i objid %04x\n", ix, cp->obj_id); - } else { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i pix %04x\n", ix, cp->pix); - } - } - - return res; + return res; } // removes the oldest accessed cached page -static s32_t spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) { - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - - if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) { - // at least one free cpage - return SPIFFS_OK; - } - - // all busy, scan thru all to find the cpage which has oldest access - int i; - int cand_ix = -1; - u32_t oldest_val = 0; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->last_access - cp->last_access) > oldest_val && - (cp->flags & flag_mask) == flags) { - oldest_val = cache->last_access - cp->last_access; - cand_ix = i; +static s32_t spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) +{ + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + + if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) + { + // at least one free cpage + return SPIFFS_OK; } - } - if (cand_ix >= 0) { - res = spiffs_cache_page_free(fs, cand_ix, 1); - } + // all busy, scan thru all to find the cpage which has oldest access + int i; + int cand_ix = -1; + u32_t oldest_val = 0; + for (i = 0; i < cache->cpage_count; i++) + { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->last_access - cp->last_access) > oldest_val && (cp->flags & flag_mask) == flags) + { + oldest_val = cache->last_access - cp->last_access; + cand_ix = i; + } + } - return res; + if (cand_ix >= 0) + { + res = spiffs_cache_page_free(fs, cand_ix, 1); + } + + return res; } -// allocates a new cached page and returns it, or null if all cache pages are busy -static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) { - spiffs_cache *cache = spiffs_get_cache(fs); - if (cache->cpage_use_map == 0xffffffff) { - // out of cache memory - return 0; - } - int i; - for (i = 0; i < cache->cpage_count; i++) { - if ((cache->cpage_use_map & (1<cpage_use_map |= (1<last_access = cache->last_access; - SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %i\n", i); - return cp; +// allocates a new cached page and returns it, or null if all cache pages are +// busy +static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) +{ + spiffs_cache *cache = spiffs_get_cache(fs); + if (cache->cpage_use_map == 0xffffffff) + { + // out of cache memory + return 0; } - } - // out of cache entries - return 0; + int i; + for (i = 0; i < cache->cpage_count; i++) + { + if ((cache->cpage_use_map & (1 << i)) == 0) + { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + cache->cpage_use_map |= (1 << i); + cp->last_access = cache->last_access; + SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %i\n", i); + return cp; + } + } + // out of cache entries + return 0; } // drops the cache page for give page index -void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) { - spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); - if (cp) { - spiffs_cache_page_free(fs, cp->ix, 0); - } +void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) +{ + spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); + if (cp) + { + spiffs_cache_page_free(fs, cp->ix, 0); + } } // ------------------------------ // reads from spi flash or the cache -s32_t spiffs_phys_rd( - spiffs *fs, - u8_t op, - spiffs_file fh, - u32_t addr, - u32_t len, - u8_t *dst) { - (void)fh; - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); - cache->last_access++; - if (cp) { +s32_t spiffs_phys_rd(spiffs *fs, u8_t op, spiffs_file fh, u32_t addr, u32_t len, u8_t *dst) +{ + (void)fh; + s32_t res = SPIFFS_OK; + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); + cache->last_access++; + if (cp) + { #if SPIFFS_CACHE_STATS - fs->cache_hits++; + fs->cache_hits++; #endif - cp->last_access = cache->last_access; - } else { - if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { - // for second layer lookup functions, we do not cache in order to prevent shredding - return SPIFFS_HAL_READ(fs, addr, len, dst); + cp->last_access = cache->last_access; } + else + { + if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) + { + // for second layer lookup functions, we do not cache in order to + // prevent shredding + return SPIFFS_HAL_READ(fs, addr, len, dst); + } #if SPIFFS_CACHE_STATS - fs->cache_misses++; + fs->cache_misses++; #endif - res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); - cp = spiffs_cache_page_allocate(fs); - if (cp) { - cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; - cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - } - s32_t res2 = SPIFFS_HAL_READ(fs, - addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), - SPIFFS_CFG_LOG_PAGE_SZ(fs), - spiffs_get_cache_page(fs, cache, cp->ix)); - if (res2 != SPIFFS_OK) { - res = res2; + res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); + cp = spiffs_cache_page_allocate(fs); + if (cp) + { + cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; + cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); + } + s32_t res2 = SPIFFS_HAL_READ(fs, addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), SPIFFS_CFG_LOG_PAGE_SZ(fs), + spiffs_get_cache_page(fs, cache, cp->ix)); + if (res2 != SPIFFS_OK) + { + res = res2; + } } - } - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); - return res; + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); + return res; } // writes to spi flash and/or the cache -s32_t spiffs_phys_wr( - spiffs *fs, - u8_t op, - spiffs_file fh, - u32_t addr, - u32_t len, - u8_t *src) { - (void)fh; - spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); - - if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) { - // have a cache page - // copy in data to cache page - - if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && - (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { - // page is being deleted, wipe from cache - unless it is a lookup page - spiffs_cache_page_free(fs, cp->ix, 0); - return SPIFFS_HAL_WRITE(fs, addr, len, src); +s32_t spiffs_phys_wr(spiffs *fs, u8_t op, spiffs_file fh, u32_t addr, u32_t len, u8_t *src) +{ + (void)fh; + spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); + spiffs_cache *cache = spiffs_get_cache(fs); + spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); + + if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) + { + // have a cache page + // copy in data to cache page + + if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) + { + // page is being deleted, wipe from cache - unless it is a lookup + // page + spiffs_cache_page_free(fs, cp->ix, 0); + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } + + u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); + memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); + + cache->last_access++; + cp->last_access = cache->last_access; + + if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) + { + // page is being updated, no write-cache, just pass thru + return SPIFFS_HAL_WRITE(fs, addr, len, src); + } + else + { + return SPIFFS_OK; + } } - - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); - - cache->last_access++; - cp->last_access = cache->last_access; - - if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) { - // page is being updated, no write-cache, just pass thru - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } else { - return SPIFFS_OK; + else + { + // no cache page, no write cache - just write thru + return SPIFFS_HAL_WRITE(fs, addr, len, src); } - } else { - // no cache page, no write cache - just write thru - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } } #if SPIFFS_CACHE_WR // returns the cache page that this fd refers, or null if no cache page -spiffs_cache_page *spiffs_cache_page_get_by_fd(spiffs *fs, spiffs_fd *fd) { - spiffs_cache *cache = spiffs_get_cache(fs); +spiffs_cache_page *spiffs_cache_page_get_by_fd(spiffs *fs, spiffs_fd *fd) +{ + spiffs_cache *cache = spiffs_get_cache(fs); + + if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) + { + // all cpages free, no cpage cannot be assigned to obj_id + return 0; + } - if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) { - // all cpages free, no cpage cannot be assigned to obj_id - return 0; - } - - int i; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) && - cp->obj_id == fd->obj_id) { - return cp; + int i; + for (i = 0; i < cache->cpage_count; i++) + { + spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); + if ((cache->cpage_use_map & (1 << i)) && (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) && cp->obj_id == fd->obj_id) + { + return cp; + } } - } - return 0; + return 0; } // allocates a new cache page and refers this to given fd - flushes an old cache // page if all cache is busy -spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) { - // before this function is called, it is ensured that there is no already existing - // cache page with same object id - spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); - spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); - if (cp == 0) { - // could not get cache page - return 0; - } +spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) +{ + // before this function is called, it is ensured that there is no already + // existing cache page with same object id + spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); + spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); + if (cp == 0) + { + // could not get cache page + return 0; + } - cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; - cp->obj_id = fd->obj_id; - fd->cache_page = cp; - return cp; + cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; + cp->obj_id = fd->obj_id; + fd->cache_page = cp; + return cp; } // unrefers all fds that this cache page refers to and releases the cache page -void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) { - if (cp == 0) return; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) { - cur_fd->cache_page = 0; +void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) +{ + if (cp == 0) + return; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) + { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) + { + cur_fd->cache_page = 0; + } } - } - spiffs_cache_page_free(fs, cp->ix, 0); + spiffs_cache_page_free(fs, cp->ix, 0); - cp->obj_id = 0; + cp->obj_id = 0; } #endif // initializes the cache -void spiffs_cache_init(spiffs *fs) { - if (fs->cache == 0) return; - u32_t sz = fs->cache_size; - u32_t cache_mask = 0; - int i; - int cache_entries = - (sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs)); - if (cache_entries <= 0) return; - - for (i = 0; i < cache_entries; i++) { - cache_mask <<= 1; - cache_mask |= 1; - } - - spiffs_cache cache; - memset(&cache, 0, sizeof(spiffs_cache)); - cache.cpage_count = cache_entries; - cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); - - cache.cpage_use_map = 0xffffffff; - cache.cpage_use_mask = cache_mask; - memcpy(fs->cache, &cache, sizeof(spiffs_cache)); - - spiffs_cache *c = spiffs_get_cache(fs); - - memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); - - c->cpage_use_map &= ~(c->cpage_use_mask); - for (i = 0; i < cache.cpage_count; i++) { - spiffs_get_cache_page_hdr(fs, c, i)->ix = i; - } +void spiffs_cache_init(spiffs *fs) +{ + if (fs->cache == 0) + return; + u32_t sz = fs->cache_size; + u32_t cache_mask = 0; + int i; + int cache_entries = (sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs)); + if (cache_entries <= 0) + return; + + for (i = 0; i < cache_entries; i++) + { + cache_mask <<= 1; + cache_mask |= 1; + } + + spiffs_cache cache; + memset(&cache, 0, sizeof(spiffs_cache)); + cache.cpage_count = cache_entries; + cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); + + cache.cpage_use_map = 0xffffffff; + cache.cpage_use_mask = cache_mask; + memcpy(fs->cache, &cache, sizeof(spiffs_cache)); + + spiffs_cache *c = spiffs_get_cache(fs); + + memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); + + c->cpage_use_map &= ~(c->cpage_use_mask); + for (i = 0; i < cache.cpage_count; i++) { spiffs_get_cache_page_hdr(fs, c, i)->ix = i; } } -#endif // SPIFFS_CACHE +#endif // SPIFFS_CACHE diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_check.c b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_check.c index 0c6481b..0dd1b63 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_check.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_check.c @@ -8,34 +8,38 @@ * Look up consistency * Checks if indices in lookup pages are coherent with page headers * Object index consistency - * Checks if there are any orphaned object indices (missing object index headers). - * If an object index is found but not its header, the object index is deleted. - * This is critical for the following page consistency check. - * Page consistency - * Checks for pages that ought to be indexed, ought not to be indexed, are multiple indexed + * Checks if there are any orphaned object indices (missing object index + * headers). If an object index is found but not its header, the object index is + * deleted. This is critical for the following page consistency check. Page + * consistency Checks for pages that ought to be indexed, ought not to be + * indexed, are multiple indexed * * * Created on: Jul 7, 2013 * Author: petera */ +#include #include "spiffs.h" #include "spiffs_nucleus.h" -#include #if !SPIFFS_READ_ONLY #if SPIFFS_HAL_CALLBACK_EXTRA -#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ - do { \ - if ((_fs)->check_cb_f) (_fs)->check_cb_f((_fs), (_type), (_rep), (_arg1), (_arg2)); \ - } while (0) +#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ + do \ + { \ + if ((_fs)->check_cb_f) \ + (_fs)->check_cb_f((_fs), (_type), (_rep), (_arg1), (_arg2)); \ + } while (0) #else -#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ - do { \ - if ((_fs)->check_cb_f) (_fs)->check_cb_f((_type), (_rep), (_arg1), (_arg2)); \ - } while (0) +#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ + do \ + { \ + if ((_fs)->check_cb_f) \ + (_fs)->check_cb_f((_type), (_rep), (_arg1), (_arg2)); \ + } while (0) #endif //--------------------------------------- @@ -44,819 +48,1031 @@ // searches in the object indices and returns the referenced page index given // the object id and the data span index // destroys fs->lu_work -static s32_t spiffs_object_get_data_page_index_reference( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix data_spix, - spiffs_page_ix *pix, - spiffs_page_ix *objix_pix) { - s32_t res; - - // calculate object index span index for given data page span index - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // find obj index for obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, objix_pix); - SPIFFS_CHECK_RES(res); - - // load obj index entry - u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, *objix_pix); - if (objix_spix == 0) { - // get referenced page from object index header - addr += sizeof(spiffs_page_object_ix_header) + data_spix * sizeof(spiffs_page_ix); - } else { - // get referenced page from object index - addr += sizeof(spiffs_page_object_ix) + SPIFFS_OBJ_IX_ENTRY(fs, data_spix) * sizeof(spiffs_page_ix); - } - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, addr, sizeof(spiffs_page_ix), (u8_t *)pix); - - return res; +static s32_t spiffs_object_get_data_page_index_reference(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix data_spix, + spiffs_page_ix *pix, spiffs_page_ix *objix_pix) +{ + s32_t res; + + // calculate object index span index for given data page span index + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // find obj index for obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, objix_pix); + SPIFFS_CHECK_RES(res); + + // load obj index entry + u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, *objix_pix); + if (objix_spix == 0) + { + // get referenced page from object index header + addr += sizeof(spiffs_page_object_ix_header) + data_spix * sizeof(spiffs_page_ix); + } + else + { + // get referenced page from object index + addr += sizeof(spiffs_page_object_ix) + SPIFFS_OBJ_IX_ENTRY(fs, data_spix) * sizeof(spiffs_page_ix); + } + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, addr, sizeof(spiffs_page_ix), (u8_t *)pix); + + return res; } // copies page contents to a new page -static s32_t spiffs_rewrite_page(spiffs *fs, spiffs_page_ix cur_pix, spiffs_page_header *p_hdr, spiffs_page_ix *new_pix) { - s32_t res; - res = spiffs_page_allocate_data(fs, p_hdr->obj_id, p_hdr, 0,0,0,0, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, - SPIFFS_PAGE_TO_PADDR(fs, *new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - return res; +static s32_t spiffs_rewrite_page(spiffs *fs, spiffs_page_ix cur_pix, spiffs_page_header *p_hdr, spiffs_page_ix *new_pix) +{ + s32_t res; + res = spiffs_page_allocate_data(fs, p_hdr->obj_id, p_hdr, 0, 0, 0, 0, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, *new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + return res; } // rewrites the object index for given object id and replaces the // data page index to a new page index -static s32_t spiffs_rewrite_index(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix data_spix, spiffs_page_ix new_data_pix, spiffs_page_ix objix_pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - spiffs_page_ix free_pix; - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - - // calculate object index span index for given data page span index - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (objix_spix == 0) { - // calc index in index header - entry = data_spix; - } else { - // calc entry in index - entry = SPIFFS_OBJ_IX_ENTRY(fs, data_spix); - - } - // load index - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; - - // be ultra safe, double check header against provided data - if (objix_p_hdr->obj_id != obj_id) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_OBJ_ID_MISM; - } - if (objix_p_hdr->span_ix != objix_spix) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_SPIX_MISM; - } - if ((objix_p_hdr->flags & (SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_INDEX | - SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) != - (SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_DELET)) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_FLAGS_BAD; - } - - // rewrite in mem - if (objix_spix == 0) { - ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; - } else { - ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; - } - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&obj_id); - SPIFFS_CHECK_RES(res); - res = spiffs_page_delete(fs, objix_pix); - - return res; +static s32_t spiffs_rewrite_index(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix data_spix, + spiffs_page_ix new_data_pix, spiffs_page_ix objix_pix) +{ + s32_t res; + spiffs_block_ix bix; + int entry; + spiffs_page_ix free_pix; + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + + // calculate object index span index for given data page span index + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (objix_spix == 0) + { + // calc index in index header + entry = data_spix; + } + else + { + // calc entry in index + entry = SPIFFS_OBJ_IX_ENTRY(fs, data_spix); + } + // load index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; + + // be ultra safe, double check header against provided data + if (objix_p_hdr->obj_id != obj_id) + { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_OBJ_ID_MISM; + } + if (objix_p_hdr->span_ix != objix_spix) + { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_SPIX_MISM; + } + if ((objix_p_hdr->flags & (SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_INDEX | + SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) != + (SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_DELET)) + { + spiffs_page_delete(fs, free_pix); + return SPIFFS_ERR_CHECK_FLAGS_BAD; + } + + // rewrite in mem + if (objix_spix == 0) + { + ((spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; + } + else + { + ((spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = + new_data_pix; + } + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, 0, + SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + res = spiffs_page_delete(fs, objix_pix); + + return res; } // deletes an object just by marking object index header as deleted -static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) { - spiffs_page_ix objix_hdr_pix; - s32_t res; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id, 0, 0, &objix_hdr_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - return SPIFFS_OK; - } - SPIFFS_CHECK_RES(res); - u8_t flags = 0xff & ~SPIFFS_PH_FLAG_IXDELE; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&flags); - return res; +static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) +{ + spiffs_page_ix objix_hdr_pix; + s32_t res; + res = spiffs_obj_lu_find_id_and_span(fs, obj_id, 0, 0, &objix_hdr_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + return SPIFFS_OK; + } + SPIFFS_CHECK_RES(res); + u8_t flags = 0xff & ~SPIFFS_PH_FLAG_IXDELE; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, 0, + SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), sizeof(u8_t), + (u8_t *)&flags); + return res; } // validates the given look up entry static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, spiffs_page_header *p_hdr, - spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, int *reload_lu) { - (void)cur_block; - (void)cur_entry; - u8_t delete_page = 0; - s32_t res = SPIFFS_OK; - spiffs_page_ix objix_pix; - spiffs_page_ix ref_pix; - // check validity, take actions - if (((lu_obj_id == SPIFFS_OBJ_ID_DELETED) && (p_hdr->flags & SPIFFS_PH_FLAG_DELET)) || - ((lu_obj_id == SPIFFS_OBJ_ID_FREE) && (p_hdr->flags & SPIFFS_PH_FLAG_USED) == 0)) { - // look up entry deleted / free but used in page header - SPIFFS_CHECK_DBG("LU: pix %04x deleted/free in lu but not on page\n", cur_pix); - *reload_lu = 1; - delete_page = 1; - if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { - // header says data page - // data page can be removed if not referenced by some object index - res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - } else { - SPIFFS_CHECK_RES(res); - if (ref_pix == cur_pix) { - // data page referenced by object index but deleted in lu - // copy page to new place and re-write the object index to new place - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: data page not found elsewhere, rewriting %04x to new page %04x\n", cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - SPIFFS_CHECK_DBG("LU: FIXUP: %04x rewritten to %04x, affected objix_pix %04x\n", cur_pix, new_pix, objix_pix); - res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); - res = spiffs_page_delete(fs, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); - } else { - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); - } - SPIFFS_CHECK_RES(res); + spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, + int *reload_lu) +{ + (void)cur_block; + (void)cur_entry; + u8_t delete_page = 0; + s32_t res = SPIFFS_OK; + spiffs_page_ix objix_pix; + spiffs_page_ix ref_pix; + // check validity, take actions + if (((lu_obj_id == SPIFFS_OBJ_ID_DELETED) && (p_hdr->flags & SPIFFS_PH_FLAG_DELET)) || + ((lu_obj_id == SPIFFS_OBJ_ID_FREE) && (p_hdr->flags & SPIFFS_PH_FLAG_USED) == 0)) + { + // look up entry deleted / free but used in page header + SPIFFS_CHECK_DBG("LU: pix %04x deleted/free in lu but not on page\n", cur_pix); + *reload_lu = 1; + delete_page = 1; + if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) + { + // header says data page + // data page can be removed if not referenced by some object index + res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + // no object with this id, so remove page safely + res = SPIFFS_OK; + } + else + { + SPIFFS_CHECK_RES(res); + if (ref_pix == cur_pix) + { + // data page referenced by object index but deleted in lu + // copy page to new place and re-write the object index to + // new place + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_DBG( + "LU: FIXUP: data page not found elsewhere, rewriting " + "%04x to new page %04x\n", + cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + SPIFFS_CHECK_DBG( + "LU: FIXUP: %04x rewritten to %04x, affected objix_pix " + "%04x\n", + cur_pix, new_pix, objix_pix); + res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) + { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); + res = spiffs_page_delete(fs, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + } + else + { + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); + } + SPIFFS_CHECK_RES(res); + } + } } - } - } else { - // header says index page - // index page can be removed if other index with same obj_id and spanix is found - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, 0); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no such index page found, check for a data page amongst page headers - // lu cannot be trusted - res = spiffs_obj_lu_find_id_and_span_by_phdr(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, 0); - if (res == SPIFFS_OK) { // ignore other errors - // got a data page also, assume lu corruption only, rewrite to new page - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: ix page with data not found elsewhere, rewriting %04x to new page %04x\n", cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + else + { + // header says index page + // index page can be removed if other index with same obj_id and + // spanix is found + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, 0); + if (res == SPIFFS_ERR_NOT_FOUND) + { + // no such index page found, check for a data page amongst page + // headers lu cannot be trusted + res = spiffs_obj_lu_find_id_and_span_by_phdr(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, 0); + if (res == SPIFFS_OK) + { // ignore other errors + // got a data page also, assume lu corruption only, rewrite + // to new page + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_DBG( + "LU: FIXUP: ix page with data not found elsewhere, " + "rewriting %04x to new page %04x\n", + cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + } + } + else + { + SPIFFS_CHECK_RES(res); + } } - } else { - SPIFFS_CHECK_RES(res); - } } - } - if (lu_obj_id != SPIFFS_OBJ_ID_FREE && lu_obj_id != SPIFFS_OBJ_ID_DELETED) { - // look up entry used - if ((p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG) != (lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG)) { - SPIFFS_CHECK_DBG("LU: pix %04x differ in obj_id lu:%04x ph:%04x\n", cur_pix, lu_obj_id, p_hdr->obj_id); - delete_page = 1; - if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0 || - (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) || - (p_hdr->flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE)) == 0) { - // page deleted or not finalized, just remove it - } else { - if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { - // if data page, check for reference to this page - res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - } else { - SPIFFS_CHECK_RES(res); - // if found, rewrite page with object id, update index, and delete current - if (ref_pix == cur_pix) { - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); - res = spiffs_page_delete(fs, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - *reload_lu = 1; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); - } - SPIFFS_CHECK_RES(res); + if (lu_obj_id != SPIFFS_OBJ_ID_FREE && lu_obj_id != SPIFFS_OBJ_ID_DELETED) + { + // look up entry used + if ((p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG) != (lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG)) + { + SPIFFS_CHECK_DBG("LU: pix %04x differ in obj_id lu:%04x ph:%04x\n", cur_pix, lu_obj_id, p_hdr->obj_id); + delete_page = 1; + if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0 || (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) || + (p_hdr->flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE)) == 0) + { + // page deleted or not finalized, just remove it } - } - } else { - // else if index, check for other pages with both obj_id's and spanix - spiffs_page_ix objix_pix_lu, objix_pix_ph; - // see if other object index page exists for lookup obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_lu); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_lu = 0; - } - SPIFFS_CHECK_RES(res); - // see if other object index exists for page header obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_ph); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_ph = 0; - } - SPIFFS_CHECK_RES(res); - // if both obj_id's found, just delete current - if (objix_pix_ph == 0 || objix_pix_lu == 0) { - // otherwise try finding first corresponding data pages - spiffs_page_ix data_pix_lu, data_pix_ph; - // see if other data page exists for look up obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_lu); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_lu = 0; + else + { + if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) + { + // if data page, check for reference to this page + res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, + &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + // no object with this id, so remove page safely + res = SPIFFS_OK; + } + else + { + SPIFFS_CHECK_RES(res); + // if found, rewrite page with object id, update + // index, and delete current + if (ref_pix == cur_pix) + { + spiffs_page_ix new_pix; + res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) + { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); + res = spiffs_page_delete(fs, new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); + *reload_lu = 1; + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); + } + SPIFFS_CHECK_RES(res); + } + } + } + else + { + // else if index, check for other pages with both obj_id's + // and spanix + spiffs_page_ix objix_pix_lu, objix_pix_ph; + // see if other object index page exists for lookup obj id + // and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, + &objix_pix_lu); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + objix_pix_lu = 0; + } + SPIFFS_CHECK_RES(res); + // see if other object index exists for page header obj id + // and span index + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, + &objix_pix_ph); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + objix_pix_ph = 0; + } + SPIFFS_CHECK_RES(res); + // if both obj_id's found, just delete current + if (objix_pix_ph == 0 || objix_pix_lu == 0) + { + // otherwise try finding first corresponding data pages + spiffs_page_ix data_pix_lu, data_pix_ph; + // see if other data page exists for look up obj id and + // span index + res = + spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_lu); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + objix_pix_lu = 0; + } + SPIFFS_CHECK_RES(res); + // see if other data page exists for page header obj id + // and span index + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, + &data_pix_ph); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + objix_pix_ph = 0; + } + SPIFFS_CHECK_RES(res); + + spiffs_page_header new_ph; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL); + new_ph.span_ix = p_hdr->span_ix; + spiffs_page_ix new_pix; + if ((objix_pix_lu && data_pix_lu && data_pix_ph && objix_pix_ph == 0) || + (objix_pix_lu == 0 && data_pix_ph && objix_pix_ph == 0)) + { + // got a data page for page header obj id + // rewrite as obj_id_ph + new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; + res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); + SPIFFS_CHECK_DBG( + "LU: FIXUP: rewrite page %04x as %04x to pix " + "%04x\n", + cur_pix, new_ph.obj_id, new_pix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + } + else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || + (objix_pix_ph == 0 && data_pix_lu && objix_pix_lu == 0)) + { + // got a data page for look up obj id + // rewrite as obj_id_lu + new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; + SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x\n", cur_pix, new_ph.obj_id); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); + SPIFFS_CHECK_RES(res); + *reload_lu = 1; + } + else + { + // cannot safely do anything + SPIFFS_CHECK_DBG("LU: FIXUP: nothing to do, just delete\n"); + } + } + } + } + } + else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) || + ((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) + { + SPIFFS_CHECK_DBG("LU: %04x lu/page index marking differ\n", cur_pix); + spiffs_page_ix data_pix, objix_pix_d; + // see if other data page exists for given obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, + &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + data_pix = 0; } SPIFFS_CHECK_RES(res); - // see if other data page exists for page header obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_ph); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_ph = 0; + // see if other object index exists for given obj id and span index + res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, + &objix_pix_d); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + objix_pix_d = 0; } SPIFFS_CHECK_RES(res); - spiffs_page_header new_ph; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL); - new_ph.span_ix = p_hdr->span_ix; - spiffs_page_ix new_pix; - if ((objix_pix_lu && data_pix_lu && data_pix_ph && objix_pix_ph == 0) || - (objix_pix_lu == 0 && data_pix_ph && objix_pix_ph == 0)) { - // got a data page for page header obj id - // rewrite as obj_id_ph - new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; - res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x to pix %04x\n", cur_pix, new_ph.obj_id, new_pix); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - } else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || - (objix_pix_ph == 0 && data_pix_lu && objix_pix_lu == 0)) { - // got a data page for look up obj id - // rewrite as obj_id_lu - new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; - SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x\n", cur_pix, new_ph.obj_id); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - } else { - // cannot safely do anything - SPIFFS_CHECK_DBG("LU: FIXUP: nothing to do, just delete\n"); + delete_page = 1; + // if other data page exists and object index exists, just delete + // page + if (data_pix && objix_pix_d) + { + SPIFFS_CHECK_DBG( + "LU: FIXUP: other index and data page exists, simply " + "remove\n"); + } + else + // if only data page exists, make this page index + if (data_pix && objix_pix_d == 0) + { + SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n"); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); + spiffs_page_header new_ph; + spiffs_page_ix new_pix; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); + new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = p_hdr->span_ix; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); + SPIFFS_CHECK_RES(res); + } + else + // if only index exists, make data page + if (data_pix == 0 && objix_pix_d) + { + SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n"); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); + spiffs_page_header new_ph; + spiffs_page_ix new_pix; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); + new_ph.obj_id = lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = p_hdr->span_ix; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); + SPIFFS_CHECK_RES(res); + } + else + { + // if nothing exists, we cannot safely make a decision - delete } - } } - } - } else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) || - ((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) { - SPIFFS_CHECK_DBG("LU: %04x lu/page index marking differ\n", cur_pix); - spiffs_page_ix data_pix, objix_pix_d; - // see if other data page exists for given obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - // see if other object index exists for given obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix_d); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_d = 0; - } - SPIFFS_CHECK_RES(res); - - delete_page = 1; - // if other data page exists and object index exists, just delete page - if (data_pix && objix_pix_d) { - SPIFFS_CHECK_DBG("LU: FIXUP: other index and data page exists, simply remove\n"); - } else - // if only data page exists, make this page index - if (data_pix && objix_pix_d == 0) { - SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n"); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); - spiffs_page_header new_ph; - spiffs_page_ix new_pix; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); - new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = p_hdr->span_ix; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); - SPIFFS_CHECK_RES(res); - } else - // if only index exists, make data page - if (data_pix == 0 && objix_pix_d) { - SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n"); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); - spiffs_page_header new_ph; - spiffs_page_ix new_pix; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); - new_ph.obj_id = lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = p_hdr->span_ix; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); - SPIFFS_CHECK_RES(res); - } else { - // if nothing exists, we cannot safely make a decision - delete - } - } - else if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0) { - SPIFFS_CHECK_DBG("LU: pix %04x busy in lu but deleted on page\n", cur_pix); - delete_page = 1; - } else if ((p_hdr->flags & SPIFFS_PH_FLAG_FINAL)) { - SPIFFS_CHECK_DBG("LU: pix %04x busy but not final\n", cur_pix); - // page can be removed if not referenced by object index - *reload_lu = 1; - res = spiffs_object_get_data_page_index_reference(fs, lu_obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - delete_page = 1; - } else { - SPIFFS_CHECK_RES(res); - if (ref_pix != cur_pix) { - SPIFFS_CHECK_DBG("LU: FIXUP: other finalized page is referred, just delete\n"); - delete_page = 1; - } else { - // page referenced by object index but not final - // just finalize - SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n"); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - u8_t flags = 0xff & ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), (u8_t*)&flags); + else if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0) + { + SPIFFS_CHECK_DBG("LU: pix %04x busy in lu but deleted on page\n", cur_pix); + delete_page = 1; + } + else if ((p_hdr->flags & SPIFFS_PH_FLAG_FINAL)) + { + SPIFFS_CHECK_DBG("LU: pix %04x busy but not final\n", cur_pix); + // page can be removed if not referenced by object index + *reload_lu = 1; + res = spiffs_object_get_data_page_index_reference(fs, lu_obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + // no object with this id, so remove page safely + res = SPIFFS_OK; + delete_page = 1; + } + else + { + SPIFFS_CHECK_RES(res); + if (ref_pix != cur_pix) + { + SPIFFS_CHECK_DBG( + "LU: FIXUP: other finalized page is referred, just " + "delete\n"); + delete_page = 1; + } + else + { + // page referenced by object index but not final + // just finalize + SPIFFS_CHECK_DBG( + "LU: FIXUP: unfinalized page is referred, " + "finalizing\n"); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); + u8_t flags = 0xff & ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, + SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), (u8_t *)&flags); + } + } } - } } - } - if (delete_page) { - SPIFFS_CHECK_DBG("LU: FIXUP: deleting page %04x\n", cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - } + if (delete_page) + { + SPIFFS_CHECK_DBG("LU: FIXUP: deleting page %04x\n", cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + } - return res; + return res; } static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, int cur_entry, - const void *user_const_p, void *user_var_p) { - (void)user_const_p; - (void)user_var_p; - s32_t res = SPIFFS_OK; - spiffs_page_header p_hdr; - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, - (cur_block * 256)/fs->block_count, 0); - - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - int reload_lu = 0; - - res = spiffs_lookup_check_validate(fs, obj_id, &p_hdr, cur_pix, cur_block, cur_entry, &reload_lu); - SPIFFS_CHECK_RES(res); - - if (res == SPIFFS_OK) { - return reload_lu ? SPIFFS_VIS_COUNTINUE_RELOAD : SPIFFS_VIS_COUNTINUE; - } - return res; -} + const void *user_const_p, void *user_var_p) +{ + (void)user_const_p; + (void)user_var_p; + s32_t res = SPIFFS_OK; + spiffs_page_header p_hdr; + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, (cur_block * 256) / fs->block_count, 0); -// Scans all object look up. For each entry, corresponding page header is checked for validity. -// If an object index header page is found, this is also checked -s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { - (void)check_all_objects; - s32_t res = SPIFFS_OK; + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), + sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + + int reload_lu = 0; + + res = spiffs_lookup_check_validate(fs, obj_id, &p_hdr, cur_pix, cur_block, cur_entry, &reload_lu); + SPIFFS_CHECK_RES(res); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); + if (res == SPIFFS_OK) + { + return reload_lu ? SPIFFS_VIS_COUNTINUE_RELOAD : SPIFFS_VIS_COUNTINUE; + } + return res; +} - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); +// Scans all object look up. For each entry, corresponding page header is +// checked for validity. If an object index header page is found, this is also +// checked +s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) +{ + (void)check_all_objects; + s32_t res = SPIFFS_OK; - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); - } + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); + + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_OK; + } + + if (res != SPIFFS_OK) + { + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); + } - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); + CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; + return res; } //--------------------------------------- // Page consistency -// Scans all pages (except lu pages), reserves 4 bits in working memory for each page -// bit 0: 0 == FREE|DELETED, 1 == USED -// bit 1: 0 == UNREFERENCED, 1 == REFERENCED -// bit 2: 0 == NOT_INDEX, 1 == INDEX -// bit 3: unused -// A consistent file system will have only pages being +// Scans all pages (except lu pages), reserves 4 bits in working memory for each +// page bit 0: 0 == FREE|DELETED, 1 == USED bit 1: 0 == UNREFERENCED, 1 == +// REFERENCED bit 2: 0 == NOT_INDEX, 1 == INDEX bit 3: unused A consistent +// file system will have only pages being // * x000 free, unreferenced, not index // * x011 used, referenced only once, not index // * x101 used, unreferenced, index // The working memory might not fit all pages so several scans might be needed -static s32_t spiffs_page_consistency_check_i(spiffs *fs) { - const u32_t bits = 4; - const spiffs_page_ix pages_per_scan = SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8 / bits; - - s32_t res = SPIFFS_OK; - spiffs_page_ix pix_offset = 0; - - // for each range of pages fitting into work memory - while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) { - // set this flag to abort all checks and rescan the page range - u8_t restart = 0; - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - - spiffs_block_ix cur_block = 0; - // build consistency bitmap for id range traversing all blocks - while (!restart && cur_block < fs->block_count) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, - (pix_offset*256)/(SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + - ((((cur_block * pages_per_scan * 256)/ (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / fs->block_count), - 0); - // traverse each page except for lookup pages - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; - while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block+1)) { - //if ((cur_pix & 0xff) == 0) - // SPIFFS_CHECK_DBG("PA: processing pix %08x, block %08x of pix %08x, block %08x\n", - // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count, fs->block_count); - - // read header - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); +static s32_t spiffs_page_consistency_check_i(spiffs *fs) +{ + const u32_t bits = 4; + const spiffs_page_ix pages_per_scan = SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8 / bits; + + s32_t res = SPIFFS_OK; + spiffs_page_ix pix_offset = 0; + + // for each range of pages fitting into work memory + while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + { + // set this flag to abort all checks and rescan the page range + u8_t restart = 0; + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + + spiffs_block_ix cur_block = 0; + // build consistency bitmap for id range traversing all blocks + while (!restart && cur_block < fs->block_count) + { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, + (pix_offset * 256) / (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + + ((((cur_block * pages_per_scan * 256) / (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / + fs->block_count), + 0); + // traverse each page except for lookup pages + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; + while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block + 1)) + { + // if ((cur_pix & 0xff) == 0) + // SPIFFS_CHECK_DBG("PA: processing pix %08x, block %08x of pix + // %08x, block %08x\n", + // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * + // fs->block_count, fs->block_count); + + // read header + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), + sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); - u8_t within_range = (cur_pix >= pix_offset && cur_pix < pix_offset + pages_per_scan); - const u32_t pix_byte_ix = (cur_pix - pix_offset) / (8/bits); - const u8_t pix_bit_ix = (cur_pix & ((8/bits)-1)) * bits; + u8_t within_range = (cur_pix >= pix_offset && cur_pix < pix_offset + pages_per_scan); + const u32_t pix_byte_ix = (cur_pix - pix_offset) / (8 / bits); + const u8_t pix_bit_ix = (cur_pix & ((8 / bits) - 1)) * bits; - if (within_range && - (p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_USED) == 0) { - // used - fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 0)); - } - if ((p_hdr.flags & SPIFFS_PH_FLAG_DELET) && - (p_hdr.flags & SPIFFS_PH_FLAG_IXDELE) && - (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) == 0) { - // found non-deleted index - if (within_range) { - fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 2)); - } - - // load non-deleted index - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - - // traverse index for referenced pages - spiffs_page_ix *object_page_index; - spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; - - int entries; - int i; - spiffs_span_ix data_spix_offset; - if (p_hdr.span_ix == 0) { - // object header page index - entries = SPIFFS_OBJ_HDR_IX_LEN(fs); - data_spix_offset = 0; - object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)); - } else { - // object page index - entries = SPIFFS_OBJ_IX_LEN(fs); - data_spix_offset = SPIFFS_OBJ_HDR_IX_LEN(fs) + SPIFFS_OBJ_IX_LEN(fs) * (p_hdr.span_ix - 1); - object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)); - } - - // for all entries in index - for (i = 0; !restart && i < entries; i++) { - spiffs_page_ix rpix = object_page_index[i]; - u8_t rpix_within_range = rpix >= pix_offset && rpix < pix_offset + pages_per_scan; - - if ((rpix != (spiffs_page_ix)-1 && rpix > SPIFFS_MAX_PAGES(fs)) - || (rpix_within_range && SPIFFS_IS_LOOKUP_PAGE(fs, rpix))) { - - // bad reference - SPIFFS_CHECK_DBG("PA: pix %04x bad pix / LU referenced from page %04x\n", - rpix, cur_pix); - // check for data page elsewhere - spiffs_page_ix data_pix; - res = spiffs_obj_lu_find_id_and_span(fs, objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, 0, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - if (data_pix == 0) { - // if not, allocate free page - spiffs_page_header new_ph; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); - new_ph.obj_id = objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = data_spix_offset + i; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &data_pix); - SPIFFS_CHECK_RES(res); - SPIFFS_CHECK_DBG("PA: FIXUP: found no existing data page, created new @ %04x\n", data_pix); - } - // remap index - SPIFFS_CHECK_DBG("PA: FIXUP: rewriting index pix %04x\n", cur_pix); - res = spiffs_rewrite_index(fs, objix_p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, data_pix, cur_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend - delete object\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); - // delete file - res = spiffs_page_delete(fs, cur_pix); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - - } else if (rpix_within_range) { - - // valid reference - // read referenced page header - spiffs_page_header rp_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); - SPIFFS_CHECK_RES(res); - - // cross reference page header check - if (rp_hdr.obj_id != (p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) || - rp_hdr.span_ix != data_spix_offset + i || - (rp_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) != - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX)) { - SPIFFS_CHECK_DBG("PA: pix %04x has inconsistent page header ix id/span:%04x/%04x, ref id/span:%04x/%04x flags:%02x\n", - rpix, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, data_spix_offset + i, - rp_hdr.obj_id, rp_hdr.span_ix, rp_hdr.flags); - // try finding correct page - spiffs_page_ix data_pix; - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, rpix, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - if (data_pix == 0) { - // not found, this index is badly borked - SPIFFS_CHECK_DBG("PA: FIXUP: index bad, delete object id %04x\n", p_hdr.obj_id); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - SPIFFS_CHECK_RES(res); - break; - } else { - // found it, so rewrite index - SPIFFS_CHECK_DBG("PA: FIXUP: found correct data pix %04x, rewrite ix pix %04x id %04x\n", - data_pix, cur_pix, p_hdr.obj_id); - res = spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - } - } - else { - // mark rpix as referenced - const u32_t rpix_byte_ix = (rpix - pix_offset) / (8/bits); - const u8_t rpix_bit_ix = (rpix & ((8/bits)-1)) * bits; - if (fs->work[rpix_byte_ix] & (1<<(rpix_bit_ix + 1))) { - SPIFFS_CHECK_DBG("PA: pix %04x multiple referenced from page %04x\n", - rpix, cur_pix); - // Here, we should have fixed all broken references - getting this means there - // must be multiple files with same object id. Only solution is to delete - // the object which is referring to this page - SPIFFS_CHECK_DBG("PA: FIXUP: removing object %04x and page %04x\n", - p_hdr.obj_id, cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - SPIFFS_CHECK_RES(res); - // extra precaution, delete this page also - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - restart = 1; + if (within_range && (p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_USED) == 0) + { + // used + fs->work[pix_byte_ix] |= (1 << (pix_bit_ix + 0)); } - fs->work[rpix_byte_ix] |= (1<<(rpix_bit_ix + 1)); - } + if ((p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_IXDELE) && + (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) == 0) + { + // found non-deleted index + if (within_range) + { + fs->work[pix_byte_ix] |= (1 << (pix_bit_ix + 2)); + } + + // load non-deleted index + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + + // traverse index for referenced pages + spiffs_page_ix *object_page_index; + spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; + + int entries; + int i; + spiffs_span_ix data_spix_offset; + if (p_hdr.span_ix == 0) + { + // object header page index + entries = SPIFFS_OBJ_HDR_IX_LEN(fs); + data_spix_offset = 0; + object_page_index = + (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)); + } + else + { + // object page index + entries = SPIFFS_OBJ_IX_LEN(fs); + data_spix_offset = SPIFFS_OBJ_HDR_IX_LEN(fs) + SPIFFS_OBJ_IX_LEN(fs) * (p_hdr.span_ix - 1); + object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)); + } + + // for all entries in index + for (i = 0; !restart && i < entries; i++) + { + spiffs_page_ix rpix = object_page_index[i]; + u8_t rpix_within_range = rpix >= pix_offset && rpix < pix_offset + pages_per_scan; + + if ((rpix != (spiffs_page_ix)-1 && rpix > SPIFFS_MAX_PAGES(fs)) || + (rpix_within_range && SPIFFS_IS_LOOKUP_PAGE(fs, rpix))) + { + // bad reference + SPIFFS_CHECK_DBG( + "PA: pix %04x bad pix / LU referenced from " + "page %04x\n", + rpix, cur_pix); + // check for data page elsewhere + spiffs_page_ix data_pix; + res = spiffs_obj_lu_find_id_and_span(fs, objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, 0, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + if (data_pix == 0) + { + // if not, allocate free page + spiffs_page_header new_ph; + new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); + new_ph.obj_id = objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + new_ph.span_ix = data_spix_offset + i; + res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &data_pix); + SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_DBG( + "PA: FIXUP: found no existing data page, " + "created new @ %04x\n", + data_pix); + } + // remap index + SPIFFS_CHECK_DBG("PA: FIXUP: rewriting index pix %04x\n", cur_pix); + res = spiffs_rewrite_index(fs, objix_p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, data_pix, cur_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) + { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG( + "PA: FIXUP: index bad %i, cannot mend - " + "delete object\n", + res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); + // delete file + res = spiffs_page_delete(fs, cur_pix); + } + else + { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, + objix_p_hdr->span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + } + else if (rpix_within_range) + { + // valid reference + // read referenced page header + spiffs_page_header rp_hdr; + res = + _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, + SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t *)&rp_hdr); + SPIFFS_CHECK_RES(res); + + // cross reference page header check + if (rp_hdr.obj_id != (p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) || + rp_hdr.span_ix != data_spix_offset + i || + (rp_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) != + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX)) + { + SPIFFS_CHECK_DBG( + "PA: pix %04x has inconsistent page header " + "ix id/span:%04x/%04x, ref " + "id/span:%04x/%04x flags:%02x\n", + rpix, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, data_spix_offset + i, rp_hdr.obj_id, + rp_hdr.span_ix, rp_hdr.flags); + // try finding correct page + spiffs_page_ix data_pix; + res = spiffs_obj_lu_find_id_and_span(fs, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, + data_spix_offset + i, rpix, &data_pix); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + data_pix = 0; + } + SPIFFS_CHECK_RES(res); + if (data_pix == 0) + { + // not found, this index is badly borked + SPIFFS_CHECK_DBG( + "PA: FIXUP: index bad, delete object " + "id %04x\n", + p_hdr.obj_id); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + SPIFFS_CHECK_RES(res); + break; + } + else + { + // found it, so rewrite index + SPIFFS_CHECK_DBG( + "PA: FIXUP: found correct data pix " + "%04x, rewrite ix pix %04x id %04x\n", + data_pix, cur_pix, p_hdr.obj_id); + res = + spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) + { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG( + "PA: FIXUP: index bad %i, cannot " + "mend!\n", + res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + } + else + { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, + p_hdr.span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + } + } + else + { + // mark rpix as referenced + const u32_t rpix_byte_ix = (rpix - pix_offset) / (8 / bits); + const u8_t rpix_bit_ix = (rpix & ((8 / bits) - 1)) * bits; + if (fs->work[rpix_byte_ix] & (1 << (rpix_bit_ix + 1))) + { + SPIFFS_CHECK_DBG( + "PA: pix %04x multiple referenced from " + "page %04x\n", + rpix, cur_pix); + // Here, we should have fixed all broken + // references - getting this means there + // must be multiple files with same object + // id. Only solution is to delete the object + // which is referring to this page + SPIFFS_CHECK_DBG( + "PA: FIXUP: removing object %04x and " + "page %04x\n", + p_hdr.obj_id, cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + SPIFFS_CHECK_RES(res); + // extra precaution, delete this page also + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + restart = 1; + } + fs->work[rpix_byte_ix] |= (1 << (rpix_bit_ix + 1)); + } + } + } // for all index entries + } // found index + + // next page + cur_pix++; } - } // for all index entries - } // found index - - // next page - cur_pix++; - } - // next block - cur_block++; - } - // check consistency bitmap - if (!restart) { - spiffs_page_ix objix_pix; - spiffs_page_ix rpix; - - u32_t byte_ix; - u8_t bit_ix; - for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) { - for (bit_ix = 0; !restart && bit_ix < 8/bits; bit_ix ++) { - u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7; - spiffs_page_ix cur_pix = pix_offset + byte_ix * (8/bits) + bit_ix; - - // 000 ok - free, unreferenced, not index - - if (bitmask == 0x1) { - - // 001 - SPIFFS_CHECK_DBG("PA: pix %04x USED, UNREFERENCED, not index\n", cur_pix); - - u8_t rewrite_ix_to_this = 0; - u8_t delete_page = 0; - // check corresponding object index entry - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - res = spiffs_object_get_data_page_index_reference(fs, p_hdr.obj_id, p_hdr.span_ix, - &rpix, &objix_pix); - if (res == SPIFFS_OK) { - if (((rpix == (spiffs_page_ix)-1 || rpix > SPIFFS_MAX_PAGES(fs)) || (SPIFFS_IS_LOOKUP_PAGE(fs, rpix)))) { - // pointing to a bad page altogether, rewrite index to this - rewrite_ix_to_this = 1; - SPIFFS_CHECK_DBG("PA: corresponding ref is bad: %04x, rewrite to this %04x\n", rpix, cur_pix); - } else { - // pointing to something else, check what - spiffs_page_header rp_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); - SPIFFS_CHECK_RES(res); - if (((p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) == rp_hdr.obj_id) && - ((rp_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL)) == - (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET))) { - // pointing to something else valid, just delete this page then - SPIFFS_CHECK_DBG("PA: corresponding ref is good but different: %04x, delete this %04x\n", rpix, cur_pix); - delete_page = 1; - } else { - // pointing to something weird, update index to point to this page instead - if (rpix != cur_pix) { - SPIFFS_CHECK_DBG("PA: corresponding ref is weird: %04x %s%s%s%s, rewrite this %04x\n", rpix, - (rp_hdr.flags & SPIFFS_PH_FLAG_INDEX) ? "" : "INDEX ", - (rp_hdr.flags & SPIFFS_PH_FLAG_DELET) ? "" : "DELETED ", - (rp_hdr.flags & SPIFFS_PH_FLAG_USED) ? "NOTUSED " : "", - (rp_hdr.flags & SPIFFS_PH_FLAG_FINAL) ? "NOTFINAL " : "", - cur_pix); - rewrite_ix_to_this = 1; - } else { - // should not happen, destined for fubar - } + // next block + cur_block++; + } + // check consistency bitmap + if (!restart) + { + spiffs_page_ix objix_pix; + spiffs_page_ix rpix; + + u32_t byte_ix; + u8_t bit_ix; + for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) + { + for (bit_ix = 0; !restart && bit_ix < 8 / bits; bit_ix++) + { + u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7; + spiffs_page_ix cur_pix = pix_offset + byte_ix * (8 / bits) + bit_ix; + + // 000 ok - free, unreferenced, not index + + if (bitmask == 0x1) + { + // 001 + SPIFFS_CHECK_DBG("PA: pix %04x USED, UNREFERENCED, not index\n", cur_pix); + + u8_t rewrite_ix_to_this = 0; + u8_t delete_page = 0; + // check corresponding object index entry + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, + SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + + res = spiffs_object_get_data_page_index_reference(fs, p_hdr.obj_id, p_hdr.span_ix, &rpix, + &objix_pix); + if (res == SPIFFS_OK) + { + if (((rpix == (spiffs_page_ix)-1 || rpix > SPIFFS_MAX_PAGES(fs)) || + (SPIFFS_IS_LOOKUP_PAGE(fs, rpix)))) + { + // pointing to a bad page altogether, rewrite + // index to this + rewrite_ix_to_this = 1; + SPIFFS_CHECK_DBG( + "PA: corresponding ref is bad: %04x, " + "rewrite to this %04x\n", + rpix, cur_pix); + } + else + { + // pointing to something else, check what + spiffs_page_header rp_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, + SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), + (u8_t *)&rp_hdr); + SPIFFS_CHECK_RES(res); + if (((p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) == rp_hdr.obj_id) && + ((rp_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET | + SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL)) == + (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET))) + { + // pointing to something else valid, just + // delete this page then + SPIFFS_CHECK_DBG( + "PA: corresponding ref is good but " + "different: %04x, delete this %04x\n", + rpix, cur_pix); + delete_page = 1; + } + else + { + // pointing to something weird, update index + // to point to this page instead + if (rpix != cur_pix) + { + SPIFFS_CHECK_DBG( + "PA: corresponding ref is weird: " + "%04x %s%s%s%s, rewrite this " + "%04x\n", + rpix, (rp_hdr.flags & SPIFFS_PH_FLAG_INDEX) ? "" : "INDEX ", + (rp_hdr.flags & SPIFFS_PH_FLAG_DELET) ? "" : "DELETED ", + (rp_hdr.flags & SPIFFS_PH_FLAG_USED) ? "NOTUSED " : "", + (rp_hdr.flags & SPIFFS_PH_FLAG_FINAL) ? "NOTFINAL " : "", cur_pix); + rewrite_ix_to_this = 1; + } + else + { + // should not happen, destined for fubar + } + } + } + } + else if (res == SPIFFS_ERR_NOT_FOUND) + { + SPIFFS_CHECK_DBG( + "PA: corresponding ref not found, delete " + "%04x\n", + cur_pix); + delete_page = 1; + res = SPIFFS_OK; + } + + if (rewrite_ix_to_this) + { + // if pointing to invalid page, redirect index to + // this page + SPIFFS_CHECK_DBG( + "PA: FIXUP: rewrite index id %04x data spix " + "%04x to point to this pix: %04x\n", + p_hdr.obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); + if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) + { + // index bad also, cannot mend this file + SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); + } + else + { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); + } + SPIFFS_CHECK_RES(res); + restart = 1; + continue; + } + else if (delete_page) + { + SPIFFS_CHECK_DBG("PA: FIXUP: deleting page %04x\n", cur_pix); + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); + res = spiffs_page_delete(fs, cur_pix); + } + SPIFFS_CHECK_RES(res); + } + if (bitmask == 0x2) + { + // 010 + SPIFFS_CHECK_DBG("PA: pix %04x FREE, REFERENCED, not index\n", cur_pix); + + // no op, this should be taken care of when checking + // valid references + } + + // 011 ok - busy, referenced, not index + + if (bitmask == 0x4) + { + // 100 + SPIFFS_CHECK_DBG("PA: pix %04x FREE, unreferenced, INDEX\n", cur_pix); + + // this should never happen, major fubar + } + + // 101 ok - busy, unreferenced, index + + if (bitmask == 0x6) + { + // 110 + SPIFFS_CHECK_DBG("PA: pix %04x FREE, REFERENCED, INDEX\n", cur_pix); + + // no op, this should be taken care of when checking + // valid references + } + if (bitmask == 0x7) + { + // 111 + SPIFFS_CHECK_DBG("PA: pix %04x USED, REFERENCED, INDEX\n", cur_pix); + + // no op, this should be taken care of when checking + // valid references + } } - } - } else if (res == SPIFFS_ERR_NOT_FOUND) { - SPIFFS_CHECK_DBG("PA: corresponding ref not found, delete %04x\n", cur_pix); - delete_page = 1; - res = SPIFFS_OK; } - - if (rewrite_ix_to_this) { - // if pointing to invalid page, redirect index to this page - SPIFFS_CHECK_DBG("PA: FIXUP: rewrite index id %04x data spix %04x to point to this pix: %04x\n", - p_hdr.obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - continue; - } else if (delete_page) { - SPIFFS_CHECK_DBG("PA: FIXUP: deleting page %04x\n", cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); - res = spiffs_page_delete(fs, cur_pix); - } - SPIFFS_CHECK_RES(res); - } - if (bitmask == 0x2) { - - // 010 - SPIFFS_CHECK_DBG("PA: pix %04x FREE, REFERENCED, not index\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - - // 011 ok - busy, referenced, not index - - if (bitmask == 0x4) { - - // 100 - SPIFFS_CHECK_DBG("PA: pix %04x FREE, unreferenced, INDEX\n", cur_pix); - - // this should never happen, major fubar - } - - // 101 ok - busy, unreferenced, index - - if (bitmask == 0x6) { - - // 110 - SPIFFS_CHECK_DBG("PA: pix %04x FREE, REFERENCED, INDEX\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - if (bitmask == 0x7) { - - // 111 - SPIFFS_CHECK_DBG("PA: pix %04x USED, REFERENCED, INDEX\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } } - } - } - SPIFFS_CHECK_DBG("PA: processed %04x, restart %i\n", pix_offset, restart); - // next page range - if (!restart) { - pix_offset += pages_per_scan; - } - } // while page range not reached end - return res; + SPIFFS_CHECK_DBG("PA: processed %04x, restart %i\n", pix_offset, restart); + // next page range + if (!restart) + { + pix_offset += pages_per_scan; + } + } // while page range not reached end + return res; } // Checks consistency amongst all pages and fixes irregularities -s32_t spiffs_page_consistency_check(spiffs *fs) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); - s32_t res = spiffs_page_consistency_check_i(fs); - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); - } - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; +s32_t spiffs_page_consistency_check(spiffs *fs) +{ + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); + s32_t res = spiffs_page_consistency_check_i(fs); + if (res != SPIFFS_OK) + { + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); + } + CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); + return res; } //--------------------------------------- @@ -864,133 +1080,162 @@ s32_t spiffs_page_consistency_check(spiffs *fs) { // searches for given object id in temporary object id index, // returns the index or -1 -static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) { - u32_t i; - spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) { - if ((obj_table[i] & ~SPIFFS_OBJ_ID_IX_FLAG) == obj_id) { - return i; +static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) +{ + u32_t i; + spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; + obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) + { + if ((obj_table[i] & ~SPIFFS_OBJ_ID_IX_FLAG) == obj_id) + { + return i; + } } - } - return -1; + return -1; } static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, - int cur_entry, const void *user_const_p, void *user_var_p) { - (void)user_const_p; - s32_t res_c = SPIFFS_VIS_COUNTINUE; - s32_t res = SPIFFS_OK; - u32_t *log_ix = (u32_t*)user_var_p; - spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, - (cur_block * 256)/fs->block_count, 0); - - if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_page_header p_hdr; - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - if (p_hdr.span_ix == 0 && - (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET)) { - SPIFFS_CHECK_DBG("IX: pix %04x, obj id:%04x spix:%04x header not fully deleted - deleting\n", - cur_pix, obj_id, p_hdr.span_ix); - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - return res_c; - } + int cur_entry, const void *user_const_p, void *user_var_p) +{ + (void)user_const_p; + s32_t res_c = SPIFFS_VIS_COUNTINUE; + s32_t res = SPIFFS_OK; + u32_t *log_ix = (u32_t *)user_var_p; + spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; + + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, (cur_block * 256) / fs->block_count, 0); + + if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) + { + spiffs_page_header p_hdr; + spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - if ((p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - return res_c; - } + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), + sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); - if (p_hdr.span_ix == 0) { - // objix header page, register objid as reachable - int r = spiffs_object_index_search(fs, obj_id); - if (r == -1) { - // not registered, do it - obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - (*log_ix)++; - if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { - *log_ix = 0; - } - } - } else { // span index - // objix page, see if header can be found - int r = spiffs_object_index_search(fs, obj_id); - u8_t delete = 0; - if (r == -1) { - // not in temporary index, try finding it - spiffs_page_ix objix_hdr_pix; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &objix_hdr_pix); - res_c = SPIFFS_VIS_COUNTINUE_RELOAD; - if (res == SPIFFS_OK) { - // found, register as reachable - obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - } else if (res == SPIFFS_ERR_NOT_FOUND) { - // not found, register as unreachable - delete = 1; - obj_table[*log_ix] = obj_id | SPIFFS_OBJ_ID_IX_FLAG; - } else { - SPIFFS_CHECK_RES(res); + if (p_hdr.span_ix == 0 && (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | + SPIFFS_PH_FLAG_IXDELE)) == (SPIFFS_PH_FLAG_DELET)) + { + SPIFFS_CHECK_DBG( + "IX: pix %04x, obj id:%04x spix:%04x header not fully deleted " + "- deleting\n", + cur_pix, obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + return res_c; } - (*log_ix)++; - if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { - *log_ix = 0; + + if ((p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | + SPIFFS_PH_FLAG_IXDELE)) == (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) + { + return res_c; } - } else { - // in temporary index, check reachable flag - if ((obj_table[r] & SPIFFS_OBJ_ID_IX_FLAG)) { - // registered as unreachable - delete = 1; + + if (p_hdr.span_ix == 0) + { + // objix header page, register objid as reachable + int r = spiffs_object_index_search(fs, obj_id); + if (r == -1) + { + // not registered, do it + obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + (*log_ix)++; + if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) + { + *log_ix = 0; + } + } } - } + else + { // span index + // objix page, see if header can be found + int r = spiffs_object_index_search(fs, obj_id); + u8_t delete = 0; + if (r == -1) + { + // not in temporary index, try finding it + spiffs_page_ix objix_hdr_pix; + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &objix_hdr_pix); + res_c = SPIFFS_VIS_COUNTINUE_RELOAD; + if (res == SPIFFS_OK) + { + // found, register as reachable + obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + } + else if (res == SPIFFS_ERR_NOT_FOUND) + { + // not found, register as unreachable + delete = 1; + obj_table[*log_ix] = obj_id | SPIFFS_OBJ_ID_IX_FLAG; + } + else + { + SPIFFS_CHECK_RES(res); + } + (*log_ix)++; + if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) + { + *log_ix = 0; + } + } + else + { + // in temporary index, check reachable flag + if ((obj_table[r] & SPIFFS_OBJ_ID_IX_FLAG)) + { + // registered as unreachable + delete = 1; + } + } - if (delete) { - SPIFFS_CHECK_DBG("IX: FIXUP: pix %04x, obj id:%04x spix:%04x is orphan index - deleting\n", - cur_pix, obj_id, p_hdr.span_ix); - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - } - } // span index - } // valid object index id + if (delete) + { + SPIFFS_CHECK_DBG( + "IX: FIXUP: pix %04x, obj id:%04x spix:%04x is orphan " + "index - deleting\n", + cur_pix, obj_id, p_hdr.span_ix); + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + } + } // span index + } // valid object index id - return res_c; + return res_c; } // Removes orphaned and partially deleted index pages. -// Scans for index pages. When an index page is found, corresponding index header is searched for. -// If no such page exists, the index page cannot be reached as no index header exists and must be -// deleted. -s32_t spiffs_object_index_consistency_check(spiffs *fs) { - s32_t res = SPIFFS_OK; - // impl note: - // fs->work is used for a temporary object index memory, listing found object ids and - // indicating whether they can be reached or not. Acting as a fifo if object ids cannot fit. - // In the temporary object index memory, SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate - // a reachable/unreachable object id. - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - u32_t obj_id_log_ix = 0; - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, 0, &obj_id_log_ix, - 0, 0); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); - } - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; +// Scans for index pages. When an index page is found, corresponding index +// header is searched for. If no such page exists, the index page cannot be +// reached as no index header exists and must be deleted. +s32_t spiffs_object_index_consistency_check(spiffs *fs) +{ + s32_t res = SPIFFS_OK; + // impl note: + // fs->work is used for a temporary object index memory, listing found + // object ids and indicating whether they can be reached or not. Acting as a + // fifo if object ids cannot fit. In the temporary object index memory, + // SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate a reachable/unreachable + // object id. + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + u32_t obj_id_log_ix = 0; + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, 0, &obj_id_log_ix, + 0, 0); + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_OK; + } + if (res != SPIFFS_OK) + { + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); + } + CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_gc.c b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_gc.c index 92bd665..87ed88f 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_gc.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_gc.c @@ -1,574 +1,698 @@ +#include + #include "spiffs.h" #include "spiffs_nucleus.h" -#include #if !SPIFFS_READ_ONLY // Erases a logical block and updates the erase counter. // If cache is enabled, all pages that might be cached in this block // is dropped. -static s32_t spiffs_gc_erase_block( - spiffs *fs, - spiffs_block_ix bix) { - s32_t res; +static s32_t spiffs_gc_erase_block(spiffs *fs, spiffs_block_ix bix) +{ + s32_t res; - SPIFFS_GC_DBG("gc: erase block %i\n", bix); - res = spiffs_erase_block(fs, bix); - SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc: erase block %i\n", bix); + res = spiffs_erase_block(fs, bix); + SPIFFS_CHECK_RES(res); #if SPIFFS_CACHE - { - u32_t i; - for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) { - spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i); + { + u32_t i; + for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) + { spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i); } } - } #endif - return res; + return res; } // Searches for blocks where all entries are deleted - if one is found, // the block is erased. Compared to the non-quick gc, the quick one ensures // that no updates are needed on existing objects on pages that are erased. -s32_t spiffs_gc_quick( - spiffs *fs, u16_t max_free_pages) { - s32_t res = SPIFFS_OK; - u32_t blocks = fs->block_count; - spiffs_block_ix cur_block = 0; - u32_t cur_block_addr = 0; - int cur_entry = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - - SPIFFS_GC_DBG("gc_quick: running\n"); +s32_t spiffs_gc_quick(spiffs *fs, u16_t max_free_pages) +{ + s32_t res = SPIFFS_OK; + u32_t blocks = fs->block_count; + spiffs_block_ix cur_block = 0; + u32_t cur_block_addr = 0; + int cur_entry = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + + SPIFFS_GC_DBG("gc_quick: running\n"); #if SPIFFS_GC_STATS - fs->stats_gc_runs++; + fs->stats_gc_runs++; #endif - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - - // find fully deleted blocks - // check each block - while (res == SPIFFS_OK && blocks--) { - u16_t deleted_pages_in_block = 0; - u16_t free_pages_in_block = 0; - - int obj_lookup_page = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && - cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_DELETED) { - deleted_pages_in_block++; - } else if (obj_id == SPIFFS_OBJ_ID_FREE) { - // kill scan, go for next block - free_pages_in_block++; - if (free_pages_in_block > max_free_pages) { - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; - } - } else { - // kill scan, go for next block - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + + // find fully deleted blocks + // check each block + while (res == SPIFFS_OK && blocks--) + { + u16_t deleted_pages_in_block = 0; + u16_t free_pages_in_block = 0; + + int obj_lookup_page = 0; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), + fs->lu_work); + // check each entry + while (res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) + { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_DELETED) + { + deleted_pages_in_block++; + } + else if (obj_id == SPIFFS_OBJ_ID_FREE) + { + // kill scan, go for next block + free_pages_in_block++; + if (free_pages_in_block > max_free_pages) + { + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } + } + else + { + // kill scan, go for next block + obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); + res = 1; // kill object lu loop + break; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + if (res == 1) + res = SPIFFS_OK; + + if (res == SPIFFS_OK && + deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) && + free_pages_in_block <= max_free_pages) + { + // found a fully deleted block + fs->stats_p_deleted -= deleted_pages_in_block; + res = spiffs_gc_erase_block(fs, cur_block); + return res; } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - if (res == 1) res = SPIFFS_OK; - - if (res == SPIFFS_OK && - deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs) && - free_pages_in_block <= max_free_pages) { - // found a fully deleted block - fs->stats_p_deleted -= deleted_pages_in_block; - res = spiffs_gc_erase_block(fs, cur_block); - return res; - } - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - } // per block + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + } // per block - if (res == SPIFFS_OK) { - res = SPIFFS_ERR_NO_DELETED_BLOCKS; - } - return res; + if (res == SPIFFS_OK) + { + res = SPIFFS_ERR_NO_DELETED_BLOCKS; + } + return res; } // Checks if garbage collecting is necessary. If so a candidate block is found, // cleansed and erased -s32_t spiffs_gc_check( - spiffs *fs, - u32_t len) { - s32_t res; - s32_t free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count-2) - - fs->stats_p_allocated - fs->stats_p_deleted; - int tries = 0; - - if (fs->free_blocks > 3 && - (s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { - return SPIFFS_OK; - } - - u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); -// if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) { -// SPIFFS_GC_DBG("gc: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); -// return SPIFFS_ERR_FULL; -// } - if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) { - SPIFFS_GC_DBG("gc_check: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); - return SPIFFS_ERR_FULL; - } - - do { - SPIFFS_GC_DBG("\ngc_check #%i: run gc free_blocks:%i pfree:%i pallo:%i pdele:%i [%i] len:%i of %i\n", - tries, - fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages+fs->stats_p_allocated+fs->stats_p_deleted), - len, free_pages*SPIFFS_DATA_PAGE_SIZE(fs)); - - spiffs_block_ix *cands; - int count; - spiffs_block_ix cand; - s32_t prev_free_pages = free_pages; - // if the fs is crammed, ignore block age when selecting candidate - kind of a bad state - res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0); - SPIFFS_CHECK_RES(res); - if (count == 0) { - SPIFFS_GC_DBG("gc_check: no candidates, return\n"); - return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL; +s32_t spiffs_gc_check(spiffs *fs, u32_t len) +{ + s32_t res; + s32_t free_pages = (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - + fs->stats_p_allocated - fs->stats_p_deleted; + int tries = 0; + + if (fs->free_blocks > 3 && (s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) + { + return SPIFFS_OK; + } + + u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); + // if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) { + // SPIFFS_GC_DBG("gc: full freeblk:%i needed:%i free:%i dele:%i\n", + // fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); + // return SPIFFS_ERR_FULL; + // } + if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) + { + SPIFFS_GC_DBG("gc_check: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, + free_pages, fs->stats_p_deleted); + return SPIFFS_ERR_FULL; } + + do + { + SPIFFS_GC_DBG( + "\ngc_check #%i: run gc free_blocks:%i pfree:%i pallo:%i pdele:%i " + "[%i] len:%i of %i\n", + tries, fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, + (free_pages + fs->stats_p_allocated + fs->stats_p_deleted), len, free_pages * SPIFFS_DATA_PAGE_SIZE(fs)); + + spiffs_block_ix *cands; + int count; + spiffs_block_ix cand; + s32_t prev_free_pages = free_pages; + // if the fs is crammed, ignore block age when selecting candidate - + // kind of a bad state + res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0); + SPIFFS_CHECK_RES(res); + if (count == 0) + { + SPIFFS_GC_DBG("gc_check: no candidates, return\n"); + return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL; + } #if SPIFFS_GC_STATS - fs->stats_gc_runs++; + fs->stats_gc_runs++; #endif - cand = cands[0]; - fs->cleaning = 1; - //printf("gcing: cleaning block %i\n", cand); - res = spiffs_gc_clean(fs, cand); - fs->cleaning = 0; - if (res < 0) { - SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); - } else { - SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); - } - SPIFFS_CHECK_RES(res); + cand = cands[0]; + fs->cleaning = 1; + // printf("gcing: cleaning block %i\n", cand); + res = spiffs_gc_clean(fs, cand); + fs->cleaning = 0; + if (res < 0) + { + SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); + } + else + { + SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); + } + SPIFFS_CHECK_RES(res); - res = spiffs_gc_erase_page_stats(fs, cand); - SPIFFS_CHECK_RES(res); + res = spiffs_gc_erase_page_stats(fs, cand); + SPIFFS_CHECK_RES(res); - res = spiffs_gc_erase_block(fs, cand); - SPIFFS_CHECK_RES(res); + res = spiffs_gc_erase_block(fs, cand); + SPIFFS_CHECK_RES(res); - free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - - fs->stats_p_allocated - fs->stats_p_deleted; + free_pages = (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - + fs->stats_p_allocated - fs->stats_p_deleted; - if (prev_free_pages <= 0 && prev_free_pages == free_pages) { - // abort early to reduce wear, at least tried once - SPIFFS_GC_DBG("gc_check: early abort, no result on gc when fs crammed\n"); - break; - } + if (prev_free_pages <= 0 && prev_free_pages == free_pages) + { + // abort early to reduce wear, at least tried once + SPIFFS_GC_DBG("gc_check: early abort, no result on gc when fs crammed\n"); + break; + } - } while (++tries < SPIFFS_GC_MAX_RUNS && (fs->free_blocks <= 2 || - (s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs))); + } while (++tries < SPIFFS_GC_MAX_RUNS && + (fs->free_blocks <= 2 || (s32_t)len > free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs))); - free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - - fs->stats_p_allocated - fs->stats_p_deleted; - if ((s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { - res = SPIFFS_ERR_FULL; - } + free_pages = (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - + fs->stats_p_allocated - fs->stats_p_deleted; + if ((s32_t)len > free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) + { + res = SPIFFS_ERR_FULL; + } - SPIFFS_GC_DBG("gc_check: finished, %i dirty, blocks %i free, %i pages free, %i tries, res %i\n", - fs->stats_p_allocated + fs->stats_p_deleted, - fs->free_blocks, free_pages, tries, res); + SPIFFS_GC_DBG( + "gc_check: finished, %i dirty, blocks %i free, %i pages free, %i " + "tries, res %i\n", + fs->stats_p_allocated + fs->stats_p_deleted, fs->free_blocks, free_pages, tries, res); - return res; + return res; } // Updates page statistics for a block that is about to be erased -s32_t spiffs_gc_erase_page_stats( - spiffs *fs, - spiffs_block_ix bix) { - s32_t res = SPIFFS_OK; - int obj_lookup_page = 0; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = 0; - u32_t dele = 0; - u32_t allo = 0; - - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - dele++; - } else { - allo++; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - SPIFFS_GC_DBG("gc_check: wipe pallo:%i pdele:%i\n", allo, dele); - fs->stats_p_allocated -= allo; - fs->stats_p_deleted -= dele; - return res; +s32_t spiffs_gc_erase_page_stats(spiffs *fs, spiffs_block_ix bix) +{ + s32_t res = SPIFFS_OK; + int obj_lookup_page = 0; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = 0; + u32_t dele = 0; + u32_t allo = 0; + + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) + { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_FREE) {} + else if (obj_id == SPIFFS_OBJ_ID_DELETED) + { + dele++; + } + else + { + allo++; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + SPIFFS_GC_DBG("gc_check: wipe pallo:%i pdele:%i\n", allo, dele); + fs->stats_p_allocated -= allo; + fs->stats_p_deleted -= dele; + return res; } // Finds block candidates to erase -s32_t spiffs_gc_find_candidate( - spiffs *fs, - spiffs_block_ix **block_candidates, - int *candidate_count, - char fs_crammed) { - s32_t res = SPIFFS_OK; - u32_t blocks = fs->block_count; - spiffs_block_ix cur_block = 0; - u32_t cur_block_addr = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = 0; - - // using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score - int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs)-8)/(sizeof(spiffs_block_ix) + sizeof(s32_t))); - *candidate_count = 0; - memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - - // divide up work area into block indices and scores - spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; - s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); - - // align cand_scores on s32_t boundary - cand_scores = (s32_t*)(((ptrdiff_t)cand_scores + sizeof(ptrdiff_t) - 1) & ~(sizeof(ptrdiff_t) - 1)); - - *block_candidates = cand_blocks; - - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - - // check each block - while (res == SPIFFS_OK && blocks--) { - u16_t deleted_pages_in_block = 0; - u16_t used_pages_in_block = 0; +s32_t spiffs_gc_find_candidate(spiffs *fs, spiffs_block_ix **block_candidates, int *candidate_count, char fs_crammed) +{ + s32_t res = SPIFFS_OK; + u32_t blocks = fs->block_count; + spiffs_block_ix cur_block = 0; + u32_t cur_block_addr = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = 0; + + // using fs->work area as sorted candidate memory, + // (spiffs_block_ix)cand_bix/(s32_t)score + int max_candidates = + MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs) - 8) / (sizeof(spiffs_block_ix) + sizeof(s32_t))); + *candidate_count = 0; + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + + // divide up work area into block indices and scores + spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; + s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); + + // align cand_scores on s32_t boundary + cand_scores = (s32_t *)(((ptrdiff_t)cand_scores + sizeof(ptrdiff_t) - 1) & ~(sizeof(ptrdiff_t) - 1)); + + *block_candidates = cand_blocks; + + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + + // check each block + while (res == SPIFFS_OK && blocks--) + { + u16_t deleted_pages_in_block = 0; + u16_t used_pages_in_block = 0; + + int obj_lookup_page = 0; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), + fs->lu_work); + // check each entry + while (res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) + { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (obj_id == SPIFFS_OBJ_ID_FREE) + { + // when a free entry is encountered, scan logic ensures that + // all following entries are free also + res = 1; // kill object lu loop + break; + } + else if (obj_id == SPIFFS_OBJ_ID_DELETED) + { + deleted_pages_in_block++; + } + else + { + used_pages_in_block++; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + if (res == 1) + res = SPIFFS_OK; + + // calculate score and insert into candidate table + // stoneage sort, but probably not so many blocks + if (res == SPIFFS_OK && deleted_pages_in_block > 0) + { + // read erase count + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, SPIFFS_ERASE_COUNT_PADDR(fs, cur_block), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); - int obj_lookup_page = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && - cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - // when a free entry is encountered, scan logic ensures that all following entries are free also - res = 1; // kill object lu loop - break; - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - deleted_pages_in_block++; - } else { - used_pages_in_block++; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - if (res == 1) res = SPIFFS_OK; - - // calculate score and insert into candidate table - // stoneage sort, but probably not so many blocks - if (res == SPIFFS_OK && deleted_pages_in_block > 0) { - // read erase count - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, cur_block), - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - - spiffs_obj_id erase_age; - if (fs->max_erase_count > erase_count) { - erase_age = fs->max_erase_count - erase_count; - } else { - erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count); - } - - s32_t score = - deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET + - used_pages_in_block * SPIFFS_GC_HEUR_W_USED + - erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); - int cand_ix = 0; - SPIFFS_GC_DBG("gc_check: bix:%i del:%i use:%i score:%i\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); - while (cand_ix < max_candidates) { - if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) { - cand_blocks[cand_ix] = cur_block; - cand_scores[cand_ix] = score; - break; - } else if (cand_scores[cand_ix] < score) { - int reorder_cand_ix = max_candidates - 2; - while (reorder_cand_ix >= cand_ix) { - cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix]; - cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix]; - reorder_cand_ix--; - } - cand_blocks[cand_ix] = cur_block; - cand_scores[cand_ix] = score; - break; + spiffs_obj_id erase_age; + if (fs->max_erase_count > erase_count) + { + erase_age = fs->max_erase_count - erase_count; + } + else + { + erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count); + } + + s32_t score = deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET + + used_pages_in_block * SPIFFS_GC_HEUR_W_USED + + erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); + int cand_ix = 0; + SPIFFS_GC_DBG("gc_check: bix:%i del:%i use:%i score:%i\n", cur_block, deleted_pages_in_block, + used_pages_in_block, score); + while (cand_ix < max_candidates) + { + if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) + { + cand_blocks[cand_ix] = cur_block; + cand_scores[cand_ix] = score; + break; + } + else if (cand_scores[cand_ix] < score) + { + int reorder_cand_ix = max_candidates - 2; + while (reorder_cand_ix >= cand_ix) + { + cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix]; + cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix]; + reorder_cand_ix--; + } + cand_blocks[cand_ix] = cur_block; + cand_scores[cand_ix] = score; + break; + } + cand_ix++; + } + (*candidate_count)++; } - cand_ix++; - } - (*candidate_count)++; - } - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - } // per block + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + } // per block - return res; + return res; } -typedef enum { - FIND_OBJ_DATA, - MOVE_OBJ_DATA, - MOVE_OBJ_IX, - FINISHED +typedef enum +{ + FIND_OBJ_DATA, + MOVE_OBJ_DATA, + MOVE_OBJ_IX, + FINISHED } spiffs_gc_clean_state; -typedef struct { - spiffs_gc_clean_state state; - spiffs_obj_id cur_obj_id; - spiffs_span_ix cur_objix_spix; - spiffs_page_ix cur_objix_pix; - int stored_scan_entry_index; - u8_t obj_id_found; +typedef struct +{ + spiffs_gc_clean_state state; + spiffs_obj_id cur_obj_id; + spiffs_span_ix cur_objix_spix; + spiffs_page_ix cur_objix_pix; + int stored_scan_entry_index; + u8_t obj_id_found; } spiffs_gc; // Empties given block by moving all data into free pages of another block // Strategy: // loop: // scan object lookup for object data pages -// for first found id, check spix and load corresponding object index page to memory -// push object scan lookup entry index -// rescan object lookup, find data pages with same id and referenced by same object index -// move data page, update object index in memory -// when reached end of lookup, store updated object index +// for first found id, check spix and load corresponding object index page to +// memory push object scan lookup entry index +// rescan object lookup, find data pages with same id and referenced by same +// object index move data page, update object index in memory when reached +// end of lookup, store updated object index // pop object scan lookup entry index // repeat loop until end of object lookup -// scan object lookup again for remaining object index pages, move to new page in other block +// scan object lookup again for remaining object index pages, move to new page +// in other block // -s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { - s32_t res = SPIFFS_OK; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - int cur_entry = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - spiffs_gc gc; - spiffs_page_ix cur_pix = 0; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - - SPIFFS_GC_DBG("gc_clean: cleaning block %i\n", bix); - - memset(&gc, 0, sizeof(spiffs_gc)); - gc.state = FIND_OBJ_DATA; - - if (fs->free_cursor_block_ix == bix) { - // move free cursor to next block, cannot use free pages from the block we want to clean - fs->free_cursor_block_ix = (bix+1)%fs->block_count; - fs->free_cursor_obj_lu_entry = 0; - SPIFFS_GC_DBG("gc_clean: move free cursor to block %i\n", fs->free_cursor_block_ix); - } - - while (res == SPIFFS_OK && gc.state != FINISHED) { - SPIFFS_GC_DBG("gc_clean: state = %i entry:%i\n", gc.state, cur_entry); - gc.obj_id_found = 0; - - // scan through lookup pages - int obj_lookup_page = cur_entry / entries_per_page; - u8_t scan = 1; - // check each object lookup page - while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (scan && res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry); - - // act upon object id depending on gc state - switch (gc.state) { - case FIND_OBJ_DATA: - if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && - ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) { - SPIFFS_GC_DBG("gc_clean: FIND_DATA state:%i - found obj id %04x\n", gc.state, obj_id); - gc.obj_id_found = 1; - gc.cur_obj_id = obj_id; - scan = 0; - } - break; - case MOVE_OBJ_DATA: - if (obj_id == gc.cur_obj_id) { - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA found data page %04x:%04x @ %04x\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix); - if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) { - SPIFFS_GC_DBG("gc_clean: MOVE_DATA no objix spix match, take in another run\n"); - } else { - spiffs_page_ix new_data_pix; - if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { - // move page - res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA move objix %04x:%04x page %04x to %04x\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix); - SPIFFS_CHECK_RES(res); - // move wipes obj_lu, reload it - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } else { - // page is deleted but not deleted in lookup, scrap it - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wipe objix %04x:%04x page %04x\n", obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - new_data_pix = SPIFFS_OBJ_ID_FREE; - } - // update memory representation of object index page with new data page - if (gc.cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = new_data_pix; - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page %04x to objix_hdr entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = new_data_pix; - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page %04x to objix entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); - } - } - } - break; - case MOVE_OBJ_IX: - if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && - (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { - // found an index object id - spiffs_page_header p_hdr; - spiffs_page_ix new_pix; - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { - // move page - res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX move objix %04x:%04x page %04x to %04x\n", obj_id, p_hdr.span_ix, cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_UPD, obj_id, p_hdr.span_ix, new_pix, 0); - // move wipes obj_lu, reload it - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } else { - // page is deleted but not deleted in lookup, scrap it - SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX wipe objix %04x:%04x page %04x\n", obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_page_delete(fs, cur_pix); - if (res == SPIFFS_OK) { - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0); - } - } - SPIFFS_CHECK_RES(res); - } - break; - default: - scan = 0; - break; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - - if (res != SPIFFS_OK) break; - - // state finalization and switch - switch (gc.state) { - case FIND_OBJ_DATA: - if (gc.obj_id_found) { - // find out corresponding obj ix page and load it to memory - spiffs_page_header p_hdr; - spiffs_page_ix objix_pix; - gc.stored_scan_entry_index = cur_entry; - cur_entry = 0; - gc.state = MOVE_OBJ_DATA; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix); - SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:%04x\n", gc.cur_objix_spix); - res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page %04x\n", objix_pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix); - gc.cur_objix_pix = objix_pix; - } else { - gc.state = MOVE_OBJ_IX; - cur_entry = 0; // restart entry scan index - } - break; - case MOVE_OBJ_DATA: { - // store modified objix (hdr) page - spiffs_page_ix new_objix_pix; - gc.state = FIND_OBJ_DATA; - cur_entry = gc.stored_scan_entry_index; - if (gc.cur_objix_spix == 0) { - // store object index header page - res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, fs->work, 0, 0, &new_objix_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix_hdr page, %04x:%04x\n", new_objix_pix, 0); - SPIFFS_CHECK_RES(res); - } else { - // store object index page - res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, %04x:%04x\n", new_objix_pix, objix->p_hdr.span_ix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - } +s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) +{ + s32_t res = SPIFFS_OK; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + int cur_entry = 0; + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + spiffs_gc gc; + spiffs_page_ix cur_pix = 0; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + + SPIFFS_GC_DBG("gc_clean: cleaning block %i\n", bix); + + memset(&gc, 0, sizeof(spiffs_gc)); + gc.state = FIND_OBJ_DATA; + + if (fs->free_cursor_block_ix == bix) + { + // move free cursor to next block, cannot use free pages from the block + // we want to clean + fs->free_cursor_block_ix = (bix + 1) % fs->block_count; + fs->free_cursor_obj_lu_entry = 0; + SPIFFS_GC_DBG("gc_clean: move free cursor to block %i\n", fs->free_cursor_block_ix); } - break; - case MOVE_OBJ_IX: - gc.state = FINISHED; - break; - default: - cur_entry = 0; - break; - } - SPIFFS_GC_DBG("gc_clean: state-> %i\n", gc.state); - } // while state != FINISHED + while (res == SPIFFS_OK && gc.state != FINISHED) + { + SPIFFS_GC_DBG("gc_clean: state = %i entry:%i\n", gc.state, cur_entry); + gc.obj_id_found = 0; + + // scan through lookup pages + int obj_lookup_page = cur_entry / entries_per_page; + u8_t scan = 1; + // check each object lookup page + while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (scan && res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) + { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry); + + // act upon object id depending on gc state + switch (gc.state) + { + case FIND_OBJ_DATA: + if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && + ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) + { + SPIFFS_GC_DBG( + "gc_clean: FIND_DATA state:%i - found obj id " + "%04x\n", + gc.state, obj_id); + gc.obj_id_found = 1; + gc.cur_obj_id = obj_id; + scan = 0; + } + break; + case MOVE_OBJ_DATA: + if (obj_id == gc.cur_obj_id) + { + spiffs_page_header p_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, + SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), + (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA found data page %04x:%04x " + "@ %04x\n", + gc.cur_obj_id, p_hdr.span_ix, cur_pix); + if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) + { + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA no objix spix match, " + "take in another run\n"); + } + else + { + spiffs_page_ix new_data_pix; + if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) + { + // move page + res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix); + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA move objix " + "%04x:%04x page %04x to %04x\n", + gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix); + SPIFFS_CHECK_RES(res); + // move wipes obj_lu, reload it + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } + else + { + // page is deleted but not deleted in + // lookup, scrap it + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA wipe objix " + "%04x:%04x page %04x\n", + obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_page_delete(fs, cur_pix); + SPIFFS_CHECK_RES(res); + new_data_pix = SPIFFS_OBJ_ID_FREE; + } + // update memory representation of object index + // page with new data page + if (gc.cur_objix_spix == 0) + { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = + new_data_pix; + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA wrote page %04x " + "to objix_hdr entry %02x in mem\n", + new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); + } + else + { + // update object index page + ((spiffs_page_ix + *)((u8_t *)objix + + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = + new_data_pix; + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA wrote page %04x " + "to objix entry %02x in mem\n", + new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); + } + } + } + break; + case MOVE_OBJ_IX: + if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && + (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) + { + // found an index object id + spiffs_page_header p_hdr; + spiffs_page_ix new_pix; + // load header + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, + SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), + (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) + { + // move page + res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix); + SPIFFS_GC_DBG( + "gc_clean: MOVE_OBJIX move objix %04x:%04x " + "page %04x to %04x\n", + obj_id, p_hdr.span_ix, cur_pix, new_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_UPD, obj_id, p_hdr.span_ix, new_pix, 0); + // move wipes obj_lu, reload it + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } + else + { + // page is deleted but not deleted in lookup, + // scrap it + SPIFFS_GC_DBG( + "gc_clean: MOVE_OBJIX wipe objix %04x:%04x " + "page %04x\n", + obj_id, p_hdr.span_ix, cur_pix); + res = spiffs_page_delete(fs, cur_pix); + if (res == SPIFFS_OK) + { + spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0); + } + } + SPIFFS_CHECK_RES(res); + } + break; + default: + scan = 0; + break; + } + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + + if (res != SPIFFS_OK) + break; + + // state finalization and switch + switch (gc.state) + { + case FIND_OBJ_DATA: + if (gc.obj_id_found) + { + // find out corresponding obj ix page and load it to memory + spiffs_page_header p_hdr; + spiffs_page_ix objix_pix; + gc.stored_scan_entry_index = cur_entry; + cur_entry = 0; + gc.state = MOVE_OBJ_DATA; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), + sizeof(spiffs_page_header), (u8_t *)&p_hdr); + SPIFFS_CHECK_RES(res); + gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix); + SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:%04x\n", gc.cur_objix_spix); + res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, + 0, &objix_pix); + SPIFFS_CHECK_RES(res); + SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page %04x\n", objix_pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix); + gc.cur_objix_pix = objix_pix; + } + else + { + gc.state = MOVE_OBJ_IX; + cur_entry = 0; // restart entry scan index + } + break; + case MOVE_OBJ_DATA: + { + // store modified objix (hdr) page + spiffs_page_ix new_objix_pix; + gc.state = FIND_OBJ_DATA; + cur_entry = gc.stored_scan_entry_index; + if (gc.cur_objix_spix == 0) + { + // store object index header page + res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, + fs->work, 0, 0, &new_objix_pix); + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA store modified objix_hdr page, " + "%04x:%04x\n", + new_objix_pix, 0); + SPIFFS_CHECK_RES(res); + } + else + { + // store object index page + res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, + &new_objix_pix); + SPIFFS_GC_DBG( + "gc_clean: MOVE_DATA store modified objix page, " + "%04x:%04x\n", + new_objix_pix, objix->p_hdr.span_ix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, + 0); + } + } + break; + case MOVE_OBJ_IX: + gc.state = FINISHED; + break; + default: + cur_entry = 0; + break; + } + SPIFFS_GC_DBG("gc_clean: state-> %i\n", gc.state); + } // while state != FINISHED - return res; + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_hydrogen.c b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_hydrogen.c index def8d1f..727fde0 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_hydrogen.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_hydrogen.c @@ -5,15 +5,16 @@ * Author: petera */ +#include + #include "spiffs.h" #include "spiffs_nucleus.h" -#include #if SPIFFS_FILEHDL_OFFSET -#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0) +#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0) #define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0) #else -#define SPIFFS_FH_OFFS(fs, fh) (fh) +#define SPIFFS_FH_OFFS(fs, fh) (fh) #define SPIFFS_FH_UNOFFS(fs, fh) (fh) #endif @@ -22,1159 +23,1291 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh); #endif #if SPIFFS_BUFFER_HELP -u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) { - return num_descs * sizeof(spiffs_fd); -} +u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) { return num_descs * sizeof(spiffs_fd); } #if SPIFFS_CACHE -u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) { - return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); +u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) +{ + return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); } #endif #endif -u8_t SPIFFS_mounted(spiffs *fs) { - return SPIFFS_CHECK_MOUNT(fs); -} +u8_t SPIFFS_mounted(spiffs *fs) { return SPIFFS_CHECK_MOUNT(fs); } -s32_t SPIFFS_format(spiffs *fs) { +s32_t SPIFFS_format(spiffs *fs) +{ #if SPIFFS_READ_ONLY - (void)fs; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - if (SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_MOUNTED; - return -1; - } - - s32_t res; - SPIFFS_LOCK(fs); - - spiffs_block_ix bix = 0; - while (bix < fs->block_count) { - fs->max_erase_count = 0; - res = spiffs_erase_block(fs, bix); - if (res != SPIFFS_OK) { - res = SPIFFS_ERR_ERASE_FAIL; + SPIFFS_API_CHECK_CFG(fs); + if (SPIFFS_CHECK_MOUNT(fs)) + { + fs->err_code = SPIFFS_ERR_MOUNTED; + return -1; } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - bix++; - } - SPIFFS_UNLOCK(fs); + s32_t res; + SPIFFS_LOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY + spiffs_block_ix bix = 0; + while (bix < fs->block_count) + { + fs->max_erase_count = 0; + res = spiffs_erase_block(fs, bix); + if (res != SPIFFS_OK) + { + res = SPIFFS_ERR_ERASE_FAIL; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + bix++; + } + + SPIFFS_UNLOCK(fs); + + return 0; +#endif // SPIFFS_READ_ONLY } -#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 +#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON == 0 -s32_t SPIFFS_probe_fs(spiffs_config *config) { - s32_t res = spiffs_probe(config); - return res; +s32_t SPIFFS_probe_fs(spiffs_config *config) +{ + s32_t res = spiffs_probe(config); + return res; } -#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 - -s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, - u8_t *fd_space, u32_t fd_space_size, - void *cache, u32_t cache_size, - spiffs_check_callback check_cb_f) { - void *user_data; - SPIFFS_LOCK(fs); - user_data = fs->user_data; - memset(fs, 0, sizeof(spiffs)); - memcpy(&fs->cfg, config, sizeof(spiffs_config)); - fs->user_data = user_data; - fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); - fs->work = &work[0]; - fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; - memset(fd_space, 0, fd_space_size); - // align fd_space pointer to pointer size byte boundary - u8_t ptr_size = sizeof(void*); - u8_t addr_lsb = ((u8_t)(intptr_t)fd_space) & (ptr_size-1); - if (addr_lsb) { - fd_space += (ptr_size-addr_lsb); - fd_space_size -= (ptr_size-addr_lsb); - } - fs->fd_space = fd_space; - fs->fd_count = (fd_space_size/sizeof(spiffs_fd)); - - // align cache pointer to 4 byte boundary - addr_lsb = ((u8_t)(intptr_t)cache) & (ptr_size-1); - if (addr_lsb) { - u8_t *cache_8 = (u8_t *)cache; - cache_8 += (ptr_size-addr_lsb); - cache = cache_8; - cache_size -= (ptr_size-addr_lsb); - } - if (cache_size & (ptr_size-1)) { - cache_size -= (cache_size & (ptr_size-1)); - } +#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 + +s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, u8_t *fd_space, u32_t fd_space_size, void *cache, + u32_t cache_size, spiffs_check_callback check_cb_f) +{ + void *user_data; + SPIFFS_LOCK(fs); + user_data = fs->user_data; + memset(fs, 0, sizeof(spiffs)); + memcpy(&fs->cfg, config, sizeof(spiffs_config)); + fs->user_data = user_data; + fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); + fs->work = &work[0]; + fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; + memset(fd_space, 0, fd_space_size); + // align fd_space pointer to pointer size byte boundary + u8_t ptr_size = sizeof(void *); + u8_t addr_lsb = ((u8_t)(intptr_t)fd_space) & (ptr_size - 1); + if (addr_lsb) + { + fd_space += (ptr_size - addr_lsb); + fd_space_size -= (ptr_size - addr_lsb); + } + fs->fd_space = fd_space; + fs->fd_count = (fd_space_size / sizeof(spiffs_fd)); + + // align cache pointer to 4 byte boundary + addr_lsb = ((u8_t)(intptr_t)cache) & (ptr_size - 1); + if (addr_lsb) + { + u8_t *cache_8 = (u8_t *)cache; + cache_8 += (ptr_size - addr_lsb); + cache = cache_8; + cache_size -= (ptr_size - addr_lsb); + } + if (cache_size & (ptr_size - 1)) + { + cache_size -= (cache_size & (ptr_size - 1)); + } #if SPIFFS_CACHE - fs->cache = cache; - fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs)*32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs)*32 : cache_size; - spiffs_cache_init(fs); + fs->cache = cache; + fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs) * 32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs) * 32 : cache_size; + spiffs_cache_init(fs); #endif - s32_t res; + s32_t res; #if SPIFFS_USE_MAGIC - res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - fs->config_magic = SPIFFS_CONFIG_MAGIC; + fs->config_magic = SPIFFS_CONFIG_MAGIC; - res = spiffs_obj_lu_scan(fs); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_obj_lu_scan(fs); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs)); - SPIFFS_DBG("object lookup pages: %i\n", SPIFFS_OBJ_LOOKUP_PAGES(fs)); - SPIFFS_DBG("page pages per block: %i\n", SPIFFS_PAGES_PER_BLOCK(fs)); - SPIFFS_DBG("page header length: %i\n", sizeof(spiffs_page_header)); - SPIFFS_DBG("object header index entries: %i\n", SPIFFS_OBJ_HDR_IX_LEN(fs)); - SPIFFS_DBG("object index entries: %i\n", SPIFFS_OBJ_IX_LEN(fs)); - SPIFFS_DBG("available file descriptors: %i\n", fs->fd_count); - SPIFFS_DBG("free blocks: %i\n", fs->free_blocks); + SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs)); + SPIFFS_DBG("object lookup pages: %i\n", SPIFFS_OBJ_LOOKUP_PAGES(fs)); + SPIFFS_DBG("page pages per block: %i\n", SPIFFS_PAGES_PER_BLOCK(fs)); + SPIFFS_DBG("page header length: %i\n", sizeof(spiffs_page_header)); + SPIFFS_DBG("object header index entries: %i\n", SPIFFS_OBJ_HDR_IX_LEN(fs)); + SPIFFS_DBG("object index entries: %i\n", SPIFFS_OBJ_IX_LEN(fs)); + SPIFFS_DBG("available file descriptors: %i\n", fs->fd_count); + SPIFFS_DBG("free blocks: %i\n", fs->free_blocks); - fs->check_cb_f = check_cb_f; + fs->check_cb_f = check_cb_f; - fs->mounted = 1; + fs->mounted = 1; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return 0; + return 0; } -void SPIFFS_unmount(spiffs *fs) { - if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return; - SPIFFS_LOCK(fs); - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr != 0) { +void SPIFFS_unmount(spiffs *fs) +{ + if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) + return; + SPIFFS_LOCK(fs); + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) + { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr != 0) + { #if SPIFFS_CACHE - (void)spiffs_fflush_cache(fs, cur_fd->file_nbr); + (void)spiffs_fflush_cache(fs, cur_fd->file_nbr); #endif - spiffs_fd_return(fs, cur_fd->file_nbr); + spiffs_fd_return(fs, cur_fd->file_nbr); + } } - } - fs->mounted = 0; + fs->mounted = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); } -s32_t SPIFFS_errno(spiffs *fs) { - return fs->err_code; -} +s32_t SPIFFS_errno(spiffs *fs) { return fs->err_code; } -void SPIFFS_clearerr(spiffs *fs) { - fs->err_code = SPIFFS_OK; -} +void SPIFFS_clearerr(spiffs *fs) { fs->err_code = SPIFFS_OK; } -s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) { +s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)path; (void)mode; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)path; + (void)mode; + return SPIFFS_ERR_RO_NOT_IMPL; #else - (void)mode; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); - spiffs_obj_id obj_id; - s32_t res; - - res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (const u8_t*)path); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_create(fs, obj_id, (const u8_t*)path, SPIFFS_TYPE_FILE, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY + (void)mode; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) + { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + spiffs_obj_id obj_id; + s32_t res; + + res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (const u8_t *)path); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_create(fs, obj_id, (const u8_t *)path, SPIFFS_TYPE_FILE, 0); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY } -spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) { - (void)mode; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); +spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) +{ + (void)mode; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) + { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - spiffs_fd *fd; - spiffs_page_ix pix; + spiffs_fd *fd; + spiffs_page_ix pix; #if SPIFFS_READ_ONLY - // not valid flags in read only mode - flags &= ~SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC; - printf("shouldn't read only\n"); -#endif // SPIFFS_READ_ONLY - - s32_t res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - if ((flags & SPIFFS_O_CREAT) == 0) { - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + // not valid flags in read only mode + flags &= ~SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC; + printf("shouldn't read only\n"); +#endif // SPIFFS_READ_ONLY - if (res == SPIFFS_OK && - (flags & (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) == (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) { - // creat and excl and file exists - fail - res = SPIFFS_ERR_FILE_EXISTS; - spiffs_fd_return(fs, fd->file_nbr); + s32_t res = spiffs_fd_find_new(fs, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)path, &pix); + if ((flags & SPIFFS_O_CREAT) == 0) + { + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if (res == SPIFFS_OK && (flags & (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) == (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) + { + // creat and excl and file exists - fail + res = SPIFFS_ERR_FILE_EXISTS; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } - if ((flags & SPIFFS_O_CREAT) && res == SPIFFS_ERR_NOT_FOUND) { + if ((flags & SPIFFS_O_CREAT) && res == SPIFFS_ERR_NOT_FOUND) + { #if !SPIFFS_READ_ONLY - spiffs_obj_id obj_id; - // no need to enter conflicting name here, already looked for it above - res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + spiffs_obj_id obj_id; + // no need to enter conflicting name here, already looked for it above + res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_create(fs, obj_id, (const u8_t *)path, SPIFFS_TYPE_FILE, &pix); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + flags &= ~SPIFFS_O_TRUNC; +#endif // !SPIFFS_READ_ONLY } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_create(fs, obj_id, (const u8_t*)path, SPIFFS_TYPE_FILE, &pix); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + else + { + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - flags &= ~SPIFFS_O_TRUNC; -#endif // !SPIFFS_READ_ONLY - } else { - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if !SPIFFS_READ_ONLY - if (flags & SPIFFS_O_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + if (flags & SPIFFS_O_TRUNC) + { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY - fd->fdoffset = 0; + fd->fdoffset = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return SPIFFS_FH_OFFS(fs, fd->file_nbr); + return SPIFFS_FH_OFFS(fs, fd->file_nbr); } -spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; + spiffs_fd *fd; - s32_t res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + s32_t res = spiffs_fd_find_new(fs, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#if !SPIFFS_READ_ONLY - if (flags & SPIFFS_O_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } -#endif // !SPIFFS_READ_ONLY +#if !SPIFFS_READ_ONLY + if (flags & SPIFFS_O_TRUNC) + { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } +#endif // !SPIFFS_READ_ONLY - fd->fdoffset = 0; + fd->fdoffset = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return SPIFFS_FH_OFFS(fs, fd->file_nbr); + return SPIFFS_FH_OFFS(fs, fd->file_nbr); } -spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; + spiffs_fd *fd; - s32_t res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + s32_t res = spiffs_fd_find_new(fs, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - if (SPIFFS_IS_LOOKUP_PAGE(fs, page_ix)) { - res = SPIFFS_ERR_NOT_A_FILE; - spiffs_fd_return(fs, fd->file_nbr); + if (SPIFFS_IS_LOOKUP_PAGE(fs, page_ix)) + { + res = SPIFFS_ERR_NOT_A_FILE; + spiffs_fd_return(fs, fd->file_nbr); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + res = spiffs_object_open_by_page(fs, page_ix, fd, flags, mode); + if (res == SPIFFS_ERR_IS_FREE || res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_NOT_FINALIZED || + res == SPIFFS_ERR_NOT_INDEX || res == SPIFFS_ERR_INDEX_SPAN_MISMATCH) + { + res = SPIFFS_ERR_NOT_A_FILE; + } + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - - res = spiffs_object_open_by_page(fs, page_ix, fd, flags, mode); - if (res == SPIFFS_ERR_IS_FREE || - res == SPIFFS_ERR_DELETED || - res == SPIFFS_ERR_NOT_FINALIZED || - res == SPIFFS_ERR_NOT_INDEX || - res == SPIFFS_ERR_INDEX_SPAN_MISMATCH) { - res = SPIFFS_ERR_NOT_A_FILE; - } - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if !SPIFFS_READ_ONLY - if (flags & SPIFFS_O_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); + if (flags & SPIFFS_O_TRUNC) + { + res = spiffs_object_truncate(fd, 0, 0); + if (res < SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY - fd->fdoffset = 0; + fd->fdoffset = 0; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return SPIFFS_FH_OFFS(fs, fd->file_nbr); + return SPIFFS_FH_OFFS(fs, fd->file_nbr); } -s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; + spiffs_fd *fd; + s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_O_RDONLY) == 0) { - res = SPIFFS_ERR_NOT_READABLE; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - if (fd->size == SPIFFS_UNDEFINED_LEN && len > 0) { - // special case for zero sized files - res = SPIFFS_ERR_END_OF_OBJECT; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + if ((fd->flags & SPIFFS_O_RDONLY) == 0) + { + res = SPIFFS_ERR_NOT_READABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if (fd->size == SPIFFS_UNDEFINED_LEN && len > 0) + { + // special case for zero sized files + res = SPIFFS_ERR_END_OF_OBJECT; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } #if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); + spiffs_fflush_cache(fs, fh); #endif - if (fd->fdoffset + len >= fd->size) { - // reading beyond file size - s32_t avail = fd->size - fd->fdoffset; - if (avail <= 0) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT); + if (fd->fdoffset + len >= fd->size) + { + // reading beyond file size + s32_t avail = fd->size - fd->fdoffset; + if (avail <= 0) + { + SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT); + } + res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t *)buf); + if (res == SPIFFS_ERR_END_OF_OBJECT) + { + fd->fdoffset += avail; + SPIFFS_UNLOCK(fs); + return avail; + } + else + { + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + len = avail; + } } - res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t*)buf); - if (res == SPIFFS_ERR_END_OF_OBJECT) { - fd->fdoffset += avail; - SPIFFS_UNLOCK(fs); - return avail; - } else { - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - len = avail; + else + { + // reading within file size + res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t *)buf); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); } - } else { - // reading within file size - res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t*)buf); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - fd->fdoffset += len; + fd->fdoffset += len; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return len; + return len; } #if !SPIFFS_READ_ONLY -static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) { - (void)fs; - s32_t res = SPIFFS_OK; - s32_t remaining = len; - if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) { - s32_t m_len = MIN((s32_t)(fd->size - offset), len); - res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len); - SPIFFS_CHECK_RES(res); - remaining -= m_len; - u8_t *buf_8 = (u8_t *)buf; - buf_8 += m_len; - buf = buf_8; - offset += m_len; - } - if (remaining > 0) { - res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining); - SPIFFS_CHECK_RES(res); - } - return len; - +static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) +{ + (void)fs; + s32_t res = SPIFFS_OK; + s32_t remaining = len; + if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) + { + s32_t m_len = MIN((s32_t)(fd->size - offset), len); + res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len); + SPIFFS_CHECK_RES(res); + remaining -= m_len; + u8_t *buf_8 = (u8_t *)buf; + buf_8 += m_len; + buf = buf_8; + offset += m_len; + } + if (remaining > 0) + { + res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining); + SPIFFS_CHECK_RES(res); + } + return len; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY -s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { +s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)fh; (void)buf; (void)len; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)fh; + (void)buf; + (void)len; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - u32_t offset; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + s32_t res; + u32_t offset; - if ((fd->flags & SPIFFS_O_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - if ((fd->flags & SPIFFS_O_APPEND)) { - fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; - } + if ((fd->flags & SPIFFS_O_WRONLY) == 0) + { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + + if ((fd->flags & SPIFFS_O_APPEND)) + { + fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; + } - offset = fd->fdoffset; + offset = fd->fdoffset; #if SPIFFS_CACHE_WR - if (fd->cache_page == 0) { - // see if object id is associated with cache already - fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); - } -#endif - if (fd->flags & SPIFFS_O_APPEND) { - if (fd->size == SPIFFS_UNDEFINED_LEN) { - offset = 0; - } else { - offset = fd->size; + if (fd->cache_page == 0) + { + // see if object id is associated with cache already + fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); } +#endif + if (fd->flags & SPIFFS_O_APPEND) + { + if (fd->size == SPIFFS_UNDEFINED_LEN) + { + offset = 0; + } + else + { + offset = fd->size; + } #if SPIFFS_CACHE_WR - if (fd->cache_page) { - offset = MAX(offset, fd->cache_page->offset + fd->cache_page->size); - } + if (fd->cache_page) + { + offset = MAX(offset, fd->cache_page->offset + fd->cache_page->size); + } #endif - } + } #if SPIFFS_CACHE_WR - if ((fd->flags & SPIFFS_O_DIRECT) == 0) { - if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - // small write, try to cache it - u8_t alloc_cpage = 1; - if (fd->cache_page) { - // have a cached page for this fd already, check cache page boundaries - if (offset < fd->cache_page->offset || // writing before cache - offset > fd->cache_page->offset + fd->cache_page->size || // writing after cache - offset + len > fd->cache_page->offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page + if ((fd->flags & SPIFFS_O_DIRECT) == 0) + { + if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - // boundary violation, write back cache first and allocate new - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, boundary viol, offs:%i size:%i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->offset, fd->cache_page->size); - spiffs_cache_fd_release(fs, fd->cache_page); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } else { - // writing within cache - alloc_cpage = 0; + // small write, try to cache it + u8_t alloc_cpage = 1; + if (fd->cache_page) + { + // have a cached page for this fd already, check cache page + // boundaries + if (offset < fd->cache_page->offset || // writing before cache + offset > fd->cache_page->offset + fd->cache_page->size || // writing after cache + offset + len > fd->cache_page->offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page + { + // boundary violation, write back cache first and allocate + // new + SPIFFS_CACHE_DBG( + "CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, " + "boundary viol, offs:%i size:%i\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); + res = + spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->offset, fd->cache_page->size); + spiffs_cache_fd_release(fs, fd->cache_page); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } + else + { + // writing within cache + alloc_cpage = 0; + } + } + + if (alloc_cpage) + { + fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd); + if (fd->cache_page) + { + fd->cache_page->offset = offset; + fd->cache_page->size = 0; + SPIFFS_CACHE_DBG( + "CACHE_WR_ALLO: allocating cache page %i for fd " + "%i:%04x\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id); + } + } + + if (fd->cache_page) + { + u32_t offset_in_cpage = offset - fd->cache_page->offset; + SPIFFS_CACHE_DBG( + "CACHE_WR_WRITE: storing to cache page %i for fd %i:%04x, " + "offs %i:%i len %i\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, offset, offset_in_cpage, len); + spiffs_cache *cache = spiffs_get_cache(fs); + u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); + memcpy(&cpage_data[offset_in_cpage], buf, len); + fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len); + fd->fdoffset += len; + SPIFFS_UNLOCK(fs); + return len; + } + else + { + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->fdoffset += len; + SPIFFS_UNLOCK(fs); + return res; + } } - } - - if (alloc_cpage) { - fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd); - if (fd->cache_page) { - fd->cache_page->offset = offset; - fd->cache_page->size = 0; - SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page %i for fd %i:%04x\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id); + else + { + // big write, no need to cache it - but first check if there is a + // cached write already + if (fd->cache_page) + { + // write back cache first + SPIFFS_CACHE_DBG( + "CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, big " + "write, offs:%i size:%i\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); + res = spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->offset, fd->cache_page->size); + spiffs_cache_fd_release(fs, fd->cache_page); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } } - } - - if (fd->cache_page) { - u32_t offset_in_cpage = offset - fd->cache_page->offset; - SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page %i for fd %i:%04x, offs %i:%i len %i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, - offset, offset_in_cpage, len); - spiffs_cache *cache = spiffs_get_cache(fs); - u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); - memcpy(&cpage_data[offset_in_cpage], buf, len); - fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len); - fd->fdoffset += len; - SPIFFS_UNLOCK(fs); - return len; - } else { - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->fdoffset += len; - SPIFFS_UNLOCK(fs); - return res; - } - } else { - // big write, no need to cache it - but first check if there is a cached write already - if (fd->cache_page) { - // write back cache first - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, big write, offs:%i size:%i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->offset, fd->cache_page->size); - spiffs_cache_fd_release(fs, fd->cache_page); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } } - } #endif - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->fdoffset += len; + res = spiffs_hydro_write(fs, fd, buf, offset, len); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->fdoffset += len; - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; -#endif // SPIFFS_READ_ONLY + return res; +#endif // SPIFFS_READ_ONLY } -s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + s32_t res; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); + spiffs_fflush_cache(fs, fh); #endif - switch (whence) { - case SPIFFS_SEEK_CUR: - offs = fd->fdoffset+offs; - break; - case SPIFFS_SEEK_END: - offs = (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size) + offs; - break; - } - - if ((offs > (s32_t)fd->size) && (SPIFFS_UNDEFINED_LEN != fd->size)) { - res = SPIFFS_ERR_END_OF_OBJECT; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - spiffs_span_ix data_spix = offs / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (fd->cursor_objix_spix != objix_spix) { - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span( - fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix); + switch (whence) + { + case SPIFFS_SEEK_CUR: + offs = fd->fdoffset + offs; + break; + case SPIFFS_SEEK_END: + offs = (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size) + offs; + break; + } + + if ((offs > (s32_t)fd->size) && (SPIFFS_UNDEFINED_LEN != fd->size)) + { + res = SPIFFS_ERR_END_OF_OBJECT; + } SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->cursor_objix_spix = objix_spix; - fd->cursor_objix_pix = pix; - } - fd->fdoffset = offs; - SPIFFS_UNLOCK(fs); + spiffs_span_ix data_spix = offs / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (fd->cursor_objix_spix != objix_spix) + { + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fd->cursor_objix_spix = objix_spix; + fd->cursor_objix_pix = pix; + } + fd->fdoffset = offs; - return offs; + SPIFFS_UNLOCK(fs); + + return offs; } -s32_t SPIFFS_remove(spiffs *fs, const char *path) { +s32_t SPIFFS_remove(spiffs *fs, const char *path) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)path; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)path; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - spiffs_page_ix pix; - s32_t res; - - res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) + { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - res = spiffs_object_open_by_page(fs, pix, fd, 0,0); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + spiffs_page_ix pix; + s32_t res; - res = spiffs_object_truncate(fd, 0, 1); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fd_find_new(fs, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)path, &pix); + if (res != SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_open_by_page(fs, pix, fd, 0, 0); + if (res != SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY + res = spiffs_object_truncate(fd, 0, 1); + if (res != SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY } -s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) { +s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)fh; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)fh; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_O_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + spiffs_fd *fd; + s32_t res; + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } + + if ((fd->flags & SPIFFS_O_WRONLY) == 0) + { + res = SPIFFS_ERR_NOT_WRITABLE; + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + } #if SPIFFS_CACHE_WR - spiffs_cache_fd_release(fs, fd->cache_page); + spiffs_cache_fd_release(fs, fd->cache_page); #endif - res = spiffs_object_truncate(fd, 0, 1); + res = spiffs_object_truncate(fd, 0, 1); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY + return 0; +#endif // SPIFFS_READ_ONLY } -static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) { - (void)fh; - spiffs_page_object_ix_header objix_hdr; - spiffs_obj_id obj_id; - s32_t res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, - SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_API_CHECK_RES(fs, res); - - u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , pix)) + - SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id); - res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh, - obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id); - SPIFFS_API_CHECK_RES(fs, res); - - s->obj_id = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - s->type = objix_hdr.type; - s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; - s->pix = pix; - strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); - - return res; +static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) +{ + (void)fh; + spiffs_page_object_ix_header objix_hdr; + spiffs_obj_id obj_id; + s32_t res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_API_CHECK_RES(fs, res); + + u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id); + res = + _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh, obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id); + SPIFFS_API_CHECK_RES(fs, res); + + s->obj_id = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + s->type = objix_hdr.type; + s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + s->pix = pix; + strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); + + return res; } -s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); +s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(path) > SPIFFS_OBJ_NAME_LEN - 1) + { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); - s32_t res; - spiffs_page_ix pix; + s32_t res; + spiffs_page_ix pix; - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)path, &pix); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_stat_pix(fs, pix, 0, s); + res = spiffs_stat_pix(fs, pix, 0, s); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; } -s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - spiffs_fd *fd; - s32_t res; + spiffs_fd *fd; + s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); + spiffs_fflush_cache(fs, fh); #endif - res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s); + res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; } // Checks if there are any cached writes for the object id associated with // given filehandle. If so, these writes are flushed. #if SPIFFS_CACHE == 1 -static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { - (void)fs; - (void)fh; - s32_t res = SPIFFS_OK; +static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) +{ + (void)fs; + (void)fh; + s32_t res = SPIFFS_OK; #if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES(fs, res); - if ((fd->flags & SPIFFS_O_DIRECT) == 0) { - if (fd->cache_page == 0) { - // see if object id is associated with cache already - fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); - } - if (fd->cache_page) { - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, flush, offs:%i size:%i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->offset, fd->cache_page->size); - if (res < SPIFFS_OK) { - fs->err_code = res; - } - spiffs_cache_fd_release(fs, fd->cache_page); + if ((fd->flags & SPIFFS_O_DIRECT) == 0) + { + if (fd->cache_page == 0) + { + // see if object id is associated with cache already + fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); + } + if (fd->cache_page) + { + SPIFFS_CACHE_DBG( + "CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, flush, " + "offs:%i size:%i\n", + fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); + res = spiffs_hydro_write(fs, fd, spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), + fd->cache_page->offset, fd->cache_page->size); + if (res < SPIFFS_OK) + { + fs->err_code = res; + } + spiffs_cache_fd_release(fs, fd->cache_page); + } } - } #endif - return res; + return res; } #endif -s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { - (void)fh; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - s32_t res = SPIFFS_OK; +s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) +{ + (void)fh; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + s32_t res = SPIFFS_OK; #if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR - SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs,res); - SPIFFS_UNLOCK(fs); + SPIFFS_LOCK(fs); + fh = SPIFFS_FH_UNOFFS(fs, fh); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); #endif - return res; + return res; } -s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); +s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) +{ + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); - s32_t res = SPIFFS_OK; - SPIFFS_LOCK(fs); + s32_t res = SPIFFS_OK; + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); #if SPIFFS_CACHE - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - res = spiffs_fd_return(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fd_return(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); + SPIFFS_UNLOCK(fs); - return res; + return res; } -s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path) { +s32_t SPIFFS_rename(spiffs *fs, const char *old_path, const char *new_path) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)old_path; (void)new_path; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)old_path; + (void)new_path; + return SPIFFS_ERR_RO_NOT_IMPL; #else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - if (strlen(new_path) > SPIFFS_OBJ_NAME_LEN - 1 || - strlen(old_path) > SPIFFS_OBJ_NAME_LEN - 1) { - SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); - } - SPIFFS_LOCK(fs); - - spiffs_page_ix pix_old, pix_dummy; - spiffs_fd *fd; - - s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)old_path, &pix_old); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)new_path, &pix_dummy); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - } else if (res == SPIFFS_OK) { - res = SPIFFS_ERR_CONFLICTING_NAME; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + if (strlen(new_path) > SPIFFS_OBJ_NAME_LEN - 1 || strlen(old_path) > SPIFFS_OBJ_NAME_LEN - 1) + { + SPIFFS_API_CHECK_RES(fs, SPIFFS_ERR_NAME_TOO_LONG); + } + SPIFFS_LOCK(fs); + + spiffs_page_ix pix_old, pix_dummy; + spiffs_fd *fd; + + s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)old_path, &pix_old); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t *)new_path, &pix_dummy); + if (res == SPIFFS_ERR_NOT_FOUND) + { + res = SPIFFS_OK; + } + else if (res == SPIFFS_OK) + { + res = SPIFFS_ERR_CONFLICTING_NAME; + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + res = spiffs_fd_find_new(fs, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (const u8_t*)new_path, - 0, &pix_dummy); + res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0); + if (res != SPIFFS_OK) + { + spiffs_fd_return(fs, fd->file_nbr); + } + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - spiffs_fd_return(fs, fd->file_nbr); + res = + spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (const u8_t *)new_path, 0, &pix_dummy); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd_return(fs, fd->file_nbr); - SPIFFS_UNLOCK(fs); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + + SPIFFS_UNLOCK(fs); - return res; -#endif // SPIFFS_READ_ONLY + return res; +#endif // SPIFFS_READ_ONLY } -spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) { - (void)name; +spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) +{ + (void)name; - if (!SPIFFS_CHECK_CFG((fs))) { - (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; - return 0; - } + if (!SPIFFS_CHECK_CFG((fs))) + { + (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; + return 0; + } - if (!SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return 0; - } + if (!SPIFFS_CHECK_MOUNT(fs)) + { + fs->err_code = SPIFFS_ERR_NOT_MOUNTED; + return 0; + } - d->fs = fs; - d->block = 0; - d->entry = 0; - return d; + d->fs = fs; + d->block = 0; + d->entry = 0; + return d; } -static s32_t spiffs_read_dir_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - (void)user_const_p; - s32_t res; - spiffs_page_object_ix_header objix_hdr; - if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || - (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { +static s32_t spiffs_read_dir_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix bix, int ix_entry, + const void *user_const_p, void *user_var_p) +{ + (void)user_const_p; + s32_t res; + spiffs_page_object_ix_header objix_hdr; + if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) + { + return SPIFFS_VIS_COUNTINUE; + } + + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + if (res != SPIFFS_OK) + return res; + if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) + { + struct spiffs_dirent *e = (struct spiffs_dirent *)user_var_p; + e->obj_id = obj_id; + strcpy((char *)e->name, (char *)objix_hdr.name); + e->type = objix_hdr.type; + e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; + e->pix = pix; + return SPIFFS_OK; + } + return SPIFFS_VIS_COUNTINUE; - } - - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - if (res != SPIFFS_OK) return res; - if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && - objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags& (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - struct spiffs_dirent *e = (struct spiffs_dirent*)user_var_p; - e->obj_id = obj_id; - strcpy((char *)e->name, (char *)objix_hdr.name); - e->type = objix_hdr.type; - e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; - e->pix = pix; - return SPIFFS_OK; - } - - return SPIFFS_VIS_COUNTINUE; } -struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { - if (!SPIFFS_CHECK_MOUNT(d->fs)) { - d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return 0; - } - SPIFFS_LOCK(d->fs); - - spiffs_block_ix bix; - int entry; - s32_t res; - struct spiffs_dirent *ret = 0; - - res = spiffs_obj_lu_find_entry_visitor(d->fs, - d->block, - d->entry, - SPIFFS_VIS_NO_WRAP, - 0, - spiffs_read_dir_v, - 0, - e, - &bix, - &entry); - if (res == SPIFFS_OK) { - d->block = bix; - d->entry = entry + 1; - ret = e; - } else { - d->fs->err_code = res; - } - SPIFFS_UNLOCK(d->fs); - return ret; +struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) +{ + if (!SPIFFS_CHECK_MOUNT(d->fs)) + { + d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; + return 0; + } + SPIFFS_LOCK(d->fs); + + spiffs_block_ix bix; + int entry; + s32_t res; + struct spiffs_dirent *ret = 0; + + res = spiffs_obj_lu_find_entry_visitor(d->fs, d->block, d->entry, SPIFFS_VIS_NO_WRAP, 0, spiffs_read_dir_v, 0, e, + &bix, &entry); + if (res == SPIFFS_OK) + { + d->block = bix; + d->entry = entry + 1; + ret = e; + } + else + { + d->fs->err_code = res; + } + SPIFFS_UNLOCK(d->fs); + return ret; } -s32_t SPIFFS_closedir(spiffs_DIR *d) { - SPIFFS_API_CHECK_CFG(d->fs); - SPIFFS_API_CHECK_MOUNT(d->fs); - return 0; +s32_t SPIFFS_closedir(spiffs_DIR *d) +{ + SPIFFS_API_CHECK_CFG(d->fs); + SPIFFS_API_CHECK_MOUNT(d->fs); + return 0; } -s32_t SPIFFS_check(spiffs *fs) { +s32_t SPIFFS_check(spiffs *fs) +{ #if SPIFFS_READ_ONLY - (void)fs; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + return SPIFFS_ERR_RO_NOT_IMPL; #else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - res = spiffs_lookup_consistency_check(fs, 0); + res = spiffs_lookup_consistency_check(fs, 0); - res = spiffs_object_index_consistency_check(fs); + res = spiffs_object_index_consistency_check(fs); - res = spiffs_page_consistency_check(fs); + res = spiffs_page_consistency_check(fs); - res = spiffs_obj_lu_scan(fs); + res = spiffs_obj_lu_scan(fs); - SPIFFS_UNLOCK(fs); - return res; -#endif // SPIFFS_READ_ONLY + SPIFFS_UNLOCK(fs); + return res; +#endif // SPIFFS_READ_ONLY } -s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - u32_t pages_per_block = SPIFFS_PAGES_PER_BLOCK(fs); - u32_t blocks = fs->block_count; - u32_t obj_lu_pages = SPIFFS_OBJ_LOOKUP_PAGES(fs); - u32_t data_page_size = SPIFFS_DATA_PAGE_SIZE(fs); - u32_t total_data_pages = (blocks - 2) * (pages_per_block - obj_lu_pages) + 1; // -2 for spare blocks, +1 for emergency page - - if (total) { - *total = total_data_pages * data_page_size; - } +s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) +{ + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + u32_t pages_per_block = SPIFFS_PAGES_PER_BLOCK(fs); + u32_t blocks = fs->block_count; + u32_t obj_lu_pages = SPIFFS_OBJ_LOOKUP_PAGES(fs); + u32_t data_page_size = SPIFFS_DATA_PAGE_SIZE(fs); + u32_t total_data_pages = + (blocks - 2) * (pages_per_block - obj_lu_pages) + 1; // -2 for spare blocks, +1 for emergency page + + if (total) + { + *total = total_data_pages * data_page_size; + } - if (used) { - *used = fs->stats_p_allocated * data_page_size; - } + if (used) + { + *used = fs->stats_p_allocated * data_page_size; + } - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } -s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { +s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)max_free_pages; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)max_free_pages; + return SPIFFS_ERR_RO_NOT_IMPL; #else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - res = spiffs_gc_quick(fs, max_free_pages); + res = spiffs_gc_quick(fs, max_free_pages); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY } - -s32_t SPIFFS_gc(spiffs *fs, u32_t size) { +s32_t SPIFFS_gc(spiffs *fs, u32_t size) +{ #if SPIFFS_READ_ONLY - (void)fs; (void)size; - return SPIFFS_ERR_RO_NOT_IMPL; + (void)fs; + (void)size; + return SPIFFS_ERR_RO_NOT_IMPL; #else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - res = spiffs_gc_check(fs, size); + res = spiffs_gc_check(fs, size); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + SPIFFS_UNLOCK(fs); + return 0; +#endif // SPIFFS_READ_ONLY } -s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) +{ + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - res = (fd->fdoffset >= (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size)); + res = (fd->fdoffset >= (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size)); - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } -s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); +s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) +{ + s32_t res; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); + fh = SPIFFS_FH_UNOFFS(fs, fh); - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + spiffs_fd *fd; + res = spiffs_fd_get(fs, fh, &fd); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #if SPIFFS_CACHE_WR - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); + res = spiffs_fflush_cache(fs, fh); + SPIFFS_API_CHECK_RES_UNLOCK(fs, res); #endif - res = fd->fdoffset; + res = fd->fdoffset; - SPIFFS_UNLOCK(fs); - return res; + SPIFFS_UNLOCK(fs); + return res; } -s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) { - SPIFFS_LOCK(fs); - fs->file_cb_f = cb_func; - SPIFFS_UNLOCK(fs); - return 0; +s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) +{ + SPIFFS_LOCK(fs); + fs->file_cb_f = cb_func; + SPIFFS_UNLOCK(fs); + return 0; } #if SPIFFS_TEST_VISUALISATION -s32_t SPIFFS_vis(spiffs *fs) { - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - spiffs_block_ix bix = 0; - - while (bix < fs->block_count) { - // check each object lookup page - int obj_lookup_page = 0; - int cur_entry = 0; - - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (cur_entry == 0) { - spiffs_printf("%4i ", bix); - } else if ((cur_entry & 0x3f) == 0) { - spiffs_printf(" "); - } - if (obj_id == SPIFFS_OBJ_ID_FREE) { - spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); - } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG){ - spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); - } else { - spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); +s32_t SPIFFS_vis(spiffs *fs) +{ + s32_t res = SPIFFS_OK; + SPIFFS_API_CHECK_CFG(fs); + SPIFFS_API_CHECK_MOUNT(fs); + SPIFFS_LOCK(fs); + + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + spiffs_block_ix bix = 0; + + while (bix < fs->block_count) + { + // check each object lookup page + int obj_lookup_page = 0; + int cur_entry = 0; + + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + // check each entry + while (res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && + cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs))) + { + spiffs_obj_id obj_id = obj_lu_buf[cur_entry - entry_offset]; + if (cur_entry == 0) + { + spiffs_printf("%4i ", bix); + } + else if ((cur_entry & 0x3f) == 0) + { + spiffs_printf(" "); + } + if (obj_id == SPIFFS_OBJ_ID_FREE) + { + spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); + } + else if (obj_id == SPIFFS_OBJ_ID_DELETED) + { + spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); + } + else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG) + { + spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); + } + else + { + spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); + } + cur_entry++; + if ((cur_entry & 0x3f) == 0) + { + spiffs_printf("\n"); + } + } // per entry + obj_lookup_page++; + } // per object lookup page + + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + + if (erase_count != (spiffs_obj_id)-1) + { + spiffs_printf("\tera_cnt: %i\n", erase_count); } - cur_entry++; - if ((cur_entry & 0x3f) == 0) { - spiffs_printf("\n"); + else + { + spiffs_printf("\tera_cnt: N/A\n"); } - } // per entry - obj_lookup_page++; - } // per object lookup page - - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - - if (erase_count != (spiffs_obj_id)-1) { - spiffs_printf("\tera_cnt: %i\n", erase_count); - } else { - spiffs_printf("\tera_cnt: N/A\n"); - } - bix++; - } // per block - - spiffs_printf("era_cnt_max: %i\n", fs->max_erase_count); - spiffs_printf("last_errno: %i\n", fs->err_code); - spiffs_printf("blocks: %i\n", fs->block_count); - spiffs_printf("free_blocks: %i\n", fs->free_blocks); - spiffs_printf("page_alloc: %i\n", fs->stats_p_allocated); - spiffs_printf("page_delet: %i\n", fs->stats_p_deleted); - SPIFFS_UNLOCK(fs); - u32_t total, used; - SPIFFS_info(fs, &total, &used); - spiffs_printf("used: %i of %i\n", used, total); - return res; + bix++; + } // per block + + spiffs_printf("era_cnt_max: %i\n", fs->max_erase_count); + spiffs_printf("last_errno: %i\n", fs->err_code); + spiffs_printf("blocks: %i\n", fs->block_count); + spiffs_printf("free_blocks: %i\n", fs->free_blocks); + spiffs_printf("page_alloc: %i\n", fs->stats_p_allocated); + spiffs_printf("page_delet: %i\n", fs->stats_p_deleted); + SPIFFS_UNLOCK(fs); + u32_t total, used; + SPIFFS_info(fs, &total, &used); + spiffs_printf("used: %i of %i\n", used, total); + return res; } #endif diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_nucleus.c b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_nucleus.c index 01ea028..a9e9a26 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_nucleus.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/spiffs_nucleus.c @@ -1,2017 +1,2253 @@ -#include "spiffs.h" #include "spiffs_nucleus.h" + #include -static s32_t spiffs_page_data_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { - s32_t res = SPIFFS_OK; - if (pix == (spiffs_page_ix)-1) { - // referring to page 0xffff...., bad object index - return SPIFFS_ERR_INDEX_REF_FREE; - } - if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // referring to an object lookup page, bad object index - return SPIFFS_ERR_INDEX_REF_LU; - } - if (pix > SPIFFS_MAX_PAGES(fs)) { - // referring to a bad page - return SPIFFS_ERR_INDEX_REF_INVALID; - } +#include "spiffs.h" + +static s32_t spiffs_page_data_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) +{ + s32_t res = SPIFFS_OK; + if (pix == (spiffs_page_ix)-1) + { + // referring to page 0xffff...., bad object index + return SPIFFS_ERR_INDEX_REF_FREE; + } + if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + // referring to an object lookup page, bad object index + return SPIFFS_ERR_INDEX_REF_LU; + } + if (pix > SPIFFS_MAX_PAGES(fs)) + { + // referring to a bad page + return SPIFFS_ERR_INDEX_REF_INVALID; + } #if SPIFFS_PAGE_CHECK - spiffs_page_header ph; - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, pix), - sizeof(spiffs_page_header), - (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_DATA(ph, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, spix); + spiffs_page_header ph; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_DATA(ph, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, spix); #endif - return res; + return res; } #if !SPIFFS_READ_ONLY -static s32_t spiffs_page_index_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { - s32_t res = SPIFFS_OK; - if (pix == (spiffs_page_ix)-1) { - // referring to page 0xffff...., bad object index - return SPIFFS_ERR_INDEX_FREE; - } - if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // referring to an object lookup page, bad object index - return SPIFFS_ERR_INDEX_LU; - } - if (pix > SPIFFS_MAX_PAGES(fs)) { - // referring to a bad page - return SPIFFS_ERR_INDEX_INVALID; - } +static s32_t spiffs_page_index_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) +{ + s32_t res = SPIFFS_OK; + if (pix == (spiffs_page_ix)-1) + { + // referring to page 0xffff...., bad object index + return SPIFFS_ERR_INDEX_FREE; + } + if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + // referring to an object lookup page, bad object index + return SPIFFS_ERR_INDEX_LU; + } + if (pix > SPIFFS_MAX_PAGES(fs)) + { + // referring to a bad page + return SPIFFS_ERR_INDEX_INVALID; + } #if SPIFFS_PAGE_CHECK - spiffs_page_header ph; - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, pix), - sizeof(spiffs_page_header), - (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(ph, fd->obj_id, spix); + spiffs_page_header ph; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(ph, fd->obj_id, spix); #endif - return res; + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY #if !SPIFFS_CACHE -s32_t spiffs_phys_rd( - spiffs *fs, - u32_t addr, - u32_t len, - u8_t *dst) { - return SPIFFS_HAL_READ(fs, addr, len, dst); -} +s32_t spiffs_phys_rd(spiffs *fs, u32_t addr, u32_t len, u8_t *dst) { return SPIFFS_HAL_READ(fs, addr, len, dst); } -s32_t spiffs_phys_wr( - spiffs *fs, - u32_t addr, - u32_t len, - u8_t *src) { - return SPIFFS_HAL_WRITE(fs, addr, len, src); -} +s32_t spiffs_phys_wr(spiffs *fs, u32_t addr, u32_t len, u8_t *src) { return SPIFFS_HAL_WRITE(fs, addr, len, src); } #endif #if !SPIFFS_READ_ONLY -s32_t spiffs_phys_cpy( - spiffs *fs, - spiffs_file fh, - u32_t dst, - u32_t src, - u32_t len) { - (void)fh; - s32_t res; - u8_t b[SPIFFS_COPY_BUFFER_STACK]; - while (len > 0) { - u32_t chunk_size = MIN(SPIFFS_COPY_BUFFER_STACK, len); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVS, fh, src, chunk_size, b); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVD, fh, dst, chunk_size, b); - SPIFFS_CHECK_RES(res); - len -= chunk_size; - src += chunk_size; - dst += chunk_size; - } - return SPIFFS_OK; +s32_t spiffs_phys_cpy(spiffs *fs, spiffs_file fh, u32_t dst, u32_t src, u32_t len) +{ + (void)fh; + s32_t res; + u8_t b[SPIFFS_COPY_BUFFER_STACK]; + while (len > 0) + { + u32_t chunk_size = MIN(SPIFFS_COPY_BUFFER_STACK, len); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVS, fh, src, chunk_size, b); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVD, fh, dst, chunk_size, b); + SPIFFS_CHECK_RES(res); + len -= chunk_size; + src += chunk_size; + dst += chunk_size; + } + return SPIFFS_OK; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY // Find object lookup entry containing given id with visitor. -// Iterate over object lookup pages in each block until a given object id entry is found. -// When found, the visitor function is called with block index, entry index and user data. -// If visitor returns SPIFFS_VIS_CONTINUE, the search goes on. Otherwise, the search will be -// ended and visitor's return code is returned to caller. -// If no visitor is given (0) the search returns on first entry with matching object id. -// If no match is found in all look up, SPIFFS_VIS_END is returned. +// Iterate over object lookup pages in each block until a given object id entry +// is found. When found, the visitor function is called with block index, entry +// index and user data. If visitor returns SPIFFS_VIS_CONTINUE, the search goes +// on. Otherwise, the search will be ended and visitor's return code is returned +// to caller. If no visitor is given (0) the search returns on first entry with +// matching object id. If no match is found in all look up, SPIFFS_VIS_END is +// returned. // @param fs the file system // @param starting_block the starting block to start search in // @param starting_lu_entry the look up index entry to start search in -// @param flags ored combination of SPIFFS_VIS_CHECK_ID, SPIFFS_VIS_CHECK_PH, +// @param flags ored combination of SPIFFS_VIS_CHECK_ID, +// SPIFFS_VIS_CHECK_PH, // SPIFFS_VIS_NO_WRAP // @param obj_id argument object id // @param v visitor callback function -// @param user_const_p any const pointer, passed to the callback visitor function -// @param user_var_p any pointer, passed to the callback visitor function +// @param user_const_p any const pointer, passed to the callback +// visitor function +// @param user_var_p any pointer, passed to the callback visitor +// function // @param block_ix reported block index where match was found // @param lu_entry reported look up index where match was found -s32_t spiffs_obj_lu_find_entry_visitor( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - u8_t flags, - spiffs_obj_id obj_id, - spiffs_visitor_f v, - const void *user_const_p, - void *user_var_p, - spiffs_block_ix *block_ix, - int *lu_entry) { - s32_t res = SPIFFS_OK; - s32_t entry_count = fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); - spiffs_block_ix cur_block = starting_block; - u32_t cur_block_addr = starting_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); - - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = starting_lu_entry; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - - // wrap initial - if (cur_entry >= (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) { - cur_entry = 0; - cur_block++; - cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); - if (cur_block >= fs->block_count) { - if (flags & SPIFFS_VIS_NO_WRAP) { - return SPIFFS_VIS_END; - } else { - // block wrap - cur_block = 0; - cur_block_addr = 0; - } - } - } - - // check each block - while (res == SPIFFS_OK && entry_count > 0) { - int obj_lookup_page = cur_entry / entries_per_page; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages - cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page - { - if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry-entry_offset] == obj_id) { - if (block_ix) *block_ix = cur_block; - if (lu_entry) *lu_entry = cur_entry; - if (v) { - res = v( - fs, - (flags & SPIFFS_VIS_CHECK_PH) ? obj_id : obj_lu_buf[cur_entry-entry_offset], - cur_block, - cur_entry, - user_const_p, - user_var_p); - if (res == SPIFFS_VIS_COUNTINUE || res == SPIFFS_VIS_COUNTINUE_RELOAD) { - if (res == SPIFFS_VIS_COUNTINUE_RELOAD) { - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } - res = SPIFFS_OK; - cur_entry++; - entry_count--; - continue; - } else { - return res; +s32_t spiffs_obj_lu_find_entry_visitor(spiffs *fs, spiffs_block_ix starting_block, int starting_lu_entry, u8_t flags, + spiffs_obj_id obj_id, spiffs_visitor_f v, const void *user_const_p, + void *user_var_p, spiffs_block_ix *block_ix, int *lu_entry) +{ + s32_t res = SPIFFS_OK; + s32_t entry_count = fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); + spiffs_block_ix cur_block = starting_block; + u32_t cur_block_addr = starting_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); + + spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; + int cur_entry = starting_lu_entry; + int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); + + // wrap initial + if (cur_entry >= (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) + { + cur_entry = 0; + cur_block++; + cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); + if (cur_block >= fs->block_count) + { + if (flags & SPIFFS_VIS_NO_WRAP) + { + return SPIFFS_VIS_END; + } + else + { + // block wrap + cur_block = 0; + cur_block_addr = 0; } - } else { - return SPIFFS_OK; - } } - entry_count--; - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - if (cur_block >= fs->block_count) { - if (flags & SPIFFS_VIS_NO_WRAP) { - return SPIFFS_VIS_END; - } else { - // block wrap - cur_block = 0; - cur_block_addr = 0; - } - } - } // per block - - SPIFFS_CHECK_RES(res); - - return SPIFFS_VIS_END; + } + + // check each block + while (res == SPIFFS_OK && entry_count > 0) + { + int obj_lookup_page = cur_entry / entries_per_page; + // check each object lookup page + while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + int entry_offset = obj_lookup_page * entries_per_page; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), + fs->lu_work); + // check each entry + while (res == SPIFFS_OK && cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages + cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page + { + if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry - entry_offset] == obj_id) + { + if (block_ix) + *block_ix = cur_block; + if (lu_entry) + *lu_entry = cur_entry; + if (v) + { + res = v(fs, (flags & SPIFFS_VIS_CHECK_PH) ? obj_id : obj_lu_buf[cur_entry - entry_offset], + cur_block, cur_entry, user_const_p, user_var_p); + if (res == SPIFFS_VIS_COUNTINUE || res == SPIFFS_VIS_COUNTINUE_RELOAD) + { + if (res == SPIFFS_VIS_COUNTINUE_RELOAD) + { + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); + SPIFFS_CHECK_RES(res); + } + res = SPIFFS_OK; + cur_entry++; + entry_count--; + continue; + } + else + { + return res; + } + } + else + { + return SPIFFS_OK; + } + } + entry_count--; + cur_entry++; + } // per entry + obj_lookup_page++; + } // per object lookup page + cur_entry = 0; + cur_block++; + cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); + if (cur_block >= fs->block_count) + { + if (flags & SPIFFS_VIS_NO_WRAP) + { + return SPIFFS_VIS_END; + } + else + { + // block wrap + cur_block = 0; + cur_block_addr = 0; + } + } + } // per block + + SPIFFS_CHECK_RES(res); + + return SPIFFS_VIS_END; } #if !SPIFFS_READ_ONLY -s32_t spiffs_erase_block( - spiffs *fs, - spiffs_block_ix bix) { - s32_t res; - u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix); - s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs); - - // here we ignore res, just try erasing the block - while (size > 0) { - SPIFFS_DBG("erase %08x:%08x\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - - addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); - size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); - } - fs->free_blocks++; - - // register erase count for this block - res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count); - SPIFFS_CHECK_RES(res); +s32_t spiffs_erase_block(spiffs *fs, spiffs_block_ix bix) +{ + s32_t res; + u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix); + s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs); + + // here we ignore res, just try erasing the block + while (size > 0) + { + SPIFFS_DBG("erase %08x:%08x\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); + + addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); + size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); + } + fs->free_blocks++; + + // register erase count for this block + res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count); + SPIFFS_CHECK_RES(res); #if SPIFFS_USE_MAGIC - // finally, write magic - spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix); - res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_MAGIC_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&magic); - SPIFFS_CHECK_RES(res); + // finally, write magic + spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix); + res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, SPIFFS_MAGIC_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&magic); + SPIFFS_CHECK_RES(res); #endif - fs->max_erase_count++; - if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) { - fs->max_erase_count = 0; - } + fs->max_erase_count++; + if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) + { + fs->max_erase_count = 0; + } - return res; + return res; } -#endif // !SPIFFS_READ_ONLY - -#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 -s32_t spiffs_probe( - spiffs_config *cfg) { - s32_t res; - u32_t paddr; - spiffs dummy_fs; // create a dummy fs struct just to be able to use macros - memcpy(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); - dummy_fs.block_count = 0; - - // Read three magics, as one block may be in an aborted erase state. - // At least two of these must contain magic and be in decreasing order. - spiffs_obj_id magic[3]; - spiffs_obj_id bix_count[3]; - - spiffs_block_ix bix; - for (bix = 0; bix < 3; bix++) { - paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, bix); +#endif // !SPIFFS_READ_ONLY + +#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON == 0 +s32_t spiffs_probe(spiffs_config *cfg) +{ + s32_t res; + u32_t paddr; + spiffs dummy_fs; // create a dummy fs struct just to be able to use macros + memcpy(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); + dummy_fs.block_count = 0; + + // Read three magics, as one block may be in an aborted erase state. + // At least two of these must contain magic and be in decreasing order. + spiffs_obj_id magic[3]; + spiffs_obj_id bix_count[3]; + + spiffs_block_ix bix; + for (bix = 0; bix < 3; bix++) + { + paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, bix); #if SPIFFS_HAL_CALLBACK_EXTRA - // not any proper fs to report here, so callback with null - // (cross fingers that no-one gets angry) - res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); + // not any proper fs to report here, so callback with null + // (cross fingers that no-one gets angry) + res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); #else - res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); + res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); #endif - bix_count[bix] = magic[bix] ^ SPIFFS_MAGIC(&dummy_fs, 0); - SPIFFS_CHECK_RES(res); - } - - // check that we have sane number of blocks - if (bix_count[0] < 3) { - return SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS; - } - // check that the order is correct, take aborted erases in calculation - // first block aborted erase - if (magic[0] == (spiffs_obj_id)(-1) && bix_count[1] - bix_count[2] == 1) { - return (bix_count[1]+1) * cfg->log_block_size; - } - // second block aborted erase - if (magic[1] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[2] == 2) { - return bix_count[0] * cfg->log_block_size; - } - // third block aborted erase - if (magic[2] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[1] == 1) { - return bix_count[0] * cfg->log_block_size; - } - // no block has aborted erase - if (bix_count[0] - bix_count[1] == 1 && bix_count[1] - bix_count[2] == 1) { - return bix_count[0] * cfg->log_block_size; - } - - return SPIFFS_ERR_PROBE_NOT_A_FS; -} -#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 - - -static s32_t spiffs_obj_lu_scan_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - (void)bix; - (void)user_const_p; - (void)user_var_p; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - if (ix_entry == 0) { - fs->free_blocks++; - // todo optimize further, return SPIFFS_NEXT_BLOCK - } - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - fs->stats_p_deleted++; - } else { - fs->stats_p_allocated++; - } + bix_count[bix] = magic[bix] ^ SPIFFS_MAGIC(&dummy_fs, 0); + SPIFFS_CHECK_RES(res); + } + + // check that we have sane number of blocks + if (bix_count[0] < 3) + { + return SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS; + } + // check that the order is correct, take aborted erases in calculation + // first block aborted erase + if (magic[0] == (spiffs_obj_id)(-1) && bix_count[1] - bix_count[2] == 1) + { + return (bix_count[1] + 1) * cfg->log_block_size; + } + // second block aborted erase + if (magic[1] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[2] == 2) + { + return bix_count[0] * cfg->log_block_size; + } + // third block aborted erase + if (magic[2] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[1] == 1) + { + return bix_count[0] * cfg->log_block_size; + } + // no block has aborted erase + if (bix_count[0] - bix_count[1] == 1 && bix_count[1] - bix_count[2] == 1) + { + return bix_count[0] * cfg->log_block_size; + } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_ERR_PROBE_NOT_A_FS; } +#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 + +static s32_t spiffs_obj_lu_scan_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix bix, int ix_entry, + const void *user_const_p, void *user_var_p) +{ + (void)bix; + (void)user_const_p; + (void)user_var_p; + if (obj_id == SPIFFS_OBJ_ID_FREE) + { + if (ix_entry == 0) + { + fs->free_blocks++; + // todo optimize further, return SPIFFS_NEXT_BLOCK + } + } + else if (obj_id == SPIFFS_OBJ_ID_DELETED) + { + fs->stats_p_deleted++; + } + else + { + fs->stats_p_allocated++; + } + return SPIFFS_VIS_COUNTINUE; +} // Scans thru all obj lu and counts free, deleted and used pages // Find the maximum block erase count // Checks magic if enabled -s32_t spiffs_obj_lu_scan( - spiffs *fs) { - s32_t res; - spiffs_block_ix bix; - int entry; +s32_t spiffs_obj_lu_scan(spiffs *fs) +{ + s32_t res; + spiffs_block_ix bix; + int entry; #if SPIFFS_USE_MAGIC - spiffs_block_ix unerased_bix = (spiffs_block_ix)-1; + spiffs_block_ix unerased_bix = (spiffs_block_ix)-1; #endif - // find out erase count - // if enabled, check magic - bix = 0; - spiffs_obj_id erase_count_final; - spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE; - spiffs_obj_id erase_count_max = 0; - while (bix < fs->block_count) { + // find out erase count + // if enabled, check magic + bix = 0; + spiffs_obj_id erase_count_final; + spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE; + spiffs_obj_id erase_count_max = 0; + while (bix < fs->block_count) + { #if SPIFFS_USE_MAGIC - spiffs_obj_id magic; - res = _spiffs_rd(fs, - SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_MAGIC_PADDR(fs, bix) , - sizeof(spiffs_obj_id), (u8_t *)&magic); + spiffs_obj_id magic; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_MAGIC_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&magic); - SPIFFS_CHECK_RES(res); - if (magic != SPIFFS_MAGIC(fs, bix)) { - if (unerased_bix == (spiffs_block_ix)-1) { - // allow one unerased block as it might be powered down during an erase - unerased_bix = bix; - } else { - // more than one unerased block, bail out - SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS); - } - } + SPIFFS_CHECK_RES(res); + if (magic != SPIFFS_MAGIC(fs, bix)) + { + if (unerased_bix == (spiffs_block_ix)-1) + { + // allow one unerased block as it might be powered down during + // an erase + unerased_bix = bix; + } + else + { + // more than one unerased block, bail out + SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS); + } + } #endif - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, - SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix) , - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - if (erase_count != SPIFFS_OBJ_ID_FREE) { - erase_count_min = MIN(erase_count_min, erase_count); - erase_count_max = MAX(erase_count_max, erase_count); + spiffs_obj_id erase_count; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), + sizeof(spiffs_obj_id), (u8_t *)&erase_count); + SPIFFS_CHECK_RES(res); + if (erase_count != SPIFFS_OBJ_ID_FREE) + { + erase_count_min = MIN(erase_count_min, erase_count); + erase_count_max = MAX(erase_count_max, erase_count); + } + bix++; } - bix++; - } - if (erase_count_min == 0 && erase_count_max == SPIFFS_OBJ_ID_FREE) { - // clean system, set counter to zero - erase_count_final = 0; - } else if (erase_count_max - erase_count_min > (SPIFFS_OBJ_ID_FREE)/2) { - // wrap, take min - erase_count_final = erase_count_min+1; - } else { - erase_count_final = erase_count_max+1; - } + if (erase_count_min == 0 && erase_count_max == SPIFFS_OBJ_ID_FREE) + { + // clean system, set counter to zero + erase_count_final = 0; + } + else if (erase_count_max - erase_count_min > (SPIFFS_OBJ_ID_FREE) / 2) + { + // wrap, take min + erase_count_final = erase_count_min + 1; + } + else + { + erase_count_final = erase_count_max + 1; + } - fs->max_erase_count = erase_count_final; + fs->max_erase_count = erase_count_final; #if SPIFFS_USE_MAGIC - if (unerased_bix != (spiffs_block_ix)-1) { - // found one unerased block, remedy - SPIFFS_DBG("mount: erase block %i\n", bix); + if (unerased_bix != (spiffs_block_ix)-1) + { + // found one unerased block, remedy + SPIFFS_DBG("mount: erase block %i\n", bix); #if SPIFFS_READ_ONLY - res = SPIFFS_ERR_RO_ABORTED_OPERATION; + res = SPIFFS_ERR_RO_ABORTED_OPERATION; #else - res = spiffs_erase_block(fs, unerased_bix); -#endif // SPIFFS_READ_ONLY - SPIFFS_CHECK_RES(res); - } + res = spiffs_erase_block(fs, unerased_bix); +#endif // SPIFFS_READ_ONLY + SPIFFS_CHECK_RES(res); + } #endif - // count blocks + // count blocks - fs->free_blocks = 0; - fs->stats_p_allocated = 0; - fs->stats_p_deleted = 0; + fs->free_blocks = 0; + fs->stats_p_allocated = 0; + fs->stats_p_deleted = 0; - res = spiffs_obj_lu_find_entry_visitor(fs, - 0, - 0, - 0, - 0, - spiffs_obj_lu_scan_v, - 0, - 0, - &bix, - &entry); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_scan_v, 0, 0, &bix, &entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_OK; + } - SPIFFS_CHECK_RES(res); + SPIFFS_CHECK_RES(res); - return res; + return res; } #if !SPIFFS_READ_ONLY // Find free object lookup entry -// Iterate over object lookup pages in each block until a free object id entry is found -s32_t spiffs_obj_lu_find_free( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - spiffs_block_ix *block_ix, - int *lu_entry) { - s32_t res; - if (!fs->cleaning && fs->free_blocks < 2) { - res = spiffs_gc_quick(fs, 0); - if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) { - res = SPIFFS_OK; +// Iterate over object lookup pages in each block until a free object id entry +// is found +s32_t spiffs_obj_lu_find_free(spiffs *fs, spiffs_block_ix starting_block, int starting_lu_entry, + spiffs_block_ix *block_ix, int *lu_entry) +{ + s32_t res; + if (!fs->cleaning && fs->free_blocks < 2) + { + res = spiffs_gc_quick(fs, 0); + if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) + { + res = SPIFFS_OK; + } + SPIFFS_CHECK_RES(res); + if (fs->free_blocks < 2) + { + return SPIFFS_ERR_FULL; + } } - SPIFFS_CHECK_RES(res); - if (fs->free_blocks < 2) { - return SPIFFS_ERR_FULL; - } - } - res = spiffs_obj_lu_find_id(fs, starting_block, starting_lu_entry, - SPIFFS_OBJ_ID_FREE, block_ix, lu_entry); - if (res == SPIFFS_OK) { - fs->free_cursor_block_ix = *block_ix; - fs->free_cursor_obj_lu_entry = *lu_entry; - if (*lu_entry == 0) { - fs->free_blocks--; - } - } - if (res == SPIFFS_ERR_FULL) { - SPIFFS_DBG("fs full\n"); - } - - return res; + res = spiffs_obj_lu_find_id(fs, starting_block, starting_lu_entry, SPIFFS_OBJ_ID_FREE, block_ix, lu_entry); + if (res == SPIFFS_OK) + { + fs->free_cursor_block_ix = *block_ix; + fs->free_cursor_obj_lu_entry = *lu_entry; + if (*lu_entry == 0) + { + fs->free_blocks--; + } + } + if (res == SPIFFS_ERR_FULL) + { + SPIFFS_DBG("fs full\n"); + } + + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY // Find object lookup entry containing given id -// Iterate over object lookup pages in each block until a given object id entry is found -s32_t spiffs_obj_lu_find_id( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - spiffs_obj_id obj_id, - spiffs_block_ix *block_ix, - int *lu_entry) { - s32_t res = spiffs_obj_lu_find_entry_visitor( - fs, starting_block, starting_lu_entry, SPIFFS_VIS_CHECK_ID, obj_id, 0, 0, 0, block_ix, lu_entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - return res; +// Iterate over object lookup pages in each block until a given object id entry +// is found +s32_t spiffs_obj_lu_find_id(spiffs *fs, spiffs_block_ix starting_block, int starting_lu_entry, spiffs_obj_id obj_id, + spiffs_block_ix *block_ix, int *lu_entry) +{ + s32_t res = spiffs_obj_lu_find_entry_visitor(fs, starting_block, starting_lu_entry, SPIFFS_VIS_CHECK_ID, obj_id, 0, + 0, 0, block_ix, lu_entry); + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_ERR_NOT_FOUND; + } + return res; } - -static s32_t spiffs_obj_lu_find_id_and_span_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - s32_t res; - spiffs_page_header ph; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - res = _spiffs_rd(fs, 0, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_header), (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - if (ph.obj_id == obj_id && - ph.span_ix == *((spiffs_span_ix*)user_var_p) && - (ph.flags & (SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED)) == SPIFFS_PH_FLAG_DELET && - !((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (ph.flags & SPIFFS_PH_FLAG_IXDELE) == 0 && ph.span_ix == 0) && - (user_const_p == 0 || *((const spiffs_page_ix*)user_const_p) != pix)) { - return SPIFFS_OK; - } else { - return SPIFFS_VIS_COUNTINUE; - } +static s32_t spiffs_obj_lu_find_id_and_span_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix bix, int ix_entry, + const void *user_const_p, void *user_var_p) +{ + s32_t res; + spiffs_page_header ph; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + res = _spiffs_rd(fs, 0, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_header), (u8_t *)&ph); + SPIFFS_CHECK_RES(res); + if (ph.obj_id == obj_id && ph.span_ix == *((spiffs_span_ix *)user_var_p) && + (ph.flags & (SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED)) == SPIFFS_PH_FLAG_DELET && + !((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (ph.flags & SPIFFS_PH_FLAG_IXDELE) == 0 && ph.span_ix == 0) && + (user_const_p == 0 || *((const spiffs_page_ix *)user_const_p) != pix)) + { + return SPIFFS_OK; + } + else + { + return SPIFFS_VIS_COUNTINUE; + } } // Find object lookup entry containing given id and span index -// Iterate over object lookup pages in each block until a given object id entry is found -s32_t spiffs_obj_lu_find_id_and_span( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix exclusion_pix, - spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - SPIFFS_VIS_CHECK_ID, - obj_id, - spiffs_obj_lu_find_id_and_span_v, - exclusion_pix ? &exclusion_pix : 0, - &spix, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - - SPIFFS_CHECK_RES(res); - - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; - - return res; +// Iterate over object lookup pages in each block until a given object id entry +// is found +s32_t spiffs_obj_lu_find_id_and_span(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix spix, + spiffs_page_ix exclusion_pix, spiffs_page_ix *pix) +{ + s32_t res; + spiffs_block_ix bix; + int entry; + + res = spiffs_obj_lu_find_entry_visitor(fs, fs->cursor_block_ix, fs->cursor_obj_lu_entry, SPIFFS_VIS_CHECK_ID, + obj_id, spiffs_obj_lu_find_id_and_span_v, exclusion_pix ? &exclusion_pix : 0, + &spix, &bix, &entry); + + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_ERR_NOT_FOUND; + } + + SPIFFS_CHECK_RES(res); + + if (pix) + { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; + + return res; } -// Find object lookup entry containing given id and span index in page headers only -// Iterate over object lookup pages in each block until a given object id entry is found -s32_t spiffs_obj_lu_find_id_and_span_by_phdr( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix exclusion_pix, - spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - SPIFFS_VIS_CHECK_PH, - obj_id, - spiffs_obj_lu_find_id_and_span_v, - exclusion_pix ? &exclusion_pix : 0, - &spix, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - - SPIFFS_CHECK_RES(res); - - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; - - return res; +// Find object lookup entry containing given id and span index in page headers +// only Iterate over object lookup pages in each block until a given object id +// entry is found +s32_t spiffs_obj_lu_find_id_and_span_by_phdr(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix spix, + spiffs_page_ix exclusion_pix, spiffs_page_ix *pix) +{ + s32_t res; + spiffs_block_ix bix; + int entry; + + res = spiffs_obj_lu_find_entry_visitor(fs, fs->cursor_block_ix, fs->cursor_obj_lu_entry, SPIFFS_VIS_CHECK_PH, + obj_id, spiffs_obj_lu_find_id_and_span_v, exclusion_pix ? &exclusion_pix : 0, + &spix, &bix, &entry); + + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_ERR_NOT_FOUND; + } + + SPIFFS_CHECK_RES(res); + + if (pix) + { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; + + return res; } #if !SPIFFS_READ_ONLY // Allocates a free defined page with given obj_id // Occupies object lookup entry and page -// data may be NULL; where only page header is stored, len and page_offs is ignored -s32_t spiffs_page_allocate_data( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_page_header *ph, - u8_t *data, - u32_t len, - u32_t page_offs, - u8_t finalize, - spiffs_page_ix *pix) { - s32_t res = SPIFFS_OK; - spiffs_block_ix bix; - int entry; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - - // occupy page in object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - // write page header - ph->flags &= ~SPIFFS_PH_FLAG_USED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_header), (u8_t*)ph); - SPIFFS_CHECK_RES(res); - - // write page data - if (data) { - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0,SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + sizeof(spiffs_page_header) + page_offs, len, data); +// data may be NULL; where only page header is stored, len and page_offs is +// ignored +s32_t spiffs_page_allocate_data(spiffs *fs, spiffs_obj_id obj_id, spiffs_page_header *ph, u8_t *data, u32_t len, + u32_t page_offs, u8_t finalize, spiffs_page_ix *pix) +{ + s32_t res = SPIFFS_OK; + spiffs_block_ix bix; + int entry; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); SPIFFS_CHECK_RES(res); - } - - // finalize header if necessary - if (finalize && (ph->flags & SPIFFS_PH_FLAG_FINAL)) { - ph->flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&ph->flags); + + // occupy page in object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, 0, + SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + // write page header + ph->flags &= ~SPIFFS_PH_FLAG_USED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), + sizeof(spiffs_page_header), (u8_t *)ph); SPIFFS_CHECK_RES(res); - } - // return written page - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } + // write page data + if (data) + { + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, + SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + sizeof(spiffs_page_header) + page_offs, len, + data); + SPIFFS_CHECK_RES(res); + } + + // finalize header if necessary + if (finalize && (ph->flags & SPIFFS_PH_FLAG_FINAL)) + { + ph->flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, + SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), (u8_t *)&ph->flags); + SPIFFS_CHECK_RES(res); + } + + // return written page + if (pix) + { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } - return res; + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY #if !SPIFFS_READ_ONLY -// Moves a page from src to a free page and finalizes it. Updates page index. Page data is given in param page. -// If page data is null, provided header is used for metainfo and page data is physically copied. -s32_t spiffs_page_move( - spiffs *fs, - spiffs_file fh, - u8_t *page_data, - spiffs_obj_id obj_id, - spiffs_page_header *page_hdr, - spiffs_page_ix src_pix, - spiffs_page_ix *dst_pix) { - s32_t res; - u8_t was_final = 0; - spiffs_page_header *p_hdr; - spiffs_block_ix bix; - int entry; - spiffs_page_ix free_pix; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - - if (dst_pix) *dst_pix = free_pix; - - p_hdr = page_data ? (spiffs_page_header *)page_data : page_hdr; - if (page_data) { - // got page data - was_final = (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) == 0; - // write unfinalized page - p_hdr->flags |= SPIFFS_PH_FLAG_FINAL; - p_hdr->flags &= ~SPIFFS_PH_FLAG_USED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), page_data); - } else { - // copy page data - res = spiffs_phys_cpy(fs, fh, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_PAGE_TO_PADDR(fs, src_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs)); - } - SPIFFS_CHECK_RES(res); - - // mark entry in destination object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - if (was_final) { - // mark finalized in destination page - p_hdr->flags &= ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fh, - SPIFFS_PAGE_TO_PADDR(fs, free_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr->flags); +// Moves a page from src to a free page and finalizes it. Updates page index. +// Page data is given in param page. If page data is null, provided header is +// used for metainfo and page data is physically copied. +s32_t spiffs_page_move(spiffs *fs, spiffs_file fh, u8_t *page_data, spiffs_obj_id obj_id, spiffs_page_header *page_hdr, + spiffs_page_ix src_pix, spiffs_page_ix *dst_pix) +{ + s32_t res; + u8_t was_final = 0; + spiffs_page_header *p_hdr; + spiffs_block_ix bix; + int entry; + spiffs_page_ix free_pix; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + + if (dst_pix) + *dst_pix = free_pix; + + p_hdr = page_data ? (spiffs_page_header *)page_data : page_hdr; + if (page_data) + { + // got page data + was_final = (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) == 0; + // write unfinalized page + p_hdr->flags |= SPIFFS_PH_FLAG_FINAL; + p_hdr->flags &= ~SPIFFS_PH_FLAG_USED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs), page_data); + } + else + { + // copy page data + res = spiffs_phys_cpy(fs, fh, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_PAGE_TO_PADDR(fs, src_pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs)); + } + SPIFFS_CHECK_RES(res); + + // mark entry in destination object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, 0, + SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), (u8_t *)&obj_id); SPIFFS_CHECK_RES(res); - } - // mark source deleted - res = spiffs_page_delete(fs, src_pix); - return res; + + fs->stats_p_allocated++; + + if (was_final) + { + // mark finalized in destination page + p_hdr->flags &= ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, fh, + SPIFFS_PAGE_TO_PADDR(fs, free_pix) + offsetof(spiffs_page_header, flags), sizeof(u8_t), + (u8_t *)&p_hdr->flags); + SPIFFS_CHECK_RES(res); + } + // mark source deleted + res = spiffs_page_delete(fs, src_pix); + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY #if !SPIFFS_READ_ONLY // Deletes a page and removes it from object lookup. -s32_t spiffs_page_delete( - spiffs *fs, - spiffs_page_ix pix) { - s32_t res; - spiffs_page_header hdr; - hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED); - // mark deleted entry in source object lookup - spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, - 0, - SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&d_obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_deleted++; - fs->stats_p_allocated--; - - // mark deleted in source page - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, - 0, - SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&hdr.flags); - - return res; +s32_t spiffs_page_delete(spiffs *fs, spiffs_page_ix pix) +{ + s32_t res; + spiffs_page_header hdr; + hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED); + // mark deleted entry in source object lookup + spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, 0, + SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_page_ix), + sizeof(spiffs_obj_id), (u8_t *)&d_obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_deleted++; + fs->stats_p_allocated--; + + // mark deleted in source page + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, 0, + SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), sizeof(u8_t), + (u8_t *)&hdr.flags); + + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY #if !SPIFFS_READ_ONLY // Create an object index header page with empty index and undefined length -s32_t spiffs_object_create( - spiffs *fs, - spiffs_obj_id obj_id, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - spiffs_obj_type type, - spiffs_page_ix *objix_hdr_pix) { - s32_t res = SPIFFS_OK; - spiffs_block_ix bix; - spiffs_page_object_ix_header oix_hdr; - int entry; - - res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("create: found free page @ %04x bix:%i entry:%i\n", SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); - - // occupy page in object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - // write empty object index page - oix_hdr.p_hdr.obj_id = obj_id; - oix_hdr.p_hdr.span_ix = 0; - oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); - oix_hdr.type = type; - oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page - strncpy((char*)&oix_hdr.name, (const char*)name, SPIFFS_OBJ_NAME_LEN); - - - // update page - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&oix_hdr); - - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_NEW, obj_id, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), SPIFFS_UNDEFINED_LEN); - - if (objix_hdr_pix) { - *objix_hdr_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - return res; +s32_t spiffs_object_create(spiffs *fs, spiffs_obj_id obj_id, const u8_t name[SPIFFS_OBJ_NAME_LEN], spiffs_obj_type type, + spiffs_page_ix *objix_hdr_pix) +{ + s32_t res = SPIFFS_OK; + spiffs_block_ix bix; + spiffs_page_object_ix_header oix_hdr; + int entry; + + res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + + // find free entry + res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG("create: found free page @ %04x bix:%i entry:%i\n", SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, + entry); + + // occupy page in object lookup + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, 0, + SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + SPIFFS_CHECK_RES(res); + + fs->stats_p_allocated++; + + // write empty object index page + oix_hdr.p_hdr.obj_id = obj_id; + oix_hdr.p_hdr.span_ix = 0; + oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); + oix_hdr.type = type; + oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later + // without wasting this page + strncpy((char *)&oix_hdr.name, (const char *)name, SPIFFS_OBJ_NAME_LEN); + + // update page + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), + sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); + + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_NEW, obj_id, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), + SPIFFS_UNDEFINED_LEN); + + if (objix_hdr_pix) + { + *objix_hdr_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + return res; } -#endif // !SPIFFS_READ_ONLY +#endif // !SPIFFS_READ_ONLY #if !SPIFFS_READ_ONLY // update object index header with any combination of name/size/index // new_objix_hdr_data may be null, if so the object index header page is loaded // name may be null, if so name is not changed // size may be null, if so size is not changed -s32_t spiffs_object_update_index_hdr( - spiffs *fs, - spiffs_fd *fd, - spiffs_obj_id obj_id, - spiffs_page_ix objix_hdr_pix, - u8_t *new_objix_hdr_data, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - u32_t size, - spiffs_page_ix *new_pix) { - s32_t res = SPIFFS_OK; - spiffs_page_object_ix_header *objix_hdr; - spiffs_page_ix new_objix_hdr_pix; - - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - - if (new_objix_hdr_data) { - // object index header page already given to us, no need to load it - objix_hdr = (spiffs_page_object_ix_header *)new_objix_hdr_data; - } else { - // read object index header page - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - objix_hdr = (spiffs_page_object_ix_header *)fs->work; - } - - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, obj_id, 0); +s32_t spiffs_object_update_index_hdr(spiffs *fs, spiffs_fd *fd, spiffs_obj_id obj_id, spiffs_page_ix objix_hdr_pix, + u8_t *new_objix_hdr_data, const u8_t name[SPIFFS_OBJ_NAME_LEN], u32_t size, + spiffs_page_ix *new_pix) +{ + s32_t res = SPIFFS_OK; + spiffs_page_object_ix_header *objix_hdr; + spiffs_page_ix new_objix_hdr_pix; + + obj_id |= SPIFFS_OBJ_ID_IX_FLAG; + + if (new_objix_hdr_data) + { + // object index header page already given to us, no need to load it + objix_hdr = (spiffs_page_object_ix_header *)new_objix_hdr_data; + } + else + { + // read object index header page + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + objix_hdr = (spiffs_page_object_ix_header *)fs->work; + } - // change name - if (name) { - strncpy((char*)objix_hdr->name, (const char*)name, SPIFFS_OBJ_NAME_LEN); - } - if (size) { - objix_hdr->size = size; - } + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, obj_id, 0); - // move and update page - res = spiffs_page_move(fs, fd == 0 ? 0 : fd->file_nbr, (u8_t*)objix_hdr, obj_id, 0, objix_hdr_pix, &new_objix_hdr_pix); + // change name + if (name) + { + strncpy((char *)objix_hdr->name, (const char *)name, SPIFFS_OBJ_NAME_LEN); + } + if (size) + { + objix_hdr->size = size; + } - if (res == SPIFFS_OK) { - if (new_pix) { - *new_pix = new_objix_hdr_pix; + // move and update page + res = spiffs_page_move(fs, fd == 0 ? 0 : fd->file_nbr, (u8_t *)objix_hdr, obj_id, 0, objix_hdr_pix, + &new_objix_hdr_pix); + + if (res == SPIFFS_OK) + { + if (new_pix) + { + *new_pix = new_objix_hdr_pix; + } + // callback on object index update + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, obj_id, objix_hdr->p_hdr.span_ix, new_objix_hdr_pix, + objix_hdr->size); + if (fd) + fd->objix_hdr_pix = new_objix_hdr_pix; // if this is not in the registered cluster } - // callback on object index update - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, obj_id, objix_hdr->p_hdr.span_ix, new_objix_hdr_pix, objix_hdr->size); - if (fd) fd->objix_hdr_pix = new_objix_hdr_pix; // if this is not in the registered cluster - } - return res; + return res; } -#endif // !SPIFFS_READ_ONLY - -void spiffs_cb_object_event( - spiffs *fs, - spiffs_fd *fd, - int ev, - spiffs_obj_id obj_id_raw, - spiffs_span_ix spix, - spiffs_page_ix new_pix, - u32_t new_size) { - (void)fd; - // update index caches in all file descriptors - spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0 || (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; - if (spix == 0) { - if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) { - SPIFFS_DBG(" callback: setting fd %i:%04x objix_hdr_pix to %04x, size:%i\n", cur_fd->file_nbr, cur_fd->obj_id, new_pix, new_size); - cur_fd->objix_hdr_pix = new_pix; - if (new_size != 0) { - cur_fd->size = new_size; +#endif // !SPIFFS_READ_ONLY + +void spiffs_cb_object_event(spiffs *fs, spiffs_fd *fd, int ev, spiffs_obj_id obj_id_raw, spiffs_span_ix spix, + spiffs_page_ix new_pix, u32_t new_size) +{ + (void)fd; + // update index caches in all file descriptors + spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) + { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0 || (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) + continue; + if (spix == 0) + { + if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) + { + SPIFFS_DBG( + " callback: setting fd %i:%04x objix_hdr_pix to " + "%04x, size:%i\n", + cur_fd->file_nbr, cur_fd->obj_id, new_pix, new_size); + cur_fd->objix_hdr_pix = new_pix; + if (new_size != 0) + { + cur_fd->size = new_size; + } + } + else if (ev == SPIFFS_EV_IX_DEL) + { + cur_fd->file_nbr = 0; + cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; + } + } + if (cur_fd->cursor_objix_spix == spix) + { + if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) + { + SPIFFS_DBG( + " callback: setting fd %i:%04x span:%04x objix_pix " + "to %04x\n", + cur_fd->file_nbr, cur_fd->obj_id, spix, new_pix); + cur_fd->cursor_objix_pix = new_pix; + } + else + { + cur_fd->cursor_objix_pix = 0; + } + } + } + + // callback to user if object index header + if (fs->file_cb_f && spix == 0 && (obj_id_raw & SPIFFS_OBJ_ID_IX_FLAG)) + { + spiffs_fileop_type op; + if (ev == SPIFFS_EV_IX_NEW) + { + op = SPIFFS_CB_CREATED; + } + else if (ev == SPIFFS_EV_IX_UPD) + { + op = SPIFFS_CB_UPDATED; } - } else if (ev == SPIFFS_EV_IX_DEL) { - cur_fd->file_nbr = 0; - cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; - } - } - if (cur_fd->cursor_objix_spix == spix) { - if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) { - SPIFFS_DBG(" callback: setting fd %i:%04x span:%04x objix_pix to %04x\n", cur_fd->file_nbr, cur_fd->obj_id, spix, new_pix); - cur_fd->cursor_objix_pix = new_pix; - } else { - cur_fd->cursor_objix_pix = 0; - } - } - } - - // callback to user if object index header - if (fs->file_cb_f && spix == 0 && (obj_id_raw & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_fileop_type op; - if (ev == SPIFFS_EV_IX_NEW) { - op = SPIFFS_CB_CREATED; - } else if (ev == SPIFFS_EV_IX_UPD) { - op = SPIFFS_CB_UPDATED; - } else if (ev == SPIFFS_EV_IX_DEL) { - op = SPIFFS_CB_DELETED; - } else { - SPIFFS_DBG(" callback: WARNING unknown callback event %02x\n", ev); - return; // bail out - } - fs->file_cb_f(fs, op, obj_id, new_pix); - } + else if (ev == SPIFFS_EV_IX_DEL) + { + op = SPIFFS_CB_DELETED; + } + else + { + SPIFFS_DBG(" callback: WARNING unknown callback event %02x\n", ev); + return; // bail out + } + fs->file_cb_f(fs, op, obj_id, new_pix); + } } // Open object by id -s32_t spiffs_object_open_by_id( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_fd *fd, - spiffs_flags flags, - spiffs_mode mode) { - s32_t res = SPIFFS_OK; - spiffs_page_ix pix; +s32_t spiffs_object_open_by_id(spiffs *fs, spiffs_obj_id obj_id, spiffs_fd *fd, spiffs_flags flags, spiffs_mode mode) +{ + s32_t res = SPIFFS_OK; + spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - SPIFFS_CHECK_RES(res); + res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + SPIFFS_CHECK_RES(res); - res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); + res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); - return res; + return res; } // Open object by page index -s32_t spiffs_object_open_by_page( - spiffs *fs, - spiffs_page_ix pix, - spiffs_fd *fd, - spiffs_flags flags, - spiffs_mode mode) { - (void)mode; - s32_t res = SPIFFS_OK; - spiffs_page_object_ix_header oix_hdr; - spiffs_obj_id obj_id; - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); - SPIFFS_CHECK_RES(res); - - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(fs, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix); - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); - - fd->fs = fs; - fd->objix_hdr_pix = pix; - fd->size = oix_hdr.size; - fd->offset = 0; - fd->cursor_objix_pix = pix; - fd->cursor_objix_spix = 0; - fd->obj_id = obj_id; - fd->flags = flags; - - SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); - - SPIFFS_DBG("open: fd %i is obj id %04x\n", fd->file_nbr, fd->obj_id); - - return res; +s32_t spiffs_object_open_by_page(spiffs *fs, spiffs_page_ix pix, spiffs_fd *fd, spiffs_flags flags, spiffs_mode mode) +{ + (void)mode; + s32_t res = SPIFFS_OK; + spiffs_page_object_ix_header oix_hdr; + spiffs_obj_id obj_id; + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); + SPIFFS_CHECK_RES(res); + + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(fs, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix); + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, 0, + SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), + (u8_t *)&obj_id); + + fd->fs = fs; + fd->objix_hdr_pix = pix; + fd->size = oix_hdr.size; + fd->offset = 0; + fd->cursor_objix_pix = pix; + fd->cursor_objix_spix = 0; + fd->obj_id = obj_id; + fd->flags = flags; + + SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); + + SPIFFS_DBG("open: fd %i is obj id %04x\n", fd->file_nbr, fd->obj_id); + + return res; } #if !SPIFFS_READ_ONLY // Append to object // keep current object index (header) page in fs->work buffer -s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { - spiffs *fs = fd->fs; - s32_t res = SPIFFS_OK; - u32_t written = 0; - - SPIFFS_DBG("append: %i bytes @ offs %i of size %i\n", len, offset, fd->size); - - if (offset > fd->size) { - SPIFFS_DBG("append: offset reversed to size\n"); - offset = fd->size; - } - - res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta - if (res != SPIFFS_OK) { - SPIFFS_DBG("append: gc check fail %i\n", res); - } - SPIFFS_CHECK_RES(res); - - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_header p_hdr; - - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; - spiffs_page_ix new_objix_hdr_page; - - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_page_ix data_page; - u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); - - // write all data - while (res == SPIFFS_OK && written < len) { - // calculate object index page span index - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // handle storing and loading of object indices - if (cur_objix_spix != prev_objix_spix) { - // new object index page - // within this clause we return directly if something fails, object index mess-up - if (written > 0) { - // store previous object index page, unless first pass - SPIFFS_DBG("append: %04x store objix %04x:%04x, written %i\n", fd->obj_id, - cur_objix_pix, prev_objix_spix, written); - if (prev_objix_spix == 0) { - // this is an update to object index header page - objix_hdr->size = offset+written; - if (offset == 0) { - // was an empty object, update same page (size was 0xffffffff) - res = spiffs_page_index_check(fs, fd, cur_objix_pix, 0); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - } else { - // was a nonempty object, update to new page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, offset+written, &new_objix_hdr_page); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: %04x store new objix_hdr, %04x:%04x, written %i\n", fd->obj_id, - new_objix_hdr_page, 0, written); - } - } else { - // this is an update to an object index page - res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD,fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); - // update length in object index header page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: %04x store new size I %i in objix_hdr, %04x:%04x, written %i\n", fd->obj_id, - offset+written, new_objix_hdr_page, 0, written); +s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) +{ + spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + u32_t written = 0; + + SPIFFS_DBG("append: %i bytes @ offs %i of size %i\n", len, offset, fd->size); + + if (offset > fd->size) + { + SPIFFS_DBG("append: offset reversed to size\n"); + offset = fd->size; + } + + res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta + if (res != SPIFFS_OK) + { + SPIFFS_DBG("append: gc check fail %i\n", res); + } + SPIFFS_CHECK_RES(res); + + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_header p_hdr; + + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; + spiffs_page_ix new_objix_hdr_page; + + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_page_ix data_page; + u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); + + // write all data + while (res == SPIFFS_OK && written < len) + { + // calculate object index page span index + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // handle storing and loading of object indices + if (cur_objix_spix != prev_objix_spix) + { + // new object index page + // within this clause we return directly if something fails, object + // index mess-up + if (written > 0) + { + // store previous object index page, unless first pass + SPIFFS_DBG("append: %04x store objix %04x:%04x, written %i\n", fd->obj_id, cur_objix_pix, + prev_objix_spix, written); + if (prev_objix_spix == 0) + { + // this is an update to object index header page + objix_hdr->size = offset + written; + if (offset == 0) + { + // was an empty object, update same page (size was + // 0xffffffff) + res = spiffs_page_index_check(fs, fd, cur_objix_pix, 0); + SPIFFS_CHECK_RES(res); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + } + else + { + // was a nonempty object, update to new page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, + offset + written, &new_objix_hdr_page); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG( + "append: %04x store new objix_hdr, %04x:%04x, " + "written %i\n", + fd->obj_id, new_objix_hdr_page, 0, written); + } + } + else + { + // this is an update to an object index page + res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, + 0); + // update length in object index header page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, offset + written, + &new_objix_hdr_page); + SPIFFS_CHECK_RES(res); + SPIFFS_DBG( + "append: %04x store new size I %i in objix_hdr, " + "%04x:%04x, written %i\n", + fd->obj_id, offset + written, new_objix_hdr_page, 0, written); + } + fd->size = offset + written; + fd->offset = offset + written; + } + + // create or load new object index page + if (cur_objix_spix == 0) + { + // load object index header page, must always exist + SPIFFS_DBG("append: %04x load objixhdr page %04x:%04x\n", fd->obj_id, cur_objix_pix, cur_objix_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + } + else + { + spiffs_span_ix len_objix_spix = + SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, (fd->size - 1) / SPIFFS_DATA_PAGE_SIZE(fs)); + // on subsequent passes, create a new object index page + if (written > 0 || cur_objix_spix > len_objix_spix) + { + p_hdr.obj_id = fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = cur_objix_spix; + p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); + res = spiffs_page_allocate_data(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, 0, 0, 0, 1, + &cur_objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); + // quick "load" of new object index page + memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + memcpy(fs->work, &p_hdr, sizeof(spiffs_page_header)); + SPIFFS_DBG( + "append: %04x create objix page, %04x:%04x, written " + "%i\n", + fd->obj_id, cur_objix_pix, cur_objix_spix, written); + } + else + { + // on first pass, we load existing object index page + spiffs_page_ix pix; + SPIFFS_DBG("append: %04x find objix span_ix:%04x\n", fd->obj_id, cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) + { + pix = fd->cursor_objix_pix; + } + else + { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, + &pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG( + "append: %04x found object index at page %04x [fd size " + "%i]\n", + fd->obj_id, pix, fd->size); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + cur_objix_pix = pix; + } + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = offset + written; + fd->size = offset + written; + } + prev_objix_spix = cur_objix_spix; } - fd->size = offset+written; - fd->offset = offset+written; - } - - // create or load new object index page - if (cur_objix_spix == 0) { - // load object index header page, must always exist - SPIFFS_DBG("append: %04x load objixhdr page %04x:%04x\n", fd->obj_id, cur_objix_pix, cur_objix_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - } else { - spiffs_span_ix len_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, (fd->size-1)/SPIFFS_DATA_PAGE_SIZE(fs)); - // on subsequent passes, create a new object index page - if (written > 0 || cur_objix_spix > len_objix_spix) { - p_hdr.obj_id = fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = cur_objix_spix; - p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); - res = spiffs_page_allocate_data(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 1, &cur_objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); - // quick "load" of new object index page - memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - memcpy(fs->work, &p_hdr, sizeof(spiffs_page_header)); - SPIFFS_DBG("append: %04x create objix page, %04x:%04x, written %i\n", fd->obj_id - , cur_objix_pix, cur_objix_spix, written); - } else { - // on first pass, we load existing object index page - spiffs_page_ix pix; - SPIFFS_DBG("append: %04x find objix span_ix:%04x\n", fd->obj_id, cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - pix = fd->cursor_objix_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + + // write data + u32_t to_write = MIN(len - written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); + if (page_offs == 0) + { + // at beginning of a page, allocate and write a new page of data + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, &data[written], to_write, + page_offs, 1, &data_page); + SPIFFS_DBG( + "append: %04x store new data page, %04x:%04x offset:%i, len " + "%i, written %i\n", + fd->obj_id, data_page, data_spix, page_offs, to_write, written); + } + else + { + // append to existing page, fill out free data in existing page + if (cur_objix_spix == 0) + { + // get data page from object index header page + data_page = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } + else + { + // get data page from object index page + data_page = ((spiffs_page_ix *)((u8_t *)objix + + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } + + res = spiffs_page_data_check(fs, fd, data_page, data_spix); SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("append: %04x found object index at page %04x [fd size %i]\n", fd->obj_id, pix, fd->size); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - cur_objix_pix = pix; + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, + &data[written]); + SPIFFS_DBG( + "append: %04x store to existing data page, %04x:%04x " + "offset:%i, len %i, written %i\n", + fd->obj_id, data_page, data_spix, page_offs, to_write, written); } - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = offset+written; - fd->size = offset+written; - } - prev_objix_spix = cur_objix_spix; - } - - // write data - u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); - if (page_offs == 0) { - // at beginning of a page, allocate and write a new page of data - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, &data[written], to_write, page_offs, 1, &data_page); - SPIFFS_DBG("append: %04x store new data page, %04x:%04x offset:%i, len %i, written %i\n", fd->obj_id, - data_page, data_spix, page_offs, to_write, written); - } else { - // append to existing page, fill out free data in existing page - if (cur_objix_spix == 0) { - // get data page from object index header page - data_page = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - data_page = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } - - res = spiffs_page_data_check(fs, fd, data_page, data_spix); - SPIFFS_CHECK_RES(res); - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - SPIFFS_DBG("append: %04x store to existing data page, %04x:%04x offset:%i, len %i, written %i\n", fd->obj_id - , data_page, data_spix, page_offs, to_write, written); - } - - if (res != SPIFFS_OK) break; - - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page; - SPIFFS_DBG("append: %04x wrote page %04x to objix_hdr entry %02x in mem\n", fd->obj_id - , data_page, data_spix); - objix_hdr->size = offset+written; - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page; - SPIFFS_DBG("append: %04x wrote page %04x to objix entry %02x in mem\n", fd->obj_id - , data_page, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - - // update internals - page_offs = 0; - data_spix++; - written += to_write; - } // while all data - - fd->size = offset+written; - fd->offset = offset+written; - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - // finalize updated object indices - s32_t res2 = SPIFFS_OK; - if (cur_objix_spix != 0) { - // wrote beyond object index header page - // write last modified object index page, unless object header index page - SPIFFS_DBG("append: %04x store objix page, %04x:%04x, written %i\n", fd->obj_id, - cur_objix_pix, cur_objix_spix, written); - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res2); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); - - // update size in object header index page - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: %04x store new size II %i in objix_hdr, %04x:%04x, written %i, res %i\n", fd->obj_id - , offset+written, new_objix_hdr_page, 0, written, res2); - SPIFFS_CHECK_RES(res2); - } else { - // wrote within object index header page - if (offset == 0) { - // wrote to empty object - simply update size and write whole page - objix_hdr->size = offset+written; - SPIFFS_DBG("append: %04x store fresh objix_hdr page, %04x:%04x, written %i\n", fd->obj_id - , cur_objix_pix, cur_objix_spix, written); - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res2); - // callback on object index update - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix_hdr->p_hdr.span_ix, cur_objix_pix, objix_hdr->size); - } else { - // modifying object index header page, update size and make new copy - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: %04x store modified objix_hdr page, %04x:%04x, written %i\n", fd->obj_id - , new_objix_hdr_page, 0, written); - SPIFFS_CHECK_RES(res2); - } - } - - return res; -} // spiffs_object_append -#endif // !SPIFFS_READ_ONLY + + if (res != SPIFFS_OK) + break; + + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) + { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page; + SPIFFS_DBG("append: %04x wrote page %04x to objix_hdr entry %02x in mem\n", fd->obj_id, data_page, + data_spix); + objix_hdr->size = offset + written; + } + else + { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = + data_page; + SPIFFS_DBG("append: %04x wrote page %04x to objix entry %02x in mem\n", fd->obj_id, data_page, + SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + + // update internals + page_offs = 0; + data_spix++; + written += to_write; + } // while all data + + fd->size = offset + written; + fd->offset = offset + written; + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + // finalize updated object indices + s32_t res2 = SPIFFS_OK; + if (cur_objix_spix != 0) + { + // wrote beyond object index header page + // write last modified object index page, unless object header index + // page + SPIFFS_DBG("append: %04x store objix page, %04x:%04x, written %i\n", fd->obj_id, cur_objix_pix, cur_objix_spix, + written); + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res2); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); + + // update size in object header index page + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, offset + written, + &new_objix_hdr_page); + SPIFFS_DBG( + "append: %04x store new size II %i in objix_hdr, %04x:%04x, " + "written %i, res %i\n", + fd->obj_id, offset + written, new_objix_hdr_page, 0, written, res2); + SPIFFS_CHECK_RES(res2); + } + else + { + // wrote within object index header page + if (offset == 0) + { + // wrote to empty object - simply update size and write whole page + objix_hdr->size = offset + written; + SPIFFS_DBG( + "append: %04x store fresh objix_hdr page, %04x:%04x, written " + "%i\n", + fd->obj_id, cur_objix_pix, cur_objix_spix, written); + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res2); + // callback on object index update + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix_hdr->p_hdr.span_ix, cur_objix_pix, + objix_hdr->size); + } + else + { + // modifying object index header page, update size and make new copy + res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, offset + written, + &new_objix_hdr_page); + SPIFFS_DBG( + "append: %04x store modified objix_hdr page, %04x:%04x, " + "written %i\n", + fd->obj_id, new_objix_hdr_page, 0, written); + SPIFFS_CHECK_RES(res2); + } + } + + return res; +} // spiffs_object_append +#endif // !SPIFFS_READ_ONLY #if !SPIFFS_READ_ONLY // Modify object // keep current object index (header) page in fs->work buffer -s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { - spiffs *fs = fd->fs; - s32_t res = SPIFFS_OK; - u32_t written = 0; - - res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_header p_hdr; - - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; - spiffs_page_ix new_objix_hdr_pix; - - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_page_ix data_pix; - u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); - - - // write all data - while (res == SPIFFS_OK && written < len) { - // calculate object index page span index - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // handle storing and loading of object indices - if (cur_objix_spix != prev_objix_spix) { - // new object index page - // within this clause we return directly if something fails, object index mess-up - if (written > 0) { - // store previous object index (header) page, unless first pass - if (prev_objix_spix == 0) { - // store previous object index header page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); - SPIFFS_CHECK_RES(res); - } else { - // store new version of previous object index page - spiffs_page_ix new_objix_pix; - - res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store previous modified objix page, %04x:%04x, written %i\n", new_objix_pix, objix->p_hdr.span_ix, written); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); +s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) +{ + spiffs *fs = fd->fs; + s32_t res = SPIFFS_OK; + u32_t written = 0; + + res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_CHECK_RES(res); + + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_header p_hdr; + + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; + spiffs_page_ix new_objix_hdr_pix; + + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + spiffs_page_ix data_pix; + u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); + + // write all data + while (res == SPIFFS_OK && written < len) + { + // calculate object index page span index + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // handle storing and loading of object indices + if (cur_objix_spix != prev_objix_spix) + { + // new object index page + // within this clause we return directly if something fails, object + // index mess-up + if (written > 0) + { + // store previous object index (header) page, unless first pass + if (prev_objix_spix == 0) + { + // store previous object index header page + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, 0, + &new_objix_hdr_pix); + SPIFFS_DBG( + "modify: store modified objix_hdr page, %04x:%04x, " + "written %i\n", + new_objix_hdr_pix, 0, written); + SPIFFS_CHECK_RES(res); + } + else + { + // store new version of previous object index page + spiffs_page_ix new_objix_pix; + + res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = + spiffs_page_move(fs, fd->file_nbr, (u8_t *)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); + SPIFFS_DBG( + "modify: store previous modified objix page, " + "%04x:%04x, written %i\n", + new_objix_pix, objix->p_hdr.span_ix, written); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, + 0); + } + } + + // load next object index page + if (cur_objix_spix == 0) + { + // load object index header page, must exist + SPIFFS_DBG("modify: load objixhdr page %04x:%04x\n", cur_objix_pix, cur_objix_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + } + else + { + // load existing object index page on first pass + spiffs_page_ix pix; + SPIFFS_DBG("modify: find objix span_ix:%04x\n", cur_objix_spix); + if (fd->cursor_objix_spix == cur_objix_spix) + { + pix = fd->cursor_objix_pix; + } + else + { + res = + spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG("modify: found object index at page %04x\n", pix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), + SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + cur_objix_pix = pix; + } + fd->cursor_objix_pix = cur_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = offset + written; + prev_objix_spix = cur_objix_spix; } - } - - // load next object index page - if (cur_objix_spix == 0) { - // load object index header page, must exist - SPIFFS_DBG("modify: load objixhdr page %04x:%04x\n", cur_objix_pix, cur_objix_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - } else { - // load existing object index page on first pass - spiffs_page_ix pix; - SPIFFS_DBG("modify: find objix span_ix:%04x\n", cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - pix = fd->cursor_objix_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); - SPIFFS_CHECK_RES(res); + + // write partial data + u32_t to_write = MIN(len - written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); + spiffs_page_ix orig_data_pix; + if (cur_objix_spix == 0) + { + // get data page from object index header page + orig_data_pix = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } + else + { + // get data page from object index page + orig_data_pix = + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; } - SPIFFS_DBG("modify: found object index at page %04x\n", pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - cur_objix_pix = pix; - } - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = offset+written; - prev_objix_spix = cur_objix_spix; - } - - // write partial data - u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); - spiffs_page_ix orig_data_pix; - if (cur_objix_spix == 0) { - // get data page from object index header page - orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } - - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff; - if (page_offs == 0 && to_write == SPIFFS_DATA_PAGE_SIZE(fs)) { - // a full page, allocate and write a new page of data - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); - SPIFFS_DBG("modify: store new data page, %04x:%04x offset:%i, len %i, written %i\n", data_pix, data_spix, page_offs, to_write, written); - } else { - // write to existing page, allocate new and copy unmodified data - - res = spiffs_page_data_check(fs, fd, orig_data_pix, data_spix); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 0, &data_pix); - if (res != SPIFFS_OK) break; - - // copy unmodified data - if (page_offs > 0) { - // before modification - res = spiffs_phys_cpy(fs, fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header), - page_offs); - if (res != SPIFFS_OK) break; - } - if (page_offs + to_write < SPIFFS_DATA_PAGE_SIZE(fs)) { - // after modification - res = spiffs_phys_cpy(fs, fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, - SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, - SPIFFS_DATA_PAGE_SIZE(fs) - (page_offs + to_write)); - if (res != SPIFFS_OK) break; - } - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - if (res != SPIFFS_OK) break; - p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr.flags); - if (res != SPIFFS_OK) break; - - SPIFFS_DBG("modify: store to existing data page, src:%04x, dst:%04x:%04x offset:%i, len %i, written %i\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); - } - - // delete original data page - res = spiffs_page_delete(fs, orig_data_pix); - if (res != SPIFFS_OK) break; - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_pix; - SPIFFS_DBG("modify: wrote page %04x to objix_hdr entry %02x in mem\n", data_pix, data_spix); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_pix; - SPIFFS_DBG("modify: wrote page %04x to objix entry %02x in mem\n", data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - - // update internals - page_offs = 0; - data_spix++; - written += to_write; - } // while all data - - fd->offset = offset+written; - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - // finalize updated object indices - s32_t res2 = SPIFFS_OK; - if (cur_objix_spix != 0) { - // wrote beyond object index header page - // write last modified object index page - // move and update page - spiffs_page_ix new_objix_pix; - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff; + if (page_offs == 0 && to_write == SPIFFS_DATA_PAGE_SIZE(fs)) + { + // a full page, allocate and write a new page of data + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, &data[written], to_write, + page_offs, 1, &data_pix); + SPIFFS_DBG( + "modify: store new data page, %04x:%04x offset:%i, len %i, " + "written %i\n", + data_pix, data_spix, page_offs, to_write, written); + } + else + { + // write to existing page, allocate new and copy unmodified data - res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store modified objix page, %04x:%04x, written %i\n", new_objix_pix, cur_objix_spix, written); - fd->cursor_objix_pix = new_objix_pix; + res = spiffs_page_data_check(fs, fd, orig_data_pix, data_spix); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, 0, 0, 0, 0, &data_pix); + if (res != SPIFFS_OK) + break; + + // copy unmodified data + if (page_offs > 0) + { + // before modification + res = spiffs_phys_cpy(fs, fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header), page_offs); + if (res != SPIFFS_OK) + break; + } + if (page_offs + to_write < SPIFFS_DATA_PAGE_SIZE(fs)) + { + // after modification + res = spiffs_phys_cpy( + fs, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, + SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, + SPIFFS_DATA_PAGE_SIZE(fs) - (page_offs + to_write)); + if (res != SPIFFS_OK) + break; + } + + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs, to_write, + &data[written]); + if (res != SPIFFS_OK) + break; + p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + offsetof(spiffs_page_header, flags), sizeof(u8_t), + (u8_t *)&p_hdr.flags); + if (res != SPIFFS_OK) + break; + + SPIFFS_DBG( + "modify: store to existing data page, src:%04x, dst:%04x:%04x " + "offset:%i, len %i, written %i\n", + orig_data_pix, data_pix, data_spix, page_offs, to_write, written); + } + + // delete original data page + res = spiffs_page_delete(fs, orig_data_pix); + if (res != SPIFFS_OK) + break; + // update memory representation of object index page with new data page + if (cur_objix_spix == 0) + { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_pix; + SPIFFS_DBG("modify: wrote page %04x to objix_hdr entry %02x in mem\n", data_pix, data_spix); + } + else + { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = + data_pix; + SPIFFS_DBG("modify: wrote page %04x to objix entry %02x in mem\n", data_pix, + SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + + // update internals + page_offs = 0; + data_spix++; + written += to_write; + } // while all data + + fd->offset = offset + written; + fd->cursor_objix_pix = cur_objix_pix; fd->cursor_objix_spix = cur_objix_spix; - SPIFFS_CHECK_RES(res2); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - - } else { - // wrote within object index header page - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); - SPIFFS_CHECK_RES(res2); - } - - return res; -} // spiffs_object_modify -#endif // !SPIFFS_READ_ONLY - -static s32_t spiffs_object_find_object_index_header_by_name_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - (void)user_var_p; - s32_t res; - spiffs_page_object_ix_header objix_hdr; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || - (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { + + // finalize updated object indices + s32_t res2 = SPIFFS_OK; + if (cur_objix_spix != 0) + { + // wrote beyond object index header page + // write last modified object index page + // move and update page + spiffs_page_ix new_objix_pix; + + res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); + SPIFFS_CHECK_RES(res2); + + res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t *)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); + SPIFFS_DBG("modify: store modified objix page, %04x:%04x, written %i\n", new_objix_pix, cur_objix_spix, + written); + fd->cursor_objix_pix = new_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + SPIFFS_CHECK_RES(res2); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + } + else + { + // wrote within object index header page + res2 = + spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); + SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); + SPIFFS_CHECK_RES(res2); + } + + return res; +} // spiffs_object_modify +#endif // !SPIFFS_READ_ONLY + +static s32_t spiffs_object_find_object_index_header_by_name_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix bix, + int ix_entry, const void *user_const_p, void *user_var_p) +{ + (void)user_var_p; + s32_t res; + spiffs_page_object_ix_header objix_hdr; + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) + { + return SPIFFS_VIS_COUNTINUE; + } + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_CHECK_RES(res); + if (objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) + { + if (strcmp((const char *)user_const_p, (char *)objix_hdr.name) == 0) + { + return SPIFFS_OK; + } + } + return SPIFFS_VIS_COUNTINUE; - } - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_CHECK_RES(res); - if (objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { - return SPIFFS_OK; - } - } - - return SPIFFS_VIS_COUNTINUE; } // Finds object index header page by name -s32_t spiffs_object_find_object_index_header_by_name( - spiffs *fs, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - 0, - 0, - spiffs_object_find_object_index_header_by_name_v, - name, - 0, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - SPIFFS_CHECK_RES(res); - - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; - - return res; -} +s32_t spiffs_object_find_object_index_header_by_name(spiffs *fs, const u8_t name[SPIFFS_OBJ_NAME_LEN], + spiffs_page_ix *pix) +{ + s32_t res; + spiffs_block_ix bix; + int entry; -#if !SPIFFS_READ_ONLY -// Truncates object to new size. If new size is null, object may be removed totally -s32_t spiffs_object_truncate( - spiffs_fd *fd, - u32_t new_size, - u8_t remove) { - s32_t res = SPIFFS_OK; - spiffs *fs = fd->fs; - - if ((fd->size == SPIFFS_UNDEFINED_LEN || fd->size == 0) && !remove) { - // no op - return res; - } + res = spiffs_obj_lu_find_entry_visitor(fs, fs->cursor_block_ix, fs->cursor_obj_lu_entry, 0, 0, + spiffs_object_find_object_index_header_by_name_v, name, 0, &bix, &entry); - // need 2 pages if not removing: object index page + possibly chopped data page - if (remove == 0) { - res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs) * 2); - SPIFFS_CHECK_RES(res); - } - - spiffs_page_ix objix_pix = fd->objix_hdr_pix; - spiffs_span_ix data_spix = (fd->size > 0 ? fd->size-1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs); - u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size ; - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_ix data_pix; - spiffs_page_ix new_objix_hdr_pix; - - // before truncating, check if object is to be fully removed and mark this - if (remove && new_size == 0) { - u8_t flags = ~( SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, fd->objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&flags); + if (res == SPIFFS_VIS_END) + { + res = SPIFFS_ERR_NOT_FOUND; + } SPIFFS_CHECK_RES(res); - } - // delete from end of object until desired len is reached - while (cur_size > new_size) { - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (pix) + { + *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); + } + + fs->cursor_block_ix = bix; + fs->cursor_obj_lu_entry = entry; + + return res; +} - // put object index for current data span index in work buffer - if (prev_objix_spix != cur_objix_spix) { - if (prev_objix_spix != (spiffs_span_ix)-1) { - // remove previous object index page - SPIFFS_DBG("truncate: delete objix page %04x:%04x\n", objix_pix, prev_objix_spix); +#if !SPIFFS_READ_ONLY +// Truncates object to new size. If new size is null, object may be removed +// totally +s32_t spiffs_object_truncate(spiffs_fd *fd, u32_t new_size, u8_t remove) +{ + s32_t res = SPIFFS_OK; + spiffs *fs = fd->fs; + + if ((fd->size == SPIFFS_UNDEFINED_LEN || fd->size == 0) && !remove) + { + // no op + return res; + } - res = spiffs_page_index_check(fs, fd, objix_pix, prev_objix_spix); + // need 2 pages if not removing: object index page + possibly chopped data + // page + if (remove == 0) + { + res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs) * 2); SPIFFS_CHECK_RES(res); + } - res = spiffs_page_delete(fs, objix_pix); + spiffs_page_ix objix_pix = fd->objix_hdr_pix; + spiffs_span_ix data_spix = (fd->size > 0 ? fd->size - 1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size; + spiffs_span_ix cur_objix_spix = 0; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + spiffs_page_ix data_pix; + spiffs_page_ix new_objix_hdr_pix; + + // before truncating, check if object is to be fully removed and mark this + if (remove && new_size == 0) + { + u8_t flags = ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE); + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, fd->objix_hdr_pix) + offsetof(spiffs_page_header, flags), + sizeof(u8_t), (u8_t *)&flags); SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); - if (prev_objix_spix > 0) { - // Update object index header page, unless we totally want to remove the file. - // If fully removing, we're not keeping consistency as good as when storing the header between chunks, - // would we be aborted. But when removing full files, a crammed system may otherwise - // report ERR_FULL a la windows. We cannot have that. - // Hence, take the risk - if aborted, a file check would free the lost pages and mend things - // as the file is marked as fully deleted in the beginning. - if (remove == 0) { - SPIFFS_DBG("truncate: update objix hdr page %04x:%04x to size %i\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, cur_size, &new_objix_hdr_pix); + } + + // delete from end of object until desired len is reached + while (cur_size > new_size) + { + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + + // put object index for current data span index in work buffer + if (prev_objix_spix != cur_objix_spix) + { + if (prev_objix_spix != (spiffs_span_ix)-1) + { + // remove previous object index page + SPIFFS_DBG("truncate: delete objix page %04x:%04x\n", objix_pix, prev_objix_spix); + + res = spiffs_page_index_check(fs, fd, objix_pix, prev_objix_spix); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_delete(fs, objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); + if (prev_objix_spix > 0) + { + // Update object index header page, unless we totally want + // to remove the file. If fully removing, we're not keeping + // consistency as good as when storing the header between + // chunks, would we be aborted. But when removing full + // files, a crammed system may otherwise report ERR_FULL a + // la windows. We cannot have that. Hence, take the risk - + // if aborted, a file check would free the lost pages and + // mend things as the file is marked as fully deleted in the + // beginning. + if (remove == 0) + { + SPIFFS_DBG( + "truncate: update objix hdr page %04x:%04x to size " + "%i\n", + fd->objix_hdr_pix, prev_objix_spix, cur_size); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, cur_size, + &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + fd->size = cur_size; + } + } + // load current object index (header) page + if (cur_objix_spix == 0) + { + objix_pix = fd->objix_hdr_pix; + } + else + { + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, + &objix_pix); + SPIFFS_CHECK_RES(res); + } + + SPIFFS_DBG("truncate: load objix page %04x:%04x for data spix:%04x\n", objix_pix, cur_objix_spix, + data_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); SPIFFS_CHECK_RES(res); - } - fd->size = cur_size; + SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); + fd->cursor_objix_pix = objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = cur_size; + + prev_objix_spix = cur_objix_spix; } - } - // load current object index (header) page - if (cur_objix_spix == 0) { - objix_pix = fd->objix_hdr_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - } - - SPIFFS_DBG("truncate: load objix page %04x:%04x for data spix:%04x\n", objix_pix, cur_objix_spix, data_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - fd->cursor_objix_pix = objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = cur_size; - - prev_objix_spix = cur_objix_spix; - } - - if (cur_objix_spix == 0) { - // get data page from object index header page - data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE; - } else { - // get data page from object index page - data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE; - } - - SPIFFS_DBG("truncate: got data pix %04x\n", data_pix); - - if (new_size == 0 || remove || cur_size - new_size >= SPIFFS_DATA_PAGE_SIZE(fs)) { - // delete full data page - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) { - SPIFFS_DBG("truncate: err validating data pix %i\n", res); - break; - } - - if (res == SPIFFS_OK) { - res = spiffs_page_delete(fs, data_pix); - if (res != SPIFFS_OK) { - SPIFFS_DBG("truncate: err deleting data pix %i\n", res); - break; + + if (cur_objix_spix == 0) + { + // get data page from object index header page + data_pix = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = + SPIFFS_OBJ_ID_FREE; } - } else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) { - res = SPIFFS_OK; - } - - // update current size - if (cur_size % SPIFFS_DATA_PAGE_SIZE(fs) == 0) { - cur_size -= SPIFFS_DATA_PAGE_SIZE(fs); - } else { - cur_size -= cur_size % SPIFFS_DATA_PAGE_SIZE(fs); - } - fd->size = cur_size; - fd->offset = cur_size; - SPIFFS_DBG("truncate: delete data page %04x for data spix:%04x, cur_size:%i\n", data_pix, data_spix, cur_size); - } else { - // delete last page, partially - spiffs_page_header p_hdr; - spiffs_page_ix new_data_pix; - u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_DBG("truncate: delete %i bytes from data page %04x for data spix:%04x, cur_size:%i\n", bytes_to_remove, data_pix, data_spix, cur_size); - - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - if (res != SPIFFS_OK) break; - - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff; - // allocate new page and copy unmodified data - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 0, &new_data_pix); - if (res != SPIFFS_OK) break; - res = spiffs_phys_cpy(fs, 0, - SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), - SPIFFS_DATA_PAGE_SIZE(fs) - bytes_to_remove); - if (res != SPIFFS_OK) break; - // delete original data page - res = spiffs_page_delete(fs, data_pix); - if (res != SPIFFS_OK) break; - p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr.flags); - if (res != SPIFFS_OK) break; - - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { + else + { + // get data page from object index page + data_pix = + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = + SPIFFS_OBJ_ID_FREE; + } + + SPIFFS_DBG("truncate: got data pix %04x\n", data_pix); + + if (new_size == 0 || remove || cur_size - new_size >= SPIFFS_DATA_PAGE_SIZE(fs)) + { + // delete full data page + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) + { + SPIFFS_DBG("truncate: err validating data pix %i\n", res); + break; + } + + if (res == SPIFFS_OK) + { + res = spiffs_page_delete(fs, data_pix); + if (res != SPIFFS_OK) + { + SPIFFS_DBG("truncate: err deleting data pix %i\n", res); + break; + } + } + else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) + { + res = SPIFFS_OK; + } + + // update current size + if (cur_size % SPIFFS_DATA_PAGE_SIZE(fs) == 0) + { + cur_size -= SPIFFS_DATA_PAGE_SIZE(fs); + } + else + { + cur_size -= cur_size % SPIFFS_DATA_PAGE_SIZE(fs); + } + fd->size = cur_size; + fd->offset = cur_size; + SPIFFS_DBG( + "truncate: delete data page %04x for data spix:%04x, " + "cur_size:%i\n", + data_pix, data_spix, cur_size); + } + else + { + // delete last page, partially + spiffs_page_header p_hdr; + spiffs_page_ix new_data_pix; + u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); + SPIFFS_DBG( + "truncate: delete %i bytes from data page %04x for data " + "spix:%04x, cur_size:%i\n", + bytes_to_remove, data_pix, data_spix, cur_size); + + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); + if (res != SPIFFS_OK) + break; + + p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; + p_hdr.span_ix = data_spix; + p_hdr.flags = 0xff; + // allocate new page and copy unmodified data + res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, &p_hdr, 0, 0, 0, 0, &new_data_pix); + if (res != SPIFFS_OK) + break; + res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + sizeof(spiffs_page_header), + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), + SPIFFS_DATA_PAGE_SIZE(fs) - bytes_to_remove); + if (res != SPIFFS_OK) + break; + // delete original data page + res = spiffs_page_delete(fs, data_pix); + if (res != SPIFFS_OK) + break; + p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; + res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + offsetof(spiffs_page_header, flags), sizeof(u8_t), + (u8_t *)&p_hdr.flags); + if (res != SPIFFS_OK) + break; + + // update memory representation of object index page with new data + // page + if (cur_objix_spix == 0) + { + // update object index header page + ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = + new_data_pix; + SPIFFS_DBG( + "truncate: wrote page %04x to objix_hdr entry %02x in " + "mem\n", + new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + else + { + // update object index page + ((spiffs_page_ix *)((u8_t *)objix + + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; + SPIFFS_DBG("truncate: wrote page %04x to objix entry %02x in mem\n", new_data_pix, + SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); + } + cur_size = new_size; + fd->size = new_size; + fd->offset = cur_size; + break; + } + data_spix--; + } // while all data + + // update object indices + if (cur_objix_spix == 0) + { // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; - SPIFFS_DBG("truncate: wrote page %04x to objix_hdr entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; - SPIFFS_DBG("truncate: wrote page %04x to objix entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - cur_size = new_size; - fd->size = new_size; - fd->offset = cur_size; - break; - } - data_spix--; - } // while all data - - // update object indices - if (cur_objix_spix == 0) { - // update object index header page - if (cur_size == 0) { - if (remove) { - // remove object altogether - SPIFFS_DBG("truncate: remove object index header page %04x\n", objix_pix); - - res = spiffs_page_index_check(fs, fd, objix_pix, 0); + if (cur_size == 0) + { + if (remove) + { + // remove object altogether + SPIFFS_DBG("truncate: remove object index header page %04x\n", objix_pix); + + res = spiffs_page_index_check(fs, fd, objix_pix, 0); + SPIFFS_CHECK_RES(res); + + res = spiffs_page_delete(fs, objix_pix); + SPIFFS_CHECK_RES(res); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, 0, objix_pix, 0); + } + else + { + // make uninitialized object + SPIFFS_DBG("truncate: reset objix_hdr page %04x\n", objix_pix); + memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, + SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, objix_pix, fs->work, 0, SPIFFS_UNDEFINED_LEN, + &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + } + else + { + // update object index header page + SPIFFS_DBG( + "truncate: update object index header page with indices and " + "size\n"); + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, objix_pix, fs->work, 0, cur_size, + &new_objix_hdr_pix); + SPIFFS_CHECK_RES(res); + } + } + else + { + // update both current object index page and object index header page + spiffs_page_ix new_objix_pix; + + res = spiffs_page_index_check(fs, fd, objix_pix, cur_objix_spix); SPIFFS_CHECK_RES(res); - res = spiffs_page_delete(fs, objix_pix); + // move and update object index page + res = spiffs_page_move(fs, fd->file_nbr, (u8_t *)objix_hdr, fd->obj_id, 0, objix_pix, &new_objix_pix); SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, 0, objix_pix, 0); - } else { - // make uninitialized object - SPIFFS_DBG("truncate: reset objix_hdr page %04x\n", objix_pix); - memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - objix_pix, fs->work, 0, SPIFFS_UNDEFINED_LEN, &new_objix_hdr_pix); + spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); + SPIFFS_DBG("truncate: store modified objix page, %04x:%04x\n", new_objix_pix, cur_objix_spix); + fd->cursor_objix_pix = new_objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + fd->offset = cur_size; + // update object index header page with new size + res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, 0, cur_size, &new_objix_hdr_pix); SPIFFS_CHECK_RES(res); - } - } else { - // update object index header page - SPIFFS_DBG("truncate: update object index header page with indices and size\n"); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - objix_pix, fs->work, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } - } else { - // update both current object index page and object index header page - spiffs_page_ix new_objix_pix; - - res = spiffs_page_index_check(fs, fd, objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res); + } + fd->size = cur_size; - // move and update object index page - res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix_hdr, fd->obj_id, 0, objix_pix, &new_objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - SPIFFS_DBG("truncate: store modified objix page, %04x:%04x\n", new_objix_pix, cur_objix_spix); - fd->cursor_objix_pix = new_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = cur_size; - // update object index header page with new size - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } - fd->size = cur_size; - - return res; -} // spiffs_object_truncate -#endif // !SPIFFS_READ_ONLY - -s32_t spiffs_object_read( - spiffs_fd *fd, - u32_t offset, - u32_t len, - u8_t *dst) { - s32_t res = SPIFFS_OK; - spiffs *fs = fd->fs; - spiffs_page_ix objix_pix; - spiffs_page_ix data_pix; - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - u32_t cur_offset = offset; - spiffs_span_ix cur_objix_spix; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - - while (cur_offset < offset + len) { - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (prev_objix_spix != cur_objix_spix) { - // load current object index (header) page - if (cur_objix_spix == 0) { - objix_pix = fd->objix_hdr_pix; - } else { - SPIFFS_DBG("read: find objix %04x:%04x\n", fd->obj_id, cur_objix_spix); - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); + return res; +} // spiffs_object_truncate +#endif // !SPIFFS_READ_ONLY + +s32_t spiffs_object_read(spiffs_fd *fd, u32_t offset, u32_t len, u8_t *dst) +{ + s32_t res = SPIFFS_OK; + spiffs *fs = fd->fs; + spiffs_page_ix objix_pix; + spiffs_page_ix data_pix; + spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); + u32_t cur_offset = offset; + spiffs_span_ix cur_objix_spix; + spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; + spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; + spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; + + while (cur_offset < offset + len) + { + cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); + if (prev_objix_spix != cur_objix_spix) + { + // load current object index (header) page + if (cur_objix_spix == 0) + { + objix_pix = fd->objix_hdr_pix; + } + else + { + SPIFFS_DBG("read: find objix %04x:%04x\n", fd->obj_id, cur_objix_spix); + res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, + &objix_pix); + SPIFFS_CHECK_RES(res); + } + SPIFFS_DBG("read: load objix page %04x:%04x for data spix:%04x\n", objix_pix, cur_objix_spix, data_spix); + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); + SPIFFS_CHECK_RES(res); + SPIFFS_VALIDATE_OBJIX(objix->p_hdr, fd->obj_id, cur_objix_spix); + + fd->offset = cur_offset; + fd->cursor_objix_pix = objix_pix; + fd->cursor_objix_spix = cur_objix_spix; + + prev_objix_spix = cur_objix_spix; + } + + if (cur_objix_spix == 0) + { + // get data page from object index header page + data_pix = ((spiffs_page_ix *)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; + } + else + { + // get data page from object index page + data_pix = + ((spiffs_page_ix *)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; + } + + // all remaining data + u32_t len_to_read = offset + len - cur_offset; + // remaining data in page + len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); + // remaining data in file + len_to_read = MIN(len_to_read, fd->size); + SPIFFS_DBG( + "read: offset:%i rd:%i data spix:%04x is data_pix:%04x addr:%08x\n", cur_offset, len_to_read, data_spix, + data_pix, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); + if (len_to_read <= 0) + { + res = SPIFFS_ERR_END_OF_OBJECT; + break; + } + res = spiffs_page_data_check(fs, fd, data_pix, data_spix); SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("read: load objix page %04x:%04x for data spix:%04x\n", objix_pix, cur_objix_spix, data_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, fd->obj_id, cur_objix_spix); - - fd->offset = cur_offset; - fd->cursor_objix_pix = objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - prev_objix_spix = cur_objix_spix; - } - - if (cur_objix_spix == 0) { - // get data page from object index header page - data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } - - // all remaining data - u32_t len_to_read = offset + len - cur_offset; - // remaining data in page - len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); - // remaining data in file - len_to_read = MIN(len_to_read, fd->size); - SPIFFS_DBG("read: offset:%i rd:%i data spix:%04x is data_pix:%04x addr:%08x\n", cur_offset, len_to_read, data_spix, data_pix, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); - if (len_to_read <= 0) { - res = SPIFFS_ERR_END_OF_OBJECT; - break; - } - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - SPIFFS_CHECK_RES(res); - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)), - len_to_read, - dst); - SPIFFS_CHECK_RES(res); - dst += len_to_read; - cur_offset += len_to_read; - fd->offset = cur_offset; - data_spix++; - } + res = _spiffs_rd( + fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, fd->file_nbr, + SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)), + len_to_read, dst); + SPIFFS_CHECK_RES(res); + dst += len_to_read; + cur_offset += len_to_read; + fd->offset = cur_offset; + data_spix++; + } - return res; + return res; } #if !SPIFFS_READ_ONLY -typedef struct { - spiffs_obj_id min_obj_id; - spiffs_obj_id max_obj_id; - u32_t compaction; - const u8_t *conflicting_name; +typedef struct +{ + spiffs_obj_id min_obj_id; + spiffs_obj_id max_obj_id; + u32_t compaction; + const u8_t *conflicting_name; } spiffs_free_obj_id_state; static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p) { - if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) { - spiffs_obj_id min_obj_id = *((spiffs_obj_id*)user_var_p); - const u8_t *conflicting_name = (const u8_t*)user_const_p; - - // if conflicting name parameter is given, also check if this name is found in object index hdrs - if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - int res; - spiffs_page_object_ix_header objix_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_CHECK_RES(res); - if (objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { - return SPIFFS_ERR_CONFLICTING_NAME; + const void *user_const_p, void *user_var_p) +{ + if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) + { + spiffs_obj_id min_obj_id = *((spiffs_obj_id *)user_var_p); + const u8_t *conflicting_name = (const u8_t *)user_const_p; + + // if conflicting name parameter is given, also check if this name is + // found in object index hdrs + if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) + { + spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); + int res; + spiffs_page_object_ix_header objix_hdr; + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, SPIFFS_PAGE_TO_PADDR(fs, pix), + sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); + SPIFFS_CHECK_RES(res); + if (objix_hdr.p_hdr.span_ix == 0 && + (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == + (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) + { + if (strcmp((const char *)user_const_p, (char *)objix_hdr.name) == 0) + { + return SPIFFS_ERR_CONFLICTING_NAME; + } + } } - } - } - id &= ~SPIFFS_OBJ_ID_IX_FLAG; - u32_t bit_ix = (id-min_obj_id) & 7; - int byte_ix = (id-min_obj_id) >> 3; - if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - fs->work[byte_ix] |= (1<> 3; + if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) + { + fs->work[byte_ix] |= (1 << bit_ix); + } } - } - return SPIFFS_VIS_COUNTINUE; + return SPIFFS_VIS_COUNTINUE; } static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p) { - (void)user_var_p; - if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED && (id & SPIFFS_OBJ_ID_IX_FLAG)) { - s32_t res; - const spiffs_free_obj_id_state *state = (const spiffs_free_obj_id_state*)user_const_p; - spiffs_page_object_ix_header objix_hdr; - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, ix_entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&objix_hdr); - if (res == SPIFFS_OK && objix_hdr.p_hdr.span_ix == 0 && - ((objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) == - (SPIFFS_PH_FLAG_DELET))) { - // ok object look up entry - if (state->conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) { - return SPIFFS_ERR_CONFLICTING_NAME; - } - - id &= ~SPIFFS_OBJ_ID_IX_FLAG; - if (id >= state->min_obj_id && id <= state->max_obj_id) { - u8_t *map = (u8_t *)fs->work; - int ix = (id - state->min_obj_id) / state->compaction; - //SPIFFS_DBG("free_obj_id: add ix %i for id %04x min:%04x max%04x comp:%i\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); - map[ix]++; - } - } - } - return SPIFFS_VIS_COUNTINUE; -} - -// Scans thru all object lookup for object index header pages. If total possible number of -// object ids cannot fit into a work buffer, these are grouped. When a group containing free -// object ids is found, the object lu is again scanned for object ids within group and bitmasked. -// Finally, the bitmask is searched for a free id -s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, const u8_t *conflicting_name) { - s32_t res = SPIFFS_OK; - u32_t max_objects = (fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) / 2; - spiffs_free_obj_id_state state; - spiffs_obj_id free_obj_id = SPIFFS_OBJ_ID_FREE; - state.min_obj_id = 1; - state.max_obj_id = max_objects + 1; - if (state.max_obj_id & SPIFFS_OBJ_ID_IX_FLAG) { - state.max_obj_id = ((spiffs_obj_id)-1) & ~SPIFFS_OBJ_ID_IX_FLAG; - } - state.compaction = 0; - state.conflicting_name = conflicting_name; - while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) { - if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8) { - // possible to represent in bitmap - u32_t i, j; - SPIFFS_DBG("free_obj_id: BITM min:%04x max:%04x\n", state.min_obj_id, state.max_obj_id); - - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, - conflicting_name, &state.min_obj_id, 0, 0); - if (res == SPIFFS_VIS_END) res = SPIFFS_OK; - SPIFFS_CHECK_RES(res); - // traverse bitmask until found free obj_id - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs); i++) { - u8_t mask = fs->work[i]; - if (mask == 0xff) { - continue; - } - for (j = 0; j < 8; j++) { - if ((mask & (1<work; - u8_t min_count = 0xff; - - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(u8_t); i++) { - if (map[i] < min_count) { - min_count = map[i]; - min_i = i; - if (min_count == 0) { - break; + const void *user_const_p, void *user_var_p) +{ + (void)user_var_p; + if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED && (id & SPIFFS_OBJ_ID_IX_FLAG)) + { + s32_t res; + const spiffs_free_obj_id_state *state = (const spiffs_free_obj_id_state *)user_const_p; + spiffs_page_object_ix_header objix_hdr; + + res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, + SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, ix_entry), sizeof(spiffs_page_object_ix_header), + (u8_t *)&objix_hdr); + if (res == SPIFFS_OK && objix_hdr.p_hdr.span_ix == 0 && + ((objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) == + (SPIFFS_PH_FLAG_DELET))) + { + // ok object look up entry + if (state->conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) + { + return SPIFFS_ERR_CONFLICTING_NAME; } - } - } - if (min_count == state.compaction) { - // there are no free objids! - SPIFFS_DBG("free_obj_id: compacted table is full\n"); - return SPIFFS_ERR_FULL; + id &= ~SPIFFS_OBJ_ID_IX_FLAG; + if (id >= state->min_obj_id && id <= state->max_obj_id) + { + u8_t *map = (u8_t *)fs->work; + int ix = (id - state->min_obj_id) / state->compaction; + // SPIFFS_DBG("free_obj_id: add ix %i for id %04x min:%04x + // max%04x comp:%i\n", ix, id, state->min_obj_id, + // state->max_obj_id, state->compaction); + map[ix]++; + } } + } + return SPIFFS_VIS_COUNTINUE; +} - SPIFFS_DBG("free_obj_id: COMP select index:%i min_count:%i min:%04x max:%04x compact:%i\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); - - if (min_count == 0) { - // no id in this range, skip compacting and use directly - *obj_id = min_i * state.compaction + state.min_obj_id; - return SPIFFS_OK; - } else { - SPIFFS_DBG("free_obj_id: COMP SEL chunk:%04x min:%04x -> %04x\n", state.compaction, state.min_obj_id, state.min_obj_id + min_i * state.compaction); - state.min_obj_id += min_i * state.compaction; - state.max_obj_id = state.min_obj_id + state.compaction; - // decrease compaction +// Scans thru all object lookup for object index header pages. If total possible +// number of object ids cannot fit into a work buffer, these are grouped. When a +// group containing free object ids is found, the object lu is again scanned for +// object ids within group and bitmasked. Finally, the bitmask is searched for a +// free id +s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, const u8_t *conflicting_name) +{ + s32_t res = SPIFFS_OK; + u32_t max_objects = (fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) / 2; + spiffs_free_obj_id_state state; + spiffs_obj_id free_obj_id = SPIFFS_OBJ_ID_FREE; + state.min_obj_id = 1; + state.max_obj_id = max_objects + 1; + if (state.max_obj_id & SPIFFS_OBJ_ID_IX_FLAG) + { + state.max_obj_id = ((spiffs_obj_id)-1) & ~SPIFFS_OBJ_ID_IX_FLAG; + } + state.compaction = 0; + state.conflicting_name = conflicting_name; + while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) + { + if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8) + { + // possible to represent in bitmap + u32_t i, j; + SPIFFS_DBG("free_obj_id: BITM min:%04x max:%04x\n", state.min_obj_id, state.max_obj_id); + + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, + conflicting_name, &state.min_obj_id, 0, 0); + if (res == SPIFFS_VIS_END) + res = SPIFFS_OK; + SPIFFS_CHECK_RES(res); + // traverse bitmask until found free obj_id + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs); i++) + { + u8_t mask = fs->work[i]; + if (mask == 0xff) + { + continue; + } + for (j = 0; j < 8; j++) + { + if ((mask & (1 << j)) == 0) + { + *obj_id = (i << 3) + j + state.min_obj_id; + return SPIFFS_OK; + } + } + } + return SPIFFS_ERR_FULL; } - if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8)) { - // no need for compacting, use bitmap - continue; + else + { + // not possible to represent all ids in range in a bitmap, compact + // and count + if (state.compaction != 0) + { + // select element in compacted table, decrease range and + // recompact + u32_t i, min_i = 0; + u8_t *map = (u8_t *)fs->work; + u8_t min_count = 0xff; + + for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t); i++) + { + if (map[i] < min_count) + { + min_count = map[i]; + min_i = i; + if (min_count == 0) + { + break; + } + } + } + + if (min_count == state.compaction) + { + // there are no free objids! + SPIFFS_DBG("free_obj_id: compacted table is full\n"); + return SPIFFS_ERR_FULL; + } + + SPIFFS_DBG( + "free_obj_id: COMP select index:%i min_count:%i min:%04x " + "max:%04x compact:%i\n", + min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); + + if (min_count == 0) + { + // no id in this range, skip compacting and use directly + *obj_id = min_i * state.compaction + state.min_obj_id; + return SPIFFS_OK; + } + else + { + SPIFFS_DBG("free_obj_id: COMP SEL chunk:%04x min:%04x -> %04x\n", state.compaction, + state.min_obj_id, state.min_obj_id + min_i * state.compaction); + state.min_obj_id += min_i * state.compaction; + state.max_obj_id = state.min_obj_id + state.compaction; + // decrease compaction + } + if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8)) + { + // no need for compacting, use bitmap + continue; + } + } + // in a work memory of log_page_size bytes, we may fit in + // log_page_size ids todo what if compaction is > 255 - then we + // cannot fit it in a byte + state.compaction = (state.max_obj_id - state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); + SPIFFS_DBG("free_obj_id: COMP min:%04x max:%04x compact:%i\n", state.min_obj_id, state.max_obj_id, + state.compaction); + + memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); + res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, &state, 0, + 0, 0); + if (res == SPIFFS_VIS_END) + res = SPIFFS_OK; + SPIFFS_CHECK_RES(res); + state.conflicting_name = 0; // searched for conflicting name once, + // no need to do it again } - } - // in a work memory of log_page_size bytes, we may fit in log_page_size ids - // todo what if compaction is > 255 - then we cannot fit it in a byte - state.compaction = (state.max_obj_id-state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); - SPIFFS_DBG("free_obj_id: COMP min:%04x max:%04x compact:%i\n", state.min_obj_id, state.max_obj_id, state.compaction); - - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, &state, 0, 0, 0); - if (res == SPIFFS_VIS_END) res = SPIFFS_OK; - SPIFFS_CHECK_RES(res); - state.conflicting_name = 0; // searched for conflicting name once, no need to do it again } - } - return res; + return res; } -#endif // !SPIFFS_READ_ONLY - -s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd) { - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0) { - cur_fd->file_nbr = i+1; - *fd = cur_fd; - return SPIFFS_OK; - } - } - return SPIFFS_ERR_OUT_OF_FILE_DESCS; +#endif // !SPIFFS_READ_ONLY + +s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd) +{ + u32_t i; + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + for (i = 0; i < fs->fd_count; i++) + { + spiffs_fd *cur_fd = &fds[i]; + if (cur_fd->file_nbr == 0) + { + cur_fd->file_nbr = i + 1; + *fd = cur_fd; + return SPIFFS_OK; + } + } + return SPIFFS_ERR_OUT_OF_FILE_DESCS; } -s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) { - if (f <= 0 || f > (s16_t)fs->fd_count) { - return SPIFFS_ERR_BAD_DESCRIPTOR; - } - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - spiffs_fd *fd = &fds[f-1]; - if (fd->file_nbr == 0) { - return SPIFFS_ERR_FILE_CLOSED; - } - fd->file_nbr = 0; - return SPIFFS_OK; +s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) +{ + if (f <= 0 || f > (s16_t)fs->fd_count) + { + return SPIFFS_ERR_BAD_DESCRIPTOR; + } + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + spiffs_fd *fd = &fds[f - 1]; + if (fd->file_nbr == 0) + { + return SPIFFS_ERR_FILE_CLOSED; + } + fd->file_nbr = 0; + return SPIFFS_OK; } -s32_t spiffs_fd_get(spiffs *fs, spiffs_file f, spiffs_fd **fd) { - if (f <= 0 || f > (s16_t)fs->fd_count) { - return SPIFFS_ERR_BAD_DESCRIPTOR; - } - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - *fd = &fds[f-1]; - if ((*fd)->file_nbr == 0) { - return SPIFFS_ERR_FILE_CLOSED; - } - return SPIFFS_OK; +s32_t spiffs_fd_get(spiffs *fs, spiffs_file f, spiffs_fd **fd) +{ + if (f <= 0 || f > (s16_t)fs->fd_count) + { + return SPIFFS_ERR_BAD_DESCRIPTOR; + } + spiffs_fd *fds = (spiffs_fd *)fs->fd_space; + *fd = &fds[f - 1]; + if ((*fd)->file_nbr == 0) + { + return SPIFFS_ERR_FILE_CLOSED; + } + return SPIFFS_OK; } diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/main.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/main.c index 28e9a92..175ddbc 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/main.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/main.c @@ -1,7 +1,9 @@ -#include "testrunner.h" #include -int main(int argc, char **args) { - run_tests(argc, args); - exit(EXIT_SUCCESS); +#include "testrunner.h" + +int main(int argc, char **args) +{ + run_tests(argc, args); + exit(EXIT_SUCCESS); } diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_bugreports.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_bugreports.c index b577e6f..f5e4351 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_bugreports.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_bugreports.c @@ -5,156 +5,157 @@ * Author: petera */ - - -#include "testrunner.h" -#include "test_spiffs.h" -#include "spiffs_nucleus.h" -#include "spiffs.h" -#include -#include -#include #include +#include +#include +#include #include +#include "spiffs.h" +#include "spiffs_nucleus.h" +#include "test_spiffs.h" +#include "testrunner.h" SUITE(bug_tests) -void setup() { - _setup_test_only(); +void setup() { _setup_test_only(); } +void teardown() { _teardown(); } + +TEST(nodemcu_full_fs_1) +{ + fs_reset_specific(0, 4096 * 20, 4096, 4096, 256); + + int res; + spiffs_file fd; + + printf(" fill up system by writing one byte a lot\n"); + fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(fd > 0); + int i; + spiffs_stat s; + res = SPIFFS_OK; + for (i = 0; i < 100 * 1000; i++) + { + u8_t buf = 'x'; + res = SPIFFS_write(FS, fd, &buf, 1); + } + + int errno = SPIFFS_errno(FS); + int res2 = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res2 == SPIFFS_OK); + printf(" >>> file %s size: %i\n", s.name, s.size); + + TEST_CHECK(errno == SPIFFS_ERR_FULL); + SPIFFS_close(FS, fd); + + printf(" remove big file\n"); + res = SPIFFS_remove(FS, "test1.txt"); + + printf("res:%i errno:%i\n", res, SPIFFS_errno(FS)); + + TEST_CHECK(res == SPIFFS_OK); + res2 = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res2 == -1); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res2 = SPIFFS_stat(FS, "test1.txt", &s); + TEST_CHECK(res2 == -1); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); + + printf(" create small file\n"); + fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(fd > 0); + res = SPIFFS_OK; + for (i = 0; res >= 0 && i < 1000; i++) + { + u8_t buf = 'x'; + res = SPIFFS_write(FS, fd, &buf, 1); + } + TEST_CHECK(res >= SPIFFS_OK); + + res2 = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res2 == SPIFFS_OK); + printf(" >>> file %s size: %i\n", s.name, s.size); + + TEST_CHECK(s.size == 1000); + SPIFFS_close(FS, fd); + + return TEST_RES_OK; } -void teardown() { - _teardown(); +TEST_END(nodemcu_full_fs_1) + +TEST(nodemcu_full_fs_2) +{ + fs_reset_specific(0, 4096 * 22, 4096, 4096, 256); + + int res; + spiffs_file fd; + + printf(" fill up system by writing one byte a lot\n"); + fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(fd > 0); + int i; + spiffs_stat s; + res = SPIFFS_OK; + for (i = 0; i < 100 * 1000; i++) + { + u8_t buf = 'x'; + res = SPIFFS_write(FS, fd, &buf, 1); + } + + int errno = SPIFFS_errno(FS); + int res2 = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res2 == SPIFFS_OK); + printf(" >>> file %s size: %i\n", s.name, s.size); + + TEST_CHECK(errno == SPIFFS_ERR_FULL); + SPIFFS_close(FS, fd); + + res2 = SPIFFS_stat(FS, "test1.txt", &s); + TEST_CHECK(res2 == SPIFFS_OK); + + SPIFFS_clearerr(FS); + printf(" create small file\n"); + fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK); + TEST_CHECK(fd > 0); + + for (i = 0; i < 1000; i++) + { + u8_t buf = 'x'; + res = SPIFFS_write(FS, fd, &buf, 1); + } + + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FULL); + res2 = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res2 == SPIFFS_OK); + printf(" >>> file %s size: %i\n", s.name, s.size); + TEST_CHECK(s.size == 0); + SPIFFS_clearerr(FS); + + printf(" remove files\n"); + res = SPIFFS_remove(FS, "test1.txt"); + TEST_CHECK(res == SPIFFS_OK); + res = SPIFFS_remove(FS, "test2.txt"); + TEST_CHECK(res == SPIFFS_OK); + + printf(" create medium file\n"); + fd = SPIFFS_open(FS, "test3.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK); + TEST_CHECK(fd > 0); + + for (i = 0; i < 20 * 1000; i++) + { + u8_t buf = 'x'; + res = SPIFFS_write(FS, fd, &buf, 1); + } + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK); + + res2 = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res2 == SPIFFS_OK); + printf(" >>> file %s size: %i\n", s.name, s.size); + TEST_CHECK(s.size == 20 * 1000); + + return TEST_RES_OK; } - -TEST(nodemcu_full_fs_1) { - fs_reset_specific(0, 4096*20, 4096, 4096, 256); - - int res; - spiffs_file fd; - - printf(" fill up system by writing one byte a lot\n"); - fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(fd > 0); - int i; - spiffs_stat s; - res = SPIFFS_OK; - for (i = 0; i < 100*1000; i++) { - u8_t buf = 'x'; - res = SPIFFS_write(FS, fd, &buf, 1); - } - - int errno = SPIFFS_errno(FS); - int res2 = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res2 == SPIFFS_OK); - printf(" >>> file %s size: %i\n", s.name, s.size); - - TEST_CHECK(errno == SPIFFS_ERR_FULL); - SPIFFS_close(FS, fd); - - printf(" remove big file\n"); - res = SPIFFS_remove(FS, "test1.txt"); - - printf("res:%i errno:%i\n",res, SPIFFS_errno(FS)); - - TEST_CHECK(res == SPIFFS_OK); - res2 = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res2 == -1); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res2 = SPIFFS_stat(FS, "test1.txt", &s); - TEST_CHECK(res2 == -1); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); - - printf(" create small file\n"); - fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(fd > 0); - res = SPIFFS_OK; - for (i = 0; res >= 0 && i < 1000; i++) { - u8_t buf = 'x'; - res = SPIFFS_write(FS, fd, &buf, 1); - } - TEST_CHECK(res >= SPIFFS_OK); - - res2 = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res2 == SPIFFS_OK); - printf(" >>> file %s size: %i\n", s.name, s.size); - - TEST_CHECK(s.size == 1000); - SPIFFS_close(FS, fd); - - return TEST_RES_OK; - -} TEST_END(nodemcu_full_fs_1) - -TEST(nodemcu_full_fs_2) { - fs_reset_specific(0, 4096*22, 4096, 4096, 256); - - int res; - spiffs_file fd; - - printf(" fill up system by writing one byte a lot\n"); - fd = SPIFFS_open(FS, "test1.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(fd > 0); - int i; - spiffs_stat s; - res = SPIFFS_OK; - for (i = 0; i < 100*1000; i++) { - u8_t buf = 'x'; - res = SPIFFS_write(FS, fd, &buf, 1); - } - - int errno = SPIFFS_errno(FS); - int res2 = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res2 == SPIFFS_OK); - printf(" >>> file %s size: %i\n", s.name, s.size); - - TEST_CHECK(errno == SPIFFS_ERR_FULL); - SPIFFS_close(FS, fd); - - res2 = SPIFFS_stat(FS, "test1.txt", &s); - TEST_CHECK(res2 == SPIFFS_OK); - - SPIFFS_clearerr(FS); - printf(" create small file\n"); - fd = SPIFFS_open(FS, "test2.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK); - TEST_CHECK(fd > 0); - - for (i = 0; i < 1000; i++) { - u8_t buf = 'x'; - res = SPIFFS_write(FS, fd, &buf, 1); - } - - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FULL); - res2 = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res2 == SPIFFS_OK); - printf(" >>> file %s size: %i\n", s.name, s.size); - TEST_CHECK(s.size == 0); - SPIFFS_clearerr(FS); - - printf(" remove files\n"); - res = SPIFFS_remove(FS, "test1.txt"); - TEST_CHECK(res == SPIFFS_OK); - res = SPIFFS_remove(FS, "test2.txt"); - TEST_CHECK(res == SPIFFS_OK); - - printf(" create medium file\n"); - fd = SPIFFS_open(FS, "test3.txt", SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK); - TEST_CHECK(fd > 0); - - for (i = 0; i < 20*1000; i++) { - u8_t buf = 'x'; - res = SPIFFS_write(FS, fd, &buf, 1); - } - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_OK); - - res2 = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res2 == SPIFFS_OK); - printf(" >>> file %s size: %i\n", s.name, s.size); - TEST_CHECK(s.size == 20*1000); - - return TEST_RES_OK; - -} TEST_END(nodemcu_full_fs_2) +TEST_END(nodemcu_full_fs_2) SUITE_END(bug_tests) diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_check.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_check.c index ab014dc..0abc8c9 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_check.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_check.c @@ -5,414 +5,417 @@ * Author: petera */ - -#include "testrunner.h" -#include "test_spiffs.h" -#include "spiffs_nucleus.h" -#include "spiffs.h" -#include -#include -#include #include +#include +#include +#include #include +#include "spiffs.h" +#include "spiffs_nucleus.h" +#include "test_spiffs.h" +#include "testrunner.h" SUITE(check_tests) -void setup() { - _setup(); -} -void teardown() { - _teardown(); +void setup() { _setup(); } +void teardown() { _teardown(); } + +TEST(evil_write) +{ + fs_set_validate_flashing(0); + printf("writing corruption to block 1 data range (leaving lu intact)\n"); + u32_t data_range = SPIFFS_CFG_LOG_BLOCK_SZ(FS) - SPIFFS_CFG_LOG_PAGE_SZ(FS) * (SPIFFS_OBJ_LOOKUP_PAGES(FS)); + u8_t *corruption = malloc(data_range); + memrand(corruption, data_range); + u32_t addr = 0 * SPIFFS_CFG_LOG_PAGE_SZ(FS) * SPIFFS_OBJ_LOOKUP_PAGES(FS); + area_write(addr, corruption, data_range); + free(corruption); + + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + + printf("CHECK1-----------------\n"); + SPIFFS_check(FS); + printf("CHECK2-----------------\n"); + SPIFFS_check(FS); + printf("CHECK3-----------------\n"); + SPIFFS_check(FS); + + res = test_create_and_write_file("file2", size, size); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; } - -TEST(evil_write) { - fs_set_validate_flashing(0); - printf("writing corruption to block 1 data range (leaving lu intact)\n"); - u32_t data_range = SPIFFS_CFG_LOG_BLOCK_SZ(FS) - - SPIFFS_CFG_LOG_PAGE_SZ(FS) * (SPIFFS_OBJ_LOOKUP_PAGES(FS)); - u8_t *corruption = malloc(data_range); - memrand(corruption, data_range); - u32_t addr = 0 * SPIFFS_CFG_LOG_PAGE_SZ(FS) * SPIFFS_OBJ_LOOKUP_PAGES(FS); - area_write(addr, corruption, data_range); - free(corruption); - - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - - printf("CHECK1-----------------\n"); - SPIFFS_check(FS); - printf("CHECK2-----------------\n"); - SPIFFS_check(FS); - printf("CHECK3-----------------\n"); - SPIFFS_check(FS); - - res = test_create_and_write_file("file2", size, size); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; -} TEST_END(evil_write) - - -TEST(lu_check1) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify lu entry data page index 1 - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix); - TEST_CHECK(res >= 0); - - // reset lu entry to being erased, but keep page data - spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED; - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); - u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry*sizeof(spiffs_obj_id); - - area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id)); +TEST_END(evil_write) + +TEST(lu_check1) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify lu entry data page index 1 + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix); + TEST_CHECK(res >= 0); + + // reset lu entry to being erased, but keep page data + spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED; + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); + u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); + + area_write(addr, (u8_t *)&obj_id, sizeof(spiffs_obj_id)); #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - return TEST_RES_OK; -} TEST_END(lu_check1) - - -TEST(page_cons1) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify object index, find object index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); - - // set object index entry 2 to a bad page - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 0 * sizeof(spiffs_page_ix); - spiffs_page_ix bad_pix_ref = 0x55; - area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); - area_write(addr+2, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); - - // delete all cache + SPIFFS_check(FS); + + return TEST_RES_OK; +} +TEST_END(lu_check1) + +TEST(page_cons1) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify object index, find object index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + // set object index entry 2 to a bad page + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 0 * sizeof(spiffs_page_ix); + spiffs_page_ix bad_pix_ref = 0x55; + area_write(addr, (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); + area_write(addr + 2, (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); + + // delete all cache #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; -} TEST_END(page_cons1) - - -TEST(page_cons2) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); + SPIFFS_check(FS); - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - // modify object index, find object index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); - - // find data page span index 0 - spiffs_page_ix dpix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &dpix); - TEST_CHECK(res >= 0); - - // set object index entry 1+2 to a data page 0 - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix); - spiffs_page_ix bad_pix_ref = dpix; - area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); - area_write(addr+sizeof(spiffs_page_ix), (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); - - // delete all cache + return TEST_RES_OK; +} +TEST_END(page_cons1) + +TEST(page_cons2) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify object index, find object index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + // find data page span index 0 + spiffs_page_ix dpix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &dpix); + TEST_CHECK(res >= 0); + + // set object index entry 1+2 to a data page 0 + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix); + spiffs_page_ix bad_pix_ref = dpix; + area_write(addr, (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); + area_write(addr + sizeof(spiffs_page_ix), (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); + + // delete all cache #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); + SPIFFS_check(FS); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - return TEST_RES_OK; -} TEST_END(page_cons2) - - - -TEST(page_cons3) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify object index, find object index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); - - // set object index entry 1+2 lookup page - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix); - spiffs_page_ix bad_pix_ref = SPIFFS_PAGES_PER_BLOCK(FS) * (*FS.block_count - 2); - area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); - area_write(addr+sizeof(spiffs_page_ix), (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); - - // delete all cache + return TEST_RES_OK; +} +TEST_END(page_cons2) + +TEST(page_cons3) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify object index, find object index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + // set object index entry 1+2 lookup page + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 1 * sizeof(spiffs_page_ix); + spiffs_page_ix bad_pix_ref = SPIFFS_PAGES_PER_BLOCK(FS) * (*FS.block_count - 2); + area_write(addr, (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); + area_write(addr + sizeof(spiffs_page_ix), (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); + + // delete all cache #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - res = read_and_verify("file"); - TEST_CHECK(res >= 0); + SPIFFS_check(FS); - return TEST_RES_OK; -} TEST_END(page_cons3) + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - -TEST(page_cons_final) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify page header, make unfinalized - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix); - TEST_CHECK(res >= 0); - - // set page span ix 1 as unfinalized - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags); - u8_t flags; - area_read(addr, (u8_t*)&flags, 1); - flags |= SPIFFS_PH_FLAG_FINAL; - area_write(addr, (u8_t*)&flags, 1); - - // delete all cache + return TEST_RES_OK; +} +TEST_END(page_cons3) + +TEST(page_cons_final) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify page header, make unfinalized + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 1, 0, &pix); + TEST_CHECK(res >= 0); + + // set page span ix 1 as unfinalized + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags); + u8_t flags; + area_read(addr, (u8_t *)&flags, 1); + flags |= SPIFFS_PH_FLAG_FINAL; + area_write(addr, (u8_t *)&flags, 1); + + // delete all cache #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; -} TEST_END(page_cons_final) - + SPIFFS_check(FS); -TEST(index_cons1) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS); - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify lu entry data page index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); - - printf(" deleting lu entry pix %04x\n", pix); - // reset lu entry to being erased, but keep page data - spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED; - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); - u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); - - area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id)); + return TEST_RES_OK; +} +TEST_END(page_cons_final) + +TEST(index_cons1) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_PAGES_PER_BLOCK(FS); + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify lu entry data page index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + printf(" deleting lu entry pix %04x\n", pix); + // reset lu entry to being erased, but keep page data + spiffs_obj_id obj_id = SPIFFS_OBJ_ID_DELETED; + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); + u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); + + area_write(addr, (u8_t *)&obj_id, sizeof(spiffs_obj_id)); #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; -} TEST_END(index_cons1) - - -TEST(index_cons2) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS); - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); + SPIFFS_check(FS); - // modify lu entry data page index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - printf(" writing lu entry for index page, ix %04x, as data page\n", pix); - spiffs_obj_id obj_id = 0x1234; - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); - u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); - - area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id)); + return TEST_RES_OK; +} +TEST_END(index_cons1) + +TEST(index_cons2) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_PAGES_PER_BLOCK(FS); + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify lu entry data page index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + printf(" writing lu entry for index page, ix %04x, as data page\n", pix); + spiffs_obj_id obj_id = 0x1234; + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); + u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); + + area_write(addr, (u8_t *)&obj_id, sizeof(spiffs_obj_id)); #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; -} TEST_END(index_cons2) - + SPIFFS_check(FS); -TEST(index_cons3) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS); - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify lu entry data page index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); - - printf(" setting lu entry pix %04x to another index page\n", pix); - // reset lu entry to being erased, but keep page data - spiffs_obj_id obj_id = 1234 | SPIFFS_OBJ_ID_IX_FLAG; - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); - u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); - - area_write(addr, (u8_t*)&obj_id, sizeof(spiffs_obj_id)); + return TEST_RES_OK; +} +TEST_END(index_cons2) + +TEST(index_cons3) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_PAGES_PER_BLOCK(FS); + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify lu entry data page index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + printf(" setting lu entry pix %04x to another index page\n", pix); + // reset lu entry to being erased, but keep page data + spiffs_obj_id obj_id = 1234 | SPIFFS_OBJ_ID_IX_FLAG; + spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(FS, pix); + int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(FS, pix); + u32_t addr = SPIFFS_BLOCK_TO_PADDR(FS, bix) + entry * sizeof(spiffs_obj_id); + + area_write(addr, (u8_t *)&obj_id, sizeof(spiffs_obj_id)); #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); + SPIFFS_check(FS); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - return TEST_RES_OK; -} TEST_END(index_cons3) - -TEST(index_cons4) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*SPIFFS_PAGES_PER_BLOCK(FS); - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - // modify lu entry data page index header, flags - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); - - printf(" cue objix hdr deletion in page %04x\n", pix); - // set flags as deleting ix header - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags); - u8_t flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE); - - area_write(addr, (u8_t*)&flags, 1); + return TEST_RES_OK; +} +TEST_END(index_cons3) + +TEST(index_cons4) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_PAGES_PER_BLOCK(FS); + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + // modify lu entry data page index header, flags + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); + + printf(" cue objix hdr deletion in page %04x\n", pix); + // set flags as deleting ix header + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + offsetof(spiffs_page_header, flags); + u8_t flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE); + + area_write(addr, (u8_t *)&flags, 1); #if SPIFFS_CACHE - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - SPIFFS_check(FS); - - return TEST_RES_OK; -} TEST_END(index_cons4) - + SPIFFS_check(FS); + return TEST_RES_OK; +} +TEST_END(index_cons4) SUITE_END(check_tests) diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_dev.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_dev.c index 70a2a94..82d7ad6 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_dev.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_dev.c @@ -5,116 +5,107 @@ * Author: petera */ - -#include "testrunner.h" -#include "test_spiffs.h" -#include "spiffs_nucleus.h" -#include "spiffs.h" -#include -#include -#include #include +#include +#include +#include #include +#include "spiffs.h" +#include "spiffs_nucleus.h" +#include "test_spiffs.h" +#include "testrunner.h" SUITE(dev_tests) -void setup() { - _setup(); -} -void teardown() { - _teardown(); -} - -TEST(interrupted_write) { - char *name = "interrupt"; - char *name2 = "interrupt2"; - int res; - spiffs_file fd; - - const u32_t sz = SPIFFS_CFG_LOG_PAGE_SZ(FS)*8; - u8_t *buf = malloc(sz); - memrand(buf, sz); - - printf(" create reference file\n"); - fd = SPIFFS_open(FS, name, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(fd > 0); - clear_flash_ops_log(); - res = SPIFFS_write(FS, fd, buf, sz); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - u32_t written = get_flash_ops_log_write_bytes(); - printf(" written bytes: %i\n", written); +void setup() { _setup(); } +void teardown() { _teardown(); } + +TEST(interrupted_write) +{ + char *name = "interrupt"; + char *name2 = "interrupt2"; + int res; + spiffs_file fd; + + const u32_t sz = SPIFFS_CFG_LOG_PAGE_SZ(FS) * 8; + u8_t *buf = malloc(sz); + memrand(buf, sz); + + printf(" create reference file\n"); + fd = SPIFFS_open(FS, name, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(fd > 0); + clear_flash_ops_log(); + res = SPIFFS_write(FS, fd, buf, sz); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + u32_t written = get_flash_ops_log_write_bytes(); + printf(" written bytes: %i\n", written); - printf(" create error file\n"); - fd = SPIFFS_open(FS, name2, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); - TEST_CHECK(fd > 0); - clear_flash_ops_log(); - invoke_error_after_write_bytes(written/2, 0); - res = SPIFFS_write(FS, fd, buf, sz); - SPIFFS_close(FS, fd); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_TEST); + printf(" create error file\n"); + fd = SPIFFS_open(FS, name2, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(fd > 0); + clear_flash_ops_log(); + invoke_error_after_write_bytes(written / 2, 0); + res = SPIFFS_write(FS, fd, buf, sz); + SPIFFS_close(FS, fd); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_TEST); - clear_flash_ops_log(); + clear_flash_ops_log(); #if SPIFFS_CACHE - // delete all cache - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + // delete all cache + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif + printf(" read error file\n"); + fd = SPIFFS_open(FS, name2, SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); - printf(" read error file\n"); - fd = SPIFFS_open(FS, name2, SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - printf(" file size: %i\n", s.size); - - if (s.size > 0) { - u8_t *buf2 = malloc(s.size); - res = SPIFFS_read(FS, fd, buf2, s.size); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); TEST_CHECK(res >= 0); - - u32_t ix = 0; - for (ix = 0; ix < s.size; ix += 16) { - int i; - printf(" "); - for (i = 0; i < 16; i++) { - printf("%02x", buf[ix+i]); - } - printf(" "); - for (i = 0; i < 16; i++) { - printf("%02x", buf2[ix+i]); - } - printf("\n"); + printf(" file size: %i\n", s.size); + + if (s.size > 0) + { + u8_t *buf2 = malloc(s.size); + res = SPIFFS_read(FS, fd, buf2, s.size); + TEST_CHECK(res >= 0); + + u32_t ix = 0; + for (ix = 0; ix < s.size; ix += 16) + { + int i; + printf(" "); + for (i = 0; i < 16; i++) { printf("%02x", buf[ix + i]); } + printf(" "); + for (i = 0; i < 16; i++) { printf("%02x", buf2[ix + i]); } + printf("\n"); + } + free(buf2); } - free(buf2); - } - SPIFFS_close(FS, fd); - - - printf(" FS check\n"); - SPIFFS_check(FS); + SPIFFS_close(FS, fd); - printf(" read error file again\n"); - fd = SPIFFS_open(FS, name2, SPIFFS_APPEND | SPIFFS_RDWR, 0); - TEST_CHECK(fd > 0); - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - printf(" file size: %i\n", s.size); - printf(" write file\n"); - res = SPIFFS_write(FS, fd, buf, sz); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); + printf(" FS check\n"); + SPIFFS_check(FS); - free(buf); + printf(" read error file again\n"); + fd = SPIFFS_open(FS, name2, SPIFFS_APPEND | SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + printf(" file size: %i\n", s.size); + printf(" write file\n"); + res = SPIFFS_write(FS, fd, buf, sz); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); - return TEST_RES_OK; + free(buf); -} TEST_END(interrupted_write) + return TEST_RES_OK; +} +TEST_END(interrupted_write) SUITE_END(dev_tests) diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_hydrogen.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_hydrogen.c index fdba160..b536f68 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_hydrogen.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_hydrogen.c @@ -5,969 +5,917 @@ * Author: petera */ - -#include "testrunner.h" -#include "test_spiffs.h" -#include "spiffs_nucleus.h" -#include "spiffs.h" -#include -#include -#include #include +#include +#include +#include #include +#include "spiffs.h" +#include "spiffs_nucleus.h" +#include "test_spiffs.h" +#include "testrunner.h" + SUITE(hydrogen_tests) -void setup() { - _setup(); -} -void teardown() { - _teardown(); -} +void setup() { _setup(); } +void teardown() { _teardown(); } TEST(info) { - u32_t used, total; - int res = SPIFFS_info(FS, &total, &used); - TEST_CHECK(res == SPIFFS_OK); - TEST_CHECK(used == 0); - TEST_CHECK(total < __fs.cfg.phys_size); - return TEST_RES_OK; + u32_t used, total; + int res = SPIFFS_info(FS, &total, &used); + TEST_CHECK(res == SPIFFS_OK); + TEST_CHECK(used == 0); + TEST_CHECK(total < __fs.cfg.phys_size); + return TEST_RES_OK; } TEST_END(info) - TEST(missing_file) { - spiffs_file fd = SPIFFS_open(FS, "this_wont_exist", SPIFFS_RDONLY, 0); - TEST_CHECK(fd < 0); - return TEST_RES_OK; + spiffs_file fd = SPIFFS_open(FS, "this_wont_exist", SPIFFS_RDONLY, 0); + TEST_CHECK(fd < 0); + return TEST_RES_OK; } TEST_END(missing_file) - TEST(bad_fd) { - int res; - spiffs_stat s; - spiffs_file fd = SPIFFS_open(FS, "this_wont_exist", SPIFFS_RDONLY, 0); - TEST_CHECK(fd < 0); - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); - res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); - res = SPIFFS_read(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); - res = SPIFFS_write(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); - return TEST_RES_OK; + int res; + spiffs_stat s; + spiffs_file fd = SPIFFS_open(FS, "this_wont_exist", SPIFFS_RDONLY, 0); + TEST_CHECK(fd < 0); + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); + res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); + res = SPIFFS_read(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); + res = SPIFFS_write(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_BAD_DESCRIPTOR); + return TEST_RES_OK; } TEST_END(bad_fd) - TEST(closed_fd) { - int res; - spiffs_stat s; - res = test_create_file("file"); - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd >= 0); - SPIFFS_close(FS, fd); - - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_read(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_write(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - return TEST_RES_OK; + int res; + spiffs_stat s; + res = test_create_file("file"); + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd >= 0); + SPIFFS_close(FS, fd); + + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_read(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_write(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + return TEST_RES_OK; } TEST_END(closed_fd) - TEST(deleted_same_fd) { - int res; - spiffs_stat s; - spiffs_file fd; - res = test_create_file("remove"); - fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res >= 0); - - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_read(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_write(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - - return TEST_RES_OK; + int res; + spiffs_stat s; + spiffs_file fd; + res = test_create_file("remove"); + fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res >= 0); + + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_read(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_write(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + + return TEST_RES_OK; } TEST_END(deleted_same_fd) - TEST(deleted_other_fd) { - int res; - spiffs_stat s; - spiffs_file fd, fd_orig; - res = test_create_file("remove"); - fd_orig = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); - TEST_CHECK(fd_orig >= 0); - fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_fremove(FS, fd_orig); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd_orig); - - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_read(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - res = SPIFFS_write(FS, fd, 0, 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); - - return TEST_RES_OK; + int res; + spiffs_stat s; + spiffs_file fd, fd_orig; + res = test_create_file("remove"); + fd_orig = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); + TEST_CHECK(fd_orig >= 0); + fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fremove(FS, fd_orig); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd_orig); + + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_CUR); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_read(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + res = SPIFFS_write(FS, fd, 0, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FILE_CLOSED); + + return TEST_RES_OK; } TEST_END(deleted_other_fd) - TEST(file_by_open) { - int res; - spiffs_stat s; - spiffs_file fd = SPIFFS_open(FS, "filebopen", SPIFFS_CREAT, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - TEST_CHECK(strcmp((char*)s.name, "filebopen") == 0); - TEST_CHECK(s.size == 0); - SPIFFS_close(FS, fd); - - fd = SPIFFS_open(FS, "filebopen", SPIFFS_RDONLY, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - TEST_CHECK(strcmp((char*)s.name, "filebopen") == 0); - TEST_CHECK(s.size == 0); - SPIFFS_close(FS, fd); - return TEST_RES_OK; + int res; + spiffs_stat s; + spiffs_file fd = SPIFFS_open(FS, "filebopen", SPIFFS_CREAT, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + TEST_CHECK(strcmp((char *)s.name, "filebopen") == 0); + TEST_CHECK(s.size == 0); + SPIFFS_close(FS, fd); + + fd = SPIFFS_open(FS, "filebopen", SPIFFS_RDONLY, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + TEST_CHECK(strcmp((char *)s.name, "filebopen") == 0); + TEST_CHECK(s.size == 0); + SPIFFS_close(FS, fd); + return TEST_RES_OK; } TEST_END(file_by_open) - TEST(file_by_creat) { - int res; - res = test_create_file("filebcreat"); - TEST_CHECK(res >= 0); - res = SPIFFS_creat(FS, "filebcreat", 0); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS)==SPIFFS_ERR_CONFLICTING_NAME); - return TEST_RES_OK; + int res; + res = test_create_file("filebcreat"); + TEST_CHECK(res >= 0); + res = SPIFFS_creat(FS, "filebcreat", 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_CONFLICTING_NAME); + return TEST_RES_OK; } TEST_END(file_by_creat) TEST(list_dir) { - int res; + int res; - char *files[4] = { - "file1", - "file2", - "file3", - "file4" - }; - int file_cnt = sizeof(files)/sizeof(char *); + char *files[4] = {"file1", "file2", "file3", "file4"}; + int file_cnt = sizeof(files) / sizeof(char *); - int i; - - for (i = 0; i < file_cnt; i++) { - res = test_create_file(files[i]); - TEST_CHECK(res >= 0); - } + int i; - spiffs_DIR d; - struct spiffs_dirent e; - struct spiffs_dirent *pe = &e; + for (i = 0; i < file_cnt; i++) + { + res = test_create_file(files[i]); + TEST_CHECK(res >= 0); + } - SPIFFS_opendir(FS, "/", &d); - int found = 0; - while ((pe = SPIFFS_readdir(&d, pe))) { - printf(" %s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); - for (i = 0; i < file_cnt; i++) { - if (strcmp(files[i], pe->name) == 0) { - found++; - break; - } + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + + SPIFFS_opendir(FS, "/", &d); + int found = 0; + while ((pe = SPIFFS_readdir(&d, pe))) + { + printf(" %s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); + for (i = 0; i < file_cnt; i++) + { + if (strcmp(files[i], pe->name) == 0) + { + found++; + break; + } + } } - } - SPIFFS_closedir(&d); + SPIFFS_closedir(&d); - TEST_CHECK(found == file_cnt); + TEST_CHECK(found == file_cnt); - return TEST_RES_OK; + return TEST_RES_OK; } TEST_END(list_dir) +TEST(open_by_dirent) +{ + int res; -TEST(open_by_dirent) { - int res; - - char *files[4] = { - "file1", - "file2", - "file3", - "file4" - }; - int file_cnt = sizeof(files)/sizeof(char *); - - int i; - int size = SPIFFS_DATA_PAGE_SIZE(FS); - - for (i = 0; i < file_cnt; i++) { - res = test_create_and_write_file(files[i], size, size); - TEST_CHECK(res >= 0); - } - - spiffs_DIR d; - struct spiffs_dirent e; - struct spiffs_dirent *pe = &e; + char *files[4] = {"file1", "file2", "file3", "file4"}; + int file_cnt = sizeof(files) / sizeof(char *); - int found = 0; - SPIFFS_opendir(FS, "/", &d); - while ((pe = SPIFFS_readdir(&d, pe))) { - spiffs_file fd = SPIFFS_open_by_dirent(FS, pe, SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = read_and_verify_fd(fd, pe->name); - TEST_CHECK(res == SPIFFS_OK); - fd = SPIFFS_open_by_dirent(FS, pe, SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res == SPIFFS_OK); - SPIFFS_close(FS, fd); - found++; - } - SPIFFS_closedir(&d); - - TEST_CHECK(found == file_cnt); + int i; + int size = SPIFFS_DATA_PAGE_SIZE(FS); - found = 0; - SPIFFS_opendir(FS, "/", &d); - while ((pe = SPIFFS_readdir(&d, pe))) { - found++; - } - SPIFFS_closedir(&d); + for (i = 0; i < file_cnt; i++) + { + res = test_create_and_write_file(files[i], size, size); + TEST_CHECK(res >= 0); + } - TEST_CHECK(found == 0); + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + + int found = 0; + SPIFFS_opendir(FS, "/", &d); + while ((pe = SPIFFS_readdir(&d, pe))) + { + spiffs_file fd = SPIFFS_open_by_dirent(FS, pe, SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = read_and_verify_fd(fd, pe->name); + TEST_CHECK(res == SPIFFS_OK); + fd = SPIFFS_open_by_dirent(FS, pe, SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res == SPIFFS_OK); + SPIFFS_close(FS, fd); + found++; + } + SPIFFS_closedir(&d); - return TEST_RES_OK; + TEST_CHECK(found == file_cnt); -} TEST_END(open_by_dirent) + found = 0; + SPIFFS_opendir(FS, "/", &d); + while ((pe = SPIFFS_readdir(&d, pe))) { found++; } + SPIFFS_closedir(&d); + TEST_CHECK(found == 0); -TEST(rename) { - int res; + return TEST_RES_OK; +} +TEST_END(open_by_dirent) - char *src_name = "baah"; - char *dst_name = "booh"; - char *dst_name2 = "beeh"; - int size = SPIFFS_DATA_PAGE_SIZE(FS); +TEST(rename) +{ + int res; - res = test_create_and_write_file(src_name, size, size); - TEST_CHECK(res >= 0); + char *src_name = "baah"; + char *dst_name = "booh"; + char *dst_name2 = "beeh"; + int size = SPIFFS_DATA_PAGE_SIZE(FS); - res = SPIFFS_rename(FS, src_name, dst_name); - TEST_CHECK(res >= 0); + res = test_create_and_write_file(src_name, size, size); + TEST_CHECK(res >= 0); - res = SPIFFS_rename(FS, dst_name, dst_name); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_CONFLICTING_NAME); + res = SPIFFS_rename(FS, src_name, dst_name); + TEST_CHECK(res >= 0); - res = SPIFFS_rename(FS, src_name, dst_name2); - TEST_CHECK(res < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); + res = SPIFFS_rename(FS, dst_name, dst_name); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_CONFLICTING_NAME); - return TEST_RES_OK; -} TEST_END(rename) + res = SPIFFS_rename(FS, src_name, dst_name2); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); + return TEST_RES_OK; +} +TEST_END(rename) TEST(remove_single_by_path) { - int res; - spiffs_file fd; - res = test_create_file("remove"); - TEST_CHECK(res >= 0); - res = SPIFFS_remove(FS, "remove"); - TEST_CHECK(res >= 0); - fd = SPIFFS_open(FS, "remove", SPIFFS_RDONLY, 0); - TEST_CHECK(fd < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); - - return TEST_RES_OK; + int res; + spiffs_file fd; + res = test_create_file("remove"); + TEST_CHECK(res >= 0); + res = SPIFFS_remove(FS, "remove"); + TEST_CHECK(res >= 0); + fd = SPIFFS_open(FS, "remove", SPIFFS_RDONLY, 0); + TEST_CHECK(fd < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); + + return TEST_RES_OK; } TEST_END(remove_single_by_path) - TEST(remove_single_by_fd) { - int res; - spiffs_file fd; - res = test_create_file("remove"); - TEST_CHECK(res >= 0); - fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - fd = SPIFFS_open(FS, "remove", SPIFFS_RDONLY, 0); - TEST_CHECK(fd < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); - - return TEST_RES_OK; + int res; + spiffs_file fd; + res = test_create_file("remove"); + TEST_CHECK(res >= 0); + fd = SPIFFS_open(FS, "remove", SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + fd = SPIFFS_open(FS, "remove", SPIFFS_RDONLY, 0); + TEST_CHECK(fd < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); + + return TEST_RES_OK; } TEST_END(remove_single_by_fd) - TEST(write_big_file_chunks_page) { - int size = ((50*(FS)->cfg.phys_size)/100); - printf(" filesize %i\n", size); - int res = test_create_and_write_file("bigfile", size, SPIFFS_DATA_PAGE_SIZE(FS)); - TEST_CHECK(res >= 0); - res = read_and_verify("bigfile"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; + int size = ((50 * (FS)->cfg.phys_size) / 100); + printf(" filesize %i\n", size); + int res = test_create_and_write_file("bigfile", size, SPIFFS_DATA_PAGE_SIZE(FS)); + TEST_CHECK(res >= 0); + res = read_and_verify("bigfile"); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; } TEST_END(write_big_file_chunks_page) - TEST(write_big_files_chunks_page) { - char name[32]; - int f; - int files = 10; - int res; - int size = ((50*(FS)->cfg.phys_size)/100)/files; - printf(" filesize %i\n", size); - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = test_create_and_write_file(name, size, SPIFFS_DATA_PAGE_SIZE(FS)); - TEST_CHECK(res >= 0); - } - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = read_and_verify(name); - TEST_CHECK(res >= 0); - } - - return TEST_RES_OK; + char name[32]; + int f; + int files = 10; + int res; + int size = ((50 * (FS)->cfg.phys_size) / 100) / files; + printf(" filesize %i\n", size); + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = test_create_and_write_file(name, size, SPIFFS_DATA_PAGE_SIZE(FS)); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + + return TEST_RES_OK; } TEST_END(write_big_files_chunks_page) - TEST(write_big_file_chunks_index) { - int size = ((50*(FS)->cfg.phys_size)/100); - printf(" filesize %i\n", size); - int res = test_create_and_write_file("bigfile", size, SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_OBJ_HDR_IX_LEN(FS)); - TEST_CHECK(res >= 0); - res = read_and_verify("bigfile"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; + int size = ((50 * (FS)->cfg.phys_size) / 100); + printf(" filesize %i\n", size); + int res = test_create_and_write_file("bigfile", size, SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_OBJ_HDR_IX_LEN(FS)); + TEST_CHECK(res >= 0); + res = read_and_verify("bigfile"); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; } TEST_END(write_big_file_chunks_index) - TEST(write_big_files_chunks_index) { - char name[32]; - int f; - int files = 10; - int res; - int size = ((50*(FS)->cfg.phys_size)/100)/files; - printf(" filesize %i\n", size); - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = test_create_and_write_file(name, size, SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_OBJ_HDR_IX_LEN(FS)); - TEST_CHECK(res >= 0); - } - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = read_and_verify(name); - TEST_CHECK(res >= 0); - } - - return TEST_RES_OK; + char name[32]; + int f; + int files = 10; + int res; + int size = ((50 * (FS)->cfg.phys_size) / 100) / files; + printf(" filesize %i\n", size); + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = test_create_and_write_file(name, size, SPIFFS_DATA_PAGE_SIZE(FS) * SPIFFS_OBJ_HDR_IX_LEN(FS)); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + + return TEST_RES_OK; } TEST_END(write_big_files_chunks_index) - TEST(write_big_file_chunks_huge) { - int size = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS); - printf(" filesize %i\n", size); - int res = test_create_and_write_file("bigfile", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("bigfile"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; + int size = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS); + printf(" filesize %i\n", size); + int res = test_create_and_write_file("bigfile", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("bigfile"); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; } TEST_END(write_big_file_chunks_huge) - TEST(write_big_files_chunks_huge) { - char name[32]; - int f; - int files = 10; - int res; - int size = ((50*(FS)->cfg.phys_size)/100)/files; - printf(" filesize %i\n", size); - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = test_create_and_write_file(name, size, size); - TEST_CHECK(res >= 0); - } - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = read_and_verify(name); - TEST_CHECK(res >= 0); - } - - return TEST_RES_OK; + char name[32]; + int f; + int files = 10; + int res; + int size = ((50 * (FS)->cfg.phys_size) / 100) / files; + printf(" filesize %i\n", size); + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = test_create_and_write_file(name, size, size); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + + return TEST_RES_OK; } TEST_END(write_big_files_chunks_huge) - TEST(truncate_big_file) { - int size = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS); - printf(" filesize %i\n", size); - int res = test_create_and_write_file("bigfile", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("bigfile"); - TEST_CHECK(res >= 0); - spiffs_file fd = SPIFFS_open(FS, "bigfile", SPIFFS_RDWR, 0); - TEST_CHECK(fd > 0); - res = SPIFFS_fremove(FS, fd); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - - fd = SPIFFS_open(FS, "bigfile", SPIFFS_RDWR, 0); - TEST_CHECK(fd < 0); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); - - return TEST_RES_OK; + int size = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS); + printf(" filesize %i\n", size); + int res = test_create_and_write_file("bigfile", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("bigfile"); + TEST_CHECK(res >= 0); + spiffs_file fd = SPIFFS_open(FS, "bigfile", SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + res = SPIFFS_fremove(FS, fd); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + + fd = SPIFFS_open(FS, "bigfile", SPIFFS_RDWR, 0); + TEST_CHECK(fd < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NOT_FOUND); + + return TEST_RES_OK; } TEST_END(truncate_big_file) +TEST(simultaneous_write) +{ + int res = SPIFFS_creat(FS, "simul1", 0); + TEST_CHECK(res >= 0); -TEST(simultaneous_write) { - int res = SPIFFS_creat(FS, "simul1", 0); - TEST_CHECK(res >= 0); - - spiffs_file fd1 = SPIFFS_open(FS, "simul1", SPIFFS_RDWR, 0); - TEST_CHECK(fd1 > 0); - spiffs_file fd2 = SPIFFS_open(FS, "simul1", SPIFFS_RDWR, 0); - TEST_CHECK(fd2 > 0); - spiffs_file fd3 = SPIFFS_open(FS, "simul1", SPIFFS_RDWR, 0); - TEST_CHECK(fd3 > 0); + spiffs_file fd1 = SPIFFS_open(FS, "simul1", SPIFFS_RDWR, 0); + TEST_CHECK(fd1 > 0); + spiffs_file fd2 = SPIFFS_open(FS, "simul1", SPIFFS_RDWR, 0); + TEST_CHECK(fd2 > 0); + spiffs_file fd3 = SPIFFS_open(FS, "simul1", SPIFFS_RDWR, 0); + TEST_CHECK(fd3 > 0); - u8_t data1 = 1; - u8_t data2 = 2; - u8_t data3 = 3; + u8_t data1 = 1; + u8_t data2 = 2; + u8_t data3 = 3; - res = SPIFFS_write(FS, fd1, &data1, 1); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd1); - res = SPIFFS_write(FS, fd2, &data2, 1); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd2); - res = SPIFFS_write(FS, fd3, &data3, 1); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd3); + res = SPIFFS_write(FS, fd1, &data1, 1); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd1); + res = SPIFFS_write(FS, fd2, &data2, 1); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd2); + res = SPIFFS_write(FS, fd3, &data3, 1); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd3); - spiffs_stat s; - res = SPIFFS_stat(FS, "simul1", &s); - TEST_CHECK(res >= 0); + spiffs_stat s; + res = SPIFFS_stat(FS, "simul1", &s); + TEST_CHECK(res >= 0); - TEST_CHECK(s.size == 1); + TEST_CHECK(s.size == 1); - u8_t rdata; - spiffs_file fd = SPIFFS_open(FS, "simul1", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - res = SPIFFS_read(FS, fd, &rdata, 1); - TEST_CHECK(res >= 0); + u8_t rdata; + spiffs_file fd = SPIFFS_open(FS, "simul1", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + res = SPIFFS_read(FS, fd, &rdata, 1); + TEST_CHECK(res >= 0); - TEST_CHECK(rdata == data3); + TEST_CHECK(rdata == data3); - return TEST_RES_OK; + return TEST_RES_OK; } TEST_END(simultaneous_write) +TEST(simultaneous_write_append) +{ + int res = SPIFFS_creat(FS, "simul2", 0); + TEST_CHECK(res >= 0); -TEST(simultaneous_write_append) { - int res = SPIFFS_creat(FS, "simul2", 0); - TEST_CHECK(res >= 0); - - spiffs_file fd1 = SPIFFS_open(FS, "simul2", SPIFFS_RDWR | SPIFFS_APPEND, 0); - TEST_CHECK(fd1 > 0); - spiffs_file fd2 = SPIFFS_open(FS, "simul2", SPIFFS_RDWR | SPIFFS_APPEND, 0); - TEST_CHECK(fd2 > 0); - spiffs_file fd3 = SPIFFS_open(FS, "simul2", SPIFFS_RDWR | SPIFFS_APPEND, 0); - TEST_CHECK(fd3 > 0); - - u8_t data1 = 1; - u8_t data2 = 2; - u8_t data3 = 3; - - res = SPIFFS_write(FS, fd1, &data1, 1); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd1); - res = SPIFFS_write(FS, fd2, &data2, 1); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd2); - res = SPIFFS_write(FS, fd3, &data3, 1); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd3); - - spiffs_stat s; - res = SPIFFS_stat(FS, "simul2", &s); - TEST_CHECK(res >= 0); - - TEST_CHECK(s.size == 3); - - u8_t rdata[3]; - spiffs_file fd = SPIFFS_open(FS, "simul2", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - res = SPIFFS_read(FS, fd, &rdata, 3); - TEST_CHECK(res >= 0); - - TEST_CHECK(rdata[0] == data1); - TEST_CHECK(rdata[1] == data2); - TEST_CHECK(rdata[2] == data3); - - return TEST_RES_OK; -} -TEST_END(simultaneous_write_append) + spiffs_file fd1 = SPIFFS_open(FS, "simul2", SPIFFS_RDWR | SPIFFS_APPEND, 0); + TEST_CHECK(fd1 > 0); + spiffs_file fd2 = SPIFFS_open(FS, "simul2", SPIFFS_RDWR | SPIFFS_APPEND, 0); + TEST_CHECK(fd2 > 0); + spiffs_file fd3 = SPIFFS_open(FS, "simul2", SPIFFS_RDWR | SPIFFS_APPEND, 0); + TEST_CHECK(fd3 > 0); + u8_t data1 = 1; + u8_t data2 = 2; + u8_t data3 = 3; -TEST(file_uniqueness) -{ - int res; - spiffs_file fd; - char fname[32]; - int files = ((SPIFFS_CFG_PHYS_SZ(FS) * 75) / 100) / 2 / SPIFFS_CFG_LOG_PAGE_SZ(FS); - //(FS_PURE_DATA_PAGES(FS) / 2) - SPIFFS_PAGES_PER_BLOCK(FS)*8; - int i; - printf(" creating %i files\n", files); - for (i = 0; i < files; i++) { - char content[20]; - sprintf(fname, "file%i", i); - sprintf(content, "%i", i); - res = test_create_file(fname); - TEST_CHECK(res >= 0); - fd = SPIFFS_open(FS, fname, SPIFFS_APPEND | SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_write(FS, fd, content, strlen(content)+1); + res = SPIFFS_write(FS, fd1, &data1, 1); TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - } - printf(" checking %i files\n", files); - for (i = 0; i < files; i++) { - char content[20]; - char ref_content[20]; - sprintf(fname, "file%i", i); - sprintf(content, "%i", i); - fd = SPIFFS_open(FS, fname, SPIFFS_RDONLY, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_read(FS, fd, ref_content, strlen(content)+1); + SPIFFS_close(FS, fd1); + res = SPIFFS_write(FS, fd2, &data2, 1); TEST_CHECK(res >= 0); - TEST_CHECK(strcmp(ref_content, content) == 0); - SPIFFS_close(FS, fd); - } - printf(" removing %i files\n", files/2); - for (i = 0; i < files; i += 2) { - sprintf(fname, "file%i", i); - res = SPIFFS_remove(FS, fname); - TEST_CHECK(res >= 0); - } - printf(" creating %i files\n", files/2); - for (i = 0; i < files; i += 2) { - char content[20]; - sprintf(fname, "file%i", i); - sprintf(content, "new%i", i); - res = test_create_file(fname); - TEST_CHECK(res >= 0); - fd = SPIFFS_open(FS, fname, SPIFFS_APPEND | SPIFFS_RDWR, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_write(FS, fd, content, strlen(content)+1); + SPIFFS_close(FS, fd2); + res = SPIFFS_write(FS, fd3, &data3, 1); TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); - } - printf(" checking %i files\n", files); - for (i = 0; i < files; i++) { - char content[20]; - char ref_content[20]; - sprintf(fname, "file%i", i); - if ((i & 1) == 0) { - sprintf(content, "new%i", i); - } else { - sprintf(content, "%i", i); - } - fd = SPIFFS_open(FS, fname, SPIFFS_RDONLY, 0); - TEST_CHECK(fd >= 0); - res = SPIFFS_read(FS, fd, ref_content, strlen(content)+1); + SPIFFS_close(FS, fd3); + + spiffs_stat s; + res = SPIFFS_stat(FS, "simul2", &s); TEST_CHECK(res >= 0); - TEST_CHECK(strcmp(ref_content, content) == 0); - SPIFFS_close(FS, fd); - } - return TEST_RES_OK; + TEST_CHECK(s.size == 3); + + u8_t rdata[3]; + spiffs_file fd = SPIFFS_open(FS, "simul2", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + res = SPIFFS_read(FS, fd, &rdata, 3); + TEST_CHECK(res >= 0); + + TEST_CHECK(rdata[0] == data1); + TEST_CHECK(rdata[1] == data2); + TEST_CHECK(rdata[2] == data3); + + return TEST_RES_OK; +} +TEST_END(simultaneous_write_append) + +TEST(file_uniqueness) +{ + int res; + spiffs_file fd; + char fname[32]; + int files = ((SPIFFS_CFG_PHYS_SZ(FS) * 75) / 100) / 2 / SPIFFS_CFG_LOG_PAGE_SZ(FS); + //(FS_PURE_DATA_PAGES(FS) / 2) - SPIFFS_PAGES_PER_BLOCK(FS)*8; + int i; + printf(" creating %i files\n", files); + for (i = 0; i < files; i++) + { + char content[20]; + sprintf(fname, "file%i", i); + sprintf(content, "%i", i); + res = test_create_file(fname); + TEST_CHECK(res >= 0); + fd = SPIFFS_open(FS, fname, SPIFFS_APPEND | SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_write(FS, fd, content, strlen(content) + 1); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + } + printf(" checking %i files\n", files); + for (i = 0; i < files; i++) + { + char content[20]; + char ref_content[20]; + sprintf(fname, "file%i", i); + sprintf(content, "%i", i); + fd = SPIFFS_open(FS, fname, SPIFFS_RDONLY, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_read(FS, fd, ref_content, strlen(content) + 1); + TEST_CHECK(res >= 0); + TEST_CHECK(strcmp(ref_content, content) == 0); + SPIFFS_close(FS, fd); + } + printf(" removing %i files\n", files / 2); + for (i = 0; i < files; i += 2) + { + sprintf(fname, "file%i", i); + res = SPIFFS_remove(FS, fname); + TEST_CHECK(res >= 0); + } + printf(" creating %i files\n", files / 2); + for (i = 0; i < files; i += 2) + { + char content[20]; + sprintf(fname, "file%i", i); + sprintf(content, "new%i", i); + res = test_create_file(fname); + TEST_CHECK(res >= 0); + fd = SPIFFS_open(FS, fname, SPIFFS_APPEND | SPIFFS_RDWR, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_write(FS, fd, content, strlen(content) + 1); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + } + printf(" checking %i files\n", files); + for (i = 0; i < files; i++) + { + char content[20]; + char ref_content[20]; + sprintf(fname, "file%i", i); + if ((i & 1) == 0) + { + sprintf(content, "new%i", i); + } + else + { + sprintf(content, "%i", i); + } + fd = SPIFFS_open(FS, fname, SPIFFS_RDONLY, 0); + TEST_CHECK(fd >= 0); + res = SPIFFS_read(FS, fd, ref_content, strlen(content) + 1); + TEST_CHECK(res >= 0); + TEST_CHECK(strcmp(ref_content, content) == 0); + SPIFFS_close(FS, fd); + } + + return TEST_RES_OK; } TEST_END(file_uniqueness) -int create_and_read_back(int size, int chunk) { - char *name = "file"; - spiffs_file fd; - s32_t res; +int create_and_read_back(int size, int chunk) +{ + char *name = "file"; + spiffs_file fd; + s32_t res; - u8_t *buf = malloc(size); - memrand(buf, size); + u8_t *buf = malloc(size); + memrand(buf, size); - res = test_create_file(name); - CHECK(res >= 0); - fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); - CHECK(fd >= 0); - res = SPIFFS_write(FS, fd, buf, size); - CHECK(res >= 0); + res = test_create_file(name); + CHECK(res >= 0); + fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); + CHECK(fd >= 0); + res = SPIFFS_write(FS, fd, buf, size); + CHECK(res >= 0); - spiffs_stat stat; - res = SPIFFS_fstat(FS, fd, &stat); - CHECK(res >= 0); - CHECK(stat.size == size); + spiffs_stat stat; + res = SPIFFS_fstat(FS, fd, &stat); + CHECK(res >= 0); + CHECK(stat.size == size); - SPIFFS_close(FS, fd); + SPIFFS_close(FS, fd); - fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); - CHECK(fd >= 0); + fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); + CHECK(fd >= 0); - u8_t *rbuf = malloc(size); - int offs = 0; - while (offs < size) { - int len = MIN(size - offs, chunk); - res = SPIFFS_read(FS, fd, &rbuf[offs], len); - CHECK(res >= 0); - CHECK(memcmp(&rbuf[offs], &buf[offs], len) == 0); + u8_t *rbuf = malloc(size); + int offs = 0; + while (offs < size) + { + int len = MIN(size - offs, chunk); + res = SPIFFS_read(FS, fd, &rbuf[offs], len); + CHECK(res >= 0); + CHECK(memcmp(&rbuf[offs], &buf[offs], len) == 0); - offs += chunk; - } + offs += chunk; + } - CHECK(memcmp(&rbuf[0], &buf[0], size) == 0); + CHECK(memcmp(&rbuf[0], &buf[0], size) == 0); - SPIFFS_close(FS, fd); + SPIFFS_close(FS, fd); - free(rbuf); - free(buf); + free(rbuf); + free(buf); - return 0; + return 0; } TEST(read_chunk_1) { - TEST_CHECK(create_and_read_back(SPIFFS_DATA_PAGE_SIZE(FS)*8, 1) == 0); - return TEST_RES_OK; + TEST_CHECK(create_and_read_back(SPIFFS_DATA_PAGE_SIZE(FS) * 8, 1) == 0); + return TEST_RES_OK; } TEST_END(read_chunk_1) - TEST(read_chunk_page) { - TEST_CHECK(create_and_read_back(SPIFFS_DATA_PAGE_SIZE(FS)*(SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS))*2, - SPIFFS_DATA_PAGE_SIZE(FS)) == 0); - return TEST_RES_OK; + TEST_CHECK( + create_and_read_back(SPIFFS_DATA_PAGE_SIZE(FS) * (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS)) * 2, + SPIFFS_DATA_PAGE_SIZE(FS)) == 0); + return TEST_RES_OK; } TEST_END(read_chunk_page) - TEST(read_chunk_index) { - TEST_CHECK(create_and_read_back(SPIFFS_DATA_PAGE_SIZE(FS)*(SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS))*4, - SPIFFS_DATA_PAGE_SIZE(FS)*(SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS))) == 0); - return TEST_RES_OK; + TEST_CHECK(create_and_read_back( + SPIFFS_DATA_PAGE_SIZE(FS) * (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS)) * 4, + SPIFFS_DATA_PAGE_SIZE(FS) * (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS))) == 0); + return TEST_RES_OK; } TEST_END(read_chunk_index) - TEST(read_chunk_huge) { - int sz = (2*(FS)->cfg.phys_size)/3; - TEST_CHECK(create_and_read_back(sz, sz) == 0); - return TEST_RES_OK; + int sz = (2 * (FS)->cfg.phys_size) / 3; + TEST_CHECK(create_and_read_back(sz, sz) == 0); + return TEST_RES_OK; } TEST_END(read_chunk_huge) - TEST(read_beyond) { - char *name = "file"; - spiffs_file fd; - s32_t res; - u32_t size = SPIFFS_DATA_PAGE_SIZE(FS)*2; + char *name = "file"; + spiffs_file fd; + s32_t res; + u32_t size = SPIFFS_DATA_PAGE_SIZE(FS) * 2; - u8_t *buf = malloc(size); - memrand(buf, size); + u8_t *buf = malloc(size); + memrand(buf, size); - res = test_create_file(name); - CHECK(res >= 0); - fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); - CHECK(fd >= 0); - res = SPIFFS_write(FS, fd, buf, size); - CHECK(res >= 0); + res = test_create_file(name); + CHECK(res >= 0); + fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); + CHECK(fd >= 0); + res = SPIFFS_write(FS, fd, buf, size); + CHECK(res >= 0); - spiffs_stat stat; - res = SPIFFS_fstat(FS, fd, &stat); - CHECK(res >= 0); - CHECK(stat.size == size); + spiffs_stat stat; + res = SPIFFS_fstat(FS, fd, &stat); + CHECK(res >= 0); + CHECK(stat.size == size); - SPIFFS_close(FS, fd); + SPIFFS_close(FS, fd); - fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); - CHECK(fd >= 0); + fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); + CHECK(fd >= 0); - u8_t *rbuf = malloc(size+10); - res = SPIFFS_read(FS, fd, rbuf, size+10); + u8_t *rbuf = malloc(size + 10); + res = SPIFFS_read(FS, fd, rbuf, size + 10); - SPIFFS_close(FS, fd); + SPIFFS_close(FS, fd); - free(rbuf); - free(buf); + free(rbuf); + free(buf); - TEST_CHECK(res == size); + TEST_CHECK(res == size); - return TEST_RES_OK; + return TEST_RES_OK; } TEST_END(read_beyond) +TEST(bad_index_1) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); -TEST(bad_index_1) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); - - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); - // modify object index, find object index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); + // modify object index, find object index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); - // set object index entry 2 to a bad page, free - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 2 * sizeof(spiffs_page_ix); - spiffs_page_ix bad_pix_ref = (spiffs_page_ix)-1; - area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); + // set object index entry 2 to a bad page, free + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 2 * sizeof(spiffs_page_ix); + spiffs_page_ix bad_pix_ref = (spiffs_page_ix)-1; + area_write(addr, (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); #if SPIFFS_CACHE - // delete all cache - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + // delete all cache + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - res = read_and_verify("file"); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_INDEX_REF_FREE); - - return TEST_RES_OK; -} TEST_END(bad_index_1) + res = read_and_verify("file"); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_INDEX_REF_FREE); + return TEST_RES_OK; +} +TEST_END(bad_index_1) -TEST(bad_index_2) { - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - int res = test_create_and_write_file("file", size, size); - TEST_CHECK(res >= 0); - res = read_and_verify("file"); - TEST_CHECK(res >= 0); +TEST(bad_index_2) +{ + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + int res = test_create_and_write_file("file", size, size); + TEST_CHECK(res >= 0); + res = read_and_verify("file"); + TEST_CHECK(res >= 0); - spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); - TEST_CHECK(fd > 0); - spiffs_stat s; - res = SPIFFS_fstat(FS, fd, &s); - TEST_CHECK(res >= 0); - SPIFFS_close(FS, fd); + spiffs_file fd = SPIFFS_open(FS, "file", SPIFFS_RDONLY, 0); + TEST_CHECK(fd > 0); + spiffs_stat s; + res = SPIFFS_fstat(FS, fd, &s); + TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); - // modify object index, find object index header - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - TEST_CHECK(res >= 0); + // modify object index, find object index header + spiffs_page_ix pix; + res = spiffs_obj_lu_find_id_and_span(FS, s.obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); + TEST_CHECK(res >= 0); - // set object index entry 2 to a bad page, lu - u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 2 * sizeof(spiffs_page_ix); - spiffs_page_ix bad_pix_ref = SPIFFS_OBJ_LOOKUP_PAGES(FS)-1; - area_write(addr, (u8_t*)&bad_pix_ref, sizeof(spiffs_page_ix)); + // set object index entry 2 to a bad page, lu + u32_t addr = SPIFFS_PAGE_TO_PADDR(FS, pix) + sizeof(spiffs_page_object_ix_header) + 2 * sizeof(spiffs_page_ix); + spiffs_page_ix bad_pix_ref = SPIFFS_OBJ_LOOKUP_PAGES(FS) - 1; + area_write(addr, (u8_t *)&bad_pix_ref, sizeof(spiffs_page_ix)); #if SPIFFS_CACHE - // delete all cache - spiffs_cache *cache = spiffs_get_cache(FS); - cache->cpage_use_map = 0; + // delete all cache + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; #endif - res = read_and_verify("file"); - TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_INDEX_REF_LU); - - return TEST_RES_OK; -} TEST_END(bad_index_2) - - -TEST(lseek_simple_modification) { - int res; - spiffs_file fd; - char *fname = "seekfile"; - int i; - int len = 4096; - fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); - TEST_CHECK(fd > 0); - int pfd = open(make_test_fname(fname), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - u8_t *buf = malloc(len); - memrand(buf, len); - res = SPIFFS_write(FS, fd, buf, len); - TEST_CHECK(res >= 0); - write(pfd, buf, len); - free(buf); - res = read_and_verify(fname); - TEST_CHECK(res >= 0); - - res = SPIFFS_lseek(FS, fd, len/2, SPIFFS_SEEK_SET); - TEST_CHECK(res >= 0); - lseek(pfd, len/2, SEEK_SET); - len = len/4; - buf = malloc(len); - memrand(buf, len); - res = SPIFFS_write(FS, fd, buf, len); - TEST_CHECK(res >= 0); - write(pfd, buf, len); - free(buf); - - res = read_and_verify(fname); - TEST_CHECK(res >= 0); - - SPIFFS_close(FS, fd); - close(pfd); - - return TEST_RES_OK; + res = read_and_verify("file"); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_INDEX_REF_LU); + + return TEST_RES_OK; } -TEST_END(lseek_simple_modification) +TEST_END(bad_index_2) +TEST(lseek_simple_modification) +{ + int res; + spiffs_file fd; + char *fname = "seekfile"; + int i; + int len = 4096; + fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + int pfd = open(make_test_fname(fname), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + u8_t *buf = malloc(len); + memrand(buf, len); + res = SPIFFS_write(FS, fd, buf, len); + TEST_CHECK(res >= 0); + write(pfd, buf, len); + free(buf); + res = read_and_verify(fname); + TEST_CHECK(res >= 0); -TEST(lseek_modification_append) { - int res; - spiffs_file fd; - char *fname = "seekfile"; - int i; - int len = 4096; - fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); - TEST_CHECK(fd > 0); - int pfd = open(make_test_fname(fname), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - u8_t *buf = malloc(len); - memrand(buf, len); - res = SPIFFS_write(FS, fd, buf, len); - TEST_CHECK(res >= 0); - write(pfd, buf, len); - free(buf); - res = read_and_verify(fname); - TEST_CHECK(res >= 0); - - res = SPIFFS_lseek(FS, fd, len/2, SPIFFS_SEEK_SET); - TEST_CHECK(res >= 0); - lseek(pfd, len/2, SEEK_SET); - - buf = malloc(len); - memrand(buf, len); - res = SPIFFS_write(FS, fd, buf, len); - TEST_CHECK(res >= 0); - write(pfd, buf, len); - free(buf); - - res = read_and_verify(fname); - TEST_CHECK(res >= 0); - - SPIFFS_close(FS, fd); - close(pfd); - - return TEST_RES_OK; -} -TEST_END(lseek_modification_append) + res = SPIFFS_lseek(FS, fd, len / 2, SPIFFS_SEEK_SET); + TEST_CHECK(res >= 0); + lseek(pfd, len / 2, SEEK_SET); + len = len / 4; + buf = malloc(len); + memrand(buf, len); + res = SPIFFS_write(FS, fd, buf, len); + TEST_CHECK(res >= 0); + write(pfd, buf, len); + free(buf); + res = read_and_verify(fname); + TEST_CHECK(res >= 0); -TEST(lseek_modification_append_multi) { - int res; - spiffs_file fd; - char *fname = "seekfile"; - int len = 1024; - int runs = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS) / (len/2); + SPIFFS_close(FS, fd); + close(pfd); - fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); - TEST_CHECK(fd > 0); - int pfd = open(make_test_fname(fname), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - u8_t *buf = malloc(len); - memrand(buf, len); - res = SPIFFS_write(FS, fd, buf, len); - TEST_CHECK(res >= 0); - write(pfd, buf, len); - free(buf); - res = read_and_verify(fname); - TEST_CHECK(res >= 0); + return TEST_RES_OK; +} +TEST_END(lseek_simple_modification) - while (runs--) { - res = SPIFFS_lseek(FS, fd, -len/2, SPIFFS_SEEK_END); +TEST(lseek_modification_append) +{ + int res; + spiffs_file fd; + char *fname = "seekfile"; + int i; + int len = 4096; + fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + int pfd = open(make_test_fname(fname), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + u8_t *buf = malloc(len); + memrand(buf, len); + res = SPIFFS_write(FS, fd, buf, len); + TEST_CHECK(res >= 0); + write(pfd, buf, len); + free(buf); + res = read_and_verify(fname); TEST_CHECK(res >= 0); - lseek(pfd, -len/2, SEEK_END); + + res = SPIFFS_lseek(FS, fd, len / 2, SPIFFS_SEEK_SET); + TEST_CHECK(res >= 0); + lseek(pfd, len / 2, SEEK_SET); buf = malloc(len); memrand(buf, len); @@ -978,417 +926,319 @@ TEST(lseek_modification_append_multi) { res = read_and_verify(fname); TEST_CHECK(res >= 0); - } - SPIFFS_close(FS, fd); - close(pfd); + SPIFFS_close(FS, fd); + close(pfd); - return TEST_RES_OK; + return TEST_RES_OK; } -TEST_END(lseek_modification_append_multi) +TEST_END(lseek_modification_append) +TEST(lseek_modification_append_multi) +{ + int res; + spiffs_file fd; + char *fname = "seekfile"; + int len = 1024; + int runs = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS) / (len / 2); + + fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + int pfd = open(make_test_fname(fname), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + u8_t *buf = malloc(len); + memrand(buf, len); + res = SPIFFS_write(FS, fd, buf, len); + TEST_CHECK(res >= 0); + write(pfd, buf, len); + free(buf); + res = read_and_verify(fname); + TEST_CHECK(res >= 0); -TEST(lseek_read) { - int res; - spiffs_file fd; - char *fname = "seekfile"; - int len = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS); - int runs = 100000; + while (runs--) + { + res = SPIFFS_lseek(FS, fd, -len / 2, SPIFFS_SEEK_END); + TEST_CHECK(res >= 0); + lseek(pfd, -len / 2, SEEK_END); + + buf = malloc(len); + memrand(buf, len); + res = SPIFFS_write(FS, fd, buf, len); + TEST_CHECK(res >= 0); + write(pfd, buf, len); + free(buf); + + res = read_and_verify(fname); + TEST_CHECK(res >= 0); + } - fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); - TEST_CHECK(fd > 0); - u8_t *refbuf = malloc(len); - memrand(refbuf, len); - res = SPIFFS_write(FS, fd, refbuf, len); - TEST_CHECK(res >= 0); + SPIFFS_close(FS, fd); + close(pfd); - int offs = 0; - res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_SET); - TEST_CHECK(res >= 0); + return TEST_RES_OK; +} +TEST_END(lseek_modification_append_multi) - while (runs--) { - int i; - u8_t buf[64]; - if (offs + 41 + sizeof(buf) >= len) { - offs = (offs + 41 + sizeof(buf)) % len; - res = SPIFFS_lseek(FS, fd, offs, SPIFFS_SEEK_SET); - TEST_CHECK(res >= 0); - } - res = SPIFFS_lseek(FS, fd, 41, SPIFFS_SEEK_CUR); - TEST_CHECK(res >= 0); - offs += 41; - res = SPIFFS_read(FS, fd, buf, sizeof(buf)); +TEST(lseek_read) +{ + int res; + spiffs_file fd; + char *fname = "seekfile"; + int len = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS); + int runs = 100000; + + fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + u8_t *refbuf = malloc(len); + memrand(refbuf, len); + res = SPIFFS_write(FS, fd, refbuf, len); TEST_CHECK(res >= 0); - for (i = 0; i < sizeof(buf); i++) { - if (buf[i] != refbuf[offs+i]) { - printf(" mismatch at offs %i\n", offs); - } - TEST_CHECK(buf[i] == refbuf[offs+i]); - } - offs += sizeof(buf); - res = SPIFFS_lseek(FS, fd, -((u32_t)sizeof(buf)+11), SPIFFS_SEEK_CUR); - TEST_CHECK(res >= 0); - offs -= (sizeof(buf)+11); - res = SPIFFS_read(FS, fd, buf, sizeof(buf)); + int offs = 0; + res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_SET); TEST_CHECK(res >= 0); - for (i = 0; i < sizeof(buf); i++) { - if (buf[i] != refbuf[offs+i]) { - printf(" mismatch at offs %i\n", offs); - } - TEST_CHECK(buf[i] == refbuf[offs+i]); + + while (runs--) + { + int i; + u8_t buf[64]; + if (offs + 41 + sizeof(buf) >= len) + { + offs = (offs + 41 + sizeof(buf)) % len; + res = SPIFFS_lseek(FS, fd, offs, SPIFFS_SEEK_SET); + TEST_CHECK(res >= 0); + } + res = SPIFFS_lseek(FS, fd, 41, SPIFFS_SEEK_CUR); + TEST_CHECK(res >= 0); + offs += 41; + res = SPIFFS_read(FS, fd, buf, sizeof(buf)); + TEST_CHECK(res >= 0); + for (i = 0; i < sizeof(buf); i++) + { + if (buf[i] != refbuf[offs + i]) + { + printf(" mismatch at offs %i\n", offs); + } + TEST_CHECK(buf[i] == refbuf[offs + i]); + } + offs += sizeof(buf); + + res = SPIFFS_lseek(FS, fd, -((u32_t)sizeof(buf) + 11), SPIFFS_SEEK_CUR); + TEST_CHECK(res >= 0); + offs -= (sizeof(buf) + 11); + res = SPIFFS_read(FS, fd, buf, sizeof(buf)); + TEST_CHECK(res >= 0); + for (i = 0; i < sizeof(buf); i++) + { + if (buf[i] != refbuf[offs + i]) + { + printf(" mismatch at offs %i\n", offs); + } + TEST_CHECK(buf[i] == refbuf[offs + i]); + } + offs += sizeof(buf); } - offs += sizeof(buf); - } - free(refbuf); - SPIFFS_close(FS, fd); + free(refbuf); + SPIFFS_close(FS, fd); - return TEST_RES_OK; + return TEST_RES_OK; } TEST_END(lseek_read) - TEST(write_small_file_chunks_1) { - int res = test_create_and_write_file("smallfile", 256, 1); - TEST_CHECK(res >= 0); - res = read_and_verify("smallfile"); - TEST_CHECK(res >= 0); + int res = test_create_and_write_file("smallfile", 256, 1); + TEST_CHECK(res >= 0); + res = read_and_verify("smallfile"); + TEST_CHECK(res >= 0); - return TEST_RES_OK; + return TEST_RES_OK; } TEST_END(write_small_file_chunks_1) - TEST(write_small_files_chunks_1) { - char name[32]; - int f; - int size = 512; - int files = ((20*(FS)->cfg.phys_size)/100)/size; - int res; - for (f = 0; f < files; f++) { - sprintf(name, "smallfile%i", f); - res = test_create_and_write_file(name, size, 1); - TEST_CHECK(res >= 0); - } - for (f = 0; f < files; f++) { - sprintf(name, "smallfile%i", f); - res = read_and_verify(name); - TEST_CHECK(res >= 0); - } - - return TEST_RES_OK; + char name[32]; + int f; + int size = 512; + int files = ((20 * (FS)->cfg.phys_size) / 100) / size; + int res; + for (f = 0; f < files; f++) + { + sprintf(name, "smallfile%i", f); + res = test_create_and_write_file(name, size, 1); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files; f++) + { + sprintf(name, "smallfile%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + + return TEST_RES_OK; } TEST_END(write_small_files_chunks_1) TEST(write_big_file_chunks_1) { - int size = ((50*(FS)->cfg.phys_size)/100); - printf(" filesize %i\n", size); - int res = test_create_and_write_file("bigfile", size, 1); - TEST_CHECK(res >= 0); - res = read_and_verify("bigfile"); - TEST_CHECK(res >= 0); - - return TEST_RES_OK; + int size = ((50 * (FS)->cfg.phys_size) / 100); + printf(" filesize %i\n", size); + int res = test_create_and_write_file("bigfile", size, 1); + TEST_CHECK(res >= 0); + res = read_and_verify("bigfile"); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; } TEST_END(write_big_file_chunks_1) TEST(write_big_files_chunks_1) { - char name[32]; - int f; - int files = 10; - int res; - int size = ((50*(FS)->cfg.phys_size)/100)/files; - printf(" filesize %i\n", size); - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = test_create_and_write_file(name, size, 1); - TEST_CHECK(res >= 0); - } - for (f = 0; f < files; f++) { - sprintf(name, "bigfile%i", f); - res = read_and_verify(name); - TEST_CHECK(res >= 0); - } - - return TEST_RES_OK; + char name[32]; + int f; + int files = 10; + int res; + int size = ((50 * (FS)->cfg.phys_size) / 100) / files; + printf(" filesize %i\n", size); + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = test_create_and_write_file(name, size, 1); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files; f++) + { + sprintf(name, "bigfile%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + + return TEST_RES_OK; } TEST_END(write_big_files_chunks_1) - TEST(long_run_config_many_small_one_long) { - tfile_conf cfgs[] = { - { .tsize = LARGE, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = LONG - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = LONG - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = LONG - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = LONG - }, - }; - - int res = run_file_config(sizeof(cfgs)/sizeof(cfgs[0]), &cfgs[0], 206, 5, 0); - TEST_CHECK(res >= 0); - return TEST_RES_OK; + tfile_conf cfgs[] = { + {.tsize = LARGE, .ttype = MODIFIED, .tlife = LONG}, {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = LONG}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = LONG}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = LONG}, {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = LONG}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = LONG}, + }; + + int res = run_file_config(sizeof(cfgs) / sizeof(cfgs[0]), &cfgs[0], 206, 5, 0); + TEST_CHECK(res >= 0); + return TEST_RES_OK; } TEST_END(long_run_config_many_small_one_long) TEST(long_run_config_many_medium) { - tfile_conf cfgs[] = { - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = LARGE, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = LARGE, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = LARGE, .ttype = MODIFIED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG - }, - }; - - int res = run_file_config(sizeof(cfgs)/sizeof(cfgs[0]), &cfgs[0], 305, 5, 0); - TEST_CHECK(res >= 0); - return TEST_RES_OK; + tfile_conf cfgs[] = { + {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG}, {.tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG}, + {.tsize = LARGE, .ttype = MODIFIED, .tlife = LONG}, {.tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG}, + {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG}, {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG}, + {.tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG}, {.tsize = LARGE, .ttype = MODIFIED, .tlife = LONG}, + {.tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG}, {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG}, + {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG}, {.tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG}, + {.tsize = LARGE, .ttype = MODIFIED, .tlife = LONG}, {.tsize = MEDIUM, .ttype = APPENDED, .tlife = LONG}, + {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = LONG}, + }; + + int res = run_file_config(sizeof(cfgs) / sizeof(cfgs[0]), &cfgs[0], 305, 5, 0); + TEST_CHECK(res >= 0); + return TEST_RES_OK; } TEST_END(long_run_config_many_medium) - TEST(long_run_config_many_small) { - tfile_conf cfgs[] = { - { .tsize = SMALL, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = LONG - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM - }, - { .tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT - }, - }; - - int res = run_file_config(sizeof(cfgs)/sizeof(cfgs[0]), &cfgs[0], 115, 6, 0); - TEST_CHECK(res >= 0); - return TEST_RES_OK; + tfile_conf cfgs[] = { + {.tsize = SMALL, .ttype = APPENDED, .tlife = LONG}, {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT}, {.tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = APPENDED, .tlife = SHORT}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT}, {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT}, {.tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = APPENDED, .tlife = SHORT}, {.tsize = SMALL, .ttype = APPENDED, .tlife = LONG}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT}, + {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT}, + {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = MODIFIED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = MODIFIED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT}, + {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = SMALL, .ttype = UNTAMPERED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = APPENDED, .tlife = SHORT}, + {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = MEDIUM}, {.tsize = EMPTY, .ttype = UNTAMPERED, .tlife = SHORT}, + }; + + int res = run_file_config(sizeof(cfgs) / sizeof(cfgs[0]), &cfgs[0], 115, 6, 0); + TEST_CHECK(res >= 0); + return TEST_RES_OK; } TEST_END(long_run_config_many_small) - TEST(long_run) { - tfile_conf cfgs[] = { - { .tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM - }, - { .tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT - }, - { .tsize = MEDIUM, .ttype = MODIFIED, .tlife = SHORT - }, - { .tsize = MEDIUM, .ttype = APPENDED, .tlife = SHORT - }, - }; - - int macro_runs = 500; - printf(" "); - u32_t clob_size = SPIFFS_CFG_PHYS_SZ(FS)/4; - int res = test_create_and_write_file("long_clobber", clob_size, clob_size); - TEST_CHECK(res >= 0); - - res = read_and_verify("long_clobber"); - TEST_CHECK(res >= 0); - - while (macro_runs--) { - //printf(" ---- run %i ----\n", macro_runs); - if ((macro_runs % 20) == 0) { - printf("."); - fflush(stdout); - } - res = run_file_config(sizeof(cfgs)/sizeof(cfgs[0]), &cfgs[0], 11, 2, 0); + tfile_conf cfgs[] = { + {.tsize = EMPTY, .ttype = APPENDED, .tlife = MEDIUM}, + {.tsize = SMALL, .ttype = REWRITTEN, .tlife = SHORT}, + {.tsize = MEDIUM, .ttype = MODIFIED, .tlife = SHORT}, + {.tsize = MEDIUM, .ttype = APPENDED, .tlife = SHORT}, + }; + + int macro_runs = 500; + printf(" "); + u32_t clob_size = SPIFFS_CFG_PHYS_SZ(FS) / 4; + int res = test_create_and_write_file("long_clobber", clob_size, clob_size); + TEST_CHECK(res >= 0); + + res = read_and_verify("long_clobber"); TEST_CHECK(res >= 0); - } - printf("\n"); - res = read_and_verify("long_clobber"); - TEST_CHECK(res >= 0); + while (macro_runs--) + { + // printf(" ---- run %i ----\n", macro_runs); + if ((macro_runs % 20) == 0) + { + printf("."); + fflush(stdout); + } + res = run_file_config(sizeof(cfgs) / sizeof(cfgs[0]), &cfgs[0], 11, 2, 0); + TEST_CHECK(res >= 0); + } + printf("\n"); + + res = read_and_verify("long_clobber"); + TEST_CHECK(res >= 0); - res = SPIFFS_check(FS); - TEST_CHECK(res >= 0); + res = SPIFFS_check(FS); + TEST_CHECK(res >= 0); - return TEST_RES_OK; + return TEST_RES_OK; } TEST_END(long_run) SUITE_END(hydrogen_tests) - diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_spiffs.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_spiffs.c index 2033566..4e14100 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_spiffs.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/test_spiffs.c @@ -5,25 +5,22 @@ * Author: petera */ +#include "test_spiffs.h" +#include +#include #include #include #include +#include +#include +#include #include "params_test.h" #include "spiffs.h" #include "spiffs_nucleus.h" - #include "testrunner.h" -#include "test_spiffs.h" - -#include -#include -#include -#include -#include - static unsigned char area[PHYS_FLASH_SIZE]; static int erases[256]; @@ -40,7 +37,7 @@ static char log_flash_ops = 1; static u32_t fs_check_fixes = 0; spiffs __fs; -static u8_t _work[LOG_PAGE*2]; +static u8_t _work[LOG_PAGE * 2]; static u8_t _fds[FD_BUF_SIZE]; static u8_t _cache[CACHE_BUF_SIZE]; @@ -48,499 +45,580 @@ static int check_valid_flash = 1; #define TEST_PATH "test_data/" -char *make_test_fname(const char *name) { - sprintf(_path, "%s%s", TEST_PATH, name); - return _path; +char *make_test_fname(const char *name) +{ + sprintf(_path, "%s%s", TEST_PATH, name); + return _path; +} + +void clear_test_path() +{ + DIR *dp; + struct dirent *ep; + dp = opendir(TEST_PATH); + + if (dp != NULL) + { + while ((ep = readdir(dp))) + { + if (ep->d_name[0] != '.') + { + sprintf(_path, "%s%s", TEST_PATH, ep->d_name); + remove(_path); + } + } + closedir(dp); + } } -void clear_test_path() { - DIR *dp; - struct dirent *ep; - dp = opendir(TEST_PATH); - - if (dp != NULL) { - while ((ep = readdir(dp))) { - if (ep->d_name[0] != '.') { - sprintf(_path, "%s%s", TEST_PATH, ep->d_name); - remove(_path); - } +static s32_t _read(u32_t addr, u32_t size, u8_t *dst) +{ + if (log_flash_ops) + { + bytes_rd += size; + reads++; + if (error_after_bytes_read > 0 && bytes_rd >= error_after_bytes_read) + { + if (error_after_bytes_read_once_only) + { + error_after_bytes_read = 0; + } + return SPIFFS_ERR_TEST; + } + } + if (addr < __fs.cfg.phys_addr) + { + printf("FATAL read addr too low %08x < %08x\n", addr, SPIFFS_PHYS_ADDR); + exit(0); + } + if (addr + size > __fs.cfg.phys_addr + __fs.cfg.phys_size) + { + printf("FATAL read addr too high %08x + %08x > %08x\n", addr, size, SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE); + exit(0); } - closedir(dp); - } + memcpy(dst, &area[addr], size); + return 0; } -static s32_t _read(u32_t addr, u32_t size, u8_t *dst) { - if (log_flash_ops) { - bytes_rd += size; - reads++; - if (error_after_bytes_read > 0 && bytes_rd >= error_after_bytes_read) { - if (error_after_bytes_read_once_only) { - error_after_bytes_read = 0; - } - return SPIFFS_ERR_TEST; +static s32_t _write(u32_t addr, u32_t size, u8_t *src) +{ + int i; + // printf("wr %08x %i\n", addr, size); + if (log_flash_ops) + { + bytes_wr += size; + writes++; + if (error_after_bytes_written > 0 && bytes_wr >= error_after_bytes_written) + { + if (error_after_bytes_written_once_only) + { + error_after_bytes_written = 0; + } + return SPIFFS_ERR_TEST; + } } - } - if (addr < __fs.cfg.phys_addr) { - printf("FATAL read addr too low %08x < %08x\n", addr, SPIFFS_PHYS_ADDR); - exit(0); - } - if (addr + size > __fs.cfg.phys_addr + __fs.cfg.phys_size) { - printf("FATAL read addr too high %08x + %08x > %08x\n", addr, size, SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE); - exit(0); - } - memcpy(dst, &area[addr], size); - return 0; -} -static s32_t _write(u32_t addr, u32_t size, u8_t *src) { - int i; - //printf("wr %08x %i\n", addr, size); - if (log_flash_ops) { - bytes_wr += size; - writes++; - if (error_after_bytes_written > 0 && bytes_wr >= error_after_bytes_written) { - if (error_after_bytes_written_once_only) { - error_after_bytes_written = 0; - } - return SPIFFS_ERR_TEST; + if (addr < __fs.cfg.phys_addr) + { + printf("FATAL write addr too low %08x < %08x\n", addr, SPIFFS_PHYS_ADDR); + exit(0); } - } - - if (addr < __fs.cfg.phys_addr) { - printf("FATAL write addr too low %08x < %08x\n", addr, SPIFFS_PHYS_ADDR); - exit(0); - } - if (addr + size > __fs.cfg.phys_addr + __fs.cfg.phys_size) { - printf("FATAL write addr too high %08x + %08x > %08x\n", addr, size, SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE); - exit(0); - } - - for (i = 0; i < size; i++) { - if (((addr + i) & (__fs.cfg.log_page_size-1)) != offsetof(spiffs_page_header, flags)) { - if (check_valid_flash && ((area[addr + i] ^ src[i]) & src[i])) { - printf("trying to write %02x to %02x at addr %08x\n", src[i], area[addr + i], addr+i); - spiffs_page_ix pix = (addr + i) / LOG_PAGE; - dump_page(&__fs, pix); - return -1; - } + if (addr + size > __fs.cfg.phys_addr + __fs.cfg.phys_size) + { + printf("FATAL write addr too high %08x + %08x > %08x\n", addr, size, SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE); + exit(0); } - area[addr + i] &= src[i]; - } - return 0; -} -static s32_t _erase(u32_t addr, u32_t size) { - if (addr & (__fs.cfg.phys_erase_block-1)) { - printf("trying to erase at addr %08x, out of boundary\n", addr); - return -1; - } - if (size & (__fs.cfg.phys_erase_block-1)) { - printf("trying to erase at with size %08x, out of boundary\n", size); - return -1; - } - erases[(addr-__fs.cfg.phys_addr)/__fs.cfg.phys_erase_block]++; - memset(&area[addr], 0xff, size); - return 0; + for (i = 0; i < size; i++) + { + if (((addr + i) & (__fs.cfg.log_page_size - 1)) != offsetof(spiffs_page_header, flags)) + { + if (check_valid_flash && ((area[addr + i] ^ src[i]) & src[i])) + { + printf("trying to write %02x to %02x at addr %08x\n", src[i], area[addr + i], addr + i); + spiffs_page_ix pix = (addr + i) / LOG_PAGE; + dump_page(&__fs, pix); + return -1; + } + } + area[addr + i] &= src[i]; + } + return 0; } -void hexdump_mem(u8_t *b, u32_t len) { - while (len--) { - if ((((intptr_t)b)&0x1f) == 0) { - printf("\n"); +static s32_t _erase(u32_t addr, u32_t size) +{ + if (addr & (__fs.cfg.phys_erase_block - 1)) + { + printf("trying to erase at addr %08x, out of boundary\n", addr); + return -1; + } + if (size & (__fs.cfg.phys_erase_block - 1)) + { + printf("trying to erase at with size %08x, out of boundary\n", size); + return -1; } - printf("%02x", *b++); - } - printf("\n"); + erases[(addr - __fs.cfg.phys_addr) / __fs.cfg.phys_erase_block]++; + memset(&area[addr], 0xff, size); + return 0; } -void hexdump(u32_t addr, u32_t len) { - int remainder = (addr % 32) == 0 ? 0 : 32 - (addr % 32); - u32_t a; - for (a = addr - remainder; a < addr+len; a++) { - if ((a & 0x1f) == 0) { - if (a != addr) { - printf(" "); - int j; - for (j = 0; j < 32; j++) { - if (a-32+j < addr) - printf(" "); - else { - printf("%c", (area[a-32+j] < 32 || area[a-32+j] >= 0x7f) ? '.' : area[a-32+j]); - } +void hexdump_mem(u8_t *b, u32_t len) +{ + while (len--) + { + if ((((intptr_t)b) & 0x1f) == 0) + { + printf("\n"); } - } - printf("%s %08x: ", a<=addr ? "":"\n", a); + printf("%02x", *b++); } - if (a < addr) { - printf(" "); - } else { - printf("%02x", area[a]); + printf("\n"); +} + +void hexdump(u32_t addr, u32_t len) +{ + int remainder = (addr % 32) == 0 ? 0 : 32 - (addr % 32); + u32_t a; + for (a = addr - remainder; a < addr + len; a++) + { + if ((a & 0x1f) == 0) + { + if (a != addr) + { + printf(" "); + int j; + for (j = 0; j < 32; j++) + { + if (a - 32 + j < addr) + printf(" "); + else + { + printf("%c", (area[a - 32 + j] < 32 || area[a - 32 + j] >= 0x7f) ? '.' : area[a - 32 + j]); + } + } + } + printf("%s %08x: ", a <= addr ? "" : "\n", a); + } + if (a < addr) + { + printf(" "); + } + else + { + printf("%02x", area[a]); + } } - } - int j; - printf(" "); - for (j = 0; j < 32; j++) { - if (a-32+j < addr) - printf(" "); - else { - printf("%c", (area[a-32+j] < 32 || area[a-32+j] >= 0x7f) ? '.' : area[a-32+j]); + int j; + printf(" "); + for (j = 0; j < 32; j++) + { + if (a - 32 + j < addr) + printf(" "); + else + { + printf("%c", (area[a - 32 + j] < 32 || area[a - 32 + j] >= 0x7f) ? '.' : area[a - 32 + j]); + } } - } - printf("\n"); + printf("\n"); } -void dump_page(spiffs *fs, spiffs_page_ix p) { - printf("page %04x ", p); - u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, p); - if (p % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // obj lu page - printf("OBJ_LU"); - } else { - u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , p)) + - SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, p) * sizeof(spiffs_obj_id); - spiffs_obj_id obj_id = *((spiffs_obj_id *)&area[obj_id_addr]); - // data page - spiffs_page_header *ph = (spiffs_page_header *)&area[addr]; - printf("DATA %04x:%04x ", obj_id, ph->span_ix); - printf("%s", ((ph->flags & SPIFFS_PH_FLAG_FINAL) == 0) ? "FIN " : "fin "); - printf("%s", ((ph->flags & SPIFFS_PH_FLAG_DELET) == 0) ? "DEL " : "del "); - printf("%s", ((ph->flags & SPIFFS_PH_FLAG_INDEX) == 0) ? "IDX " : "idx "); - printf("%s", ((ph->flags & SPIFFS_PH_FLAG_USED) == 0) ? "USD " : "usd "); - printf("%s ", ((ph->flags & SPIFFS_PH_FLAG_IXDELE) == 0) ? "IDL " : "idl "); - if (obj_id & SPIFFS_OBJ_ID_IX_FLAG) { - // object index - printf("OBJ_IX"); - if (ph->span_ix == 0) { - printf("_HDR "); - spiffs_page_object_ix_header *oix_hdr = (spiffs_page_object_ix_header *)&area[addr]; - printf("'%s' %i bytes type:%02x", oix_hdr->name, oix_hdr->size, oix_hdr->type); - } - } else { - // data page - printf("CONTENT"); +void dump_page(spiffs *fs, spiffs_page_ix p) +{ + printf("page %04x ", p); + u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, p); + if (p % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) + { + // obj lu page + printf("OBJ_LU"); + } + else + { + u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, p)) + + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, p) * sizeof(spiffs_obj_id); + spiffs_obj_id obj_id = *((spiffs_obj_id *)&area[obj_id_addr]); + // data page + spiffs_page_header *ph = (spiffs_page_header *)&area[addr]; + printf("DATA %04x:%04x ", obj_id, ph->span_ix); + printf("%s", ((ph->flags & SPIFFS_PH_FLAG_FINAL) == 0) ? "FIN " : "fin "); + printf("%s", ((ph->flags & SPIFFS_PH_FLAG_DELET) == 0) ? "DEL " : "del "); + printf("%s", ((ph->flags & SPIFFS_PH_FLAG_INDEX) == 0) ? "IDX " : "idx "); + printf("%s", ((ph->flags & SPIFFS_PH_FLAG_USED) == 0) ? "USD " : "usd "); + printf("%s ", ((ph->flags & SPIFFS_PH_FLAG_IXDELE) == 0) ? "IDL " : "idl "); + if (obj_id & SPIFFS_OBJ_ID_IX_FLAG) + { + // object index + printf("OBJ_IX"); + if (ph->span_ix == 0) + { + printf("_HDR "); + spiffs_page_object_ix_header *oix_hdr = (spiffs_page_object_ix_header *)&area[addr]; + printf("'%s' %i bytes type:%02x", oix_hdr->name, oix_hdr->size, oix_hdr->type); + } + } + else + { + // data page + printf("CONTENT"); + } } - } - printf("\n"); - u32_t len = fs->cfg.log_page_size; - hexdump(addr, len); + printf("\n"); + u32_t len = fs->cfg.log_page_size; + hexdump(addr, len); } -void area_write(u32_t addr, u8_t *buf, u32_t size) { - int i; - for (i = 0; i < size; i++) { - area[addr + i] = *buf++; - } +void area_write(u32_t addr, u8_t *buf, u32_t size) +{ + int i; + for (i = 0; i < size; i++) { area[addr + i] = *buf++; } } -void area_read(u32_t addr, u8_t *buf, u32_t size) { - int i; - for (i = 0; i < size; i++) { - *buf++ = area[addr + i]; - } +void area_read(u32_t addr, u8_t *buf, u32_t size) +{ + int i; + for (i = 0; i < size; i++) { *buf++ = area[addr + i]; } } -void dump_erase_counts(spiffs *fs) { - spiffs_block_ix bix; - printf(" BLOCK |\n"); - printf(" AGE COUNT|\n"); - for (bix = 0; bix < fs->block_count; bix++) { - printf("----%3i ----|", bix); - } - printf("\n"); - for (bix = 0; bix < fs->block_count; bix++) { - spiffs_obj_id erase_mark; - _spiffs_rd(fs, 0, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), sizeof(spiffs_obj_id), (u8_t *)&erase_mark); - if (erases[bix] == 0) { - printf(" |"); - } else { - printf("%7i %4i|", (fs->max_erase_count - erase_mark), erases[bix]); +void dump_erase_counts(spiffs *fs) +{ + spiffs_block_ix bix; + printf(" BLOCK |\n"); + printf(" AGE COUNT|\n"); + for (bix = 0; bix < fs->block_count; bix++) { printf("----%3i ----|", bix); } + printf("\n"); + for (bix = 0; bix < fs->block_count; bix++) + { + spiffs_obj_id erase_mark; + _spiffs_rd(fs, 0, 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix), sizeof(spiffs_obj_id), (u8_t *)&erase_mark); + if (erases[bix] == 0) + { + printf(" |"); + } + else + { + printf("%7i %4i|", (fs->max_erase_count - erase_mark), erases[bix]); + } } - } - printf("\n"); + printf("\n"); } -void dump_flash_access_stats() { - printf(" RD: %10i reads %10i bytes %10i avg bytes/read\n", reads, bytes_rd, reads == 0 ? 0 : (bytes_rd / reads)); - printf(" WR: %10i writes %10i bytes %10i avg bytes/write\n", writes, bytes_wr, writes == 0 ? 0 : (bytes_wr / writes)); +void dump_flash_access_stats() +{ + printf(" RD: %10i reads %10i bytes %10i avg bytes/read\n", reads, bytes_rd, reads == 0 ? 0 : (bytes_rd / reads)); + printf(" WR: %10i writes %10i bytes %10i avg bytes/write\n", writes, bytes_wr, + writes == 0 ? 0 : (bytes_wr / writes)); } - static u32_t old_perc = 999; -static void spiffs_check_cb_f(spiffs_check_type type, spiffs_check_report report, - u32_t arg1, u32_t arg2) { -/* if (report == SPIFFS_CHECK_PROGRESS && old_perc != arg1) { - old_perc = arg1; - printf("CHECK REPORT: "); - switch(type) { - case SPIFFS_CHECK_LOOKUP: - printf("LU "); break; - case SPIFFS_CHECK_INDEX: - printf("IX "); break; - case SPIFFS_CHECK_PAGE: - printf("PA "); break; - } - printf("%i%%\n", arg1 * 100 / 256); - }*/ - if (report != SPIFFS_CHECK_PROGRESS) { - if (report != SPIFFS_CHECK_ERROR) fs_check_fixes++; - printf(" check: "); - switch (type) { - case SPIFFS_CHECK_INDEX: - printf("INDEX "); break; - case SPIFFS_CHECK_LOOKUP: - printf("LOOKUP "); break; - case SPIFFS_CHECK_PAGE: - printf("PAGE "); break; - default: - printf("???? "); break; - } - if (report == SPIFFS_CHECK_ERROR) { - printf("ERROR %i", arg1); - } else if (report == SPIFFS_CHECK_DELETE_BAD_FILE) { - printf("DELETE BAD FILE %04x", arg1); - } else if (report == SPIFFS_CHECK_DELETE_ORPHANED_INDEX) { - printf("DELETE ORPHANED INDEX %04x", arg1); - } else if (report == SPIFFS_CHECK_DELETE_PAGE) { - printf("DELETE PAGE %04x", arg1); - } else if (report == SPIFFS_CHECK_FIX_INDEX) { - printf("FIX INDEX %04x:%04x", arg1, arg2); - } else if (report == SPIFFS_CHECK_FIX_LOOKUP) { - printf("FIX INDEX %04x:%04x", arg1, arg2); - } else { - printf("??"); +static void spiffs_check_cb_f(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2) +{ + /* if (report == SPIFFS_CHECK_PROGRESS && old_perc != arg1) { + old_perc = arg1; + printf("CHECK REPORT: "); + switch(type) { + case SPIFFS_CHECK_LOOKUP: + printf("LU "); break; + case SPIFFS_CHECK_INDEX: + printf("IX "); break; + case SPIFFS_CHECK_PAGE: + printf("PA "); break; + } + printf("%i%%\n", arg1 * 100 / 256); + }*/ + if (report != SPIFFS_CHECK_PROGRESS) + { + if (report != SPIFFS_CHECK_ERROR) + fs_check_fixes++; + printf(" check: "); + switch (type) + { + case SPIFFS_CHECK_INDEX: + printf("INDEX "); + break; + case SPIFFS_CHECK_LOOKUP: + printf("LOOKUP "); + break; + case SPIFFS_CHECK_PAGE: + printf("PAGE "); + break; + default: + printf("???? "); + break; + } + if (report == SPIFFS_CHECK_ERROR) + { + printf("ERROR %i", arg1); + } + else if (report == SPIFFS_CHECK_DELETE_BAD_FILE) + { + printf("DELETE BAD FILE %04x", arg1); + } + else if (report == SPIFFS_CHECK_DELETE_ORPHANED_INDEX) + { + printf("DELETE ORPHANED INDEX %04x", arg1); + } + else if (report == SPIFFS_CHECK_DELETE_PAGE) + { + printf("DELETE PAGE %04x", arg1); + } + else if (report == SPIFFS_CHECK_FIX_INDEX) + { + printf("FIX INDEX %04x:%04x", arg1, arg2); + } + else if (report == SPIFFS_CHECK_FIX_LOOKUP) + { + printf("FIX INDEX %04x:%04x", arg1, arg2); + } + else + { + printf("??"); + } + printf("\n"); } - printf("\n"); - } } -void fs_reset_specific(u32_t phys_addr, u32_t phys_size, - u32_t phys_sector_size, - u32_t log_block_size, u32_t log_page_size) { - memset(area, 0xcc, sizeof(area)); - memset(&area[phys_addr], 0xff, phys_size); - - spiffs_config c; - c.hal_erase_f = _erase; - c.hal_read_f = _read; - c.hal_write_f = _write; - c.log_block_size = log_block_size; - c.log_page_size = log_page_size; - c.phys_addr = phys_addr; - c.phys_erase_block = phys_sector_size; - c.phys_size = phys_size; - - memset(erases,0,sizeof(erases)); - memset(_cache,0,sizeof(_cache)); - - SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f); - - clear_flash_ops_log(); - log_flash_ops = 1; - fs_check_fixes = 0; -} +void fs_reset_specific(u32_t phys_addr, u32_t phys_size, u32_t phys_sector_size, u32_t log_block_size, + u32_t log_page_size) +{ + memset(area, 0xcc, sizeof(area)); + memset(&area[phys_addr], 0xff, phys_size); -void fs_reset() { - fs_reset_specific(SPIFFS_PHYS_ADDR, SPIFFS_FLASH_SIZE, SECTOR_SIZE, LOG_BLOCK, LOG_PAGE); -} + spiffs_config c; + c.hal_erase_f = _erase; + c.hal_read_f = _read; + c.hal_write_f = _write; + c.log_block_size = log_block_size; + c.log_page_size = log_page_size; + c.phys_addr = phys_addr; + c.phys_erase_block = phys_sector_size; + c.phys_size = phys_size; -void set_flash_ops_log(int enable) { - log_flash_ops = enable; -} + memset(erases, 0, sizeof(erases)); + memset(_cache, 0, sizeof(_cache)); -void clear_flash_ops_log() { - bytes_rd = 0; - bytes_wr = 0; - reads = 0; - writes = 0; - error_after_bytes_read = 0; - error_after_bytes_written = 0; -} + SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f); -u32_t get_flash_ops_log_read_bytes() { - return bytes_rd; + clear_flash_ops_log(); + log_flash_ops = 1; + fs_check_fixes = 0; } -u32_t get_flash_ops_log_write_bytes() { - return bytes_wr; -} +void fs_reset() { fs_reset_specific(SPIFFS_PHYS_ADDR, SPIFFS_FLASH_SIZE, SECTOR_SIZE, LOG_BLOCK, LOG_PAGE); } -void invoke_error_after_read_bytes(u32_t b, char once_only) { - error_after_bytes_read = b; - error_after_bytes_read_once_only = once_only; -} -void invoke_error_after_write_bytes(u32_t b, char once_only) { - error_after_bytes_written = b; - error_after_bytes_written_once_only = once_only; -} +void set_flash_ops_log(int enable) { log_flash_ops = enable; } -void fs_set_validate_flashing(int i) { - check_valid_flash = i; +void clear_flash_ops_log() +{ + bytes_rd = 0; + bytes_wr = 0; + reads = 0; + writes = 0; + error_after_bytes_read = 0; + error_after_bytes_written = 0; } -void real_assert(int c, const char *n, const char *file, int l) { - if (c == 0) { - printf("ASSERT: %s %s @ %i\n", (n ? n : ""), file, l); - printf("fs errno:%i\n", __fs.err_code); - exit(0); - } +u32_t get_flash_ops_log_read_bytes() { return bytes_rd; } + +u32_t get_flash_ops_log_write_bytes() { return bytes_wr; } + +void invoke_error_after_read_bytes(u32_t b, char once_only) +{ + error_after_bytes_read = b; + error_after_bytes_read_once_only = once_only; } +void invoke_error_after_write_bytes(u32_t b, char once_only) +{ + error_after_bytes_written = b; + error_after_bytes_written_once_only = once_only; +} + +void fs_set_validate_flashing(int i) { check_valid_flash = i; } -int read_and_verify(char *name) { - s32_t res; - int fd = SPIFFS_open(&__fs, name, SPIFFS_RDONLY, 0); - if (fd < 0) { - printf(" read_and_verify: could not open file %s\n", name); - return fd; - } - return read_and_verify_fd(fd, name); +void real_assert(int c, const char *n, const char *file, int l) +{ + if (c == 0) + { + printf("ASSERT: %s %s @ %i\n", (n ? n : ""), file, l); + printf("fs errno:%i\n", __fs.err_code); + exit(0); + } } -int read_and_verify_fd(spiffs_file fd, char *name) { - s32_t res; - int pfd = open(make_test_fname(name), O_RDONLY); - spiffs_stat s; - res = SPIFFS_fstat(&__fs, fd, &s); - if (res < 0) { - printf(" read_and_verify: could not stat file %s\n", name); - return res; - } - if (s.size == 0) { - SPIFFS_close(&__fs, fd); - close(pfd); - return 0; - } - - //printf("verifying %s, len %i\n", name, s.size); - int offs = 0; - u8_t buf_d[256]; - u8_t buf_v[256]; - while (offs < s.size) { - int read_len = MIN(s.size - offs, sizeof(buf_d)); - res = SPIFFS_read(&__fs, fd, buf_d, read_len); - if (res < 0) { - printf(" read_and_verify: could not read file %s offs:%i len:%i filelen:%i\n", name, offs, read_len, s.size); - return res; +int read_and_verify(char *name) +{ + s32_t res; + int fd = SPIFFS_open(&__fs, name, SPIFFS_RDONLY, 0); + if (fd < 0) + { + printf(" read_and_verify: could not open file %s\n", name); + return fd; } - int pres = read(pfd, buf_v, read_len); - (void)pres; - //printf("reading offs:%i len:%i spiffs_res:%i posix_res:%i\n", offs, read_len, res, pres); - int i; - int veri_ok = 1; - for (i = 0; veri_ok && i < read_len; i++) { - if (buf_d[i] != buf_v[i]) { - printf("file verification mismatch @ %i, %02x %c != %02x %c\n", offs+i, buf_d[i], buf_d[i], buf_v[i], buf_v[i]); - int j = MAX(0, i-16); - int k = MIN(sizeof(buf_d), i+16); - k = MIN(s.size-offs, k); - int l; - for (l = j; l < k; l++) { - printf("%c", buf_d[l] > 31 ? buf_d[l] : '.'); - } - printf("\n"); - for (l = j; l < k; l++) { - printf("%c", buf_v[l] > 31 ? buf_v[l] : '.'); - } - printf("\n"); - veri_ok = 0; - } + return read_and_verify_fd(fd, name); +} + +int read_and_verify_fd(spiffs_file fd, char *name) +{ + s32_t res; + int pfd = open(make_test_fname(name), O_RDONLY); + spiffs_stat s; + res = SPIFFS_fstat(&__fs, fd, &s); + if (res < 0) + { + printf(" read_and_verify: could not stat file %s\n", name); + return res; } - if (!veri_ok) { - SPIFFS_close(&__fs, fd); - close(pfd); - printf("data mismatch\n"); - return -1; + if (s.size == 0) + { + SPIFFS_close(&__fs, fd); + close(pfd); + return 0; } - offs += read_len; - } + // printf("verifying %s, len %i\n", name, s.size); + int offs = 0; + u8_t buf_d[256]; + u8_t buf_v[256]; + while (offs < s.size) + { + int read_len = MIN(s.size - offs, sizeof(buf_d)); + res = SPIFFS_read(&__fs, fd, buf_d, read_len); + if (res < 0) + { + printf( + " read_and_verify: could not read file %s offs:%i len:%i " + "filelen:%i\n", + name, offs, read_len, s.size); + return res; + } + int pres = read(pfd, buf_v, read_len); + (void)pres; + // printf("reading offs:%i len:%i spiffs_res:%i posix_res:%i\n", offs, + // read_len, res, pres); + int i; + int veri_ok = 1; + for (i = 0; veri_ok && i < read_len; i++) + { + if (buf_d[i] != buf_v[i]) + { + printf("file verification mismatch @ %i, %02x %c != %02x %c\n", offs + i, buf_d[i], buf_d[i], buf_v[i], + buf_v[i]); + int j = MAX(0, i - 16); + int k = MIN(sizeof(buf_d), i + 16); + k = MIN(s.size - offs, k); + int l; + for (l = j; l < k; l++) { printf("%c", buf_d[l] > 31 ? buf_d[l] : '.'); } + printf("\n"); + for (l = j; l < k; l++) { printf("%c", buf_v[l] > 31 ? buf_v[l] : '.'); } + printf("\n"); + veri_ok = 0; + } + } + if (!veri_ok) + { + SPIFFS_close(&__fs, fd); + close(pfd); + printf("data mismatch\n"); + return -1; + } + + offs += read_len; + } - SPIFFS_close(&__fs, fd); - close(pfd); + SPIFFS_close(&__fs, fd); + close(pfd); - return 0; + return 0; } -static void test_on_stop(test *t) { - printf(" spiffs errno:%i\n", SPIFFS_errno(&__fs)); +static void test_on_stop(test *t) +{ + printf(" spiffs errno:%i\n", SPIFFS_errno(&__fs)); #if SPIFFS_TEST_VISUALISATION - SPIFFS_vis(FS); + SPIFFS_vis(FS); #endif - } -void memrand(u8_t *b, int len) { - int i; - for (i = 0; i < len; i++) { - b[i] = rand(); - } -} - -int test_create_file(char *name) { - spiffs_stat s; - spiffs_file fd; - int res = SPIFFS_creat(FS, name, 0); - CHECK_RES(res); - fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); - CHECK(fd >= 0); - res = SPIFFS_fstat(FS, fd, &s); - CHECK_RES(res); - CHECK(strcmp((char*)s.name, name) == 0); - CHECK(s.size == 0); - SPIFFS_close(FS, fd); - return 0; +void memrand(u8_t *b, int len) +{ + int i; + for (i = 0; i < len; i++) { b[i] = rand(); } +} + +int test_create_file(char *name) +{ + spiffs_stat s; + spiffs_file fd; + int res = SPIFFS_creat(FS, name, 0); + CHECK_RES(res); + fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); + CHECK(fd >= 0); + res = SPIFFS_fstat(FS, fd, &s); + CHECK_RES(res); + CHECK(strcmp((char *)s.name, name) == 0); + CHECK(s.size == 0); + SPIFFS_close(FS, fd); + return 0; } -int test_create_and_write_file(char *name, int size, int chunk_size) { - int res; - spiffs_file fd; - printf(" create and write %s", name); - res = test_create_file(name); - if (res < 0) { - printf(" failed creation, %i\n",res); - } - CHECK(res >= 0); - fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); - if (res < 0) { - printf(" failed open, %i\n",res); - } - CHECK(fd >= 0); - int pfd = open(make_test_fname(name), O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - int offset = 0; - int mark = 0; - while (offset < size) { - int len = MIN(size-offset, chunk_size); - if (offset > mark) { - mark += size/16; - printf("."); - fflush(stdout); +int test_create_and_write_file(char *name, int size, int chunk_size) +{ + int res; + spiffs_file fd; + printf(" create and write %s", name); + res = test_create_file(name); + if (res < 0) + { + printf(" failed creation, %i\n", res); + } + CHECK(res >= 0); + fd = SPIFFS_open(FS, name, SPIFFS_APPEND | SPIFFS_RDWR, 0); + if (res < 0) + { + printf(" failed open, %i\n", res); + } + CHECK(fd >= 0); + int pfd = open(make_test_fname(name), O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + int offset = 0; + int mark = 0; + while (offset < size) + { + int len = MIN(size - offset, chunk_size); + if (offset > mark) + { + mark += size / 16; + printf("."); + fflush(stdout); + } + u8_t *buf = malloc(len); + memrand(buf, len); + res = SPIFFS_write(FS, fd, buf, len); + write(pfd, buf, len); + free(buf); + if (res < 0) + { + printf("\n error @ offset %i, res %i\n", offset, res); + } + offset += len; + CHECK(res >= 0); } - u8_t *buf = malloc(len); - memrand(buf, len); - res = SPIFFS_write(FS, fd, buf, len); - write(pfd, buf, len); - free(buf); - if (res < 0) { - printf("\n error @ offset %i, res %i\n", offset, res); + printf("\n"); + close(pfd); + + spiffs_stat stat; + res = SPIFFS_fstat(FS, fd, &stat); + if (res < 0) + { + printf(" failed fstat, %i\n", res); } - offset += len; CHECK(res >= 0); - } - printf("\n"); - close(pfd); - - spiffs_stat stat; - res = SPIFFS_fstat(FS, fd, &stat); - if (res < 0) { - printf(" failed fstat, %i\n",res); - } - CHECK(res >= 0); - if (stat.size != size) { - printf(" failed size, %i != %i\n", stat.size, size); - } - CHECK(stat.size == size); - - SPIFFS_close(FS, fd); - return 0; + if (stat.size != size) + { + printf(" failed size, %i != %i\n", stat.size, size); + } + CHECK(stat.size == size); + + SPIFFS_close(FS, fd); + return 0; } #if SPIFFS_CACHE @@ -550,197 +628,221 @@ static u32_t cmiss_tot = 0; #endif #endif -void _setup_test_only() { - fs_set_validate_flashing(1); - test_init(test_on_stop); +void _setup_test_only() +{ + fs_set_validate_flashing(1); + test_init(test_on_stop); } -void _setup() { - fs_reset(); - _setup_test_only(); +void _setup() +{ + fs_reset(); + _setup_test_only(); } -void _teardown() { - printf(" free blocks : %i of %i\n", (FS)->free_blocks, (FS)->block_count); - printf(" pages allocated : %i\n", (FS)->stats_p_allocated); - printf(" pages deleted : %i\n", (FS)->stats_p_deleted); +void _teardown() +{ + printf(" free blocks : %i of %i\n", (FS)->free_blocks, (FS)->block_count); + printf(" pages allocated : %i\n", (FS)->stats_p_allocated); + printf(" pages deleted : %i\n", (FS)->stats_p_deleted); #if SPIFFS_GC_STATS - printf(" gc runs : %i\n", (FS)->stats_gc_runs); + printf(" gc runs : %i\n", (FS)->stats_gc_runs); #endif #if SPIFFS_CACHE #if SPIFFS_CACHE_STATS - chits_tot += (FS)->cache_hits; - cmiss_tot += (FS)->cache_misses; - printf(" cache hits : %i (sum %i)\n", (FS)->cache_hits, chits_tot); - printf(" cache misses : %i (sum %i)\n", (FS)->cache_misses, cmiss_tot); - printf(" cache utiliz : %f\n", ((float)chits_tot/(float)(chits_tot + cmiss_tot))); + chits_tot += (FS)->cache_hits; + cmiss_tot += (FS)->cache_misses; + printf(" cache hits : %i (sum %i)\n", (FS)->cache_hits, chits_tot); + printf(" cache misses : %i (sum %i)\n", (FS)->cache_misses, cmiss_tot); + printf(" cache utiliz : %f\n", ((float)chits_tot / (float)(chits_tot + cmiss_tot))); #endif #endif - dump_flash_access_stats(); - clear_flash_ops_log(); + dump_flash_access_stats(); + clear_flash_ops_log(); #if SPIFFS_GC_STATS - if ((FS)->stats_gc_runs > 0) + if ((FS)->stats_gc_runs > 0) #endif - dump_erase_counts(FS); - printf(" fs consistency check:\n"); - SPIFFS_check(FS); - clear_test_path(); - - //hexdump_mem(&area[SPIFFS_PHYS_ADDR - 16], 32); - //hexdump_mem(&area[SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE - 16], 32); -} - -u32_t tfile_get_size(tfile_size s) { - switch (s) { - case EMPTY: + dump_erase_counts(FS); + printf(" fs consistency check:\n"); + SPIFFS_check(FS); + clear_test_path(); + + // hexdump_mem(&area[SPIFFS_PHYS_ADDR - 16], 32); + // hexdump_mem(&area[SPIFFS_PHYS_ADDR + SPIFFS_FLASH_SIZE - 16], 32); +} + +u32_t tfile_get_size(tfile_size s) +{ + switch (s) + { + case EMPTY: + return 0; + case SMALL: + return SPIFFS_DATA_PAGE_SIZE(FS) / 2; + case MEDIUM: + return SPIFFS_DATA_PAGE_SIZE(FS) * (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS)); + case LARGE: + return (FS)->cfg.phys_size / 3; + } return 0; - case SMALL: - return SPIFFS_DATA_PAGE_SIZE(FS)/2; - case MEDIUM: - return SPIFFS_DATA_PAGE_SIZE(FS) * (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS)); - case LARGE: - return (FS)->cfg.phys_size/3; - } - return 0; } -int run_file_config(int cfg_count, tfile_conf* cfgs, int max_runs, int max_concurrent_files, int dbg) { - int res; - tfile *tfiles = malloc(sizeof(tfile) * max_concurrent_files); - memset(tfiles, 0, sizeof(tfile) * max_concurrent_files); - int run = 0; - int cur_config_ix = 0; - char name[32]; - while (run < max_runs) { - if (dbg) printf(" run %i/%i\n", run, max_runs); - int i; - for (i = 0; i < max_concurrent_files; i++) { - sprintf(name, "file%i_%i", (1+run), i); - tfile *tf = &tfiles[i]; - if (tf->state == 0 && cur_config_ix < cfg_count) { -// create a new file - strcpy(tf->name, name); - tf->state = 1; - tf->cfg = cfgs[cur_config_ix]; - int size = tfile_get_size(tf->cfg.tsize); - if (dbg) printf(" create new %s with cfg %i/%i, size %i\n", name, (1+cur_config_ix), cfg_count, size); - - if (tf->cfg.tsize == EMPTY) { - res = SPIFFS_creat(FS, name, 0); - CHECK_RES(res); - int pfd = open(make_test_fname(name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - close(pfd); - int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0; - spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_RDWR, 0); - CHECK(fd > 0); - tf->fd = fd; - } else { - int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0; - spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); - CHECK(fd > 0); - extra_flags = tf->cfg.ttype == APPENDED ? O_APPEND : 0; - int pfd = open(make_test_fname(name), extra_flags | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - tf->fd = fd; - u8_t *buf = malloc(size); - memrand(buf, size); - res = SPIFFS_write(FS, fd, buf, size); - CHECK_RES(res); - write(pfd, buf, size); - close(pfd); - free(buf); - res = read_and_verify(name); - CHECK_RES(res); - } - - cur_config_ix++; - } else if (tf->state > 0) { -// hande file lifecycle - switch (tf->cfg.ttype) { - case UNTAMPERED: { - break; - } - case APPENDED: { - if (dbg) printf(" appending %s\n", tf->name); - int size = SPIFFS_DATA_PAGE_SIZE(FS)*3; - u8_t *buf = malloc(size); - memrand(buf, size); - res = SPIFFS_write(FS, tf->fd, buf, size); - CHECK_RES(res); - int pfd = open(make_test_fname(tf->name), O_APPEND | O_RDWR); - write(pfd, buf, size); - close(pfd); - free(buf); - res = read_and_verify(tf->name); - CHECK_RES(res); - break; - } - case MODIFIED: { - if (dbg) printf(" modify %s\n", tf->name); - spiffs_stat stat; - res = SPIFFS_fstat(FS, tf->fd, &stat); - CHECK_RES(res); - int size = stat.size / tf->cfg.tlife + SPIFFS_DATA_PAGE_SIZE(FS)/3; - int offs = (stat.size / tf->cfg.tlife) * tf->state; - res = SPIFFS_lseek(FS, tf->fd, offs, SPIFFS_SEEK_SET); - CHECK_RES(res); - u8_t *buf = malloc(size); - memrand(buf, size); - res = SPIFFS_write(FS, tf->fd, buf, size); - CHECK_RES(res); - int pfd = open(make_test_fname(tf->name), O_RDWR); - lseek(pfd, offs, SEEK_SET); - write(pfd, buf, size); - close(pfd); - free(buf); - res = read_and_verify(tf->name); - CHECK_RES(res); - break; - } - case REWRITTEN: { - if (tf->fd > 0) { - SPIFFS_close(FS, tf->fd); - } - if (dbg) printf(" rewriting %s\n", tf->name); - spiffs_file fd = SPIFFS_open(FS, tf->name, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); - CHECK(fd > 0); - int pfd = open(make_test_fname(tf->name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - tf->fd = fd; - int size = tfile_get_size(tf->cfg.tsize); - u8_t *buf = malloc(size); - memrand(buf, size); - res = SPIFFS_write(FS, fd, buf, size); - CHECK_RES(res); - write(pfd, buf, size); - close(pfd); - free(buf); - res = read_and_verify(tf->name); - CHECK_RES(res); - break; - } - } - tf->state++; - if (tf->state > tf->cfg.tlife) { -// file outlived its time, kill it - if (tf->fd > 0) { - SPIFFS_close(FS, tf->fd); - } - if (dbg) printf(" removing %s\n", tf->name); - res = read_and_verify(tf->name); - CHECK_RES(res); - res = SPIFFS_remove(FS, tf->name); - CHECK_RES(res); - remove(make_test_fname(tf->name)); - memset(tf, 0, sizeof(tf)); +int run_file_config(int cfg_count, tfile_conf *cfgs, int max_runs, int max_concurrent_files, int dbg) +{ + int res; + tfile *tfiles = malloc(sizeof(tfile) * max_concurrent_files); + memset(tfiles, 0, sizeof(tfile) * max_concurrent_files); + int run = 0; + int cur_config_ix = 0; + char name[32]; + while (run < max_runs) + { + if (dbg) + printf(" run %i/%i\n", run, max_runs); + int i; + for (i = 0; i < max_concurrent_files; i++) + { + sprintf(name, "file%i_%i", (1 + run), i); + tfile *tf = &tfiles[i]; + if (tf->state == 0 && cur_config_ix < cfg_count) + { + // create a new file + strcpy(tf->name, name); + tf->state = 1; + tf->cfg = cfgs[cur_config_ix]; + int size = tfile_get_size(tf->cfg.tsize); + if (dbg) + printf(" create new %s with cfg %i/%i, size %i\n", name, (1 + cur_config_ix), cfg_count, size); + + if (tf->cfg.tsize == EMPTY) + { + res = SPIFFS_creat(FS, name, 0); + CHECK_RES(res); + int pfd = open(make_test_fname(name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + close(pfd); + int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0; + spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_RDWR, 0); + CHECK(fd > 0); + tf->fd = fd; + } + else + { + int extra_flags = tf->cfg.ttype == APPENDED ? SPIFFS_APPEND : 0; + spiffs_file fd = SPIFFS_open(FS, name, extra_flags | SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + CHECK(fd > 0); + extra_flags = tf->cfg.ttype == APPENDED ? O_APPEND : 0; + int pfd = open(make_test_fname(name), extra_flags | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + tf->fd = fd; + u8_t *buf = malloc(size); + memrand(buf, size); + res = SPIFFS_write(FS, fd, buf, size); + CHECK_RES(res); + write(pfd, buf, size); + close(pfd); + free(buf); + res = read_and_verify(name); + CHECK_RES(res); + } + + cur_config_ix++; + } + else if (tf->state > 0) + { + // hande file lifecycle + switch (tf->cfg.ttype) + { + case UNTAMPERED: + { + break; + } + case APPENDED: + { + if (dbg) + printf(" appending %s\n", tf->name); + int size = SPIFFS_DATA_PAGE_SIZE(FS) * 3; + u8_t *buf = malloc(size); + memrand(buf, size); + res = SPIFFS_write(FS, tf->fd, buf, size); + CHECK_RES(res); + int pfd = open(make_test_fname(tf->name), O_APPEND | O_RDWR); + write(pfd, buf, size); + close(pfd); + free(buf); + res = read_and_verify(tf->name); + CHECK_RES(res); + break; + } + case MODIFIED: + { + if (dbg) + printf(" modify %s\n", tf->name); + spiffs_stat stat; + res = SPIFFS_fstat(FS, tf->fd, &stat); + CHECK_RES(res); + int size = stat.size / tf->cfg.tlife + SPIFFS_DATA_PAGE_SIZE(FS) / 3; + int offs = (stat.size / tf->cfg.tlife) * tf->state; + res = SPIFFS_lseek(FS, tf->fd, offs, SPIFFS_SEEK_SET); + CHECK_RES(res); + u8_t *buf = malloc(size); + memrand(buf, size); + res = SPIFFS_write(FS, tf->fd, buf, size); + CHECK_RES(res); + int pfd = open(make_test_fname(tf->name), O_RDWR); + lseek(pfd, offs, SEEK_SET); + write(pfd, buf, size); + close(pfd); + free(buf); + res = read_and_verify(tf->name); + CHECK_RES(res); + break; + } + case REWRITTEN: + { + if (tf->fd > 0) + { + SPIFFS_close(FS, tf->fd); + } + if (dbg) + printf(" rewriting %s\n", tf->name); + spiffs_file fd = SPIFFS_open(FS, tf->name, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + CHECK(fd > 0); + int pfd = open(make_test_fname(tf->name), O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + tf->fd = fd; + int size = tfile_get_size(tf->cfg.tsize); + u8_t *buf = malloc(size); + memrand(buf, size); + res = SPIFFS_write(FS, fd, buf, size); + CHECK_RES(res); + write(pfd, buf, size); + close(pfd); + free(buf); + res = read_and_verify(tf->name); + CHECK_RES(res); + break; + } + } + tf->state++; + if (tf->state > tf->cfg.tlife) + { + // file outlived its time, kill it + if (tf->fd > 0) + { + SPIFFS_close(FS, tf->fd); + } + if (dbg) + printf(" removing %s\n", tf->name); + res = read_and_verify(tf->name); + CHECK_RES(res); + res = SPIFFS_remove(FS, tf->name); + CHECK_RES(res); + remove(make_test_fname(tf->name)); + memset(tf, 0, sizeof(tf)); + } + } } - } + run++; } - - run++; - } - free(tfiles); - return 0; + free(tfiles); + return 0; } - - - diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/testrunner.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/testrunner.c index ad4fd1f..a624f73 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/testrunner.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/testrunner.c @@ -5,171 +5,198 @@ * Author: petera */ +#include "testrunner.h" +#include +#include #include #include #include - -#include #include -#include -#include +#include #include -#include "testrunner.h" - -static struct { - test *tests; - test *_last_test; - int test_count; - void (*on_stop)(test *t); - test_res *failed; - test_res *failed_last; - test_res *stopped; - test_res *stopped_last; - FILE *spec; +static struct +{ + test *tests; + test *_last_test; + int test_count; + void (*on_stop)(test *t); + test_res *failed; + test_res *failed_last; + test_res *stopped; + test_res *stopped_last; + FILE *spec; } test_main; -void test_init(void (*on_stop)(test *t)) { - test_main.on_stop = on_stop; -} +void test_init(void (*on_stop)(test *t)) { test_main.on_stop = on_stop; } -static char check_spec(char *name) { - if (test_main.spec) { - fseek(test_main.spec, 0, SEEK_SET); - char *line = NULL; - size_t sz; - ssize_t read; - while ((read = getline(&line, &sz, test_main.spec)) != -1) { - if (strncmp(line, name, strlen(name)) == 0) { +static char check_spec(char *name) +{ + if (test_main.spec) + { + fseek(test_main.spec, 0, SEEK_SET); + char *line = NULL; + size_t sz; + ssize_t read; + while ((read = getline(&line, &sz, test_main.spec)) != -1) + { + if (strncmp(line, name, strlen(name)) == 0) + { + free(line); + return 1; + } + } free(line); + return 0; + } + else + { return 1; - } } - free(line); - return 0; - } else { - return 1; - } } -void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t)) { - if (f == 0) return; - if (!check_spec(name)) return; - DBGT("adding test %s\n", name); - test *t = malloc(sizeof(test)); - memset(t, 0, sizeof(test)); - t->f = f; - strcpy(t->name, name); - t->setup = setup; - t->teardown = teardown; - if (test_main.tests == 0) { - test_main.tests = t; - } else { - test_main._last_test->_next = t; - } - test_main._last_test = t; - test_main.test_count++; +void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t)) +{ + if (f == 0) + return; + if (!check_spec(name)) + return; + DBGT("adding test %s\n", name); + test *t = malloc(sizeof(test)); + memset(t, 0, sizeof(test)); + t->f = f; + strcpy(t->name, name); + t->setup = setup; + t->teardown = teardown; + if (test_main.tests == 0) + { + test_main.tests = t; + } + else + { + test_main._last_test->_next = t; + } + test_main._last_test = t; + test_main.test_count++; } -static void add_res(test *t, test_res **head, test_res **last) { - test_res *tr = malloc(sizeof(test_res)); - memset(tr,0,sizeof(test_res)); - strcpy(tr->name, t->name); - if (*head == 0) { - *head = tr; - } else { - (*last)->_next = tr; - } - *last = tr; +static void add_res(test *t, test_res **head, test_res **last) +{ + test_res *tr = malloc(sizeof(test_res)); + memset(tr, 0, sizeof(test_res)); + strcpy(tr->name, t->name); + if (*head == 0) + { + *head = tr; + } + else + { + (*last)->_next = tr; + } + *last = tr; } -static void dump_res(test_res **head) { - test_res *tr = (*head); - while (tr) { - test_res *next_tr = tr->_next; - printf(" %s\n", tr->name); - free(tr); - tr = next_tr; - } +static void dump_res(test_res **head) +{ + test_res *tr = (*head); + while (tr) + { + test_res *next_tr = tr->_next; + printf(" %s\n", tr->name); + free(tr); + tr = next_tr; + } } -void run_tests(int argc, char **args) { - memset(&test_main, 0, sizeof(test_main)); - if (argc > 1) { - printf("running tests from %s\n", args[1]); - FILE *fd = fopen(args[1], "r"); - if (fd == NULL) { - printf("%s not found\n", args[1]); - exit(EXIT_FAILURE); +void run_tests(int argc, char **args) +{ + memset(&test_main, 0, sizeof(test_main)); + if (argc > 1) + { + printf("running tests from %s\n", args[1]); + FILE *fd = fopen(args[1], "r"); + if (fd == NULL) + { + printf("%s not found\n", args[1]); + exit(EXIT_FAILURE); + } + test_main.spec = fd; } - test_main.spec = fd; - } - DBGT("adding suites...\n"); - add_suites(); - DBGT("%i tests added\n", test_main.test_count); - if (test_main.spec) { - fclose(test_main.spec); - } + DBGT("adding suites...\n"); + add_suites(); + DBGT("%i tests added\n", test_main.test_count); + if (test_main.spec) + { + fclose(test_main.spec); + } - if (test_main.test_count == 0) { - printf("No tests to run\n"); - return; - } + if (test_main.test_count == 0) + { + printf("No tests to run\n"); + return; + } - int fd_success = open("_tests_ok", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - int fd_bad = open("_tests_fail", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + int fd_success = open("_tests_ok", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + int fd_bad = open("_tests_fail", O_APPEND | O_TRUNC | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); - DBGT("running tests...\n"); - int ok = 0; - int failed = 0; - int stopped = 0; - test *cur_t = test_main.tests; - int i = 1; - while (cur_t) { - cur_t->setup(cur_t); - test *next_test = cur_t->_next; - DBGT("TEST %i/%i : running test %s\n", i, test_main.test_count, cur_t->name); - i++; - int res = cur_t->f(cur_t); - cur_t->teardown(cur_t); - int fd = res == TEST_RES_OK ? fd_success : fd_bad; - write(fd, cur_t->name, strlen(cur_t->name)); - write(fd, "\n", 1); - switch (res) { - case TEST_RES_OK: - ok++; - printf(" .. ok\n"); - break; - case TEST_RES_FAIL: - failed++; - printf(" .. FAILED\n"); - if (test_main.on_stop) test_main.on_stop(cur_t); - add_res(cur_t, &test_main.failed, &test_main.failed_last); - break; - case TEST_RES_ASSERT: - stopped++; - printf(" .. ABORTED\n"); - if (test_main.on_stop) test_main.on_stop(cur_t); - add_res(cur_t, &test_main.stopped, &test_main.stopped_last); - break; + DBGT("running tests...\n"); + int ok = 0; + int failed = 0; + int stopped = 0; + test *cur_t = test_main.tests; + int i = 1; + while (cur_t) + { + cur_t->setup(cur_t); + test *next_test = cur_t->_next; + DBGT("TEST %i/%i : running test %s\n", i, test_main.test_count, cur_t->name); + i++; + int res = cur_t->f(cur_t); + cur_t->teardown(cur_t); + int fd = res == TEST_RES_OK ? fd_success : fd_bad; + write(fd, cur_t->name, strlen(cur_t->name)); + write(fd, "\n", 1); + switch (res) + { + case TEST_RES_OK: + ok++; + printf(" .. ok\n"); + break; + case TEST_RES_FAIL: + failed++; + printf(" .. FAILED\n"); + if (test_main.on_stop) + test_main.on_stop(cur_t); + add_res(cur_t, &test_main.failed, &test_main.failed_last); + break; + case TEST_RES_ASSERT: + stopped++; + printf(" .. ABORTED\n"); + if (test_main.on_stop) + test_main.on_stop(cur_t); + add_res(cur_t, &test_main.stopped, &test_main.stopped_last); + break; + } + free(cur_t); + cur_t = next_test; + } + close(fd_success); + close(fd_bad); + DBGT("ran %i tests\n", test_main.test_count); + printf("Test report, %i tests\n", test_main.test_count); + printf("%i succeeded\n", ok); + printf("%i failed\n", failed); + dump_res(&test_main.failed); + printf("%i stopped\n", stopped); + dump_res(&test_main.stopped); + if (ok < test_main.test_count) + { + printf("\nFAILED\n"); + } + else + { + printf("\nALL TESTS OK\n"); } - free(cur_t); - cur_t = next_test; - } - close(fd_success); - close(fd_bad); - DBGT("ran %i tests\n", test_main.test_count); - printf("Test report, %i tests\n", test_main.test_count); - printf("%i succeeded\n", ok); - printf("%i failed\n", failed); - dump_res(&test_main.failed); - printf("%i stopped\n", stopped); - dump_res(&test_main.stopped); - if (ok < test_main.test_count) { - printf("\nFAILED\n"); - } else { - printf("\nALL TESTS OK\n"); - } } diff --git a/LuaNode_Esp32/LuaNode32/components/spiffs/test/testsuites.c b/LuaNode_Esp32/LuaNode32/components/spiffs/test/testsuites.c index 7627db0..9ec60fd 100644 --- a/LuaNode_Esp32/LuaNode32/components/spiffs/test/testsuites.c +++ b/LuaNode_Esp32/LuaNode32/components/spiffs/test/testsuites.c @@ -7,9 +7,10 @@ #include "testrunner.h" -void add_suites() { - //ADD_SUITE(dev_tests); - ADD_SUITE(check_tests); - ADD_SUITE(hydrogen_tests) - ADD_SUITE(bug_tests) +void add_suites() +{ + // ADD_SUITE(dev_tests); + ADD_SUITE(check_tests); + ADD_SUITE(hydrogen_tests) + ADD_SUITE(bug_tests) } diff --git a/LuaNode_Esp32/LuaNode32/components/task/task.c b/LuaNode_Esp32/LuaNode32/components/task/task.c index 7603548..5da90cd 100644 --- a/LuaNode_Esp32/LuaNode32/components/task/task.c +++ b/LuaNode_Esp32/LuaNode32/components/task/task.c @@ -1,7 +1,9 @@ /** - This file encapsulates the SDK-based task handling for the NodeMCU Lua firmware. + This file encapsulates the SDK-based task handling for the NodeMCU Lua + firmware. */ #include "task/task.h" + #include #include @@ -10,21 +12,29 @@ #include "freertos/semphr.h" #define TASK_HANDLE_MONIKER 0x68680000 -#define TASK_HANDLE_MASK 0xFFF80000 -#define TASK_HANDLE_UNMASK (~TASK_HANDLE_MASK) -#define TASK_HANDLE_ALLOCATION_BRICK 4 // must be a power of 2 +#define TASK_HANDLE_MASK 0xFFF80000 +#define TASK_HANDLE_UNMASK (~TASK_HANDLE_MASK) +#define TASK_HANDLE_ALLOCATION_BRICK 4 // must be a power of 2 #define TASK_DEFAULT_QUEUE_LEN 8 -#define CHECK(p,v,msg) if (!(p)) { NODE_DBG ( msg ); return (v); } +#define CHECK(p, v, msg) \ + if (!(p)) \ + { \ + NODE_DBG(msg); \ + return (v); \ + } #ifndef NODE_DBG -# define NODE_DBG(...) do{}while(0) +#define NODE_DBG(...) \ + do \ + { \ + } while (0) #endif typedef struct { - task_handle_t sig; - task_param_t par; + task_handle_t sig; + task_param_t par; } task_event_t; /* @@ -39,106 +49,106 @@ static xSemaphoreHandle pending; static task_callback_t *task_func; static int task_count; - /* * Initialise the task handle callback for a given priority. This doesn't need * to be called explicitly as the get_id function will call this lazily. */ -bool task_init_handler(task_prio_t priority, uint8 qlen) { - if (priority >= TASK_PRIORITY_COUNT) - return false; - - if (task_Q[priority] == NULL) - { - task_Q[priority] = xQueueCreate (qlen, sizeof (task_event_t)); - return task_Q[priority] != NULL; - } - else - return false; -} +bool task_init_handler(task_prio_t priority, uint8 qlen) +{ + if (priority >= TASK_PRIORITY_COUNT) + return false; + if (task_Q[priority] == NULL) + { + task_Q[priority] = xQueueCreate(qlen, sizeof(task_event_t)); + return task_Q[priority] != NULL; + } + else + return false; +} -task_handle_t task_get_id(task_callback_t t) { - /* Initialise any uninitialised Qs with the default Q len */ - for (task_prio_t p = TASK_PRIORITY_LOW; p != TASK_PRIORITY_COUNT; ++p) - { - if (!task_Q[p]) { - CHECK(task_init_handler( p, TASK_DEFAULT_QUEUE_LEN ), 0, "Task initialisation failed"); +task_handle_t task_get_id(task_callback_t t) +{ + /* Initialise any uninitialised Qs with the default Q len */ + for (task_prio_t p = TASK_PRIORITY_LOW; p != TASK_PRIORITY_COUNT; ++p) + { + if (!task_Q[p]) + { + CHECK(task_init_handler(p, TASK_DEFAULT_QUEUE_LEN), 0, "Task initialisation failed"); + } } - } - if ( (task_count & (TASK_HANDLE_ALLOCATION_BRICK - 1)) == 0 ) { - /* With a brick size of 4 this branch is taken at 0, 4, 8 ... and the new size is +4 */ - task_func =(task_callback_t *)realloc( - task_func, - sizeof(task_callback_t)*(task_count+TASK_HANDLE_ALLOCATION_BRICK)); + if ((task_count & (TASK_HANDLE_ALLOCATION_BRICK - 1)) == 0) + { + /* With a brick size of 4 this branch is taken at 0, 4, 8 ... and the + * new size is +4 */ + task_func = (task_callback_t *)realloc(task_func, + sizeof(task_callback_t) * (task_count + TASK_HANDLE_ALLOCATION_BRICK)); - CHECK(task_func, 0 , "Malloc failure in task_get_id"); - memset (task_func+task_count, 0, sizeof(task_callback_t)*TASK_HANDLE_ALLOCATION_BRICK); - } + CHECK(task_func, 0, "Malloc failure in task_get_id"); + memset(task_func + task_count, 0, sizeof(task_callback_t) * TASK_HANDLE_ALLOCATION_BRICK); + } - task_func[task_count] = t; - return TASK_HANDLE_MONIKER | task_count++; + task_func[task_count] = t; + return TASK_HANDLE_MONIKER | task_count++; } - -bool task_post (task_prio_t priority, task_handle_t handle, task_param_t param) +bool task_post(task_prio_t priority, task_handle_t handle, task_param_t param) { - if (priority >= TASK_PRIORITY_COUNT || - !task_Q[priority] || - (handle & TASK_HANDLE_MASK) != TASK_HANDLE_MONIKER) - return false; + if (priority >= TASK_PRIORITY_COUNT || !task_Q[priority] || (handle & TASK_HANDLE_MASK) != TASK_HANDLE_MONIKER) + return false; - task_event_t ev = { handle, param }; - bool res = pdPASS == xQueueSendToBackFromISR (task_Q[priority], &ev, NULL); + task_event_t ev = {handle, param}; + bool res = pdPASS == xQueueSendToBackFromISR(task_Q[priority], &ev, NULL); - if (pending) /* only need to raise semaphore if it's been initialised */ - xSemaphoreGiveFromISR (pending, NULL); + if (pending) /* only need to raise semaphore if it's been initialised */ + xSemaphoreGiveFromISR(pending, NULL); - return res; + return res; } - -static bool next_event (task_event_t *ev, task_prio_t *prio) +static bool next_event(task_event_t *ev, task_prio_t *prio) { - for (task_prio_t pr = TASK_PRIORITY_COUNT; pr != TASK_PRIORITY_LOW; --pr) - { - task_prio_t p = pr -1; - if (task_Q[p] && xQueueReceive (task_Q[p], ev, 0) == pdTRUE) + for (task_prio_t pr = TASK_PRIORITY_COUNT; pr != TASK_PRIORITY_LOW; --pr) { - *prio = p; - return true; + task_prio_t p = pr - 1; + if (task_Q[p] && xQueueReceive(task_Q[p], ev, 0) == pdTRUE) + { + *prio = p; + return true; + } } - } - return false; // no events queued + return false; // no events queued } - -static void dispatch (task_event_t *e, uint8_t prio) { - task_handle_t handle = e->sig; - if ( (handle & TASK_HANDLE_MASK) == TASK_HANDLE_MONIKER) { - uint16_t entry = (handle & TASK_HANDLE_UNMASK); - if ( task_func && entry < task_count ){ - /* call the registered task handler with the specified parameter and priority */ - task_func[entry](e->par, prio); - return; +static void dispatch(task_event_t *e, uint8_t prio) +{ + task_handle_t handle = e->sig; + if ((handle & TASK_HANDLE_MASK) == TASK_HANDLE_MONIKER) + { + uint16_t entry = (handle & TASK_HANDLE_UNMASK); + if (task_func && entry < task_count) + { + /* call the registered task handler with the specified parameter and + * priority */ + task_func[entry](e->par, prio); + return; + } } - } - /* Invalid signals are ignored */ - NODE_DBG ( "Invalid signal issued: %08x", handle); + /* Invalid signals are ignored */ + NODE_DBG("Invalid signal issued: %08x", handle); } - -void task_pump_messages (void) +void task_pump_messages(void) { - vSemaphoreCreateBinary (pending); - for (;;) - { - task_event_t ev; - task_prio_t prio; - if (next_event (&ev, &prio)) - dispatch (&ev, prio); - else - xSemaphoreTake (pending, portMAX_DELAY); - } + vSemaphoreCreateBinary(pending); + for (;;) + { + task_event_t ev; + task_prio_t prio; + if (next_event(&ev, &prio)) + dispatch(&ev, prio); + else + xSemaphoreTake(pending, portMAX_DELAY); + } } diff --git a/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c b/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c index 985b084..124fbd4 100644 --- a/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c +++ b/LuaNode_Esp32/LuaNode32/components/uart/my_uart.c @@ -1,46 +1,48 @@ #include "my_uart.h" -#include "esp_intr.h" -#include "esp_log.h" + +#include +#include + +#include "c_string.h" #include "c_types.h" -#include "rom/uart.h" #include "driver/uart.h" -#include "soc/uart_register.h" +#include "esp_intr.h" +#include "esp_log.h" #include "extras/esp_intr_ext.h" -#include "c_string.h" -#include "lua.h" - #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/queue.h" - -#include -#include +#include "freertos/task.h" +#include "lua.h" +#include "rom/uart.h" +#include "soc/uart_register.h" #define UART_FRM_ERR_INT_ST (BIT(3)) #define UART_FRM_ERR_INT_CLR (BIT(3)) -#define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) -#define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) +#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10) +#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0) #define UART_RXFIFO_FULL_INT_ST (BIT(0)) #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) -#define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) +#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC) #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) #define UART_RXFIFO_OVF_INT_ST (BIT(4)) #define EX_UART_NUM UART_NUM_0 -#define TAG "my_uart" +#define TAG "my_uart" -enum { +enum +{ UART_EVENT_RX_CHAR, - //UART_EVENT_MAX + // UART_EVENT_MAX }; -typedef struct _os_event_ { +typedef struct _os_event_ +{ uint32 event; uint32 param; } os_event_t; @@ -51,88 +53,108 @@ RcvMsgBuff rcvMsgBuff; static uint8_t pbuff[RX_BUFF_SIZE] = {0}; - static void uart_event_task(void *pvParameters) { uart_event_t event; size_t buffered_size; - memset(pbuff, 0, RX_BUFF_SIZE); - while (1) { + memset(pbuff, 0, RX_BUFF_SIZE); + while (1) + { /* Waiting for UART event. If it happens then print out information what is it */ - if (xQueueReceive(xQueueUart, (void * )&event, (portTickType)portMAX_DELAY)) { - //ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM); - switch (event.type) { - case UART_DATA: { - /* Event of UART receiving data - * We'd better handler data event fast, there would be much more data events - * than other types of events. - * If we take too much time on data event, the queue might be full. - * In this example, we don't process data in event, but read data outside. - */ - uart_get_buffered_data_len(EX_UART_NUM, &buffered_size); - //ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); - int len = uart_read_bytes(EX_UART_NUM, pbuff, RX_BUFF_SIZE, 100 / portTICK_RATE_MS); - if (len > 0) { - //ESP_LOGI(TAG, "data: %s", pbuff); - uint8 RcvChar; - for (int i = 0; i < len; i++) { - RcvChar = pbuff[i]; - *(rcvMsgBuff.pWritePos) = RcvChar; - if (RcvChar == '\r' || RcvChar == '\n' ) { - rcvMsgBuff.BuffState = WRITE_OVER; - } - - if (rcvMsgBuff.pWritePos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) { - // overflow ...we may need more error handle here. - rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff ; - } else { - rcvMsgBuff.pWritePos++; - } - - if (rcvMsgBuff.pWritePos == rcvMsgBuff.pReadPos){ // overflow one byte, need push pReadPos one byte ahead - if (rcvMsgBuff.pReadPos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) { - rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff ; - } else { - rcvMsgBuff.pReadPos++; - } - } - } - - - lua_handle_input(false); - } - break; - } - case UART_FIFO_OVF: { - ESP_LOGE(TAG, "hw fifo overflow"); - // If fifo overflow happened, you should consider adding flow control for your application. - // We can read data out out the buffer, or directly flush the Rx buffer. - uart_flush(EX_UART_NUM); - break; - } - case UART_BUFFER_FULL: { - ESP_LOGE(TAG, "ring buffer full"); - // If buffer full happened, you should consider increasing your buffer size - // We can read data out out the buffer, or directly flush the Rx buffer. - uart_flush(EX_UART_NUM); - break; - } - case UART_BREAK: - ESP_LOGI(TAG, "uart rx break detected"); - break; - case UART_PARITY_ERR: - ESP_LOGE(TAG, "uart parity error"); - break; - case UART_FRAME_ERR: - ESP_LOGE(TAG, "uart frame error"); - break; - case UART_PATTERN_DET: - ESP_LOGI(TAG, "uart pattern detected"); - break; - default: - ESP_LOGE(TAG, "not serviced uart event type: %d\n", event.type); - break; + if (xQueueReceive(xQueueUart, (void *)&event, (portTickType)portMAX_DELAY)) + { + // ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM); + switch (event.type) + { + case UART_DATA: + { + /* Event of UART receiving data + * We'd better handler data event fast, there would be much + * more data events than other types of events. If we take + * too much time on data event, the queue might be full. In + * this example, we don't process data in event, but read + * data outside. + */ + uart_get_buffered_data_len(EX_UART_NUM, &buffered_size); + // ESP_LOGI(TAG, "data, len: %d; buffered len: %d", + // event.size, buffered_size); + int len = uart_read_bytes(EX_UART_NUM, pbuff, RX_BUFF_SIZE, 100 / portTICK_RATE_MS); + if (len > 0) + { + // ESP_LOGI(TAG, "data: %s", pbuff); + uint8 RcvChar; + for (int i = 0; i < len; i++) + { + RcvChar = pbuff[i]; + *(rcvMsgBuff.pWritePos) = RcvChar; + if (RcvChar == '\r' || RcvChar == '\n') + { + rcvMsgBuff.BuffState = WRITE_OVER; + } + + if (rcvMsgBuff.pWritePos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) + { + // overflow ...we may need more error handle + // here. + rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff; + } + else + { + rcvMsgBuff.pWritePos++; + } + + if (rcvMsgBuff.pWritePos == rcvMsgBuff.pReadPos) + { // overflow one byte, need push pReadPos one byte + // ahead + if (rcvMsgBuff.pReadPos == (rcvMsgBuff.pRcvMsgBuff + RX_BUFF_SIZE)) + { + rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff; + } + else + { + rcvMsgBuff.pReadPos++; + } + } + } + + lua_handle_input(false); + } + break; + } + case UART_FIFO_OVF: + { + ESP_LOGE(TAG, "hw fifo overflow"); + // If fifo overflow happened, you should consider adding + // flow control for your application. We can read data out + // out the buffer, or directly flush the Rx buffer. + uart_flush(EX_UART_NUM); + break; + } + case UART_BUFFER_FULL: + { + ESP_LOGE(TAG, "ring buffer full"); + // If buffer full happened, you should consider increasing + // your buffer size We can read data out out the buffer, or + // directly flush the Rx buffer. + uart_flush(EX_UART_NUM); + break; + } + case UART_BREAK: + ESP_LOGI(TAG, "uart rx break detected"); + break; + case UART_PARITY_ERR: + ESP_LOGE(TAG, "uart parity error"); + break; + case UART_FRAME_ERR: + ESP_LOGE(TAG, "uart frame error"); + break; + case UART_PATTERN_DET: + ESP_LOGI(TAG, "uart pattern detected"); + break; + default: + ESP_LOGE(TAG, "not serviced uart event type: %d\n", event.type); + break; } } } @@ -141,40 +163,37 @@ static void uart_event_task(void *pvParameters) void uart_sendStr(const char *str) { - while(*str) { - uart_tx_one_char(*str++); - } + while (*str) { uart_tx_one_char(*str++); } } void uart_putc(uint8_t TxChar) { - while (true) { + while (true) + { uint32 fifo_cnt = READ_PERI_REG(UART_STATUS_REG(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); - if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) + { break; } } - WRITE_PERI_REG(UART_FIFO(0) , TxChar); + WRITE_PERI_REG(UART_FIFO(0), TxChar); } - void uart_init(void) { - printf("UART init ...\r\n"); - rcvMsgBuff.pRcvMsgBuff = malloc(RX_BUFF_SIZE); - memset(rcvMsgBuff.pRcvMsgBuff, 0, RX_BUFF_SIZE); - rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff; - rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff; - - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE - }; + printf("UART init ...\r\n"); + rcvMsgBuff.pRcvMsgBuff = malloc(RX_BUFF_SIZE); + memset(rcvMsgBuff.pRcvMsgBuff, 0, RX_BUFF_SIZE); + rcvMsgBuff.pWritePos = rcvMsgBuff.pRcvMsgBuff; + rcvMsgBuff.pReadPos = rcvMsgBuff.pRcvMsgBuff; + + uart_config_t uart_config = {.baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE}; uart_param_config(EX_UART_NUM, &uart_config); // Set UART pins using UART0 default pins i.e. no changes uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); diff --git a/LuaNode_Esp32/LuaNode32/components/utils/base64.c b/LuaNode_Esp32/LuaNode32/components/utils/base64.c index 5b138b8..3d61864 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/base64.c +++ b/LuaNode_Esp32/LuaNode32/components/utils/base64.c @@ -1,11 +1,11 @@ -/* +/* * This file is based on roken from the FreeBSD source. It has been modified - * to not use malloc() and instead expect static buffers, and tabs have been - * replaced with spaces. Also, instead of strlen() on the resulting string, + * to not use malloc() and instead expect static buffers, and tabs have been + * replaced with spaces. Also, instead of strlen() on the resulting string, * pointer arithmitic is done, as p represents the end of the buffer. */ -/* +/* * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. @@ -38,18 +38,14 @@ * SUCH DAMAGE. */ +#include +#include #include #include -#include - -#include - -static const char base64_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static int -pos(char c) +static int pos(char c) { const char *p; for (p = base64_chars; *p; p++) @@ -58,8 +54,7 @@ pos(char c) return -1; } -int -base64_encode(const void *data, int size, char *s, uint8_t should_pad) +int base64_encode(const void *data, int size, char *s, uint8_t should_pad) { char *p; int i; @@ -70,10 +65,11 @@ base64_encode(const void *data, int size, char *s, uint8_t should_pad) p = s; - q = (const unsigned char *) data; + q = (const unsigned char *)data; last = NULL; i = 0; - while (i < size) { + while (i < size) + { c = q[i++]; c *= 256; if (i < size) @@ -91,29 +87,34 @@ base64_encode(const void *data, int size, char *s, uint8_t should_pad) p += 4; } - if (last) { + if (last) + { diff = i - size; - if (diff > 0) { - if (should_pad) { + if (diff > 0) + { + if (should_pad) + { memset(last + (4 - diff), '=', diff); - } else { + } + else + { p = last + (4 - diff); } } - } + } *p = 0; return (p - s); } -int -base64_pad(char *buf, int len) +int base64_pad(char *buf, int len) { int remainder; remainder = len % 4; - if (remainder == 0) { + if (remainder == 0) + { return (0); } @@ -124,15 +125,15 @@ base64_pad(char *buf, int len) #define DECODE_ERROR -1 -static unsigned int -token_decode(const char *token) +static unsigned int token_decode(const char *token) { int i; unsigned int val = 0; int marker = 0; if (strlen(token) < 4) return DECODE_ERROR; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) + { val *= 64; if (token[i] == '=') marker++; @@ -146,14 +147,14 @@ token_decode(const char *token) return (marker << 24) | val; } -int -base64_decode(const char *str, void *data) +int base64_decode(const char *str, void *data) { const char *p; unsigned char *q; q = data; - for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) { + for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) + { unsigned int val = token_decode(p); unsigned int marker = (val >> 24) & 0xff; if (val == DECODE_ERROR) @@ -164,18 +165,14 @@ base64_decode(const char *str, void *data) if (marker < 1) *q++ = val & 0xff; } - return q - (unsigned char *) data; + return q - (unsigned char *)data; } - -int -base64_decode_len(const char *str) +int base64_decode_len(const char *str) { int len; len = strlen(str); - while (len && str[len - 1] == '=') { - len--; - } + while (len && str[len - 1] == '=') { len--; } return len * 3 / 4; } diff --git a/LuaNode_Esp32/LuaNode32/components/utils/crc16.c b/LuaNode_Esp32/LuaNode32/components/utils/crc16.c index c4c39af..805b7d2 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/crc16.c +++ b/LuaNode_Esp32/LuaNode32/components/utils/crc16.c @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001-2010 Georges Menie (www.menie.org) * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -25,48 +25,34 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include "crc16.h" +#include + /* CRC16 implementation acording to CCITT standards */ -static const uint16_t crc16tab[256]= { - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, - 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, - 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, - 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, - 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, - 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, - 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, - 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, - 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, - 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, - 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, - 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, - 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, - 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, - 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, - 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, - 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, - 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, - 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, - 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, - 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, - 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, - 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, - 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, - 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, - 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, - 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, - 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, - 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, - 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, - 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 -}; - -uint16_t -crc16_ccitt(uint16_t initial_crc, const void *buf, int len) +static const uint16_t crc16tab[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, + 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, + 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, + 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, + 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, + 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, + 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, + 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, + 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, + 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, + 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, + 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, + 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, + 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, + 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + +uint16_t crc16_ccitt(uint16_t initial_crc, const void *buf, int len) { const uint8_t *ptr; uint16_t crc; @@ -75,9 +61,7 @@ crc16_ccitt(uint16_t initial_crc, const void *buf, int len) crc = initial_crc; ptr = buf; - for (counter = 0; counter < len; counter++) { - crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *ptr++)&0x00FF]; - } + for (counter = 0; counter < len; counter++) { crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ *ptr++) & 0x00FF]; } return crc; } diff --git a/LuaNode_Esp32/LuaNode32/components/utils/crc8.c b/LuaNode_Esp32/LuaNode32/components/utils/crc8.c index 1894fe8..c1265a2 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/crc8.c +++ b/LuaNode_Esp32/LuaNode32/components/utils/crc8.c @@ -48,27 +48,21 @@ #include "crc8.h" -static uint8_t crc8_small_table[16] = { - 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, - 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d -}; +static uint8_t crc8_small_table[16] = {0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, + 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d}; -uint8_t -crc8_init(void) -{ - return 0xff; -} +uint8_t crc8_init(void) { return 0xff; } -uint8_t -crc8_calc(uint8_t val, void *buf, int cnt) +uint8_t crc8_calc(uint8_t val, void *buf, int cnt) { - int i; - uint8_t *p = buf; + int i; + uint8_t *p = buf; - for (i = 0; i < cnt; i++) { - val ^= p[i]; - val = (val << 4) ^ crc8_small_table[val >> 4]; - val = (val << 4) ^ crc8_small_table[val >> 4]; - } - return val; + for (i = 0; i < cnt; i++) + { + val ^= p[i]; + val = (val << 4) ^ crc8_small_table[val >> 4]; + val = (val << 4) ^ crc8_small_table[val >> 4]; + } + return val; } diff --git a/LuaNode_Esp32/LuaNode32/components/utils/datetime.c b/LuaNode_Esp32/LuaNode32/components/utils/datetime.c index 970b315..4b46121 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/datetime.c +++ b/LuaNode_Esp32/LuaNode32/components/utils/datetime.c @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -57,39 +57,38 @@ * from: src/sys/i386/isa/clock.c,v 1.176 2001/09/04 */ -#include "os_time.h" +#include "datetime.h" -#include #include +#include #include -#include "datetime.h" -struct clocktime { - int year; /* year (4 digit year) */ - int mon; /* month (1 - 12) */ - int day; /* day (1 - 31) */ - int hour; /* hour (0 - 23) */ - int min; /* minute (0 - 59) */ - int sec; /* second (0 - 59) */ - int dow; /* day of week (0 - 6; 0 = Sunday) */ - int usec; /* micro seconds */ +#include "os_time.h" + +struct clocktime +{ + int year; /* year (4 digit year) */ + int mon; /* month (1 - 12) */ + int day; /* day (1 - 31) */ + int hour; /* hour (0 - 23) */ + int min; /* minute (0 - 59) */ + int sec; /* second (0 - 59) */ + int dow; /* day of week (0 - 6; 0 = Sunday) */ + int usec; /* micro seconds */ }; -#define days_in_year(y) (leapyear(y) ? 366 : 365) +#define days_in_year(y) (leapyear(y) ? 366 : 365) -#define FEBRUARY 2 -#define days_in_month(y, m) \ - (month_days[(m) - 1] + (m == FEBRUARY ? leapyear(y) : 0)) +#define FEBRUARY 2 +#define days_in_month(y, m) (month_days[(m)-1] + (m == FEBRUARY ? leapyear(y) : 0)) /* Day of week. Days are counted from 1/1/1970, which was a Thursday */ -#define day_of_week(days) (((days) + 4) % 7) +#define day_of_week(days) (((days) + 4) % 7) -static const int month_days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; +static const int month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; #define POSIX_BASE_YEAR 1970 -#define SECDAY (24 * 60 * 60) +#define SECDAY (24 * 60 * 60) /* * This inline avoids some unnecessary modulo operations @@ -99,14 +98,15 @@ static const int month_days[12] = { * ((year % 400) == 0) ) * It is otherwise equivalent. */ -static int -leapyear(int year) +static int leapyear(int year) { int rv = 0; - if ((year & 3) == 0) { + if ((year & 3) == 0) + { rv = 1; - if ((year % 100) == 0) { + if ((year % 100) == 0) + { rv = 0; if ((year % 400) == 0) rv = 1; @@ -115,27 +115,19 @@ leapyear(int year) return (rv); } -int -isLeapyear(int year) -{ - return leapyear(year); -} +int isLeapyear(int year) { return leapyear(year); } -static int -clocktime_to_timeval(const struct clocktime *ct, struct os_timeval *tv) +static int clocktime_to_timeval(const struct clocktime *ct, struct os_timeval *tv) { int i, year, days; year = ct->year; /* Sanity checks. */ - if (year < POSIX_BASE_YEAR || - ct->mon < 1 || ct->mon > 12 || - ct->day < 1 || ct->day > days_in_month(year, ct->mon) || - ct->hour < 0 || ct->hour > 23 || - ct->min < 0 || ct->min > 59 || - ct->sec < 0 || ct->sec > 59 || - ct->usec < 0 || ct->usec > 999999) { + if (year < POSIX_BASE_YEAR || ct->mon < 1 || ct->mon > 12 || ct->day < 1 || + ct->day > days_in_month(year, ct->mon) || ct->hour < 0 || ct->hour > 23 || ct->min < 0 || ct->min > 59 || + ct->sec < 0 || ct->sec > 59 || ct->usec < 0 || ct->usec > 999999) + { return (-1); } @@ -144,37 +136,34 @@ clocktime_to_timeval(const struct clocktime *ct, struct os_timeval *tv) * First from years, then from months. */ days = 0; - for (i = POSIX_BASE_YEAR; i < year; i++) - days += days_in_year(i); + for (i = POSIX_BASE_YEAR; i < year; i++) days += days_in_year(i); /* Months */ - for (i = 1; i < ct->mon; i++) - days += days_in_month(year, i); + for (i = 1; i < ct->mon; i++) days += days_in_month(year, i); days += (ct->day - 1); - tv->tv_sec = (((int64_t)days * 24 + ct->hour) * 60 + ct->min) * 60 + - ct->sec; + tv->tv_sec = (((int64_t)days * 24 + ct->hour) * 60 + ct->min) * 60 + ct->sec; tv->tv_usec = ct->usec; return (0); } -static int -timeval_to_clocktime(const struct os_timeval *tv, const struct os_timezone *tz, - struct clocktime *ct) +static int timeval_to_clocktime(const struct os_timeval *tv, const struct os_timezone *tz, struct clocktime *ct) { int i, year, days; - int64_t rsec; /* remainder seconds */ + int64_t rsec; /* remainder seconds */ int64_t secs; secs = tv->tv_sec; - if (tz != NULL) { + if (tz != NULL) + { /* Convert utctime to localtime */ secs -= tz->tz_minuteswest * 60; secs += tz->tz_dsttime ? 3600 : 0; } - if (secs < 0 || tv->tv_usec < 0 || tv->tv_usec > 999999) { + if (secs < 0 || tv->tv_usec < 0 || tv->tv_usec > 999999) + { return (-1); } @@ -184,13 +173,11 @@ timeval_to_clocktime(const struct os_timeval *tv, const struct os_timezone *tz, ct->dow = day_of_week(days); /* Subtract out whole years, counting them in i. */ - for (year = POSIX_BASE_YEAR; days >= days_in_year(year); year++) - days -= days_in_year(year); + for (year = POSIX_BASE_YEAR; days >= days_in_year(year); year++) days -= days_in_year(year); ct->year = year; /* Subtract out whole months, counting them in i. */ - for (i = 1; days >= days_in_month(year, i); i++) - days -= days_in_month(year, i); + for (i = 1; days >= days_in_month(year, i); i++) days -= days_in_month(year, i); ct->mon = i; /* Days are what is left over (+1) from all that. */ @@ -199,25 +186,26 @@ timeval_to_clocktime(const struct os_timeval *tv, const struct os_timezone *tz, /* Hours, minutes, seconds are easy */ ct->hour = rsec / 3600; rsec = rsec % 3600; - ct->min = rsec / 60; + ct->min = rsec / 60; rsec = rsec % 60; - ct->sec = rsec; + ct->sec = rsec; ct->usec = tv->tv_usec; return (0); } -static const char * -parse_number(const char *str, int digits, int *val) +static const char *parse_number(const char *str, int digits, int *val) { const char *cp; const char *end; - + *val = 0; cp = str; end = str + digits; - while (cp < end) { - if (!isdigit((int) *cp)) { + while (cp < end) + { + if (!isdigit((int)*cp)) + { return (NULL); } *val *= 10; @@ -236,8 +224,7 @@ parse_number(const char *str, int digits, int *val) * 2016-03-02T22:44:00.1 fractional seconds * 2016-03-02T22:44:00.101+05:30 fractional seconds with timezone */ -int -parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) +int parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) { int digits, sign; int off_hour, off_min; @@ -247,52 +234,59 @@ parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) bzero(&ct, sizeof(struct clocktime)); bzero(tv, sizeof(struct os_timeval)); - bzero(tz, sizeof(struct os_timezone)); /* default to UTC time */ + bzero(tz, sizeof(struct os_timezone)); /* default to UTC time */ cp = input; cp = parse_number(cp, 4, &ct.year); - if (cp == NULL || *cp != '-') { + if (cp == NULL || *cp != '-') + { goto err; } cp = parse_number(cp + 1, 2, &ct.mon); - if (cp == NULL || *cp != '-') { + if (cp == NULL || *cp != '-') + { goto err; } cp = parse_number(cp + 1, 2, &ct.day); - if (cp == NULL || *cp != 'T') { + if (cp == NULL || *cp != 'T') + { goto err; } cp = parse_number(cp + 1, 2, &ct.hour); - if (cp == NULL || *cp != ':') { + if (cp == NULL || *cp != ':') + { goto err; } cp = parse_number(cp + 1, 2, &ct.min); - if (cp == NULL || *cp != ':') { + if (cp == NULL || *cp != ':') + { goto err; } cp = parse_number(cp + 1, 2, &ct.sec); - if (cp == NULL) { + if (cp == NULL) + { goto err; } /* parse fractional seconds if specified */ - if (*cp == '.') { + if (*cp == '.') + { ep = ++cp; - while (isdigit((int) *ep)) { - ep++; - } + while (isdigit((int)*ep)) { ep++; } digits = ep - cp; - if (digits <= 0 || digits > 6) { + if (digits <= 0 || digits > 6) + { goto err; } cp = parse_number(cp, digits, &ct.usec); - if (cp == NULL) { + if (cp == NULL) + { goto err; } @@ -307,26 +301,30 @@ parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) * .00001 1 part out of 100000 10 usec * .000001 1 part out of 1000000 1 usec */ - while (digits++ < 6) { - ct.usec *= 10; - } + while (digits++ < 6) { ct.usec *= 10; } } - if (*cp == 'Z' || *cp == 'z') { + if (*cp == 'Z' || *cp == 'z') + { cp++; - } else if (*cp == '+' || *cp == '-') { + } + else if (*cp == '+' || *cp == '-') + { sign = (*cp == '+') ? +1 : -1; cp = parse_number(cp + 1, 2, &off_hour); - if (cp == NULL || *cp != ':') { + if (cp == NULL || *cp != ':') + { goto err; } cp = parse_number(cp + 1, 2, &off_min); - if (cp == NULL) { + if (cp == NULL) + { goto err; } - if (off_hour < 0 || off_hour > 23 || off_min < 0 || off_min > 59) { + if (off_hour < 0 || off_hour > 23 || off_min < 0 || off_min > 59) + { goto err; } @@ -335,7 +333,8 @@ parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) * https://docs.oracle.com/javase/8/docs/api/java/time/ZoneOffset.html */ tz->tz_minuteswest = off_hour * 60 + off_min; - if (tz->tz_minuteswest > 18 * 60) { + if (tz->tz_minuteswest > 18 * 60) + { goto err; } @@ -343,20 +342,25 @@ parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) * Positive GMT offsets (i.e. timezones to the east of GMT) are * represented with a negative 'tz_minuteswest' value. */ - if (sign > 0) { + if (sign > 0) + { tz->tz_minuteswest = -tz->tz_minuteswest; } - } else { + } + else + { /* * 'time offset' is not specified so date/time defaults to UTC. */ } - if (*cp != '\0') { + if (*cp != '\0') + { goto err; } - if (clocktime_to_timeval(&ct, tv) != 0) { + if (clocktime_to_timeval(&ct, tv) != 0) + { goto err; } @@ -368,9 +372,7 @@ parse_datetime(const char *input, struct os_timeval *tv, struct os_timezone *tz) return (-1); } -int -format_datetime(const struct os_timeval *tv, const struct os_timezone *tz, - char *ostr, int olen) +int format_datetime(const struct os_timeval *tv, const struct os_timezone *tz, char *ostr, int olen) { char *cp; int rc, rlen, minswest; @@ -378,53 +380,65 @@ format_datetime(const struct os_timeval *tv, const struct os_timezone *tz, struct clocktime ct; rc = timeval_to_clocktime(tv, tz, &ct); - if (rc != 0) { + if (rc != 0) + { goto err; } - + cp = ostr; rlen = olen; - rc = snprintf(cp, rlen, "%04d-%02d-%02dT%02d:%02d:%02d", - ct.year, ct.mon, ct.day, ct.hour, ct.min, ct.sec); + rc = snprintf(cp, rlen, "%04d-%02d-%02dT%02d:%02d:%02d", ct.year, ct.mon, ct.day, ct.hour, ct.min, ct.sec); cp += rc; rlen -= rc; - if (rc < 0 || rlen <= 0) { + if (rc < 0 || rlen <= 0) + { goto err; } - if (ct.usec != 0) { + if (ct.usec != 0) + { rc = snprintf(cp, rlen, ".%06d", ct.usec); cp += rc; rlen -= rc; - if (rc < 0 || rlen <= 0) { + if (rc < 0 || rlen <= 0) + { goto err; } } - if (tz != NULL) { + if (tz != NULL) + { minswest = tz->tz_minuteswest; - if (tz->tz_dsttime) { + if (tz->tz_dsttime) + { minswest -= 60; } - } else { + } + else + { minswest = 0; } - if (minswest < 0) { + if (minswest < 0) + { sign = '+'; minswest = -minswest; - } else { + } + else + { sign = '-'; } off_hour = minswest / 60; off_min = minswest % 60; - if (off_hour || off_min) { + if (off_hour || off_min) + { rc = snprintf(cp, rlen, "%c%02d:%02d", sign, off_hour, off_min); cp += rc; rlen -= rc; - if (rc < 0 || rlen <= 0) { + if (rc < 0 || rlen <= 0) + { goto err; } } diff --git a/LuaNode_Esp32/LuaNode32/components/utils/md5.c b/LuaNode_Esp32/LuaNode32/components/utils/md5.c index 20d7185..a2f0ad8 100644 --- a/LuaNode_Esp32/LuaNode32/components/utils/md5.c +++ b/LuaNode_Esp32/LuaNode32/components/utils/md5.c @@ -1,10 +1,10 @@ -#include #include "md5.h" -unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +#include + +unsigned char PADDING[] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void MD5Init(MD5_CTX *context) { @@ -15,85 +15,81 @@ void MD5Init(MD5_CTX *context) context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; } -void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) +void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen) { - unsigned int i = 0,index = 0,partlen = 0; + unsigned int i = 0, index = 0, partlen = 0; index = (context->count[0] >> 3) & 0x3F; partlen = 64 - index; context->count[0] += inputlen << 3; - if(context->count[0] < (inputlen << 3)) + if (context->count[0] < (inputlen << 3)) context->count[1]++; context->count[1] += inputlen >> 29; - if(inputlen >= partlen) + if (inputlen >= partlen) { - memcpy(&context->buffer[index],input,partlen); - MD5Transform(context->state,context->buffer); - for(i = partlen;i+64 <= inputlen;i+=64) - MD5Transform(context->state,&input[i]); + memcpy(&context->buffer[index], input, partlen); + MD5Transform(context->state, context->buffer); + for (i = partlen; i + 64 <= inputlen; i += 64) MD5Transform(context->state, &input[i]); index = 0; } else { i = 0; } - memcpy(&context->buffer[index],&input[i],inputlen-i); + memcpy(&context->buffer[index], &input[i], inputlen - i); } -void MD5Final(MD5_CTX *context,unsigned char digest[16]) +void MD5Final(MD5_CTX *context, unsigned char digest[16]) { - unsigned int index = 0,padlen = 0; + unsigned int index = 0, padlen = 0; unsigned char bits[8]; index = (context->count[0] >> 3) & 0x3F; - padlen = (index < 56)?(56-index):(120-index); - MD5Encode(bits,context->count,8); - MD5Update(context,PADDING,padlen); - MD5Update(context,bits,8); - MD5Encode(digest,context->state,16); + padlen = (index < 56) ? (56 - index) : (120 - index); + MD5Encode(bits, context->count, 8); + MD5Update(context, PADDING, padlen); + MD5Update(context, bits, 8); + MD5Encode(digest, context->state, 16); } -void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) +void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len) { - unsigned int i = 0,j = 0; - while(j < len) + unsigned int i = 0, j = 0; + while (j < len) { output[j] = input[i] & 0xFF; - output[j+1] = (input[i] >> 8) & 0xFF; - output[j+2] = (input[i] >> 16) & 0xFF; - output[j+3] = (input[i] >> 24) & 0xFF; + output[j + 1] = (input[i] >> 8) & 0xFF; + output[j + 2] = (input[i] >> 16) & 0xFF; + output[j + 3] = (input[i] >> 24) & 0xFF; i++; - j+=4; + j += 4; } } -void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) +void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len) { - unsigned int i = 0,j = 0; - while(j < len) + unsigned int i = 0, j = 0; + while (j < len) { - output[i] = (input[j]) | - (input[j+1] << 8) | - (input[j+2] << 16) | - (input[j+3] << 24); + output[i] = (input[j]) | (input[j + 1] << 8) | (input[j + 2] << 16) | (input[j + 3] << 24); i++; - j+=4; + j += 4; } } -void MD5Transform(unsigned int state[4],unsigned char block[64]) +void MD5Transform(unsigned int state[4], unsigned char block[64]) { unsigned int a = state[0]; unsigned int b = state[1]; unsigned int c = state[2]; unsigned int d = state[3]; unsigned int x[64]; - MD5Decode(x,block,64); - FF(a, b, c, d, x[ 0], 7, 0xd76aa478); - FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); - FF(c, d, a, b, x[ 2], 17, 0x242070db); - FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); - FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); - FF(d, a, b, c, x[ 5], 12, 0x4787c62a); - FF(c, d, a, b, x[ 6], 17, 0xa8304613); - FF(b, c, d, a, x[ 7], 22, 0xfd469501); - FF(a, b, c, d, x[ 8], 7, 0x698098d8); - FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); + MD5Decode(x, block, 64); + FF(a, b, c, d, x[0], 7, 0xd76aa478); + FF(d, a, b, c, x[1], 12, 0xe8c7b756); + FF(c, d, a, b, x[2], 17, 0x242070db); + FF(b, c, d, a, x[3], 22, 0xc1bdceee); + FF(a, b, c, d, x[4], 7, 0xf57c0faf); + FF(d, a, b, c, x[5], 12, 0x4787c62a); + FF(c, d, a, b, x[6], 17, 0xa8304613); + FF(b, c, d, a, x[7], 22, 0xfd469501); + FF(a, b, c, d, x[8], 7, 0x698098d8); + FF(d, a, b, c, x[9], 12, 0x8b44f7af); FF(c, d, a, b, x[10], 17, 0xffff5bb1); FF(b, c, d, a, x[11], 22, 0x895cd7be); FF(a, b, c, d, x[12], 7, 0x6b901122); @@ -101,59 +97,56 @@ void MD5Transform(unsigned int state[4],unsigned char block[64]) FF(c, d, a, b, x[14], 17, 0xa679438e); FF(b, c, d, a, x[15], 22, 0x49b40821); - - GG(a, b, c, d, x[ 1], 5, 0xf61e2562); - GG(d, a, b, c, x[ 6], 9, 0xc040b340); + GG(a, b, c, d, x[1], 5, 0xf61e2562); + GG(d, a, b, c, x[6], 9, 0xc040b340); GG(c, d, a, b, x[11], 14, 0x265e5a51); - GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); - GG(a, b, c, d, x[ 5], 5, 0xd62f105d); - GG(d, a, b, c, x[10], 9, 0x2441453); + GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); + GG(a, b, c, d, x[5], 5, 0xd62f105d); + GG(d, a, b, c, x[10], 9, 0x2441453); GG(c, d, a, b, x[15], 14, 0xd8a1e681); - GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); - GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); + GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); + GG(a, b, c, d, x[9], 5, 0x21e1cde6); GG(d, a, b, c, x[14], 9, 0xc33707d6); - GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); - GG(b, c, d, a, x[ 8], 20, 0x455a14ed); + GG(c, d, a, b, x[3], 14, 0xf4d50d87); + GG(b, c, d, a, x[8], 20, 0x455a14ed); GG(a, b, c, d, x[13], 5, 0xa9e3e905); - GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); - GG(c, d, a, b, x[ 7], 14, 0x676f02d9); + GG(d, a, b, c, x[2], 9, 0xfcefa3f8); + GG(c, d, a, b, x[7], 14, 0x676f02d9); GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); - - HH(a, b, c, d, x[ 5], 4, 0xfffa3942); - HH(d, a, b, c, x[ 8], 11, 0x8771f681); + HH(a, b, c, d, x[5], 4, 0xfffa3942); + HH(d, a, b, c, x[8], 11, 0x8771f681); HH(c, d, a, b, x[11], 16, 0x6d9d6122); HH(b, c, d, a, x[14], 23, 0xfde5380c); - HH(a, b, c, d, x[ 1], 4, 0xa4beea44); - HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); - HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); + HH(a, b, c, d, x[1], 4, 0xa4beea44); + HH(d, a, b, c, x[4], 11, 0x4bdecfa9); + HH(c, d, a, b, x[7], 16, 0xf6bb4b60); HH(b, c, d, a, x[10], 23, 0xbebfbc70); HH(a, b, c, d, x[13], 4, 0x289b7ec6); - HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); - HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); - HH(b, c, d, a, x[ 6], 23, 0x4881d05); - HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); + HH(d, a, b, c, x[0], 11, 0xeaa127fa); + HH(c, d, a, b, x[3], 16, 0xd4ef3085); + HH(b, c, d, a, x[6], 23, 0x4881d05); + HH(a, b, c, d, x[9], 4, 0xd9d4d039); HH(d, a, b, c, x[12], 11, 0xe6db99e5); HH(c, d, a, b, x[15], 16, 0x1fa27cf8); - HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); - + HH(b, c, d, a, x[2], 23, 0xc4ac5665); - II(a, b, c, d, x[ 0], 6, 0xf4292244); - II(d, a, b, c, x[ 7], 10, 0x432aff97); + II(a, b, c, d, x[0], 6, 0xf4292244); + II(d, a, b, c, x[7], 10, 0x432aff97); II(c, d, a, b, x[14], 15, 0xab9423a7); - II(b, c, d, a, x[ 5], 21, 0xfc93a039); + II(b, c, d, a, x[5], 21, 0xfc93a039); II(a, b, c, d, x[12], 6, 0x655b59c3); - II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); + II(d, a, b, c, x[3], 10, 0x8f0ccc92); II(c, d, a, b, x[10], 15, 0xffeff47d); - II(b, c, d, a, x[ 1], 21, 0x85845dd1); - II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); + II(b, c, d, a, x[1], 21, 0x85845dd1); + II(a, b, c, d, x[8], 6, 0x6fa87e4f); II(d, a, b, c, x[15], 10, 0xfe2ce6e0); - II(c, d, a, b, x[ 6], 15, 0xa3014314); + II(c, d, a, b, x[6], 15, 0xa3014314); II(b, c, d, a, x[13], 21, 0x4e0811a1); - II(a, b, c, d, x[ 4], 6, 0xf7537e82); + II(a, b, c, d, x[4], 6, 0xf7537e82); II(d, a, b, c, x[11], 10, 0xbd3af235); - II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); - II(b, c, d, a, x[ 9], 21, 0xeb86d391); + II(c, d, a, b, x[2], 15, 0x2ad7d2bb); + II(b, c, d, a, x[9], 21, 0xeb86d391); state[0] += a; state[1] += b; state[2] += c; diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/alexa/alexa.c b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/alexa/alexa.c index 73214f1..ab03b07 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/alexa/alexa.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/alexa/alexa.c @@ -12,20 +12,21 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "alexa.h" + #include -#include "alexa.h" -#include "utils.h" -#include "user_config.h" -#include "esp_log.h" #include "driver/gpio.h" +#include "esp_log.h" #include "lwip/api.h" -#include "lwip/sockets.h" #include "lwip/igmp.h" +#include "lwip/sockets.h" +#include "user_config.h" +#include "utils.h" -#define RECV_BUFFSIZE 1024 -#define UDP_PORT 1900 -#define MAX_HTTP_CLIENT_CONN 1 +#define RECV_BUFFSIZE 1024 +#define UDP_PORT 1900 +#define MAX_HTTP_CLIENT_CONN 1 static const char *TAG = "alexa"; @@ -43,157 +44,187 @@ extern unsigned char *get_ip_num(void); extern char *get_local_ip(void); static void alexa_udp_task(void *pvParameter); -static void turn_on_led() { - gpio_set_level(GPIO_TEST, 1); // turn on relay with voltage HIGH +static void turn_on_led() +{ + gpio_set_level(GPIO_TEST, 1); // turn on relay with voltage HIGH } -static void turn_off_led() { - gpio_set_level(GPIO_TEST, 0); // turn off relay with voltage LOW +static void turn_off_led() +{ + gpio_set_level(GPIO_TEST, 0); // turn off relay with voltage LOW } static bool connect_udp(void) { - ESP_LOGI(TAG, "connecting to UDP"); - udpconn = netconn_new(NETCONN_UDP); - if (udpconn == NULL) { - ESP_LOGE(TAG, "new netconn failed"); - return false; - } - - err_t err = netconn_bind(udpconn, IP_ADDR_ANY, UDP_PORT); - if (err != 0) { - ESP_LOGE(TAG, "netconn bind failed"); - return false; - } - - ip_addr_t destipaddr; - IP_ADDR4(&destipaddr, 239, 255, 255, 250); - /*err = netconn_connect(udpconn, &destipaddr, UDP_PORT); - if (err != 0) { - ESP_LOGE(TAG, "netconn connect failed"); - return false; - }*/ - - unsigned char *ip_num = get_ip_num(); - ip_addr_t loc; - ESP_LOGI(TAG, "local ip: %d.%d.%d.%d", ip_num[0], ip_num[1], ip_num[2], ip_num[3]); - IP_ADDR4(&loc, ip_num[0], ip_num[1], ip_num[2], ip_num[3]); - if (igmp_joingroup(&loc, &destipaddr)!= ERR_OK) { - ESP_LOGE(TAG, "igmp join group failed"); + ESP_LOGI(TAG, "connecting to UDP"); + udpconn = netconn_new(NETCONN_UDP); + if (udpconn == NULL) + { + ESP_LOGE(TAG, "new netconn failed"); + return false; + } + + err_t err = netconn_bind(udpconn, IP_ADDR_ANY, UDP_PORT); + if (err != 0) + { + ESP_LOGE(TAG, "netconn bind failed"); return false; } - xTaskCreate(&alexa_udp_task, "alexa_udp_task", ALEXA_UDP_TASK_STACK_SIZE, NULL, ALEXA_UDP_TASK_PRIO, NULL); - - return true; + ip_addr_t destipaddr; + IP_ADDR4(&destipaddr, 239, 255, 255, 250); + /*err = netconn_connect(udpconn, &destipaddr, UDP_PORT); + if (err != 0) { + ESP_LOGE(TAG, "netconn connect failed"); + return false; + }*/ + + unsigned char *ip_num = get_ip_num(); + ip_addr_t loc; + ESP_LOGI(TAG, "local ip: %d.%d.%d.%d", ip_num[0], ip_num[1], ip_num[2], ip_num[3]); + IP_ADDR4(&loc, ip_num[0], ip_num[1], ip_num[2], ip_num[3]); + if (igmp_joingroup(&loc, &destipaddr) != ERR_OK) + { + ESP_LOGE(TAG, "igmp join group failed"); + return false; + } + + xTaskCreate(&alexa_udp_task, "alexa_udp_task", ALEXA_UDP_TASK_STACK_SIZE, NULL, ALEXA_UDP_TASK_PRIO, NULL); + + return true; } static void response_to_search(unsigned char *addr, int port) { - char resp[768] = {0}; - char *local_ip = get_local_ip(); - sprintf(resp, - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=86400\r\n" - "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://%s:80/setup.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n" - "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n" - "ST: urn:Belkin:device:**\r\n" - "USN: uuid:%s::urn:Belkin:device:**\r\n" - "X-User-Agent: redsonic\r\n\r\n", local_ip, persistent_uuid); - - struct netbuf *sentbuf = netbuf_new(); - if (sentbuf == NULL) { - ESP_LOGE(TAG, "netbuf alloc failed"); - return; - } - netbuf_alloc(sentbuf, strlen(resp)); - memcpy(sentbuf->p->payload, (void*)resp, strlen(resp)); - ip_addr_t dest; - IP_ADDR4(&dest, addr[0], addr[1], addr[2], addr[3]); - err_t err = netconn_sendto(udpconn, sentbuf, &dest, port); - if (err != 0) { - ESP_LOGE(TAG, "udp send data failed!"); - } - ESP_LOGI(TAG, "sent: %s", resp); - netbuf_delete(sentbuf); + char resp[768] = {0}; + char *local_ip = get_local_ip(); + sprintf(resp, + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=86400\r\n" + "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://%s:80/setup.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n" + "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n" + "ST: urn:Belkin:device:**\r\n" + "USN: uuid:%s::urn:Belkin:device:**\r\n" + "X-User-Agent: redsonic\r\n\r\n", + local_ip, persistent_uuid); + + struct netbuf *sentbuf = netbuf_new(); + if (sentbuf == NULL) + { + ESP_LOGE(TAG, "netbuf alloc failed"); + return; + } + netbuf_alloc(sentbuf, strlen(resp)); + memcpy(sentbuf->p->payload, (void *)resp, strlen(resp)); + ip_addr_t dest; + IP_ADDR4(&dest, addr[0], addr[1], addr[2], addr[3]); + err_t err = netconn_sendto(udpconn, sentbuf, &dest, port); + if (err != 0) + { + ESP_LOGE(TAG, "udp send data failed!"); + } + ESP_LOGI(TAG, "sent: %s", resp); + netbuf_delete(sentbuf); } static void parse_udp_data(char *data, int len, unsigned char *addr, int port) { - if (NULL != strstr(data, "M-SEARCH")) { - ESP_LOGI(TAG, "M-SEARCH"); - if (NULL != strstr(data, "urn:Belkin:device:**")) { - ESP_LOGI(TAG, "response to search request ......"); - response_to_search(addr, port); - } - } + if (NULL != strstr(data, "M-SEARCH")) + { + ESP_LOGI(TAG, "M-SEARCH"); + if (NULL != strstr(data, "urn:Belkin:device:**")) + { + ESP_LOGI(TAG, "response to search request ......"); + response_to_search(addr, port); + } + } } static int parse_http_request(int sock, char *data, int len) { - if (NULL != strstr(data, "/index.html")) { - ESP_LOGI(TAG, "response to index.xml"); - char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 5\r\nConnection: close\r\n\r\n"; // 5 is the body length, if you change body content, - write(sock, header, strlen(header)); - char *body = "hello"; - write(sock, body, strlen(body)); - } else if (NULL != strstr(data, "/eventservice.xml")) { - ESP_LOGI(TAG, "response to eventservice.xml"); - char *eventservice_xml = "" + if (NULL != strstr(data, "/index.html")) + { + ESP_LOGI(TAG, "response to index.xml"); + char *header = + "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: " + "5\r\nConnection: close\r\n\r\n"; // 5 is the body length, if you + // change body content, + write(sock, header, strlen(header)); + char *body = "hello"; + write(sock, body, strlen(body)); + } + else if (NULL != strstr(data, "/eventservice.xml")) + { + ESP_LOGI(TAG, "response to eventservice.xml"); + char *eventservice_xml = + "" "" - "" - "SetBinaryState" - "" - "" - "" - "BinaryState" - "BinaryState" - "in" - "" - "" - "" - "" - "BinaryState" - "Boolean" - "0" - "" - "" - "level" - "string" - "0" - "" - "" - "" + "" + "SetBinaryState" + "" + "" + "" + "BinaryState" + "BinaryState" + "in" + "" + "" + "" + "" + "BinaryState" + "Boolean" + "0" + "" + "" + "level" + "string" + "0" + "" + "" + "" "\r\n" "\r\n"; - char header[256] = {0}; - int body_len = strlen(eventservice_xml); - sprintf(header, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", body_len); - write(sock, header, strlen(header)); - write(sock, eventservice_xml, body_len); - } else if (NULL != strstr(data, "/upnp/control/basicevent1")) { - ESP_LOGI(TAG, "response to /upnp/control/basicevent1"); - if (NULL != strstr(data, "1")) { - ESP_LOGI(TAG, "turn on LED"); - turn_on_led(); - } - if (NULL != strstr(data, "0")) { - ESP_LOGI(TAG, "turn off LED"); - turn_off_led(); - } - // you must response to Alexa when you finish your operation, otherwise, Alexa will say something like "You device is poweroff" - char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"; - write(sock, header, strlen(header)); - } else if (NULL != strstr(data, "/setup.xml")) { - ESP_LOGI(TAG, "response to setup.xml"); - char setup_xml[1024] = {0}; - sprintf(setup_xml, "" - "" - "" + char header[256] = {0}; + int body_len = strlen(eventservice_xml); + sprintf(header, + "HTTP/1.1 200 OK\r\nContent-Type: " + "text/plain\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", + body_len); + write(sock, header, strlen(header)); + write(sock, eventservice_xml, body_len); + } + else if (NULL != strstr(data, "/upnp/control/basicevent1")) + { + ESP_LOGI(TAG, "response to /upnp/control/basicevent1"); + if (NULL != strstr(data, "1")) + { + ESP_LOGI(TAG, "turn on LED"); + turn_on_led(); + } + if (NULL != strstr(data, "0")) + { + ESP_LOGI(TAG, "turn off LED"); + turn_off_led(); + } + // you must response to Alexa when you finish your operation, otherwise, + // Alexa will say something like "You device is poweroff" + char *header = + "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: " + "0\r\nConnection: close\r\n\r\n"; + write(sock, header, strlen(header)); + } + else if (NULL != strstr(data, "/setup.xml")) + { + ESP_LOGI(TAG, "response to setup.xml"); + char setup_xml[1024] = {0}; + sprintf(setup_xml, + "" + "" + "" "urn:Belkin:device:controllee:1" "%s" "Belkin International Inc." @@ -203,147 +234,173 @@ static int parse_http_request(int sock, char *data, int len) "221517K0101769" "0" "" - "" - "urn:Belkin:service:basicevent:1" - "urn:Belkin:serviceId:basicevent1" - "/upnp/control/basicevent1" - "/upnp/event/basicevent1" - "/eventservice.xml" - "" - "" - "" - "\r\n" - "\r\n", device_name, persistent_uuid); - char header[256] = {0}; - int body_len = strlen(setup_xml); - sprintf(header, "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", body_len); - write(sock, header, strlen(header)); - write(sock, setup_xml, body_len); - } else { - ESP_LOGE(TAG, "unknown http request?"); - } - return 0; + "" + "urn:Belkin:service:basicevent:1" + "urn:Belkin:serviceId:basicevent1" + "/upnp/control/basicevent1" + "/upnp/event/basicevent1" + "/eventservice.xml" + "" + "" + "" + "\r\n" + "\r\n", + device_name, persistent_uuid); + char header[256] = {0}; + int body_len = strlen(setup_xml); + sprintf(header, + "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\nContent-Length: " + "%d\r\nConnection: close\r\n\r\n", + body_len); + write(sock, header, strlen(header)); + write(sock, setup_xml, body_len); + } + else + { + ESP_LOGE(TAG, "unknown http request?"); + } + return 0; } static void task_http_server_client(void *inFd) { - int32_t client_sock = *(int *) inFd; - int recbytes = 0; - - ESP_LOGI(TAG, "setup socket:(%d)", client_sock); - - //int nNetTimeout = 5; - //setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, - // sizeof(int)); //non-block - while (1) { - recbytes = read(client_sock, text, RECV_BUFFSIZE); - if (recbytes > 0) { - text[recbytes] = 0; - ESP_LOGI(TAG, "(socket:%d) recieve:(%d): %s", client_sock, recbytes, text); - if (parse_http_request(client_sock, text, recbytes) == 0) { - break; - } - } else if (recbytes == 0) { - break; - } - } - - ESP_LOGI(TAG, "task_http_server_client > close socket:(%d)\n", client_sock); - close(client_sock); + int32_t client_sock = *(int *)inFd; + int recbytes = 0; + + ESP_LOGI(TAG, "setup socket:(%d)", client_sock); + + // int nNetTimeout = 5; + // setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, + // sizeof(int)); //non-block + while (1) + { + recbytes = read(client_sock, text, RECV_BUFFSIZE); + if (recbytes > 0) + { + text[recbytes] = 0; + ESP_LOGI(TAG, "(socket:%d) recieve:(%d): %s", client_sock, recbytes, text); + if (parse_http_request(client_sock, text, recbytes) == 0) + { + break; + } + } + else if (recbytes == 0) + { + break; + } + } + + ESP_LOGI(TAG, "task_http_server_client > close socket:(%d)\n", client_sock); + close(client_sock); } static void alexa_udp_task(void *pvParameter) { - struct netbuf *recvbuf; - struct pbuf *q; - - if (udp_connected) { - while (1) { - int data_len = 0; - netconn_recv(udpconn, &recvbuf); - if (recvbuf != NULL) { - int fromport = netbuf_fromport(recvbuf); - ip_addr_t *addr = netbuf_fromaddr(recvbuf); - unsigned char n_addr[4] = {0}; - ip_addr_to_num(n_addr, addr); - ESP_LOGI(TAG, "==> received from addr:%d.%d.%d.%d, port:%d", n_addr[0], n_addr[1], n_addr[2], n_addr[3], fromport); - // received data - memset(udp_buff, 0, RECV_BUFFSIZE + 1); - for(q=recvbuf->p; q!=NULL; q=q->next) { - if(q->len > (RECV_BUFFSIZE-data_len)) { - memcpy(udp_buff+data_len, q->payload, (RECV_BUFFSIZE-data_len)); - } else { - memcpy(udp_buff+data_len,q->payload,q->len); - } - data_len += q->len; - if(data_len > RECV_BUFFSIZE) { - ESP_LOGE(TAG, "receive buffer overflow!!!"); - break; - } - } - //ESP_LOGI(TAG, "==> received: %s", udp_buff); - parse_udp_data(udp_buff, data_len, n_addr, fromport); - netbuf_delete(recvbuf); // do not forget to delete netbuf - } - delay_ms(50); - } - } - vTaskDelete(NULL); + struct netbuf *recvbuf; + struct pbuf *q; + + if (udp_connected) + { + while (1) + { + int data_len = 0; + netconn_recv(udpconn, &recvbuf); + if (recvbuf != NULL) + { + int fromport = netbuf_fromport(recvbuf); + ip_addr_t *addr = netbuf_fromaddr(recvbuf); + unsigned char n_addr[4] = {0}; + ip_addr_to_num(n_addr, addr); + ESP_LOGI(TAG, "==> received from addr:%d.%d.%d.%d, port:%d", n_addr[0], n_addr[1], n_addr[2], n_addr[3], + fromport); + // received data + memset(udp_buff, 0, RECV_BUFFSIZE + 1); + for (q = recvbuf->p; q != NULL; q = q->next) + { + if (q->len > (RECV_BUFFSIZE - data_len)) + { + memcpy(udp_buff + data_len, q->payload, (RECV_BUFFSIZE - data_len)); + } + else + { + memcpy(udp_buff + data_len, q->payload, q->len); + } + data_len += q->len; + if (data_len > RECV_BUFFSIZE) + { + ESP_LOGE(TAG, "receive buffer overflow!!!"); + break; + } + } + // ESP_LOGI(TAG, "==> received: %s", udp_buff); + parse_udp_data(udp_buff, data_len, n_addr, fromport); + netbuf_delete(recvbuf); // do not forget to delete netbuf + } + delay_ms(50); + } + } + vTaskDelete(NULL); } static void alexa_http_task(void *pvParameter) { - ESP_LOGI(TAG, "Starting ALEXA http task..."); - - int32_t listenfd; - struct sockaddr_in server_addr, remote_addr; - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_len = sizeof(server_addr); - server_addr.sin_port = htons(HTTP_SRV_PORT); - - while ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ESP_LOGI(TAG, "http socket create failed"); - delay_ms(1000); - } - - while (bind(listenfd, (struct sockaddr * )&server_addr, sizeof(server_addr)) != 0) { - ESP_LOGI(TAG, "http socket bind failed"); - delay_ms(1000); - } - - while (listen(listenfd, MAX_HTTP_CLIENT_CONN) != 0) { - ESP_LOGI(TAG, "http socket listen failed"); - delay_ms(1000); - } - - int32_t len = sizeof(struct sockaddr_in); - - while (1) { - ESP_LOGI(TAG, "http wait client"); - if ((sock_id = accept(listenfd, (struct sockaddr * )&remote_addr, (socklen_t * )&len)) < 0) { - ESP_LOGI(TAG, "socket accept failed"); - delay_ms(1000); - continue; - } - - printf("ESP32 HTTP server task > Client from %s %d\n", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port)); - //xTaskCreate(task_http_server_client, "task_http_server_client", 1024, - // &client_sock, 1, NULL); - task_http_server_client(&sock_id); - } - - vTaskDelete(NULL); -} + ESP_LOGI(TAG, "Starting ALEXA http task..."); + + int32_t listenfd; + struct sockaddr_in server_addr, remote_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_len = sizeof(server_addr); + server_addr.sin_port = htons(HTTP_SRV_PORT); + + while ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + ESP_LOGI(TAG, "http socket create failed"); + delay_ms(1000); + } + + while (bind(listenfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) + { + ESP_LOGI(TAG, "http socket bind failed"); + delay_ms(1000); + } + + while (listen(listenfd, MAX_HTTP_CLIENT_CONN) != 0) + { + ESP_LOGI(TAG, "http socket listen failed"); + delay_ms(1000); + } + int32_t len = sizeof(struct sockaddr_in); + + while (1) + { + ESP_LOGI(TAG, "http wait client"); + if ((sock_id = accept(listenfd, (struct sockaddr *)&remote_addr, (socklen_t *)&len)) < 0) + { + ESP_LOGI(TAG, "socket accept failed"); + delay_ms(1000); + continue; + } + + printf("ESP32 HTTP server task > Client from %s %d\n", inet_ntoa(remote_addr.sin_addr), + htons(remote_addr.sin_port)); + // xTaskCreate(task_http_server_client, "task_http_server_client", 1024, + // &client_sock, 1, NULL); + task_http_server_client(&sock_id); + } + + vTaskDelete(NULL); +} void alexa_init(void) { - udp_connected = connect_udp(); - if (!udp_connected) { - ESP_LOGE(TAG, "udp connect failed!"); - return; - } - xTaskCreate(&alexa_http_task, "alexa_http_task", ALEXA_TASK_STACK_SIZE, NULL, ALEXA_TASK_PRIO, NULL); + udp_connected = connect_udp(); + if (!udp_connected) + { + ESP_LOGE(TAG, "udp connect failed!"); + return; + } + xTaskCreate(&alexa_http_task, "alexa_http_task", ALEXA_TASK_STACK_SIZE, NULL, ALEXA_TASK_PRIO, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/utils/utils.c b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/utils/utils.c index a6ca28d..4fc3815 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/utils/utils.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/components/utils/utils.c @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "utils.h" + #include -#include "utils.h" #include "esp_log.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -24,21 +24,18 @@ static const char *TAG = "utils"; void printHex(char c) { - char buff[3] = {0x0}; - sprintf(buff, "%02X ", c); - ESP_LOGI(TAG, "%s", buff); + char buff[3] = {0x0}; + sprintf(buff, "%02X ", c); + ESP_LOGI(TAG, "%s", buff); } -void delay_ms(int ms) -{ - vTaskDelay(ms / portTICK_RATE_MS); -} +void delay_ms(int ms) { vTaskDelay(ms / portTICK_RATE_MS); } void ip_addr_to_num(unsigned char *res, ip_addr_t *addr) { - unsigned int ip = (addr->u_addr).ip4.addr; - res[0] = (unsigned char)(ip & 0xFF); - res[1] = (unsigned char)((ip >> 8) & 0xFF); - res[2] = (unsigned char)((ip >> 16) & 0xFF); - res[3] = (unsigned char)((ip >> 24) & 0xFF); + unsigned int ip = (addr->u_addr).ip4.addr; + res[0] = (unsigned char)(ip & 0xFF); + res[1] = (unsigned char)((ip >> 8) & 0xFF); + res[2] = (unsigned char)((ip >> 16) & 0xFF); + res[3] = (unsigned char)((ip >> 24) & 0xFF); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c index 26004b7..a413e8e 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_esp32/main/main.c @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - /** * Nicholas3388 * 2017.06.02 @@ -20,124 +19,120 @@ * www.doit.am */ -#include "user_config.h" #include "alexa.h" -#include "esp_wifi.h" +#include "driver/gpio.h" #include "esp_event_loop.h" #include "esp_log.h" +#include "esp_wifi.h" #include "freertos/event_groups.h" -#include "driver/gpio.h" +#include "user_config.h" static const char *TAG = "main"; -static const int CONNECTED_BIT = BIT0; +static const int CONNECTED_BIT = BIT0; static EventGroupHandle_t wifi_event_group; -static uint8_t wifi_mac[6] = {0}; +static uint8_t wifi_mac[6] = {0}; static tcpip_adapter_ip_info_t ip_info; -static char local_ip[16] = {0}; +static char local_ip[16] = {0}; static unsigned char local_ip_num[4] = {0}; -char *get_local_ip(void) -{ - return local_ip; -} +char *get_local_ip(void) { return local_ip; } -unsigned char *get_ip_num(void) -{ - return local_ip_num; -} +unsigned char *get_ip_num(void) { return local_ip_num; } static void save_ip_num(uint32_t ip) { - local_ip_num[0] = (unsigned char)(ip & 0xFF); - local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); - local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); - local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); + local_ip_num[0] = (unsigned char)(ip & 0xFF); + local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); + local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); + local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); } static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; } return ESP_OK; } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) + { ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "IP:" IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:" IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:" IPSTR, IP2STR(&ip_info.gw)); ESP_LOGI(TAG, "~~~~~~~~~~~"); - sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); - save_ip_num(ip_info.ip.addr); + sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); + save_ip_num(ip_info.ip.addr); } ESP_LOGI(TAG, "AP+STA started"); - alexa_init(); - } - vTaskDelete(NULL); + alexa_init(); + } + vTaskDelete(NULL); } static void initialise_wifi(void) { - tcpip_adapter_init(); - - wifi_config_t sta_config = { - .sta = { - .ssid = MY_WIFI_SSID, - .password = MY_WIFI_PASS, - .bssid_set = false - }, - }; - - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + tcpip_adapter_init(); - esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); - if (er != ESP_OK) { - ESP_LOGE(TAG, "get wifi MAC failed"); - } else { - ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); - } + wifi_config_t sta_config = { + .sta = {.ssid = MY_WIFI_SSID, .password = MY_WIFI_PASS, .bssid_set = false}, + }; - ESP_ERROR_CHECK(esp_wifi_start()); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + + esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); + if (er != ESP_OK) + { + ESP_LOGE(TAG, "get wifi MAC failed"); + } + else + { + ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], + wifi_mac[4], wifi_mac[5]); + } + ESP_ERROR_CHECK(esp_wifi_start()); } void gpio_init(void) { - gpio_pad_select_gpio(GPIO_TEST); - gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_TEST, 0); + gpio_pad_select_gpio(GPIO_TEST); + gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_TEST, 0); } void app_main(void) { - ESP_LOGI(TAG, "enter main"); - initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); - gpio_init(); + ESP_LOGI(TAG, "enter main"); + initialise_wifi(); + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); + gpio_init(); } diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa.c b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa.c index 0faddd1..c25d21d 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa.c @@ -12,79 +12,57 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "alexa.h" + #include -#include "alexa.h" -#include "utils.h" #include "alexa_device.h" -#include "upnp_broadcast_responder.h" -#include "user_config.h" -#include "esp_log.h" #include "driver/gpio.h" +#include "esp_log.h" #include "lwip/api.h" -#include "lwip/sockets.h" #include "lwip/igmp.h" - +#include "lwip/sockets.h" +#include "upnp_broadcast_responder.h" +#include "user_config.h" +#include "utils.h" static const char *TAG = "alexa"; static const char *relay_name = "receptacle"; static const char *backlight_name = "backlight"; -void turn_on_relay(void) -{ - ESP_LOGI(TAG, "turn on relay"); -} +void turn_on_relay(void) { ESP_LOGI(TAG, "turn on relay"); } -void turn_off_relay(void) -{ - ESP_LOGI(TAG, "turn off relay"); -} +void turn_off_relay(void) { ESP_LOGI(TAG, "turn off relay"); } -void turn_on_backlight(void) -{ - ESP_LOGI(TAG, "turn on backlight"); -} +void turn_on_backlight(void) { ESP_LOGI(TAG, "turn on backlight"); } -void turn_off_backlight(void) -{ - ESP_LOGI(TAG, "turn off backlight"); -} +void turn_off_backlight(void) { ESP_LOGI(TAG, "turn off backlight"); } -void suspend_device(alexa_dev_t *dev) -{ - vTaskSuspend(dev->task_handle); -} +void suspend_device(alexa_dev_t *dev) { vTaskSuspend(dev->task_handle); } -void resume_device(alexa_dev_t *dev) -{ - vTaskResume(dev->task_handle); -} +void resume_device(alexa_dev_t *dev) { vTaskResume(dev->task_handle); } void alexa_init(void) { - alexa_device_list_init(); - upnp_broadcast_responder_init(); - - alexa_dev_t *relay = create_new_device(relay_name, 80, turn_on_relay, turn_off_relay); - if (relay == NULL) { - ESP_LOGE(TAG, "create relay device failed!"); - return; - } - delay_ms(2000); - - alexa_dev_t *backlight = create_new_device(backlight_name, 81, turn_on_backlight, turn_off_backlight); - if (backlight == NULL) { - ESP_LOGE(TAG, "create backlight device failed!"); - return; - } + alexa_device_list_init(); + upnp_broadcast_responder_init(); + + alexa_dev_t *relay = create_new_device(relay_name, 80, turn_on_relay, turn_off_relay); + if (relay == NULL) + { + ESP_LOGE(TAG, "create relay device failed!"); + return; + } + delay_ms(2000); + + alexa_dev_t *backlight = create_new_device(backlight_name, 81, turn_on_backlight, turn_off_backlight); + if (backlight == NULL) + { + ESP_LOGE(TAG, "create backlight device failed!"); + return; + } } -void alexa_suspend(void) -{ - alexa_device_list_traverse(suspend_device); -} +void alexa_suspend(void) { alexa_device_list_traverse(suspend_device); } -void alexa_resume(void) -{ - alexa_device_list_traverse(resume_device); -} +void alexa_resume(void) { alexa_device_list_traverse(resume_device); } diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa_device.c b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa_device.c index 259d029..775bbb9 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa_device.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/alexa_device.c @@ -12,24 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "alexa_device.h" + #include #include -#include "alexa_device.h" -#include "user_config.h" -#include "utils.h" #include "esp_log.h" - -#include "lwip/sockets.h" #include "lwip/igmp.h" +#include "lwip/sockets.h" +#include "user_config.h" +#include "utils.h" - -#define RECV_BUFFSIZE 1024 -#define MAX_HTTP_CLIENT_CONN 1 +#define RECV_BUFFSIZE 1024 +#define MAX_HTTP_CLIENT_CONN 1 static const char *TAG = "alexa_dev"; static alexa_dev_t root; -//static char *persistent_uuid = "Socket-1_0-38323636-4558-4dda-9188-cda0e6332211"; +// static char *persistent_uuid = +// "Socket-1_0-38323636-4558-4dda-9188-cda0e6332211"; static char *persistent_uuid = "Socket-1_0-38323636-4558-4dda-9188-cda0e63322"; static char text[RECV_BUFFSIZE + 1] = {0}; @@ -41,204 +41,238 @@ extern char *get_local_ip(void); // device list operations void alexa_device_remove(alexa_dev_t *dev) { - if (dev == NULL) { - return; - } - - alexa_dev_t *tmp = root.next; - alexa_dev_t *prev = &root; - int found = 0; - while (tmp != NULL) { - if (tmp == dev) { - found = 1; - break; - } - prev = tmp; - tmp = tmp->next; - } - - if (found == 1) { - ESP_LOGI(TAG, "remove device"); - prev = tmp->next; - vTaskDelete(tmp->task_handle); - free(tmp); - } + if (dev == NULL) + { + return; + } + + alexa_dev_t *tmp = root.next; + alexa_dev_t *prev = &root; + int found = 0; + while (tmp != NULL) + { + if (tmp == dev) + { + found = 1; + break; + } + prev = tmp; + tmp = tmp->next; + } + + if (found == 1) + { + ESP_LOGI(TAG, "remove device"); + prev = tmp->next; + vTaskDelete(tmp->task_handle); + free(tmp); + } } void alexa_device_add(alexa_dev_t *dev) { - if (dev == NULL) { - return; - } - - alexa_dev_t *tmp = &root; - while (tmp->next != NULL) { - tmp = tmp->next; - } - tmp->next = dev; + if (dev == NULL) + { + return; + } + + alexa_dev_t *tmp = &root; + while (tmp->next != NULL) { tmp = tmp->next; } + tmp->next = dev; } void alexa_device_list_init(void) { - memset((void *)&root, 0, sizeof(alexa_dev_t)); - root.next = NULL; + memset((void *)&root, 0, sizeof(alexa_dev_t)); + root.next = NULL; } alexa_dev_t *alexa_device_get_dev_by_index(int index) { - alexa_dev_t *tmp = root.next; - while (tmp != NULL) { - if (tmp->index == index) { - return tmp; - } - tmp = tmp->next; - } - return NULL; + alexa_dev_t *tmp = root.next; + while (tmp != NULL) + { + if (tmp->index == index) + { + return tmp; + } + tmp = tmp->next; + } + return NULL; } -int alexa_device_get_num(void) +int alexa_device_get_num(void) { - int num = 0; - alexa_dev_t *tmp = root.next; - while (tmp != NULL) { - num++; - tmp = tmp->next; - } - return num; + int num = 0; + alexa_dev_t *tmp = root.next; + while (tmp != NULL) + { + num++; + tmp = tmp->next; + } + return num; } void alexa_device_list_destroy(void) { - alexa_dev_t *tmp = NULL; - while (root.next != NULL) { - tmp = root.next; - root.next = tmp->next; - if (tmp->task_handle != NULL) { - vTaskDelete(tmp->task_handle); - } - free(tmp); - } + alexa_dev_t *tmp = NULL; + while (root.next != NULL) + { + tmp = root.next; + root.next = tmp->next; + if (tmp->task_handle != NULL) + { + vTaskDelete(tmp->task_handle); + } + free(tmp); + } } void alexa_device_list_traverse(void (*cb)(alexa_dev_t *dev)) { - alexa_dev_t *tmp = root.next; - while (tmp != NULL) { - if (cb != NULL) { - cb(tmp); - } - tmp = tmp->next; - } + alexa_dev_t *tmp = root.next; + while (tmp != NULL) + { + if (cb != NULL) + { + cb(tmp); + } + tmp = tmp->next; + } } //////////////////////////////////////////////// -// +// void response_to_search(struct netconn *udpconn, unsigned char *addr, int port) { - char resp[768] = {0}; - char *local_ip = get_local_ip(); - - alexa_dev_t *tmp = root.next; - while (tmp != NULL) { - int local_port = tmp->local_port; - char p[4] = {0}; - sprintf(p, "%d", local_port); - sprintf(resp, - "HTTP/1.1 200 OK\r\n" - "CACHE-CONTROL: max-age=86400\r\n" - "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n" - "EXT:\r\n" - "LOCATION: http://%s:%s/setup.xml\r\n" - "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" - "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n" - "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n" - "ST: urn:Belkin:device:**\r\n" - "USN: uuid:%s%s::urn:Belkin:device:**\r\n" - "X-User-Agent: redsonic\r\n\r\n", local_ip, p, persistent_uuid, p); - - struct netbuf *sentbuf = netbuf_new(); - if (sentbuf == NULL) { - ESP_LOGE(TAG, "netbuf alloc failed"); - return; - } - netbuf_alloc(sentbuf, strlen(resp)); - memcpy(sentbuf->p->payload, (void*)resp, strlen(resp)); - ip_addr_t dest; - IP_ADDR4(&dest, addr[0], addr[1], addr[2], addr[3]); - err_t err = netconn_sendto(udpconn, sentbuf, &dest, port); - if (err != 0) { - ESP_LOGE(TAG, "udp send data failed!"); - } - ESP_LOGI(TAG, "sent: %s", resp); - netbuf_delete(sentbuf); - - tmp = tmp->next; - } + char resp[768] = {0}; + char *local_ip = get_local_ip(); + + alexa_dev_t *tmp = root.next; + while (tmp != NULL) + { + int local_port = tmp->local_port; + char p[4] = {0}; + sprintf(p, "%d", local_port); + sprintf(resp, + "HTTP/1.1 200 OK\r\n" + "CACHE-CONTROL: max-age=86400\r\n" + "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n" + "EXT:\r\n" + "LOCATION: http://%s:%s/setup.xml\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" + "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n" + "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n" + "ST: urn:Belkin:device:**\r\n" + "USN: uuid:%s%s::urn:Belkin:device:**\r\n" + "X-User-Agent: redsonic\r\n\r\n", + local_ip, p, persistent_uuid, p); + + struct netbuf *sentbuf = netbuf_new(); + if (sentbuf == NULL) + { + ESP_LOGE(TAG, "netbuf alloc failed"); + return; + } + netbuf_alloc(sentbuf, strlen(resp)); + memcpy(sentbuf->p->payload, (void *)resp, strlen(resp)); + ip_addr_t dest; + IP_ADDR4(&dest, addr[0], addr[1], addr[2], addr[3]); + err_t err = netconn_sendto(udpconn, sentbuf, &dest, port); + if (err != 0) + { + ESP_LOGE(TAG, "udp send data failed!"); + } + ESP_LOGI(TAG, "sent: %s", resp); + netbuf_delete(sentbuf); + + tmp = tmp->next; + } } static int parse_http_request(int sock, char *data, int len, int port, alexa_dev_t *dev) { - if (NULL != strstr(data, "/index.html")) { - ESP_LOGI(TAG, "response to index.xml"); - char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 5\r\nConnection: close\r\n\r\n"; // 5 is the body length, if you change body content, - write(sock, header, strlen(header)); - char *body = "hello"; - write(sock, body, strlen(body)); - } else if (NULL != strstr(data, "/eventservice.xml")) { - ESP_LOGI(TAG, "response to eventservice.xml"); - char *eventservice_xml = "" + if (NULL != strstr(data, "/index.html")) + { + ESP_LOGI(TAG, "response to index.xml"); + char *header = + "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: " + "5\r\nConnection: close\r\n\r\n"; // 5 is the body length, if you + // change body content, + write(sock, header, strlen(header)); + char *body = "hello"; + write(sock, body, strlen(body)); + } + else if (NULL != strstr(data, "/eventservice.xml")) + { + ESP_LOGI(TAG, "response to eventservice.xml"); + char *eventservice_xml = + "" "" - "" - "SetBinaryState" - "" - "" - "" - "BinaryState" - "BinaryState" - "in" - "" - "" - "" - "" - "BinaryState" - "Boolean" - "0" - "" - "" - "level" - "string" - "0" - "" - "" - "" + "" + "SetBinaryState" + "" + "" + "" + "BinaryState" + "BinaryState" + "in" + "" + "" + "" + "" + "BinaryState" + "Boolean" + "0" + "" + "" + "level" + "string" + "0" + "" + "" + "" "\r\n" "\r\n"; - char header[256] = {0}; - int body_len = strlen(eventservice_xml); - sprintf(header, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", body_len); - write(sock, header, strlen(header)); - write(sock, eventservice_xml, body_len); - } else if (NULL != strstr(data, "/upnp/control/basicevent1")) { - ESP_LOGI(TAG, "response to /upnp/control/basicevent1"); - if (NULL != strstr(data, "1")) { - ESP_LOGI(TAG, "turn on LED"); - (dev->turn_on_cb)(); - } - if (NULL != strstr(data, "0")) { - ESP_LOGI(TAG, "turn off LED"); - (dev->turn_off_cb)(); - } - // you must response to Alexa when you finish your operation, otherwise, Alexa will say something like "You device is poweroff" - char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"; - write(sock, header, strlen(header)); - } else if (NULL != strstr(data, "/setup.xml")) { - ESP_LOGI(TAG, "response to setup.xml"); - char setup_xml[1024] = {0}; - char p[4] = {0}; - sprintf(p, "%d", port); - sprintf(setup_xml, "" - "" - "" + char header[256] = {0}; + int body_len = strlen(eventservice_xml); + sprintf(header, + "HTTP/1.1 200 OK\r\nContent-Type: " + "text/plain\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", + body_len); + write(sock, header, strlen(header)); + write(sock, eventservice_xml, body_len); + } + else if (NULL != strstr(data, "/upnp/control/basicevent1")) + { + ESP_LOGI(TAG, "response to /upnp/control/basicevent1"); + if (NULL != strstr(data, "1")) + { + ESP_LOGI(TAG, "turn on LED"); + (dev->turn_on_cb)(); + } + if (NULL != strstr(data, "0")) + { + ESP_LOGI(TAG, "turn off LED"); + (dev->turn_off_cb)(); + } + // you must response to Alexa when you finish your operation, otherwise, + // Alexa will say something like "You device is poweroff" + char *header = + "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: " + "0\r\nConnection: close\r\n\r\n"; + write(sock, header, strlen(header)); + } + else if (NULL != strstr(data, "/setup.xml")) + { + ESP_LOGI(TAG, "response to setup.xml"); + char setup_xml[1024] = {0}; + char p[4] = {0}; + sprintf(p, "%d", port); + sprintf(setup_xml, + "" + "" + "" "urn:Belkin:device:controllee:1" "%s" "Belkin International Inc." @@ -248,136 +282,160 @@ static int parse_http_request(int sock, char *data, int len, int port, alexa_dev "221517K0101769" "0" "" - "" - "urn:Belkin:service:basicevent:1" - "urn:Belkin:serviceId:basicevent1" - "/upnp/control/basicevent1" - "/upnp/event/basicevent1" - "/eventservice.xml" - "" - "" - "" - "\r\n" - "\r\n", dev->dev_name, persistent_uuid, p); - char header[256] = {0}; - int body_len = strlen(setup_xml); - sprintf(header, "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\nContent-Length: %d\r\nConnection: close\r\n\r\n", body_len); - write(sock, header, strlen(header)); - write(sock, setup_xml, body_len); - } else { - ESP_LOGE(TAG, "unknown http request?"); - } - return 0; + "" + "urn:Belkin:service:basicevent:1" + "urn:Belkin:serviceId:basicevent1" + "/upnp/control/basicevent1" + "/upnp/event/basicevent1" + "/eventservice.xml" + "" + "" + "" + "\r\n" + "\r\n", + dev->dev_name, persistent_uuid, p); + char header[256] = {0}; + int body_len = strlen(setup_xml); + sprintf(header, + "HTTP/1.1 200 OK\r\nContent-Type: text/xml\r\nContent-Length: " + "%d\r\nConnection: close\r\n\r\n", + body_len); + write(sock, header, strlen(header)); + write(sock, setup_xml, body_len); + } + else + { + ESP_LOGE(TAG, "unknown http request?"); + } + return 0; } static void task_http_server_client(int client_sock, int port, alexa_dev_t *dev) { - int recbytes = 0; - - ESP_LOGI(TAG, "setup socket:(%d)", client_sock); - - //int nNetTimeout = 5; - //setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, - // sizeof(int)); //non-block - while (1) { - recbytes = read(client_sock, text, RECV_BUFFSIZE); - if (recbytes > 0) { - text[recbytes] = 0; - ESP_LOGI(TAG, "(socket:%d) recieve:(%d): %s", client_sock, recbytes, text); - if (parse_http_request(client_sock, text, recbytes, port, dev) == 0) { - break; - } - } else if (recbytes == 0) { - break; - } - } - - ESP_LOGI(TAG, "task_http_server_client > close socket:(%d) port: (%d)\n", client_sock, port); - close(client_sock); + int recbytes = 0; + + ESP_LOGI(TAG, "setup socket:(%d)", client_sock); + + // int nNetTimeout = 5; + // setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, + // sizeof(int)); //non-block + while (1) + { + recbytes = read(client_sock, text, RECV_BUFFSIZE); + if (recbytes > 0) + { + text[recbytes] = 0; + ESP_LOGI(TAG, "(socket:%d) recieve:(%d): %s", client_sock, recbytes, text); + if (parse_http_request(client_sock, text, recbytes, port, dev) == 0) + { + break; + } + } + else if (recbytes == 0) + { + break; + } + } + + ESP_LOGI(TAG, "task_http_server_client > close socket:(%d) port: (%d)\n", client_sock, port); + close(client_sock); } static void alexa_http_task(void *pvParameter) { - int task_index = (int)pvParameter; - ESP_LOGI(TAG, "Starting ALEXA http task %d ...", task_index); - alexa_dev_t *dev_t = alexa_device_get_dev_by_index(task_index); - if (dev_t == NULL) { - ESP_LOGE(TAG, "alexa struct not found!"); - return; - } else { - ESP_LOGI(TAG, "got struct"); - } - int local_port = dev_t->local_port; - ESP_LOGI(TAG, "port : %d", local_port); - - int32_t listenfd; - struct sockaddr_in server_addr, remote_addr; - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_len = sizeof(server_addr); - server_addr.sin_port = htons(local_port); - - while ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ESP_LOGI(TAG, "http socket create failed"); - delay_ms(1000); - } - - while (bind(listenfd, (struct sockaddr * )&server_addr, sizeof(server_addr)) != 0) { - ESP_LOGI(TAG, "http socket bind failed"); - delay_ms(1000); - } - - while (listen(listenfd, MAX_HTTP_CLIENT_CONN) != 0) { - ESP_LOGI(TAG, "http socket listen failed"); - delay_ms(1000); - } - - int32_t len = sizeof(struct sockaddr_in); - - while (1) { - ESP_LOGI(TAG, "http wait client %d", task_index); - if ((dev_t->sock_id = accept(listenfd, (struct sockaddr * )&remote_addr, (socklen_t * )&len)) < 0) { - ESP_LOGI(TAG, "socket accept failed"); - delay_ms(1000); - continue; - } - - printf("ESP32 HTTP server task > Client from %s %d\n", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port)); - //xTaskCreate(task_http_server_client, "task_http_server_client", 1024, - // &client_sock, 1, NULL); - task_http_server_client(dev_t->sock_id, local_port, dev_t); - } - - vTaskDelete(NULL); + int task_index = (int)pvParameter; + ESP_LOGI(TAG, "Starting ALEXA http task %d ...", task_index); + alexa_dev_t *dev_t = alexa_device_get_dev_by_index(task_index); + if (dev_t == NULL) + { + ESP_LOGE(TAG, "alexa struct not found!"); + return; + } + else + { + ESP_LOGI(TAG, "got struct"); + } + int local_port = dev_t->local_port; + ESP_LOGI(TAG, "port : %d", local_port); + + int32_t listenfd; + struct sockaddr_in server_addr, remote_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_len = sizeof(server_addr); + server_addr.sin_port = htons(local_port); + + while ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + ESP_LOGI(TAG, "http socket create failed"); + delay_ms(1000); + } + + while (bind(listenfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) + { + ESP_LOGI(TAG, "http socket bind failed"); + delay_ms(1000); + } + + while (listen(listenfd, MAX_HTTP_CLIENT_CONN) != 0) + { + ESP_LOGI(TAG, "http socket listen failed"); + delay_ms(1000); + } + + int32_t len = sizeof(struct sockaddr_in); + + while (1) + { + ESP_LOGI(TAG, "http wait client %d", task_index); + if ((dev_t->sock_id = accept(listenfd, (struct sockaddr *)&remote_addr, (socklen_t *)&len)) < 0) + { + ESP_LOGI(TAG, "socket accept failed"); + delay_ms(1000); + continue; + } + + printf("ESP32 HTTP server task > Client from %s %d\n", inet_ntoa(remote_addr.sin_addr), + htons(remote_addr.sin_port)); + // xTaskCreate(task_http_server_client, "task_http_server_client", 1024, + // &client_sock, 1, NULL); + task_http_server_client(dev_t->sock_id, local_port, dev_t); + } + + vTaskDelete(NULL); } alexa_dev_t *create_new_device(const char *name, int port, void (*on_cb)(void), void (*off_cb)(void)) { - ESP_LOGI(TAG, "create new alexa device"); - - alexa_dev_t *new_dev = (alexa_dev_t *) malloc(sizeof(alexa_dev_t)); - if (new_dev == NULL) { - ESP_LOGE(TAG, "malloc for device struct failed!"); - return NULL; - } else { - ESP_LOGI(TAG, "alexa device malloc OK"); - } - - memset(new_dev->dev_name, 0, 20); - strcpy(new_dev->dev_name, name); - new_dev->local_port = port; - new_dev->turn_on_cb = on_cb; - new_dev->turn_off_cb = off_cb; - new_dev->task_handle = NULL; - new_dev->next = NULL; - ESP_LOGI(TAG, "dev set OK"); - - int index = alexa_device_get_num() + 1; - new_dev->index = index; - ESP_LOGI(TAG, "new device index: %d", new_dev->index); - alexa_device_add(new_dev); - xTaskCreate(&alexa_http_task, "alexa_http_task", ALEXA_TASK_STACK_SIZE, (void *)index, ALEXA_TASK_PRIO, &(new_dev->task_handle)); - - return new_dev; + ESP_LOGI(TAG, "create new alexa device"); + + alexa_dev_t *new_dev = (alexa_dev_t *)malloc(sizeof(alexa_dev_t)); + if (new_dev == NULL) + { + ESP_LOGE(TAG, "malloc for device struct failed!"); + return NULL; + } + else + { + ESP_LOGI(TAG, "alexa device malloc OK"); + } + + memset(new_dev->dev_name, 0, 20); + strcpy(new_dev->dev_name, name); + new_dev->local_port = port; + new_dev->turn_on_cb = on_cb; + new_dev->turn_off_cb = off_cb; + new_dev->task_handle = NULL; + new_dev->next = NULL; + ESP_LOGI(TAG, "dev set OK"); + + int index = alexa_device_get_num() + 1; + new_dev->index = index; + ESP_LOGI(TAG, "new device index: %d", new_dev->index); + alexa_device_add(new_dev); + xTaskCreate(&alexa_http_task, "alexa_http_task", ALEXA_TASK_STACK_SIZE, (void *)index, ALEXA_TASK_PRIO, + &(new_dev->task_handle)); + + return new_dev; } diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/upnp_broadcast_responder.c b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/upnp_broadcast_responder.c index b7781e3..e0b171e 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/upnp_broadcast_responder.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/alexa/upnp_broadcast_responder.c @@ -12,21 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include "upnp_broadcast_responder.h" -#include "user_config.h" -#include "utils.h" -#include "alexa_device.h" -#include "esp_log.h" +#include +#include "alexa_device.h" +#include "esp_log.h" #include "lwip/api.h" -#include "lwip/sockets.h" #include "lwip/igmp.h" +#include "lwip/sockets.h" +#include "user_config.h" +#include "utils.h" - -#define UDP_PORT 1900 -#define RECV_BUFFSIZE 1024 +#define UDP_PORT 1900 +#define RECV_BUFFSIZE 1024 static const char *TAG = "upnp_broadcast_responder"; static bool udp_connected = false; @@ -40,97 +39,113 @@ extern char *get_local_ip(void); static void parse_udp_data(char *data, int len, unsigned char *addr, int port) { - if (NULL != strstr(data, "M-SEARCH")) { - ESP_LOGI(TAG, "M-SEARCH"); - if (NULL != strstr(data, "urn:Belkin:device:**")) { - ESP_LOGI(TAG, "response to search request ......"); - response_to_search(udpconn, addr, port); - } - } + if (NULL != strstr(data, "M-SEARCH")) + { + ESP_LOGI(TAG, "M-SEARCH"); + if (NULL != strstr(data, "urn:Belkin:device:**")) + { + ESP_LOGI(TAG, "response to search request ......"); + response_to_search(udpconn, addr, port); + } + } } static void alexa_udp_task(void *pvParameter) { - struct netbuf *recvbuf; - struct pbuf *q; - - if (udp_connected) { - while (1) { - int data_len = 0; - netconn_recv(udpconn, &recvbuf); - if (recvbuf != NULL) { - int fromport = netbuf_fromport(recvbuf); - ip_addr_t *addr = netbuf_fromaddr(recvbuf); - unsigned char n_addr[4] = {0}; - ip_addr_to_num(n_addr, addr); - ESP_LOGI(TAG, "==> received from addr:%d.%d.%d.%d, port:%d", n_addr[0], n_addr[1], n_addr[2], n_addr[3], fromport); - // received data - memset(udp_buff, 0, RECV_BUFFSIZE + 1); - for(q=recvbuf->p; q!=NULL; q=q->next) { - if(q->len > (RECV_BUFFSIZE-data_len)) { - memcpy(udp_buff+data_len, q->payload, (RECV_BUFFSIZE-data_len)); - } else { - memcpy(udp_buff+data_len,q->payload,q->len); - } - data_len += q->len; - if(data_len > RECV_BUFFSIZE) { - ESP_LOGE(TAG, "receive buffer overflow!!!"); - break; - } - } - //ESP_LOGI(TAG, "==> received: %s", udp_buff); - parse_udp_data(udp_buff, data_len, n_addr, fromport); - netbuf_delete(recvbuf); // do not forget to delete netbuf - } - delay_ms(50); - } - } - vTaskDelete(NULL); + struct netbuf *recvbuf; + struct pbuf *q; + + if (udp_connected) + { + while (1) + { + int data_len = 0; + netconn_recv(udpconn, &recvbuf); + if (recvbuf != NULL) + { + int fromport = netbuf_fromport(recvbuf); + ip_addr_t *addr = netbuf_fromaddr(recvbuf); + unsigned char n_addr[4] = {0}; + ip_addr_to_num(n_addr, addr); + ESP_LOGI(TAG, "==> received from addr:%d.%d.%d.%d, port:%d", n_addr[0], n_addr[1], n_addr[2], n_addr[3], + fromport); + // received data + memset(udp_buff, 0, RECV_BUFFSIZE + 1); + for (q = recvbuf->p; q != NULL; q = q->next) + { + if (q->len > (RECV_BUFFSIZE - data_len)) + { + memcpy(udp_buff + data_len, q->payload, (RECV_BUFFSIZE - data_len)); + } + else + { + memcpy(udp_buff + data_len, q->payload, q->len); + } + data_len += q->len; + if (data_len > RECV_BUFFSIZE) + { + ESP_LOGE(TAG, "receive buffer overflow!!!"); + break; + } + } + // ESP_LOGI(TAG, "==> received: %s", udp_buff); + parse_udp_data(udp_buff, data_len, n_addr, fromport); + netbuf_delete(recvbuf); // do not forget to delete netbuf + } + delay_ms(50); + } + } + vTaskDelete(NULL); } static bool connect_udp(void) { - ESP_LOGI(TAG, "connecting to UDP"); - udpconn = netconn_new(NETCONN_UDP); - if (udpconn == NULL) { - ESP_LOGE(TAG, "new netconn failed"); - return false; - } - - err_t err = netconn_bind(udpconn, IP_ADDR_ANY, UDP_PORT); - if (err != 0) { - ESP_LOGE(TAG, "netconn bind failed"); - return false; - } - - ip_addr_t destipaddr; - IP_ADDR4(&destipaddr, 239, 255, 255, 250); - /*err = netconn_connect(udpconn, &destipaddr, UDP_PORT); - if (err != 0) { - ESP_LOGE(TAG, "netconn connect failed"); - return false; - }*/ - - unsigned char *ip_num = get_ip_num(); - ip_addr_t loc; - ESP_LOGI(TAG, "local ip: %d.%d.%d.%d", ip_num[0], ip_num[1], ip_num[2], ip_num[3]); - IP_ADDR4(&loc, ip_num[0], ip_num[1], ip_num[2], ip_num[3]); - if (igmp_joingroup(&loc, &destipaddr)!= ERR_OK) { - ESP_LOGE(TAG, "igmp join group failed"); + ESP_LOGI(TAG, "connecting to UDP"); + udpconn = netconn_new(NETCONN_UDP); + if (udpconn == NULL) + { + ESP_LOGE(TAG, "new netconn failed"); + return false; + } + + err_t err = netconn_bind(udpconn, IP_ADDR_ANY, UDP_PORT); + if (err != 0) + { + ESP_LOGE(TAG, "netconn bind failed"); return false; } - xTaskCreate(&alexa_udp_task, "alexa_udp_task", ALEXA_UDP_TASK_STACK_SIZE, NULL, ALEXA_UDP_TASK_PRIO, &udp_tsk_handle); - - return true; + ip_addr_t destipaddr; + IP_ADDR4(&destipaddr, 239, 255, 255, 250); + /*err = netconn_connect(udpconn, &destipaddr, UDP_PORT); + if (err != 0) { + ESP_LOGE(TAG, "netconn connect failed"); + return false; + }*/ + + unsigned char *ip_num = get_ip_num(); + ip_addr_t loc; + ESP_LOGI(TAG, "local ip: %d.%d.%d.%d", ip_num[0], ip_num[1], ip_num[2], ip_num[3]); + IP_ADDR4(&loc, ip_num[0], ip_num[1], ip_num[2], ip_num[3]); + if (igmp_joingroup(&loc, &destipaddr) != ERR_OK) + { + ESP_LOGE(TAG, "igmp join group failed"); + return false; + } + + xTaskCreate(&alexa_udp_task, "alexa_udp_task", ALEXA_UDP_TASK_STACK_SIZE, NULL, ALEXA_UDP_TASK_PRIO, + &udp_tsk_handle); + + return true; } void upnp_broadcast_responder_init(void) { - ESP_LOGI(TAG, "upnp broadcast responder init"); - udp_connected = connect_udp(); - if (!udp_connected) { - ESP_LOGE(TAG, "udp connect failed!"); - return; - } + ESP_LOGI(TAG, "upnp broadcast responder init"); + udp_connected = connect_udp(); + if (!udp_connected) + { + ESP_LOGE(TAG, "udp connect failed!"); + return; + } } diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/utils/utils.c b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/utils/utils.c index a6ca28d..4fc3815 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/utils/utils.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/components/utils/utils.c @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "utils.h" + #include -#include "utils.h" #include "esp_log.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -24,21 +24,18 @@ static const char *TAG = "utils"; void printHex(char c) { - char buff[3] = {0x0}; - sprintf(buff, "%02X ", c); - ESP_LOGI(TAG, "%s", buff); + char buff[3] = {0x0}; + sprintf(buff, "%02X ", c); + ESP_LOGI(TAG, "%s", buff); } -void delay_ms(int ms) -{ - vTaskDelay(ms / portTICK_RATE_MS); -} +void delay_ms(int ms) { vTaskDelay(ms / portTICK_RATE_MS); } void ip_addr_to_num(unsigned char *res, ip_addr_t *addr) { - unsigned int ip = (addr->u_addr).ip4.addr; - res[0] = (unsigned char)(ip & 0xFF); - res[1] = (unsigned char)((ip >> 8) & 0xFF); - res[2] = (unsigned char)((ip >> 16) & 0xFF); - res[3] = (unsigned char)((ip >> 24) & 0xFF); + unsigned int ip = (addr->u_addr).ip4.addr; + res[0] = (unsigned char)(ip & 0xFF); + res[1] = (unsigned char)((ip >> 8) & 0xFF); + res[2] = (unsigned char)((ip >> 16) & 0xFF); + res[3] = (unsigned char)((ip >> 24) & 0xFF); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c index 26004b7..a413e8e 100644 --- a/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/alexa_multi_esp32/main/main.c @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - /** * Nicholas3388 * 2017.06.02 @@ -20,124 +19,120 @@ * www.doit.am */ -#include "user_config.h" #include "alexa.h" -#include "esp_wifi.h" +#include "driver/gpio.h" #include "esp_event_loop.h" #include "esp_log.h" +#include "esp_wifi.h" #include "freertos/event_groups.h" -#include "driver/gpio.h" +#include "user_config.h" static const char *TAG = "main"; -static const int CONNECTED_BIT = BIT0; +static const int CONNECTED_BIT = BIT0; static EventGroupHandle_t wifi_event_group; -static uint8_t wifi_mac[6] = {0}; +static uint8_t wifi_mac[6] = {0}; static tcpip_adapter_ip_info_t ip_info; -static char local_ip[16] = {0}; +static char local_ip[16] = {0}; static unsigned char local_ip_num[4] = {0}; -char *get_local_ip(void) -{ - return local_ip; -} +char *get_local_ip(void) { return local_ip; } -unsigned char *get_ip_num(void) -{ - return local_ip_num; -} +unsigned char *get_ip_num(void) { return local_ip_num; } static void save_ip_num(uint32_t ip) { - local_ip_num[0] = (unsigned char)(ip & 0xFF); - local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); - local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); - local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); + local_ip_num[0] = (unsigned char)(ip & 0xFF); + local_ip_num[1] = (unsigned char)((ip >> 8) & 0xFF); + local_ip_num[2] = (unsigned char)((ip >> 16) & 0xFF); + local_ip_num[3] = (unsigned char)((ip >> 24) & 0xFF); } static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; } return ESP_OK; } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) + { ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "IP:" IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:" IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:" IPSTR, IP2STR(&ip_info.gw)); ESP_LOGI(TAG, "~~~~~~~~~~~"); - sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); - save_ip_num(ip_info.ip.addr); + sprintf(local_ip, IPSTR, IP2STR(&ip_info.ip)); + save_ip_num(ip_info.ip.addr); } ESP_LOGI(TAG, "AP+STA started"); - alexa_init(); - } - vTaskDelete(NULL); + alexa_init(); + } + vTaskDelete(NULL); } static void initialise_wifi(void) { - tcpip_adapter_init(); - - wifi_config_t sta_config = { - .sta = { - .ssid = MY_WIFI_SSID, - .password = MY_WIFI_PASS, - .bssid_set = false - }, - }; - - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + tcpip_adapter_init(); - esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); - if (er != ESP_OK) { - ESP_LOGE(TAG, "get wifi MAC failed"); - } else { - ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); - } + wifi_config_t sta_config = { + .sta = {.ssid = MY_WIFI_SSID, .password = MY_WIFI_PASS, .bssid_set = false}, + }; - ESP_ERROR_CHECK(esp_wifi_start()); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + + esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); + if (er != ESP_OK) + { + ESP_LOGE(TAG, "get wifi MAC failed"); + } + else + { + ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], + wifi_mac[4], wifi_mac[5]); + } + ESP_ERROR_CHECK(esp_wifi_start()); } void gpio_init(void) { - gpio_pad_select_gpio(GPIO_TEST); - gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); - gpio_set_level(GPIO_TEST, 0); + gpio_pad_select_gpio(GPIO_TEST); + gpio_set_direction(GPIO_TEST, GPIO_MODE_OUTPUT); + gpio_set_level(GPIO_TEST, 0); } void app_main(void) { - ESP_LOGI(TAG, "enter main"); - initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); - gpio_init(); + ESP_LOGI(TAG, "enter main"); + initialise_wifi(); + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); + gpio_init(); } diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_led_control/client/main/gattc_demo.c b/LuaNode_Esp32/LuaNode32/examples/ble_led_control/client/main/gattc_demo.c index a4b1f65..5197bf2 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_led_control/client/main/gattc_demo.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_led_control/client/main/gattc_demo.c @@ -13,39 +13,36 @@ // See the License for the specific language governing permissions and // limitations under the License. - - /**************************************************************************** -* -* This file is for gatt client. It can scan ble device, connect one device, -* -****************************************************************************/ + * + * This file is for gatt client. It can scan ble device, connect one device, + * + ****************************************************************************/ -#include -#include #include +#include #include -#include "controller.h" +#include #include "bt.h" #include "bt_trace.h" #include "bt_types.h" -#include "btm_api.h" #include "bta_api.h" #include "bta_gatt_api.h" +#include "btm_api.h" +#include "controller.h" +#include "esp_bt_main.h" #include "esp_gap_ble_api.h" -#include "esp_gattc_api.h" #include "esp_gatt_defs.h" -#include "esp_bt_main.h" - +#include "esp_gattc_api.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" -#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] +#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] -#define TEST_SRV_UUID 0x00FF -#define TEST_CHAR_UUID 0xFF01 +#define TEST_SRV_UUID 0x00FF +#define TEST_CHAR_UUID 0xFF01 static esp_gatt_if_t client_if; static uint16_t client_conn = 0; @@ -55,62 +52,86 @@ uint16_t simpleClient_id = 0xEE; const char device_name[] = "GATTS_LED_DEMO"; static char tar_dev_mac[6] = {0xff, 0xb5, 0x30, 0x4e, 0x0a, 0xcb}; -static const char tar_char[] = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e}; -static const char write_char[] = {0x6e, 0x40, 0x00, 0x03, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5, 0x0e, 0x24, 0xdc, 0xca, 0x9e}; +static const char tar_char[] = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, + 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e}; +static const char write_char[] = {0x6e, 0x40, 0x00, 0x03, 0xb5, 0xa3, 0xf3, 0x93, + 0xe0, 0xa9, 0xe5, 0x0e, 0x24, 0xdc, 0xca, 0x9e}; static esp_bd_addr_t server_dba; -static esp_ble_scan_params_t ble_scan_params = { - .scan_type = BLE_SCAN_TYPE_ACTIVE, - .own_addr_type = ESP_PUBLIC_ADDR, - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30 -}; +static esp_ble_scan_params_t ble_scan_params = {.scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = ESP_PUBLIC_ADDR, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x50, + .scan_window = 0x30}; static esp_gatt_srvc_id_t test_service_id = { - .id = { - .uuid = { - .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = TEST_SRV_UUID,}, + .id = + { + .uuid = + { + .len = ESP_UUID_LEN_16, + .uuid = + { + .uuid16 = TEST_SRV_UUID, + }, + }, + .inst_id = 0, }, - .inst_id = 0, - }, .is_primary = true, }; static esp_gatt_id_t test_char_id = { - .uuid = { - .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = TEST_CHAR_UUID,}, - }, + .uuid = + { + .len = ESP_UUID_LEN_16, + .uuid = + { + .uuid16 = TEST_CHAR_UUID, + }, + }, .inst_id = 0, }; static esp_gatt_id_t notify_descr_id = { - .uuid = { - .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG,}, - }, + .uuid = + { + .len = ESP_UUID_LEN_16, + .uuid = + { + .uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG, + }, + }, .inst_id = 0, }; static esp_gatt_srvc_id_t nrf51_service_id = { - .id = { - .uuid = { - .len = ESP_UUID_LEN_128, - .uuid = {.uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e},}, + .id = + { + .uuid = + { + .len = ESP_UUID_LEN_128, + .uuid = + { + .uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, + 0x00, 0x40, 0x6e}, + }, + }, + .inst_id = 0, }, - .inst_id = 0, - }, .is_primary = true, }; static esp_gatt_id_t nrf51_char_id = { - .uuid = { - .len = ESP_UUID_LEN_128, - .uuid = {.uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e},}, - }, + .uuid = + { + .len = ESP_UUID_LEN_128, + .uuid = + { + .uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, + 0x40, 0x6e}, + }, + }, .inst_id = 0, }; @@ -123,579 +144,747 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp static void get_characteristic_property(uint32_t flag) { - int i; - ESP_LOGI(TAG, "======================================="); - for (i = 0; i < 8; i ++) { - switch (flag & (2 << i)) - { - case ESP_GATT_CHAR_PROP_BIT_BROADCAST: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_BROADCAST"); - break; - case ESP_GATT_CHAR_PROP_BIT_READ: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_READ"); - break; - case ESP_GATT_CHAR_PROP_BIT_WRITE_NR: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE_NR"); - break; - case ESP_GATT_CHAR_PROP_BIT_WRITE: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE"); - break; - case ESP_GATT_CHAR_PROP_BIT_NOTIFY: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_NOTIFY"); - break; - case ESP_GATT_CHAR_PROP_BIT_INDICATE: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_INDICATE"); - break; - case ESP_GATT_CHAR_PROP_BIT_AUTH: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_AUTH"); - break; - case ESP_GATT_CHAR_PROP_BIT_EXT_PROP: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_EXT_PROP"); - break; - default: - break; - } - } - ESP_LOGI(TAG, "======================================="); + int i; + ESP_LOGI(TAG, "======================================="); + for (i = 0; i < 8; i++) + { + switch (flag & (2 << i)) + { + case ESP_GATT_CHAR_PROP_BIT_BROADCAST: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_BROADCAST"); + break; + case ESP_GATT_CHAR_PROP_BIT_READ: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_READ"); + break; + case ESP_GATT_CHAR_PROP_BIT_WRITE_NR: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE_NR"); + break; + case ESP_GATT_CHAR_PROP_BIT_WRITE: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE"); + break; + case ESP_GATT_CHAR_PROP_BIT_NOTIFY: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_NOTIFY"); + break; + case ESP_GATT_CHAR_PROP_BIT_INDICATE: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_INDICATE"); + break; + case ESP_GATT_CHAR_PROP_BIT_AUTH: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_AUTH"); + break; + case ESP_GATT_CHAR_PROP_BIT_EXT_PROP: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_EXT_PROP"); + break; + default: + break; + } + } + ESP_LOGI(TAG, "======================================="); } static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { uint8_t *adv_name = NULL; uint8_t adv_name_len = 0; - switch (event) { - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second - uint32_t duration = 10; - esp_ble_gap_start_scanning(duration); - break; - } - case ESP_GAP_BLE_SCAN_RESULT_EVT: { - esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.search_evt) { - case ESP_GAP_SEARCH_INQ_RES_EVT: - switch (scan_result->scan_rst.dev_type) { - case ESP_BT_DEVICE_TYPE_BREDR: - ESP_LOGI(TAG, "==> Connected Device type BREDR"); - break; - case ESP_BT_DEVICE_TYPE_BLE: - ESP_LOGI(TAG, "==> Connected Device type BLE"); - break; - case ESP_BT_DEVICE_TYPE_DUMO: - ESP_LOGI(TAG, "==> Connected Device type DUMO"); - break; - default: - break; - } - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - for (int i = 0; i < 6; i++) { - server_dba[i]=scan_result->scan_rst.bda[i]; - } - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); - LOG_INFO("adv_name_len=%x\n", adv_name_len); - /*for (int j = 0; j < adv_name_len; j++) { - LOG_INFO("a%d %x %c = d%d %x %c",j, adv_name[j], adv_name[j],j, device_name[j], device_name[j]); - }*/ - - if (strncmp((char *)adv_name, device_name,adv_name_len) == 0 && connet == false) { - connet = true; - ESP_LOGI(TAG, "==> address type: %d, dev name: %s", scan_result->scan_rst.ble_addr_type, adv_name); - LOG_INFO("Connect to the remote device."); - esp_ble_gap_stop_scanning(); - esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); - memcpy(tar_dev_mac, scan_result->scan_rst.bda, 6); - } + switch (event) + { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + { + // the unit of the duration is second + uint32_t duration = 10; + esp_ble_gap_start_scanning(duration); break; - case ESP_GAP_SEARCH_INQ_CMPL_EVT: - //esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.ble_evt_type) { - case ESP_BLE_EVT_CONN_ADV: - ESP_LOGI(TAG, "==> CONN_ADV"); - ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); - ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); - break; - case ESP_BLE_EVT_CONN_DIR_ADV: - ESP_LOGI(TAG, "==> CONN_DIR_ADV"); - break; - case ESP_BLE_EVT_DISC_ADV: - ESP_LOGI(TAG, "==> DISC_ADV"); - break; - case ESP_BLE_EVT_NON_CONN_ADV: - ESP_LOGI(TAG, "==> NON_CONN_ADV"); - break; - case ESP_BLE_EVT_SCAN_RSP: - ESP_LOGI(TAG, "==> receive scan response"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - } + } + case ESP_GAP_BLE_SCAN_RESULT_EVT: + { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) + { + case ESP_GAP_SEARCH_INQ_RES_EVT: + switch (scan_result->scan_rst.dev_type) + { + case ESP_BT_DEVICE_TYPE_BREDR: + ESP_LOGI(TAG, "==> Connected Device type BREDR"); + break; + case ESP_BT_DEVICE_TYPE_BLE: + ESP_LOGI(TAG, "==> Connected Device type BLE"); + break; + case ESP_BT_DEVICE_TYPE_DUMO: + ESP_LOGI(TAG, "==> Connected Device type DUMO"); + break; + default: + break; + } + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + for (int i = 0; i < 6; i++) { server_dba[i] = scan_result->scan_rst.bda[i]; } + adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); + LOG_INFO("adv_name_len=%x\n", adv_name_len); + /*for (int j = 0; j < adv_name_len; j++) { + LOG_INFO("a%d %x %c = d%d %x %c",j, adv_name[j], + adv_name[j],j, device_name[j], device_name[j]); + }*/ + + if (strncmp((char *)adv_name, device_name, adv_name_len) == 0 && connet == false) + { + connet = true; + ESP_LOGI(TAG, "==> address type: %d, dev name: %s", scan_result->scan_rst.ble_addr_type, + adv_name); + LOG_INFO("Connect to the remote device."); + esp_ble_gap_stop_scanning(); + esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); + memcpy(tar_dev_mac, scan_result->scan_rst.bda, 6); + } + break; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + // esp_ble_gap_cb_param_t *scan_result = + // (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.ble_evt_type) + { + case ESP_BLE_EVT_CONN_ADV: + ESP_LOGI(TAG, "==> CONN_ADV"); + ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], + scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); + ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); + break; + case ESP_BLE_EVT_CONN_DIR_ADV: + ESP_LOGI(TAG, "==> CONN_DIR_ADV"); + break; + case ESP_BLE_EVT_DISC_ADV: + ESP_LOGI(TAG, "==> DISC_ADV"); + break; + case ESP_BLE_EVT_NON_CONN_ADV: + ESP_LOGI(TAG, "==> NON_CONN_ADV"); + break; + case ESP_BLE_EVT_SCAN_RSP: + ESP_LOGI(TAG, "==> receive scan response"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], + scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + } + break; + default: + break; + } break; + } default: break; - } - break; - } - default: - break; } } - static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) { uint16_t conn_id = 0; esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; LOG_INFO("esp_gattc_cb, event = %x", event); - switch (event) { - case ESP_GATTC_REG_EVT: - status = p_data->reg.status; - LOG_INFO("ESP_GATTC_REG_EVT status = %x, client_if = %x", status, gattc_if); - if (status == ESP_GATT_OK) { - client_if = gattc_if; - } else { - LOG_INFO("ESP_GATTC_REG failed!"); - } - break; - case ESP_GATTC_OPEN_EVT: - conn_id = p_data->open.conn_id; - LOG_INFO("ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d", conn_id, gattc_if, p_data->open.status); - if (p_data->open.status != 0) { - LOG_INFO("==> open GATTC error, closed"); - esp_ble_gattc_close(gattc_if, conn_id); - esp_ble_gattc_open(gattc_if, (uint8_t *)tar_dev_mac, true); - break; - } - esp_ble_gattc_search_service(gattc_if, conn_id, NULL); - client_conn = conn_id; - break; - case ESP_GATTC_CLOSE_EVT: - LOG_INFO("==> GATTC closed"); - task_run = false; - client_conn = 0; - break; - case ESP_GATTC_READ_CHAR_EVT: { - // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; - esp_gatt_id_t *char_id = &p_data->read.char_id; - conn_id = p_data->open.conn_id; - LOG_INFO("READ CHAR: open.conn_id = %x search_res.conn_id = %x read.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->read.conn_id); - LOG_INFO("READ CHAR: read.status = %x inst_id = %x", p_data->read.status, char_id->inst_id); - if (p_data->read.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); - } - for (int i = 0; i < p_data->read.value_len; i++) { - LOG_INFO("%x:", p_data->read.value[i]); + switch (event) + { + case ESP_GATTC_REG_EVT: + status = p_data->reg.status; + LOG_INFO("ESP_GATTC_REG_EVT status = %x, client_if = %x", status, gattc_if); + if (status == ESP_GATT_OK) + { + client_if = gattc_if; + } + else + { + LOG_INFO("ESP_GATTC_REG failed!"); + } + break; + case ESP_GATTC_OPEN_EVT: + conn_id = p_data->open.conn_id; + LOG_INFO("ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d", conn_id, gattc_if, p_data->open.status); + if (p_data->open.status != 0) + { + LOG_INFO("==> open GATTC error, closed"); + esp_ble_gattc_close(gattc_if, conn_id); + esp_ble_gattc_open(gattc_if, (uint8_t *)tar_dev_mac, true); + break; + } + esp_ble_gattc_search_service(gattc_if, conn_id, NULL); + client_conn = conn_id; + break; + case ESP_GATTC_CLOSE_EVT: + LOG_INFO("==> GATTC closed"); + task_run = false; + client_conn = 0; + break; + case ESP_GATTC_READ_CHAR_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; + esp_gatt_id_t *char_id = &p_data->read.char_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "READ CHAR: open.conn_id = %x search_res.conn_id = %x " + "read.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->read.conn_id); + LOG_INFO("READ CHAR: read.status = %x inst_id = %x", p_data->read.status, char_id->inst_id); + if (p_data->read.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); + } + for (int i = 0; i < p_data->read.value_len; i++) { LOG_INFO("%x:", p_data->read.value[i]); } } + break; } - break; - } - case ESP_GATTC_WRITE_CHAR_EVT: { - // esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; - esp_gatt_id_t *char_id = &p_data->write.char_id; - esp_gatt_id_t *descr_id = &p_data->write.descr_id; - conn_id = p_data->open.conn_id; - LOG_INFO("WRITE CHAR: open.conn_id = %x search_res.conn_id = %x write.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->write.conn_id); - LOG_INFO("WRITE CHAR: write.status = %x inst_id = %x", p_data->write.status, char_id->inst_id); - if (p_data->write.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); - } - if (descr_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); - } else if (descr_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); - } else if (descr_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Decr UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", descr_id->uuid.uuid.uuid128[0], - descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], descr_id->uuid.uuid.uuid128[3], - descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], descr_id->uuid.uuid.uuid128[6], - descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], descr_id->uuid.uuid.uuid128[9], - descr_id->uuid.uuid.uuid128[10], descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], - descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], descr_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); - } + case ESP_GATTC_WRITE_CHAR_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; + esp_gatt_id_t *char_id = &p_data->write.char_id; + esp_gatt_id_t *descr_id = &p_data->write.descr_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "WRITE CHAR: open.conn_id = %x search_res.conn_id = %x " + "write.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->write.conn_id); + LOG_INFO("WRITE CHAR: write.status = %x inst_id = %x", p_data->write.status, char_id->inst_id); + if (p_data->write.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); + } + if (descr_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Decr UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + descr_id->uuid.uuid.uuid128[0], descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], + descr_id->uuid.uuid.uuid128[3], descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], + descr_id->uuid.uuid.uuid128[6], descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], + descr_id->uuid.uuid.uuid128[9], descr_id->uuid.uuid.uuid128[10], + descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], + descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], + descr_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); + } + } + break; } - break; - } - case ESP_GATTC_SEARCH_RES_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; - conn_id = p_data->open.conn_id; - LOG_INFO("SEARCH RES: open.conn_id = %x search_res.conn_id = %x", conn_id,p_data->search_res.conn_id); - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", srvc_id->id.uuid.uuid.uuid128[0], - srvc_id->id.uuid.uuid.uuid128[1], srvc_id->id.uuid.uuid.uuid128[2], srvc_id->id.uuid.uuid.uuid128[3], - srvc_id->id.uuid.uuid.uuid128[4], srvc_id->id.uuid.uuid.uuid128[5], srvc_id->id.uuid.uuid.uuid128[6], - srvc_id->id.uuid.uuid.uuid128[7], srvc_id->id.uuid.uuid.uuid128[8], srvc_id->id.uuid.uuid.uuid128[9], - srvc_id->id.uuid.uuid.uuid128[10], srvc_id->id.uuid.uuid.uuid128[11], srvc_id->id.uuid.uuid.uuid128[12], - srvc_id->id.uuid.uuid.uuid128[13], srvc_id->id.uuid.uuid.uuid128[14], srvc_id->id.uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("UNKNOWN LEN %d", srvc_id->id.uuid.len); + case ESP_GATTC_SEARCH_RES_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; + conn_id = p_data->open.conn_id; + LOG_INFO("SEARCH RES: open.conn_id = %x search_res.conn_id = %x", conn_id, p_data->search_res.conn_id); + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("UUID16: %x", srvc_id->id.uuid.uuid.uuid16); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("UUID32: %x", srvc_id->id.uuid.uuid.uuid32); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", srvc_id->id.uuid.uuid.uuid128[0], + srvc_id->id.uuid.uuid.uuid128[1], srvc_id->id.uuid.uuid.uuid128[2], + srvc_id->id.uuid.uuid.uuid128[3], srvc_id->id.uuid.uuid.uuid128[4], + srvc_id->id.uuid.uuid.uuid128[5], srvc_id->id.uuid.uuid.uuid128[6], + srvc_id->id.uuid.uuid.uuid128[7], srvc_id->id.uuid.uuid.uuid128[8], + srvc_id->id.uuid.uuid.uuid128[9], srvc_id->id.uuid.uuid.uuid128[10], + srvc_id->id.uuid.uuid.uuid128[11], srvc_id->id.uuid.uuid.uuid128[12], + srvc_id->id.uuid.uuid.uuid128[13], srvc_id->id.uuid.uuid.uuid128[14], + srvc_id->id.uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("UNKNOWN LEN %d", srvc_id->id.uuid.len); + } + esp_ble_gattc_get_characteristic(gattc_if, p_data->search_res.conn_id, srvc_id, NULL); + break; } - esp_ble_gattc_get_characteristic(gattc_if, p_data->search_res.conn_id, srvc_id, NULL); - break; - } - case ESP_GATTC_WRITE_DESCR_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; - esp_gatt_id_t *char_id = &p_data->write.char_id; - esp_gatt_id_t *descr_id = &p_data->write.descr_id; - conn_id = p_data->open.conn_id; - LOG_INFO("WRITE DESCR: open.conn_id = %x search_res.conn_id = %x write.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->write.conn_id); - LOG_INFO("WRITE DESCR: write.status = %x inst_id = %x open.gatt_if = %x", p_data->write.status, char_id->inst_id,gattc_if); - if (p_data->write.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); - } - if (descr_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); - } else if (descr_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); - } else if (descr_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Decr UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", descr_id->uuid.uuid.uuid128[0], - descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], descr_id->uuid.uuid.uuid128[3], - descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], descr_id->uuid.uuid.uuid128[6], - descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], descr_id->uuid.uuid.uuid128[9], - descr_id->uuid.uuid.uuid128[10], descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], - descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], descr_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); - } - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("SRVC UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("SRVC UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("SRVC UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", srvc_id->id.uuid.uuid.uuid128[0], - srvc_id->id.uuid.uuid.uuid128[1], srvc_id->id.uuid.uuid.uuid128[2], srvc_id->id.uuid.uuid.uuid128[3], - srvc_id->id.uuid.uuid.uuid128[4], srvc_id->id.uuid.uuid.uuid128[5], srvc_id->id.uuid.uuid.uuid128[6], - srvc_id->id.uuid.uuid.uuid128[7], srvc_id->id.uuid.uuid.uuid128[8], srvc_id->id.uuid.uuid.uuid128[9], - srvc_id->id.uuid.uuid.uuid128[10], srvc_id->id.uuid.uuid.uuid128[11], srvc_id->id.uuid.uuid.uuid128[12], - srvc_id->id.uuid.uuid.uuid128[13], srvc_id->id.uuid.uuid.uuid128[14], srvc_id->id.uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("SRVC UNKNOWN LEN %d", srvc_id->id.uuid.len); - } - LOG_INFO("WRITE DESCR: gattc_if = %x",gattc_if); - LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:",p_data->open.remote_bda[0], - p_data->open.remote_bda[1],p_data->open.remote_bda[2], - p_data->open.remote_bda[3],p_data->open.remote_bda[4], - p_data->open.remote_bda[5]); - LOG_INFO("server_dba %x,%x,%x,%x,%x,%x:",server_dba[0], - server_dba[1],server_dba[2], - server_dba[3],server_dba[4], - server_dba[5]); + case ESP_GATTC_WRITE_DESCR_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; + esp_gatt_id_t *char_id = &p_data->write.char_id; + esp_gatt_id_t *descr_id = &p_data->write.descr_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "WRITE DESCR: open.conn_id = %x search_res.conn_id = %x " + "write.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->write.conn_id); + LOG_INFO("WRITE DESCR: write.status = %x inst_id = %x open.gatt_if = %x", p_data->write.status, + char_id->inst_id, gattc_if); + if (p_data->write.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); + } + if (descr_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Decr UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + descr_id->uuid.uuid.uuid128[0], descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], + descr_id->uuid.uuid.uuid128[3], descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], + descr_id->uuid.uuid.uuid128[6], descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], + descr_id->uuid.uuid.uuid128[9], descr_id->uuid.uuid.uuid128[10], + descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], + descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], + descr_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); + } + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("SRVC UUID16: %x", srvc_id->id.uuid.uuid.uuid16); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("SRVC UUID32: %x", srvc_id->id.uuid.uuid.uuid32); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "SRVC UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + srvc_id->id.uuid.uuid.uuid128[0], srvc_id->id.uuid.uuid.uuid128[1], + srvc_id->id.uuid.uuid.uuid128[2], srvc_id->id.uuid.uuid.uuid128[3], + srvc_id->id.uuid.uuid.uuid128[4], srvc_id->id.uuid.uuid.uuid128[5], + srvc_id->id.uuid.uuid.uuid128[6], srvc_id->id.uuid.uuid.uuid128[7], + srvc_id->id.uuid.uuid.uuid128[8], srvc_id->id.uuid.uuid.uuid128[9], + srvc_id->id.uuid.uuid.uuid128[10], srvc_id->id.uuid.uuid.uuid128[11], + srvc_id->id.uuid.uuid.uuid128[12], srvc_id->id.uuid.uuid.uuid128[13], + srvc_id->id.uuid.uuid.uuid128[14], srvc_id->id.uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("SRVC UNKNOWN LEN %d", srvc_id->id.uuid.len); + } + LOG_INFO("WRITE DESCR: gattc_if = %x", gattc_if); + LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:", p_data->open.remote_bda[0], p_data->open.remote_bda[1], + p_data->open.remote_bda[2], p_data->open.remote_bda[3], p_data->open.remote_bda[4], + p_data->open.remote_bda[5]); + LOG_INFO("server_dba %x,%x,%x,%x,%x,%x:", server_dba[0], server_dba[1], server_dba[2], server_dba[3], + server_dba[4], server_dba[5]); + } + break; } - break; - } - case ESP_GATTC_NOTIFY_EVT: { - // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; - esp_gatt_id_t *char_id = &p_data->notify.char_id; - conn_id = p_data->open.conn_id; - LOG_INFO("NOTIFY: open.conn_id = %x search_res.conn_id = %x notify.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->notify.conn_id); - LOG_INFO("NOTIFY: notify.is_notify = %x inst_id = %x", p_data->notify.is_notify, char_id->inst_id); - if (p_data->notify.is_notify==1) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); - } - for (int i = 0; i < p_data->notify.value_len; i++) { - LOG_INFO("NOTIFY: V%d %x:", i, p_data->notify.value[i]); + case ESP_GATTC_NOTIFY_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; + esp_gatt_id_t *char_id = &p_data->notify.char_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "NOTIFY: open.conn_id = %x search_res.conn_id = %x " + "notify.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->notify.conn_id); + LOG_INFO("NOTIFY: notify.is_notify = %x inst_id = %x", p_data->notify.is_notify, char_id->inst_id); + if (p_data->notify.is_notify == 1) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); + } + for (int i = 0; i < p_data->notify.value_len; i++) + { LOG_INFO("NOTIFY: V%d %x:", i, p_data->notify.value[i]); } } + break; } - break; - } - case ESP_GATTC_GET_CHAR_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->get_char.srvc_id; - esp_gatt_id_t *char_id = &p_data->get_char.char_id; - conn_id = p_data->open.conn_id; - LOG_INFO("GET CHAR: open.conn_id = %x search_res.conn_id = %x get_char.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->get_char.conn_id); - LOG_INFO("GET CHAR: get_char.char_prop = %x get_char.status = %x inst_id = %x open.gatt_if = %x", p_data->get_char.char_prop, p_data->get_char.status, char_id->inst_id,gattc_if); - LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:",p_data->open.remote_bda[0], - p_data->open.remote_bda[1],p_data->open.remote_bda[2], - p_data->open.remote_bda[3],p_data->open.remote_bda[4], - p_data->open.remote_bda[5]); - if (p_data->get_char.status==0) { - // print characteristic property - get_characteristic_property(p_data->get_char.char_prop); - - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); - if (char_id->uuid.uuid.uuid16 == TEST_CHAR_UUID) { - ESP_LOGI(TAG, "register notify\n"); - esp_ble_gattc_register_for_notify(gattc_if, p_data->open.remote_bda, &test_service_id, &p_data->get_char.char_id); - } - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - - esp_ble_gattc_get_descriptor(gattc_if, conn_id, srvc_id, char_id, NULL); - esp_ble_gattc_get_characteristic(gattc_if, conn_id, srvc_id, char_id); - } else { - LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); - } - } else { - ESP_LOGE(TAG, "get characteristic failed"); - } - break; - } - case ESP_GATTC_GET_DESCR_EVT: { - //esp_gatt_srvc_id_t *srvc_id = &p_data->get_descr.srvc_id; - esp_gatt_id_t *char_id = &p_data->get_descr.char_id; - esp_gatt_id_t *descr_id = &p_data->get_descr.descr_id; - conn_id = p_data->open.conn_id; - LOG_INFO("GET DESCR: open.conn_id = %x search_res.conn_id = %x get_descr.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->get_descr.conn_id); - LOG_INFO("GET DESCR: get_descr.status = %x inst_id = %x open.gatt_if = %x", p_data->get_descr.status, char_id->inst_id,gattc_if); - //uint8_t value[2]; - //value[0]=0x01; - //value[1]=0x00; - if (p_data->get_descr.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); - } - if (descr_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); - } else if (descr_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); - } else if (descr_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Decr UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", descr_id->uuid.uuid.uuid128[0], - descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], descr_id->uuid.uuid.uuid128[3], - descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], descr_id->uuid.uuid.uuid128[6], - descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], descr_id->uuid.uuid.uuid128[9], - descr_id->uuid.uuid.uuid128[10], descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], - descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], descr_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); - } - /*esp_ble_gattc_write_char_descr ( - gattc_if, - conn_id, - srvc_id, - char_id, - descr_id, - 2, - &value[0], - ESP_GATT_WRITE_TYPE_NO_RSP, - ESP_GATT_AUTH_REQ_NONE);*/ + case ESP_GATTC_GET_CHAR_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->get_char.srvc_id; + esp_gatt_id_t *char_id = &p_data->get_char.char_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "GET CHAR: open.conn_id = %x search_res.conn_id = %x " + "get_char.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->get_char.conn_id); + LOG_INFO( + "GET CHAR: get_char.char_prop = %x get_char.status = %x " + "inst_id = %x open.gatt_if = %x", + p_data->get_char.char_prop, p_data->get_char.status, char_id->inst_id, gattc_if); + LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:", p_data->open.remote_bda[0], p_data->open.remote_bda[1], + p_data->open.remote_bda[2], p_data->open.remote_bda[3], p_data->open.remote_bda[4], + p_data->open.remote_bda[5]); + if (p_data->get_char.status == 0) + { + // print characteristic property + get_characteristic_property(p_data->get_char.char_prop); + + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); + if (char_id->uuid.uuid.uuid16 == TEST_CHAR_UUID) + { + ESP_LOGI(TAG, "register notify\n"); + esp_ble_gattc_register_for_notify(gattc_if, p_data->open.remote_bda, &test_service_id, + &p_data->get_char.char_id); + } + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + + esp_ble_gattc_get_descriptor(gattc_if, conn_id, srvc_id, char_id, NULL); + esp_ble_gattc_get_characteristic(gattc_if, conn_id, srvc_id, char_id); + } + else + { + LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); + } + } + else + { + ESP_LOGE(TAG, "get characteristic failed"); + } + break; } - break; - } - case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - LOG_INFO("NOTIFY_EVT: open.conn_id = %x ", p_data->open.conn_id); - LOG_INFO("NOTIFY_EVT: reg_for_notify.status = %x ", p_data->reg_for_notify.status); - esp_gatt_id_t *char_id = &p_data->reg_for_notify.char_id; - if (p_data->reg_for_notify.status==0) { - // send notify each 2 seconds - task_run = true; - - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); - } - - uint16_t notify_en = 1; - esp_err_t err = esp_ble_gattc_write_char_descr( - gattc_if, - conn_id, - &test_service_id, - &p_data->reg_for_notify.char_id, - ¬ify_descr_id, - sizeof(notify_en), - (uint8_t *)¬ify_en, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - if (err != 0) { - ESP_LOGE(TAG, "write char failed"); - } - } else { - ESP_LOGE(TAG, "notify register failed"); - } - break; - } - case ESP_GATTC_SEARCH_CMPL_EVT: - conn_id = p_data->search_cmpl.conn_id; - LOG_INFO("SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); - esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.ble_evt_type) { - case ESP_BLE_EVT_CONN_ADV: - ESP_LOGI(TAG, "==> CONN_ADV"); - ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); - ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); - /*esp_ble_gap_stop_scanning(); - esp_err_t err = esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); - ESP_LOGI(TAG, "==> esp_ble_gattc_open %d", err);*/ - break; - case ESP_BLE_EVT_CONN_DIR_ADV: - ESP_LOGI(TAG, "==> CONN_DIR_ADV"); - break; - case ESP_BLE_EVT_DISC_ADV: - ESP_LOGI(TAG, "==> DISC_ADV"); - break; - case ESP_BLE_EVT_NON_CONN_ADV: - ESP_LOGI(TAG, "==> NON_CONN_ADV"); - break; - case ESP_BLE_EVT_SCAN_RSP: - ESP_LOGI(TAG, "==> receive scan response"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - } - //esp_ble_gattc_get_characteristic(gattc_if, conn_id, &p_data->search_res.srvc_id, NULL); - break; - default: - break; + case ESP_GATTC_GET_DESCR_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->get_descr.srvc_id; + esp_gatt_id_t *char_id = &p_data->get_descr.char_id; + esp_gatt_id_t *descr_id = &p_data->get_descr.descr_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "GET DESCR: open.conn_id = %x search_res.conn_id = %x " + "get_descr.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->get_descr.conn_id); + LOG_INFO( + "GET DESCR: get_descr.status = %x inst_id = %x open.gatt_if = " + "%x", + p_data->get_descr.status, char_id->inst_id, gattc_if); + // uint8_t value[2]; + // value[0]=0x01; + // value[1]=0x00; + if (p_data->get_descr.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); + } + if (descr_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Decr UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + descr_id->uuid.uuid.uuid128[0], descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], + descr_id->uuid.uuid.uuid128[3], descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], + descr_id->uuid.uuid.uuid128[6], descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], + descr_id->uuid.uuid.uuid128[9], descr_id->uuid.uuid.uuid128[10], + descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], + descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], + descr_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); + } + /*esp_ble_gattc_write_char_descr ( + gattc_if, + conn_id, + srvc_id, + char_id, + descr_id, + 2, + &value[0], + ESP_GATT_WRITE_TYPE_NO_RSP, + ESP_GATT_AUTH_REQ_NONE);*/ + } + break; + } + case ESP_GATTC_REG_FOR_NOTIFY_EVT: + { + LOG_INFO("NOTIFY_EVT: open.conn_id = %x ", p_data->open.conn_id); + LOG_INFO("NOTIFY_EVT: reg_for_notify.status = %x ", p_data->reg_for_notify.status); + esp_gatt_id_t *char_id = &p_data->reg_for_notify.char_id; + if (p_data->reg_for_notify.status == 0) + { + // send notify each 2 seconds + task_run = true; + + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); + } + + uint16_t notify_en = 1; + esp_err_t err = esp_ble_gattc_write_char_descr( + gattc_if, conn_id, &test_service_id, &p_data->reg_for_notify.char_id, ¬ify_descr_id, + sizeof(notify_en), (uint8_t *)¬ify_en, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + if (err != 0) + { + ESP_LOGE(TAG, "write char failed"); + } + } + else + { + ESP_LOGE(TAG, "notify register failed"); + } + break; + } + case ESP_GATTC_SEARCH_CMPL_EVT: + conn_id = p_data->search_cmpl.conn_id; + LOG_INFO("SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.ble_evt_type) + { + case ESP_BLE_EVT_CONN_ADV: + ESP_LOGI(TAG, "==> CONN_ADV"); + ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); + ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); + /*esp_ble_gap_stop_scanning(); + esp_err_t err = esp_ble_gattc_open(client_if, + scan_result->scan_rst.bda, true); ESP_LOGI(TAG, "==> + esp_ble_gattc_open %d", err);*/ + break; + case ESP_BLE_EVT_CONN_DIR_ADV: + ESP_LOGI(TAG, "==> CONN_DIR_ADV"); + break; + case ESP_BLE_EVT_DISC_ADV: + ESP_LOGI(TAG, "==> DISC_ADV"); + break; + case ESP_BLE_EVT_NON_CONN_ADV: + ESP_LOGI(TAG, "==> NON_CONN_ADV"); + break; + case ESP_BLE_EVT_SCAN_RSP: + ESP_LOGI(TAG, "==> receive scan response"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + } + // esp_ble_gattc_get_characteristic(gattc_if, conn_id, + // &p_data->search_res.srvc_id, NULL); + break; + default: + break; } } static void led_task(void *arg) { - esp_err_t err; - uint16_t notify_en = 0; - - while (1) { - ESP_LOGI(TAG, "led_task is running"); - if (task_run) { - if (toggle == 0) { - notify_en = 0; - err = esp_ble_gattc_write_char_descr( - client_if, - client_conn, - &test_service_id, - &test_char_id, - ¬ify_descr_id, - sizeof(notify_en), - (uint8_t *)¬ify_en, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - if (err != 0) { - ESP_LOGE(TAG, "BLE charateristic write failed"); - } - toggle = 1; - ESP_LOGE(TAG, "BLE charateristic write notify 0"); - } else { - notify_en = 1; - err = esp_ble_gattc_write_char_descr( - client_if, - client_conn, - &test_service_id, - &test_char_id, - ¬ify_descr_id, - sizeof(notify_en), - (uint8_t *)¬ify_en, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - if (err != 0) { - ESP_LOGE(TAG, "BLE charateristic write failed"); - } - toggle = 0; - ESP_LOGE(TAG, "BLE charateristic write notify 1"); - } - } - vTaskDelay(2000 / portTICK_RATE_MS); - } - vTaskDelete(NULL); + esp_err_t err; + uint16_t notify_en = 0; + + while (1) + { + ESP_LOGI(TAG, "led_task is running"); + if (task_run) + { + if (toggle == 0) + { + notify_en = 0; + err = esp_ble_gattc_write_char_descr(client_if, client_conn, &test_service_id, &test_char_id, + ¬ify_descr_id, sizeof(notify_en), (uint8_t *)¬ify_en, + ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + if (err != 0) + { + ESP_LOGE(TAG, "BLE charateristic write failed"); + } + toggle = 1; + ESP_LOGE(TAG, "BLE charateristic write notify 0"); + } + else + { + notify_en = 1; + err = esp_ble_gattc_write_char_descr(client_if, client_conn, &test_service_id, &test_char_id, + ¬ify_descr_id, sizeof(notify_en), (uint8_t *)¬ify_en, + ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + if (err != 0) + { + ESP_LOGE(TAG, "BLE charateristic write failed"); + } + toggle = 0; + ESP_LOGE(TAG, "BLE charateristic write notify 1"); + } + } + vTaskDelay(2000 / portTICK_RATE_MS); + } + vTaskDelete(NULL); } void ble_client_appRegister(void) { LOG_INFO("register callback"); - //register the scan callback function to the Generic Access Profile (GAP) module - if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) { + // register the scan callback function to the Generic Access Profile (GAP) + // module + if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) + { LOG_ERROR("gap register error, error code = %x", status); return; } - //register the callback function to the Generic Attribute Profile (GATT) Client (GATTC) module - if ((status = esp_ble_gattc_register_callback(esp_gattc_cb)) != ESP_OK) { + // register the callback function to the Generic Attribute Profile (GATT) + // Client (GATTC) module + if ((status = esp_ble_gattc_register_callback(esp_gattc_cb)) != ESP_OK) + { LOG_ERROR("gattc register error, error code = %x", status); return; } @@ -716,6 +905,5 @@ void app_main() esp_bt_controller_enable(ESP_BT_MODE_BTDM); gattc_client_test(); - xTaskCreate(&led_task, "led_task", 2048, NULL, 6, &ledTaskHandle); + xTaskCreate(&led_task, "led_task", 2048, NULL, 6, &ledTaskHandle); } - diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_led_control/server/main/gatts_demo.c b/LuaNode_Esp32/LuaNode32/examples/ble_led_control/server/main/gatts_demo.c index 1222ed9..e645e61 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_led_control/server/main/gatts_demo.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_led_control/server/main/gatts_demo.c @@ -15,74 +15,102 @@ #include #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_log.h" -#include "nvs_flash.h" + #include "bt.h" #include "bta_api.h" - -#include "esp_gap_ble_api.h" -#include "esp_gatts_api.h" +#include "driver/gpio.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" -#include "esp_bt_main.h" - -#include "driver/gpio.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_log.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "sdkconfig.h" #define GATTS_TAG "GATTS_DEMO" -///Declare the static function -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); +/// Declare the static function +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param); +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param); -#define GATTS_SERVICE_UUID_TEST_A 0x00FF -#define GATTS_CHAR_UUID_TEST_A 0xFF01 -#define GATTS_DESCR_UUID_TEST_A 0x3333 -#define GATTS_NUM_HANDLE_TEST_A 4 +#define GATTS_SERVICE_UUID_TEST_A 0x00FF +#define GATTS_CHAR_UUID_TEST_A 0xFF01 +#define GATTS_DESCR_UUID_TEST_A 0x3333 +#define GATTS_NUM_HANDLE_TEST_A 4 -#define GATTS_SERVICE_UUID_TEST_B 0x00EE -#define GATTS_CHAR_UUID_TEST_B 0xEE01 -#define GATTS_DESCR_UUID_TEST_B 0x2222 -#define GATTS_NUM_HANDLE_TEST_B 4 +#define GATTS_SERVICE_UUID_TEST_B 0x00EE +#define GATTS_CHAR_UUID_TEST_B 0xEE01 +#define GATTS_DESCR_UUID_TEST_B 0x2222 +#define GATTS_NUM_HANDLE_TEST_B 4 -#define TEST_DEVICE_NAME "GATTS_LED_DEMO" -#define TEST_MANUFACTURER_DATA_LEN 17 +#define TEST_DEVICE_NAME "GATTS_LED_DEMO" +#define TEST_MANUFACTURER_DATA_LEN 17 #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 -#define LED_GPIO 2 +#define LED_GPIO 2 -uint8_t char1_str[] = {0x11,0x22,0x33}; -esp_attr_value_t gatts_demo_char1_val = -{ +uint8_t char1_str[] = {0x11, 0x22, 0x33}; +esp_attr_value_t gatts_demo_char1_val = { .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, - .attr_len = sizeof(char1_str), - .attr_value = char1_str, + .attr_len = sizeof(char1_str), + .attr_value = char1_str, }; #ifdef CONFIG_SET_RAW_ADV_DATA -static uint8_t raw_adv_data[] = { - 0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd -}; -static uint8_t raw_scan_rsp_data[] = { - 0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd -}; +static uint8_t raw_adv_data[] = {0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, + 0x53, 0x5f, 0x44, 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd}; +static uint8_t raw_scan_rsp_data[] = {0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, + 0x53, 0x5f, 0x44, 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd}; #else static uint8_t test_service_uuid128[32] = { - /* LSB <--------------------------------------------------------------------------------> MSB */ - //first uuid, 16bit, [12],[13] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0x00, 0x00, - //second uuid, 32bit, [12], [13], [14], [15] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD, + /* LSB + <--------------------------------------------------------------------------------> + MSB */ + // first uuid, 16bit, [12],[13] is the value + 0xfb, + 0x34, + 0x9b, + 0x5f, + 0x80, + 0x00, + 0x00, + 0x80, + 0x00, + 0x10, + 0x00, + 0x00, + 0xAB, + 0xCD, + 0x00, + 0x00, + // second uuid, 32bit, [12], [13], [14], [15] is the value + 0xfb, + 0x34, + 0x9b, + 0x5f, + 0x80, + 0x00, + 0x00, + 0x80, + 0x00, + 0x10, + 0x00, + 0x00, + 0xAB, + 0xCD, + 0xAB, + 0xCD, }; -//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56}; +// static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, +// 0x45, 0x56}; static esp_ble_adv_data_t test_adv_data = { .set_scan_rsp = false, .include_name = true, @@ -90,8 +118,8 @@ static esp_ble_adv_data_t test_adv_data = { .min_interval = 0x20, .max_interval = 0x40, .appearance = 0x00, - .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, - .p_manufacturer_data = NULL, //&test_manufacturer[0], + .manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN, + .p_manufacturer_data = NULL, //&test_manufacturer[0], .service_data_len = 0, .p_service_data = NULL, .service_uuid_len = 32, @@ -101,13 +129,13 @@ static esp_ble_adv_data_t test_adv_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t test_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, - .adv_type = ADV_TYPE_SCAN_IND, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .adv_int_min = 0x20, + .adv_int_max = 0x40, + .adv_type = ADV_TYPE_SCAN_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, //.peer_addr = //.peer_addr_type = - .channel_map = ADV_CHNL_ALL, + .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; @@ -115,7 +143,8 @@ static esp_ble_adv_params_t test_adv_params = { #define PROFILE_A_APP_ID 0 #define PROFILE_B_APP_ID 1 -struct gatts_profile_inst { +struct gatts_profile_inst +{ esp_gatts_cb_t gatts_cb; uint16_t gatts_if; uint16_t app_id; @@ -130,300 +159,341 @@ struct gatts_profile_inst { esp_bt_uuid_t descr_uuid; }; -/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */ +/* One gatt-based profile one app_id and one gatts_if, this array will store the + * gatts_if returned by ESP_GATTS_REG_EVT */ static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = { - [PROFILE_A_APP_ID] = { - .gatts_cb = gatts_profile_a_event_handler, - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, - [PROFILE_B_APP_ID] = { - .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, similar as profile A */ - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, + [PROFILE_A_APP_ID] = + { + .gatts_cb = gatts_profile_a_event_handler, .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial + is ESP_GATT_IF_NONE */ + }, + [PROFILE_B_APP_ID] = + { + .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, + similar as profile A */ + .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is + ESP_GATT_IF_NONE */ + }, }; static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.ble_evt_type) { - case ESP_BLE_EVT_CONN_ADV: - ESP_LOGI(TAG, "==> CONN_ADV"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - case ESP_BLE_EVT_CONN_DIR_ADV: - ESP_LOGI(TAG, "==> CONN_DIR_ADV"); - break; - case ESP_BLE_EVT_DISC_ADV: - ESP_LOGI(TAG, "==> DISC_ADV"); - break; - case ESP_BLE_EVT_NON_CONN_ADV: - ESP_LOGI(TAG, "==> NON_CONN_ADV"); - break; - case ESP_BLE_EVT_SCAN_RSP: - ESP_LOGI(TAG, "==> receive scan response"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - } - switch (event) { - case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: - //advertising start complete event to indicate advertising start successfully or failed - if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); - } - break; - default: - break; + switch (scan_result->scan_rst.ble_evt_type) + { + case ESP_BLE_EVT_CONN_ADV: + ESP_LOGI(TAG, "==> CONN_ADV"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + case ESP_BLE_EVT_CONN_DIR_ADV: + ESP_LOGI(TAG, "==> CONN_DIR_ADV"); + break; + case ESP_BLE_EVT_DISC_ADV: + ESP_LOGI(TAG, "==> DISC_ADV"); + break; + case ESP_BLE_EVT_NON_CONN_ADV: + ESP_LOGI(TAG, "==> NON_CONN_ADV"); + break; + case ESP_BLE_EVT_SCAN_RSP: + ESP_LOGI(TAG, "==> receive scan response"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + } + switch (event) + { + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + // advertising start complete event to indicate advertising start + // successfully or failed + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); + } + break; + default: + break; } } -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; - - esp_ble_gap_set_device_name(TEST_DEVICE_NAME); +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) + { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; + + esp_ble_gap_set_device_name(TEST_DEVICE_NAME); #ifdef CONFIG_SET_RAW_ADV_DATA - esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); - esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); + esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); + esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); #else - esp_ble_gap_config_adv_data(&test_adv_data); + esp_ble_gap_config_adv_data(&test_adv_data); #endif - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A); - break; - case ESP_GATTS_READ_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); - esp_gatt_rsp_t rsp; - memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); - rsp.attr_value.handle = param->read.handle; - rsp.attr_value.len = 4; - rsp.attr_value.value[0] = 0xde; - rsp.attr_value.value[1] = 0xed; - rsp.attr_value.value[2] = 0xbe; - rsp.attr_value.value[3] = 0xef; - esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, - ESP_GATT_OK, &rsp); - break; - } - case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value); - esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); - uint32_t val = *(uint32_t *)param->write.value; - if (val == 0x0) { - gpio_set_level(LED_GPIO, 0); - } else if (val == 0x1) { - gpio_set_level(LED_GPIO, 1); - } else { - ESP_LOGE(GATTS_TAG, "Unknown notify value"); - } - break; - } - case ESP_GATTS_EXEC_WRITE_EVT: - case ESP_GATTS_MTU_EVT: - case ESP_GATTS_CONF_EVT: - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_CREATE_EVT: - ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; - - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); - - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - &gatts_demo_char1_val, NULL); - break; - case ESP_GATTS_ADD_INCL_SRVC_EVT: - break; - case ESP_GATTS_ADD_CHAR_EVT: { - uint16_t length = 0; - const uint8_t *prf_char; - - ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); - - ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); - for(int i = 0; i < length; i++){ - ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]); + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, + GATTS_NUM_HANDLE_TEST_A); + break; + case ESP_GATTS_READ_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, + param->read.trans_id, param->read.handle); + esp_gatt_rsp_t rsp; + memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); + rsp.attr_value.handle = param->read.handle; + rsp.attr_value.len = 4; + rsp.attr_value.value[0] = 0xde; + rsp.attr_value.value[1] = 0xed; + rsp.attr_value.value[2] = 0xbe; + rsp.attr_value.value[3] = 0xef; + esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); + break; } - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); - break; - } - case ESP_GATTS_ADD_CHAR_DESCR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", - param->start.status, param->start.service_handle); - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", - param->connect.conn_id, - param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], - param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], - param->connect.is_connected); - gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; - break; - case ESP_GATTS_DISCONNECT_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GATTS_OPEN_EVT: - case ESP_GATTS_CANCEL_OPEN_EVT: - case ESP_GATTS_CLOSE_EVT: - case ESP_GATTS_LISTEN_EVT: - case ESP_GATTS_CONGEST_EVT: - default: - break; + case ESP_GATTS_WRITE_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, + param->write.trans_id, param->write.handle); + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, + *(uint32_t *)param->write.value); + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); + uint32_t val = *(uint32_t *)param->write.value; + if (val == 0x0) + { + gpio_set_level(LED_GPIO, 0); + } + else if (val == 0x1) + { + gpio_set_level(LED_GPIO, 1); + } + else + { + ESP_LOGE(GATTS_TAG, "Unknown notify value"); + } + break; + } + case ESP_GATTS_EXEC_WRITE_EVT: + case ESP_GATTS_MTU_EVT: + case ESP_GATTS_CONF_EVT: + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_CREATE_EVT: + ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, + param->create.service_handle); + gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; + + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); + + esp_ble_gatts_add_char( + gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, + &gatts_demo_char1_val, NULL); + break; + case ESP_GATTS_ADD_INCL_SRVC_EVT: + break; + case ESP_GATTS_ADD_CHAR_EVT: + { + uint16_t length = 0; + const uint8_t *prf_char; + + ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); + + ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); + for (int i = 0; i < length; i++) { ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n", i, prf_char[i]); } + esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, + &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + break; + } + case ESP_GATTS_ADD_CHAR_DESCR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status, + param->start.service_handle); + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TAG, + "SERVICE_START_EVT, conn_id %d, remote " + "%02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", + param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], + param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], + param->connect.remote_bda[5], param->connect.is_connected); + gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; + break; + case ESP_GATTS_DISCONNECT_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + default: + break; } } -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; - - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B); - break; - case ESP_GATTS_READ_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); - esp_gatt_rsp_t rsp; - memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); - rsp.attr_value.handle = param->read.handle; - rsp.attr_value.len = 4; - rsp.attr_value.value[0] = 0xde; - rsp.attr_value.value[1] = 0xed; - rsp.attr_value.value[2] = 0xbe; - rsp.attr_value.value[3] = 0xef; - esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, - ESP_GATT_OK, &rsp); - break; - } - case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, *(uint32_t *)param->write.value); - esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); - break; - } - case ESP_GATTS_EXEC_WRITE_EVT: - case ESP_GATTS_MTU_EVT: - case ESP_GATTS_CONF_EVT: - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_CREATE_EVT: - ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; - - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); - - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - NULL, NULL); - break; - case ESP_GATTS_ADD_INCL_SRVC_EVT: - break; - case ESP_GATTS_ADD_CHAR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - - gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - NULL, NULL); - break; - case ESP_GATTS_ADD_CHAR_DESCR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", - param->start.status, param->start.service_handle); - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", - param->connect.conn_id, - param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], - param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], - param->connect.is_connected); - gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; - break; - case ESP_GATTS_DISCONNECT_EVT: - case ESP_GATTS_OPEN_EVT: - case ESP_GATTS_CANCEL_OPEN_EVT: - case ESP_GATTS_CLOSE_EVT: - case ESP_GATTS_LISTEN_EVT: - case ESP_GATTS_CONGEST_EVT: - default: - break; +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) + { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; + + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, + GATTS_NUM_HANDLE_TEST_B); + break; + case ESP_GATTS_READ_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, + param->read.trans_id, param->read.handle); + esp_gatt_rsp_t rsp; + memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); + rsp.attr_value.handle = param->read.handle; + rsp.attr_value.len = 4; + rsp.attr_value.value[0] = 0xde; + rsp.attr_value.value[1] = 0xed; + rsp.attr_value.value[2] = 0xbe; + rsp.attr_value.value[3] = 0xef; + esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); + break; + } + case ESP_GATTS_WRITE_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, + param->write.trans_id, param->write.handle); + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %08x\n", param->write.len, + *(uint32_t *)param->write.value); + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); + break; + } + case ESP_GATTS_EXEC_WRITE_EVT: + case ESP_GATTS_MTU_EVT: + case ESP_GATTS_CONF_EVT: + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_CREATE_EVT: + ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, + param->create.service_handle); + gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; + + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); + + esp_ble_gatts_add_char( + gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, NULL, NULL); + break; + case ESP_GATTS_ADD_INCL_SRVC_EVT: + break; + case ESP_GATTS_ADD_CHAR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + + gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, + &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + break; + case ESP_GATTS_ADD_CHAR_DESCR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status, + param->start.service_handle); + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TAG, + "SERVICE_START_EVT, conn_id %d, remote " + "%02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", + param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], + param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], + param->connect.remote_bda[5], param->connect.is_connected); + gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; + break; + case ESP_GATTS_DISCONNECT_EVT: + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + default: + break; } } static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { /* If event is register event, store the gatts_if for each profile */ - if (event == ESP_GATTS_REG_EVT) { - if (param->reg.status == ESP_GATT_OK) { + if (event == ESP_GATTS_REG_EVT) + { + if (param->reg.status == ESP_GATT_OK) + { gl_profile_tab[param->reg.app_id].gatts_if = gatts_if; - } else { - ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", - param->reg.app_id, - param->reg.status); + } + else + { + ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status); return; } } /* If the gatts_if equal to profile A, call profile A cb handler, * so here call each profile's callback */ - do { + do + { int idx; - for (idx = 0; idx < PROFILE_NUM; idx++) { - if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */ - gatts_if == gl_profile_tab[idx].gatts_if) { - if (gl_profile_tab[idx].gatts_cb) { + for (idx = 0; idx < PROFILE_NUM; idx++) + { + if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a + certain gatt_if, need to call every + profile cb function */ + gatts_if == gl_profile_tab[idx].gatts_if) + { + if (gl_profile_tab[idx].gatts_cb) + { gl_profile_tab[idx].gatts_cb(event, gatts_if, param); } } @@ -438,22 +508,25 @@ void app_main() esp_bt_controller_init(); ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed\n", __func__); return; } - gpio_pad_select_gpio(LED_GPIO); + gpio_pad_select_gpio(LED_GPIO); /* Set the GPIO as a push/pull output */ gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(LED_GPIO, 0); diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_client/main/gattc_demo.c b/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_client/main/gattc_demo.c index eab2c20..5b8b652 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_client/main/gattc_demo.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_client/main/gattc_demo.c @@ -12,78 +12,81 @@ // See the License for the specific language governing permissions and // limitations under the License. - - /**************************************************************************** -* -* This file is for gatt client. It can scan ble device, connect one device, -* -****************************************************************************/ + * + * This file is for gatt client. It can scan ble device, connect one device, + * + ****************************************************************************/ -#include -#include #include +#include #include -#include "nvs.h" -#include "nvs_flash.h" -#include "controller.h" +#include #include "bt.h" #include "bt_trace.h" #include "bt_types.h" -#include "btm_api.h" #include "bta_api.h" #include "bta_gatt_api.h" +#include "btm_api.h" +#include "controller.h" +#include "esp_bt_main.h" #include "esp_gap_ble_api.h" -#include "esp_gattc_api.h" #include "esp_gatt_defs.h" -#include "esp_bt_main.h" +#include "esp_gattc_api.h" +#include "nvs.h" +#include "nvs_flash.h" #define GATTC_TAG "GATTC_DEMO" -///Declare static functions +/// Declare static functions static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); -static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); - - +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t *param); static esp_gatt_srvc_id_t alert_service_id = { - .id = { - .uuid = { - .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = 0x00FF,}, + .id = + { + .uuid = + { + .len = ESP_UUID_LEN_16, + .uuid = + { + .uuid16 = 0x00FF, + }, + }, + .inst_id = 0, }, - .inst_id = 0, - }, .is_primary = true, }; static esp_gatt_id_t notify_descr_id = { - .uuid = { - .len = ESP_UUID_LEN_16, - .uuid = {.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG,}, - }, + .uuid = + { + .len = ESP_UUID_LEN_16, + .uuid = + { + .uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG, + }, + }, .inst_id = 0, }; - static bool connect = false; static const char device_name[] = "ESP_GATTS_DEMO"; -static esp_ble_scan_params_t ble_scan_params = { - .scan_type = BLE_SCAN_TYPE_ACTIVE, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x50, - .scan_window = 0x30 -}; - +static esp_ble_scan_params_t ble_scan_params = {.scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x50, + .scan_window = 0x30}; #define PROFILE_NUM 1 #define PROFILE_A_APP_ID 0 -struct gattc_profile_inst { +struct gattc_profile_inst +{ esp_gattc_cb_t gattc_cb; uint16_t gattc_if; uint16_t app_id; @@ -91,136 +94,155 @@ struct gattc_profile_inst { esp_bd_addr_t remote_bda; }; -/* One gatt-based profile one app_id and one gattc_if, this array will store the gattc_if returned by ESP_GATTS_REG_EVT */ +/* One gatt-based profile one app_id and one gattc_if, this array will store the + * gattc_if returned by ESP_GATTS_REG_EVT */ static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = { - [PROFILE_A_APP_ID] = { - .gattc_cb = gattc_profile_event_handler, - .gattc_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, + [PROFILE_A_APP_ID] = + { + .gattc_cb = gattc_profile_event_handler, .gattc_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is + ESP_GATT_IF_NONE */ + }, }; -static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) +static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t *param) { uint16_t conn_id = 0; esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; - switch (event) { - case ESP_GATTC_REG_EVT: - ESP_LOGI(GATTC_TAG, "REG_EVT"); - esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params); - if (scan_ret){ - ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret); - } - break; - case ESP_GATTC_OPEN_EVT: - if (param->open.status != ESP_GATT_OK){ + switch (event) + { + case ESP_GATTC_REG_EVT: + ESP_LOGI(GATTC_TAG, "REG_EVT"); + esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params); + if (scan_ret) + { + ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret); + } + break; + case ESP_GATTC_OPEN_EVT: + if (param->open.status != ESP_GATT_OK) + { ESP_LOGE(GATTC_TAG, "Open failed, status %d", p_data->open.status); break; - } - conn_id = p_data->open.conn_id; - gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->open.conn_id; - memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, sizeof(esp_bd_addr_t)); - ESP_LOGI(GATTC_TAG, "ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d, mtu %d", conn_id, gattc_if, p_data->open.status, p_data->open.mtu); - ESP_LOGI(GATTC_TAG, "REMOTE BDA:"); - //esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t)); - esp_err_t mtu_ret = esp_ble_gattc_config_mtu (gattc_if, conn_id, 200); - if (mtu_ret){ - ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret); - } - break; - case ESP_GATTC_CFG_MTU_EVT: - if (param->cfg_mtu.status != ESP_GATT_OK){ - ESP_LOGE(GATTC_TAG,"Config mtu failed"); + } + conn_id = p_data->open.conn_id; + gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->open.conn_id; + memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d, mtu %d", conn_id, gattc_if, + p_data->open.status, p_data->open.mtu); + ESP_LOGI(GATTC_TAG, "REMOTE BDA:"); + // esp_log_buffer_hex(GATTC_TAG, + // gl_profile_tab[PROFILE_A_APP_ID].remote_bda, + // sizeof(esp_bd_addr_t)); + esp_err_t mtu_ret = esp_ble_gattc_config_mtu(gattc_if, conn_id, 200); + if (mtu_ret) + { + ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret); + } break; - } - ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id); - esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, NULL); - break; - case ESP_GATTC_SEARCH_RES_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; - conn_id = p_data->search_res.conn_id; - ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", conn_id); - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { - ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - ESP_LOGI(GATTC_TAG, "UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - ESP_LOGI(GATTC_TAG, "UUID128:"); - //esp_log_buffer_hex(GATTC_TAG, srvc_id->id.uuid.uuid.uuid128, ESP_UUID_LEN_128); - } else { - ESP_LOGE(GATTC_TAG, "UNKNOWN LEN %d", srvc_id->id.uuid.len); - } - break; - } - case ESP_GATTC_SEARCH_CMPL_EVT: - conn_id = p_data->search_cmpl.conn_id; - ESP_LOGI(GATTC_TAG, "SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); - esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, NULL); - break; - case ESP_GATTC_GET_CHAR_EVT: - if (p_data->get_char.status != ESP_GATT_OK) { + case ESP_GATTC_CFG_MTU_EVT: + if (param->cfg_mtu.status != ESP_GATT_OK) + { + ESP_LOGE(GATTC_TAG, "Config mtu failed"); + break; + } + ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, + param->cfg_mtu.mtu, param->cfg_mtu.conn_id); + esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, NULL); + break; + case ESP_GATTC_SEARCH_RES_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; + conn_id = p_data->search_res.conn_id; + ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x", conn_id); + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) + { + ESP_LOGI(GATTC_TAG, "UUID16: %x", srvc_id->id.uuid.uuid.uuid16); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) + { + ESP_LOGI(GATTC_TAG, "UUID32: %x", srvc_id->id.uuid.uuid.uuid32); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) + { + ESP_LOGI(GATTC_TAG, "UUID128:"); + // esp_log_buffer_hex(GATTC_TAG, srvc_id->id.uuid.uuid.uuid128, + // ESP_UUID_LEN_128); + } + else + { + ESP_LOGE(GATTC_TAG, "UNKNOWN LEN %d", srvc_id->id.uuid.len); + } break; } - ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status); - ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16); + case ESP_GATTC_SEARCH_CMPL_EVT: + conn_id = p_data->search_cmpl.conn_id; + ESP_LOGI(GATTC_TAG, "SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); + esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, NULL); + break; + case ESP_GATTC_GET_CHAR_EVT: + if (p_data->get_char.status != ESP_GATT_OK) + { + break; + } + ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status); + ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", + p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16); + + if (p_data->get_char.char_id.uuid.uuid.uuid16 == 0xff01) + { + ESP_LOGI(GATTC_TAG, "register notify"); + esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, + &alert_service_id, &p_data->get_char.char_id); + } - if (p_data->get_char.char_id.uuid.uuid.uuid16 == 0xff01) { - ESP_LOGI(GATTC_TAG, "register notify"); - esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &alert_service_id, &p_data->get_char.char_id); + esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, &p_data->get_char.char_id); + break; + case ESP_GATTC_REG_FOR_NOTIFY_EVT: + { + uint16_t notify_en = 1; + ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d", p_data->reg_for_notify.status); + ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", + p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, + p_data->reg_for_notify.char_id.uuid.uuid.uuid16); + + esp_ble_gattc_write_char_descr(gattc_if, conn_id, &alert_service_id, &p_data->reg_for_notify.char_id, + ¬ify_descr_id, sizeof(notify_en), (uint8_t *)¬ify_en, + ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + break; } - - esp_ble_gattc_get_characteristic(gattc_if, conn_id, &alert_service_id, &p_data->get_char.char_id); - break; - case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - uint16_t notify_en = 1; - ESP_LOGI(GATTC_TAG, "REG FOR NOTIFY: status %d", p_data->reg_for_notify.status); - ESP_LOGI(GATTC_TAG, "REG FOR_NOTIFY: srvc_id = %04x, char_id = %04x", p_data->reg_for_notify.srvc_id.id.uuid.uuid.uuid16, p_data->reg_for_notify.char_id.uuid.uuid.uuid16); - - esp_ble_gattc_write_char_descr( gattc_if, - conn_id, - &alert_service_id, - &p_data->reg_for_notify.char_id, - ¬ify_descr_id, - sizeof(notify_en), - (uint8_t *)¬ify_en, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - break; - } - case ESP_GATTC_NOTIFY_EVT: - ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:"); - //esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len); - //write back - esp_ble_gattc_write_char(gattc_if, - gl_profile_tab[PROFILE_A_APP_ID].conn_id, - &alert_service_id, - &p_data->notify.char_id, - p_data->notify.value_len, - p_data->notify.value, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - break; - case ESP_GATTC_WRITE_DESCR_EVT: - ESP_LOGI(GATTC_TAG, "WRITE DESCR: status %d", p_data->write.status); - break; - case ESP_GATTC_SRVC_CHG_EVT: { - esp_bd_addr_t bda; - memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t)); - ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:"); - //esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t)); - break; - } - case ESP_GATTC_WRITE_CHAR_EVT: - ESP_LOGI(GATTC_TAG, "WRITE: status %d", p_data->write.status); - if (p_data->write.status == ESP_GATT_OK){ - ESP_LOGI(GATTC_TAG, "Write char success "); + case ESP_GATTC_NOTIFY_EVT: + ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, Receive notify value:"); + // esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, + // p_data->notify.value_len); write back + esp_ble_gattc_write_char(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, &alert_service_id, + &p_data->notify.char_id, p_data->notify.value_len, p_data->notify.value, + ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + break; + case ESP_GATTC_WRITE_DESCR_EVT: + ESP_LOGI(GATTC_TAG, "WRITE DESCR: status %d", p_data->write.status); + break; + case ESP_GATTC_SRVC_CHG_EVT: + { + esp_bd_addr_t bda; + memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t)); + ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:"); + // esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t)); + break; } - break; - /*case ESP_GATTC_DISCONNECT_EVT: - ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, status = %d", p_data->disconnect.status); - break;*/ - default: - break; + case ESP_GATTC_WRITE_CHAR_EVT: + ESP_LOGI(GATTC_TAG, "WRITE: status %d", p_data->write.status); + if (p_data->write.status == ESP_GATT_OK) + { + ESP_LOGI(GATTC_TAG, "Write char success "); + } + break; + /*case ESP_GATTC_DISCONNECT_EVT: + ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, status = %d", + p_data->disconnect.status); break;*/ + default: + break; } } @@ -228,72 +250,91 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par { uint8_t *adv_name = NULL; uint8_t adv_name_len = 0; - switch (event) { - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second - uint32_t duration = 30; - esp_ble_gap_start_scanning(duration); - break; - } - case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: - //scan start complete event to indicate scan start successfully or failed - if (param->scan_start_cmpl.status == ESP_BT_STATUS_SUCCESS) { - ESP_LOGI(GATTC_TAG, "Scan start success"); - }else{ - ESP_LOGE(GATTC_TAG, "Scan start failed"); + switch (event) + { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + { + // the unit of the duration is second + uint32_t duration = 30; + esp_ble_gap_start_scanning(duration); + break; } - break; - case ESP_GAP_BLE_SCAN_RESULT_EVT: { - esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.search_evt) { - case ESP_GAP_SEARCH_INQ_RES_EVT: - //esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); - ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); - ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); - //esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); - ESP_LOGI(GATTC_TAG, "\n"); - if (adv_name != NULL) { - if (strlen(device_name) == adv_name_len && strncmp((char *)adv_name, device_name, adv_name_len) == 0) { - ESP_LOGI(GATTC_TAG, "Searched device %s\n", device_name); - if (connect == false) { - connect = true; - ESP_LOGI(GATTC_TAG, "Connect to the remote device."); - esp_ble_gap_stop_scanning(); - esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, true); - } - } + case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: + // scan start complete event to indicate scan start successfully or + // failed + if (param->scan_start_cmpl.status == ESP_BT_STATUS_SUCCESS) + { + ESP_LOGI(GATTC_TAG, "Scan start success"); + } + else + { + ESP_LOGE(GATTC_TAG, "Scan start failed"); } break; - case ESP_GAP_SEARCH_INQ_CMPL_EVT: - break; - default: + case ESP_GAP_BLE_SCAN_RESULT_EVT: + { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) + { + case ESP_GAP_SEARCH_INQ_RES_EVT: + // esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, + // 6); + ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", + scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); + adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); + ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); + // esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); + ESP_LOGI(GATTC_TAG, "\n"); + if (adv_name != NULL) + { + if (strlen(device_name) == adv_name_len && + strncmp((char *)adv_name, device_name, adv_name_len) == 0) + { + ESP_LOGI(GATTC_TAG, "Searched device %s\n", device_name); + if (connect == false) + { + connect = true; + ESP_LOGI(GATTC_TAG, "Connect to the remote device."); + esp_ble_gap_stop_scanning(); + esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, + true); + } + } + } + break; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + break; + default: + break; + } break; } - break; - } - case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: - if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ - ESP_LOGE(GATTC_TAG, "Scan stop failed"); - } - else { - ESP_LOGI(GATTC_TAG, "Stop scan successfully"); - } - break; + case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: + if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(GATTC_TAG, "Scan stop failed"); + } + else + { + ESP_LOGI(GATTC_TAG, "Stop scan successfully"); + } + break; - case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: - if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){ - ESP_LOGE(GATTC_TAG, "Adv stop failed"); - } - else { - ESP_LOGI(GATTC_TAG, "Stop adv successfully"); - } - break; + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(GATTC_TAG, "Adv stop failed"); + } + else + { + ESP_LOGI(GATTC_TAG, "Stop adv successfully"); + } + break; - default: - break; + default: + break; } } @@ -302,25 +343,33 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp ESP_LOGI(GATTC_TAG, "EVT %d, gattc if %d", event, gattc_if); /* If event is register event, store the gattc_if for each profile */ - if (event == ESP_GATTC_REG_EVT) { - if (param->reg.status == ESP_GATT_OK) { + if (event == ESP_GATTC_REG_EVT) + { + if (param->reg.status == ESP_GATT_OK) + { gl_profile_tab[param->reg.app_id].gattc_if = gattc_if; - } else { - ESP_LOGI(GATTC_TAG, "Reg app failed, app_id %04x, status %d", - param->reg.app_id, - param->reg.status); + } + else + { + ESP_LOGI(GATTC_TAG, "Reg app failed, app_id %04x, status %d", param->reg.app_id, param->reg.status); return; } } /* If the gattc_if equal to profile A, call profile A cb handler, * so here call each profile's callback */ - do { + do + { int idx; - for (idx = 0; idx < PROFILE_NUM; idx++) { - if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */ - gattc_if == gl_profile_tab[idx].gattc_if) { - if (gl_profile_tab[idx].gattc_cb) { + for (idx = 0; idx < PROFILE_NUM; idx++) + { + if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a + certain gatt_if, need to call every + profile cb function */ + gattc_if == gl_profile_tab[idx].gattc_if) + { + if (gl_profile_tab[idx].gattc_cb) + { gl_profile_tab[idx].gattc_cb(event, gattc_if, param); } } @@ -332,55 +381,61 @@ void app_main() { // Initialize NVS. esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - //ESP_ERROR_CHECK(nvs_flash_erase()); //nvs_erase_all + if (ret == ESP_ERR_NVS_NO_FREE_PAGES) + { + // ESP_ERROR_CHECK(nvs_flash_erase()); //nvs_erase_all ret = nvs_flash_init(); } - ESP_ERROR_CHECK( ret ); + ESP_ERROR_CHECK(ret); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); - if (ret) { + if (ret) + { ESP_LOGE(GATTC_TAG, "%s initialize controller failed\n", __func__); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); - if (ret) { + if (ret) + { ESP_LOGE(GATTC_TAG, "%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); - if (ret) { + if (ret) + { ESP_LOGE(GATTC_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); - if (ret) { + if (ret) + { ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed\n", __func__); return; } - //register the callback function to the gap module + // register the callback function to the gap module ret = esp_ble_gap_register_callback(esp_gap_cb); - if (ret){ + if (ret) + { ESP_LOGE(GATTC_TAG, "gap register error, error code = %x", ret); return; } - //register the callback function to the gattc module + // register the callback function to the gattc module ret = esp_ble_gattc_register_callback(esp_gattc_cb); - if(ret){ + if (ret) + { ESP_LOGE(GATTC_TAG, "gattc register error, error code = %x", ret); return; } ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID); - if (ret){ + if (ret) + { ESP_LOGE(GATTC_TAG, "gattc app register error, error code = %x", ret); } - } - diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_server/main/gatts_demo.c b/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_server/main/gatts_demo.c index 3c66180..0c5ff9e 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_server/main/gatts_demo.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_notification/gatt_server/main/gatts_demo.c @@ -15,74 +15,101 @@ #include #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_log.h" -#include "nvs.h" -#include "nvs_flash.h" + #include "bt.h" #include "bta_api.h" - -#include "esp_gap_ble_api.h" -#include "esp_gatts_api.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" -#include "esp_bt_main.h" - +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_log.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "nvs.h" +#include "nvs_flash.h" #include "sdkconfig.h" #define GATTS_TAG "GATTS_DEMO" -///Declare the static function -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); +/// Declare the static function +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param); +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param); -#define GATTS_SERVICE_UUID_TEST_A 0x00FF -#define GATTS_CHAR_UUID_TEST_A 0xFF01 -#define GATTS_DESCR_UUID_TEST_A 0x3333 -#define GATTS_NUM_HANDLE_TEST_A 4 +#define GATTS_SERVICE_UUID_TEST_A 0x00FF +#define GATTS_CHAR_UUID_TEST_A 0xFF01 +#define GATTS_DESCR_UUID_TEST_A 0x3333 +#define GATTS_NUM_HANDLE_TEST_A 4 -#define GATTS_SERVICE_UUID_TEST_B 0x00EE -#define GATTS_CHAR_UUID_TEST_B 0xEE01 -#define GATTS_DESCR_UUID_TEST_B 0x2222 -#define GATTS_NUM_HANDLE_TEST_B 4 +#define GATTS_SERVICE_UUID_TEST_B 0x00EE +#define GATTS_CHAR_UUID_TEST_B 0xEE01 +#define GATTS_DESCR_UUID_TEST_B 0x2222 +#define GATTS_NUM_HANDLE_TEST_B 4 -#define TEST_DEVICE_NAME "ESP_GATTS_DEMO" -#define TEST_MANUFACTURER_DATA_LEN 17 +#define TEST_DEVICE_NAME "ESP_GATTS_DEMO" +#define TEST_MANUFACTURER_DATA_LEN 17 #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 #define PREPARE_BUF_MAX_SIZE 1024 -uint8_t char1_str[] = {0x11,0x22,0x33}; -esp_attr_value_t gatts_demo_char1_val = -{ +uint8_t char1_str[] = {0x11, 0x22, 0x33}; +esp_attr_value_t gatts_demo_char1_val = { .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, - .attr_len = sizeof(char1_str), - .attr_value = char1_str, + .attr_len = sizeof(char1_str), + .attr_value = char1_str, }; #ifdef CONFIG_SET_RAW_ADV_DATA -static uint8_t raw_adv_data[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd -}; -static uint8_t raw_scan_rsp_data[] = { - 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f -}; +static uint8_t raw_adv_data[] = {0x02, 0x01, 0x06, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd}; +static uint8_t raw_scan_rsp_data[] = {0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, + 0x54, 0x54, 0x53, 0x5f, 0x44, 0x45, 0x4d, 0x4f}; #else static uint8_t test_service_uuid128[32] = { - /* LSB <--------------------------------------------------------------------------------> MSB */ - //first uuid, 16bit, [12],[13] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0x00, 0x00, - //second uuid, 32bit, [12], [13], [14], [15] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD, + /* LSB + <--------------------------------------------------------------------------------> + MSB */ + // first uuid, 16bit, [12],[13] is the value + 0xfb, + 0x34, + 0x9b, + 0x5f, + 0x80, + 0x00, + 0x00, + 0x80, + 0x00, + 0x10, + 0x00, + 0x00, + 0xAB, + 0xCD, + 0x00, + 0x00, + // second uuid, 32bit, [12], [13], [14], [15] is the value + 0xfb, + 0x34, + 0x9b, + 0x5f, + 0x80, + 0x00, + 0x00, + 0x80, + 0x00, + 0x10, + 0x00, + 0x00, + 0xAB, + 0xCD, + 0xAB, + 0xCD, }; -//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56}; +// static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, +// 0x45, 0x56}; static esp_ble_adv_data_t test_adv_data = { .set_scan_rsp = false, .include_name = true, @@ -90,8 +117,8 @@ static esp_ble_adv_data_t test_adv_data = { .min_interval = 0x20, .max_interval = 0x40, .appearance = 0x00, - .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, - .p_manufacturer_data = NULL, //&test_manufacturer[0], + .manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN, + .p_manufacturer_data = NULL, //&test_manufacturer[0], .service_data_len = 0, .p_service_data = NULL, .service_uuid_len = 32, @@ -101,13 +128,13 @@ static esp_ble_adv_data_t test_adv_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t test_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, - .adv_type = ADV_TYPE_IND, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .adv_int_min = 0x20, + .adv_int_max = 0x40, + .adv_type = ADV_TYPE_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, //.peer_addr = //.peer_addr_type = - .channel_map = ADV_CHNL_ALL, + .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; @@ -115,7 +142,8 @@ static esp_ble_adv_params_t test_adv_params = { #define PROFILE_A_APP_ID 0 #define PROFILE_B_APP_ID 1 -struct gatts_profile_inst { +struct gatts_profile_inst +{ esp_gatts_cb_t gatts_cb; uint16_t gatts_if; uint16_t app_id; @@ -130,84 +158,108 @@ struct gatts_profile_inst { esp_bt_uuid_t descr_uuid; }; -/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */ +/* One gatt-based profile one app_id and one gatts_if, this array will store the + * gatts_if returned by ESP_GATTS_REG_EVT */ static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = { - [PROFILE_A_APP_ID] = { - .gatts_cb = gatts_profile_a_event_handler, - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, - [PROFILE_B_APP_ID] = { - .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, similar as profile A */ - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, + [PROFILE_A_APP_ID] = + { + .gatts_cb = gatts_profile_a_event_handler, .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial + is ESP_GATT_IF_NONE */ + }, + [PROFILE_B_APP_ID] = + { + .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, + similar as profile A */ + .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is + ESP_GATT_IF_NONE */ + }, }; -typedef struct { - uint8_t *prepare_buf; - int prepare_len; +typedef struct +{ + uint8_t *prepare_buf; + int prepare_len; } prepare_type_env_t; static prepare_type_env_t a_prepare_write_env; static prepare_type_env_t b_prepare_write_env; -void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param); +void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, + esp_ble_gatts_cb_param_t *param); void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param); static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { - switch (event) { - case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: - //advertising start complete event to indicate advertising start successfully or failed - if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); - } - break; - case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: - if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTS_TAG, "Advertising stop failed\n"); - } - else { - ESP_LOGI(GATTS_TAG, "Stop adv successfully\n"); - } - break; - /*case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTS_TAG, "update connetion params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", - param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, - param->update_conn_params.conn_int, - param->update_conn_params.latency, - param->update_conn_params.timeout);*/ - break; - default: - break; + switch (event) + { + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + // advertising start complete event to indicate advertising start + // successfully or failed + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); + } + break; + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(GATTS_TAG, "Advertising stop failed\n"); + } + else + { + ESP_LOGI(GATTS_TAG, "Stop adv successfully\n"); + } + break; + /*case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: + ESP_LOGI(GATTS_TAG, "update connetion params status = %d, + min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = + %d", param->update_conn_params.status, + param->update_conn_params.min_int, + param->update_conn_params.max_int, + param->update_conn_params.conn_int, + param->update_conn_params.latency, + param->update_conn_params.timeout);*/ + break; + default: + break; } } -void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ +void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, + esp_ble_gatts_cb_param_t *param) +{ esp_gatt_status_t status = ESP_GATT_OK; - if (param->write.need_rsp){ - if (param->write.is_prep){ - if (prepare_write_env->prepare_buf == NULL) { - prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); + if (param->write.need_rsp) + { + if (param->write.is_prep) + { + if (prepare_write_env->prepare_buf == NULL) + { + prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t)); prepare_write_env->prepare_len = 0; - if (prepare_write_env->prepare_buf == NULL) { + if (prepare_write_env->prepare_buf == NULL) + { LOG_ERROR("Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { + } + else + { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) + { status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + } + else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) + { status = ESP_GATT_INVALID_ATTR_LEN; } } @@ -218,351 +270,407 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare gatt_rsp->attr_value.offset = param->write.offset; gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE; memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len); - esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp); - if (response_err != ESP_OK){ - LOG_ERROR("Send response error\n"); + esp_err_t response_err = + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp); + if (response_err != ESP_OK) + { + LOG_ERROR("Send response error\n"); } free(gatt_rsp); - if (status != ESP_GATT_OK){ + if (status != ESP_GATT_OK) + { return; } - memcpy(prepare_write_env->prepare_buf + param->write.offset, - param->write.value, - param->write.len); + memcpy(prepare_write_env->prepare_buf + param->write.offset, param->write.value, param->write.len); prepare_write_env->prepare_len += param->write.len; - - }else{ + } + else + { esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL); } } } -void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ - if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC){ - //esp_log_buffer_hex(GATTS_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len); - }else{ - ESP_LOGI(GATTS_TAG,"ESP_GATT_PREP_WRITE_CANCEL"); +void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param) +{ + if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) + { + // esp_log_buffer_hex(GATTS_TAG, prepare_write_env->prepare_buf, + // prepare_write_env->prepare_len); + } + else + { + ESP_LOGI(GATTS_TAG, "ESP_GATT_PREP_WRITE_CANCEL"); } - if (prepare_write_env->prepare_buf) { + if (prepare_write_env->prepare_buf) + { free(prepare_write_env->prepare_buf); prepare_write_env->prepare_buf = NULL; } prepare_write_env->prepare_len = 0; } -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; - - esp_ble_gap_set_device_name(TEST_DEVICE_NAME); +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) + { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; + + esp_ble_gap_set_device_name(TEST_DEVICE_NAME); #ifdef CONFIG_SET_RAW_ADV_DATA - esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); - if (raw_adv_ret){ - ESP_LOGE(GATTS_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret); - } - esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); - if (raw_scan_ret){ - ESP_LOGE(GATTS_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret); - } + esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); + if (raw_adv_ret) + { + ESP_LOGE(GATTS_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret); + } + esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); + if (raw_scan_ret) + { + ESP_LOGE(GATTS_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret); + } #else - esp_err_t adv_ret = esp_ble_gap_config_adv_data(&test_adv_data); - if (adv_ret){ - ESP_LOGE(GATTS_TAG, "config adv data failed, error code = %x", adv_ret); - } + esp_err_t adv_ret = esp_ble_gap_config_adv_data(&test_adv_data); + if (adv_ret) + { + ESP_LOGE(GATTS_TAG, "config adv data failed, error code = %x", adv_ret); + } #endif - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A); - break; - case ESP_GATTS_READ_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); - esp_gatt_rsp_t rsp; - memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); - rsp.attr_value.handle = param->read.handle; - rsp.attr_value.len = 4; - rsp.attr_value.value[0] = 0xde; - rsp.attr_value.value[1] = 0xed; - rsp.attr_value.value[2] = 0xbe; - rsp.attr_value.value[3] = 0xef; - esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, - ESP_GATT_OK, &rsp); - break; - } - case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d", param->write.conn_id, param->write.trans_id, param->write.handle); - if (!param->write.is_prep){ - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); - //esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len); - if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2){ - uint16_t value= param->write.value[1]<<8 | param->write.value[0]; - if (value == 0x0001){ - ESP_LOGI(GATTS_TAG, "notify Enable "); - uint8_t value[15]; - for (int i = 0; i < sizeof(value); ++i) + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, + GATTS_NUM_HANDLE_TEST_A); + break; + case ESP_GATTS_READ_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, + param->read.trans_id, param->read.handle); + esp_gatt_rsp_t rsp; + memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); + rsp.attr_value.handle = param->read.handle; + rsp.attr_value.len = 4; + rsp.attr_value.value[0] = 0xde; + rsp.attr_value.value[1] = 0xed; + rsp.attr_value.value[2] = 0xbe; + rsp.attr_value.value[3] = 0xef; + esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); + break; + } + case ESP_GATTS_WRITE_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d", param->write.conn_id, + param->write.trans_id, param->write.handle); + if (!param->write.is_prep) + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); + // esp_log_buffer_hex(GATTS_TAG, param->write.value, + // param->write.len); + if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2) + { + uint16_t value = param->write.value[1] << 8 | param->write.value[0]; + if (value == 0x0001) { - value[i] = i%0xff; + ESP_LOGI(GATTS_TAG, "notify Enable "); + uint8_t value[15]; + for (int i = 0; i < sizeof(value); ++i) { value[i] = i % 0xff; } + // the size of value[] need less than MTU size + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, + gl_profile_tab[PROFILE_A_APP_ID].char_handle, sizeof(value), value, + false); + } + else if (value == 0x0000) + { + ESP_LOGI(GATTS_TAG, "notify disable "); + } + else + { + ESP_LOGE(GATTS_TAG, "unknown value"); } - //the size of value[] need less than MTU size - esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle, sizeof(value), value, false); - }else if (value == 0x0000){ - ESP_LOGI(GATTS_TAG, "notify disable "); - }else{ - ESP_LOGE(GATTS_TAG, "unknown value"); } - } + example_write_event_env(gatts_if, &a_prepare_write_env, param); + break; } - example_write_event_env(gatts_if, &a_prepare_write_env, param); - break; - } - case ESP_GATTS_EXEC_WRITE_EVT: - ESP_LOGI(GATTS_TAG,"ESP_GATTS_EXEC_WRITE_EVT"); - esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); - example_exec_write_event_env(&a_prepare_write_env, param); - break; - case ESP_GATTS_MTU_EVT: - ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); - break; - case ESP_GATTS_CONF_EVT: - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_CREATE_EVT: - ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; - - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); - - esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - &gatts_demo_char1_val, NULL); - if (add_char_ret){ - ESP_LOGE(GATTS_TAG, "add char failed, error code =%x",add_char_ret); - } - break; - case ESP_GATTS_ADD_INCL_SRVC_EVT: - break; - case ESP_GATTS_ADD_CHAR_EVT: { - uint16_t length = 0; - const uint8_t *prf_char; - - ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); - if (get_attr_ret == ESP_FAIL){ - ESP_LOGE(GATTS_TAG, "ILLEGAL HANDLE"); - } + case ESP_GATTS_EXEC_WRITE_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT"); + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); + example_exec_write_event_env(&a_prepare_write_env, param); + break; + case ESP_GATTS_MTU_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); + break; + case ESP_GATTS_CONF_EVT: + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_CREATE_EVT: + ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, + param->create.service_handle); + gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; + + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); + + esp_err_t add_char_ret = esp_ble_gatts_add_char( + gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, + &gatts_demo_char1_val, NULL); + if (add_char_ret) + { + ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", add_char_ret); + } + break; + case ESP_GATTS_ADD_INCL_SRVC_EVT: + break; + case ESP_GATTS_ADD_CHAR_EVT: + { + uint16_t length = 0; + const uint8_t *prf_char; + + ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); + if (get_attr_ret == ESP_FAIL) + { + ESP_LOGE(GATTS_TAG, "ILLEGAL HANDLE"); + } - ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); - for(int i = 0; i < length; i++){ - ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]); + ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); + for (int i = 0; i < length; i++) { ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n", i, prf_char[i]); } + esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr( + gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + if (add_descr_ret) + { + ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret); + } + break; } - esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); - if (add_descr_ret){ - ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret); + case ESP_GATTS_ADD_CHAR_DESCR_EVT: + gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char.attr_handle; + ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status, + param->start.service_handle); + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + { + esp_ble_conn_update_params_t conn_params = {0}; + memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t)); + /* For the IOS system, please reference the apple official documents + * about the ble connection parameters restrictions. */ + conn_params.latency = 0; + conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms + conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms + conn_params.timeout = 400; // timeout = 400*10ms = 4000ms + ESP_LOGI(GATTS_TAG, + "ESP_GATTS_CONNECT_EVT, conn_id %d, remote " + "%02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d", + param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], + param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], + param->connect.remote_bda[5], param->connect.is_connected); + gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; + // start sent the update connection parameters to the peer device. + esp_ble_gap_update_conn_params(&conn_params); + break; } - break; - } - case ESP_GATTS_ADD_CHAR_DESCR_EVT: - gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char.attr_handle; - ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", - param->start.status, param->start.service_handle); - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: { - esp_ble_conn_update_params_t conn_params = {0}; - memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t)); - /* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */ - conn_params.latency = 0; - conn_params.max_int = 0x50; // max_int = 0x50*1.25ms = 100ms - conn_params.min_int = 0x30; // min_int = 0x30*1.25ms = 60ms - conn_params.timeout = 400; // timeout = 400*10ms = 4000ms - ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d", - param->connect.conn_id, - param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], - param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], - param->connect.is_connected); - gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; - //start sent the update connection parameters to the peer device. - esp_ble_gap_update_conn_params(&conn_params); - break; - } - case ESP_GATTS_DISCONNECT_EVT: - ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT"); - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GATTS_OPEN_EVT: - case ESP_GATTS_CANCEL_OPEN_EVT: - case ESP_GATTS_CLOSE_EVT: - case ESP_GATTS_LISTEN_EVT: - case ESP_GATTS_CONGEST_EVT: - default: - break; + case ESP_GATTS_DISCONNECT_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT"); + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + default: + break; } } -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; - - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B); - break; - case ESP_GATTS_READ_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); - esp_gatt_rsp_t rsp; - memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); - rsp.attr_value.handle = param->read.handle; - rsp.attr_value.len = 4; - rsp.attr_value.value[0] = 0xde; - rsp.attr_value.value[1] = 0xed; - rsp.attr_value.value[2] = 0xbe; - rsp.attr_value.value[3] = 0xef; - esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, - ESP_GATT_OK, &rsp); - break; - } - case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - if (!param->write.is_prep){ - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); - //esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len); - if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2){ - uint16_t value= param->write.value[1]<<8 | param->write.value[0]; - if (value == 0x0001){ - ESP_LOGI(GATTS_TAG, "notify Enable "); - uint8_t value[15]; - for (int i = 0; i < sizeof(value); ++i) +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) + { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; + + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, + GATTS_NUM_HANDLE_TEST_B); + break; + case ESP_GATTS_READ_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, + param->read.trans_id, param->read.handle); + esp_gatt_rsp_t rsp; + memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); + rsp.attr_value.handle = param->read.handle; + rsp.attr_value.len = 4; + rsp.attr_value.value[0] = 0xde; + rsp.attr_value.value[1] = 0xed; + rsp.attr_value.value[2] = 0xbe; + rsp.attr_value.value[3] = 0xef; + esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); + break; + } + case ESP_GATTS_WRITE_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, + param->write.trans_id, param->write.handle); + if (!param->write.is_prep) + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len); + // esp_log_buffer_hex(GATTS_TAG, param->write.value, + // param->write.len); + if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2) + { + uint16_t value = param->write.value[1] << 8 | param->write.value[0]; + if (value == 0x0001) { - value[i] = i%0xff; + ESP_LOGI(GATTS_TAG, "notify Enable "); + uint8_t value[15]; + for (int i = 0; i < sizeof(value); ++i) { value[i] = i % 0xff; } + // the size of value[] need less than MTU size + esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, + gl_profile_tab[PROFILE_B_APP_ID].char_handle, sizeof(value), value, + false); + } + else if (value == 0x0000) + { + ESP_LOGI(GATTS_TAG, "notify disable "); + } + else + { + ESP_LOGE(GATTS_TAG, "unknown value"); } - //the size of value[] need less than MTU size - esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle, sizeof(value), value, false); - }else if (value == 0x0000){ - ESP_LOGI(GATTS_TAG, "notify disable "); - }else{ - ESP_LOGE(GATTS_TAG, "unknown value"); } - } + example_write_event_env(gatts_if, &b_prepare_write_env, param); + break; } - example_write_event_env(gatts_if, &b_prepare_write_env, param); - break; - } - case ESP_GATTS_EXEC_WRITE_EVT: - ESP_LOGI(GATTS_TAG,"ESP_GATTS_EXEC_WRITE_EVT"); - esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); - example_exec_write_event_env(&b_prepare_write_env, param); - break; - case ESP_GATTS_MTU_EVT: - ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); - break; - case ESP_GATTS_CONF_EVT: - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_CREATE_EVT: - ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; - - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); - - esp_err_t add_char_ret =esp_ble_gatts_add_char( gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - NULL, NULL); - if (add_char_ret){ - ESP_LOGE(GATTS_TAG, "add char failed, error code =%x",add_char_ret); - } - break; - case ESP_GATTS_ADD_INCL_SRVC_EVT: - break; - case ESP_GATTS_ADD_CHAR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - - gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - NULL, NULL); - break; - case ESP_GATTS_ADD_CHAR_DESCR_EVT: - gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char.attr_handle; - ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", - param->start.status, param->start.service_handle); - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: - ESP_LOGI(GATTS_TAG, "CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d", - param->connect.conn_id, - param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], - param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], - param->connect.is_connected); - gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; - break; - case ESP_GATTS_DISCONNECT_EVT: - case ESP_GATTS_OPEN_EVT: - case ESP_GATTS_CANCEL_OPEN_EVT: - case ESP_GATTS_CLOSE_EVT: - case ESP_GATTS_LISTEN_EVT: - case ESP_GATTS_CONGEST_EVT: - default: - break; + case ESP_GATTS_EXEC_WRITE_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT"); + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); + example_exec_write_event_env(&b_prepare_write_env, param); + break; + case ESP_GATTS_MTU_EVT: + ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu); + break; + case ESP_GATTS_CONF_EVT: + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_CREATE_EVT: + ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, + param->create.service_handle); + gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; + + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); + + esp_err_t add_char_ret = esp_ble_gatts_add_char( + gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, NULL, NULL); + if (add_char_ret) + { + ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", add_char_ret); + } + break; + case ESP_GATTS_ADD_INCL_SRVC_EVT: + break; + case ESP_GATTS_ADD_CHAR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + + gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, + &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + break; + case ESP_GATTS_ADD_CHAR_DESCR_EVT: + gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char.attr_handle; + ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status, + param->start.service_handle); + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TAG, + "CONNECT_EVT, conn_id %d, remote " + "%02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d", + param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], + param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], + param->connect.remote_bda[5], param->connect.is_connected); + gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; + break; + case ESP_GATTS_DISCONNECT_EVT: + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + default: + break; } } static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { /* If event is register event, store the gatts_if for each profile */ - if (event == ESP_GATTS_REG_EVT) { - if (param->reg.status == ESP_GATT_OK) { + if (event == ESP_GATTS_REG_EVT) + { + if (param->reg.status == ESP_GATT_OK) + { gl_profile_tab[param->reg.app_id].gatts_if = gatts_if; - } else { - ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", - param->reg.app_id, - param->reg.status); + } + else + { + ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status); return; } } /* If the gatts_if equal to profile A, call profile A cb handler, * so here call each profile's callback */ - do { + do + { int idx; - for (idx = 0; idx < PROFILE_NUM; idx++) { - if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */ - gatts_if == gl_profile_tab[idx].gatts_if) { - if (gl_profile_tab[idx].gatts_cb) { + for (idx = 0; idx < PROFILE_NUM; idx++) + { + if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a + certain gatt_if, need to call every + profile cb function */ + gatts_if == gl_profile_tab[idx].gatts_if) + { + if (gl_profile_tab[idx].gatts_cb) + { gl_profile_tab[idx].gatts_cb(event, gatts_if, param); } } @@ -576,52 +684,61 @@ void app_main() // Initialize NVS. ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - //ESP_ERROR_CHECK(nvs_flash_erase()); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES) + { + // ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } - ESP_ERROR_CHECK( ret ); + ESP_ERROR_CHECK(ret); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s initialize controller failed\n", __func__); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed\n", __func__); return; } ret = esp_ble_gatts_register_callback(gatts_event_handler); - if (ret){ + if (ret) + { ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret); return; } ret = esp_ble_gap_register_callback(gap_event_handler); - if (ret){ + if (ret) + { ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret); return; } ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID); - if (ret){ + if (ret) + { ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); return; } ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID); - if (ret){ + if (ret) + { ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret); return; } diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/ble/ble.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/ble/ble.c index 80ceb21..5b373e8 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/ble/ble.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/ble/ble.c @@ -1,219 +1,230 @@ -#include - #include "ble.h" -#include "my_list.h" -#include "user_config.h" + +#include #include "bt.h" #include "bt_types.h" -#include "btm_api.h" #include "bta_api.h" #include "bta_gatt_api.h" +#include "btm_api.h" +#include "esp_bt_main.h" #include "esp_gap_ble_api.h" -#include "esp_gattc_api.h" #include "esp_gatt_defs.h" -#include "esp_bt_main.h" +#include "esp_gattc_api.h" #include "esp_log.h" +#include "my_list.h" +#include "user_config.h" +#define SCAN_DURATION 5 -#define SCAN_DURATION 5 - -//static const char *TAG = "ble"; +// static const char *TAG = "ble"; static uint16_t client_id = 0xEE; static esp_gatt_if_t client_if; static esp_gatt_status_t status = ESP_GATT_ERROR; -static esp_ble_scan_params_t ble_scan_params = { - .scan_type = BLE_SCAN_TYPE_PASSIVE, - .own_addr_type = ESP_PUBLIC_ADDR, - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x640, - .scan_window = 0x640 -}; +static esp_ble_scan_params_t ble_scan_params = {.scan_type = BLE_SCAN_TYPE_PASSIVE, + .own_addr_type = ESP_PUBLIC_ADDR, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x640, + .scan_window = 0x640}; extern void wifi_init_task(void); extern void initialise_wifi(void); static void get_uuid(const char *data, char *res) { - int j = 0; - char k[4] = {0x0}; - k[3] = 0x00; - int uuid_len = 16; - /*for (j = 9; j < 9+uuid_len; j++) { - sprintf(k, "%02X ", data[j]); - strcat(res, k); - }*/ - for (j = 9; j < 9+4; j++) { - sprintf(k, "%02X", data[j]); - strcat(res, k); - } - strcat(res, "-"); - for (j = 9+4; j < 9+4+2; j++) { - sprintf(k, "%02X", data[j]); - strcat(res, k); - } - strcat(res, "-"); - for (j = 9+4+2; j < 9+4+2+2; j++) { - sprintf(k, "%02X", data[j]); - strcat(res, k); - } - strcat(res, "-"); - for (j = 9+4+2+2; j < 9+4+2+2+2; j++) { - sprintf(k, "%02X", data[j]); - strcat(res, k); - } - strcat(res, "-"); - for (j = 9+4+2+2+2; j < 9+uuid_len; j++) { - sprintf(k, "%02X", data[j]); - strcat(res, k); - } + int j = 0; + char k[4] = {0x0}; + k[3] = 0x00; + int uuid_len = 16; + /*for (j = 9; j < 9+uuid_len; j++) { + sprintf(k, "%02X ", data[j]); + strcat(res, k); + }*/ + for (j = 9; j < 9 + 4; j++) + { + sprintf(k, "%02X", data[j]); + strcat(res, k); + } + strcat(res, "-"); + for (j = 9 + 4; j < 9 + 4 + 2; j++) + { + sprintf(k, "%02X", data[j]); + strcat(res, k); + } + strcat(res, "-"); + for (j = 9 + 4 + 2; j < 9 + 4 + 2 + 2; j++) + { + sprintf(k, "%02X", data[j]); + strcat(res, k); + } + strcat(res, "-"); + for (j = 9 + 4 + 2 + 2; j < 9 + 4 + 2 + 2 + 2; j++) + { + sprintf(k, "%02X", data[j]); + strcat(res, k); + } + strcat(res, "-"); + for (j = 9 + 4 + 2 + 2 + 2; j < 9 + uuid_len; j++) + { + sprintf(k, "%02X", data[j]); + strcat(res, k); + } } static bool is_valid_ibeacon(const char *package) { - if (package[0] != 0x02) { - return false; - } - return true; + if (package[0] != 0x02) + { + return false; + } + return true; } static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { uint8_t *adv_name = NULL; uint8_t adv_name_len = 0; - switch (event) { - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second - uint32_t duration = SCAN_DURATION; - esp_ble_gap_start_scanning(duration); - break; - } - case ESP_GAP_BLE_SCAN_RESULT_EVT: { - esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.search_evt) { - case ESP_GAP_SEARCH_INQ_RES_EVT: + switch (event) + { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + { + // the unit of the duration is second + uint32_t duration = SCAN_DURATION; + esp_ble_gap_start_scanning(duration); + break; + } + case ESP_GAP_BLE_SCAN_RESULT_EVT: + { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) + { + case ESP_GAP_SEARCH_INQ_RES_EVT: #ifdef ENABLE_SCAN_OUTPUT - switch (scan_result->scan_rst.dev_type) { - case ESP_BT_DEVICE_TYPE_BREDR: - ESP_LOGI(TAG, "==> Connected Device type BREDR"); - break; - case ESP_BT_DEVICE_TYPE_BLE: - ESP_LOGI(TAG, "==> Connected Device type BLE"); - break; - case ESP_BT_DEVICE_TYPE_DUMO: - ESP_LOGI(TAG, "==> Connected Device type DUMO"); - break; - default: - break; - } - ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); + switch (scan_result->scan_rst.dev_type) + { + case ESP_BT_DEVICE_TYPE_BREDR: + ESP_LOGI(TAG, "==> Connected Device type BREDR"); + break; + case ESP_BT_DEVICE_TYPE_BLE: + ESP_LOGI(TAG, "==> Connected Device type BLE"); + break; + case ESP_BT_DEVICE_TYPE_DUMO: + ESP_LOGI(TAG, "==> Connected Device type DUMO"); + break; + default: + break; + } + ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); #endif - /*for (int i = 0; i < 6; i++) { - server_dba[i]=scan_result->scan_rst.bda[i]; - }*/ - if (!is_valid_ibeacon((const char *) scan_result->scan_rst.ble_adv)) { + /*for (int i = 0; i < 6; i++) { + server_dba[i]=scan_result->scan_rst.bda[i]; + }*/ + if (!is_valid_ibeacon((const char *)scan_result->scan_rst.ble_adv)) + { #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "not an ibeacon package"); + ESP_LOGI(TAG, "not an ibeacon package"); #endif - break; - } + break; + } - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "adv_name_len=%x\n", adv_name_len); - ESP_LOGI(TAG, "rssi: %d", scan_result->scan_rst.rssi); + ESP_LOGI(TAG, "adv_name_len=%x\n", adv_name_len); + ESP_LOGI(TAG, "rssi: %d", scan_result->scan_rst.rssi); #endif - char uuid[64] = {0}; - get_uuid((const char *)scan_result->scan_rst.ble_adv, uuid); + char uuid[64] = {0}; + get_uuid((const char *)scan_result->scan_rst.ble_adv, uuid); #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "%s", uuid); + ESP_LOGI(TAG, "%s", uuid); #endif - char buff[BDA_SIZE] = {0}; - scan_list_t *tmp = list_new_item(); - if (tmp == NULL) { - ESP_LOGE(TAG, "cannot alloc for list item!"); - break; - } - sprintf(buff, "%02x%02x%02x%02x%02x%02x", scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - memcpy(tmp->bda, buff, 12); - tmp->bda[12] = 0; - memcpy(tmp->uuid, uuid, 48); - tmp->uuid[48] = 0; - tmp->rssi = scan_result->scan_rst.rssi; - list_insert_to_head(tmp); - - //ESP_LOGI(TAG, "dev name: %s", adv_name); - /*for (int j = 0; j < adv_name_len; j++) { - LOG_INFO("a%d %x %c = d%d %x %c",j, adv_name[j], adv_name[j],j, device_name[j], device_name[j]); - }*/ - - /*if (strncmp((char *)adv_name, device_name,adv_name_len) == 0 && connet == false) { - connet = true; - ESP_LOGI(TAG, "==> address type: %d, dev name: %s", scan_result->scan_rst.ble_addr_type, adv_name); - LOG_INFO("Connect to the remote device."); - esp_ble_gap_stop_scanning(); - esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); - memcpy(tar_dev_mac, scan_result->scan_rst.bda, 6); - }*/ - break; - case ESP_GAP_SEARCH_INQ_CMPL_EVT: - //esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + char buff[BDA_SIZE] = {0}; + scan_list_t *tmp = list_new_item(); + if (tmp == NULL) + { + ESP_LOGE(TAG, "cannot alloc for list item!"); + break; + } + sprintf(buff, "%02x%02x%02x%02x%02x%02x", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], + scan_result->scan_rst.bda[4], scan_result->scan_rst.bda[5]); + memcpy(tmp->bda, buff, 12); + tmp->bda[12] = 0; + memcpy(tmp->uuid, uuid, 48); + tmp->uuid[48] = 0; + tmp->rssi = scan_result->scan_rst.rssi; + list_insert_to_head(tmp); + + // ESP_LOGI(TAG, "dev name: %s", adv_name); + /*for (int j = 0; j < adv_name_len; j++) { + LOG_INFO("a%d %x %c = d%d %x %c",j, adv_name[j], + adv_name[j],j, device_name[j], device_name[j]); + }*/ + + /*if (strncmp((char *)adv_name, device_name,adv_name_len) == + 0 && connet == false) { connet = true; ESP_LOGI(TAG, "==> address + type: %d, dev name: %s", scan_result->scan_rst.ble_addr_type, + adv_name); LOG_INFO("Connect to the remote device."); + esp_ble_gap_stop_scanning(); + esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); + memcpy(tar_dev_mac, scan_result->scan_rst.bda, 6); + }*/ + break; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + // esp_ble_gap_cb_param_t *scan_result = + // (esp_ble_gap_cb_param_t *)param; #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "========================="); - ESP_LOGI(TAG, "Scan over"); - ESP_LOGI(TAG, "========================="); + ESP_LOGI(TAG, "========================="); + ESP_LOGI(TAG, "Scan over"); + ESP_LOGI(TAG, "========================="); #endif - esp_ble_gap_stop_scanning(); - wifi_init_task(); - initialise_wifi(); + esp_ble_gap_stop_scanning(); + wifi_init_task(); + initialise_wifi(); #ifdef ENABLE_SCAN_OUTPUT - switch (scan_result->scan_rst.ble_evt_type) { - case ESP_BLE_EVT_CONN_ADV: - ESP_LOGI(TAG, "==> CONN_ADV"); - ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); - ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); - break; - case ESP_BLE_EVT_CONN_DIR_ADV: - ESP_LOGI(TAG, "==> CONN_DIR_ADV"); - break; - case ESP_BLE_EVT_DISC_ADV: - ESP_LOGI(TAG, "==> DISC_ADV"); - break; - case ESP_BLE_EVT_NON_CONN_ADV: - ESP_LOGI(TAG, "==> NON_CONN_ADV"); - break; - case ESP_BLE_EVT_SCAN_RSP: - ESP_LOGI(TAG, "==> receive scan response"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - } + switch (scan_result->scan_rst.ble_evt_type) + { + case ESP_BLE_EVT_CONN_ADV: + ESP_LOGI(TAG, "==> CONN_ADV"); + ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], + scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); + ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); + break; + case ESP_BLE_EVT_CONN_DIR_ADV: + ESP_LOGI(TAG, "==> CONN_DIR_ADV"); + break; + case ESP_BLE_EVT_DISC_ADV: + ESP_LOGI(TAG, "==> DISC_ADV"); + break; + case ESP_BLE_EVT_NON_CONN_ADV: + ESP_LOGI(TAG, "==> NON_CONN_ADV"); + break; + case ESP_BLE_EVT_SCAN_RSP: + ESP_LOGI(TAG, "==> receive scan response"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], + scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + } #endif + break; + default: + break; + } break; + } default: break; - } - break; - } - default: - break; } } @@ -221,8 +232,10 @@ void ble_client_app_register(void) { ESP_LOGI(TAG, "register gap callback"); - //register the scan callback function to the Generic Access Profile (GAP) module - if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) { + // register the scan callback function to the Generic Access Profile (GAP) + // module + if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) + { ESP_LOGE(TAG, "gap register error, error code = %x", status); return; } @@ -232,24 +245,23 @@ void ble_client_app_register(void) void ble_init(void) { - esp_bt_controller_init(); - esp_bt_controller_enable(ESP_BT_MODE_BTDM); - int ret = esp_bluedroid_init(); - if (ret) { + esp_bt_controller_init(); + esp_bt_controller_enable(ESP_BT_MODE_BTDM); + int ret = esp_bluedroid_init(); + if (ret) + { ESP_LOGE(TAG, "init bluedroid failed\n"); return; } ret = esp_bluedroid_enable(); - if (ret) { + if (ret) + { ESP_LOGE(TAG, "init bluedroid failed2\n"); return; } - - //ble_client_app_register(); + + // ble_client_app_register(); } -void ble_start_scanning(void) -{ - esp_ble_gap_start_scanning(SCAN_DURATION); -} \ No newline at end of file +void ble_start_scanning(void) { esp_ble_gap_start_scanning(SCAN_DURATION); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c index aa1d462..c08efa2 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/uart/my_uart.c @@ -3,21 +3,22 @@ * 2017.04.12 */ +#include "my_uart.h" + #include #include #include -#include "my_uart.h" + #include "ble.h" -#include "utils.h" -#include "user_config.h" +#include "driver/uart.h" #include "esp_log.h" #include "esp_system.h" -#include "driver/uart.h" -#include "soc/uart_struct.h" - #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/queue.h" +#include "freertos/task.h" +#include "soc/uart_struct.h" +#include "user_config.h" +#include "utils.h" static const char *TAG = "uart"; QueueHandle_t uart0_queue; @@ -37,157 +38,194 @@ extern esp_err_t save_int32(const char *key, int data); void show_help_info() { - ESP_LOGI(TAG, " "); - ESP_LOGI(TAG, "----------------------------------------"); - ESP_LOGI(TAG, "input the following command to setup:"); - ESP_LOGI(TAG, " ssid - set AP ssid"); - ESP_LOGI(TAG, " pass - set password"); - ESP_LOGI(TAG, " ip - set server ip"); - ESP_LOGI(TAG, " port - set server port"); - ESP_LOGI(TAG, " wifi - start connecting to wifi"); - ESP_LOGI(TAG, " quit - reset wifi parameters"); - ESP_LOGI(TAG, " help - show help info"); - ESP_LOGI(TAG, "----------------------------------------"); - ESP_LOGI(TAG, " "); + ESP_LOGI(TAG, " "); + ESP_LOGI(TAG, "----------------------------------------"); + ESP_LOGI(TAG, "input the following command to setup:"); + ESP_LOGI(TAG, " ssid - set AP ssid"); + ESP_LOGI(TAG, " pass - set password"); + ESP_LOGI(TAG, " ip - set server ip"); + ESP_LOGI(TAG, " port - set server port"); + ESP_LOGI(TAG, " wifi - start connecting to wifi"); + ESP_LOGI(TAG, " quit - reset wifi parameters"); + ESP_LOGI(TAG, " help - show help info"); + ESP_LOGI(TAG, "----------------------------------------"); + ESP_LOGI(TAG, " "); } -static bool is_valid_port(const char *port, int len) +static bool is_valid_port(const char *port, int len) { - int i; - if (len > 5) { - ESP_LOGE(TAG, "invalid port!"); - return false; - } + int i; + if (len > 5) + { + ESP_LOGE(TAG, "invalid port!"); + return false; + } - if (str2num(port, len) > 65535) { - ESP_LOGE(TAG, "port > 65535"); - return false; - } + if (str2num(port, len) > 65535) + { + ESP_LOGE(TAG, "port > 65535"); + return false; + } - for (i = 0; i < len; i++) { - if (port[i] < '0' || port[i] > '9') { - return false; - } - } - return true; + for (i = 0; i < len; i++) + { + if (port[i] < '0' || port[i] > '9') + { + return false; + } + } + return true; } static void uart_input_handler(const char *data, int len) { - int i; - if (len < 1) { - return; - } + int i; + if (len < 1) + { + return; + } - if (data[0] == 0x7f || data[0] == 0x08) { - if (rcvMsg.pWritePos != rcvMsg.pRcvMsgBuff) { - const char back = 0x08, space = ' '; - uart_write_bytes(UART_NUM_0, &back, 1); - uart_write_bytes(UART_NUM_0, &space, 1); - //uart_write_bytes(UART_NUM_0, &back, 1); - rcvMsg.pWritePos[0] = 0; - rcvMsg.pWritePos -= 1; - } else { - // nothing to delete - return; - } - } + if (data[0] == 0x7f || data[0] == 0x08) + { + if (rcvMsg.pWritePos != rcvMsg.pRcvMsgBuff) + { + const char back = 0x08, space = ' '; + uart_write_bytes(UART_NUM_0, &back, 1); + uart_write_bytes(UART_NUM_0, &space, 1); + // uart_write_bytes(UART_NUM_0, &back, 1); + rcvMsg.pWritePos[0] = 0; + rcvMsg.pWritePos -= 1; + } + else + { + // nothing to delete + return; + } + } - if (data[0] == '\r' || data[0] == '\n') { - // enter key press - rcvMsg.pWritePos[0] = 0; + if (data[0] == '\r' || data[0] == '\n') + { + // enter key press + rcvMsg.pWritePos[0] = 0; - if (rcvMsg.pWritePos == rcvMsg.pRcvMsgBuff) { - uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); - } else { - int length = rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff; - uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); - if (status == INPUT_SSID) { - memset(wifi_ssid, 0, WIFI_SSID_MAX_LEN); - memcpy(wifi_ssid, rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set ssid: %s", wifi_ssid); - esp_err_t er = save_string(CMD_SSID, (char *)wifi_ssid); - if (er != ESP_OK) - ESP_LOGE(TAG, "save ssid error"); - goto set_end; - } else if (status == INPUT_PASS) { - memset(wifi_pass, 0, WIFI_PASS_MAX_LEN); - memcpy(wifi_pass, rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set password: %s", wifi_pass); - esp_err_t er = save_string(CMD_PASS, (char *)wifi_pass); - if (er != ESP_OK) - ESP_LOGE(TAG, "save pass error"); - goto set_end; - } else if (status == INPUT_IP) { - memset(srv_ip, 0, SRV_IP_MAX_LEN); - memcpy(srv_ip, rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set server ip: %s", srv_ip); - esp_err_t er = save_string(CMD_IP, (char *)srv_ip); - if (er != ESP_OK) - ESP_LOGE(TAG, "save ip error"); - goto set_end; - } else if (status == INPUT_PORT) { - if (!is_valid_port((const char *)rcvMsg.pRcvMsgBuff, length)) { - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; - ESP_LOGE(TAG, "invalid server port, please input again"); - return; - } - srv_port = str2num((const char *)rcvMsg.pRcvMsgBuff, length); - status = NONE; - ESP_LOGI(TAG, "you set server port: %d", srv_port); - //esp_err_t er = save_int32(CMD_PORT, srv_port); - esp_err_t er = save_string(CMD_PORT, (char *)rcvMsg.pRcvMsgBuff); - if (er != ESP_OK) - ESP_LOGE(TAG, "save port error"); - goto set_end; - } + if (rcvMsg.pWritePos == rcvMsg.pRcvMsgBuff) + { + uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); + } + else + { + int length = rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff; + uart_write_bytes(UART_NUM_0, PROMPT, PROMPT_LEN); + if (status == INPUT_SSID) + { + memset(wifi_ssid, 0, WIFI_SSID_MAX_LEN); + memcpy(wifi_ssid, rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set ssid: %s", wifi_ssid); + esp_err_t er = save_string(CMD_SSID, (char *)wifi_ssid); + if (er != ESP_OK) + ESP_LOGE(TAG, "save ssid error"); + goto set_end; + } + else if (status == INPUT_PASS) + { + memset(wifi_pass, 0, WIFI_PASS_MAX_LEN); + memcpy(wifi_pass, rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set password: %s", wifi_pass); + esp_err_t er = save_string(CMD_PASS, (char *)wifi_pass); + if (er != ESP_OK) + ESP_LOGE(TAG, "save pass error"); + goto set_end; + } + else if (status == INPUT_IP) + { + memset(srv_ip, 0, SRV_IP_MAX_LEN); + memcpy(srv_ip, rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set server ip: %s", srv_ip); + esp_err_t er = save_string(CMD_IP, (char *)srv_ip); + if (er != ESP_OK) + ESP_LOGE(TAG, "save ip error"); + goto set_end; + } + else if (status == INPUT_PORT) + { + if (!is_valid_port((const char *)rcvMsg.pRcvMsgBuff, length)) + { + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; + ESP_LOGE(TAG, "invalid server port, please input again"); + return; + } + srv_port = str2num((const char *)rcvMsg.pRcvMsgBuff, length); + status = NONE; + ESP_LOGI(TAG, "you set server port: %d", srv_port); + // esp_err_t er = save_int32(CMD_PORT, srv_port); + esp_err_t er = save_string(CMD_PORT, (char *)rcvMsg.pRcvMsgBuff); + if (er != ESP_OK) + ESP_LOGE(TAG, "save port error"); + goto set_end; + } - if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_SSID, length) == 0) { - ESP_LOGI(TAG, "input your ssid [less than 32byte]:"); - status = INPUT_SSID; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PASS, length) == 0) { - ESP_LOGI(TAG, "input your password [less than 32byte]:"); - status = INPUT_PASS; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_IP, length) == 0) { - ESP_LOGI(TAG, "input server IP:"); - status = INPUT_IP; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PORT, length) == 0) { - ESP_LOGI(TAG, "input server port:"); - status = INPUT_PORT; - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_HELP, length) == 0) { - show_help_info(); - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_WIFI, length) == 0) { - ESP_LOGI(TAG, "BLE scanning ......"); - close_nvs(); - ble_client_app_register(); - //initialise_wifi(); - } else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_QUIT, length) == 0) { - ESP_LOGI(TAG, "reset wifi info:"); - clear_storage(); - close_nvs(); - system_restart(); - } else { - ESP_LOGI(TAG, "invalid command %s", rcvMsg.pRcvMsgBuff); - show_help_info(); - } - } -set_end: - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; - memset(rcvMsg.pRcvMsgBuff, 0, RECV_BUF_SIZE); - return; - } + if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_SSID, length) == 0) + { + ESP_LOGI(TAG, "input your ssid [less than 32byte]:"); + status = INPUT_SSID; + } + else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PASS, length) == 0) + { + ESP_LOGI(TAG, "input your password [less than 32byte]:"); + status = INPUT_PASS; + } + else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_IP, length) == 0) + { + ESP_LOGI(TAG, "input server IP:"); + status = INPUT_IP; + } + else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_PORT, length) == 0) + { + ESP_LOGI(TAG, "input server port:"); + status = INPUT_PORT; + } + else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_HELP, length) == 0) + { + show_help_info(); + } + else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_WIFI, length) == 0) + { + ESP_LOGI(TAG, "BLE scanning ......"); + close_nvs(); + ble_client_app_register(); + // initialise_wifi(); + } + else if (strncmp((const char *)rcvMsg.pRcvMsgBuff, CMD_QUIT, length) == 0) + { + ESP_LOGI(TAG, "reset wifi info:"); + clear_storage(); + close_nvs(); + system_restart(); + } + else + { + ESP_LOGI(TAG, "invalid command %s", rcvMsg.pRcvMsgBuff); + show_help_info(); + } + } + set_end: + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; + memset(rcvMsg.pRcvMsgBuff, 0, RECV_BUF_SIZE); + return; + } - *(rcvMsg.pWritePos) = data[0]; - uart_write_bytes(UART_NUM_0, &data[0], 1); - rcvMsg.pWritePos += 1; + *(rcvMsg.pWritePos) = data[0]; + uart_write_bytes(UART_NUM_0, &data[0], 1); + rcvMsg.pWritePos += 1; - if (rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff >= RECV_BUF_SIZE - 1) { - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; // overflow, restart - ESP_LOGI(TAG, "overflow"); - } + if (rcvMsg.pWritePos - rcvMsg.pRcvMsgBuff >= RECV_BUF_SIZE - 1) + { + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; // overflow, restart + ESP_LOGI(TAG, "overflow"); + } } static void uart_task(void *pvParameters) @@ -195,52 +233,58 @@ static void uart_task(void *pvParameters) int uart_num = UART_NUM_0; uart_event_t event; size_t buffered_size; - uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE); - for(;;) { - //Waiting for UART event. - if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - //ESP_LOGI(TAG, "uart[%d] event:", uart_num); - switch(event.type) { - //Event of UART receving data - /*We'd better handler data event fast, there would be much more data events than - other types of events. If we take too much time on data event, the queue might - be full. - in this example, we don't process data in event, but read data outside.*/ + uint8_t *dtmp = (uint8_t *)malloc(BUF_SIZE); + for (;;) + { + // Waiting for UART event. + if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY)) + { + // ESP_LOGI(TAG, "uart[%d] event:", uart_num); + switch (event.type) + { + // Event of UART receving data + /*We'd better handler data event fast, there would be much more + data events than other types of events. If we take too much time + on data event, the queue might be full. in this example, we + don't process data in event, but read data outside.*/ case UART_DATA: uart_get_buffered_data_len(uart_num, &buffered_size); - //ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); + // ESP_LOGI(TAG, "data, len: %d; buffered len: %d", + // event.size, buffered_size); break; - //Event of HW FIFO overflow detected + // Event of HW FIFO overflow detected case UART_FIFO_OVF: ESP_LOGI(TAG, "hw fifo overflow\n"); - //If fifo overflow happened, you should consider adding flow control for your application. - //We can read data out out the buffer, or directly flush the rx buffer. + // If fifo overflow happened, you should consider adding + // flow control for your application. We can read data out + // out the buffer, or directly flush the rx buffer. uart_flush(uart_num); break; - //Event of UART ring buffer full + // Event of UART ring buffer full case UART_BUFFER_FULL: ESP_LOGI(TAG, "ring buffer full\n"); - //If buffer full happened, you should consider encreasing your buffer size - //We can read data out out the buffer, or directly flush the rx buffer. + // If buffer full happened, you should consider encreasing + // your buffer size We can read data out out the buffer, or + // directly flush the rx buffer. uart_flush(uart_num); break; - //Event of UART RX break detected + // Event of UART RX break detected case UART_BREAK: ESP_LOGI(TAG, "uart rx break\n"); break; - //Event of UART parity check error + // Event of UART parity check error case UART_PARITY_ERR: ESP_LOGI(TAG, "uart parity error\n"); break; - //Event of UART frame error + // Event of UART frame error case UART_FRAME_ERR: ESP_LOGI(TAG, "uart frame error\n"); break; - //UART_PATTERN_DET + // UART_PATTERN_DET case UART_PATTERN_DET: ESP_LOGI(TAG, "uart pattern detected\n"); break; - //Others + // Others default: ESP_LOGI(TAG, "uart event type: %d\n", event.type); break; @@ -256,50 +300,54 @@ static void uart_evt_task(void *pvParameters) { int uart_num = UART_NUM_0; uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .rx_flow_ctrl_thresh = 122, + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 122, }; - //Set UART parameters + // Set UART parameters uart_param_config(uart_num, &uart_config); - //Set UART log level + // Set UART log level esp_log_level_set(TAG, ESP_LOG_INFO); - //Install UART driver, and get the queue. + // Install UART driver, and get the queue. uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0); - //Set UART pins,(-1: default pin, no change.) - //For UART0, we can just use the default pins. - //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - //Set uart pattern detect function. + // Set UART pins,(-1: default pin, no change.) + // For UART0, we can just use the default pins. + // uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, + // UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); Set uart pattern detect + // function. uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); - //Create a task to handler UART event from ISR + // Create a task to handler UART event from ISR xTaskCreate(uart_task, "uart_task", UART_TASK_STACK_SIZE, NULL, UART_TASK_PRIO, NULL); - //process data - uint8_t* data = (uint8_t*) malloc(BUF_SIZE); - do { + // process data + uint8_t *data = (uint8_t *)malloc(BUF_SIZE); + do + { int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); - if(len > 0) { - //ESP_LOGI(TAG, "uart read : %d", len); - //uart_write_bytes(uart_num, (const char*)data, len); - uart_input_handler((const char*)data, len); + if (len > 0) + { + // ESP_LOGI(TAG, "uart read : %d", len); + // uart_write_bytes(uart_num, (const char*)data, len); + uart_input_handler((const char *)data, len); } - } while(1); + } while (1); } void uart_init(void) { - memset(&rcvMsg, 0, sizeof(rcvMsg)); - rcvMsg.RcvBuffSize = RECV_BUF_SIZE; - rcvMsg.pRcvMsgBuff = NULL; - rcvMsg.pRcvMsgBuff = (uint8_t *) malloc(RECV_BUF_SIZE); - if (rcvMsg.pRcvMsgBuff == NULL) { - ESP_LOGE(TAG, "receive buffer alloc failed"); - return; - } - rcvMsg.pReadPos = rcvMsg.pRcvMsgBuff; - rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; + memset(&rcvMsg, 0, sizeof(rcvMsg)); + rcvMsg.RcvBuffSize = RECV_BUF_SIZE; + rcvMsg.pRcvMsgBuff = NULL; + rcvMsg.pRcvMsgBuff = (uint8_t *)malloc(RECV_BUF_SIZE); + if (rcvMsg.pRcvMsgBuff == NULL) + { + ESP_LOGE(TAG, "receive buffer alloc failed"); + return; + } + rcvMsg.pReadPos = rcvMsg.pRcvMsgBuff; + rcvMsg.pWritePos = rcvMsg.pRcvMsgBuff; - xTaskCreate(uart_evt_task, "uart_evt_task", UART_EVT_TASK_STACK_SIZE, NULL, UART_EVT_TASK_PRIO, NULL); + xTaskCreate(uart_evt_task, "uart_evt_task", UART_EVT_TASK_STACK_SIZE, NULL, UART_EVT_TASK_PRIO, NULL); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c index 5b5b424..2c9bd64 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/my_list.c @@ -1,6 +1,8 @@ +#include "my_list.h" + #include #include -#include "my_list.h" + #include "esp_log.h" #include "user_config.h" @@ -10,60 +12,61 @@ static scan_list_t head; void list_init(void) { - head.bda = NULL; - head.uuid = NULL; - head.rssi = 0; - head.pNext = NULL; + head.bda = NULL; + head.uuid = NULL; + head.rssi = 0; + head.pNext = NULL; } scan_list_t *list_new_item(void) { - scan_list_t *newItem = (scan_list_t *) malloc(sizeof(scan_list_t)); - if (newItem == NULL) { - ESP_LOGE(TAG, "malloc list item failed!"); - return NULL; - } - memset(newItem, 0, sizeof(scan_list_t)); - newItem->bda = (char *) malloc(BDA_SIZE); + scan_list_t *newItem = (scan_list_t *)malloc(sizeof(scan_list_t)); + if (newItem == NULL) + { + ESP_LOGE(TAG, "malloc list item failed!"); + return NULL; + } + memset(newItem, 0, sizeof(scan_list_t)); + newItem->bda = (char *)malloc(BDA_SIZE); - if (newItem->bda == NULL) { - ESP_LOGE(TAG, "alloc for BDA failed!"); - free(newItem); - return NULL; - } + if (newItem->bda == NULL) + { + ESP_LOGE(TAG, "alloc for BDA failed!"); + free(newItem); + return NULL; + } - newItem->uuid = (char *)malloc(UUID_SIZE); - if (newItem->uuid == NULL) { - ESP_LOGE(TAG, "alloc for UUID failed!"); - free(newItem->bda); - free(newItem); - return NULL; - } + newItem->uuid = (char *)malloc(UUID_SIZE); + if (newItem->uuid == NULL) + { + ESP_LOGE(TAG, "alloc for UUID failed!"); + free(newItem->bda); + free(newItem); + return NULL; + } - return newItem; + return newItem; } void list_insert_to_head(scan_list_t *item) { - scan_list_t *next = NULL; - next = head.pNext; - head.pNext = item; - item->pNext = next; + scan_list_t *next = NULL; + next = head.pNext; + head.pNext = item; + item->pNext = next; } void list_destroy(void) { - scan_list_t *next = NULL; - while (head.pNext != NULL) { - next = (head.pNext)->pNext; - free((head.pNext)->bda); - free((head.pNext)->uuid); - free(head.pNext); - head.pNext = next; - } + scan_list_t *next = NULL; + while (head.pNext != NULL) + { + next = (head.pNext)->pNext; + free((head.pNext)->bda); + free((head.pNext)->uuid); + free(head.pNext); + head.pNext = next; + } } -scan_list_t *list_get_head(void) -{ - return &head; -} \ No newline at end of file +scan_list_t *list_get_head(void) { return &head; } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/utils.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/utils.c index 752c499..2f99ae2 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/utils.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/components/utils/utils.c @@ -1,14 +1,15 @@ +#include "utils.h" + #include #include -#include "utils.h" int str2num(const char *str, int len) { - int res; - unsigned char *temp = (unsigned char *) malloc(len+1); - memcpy(temp, str, len); - temp[len] = 0; - res = atoi((const char *)temp); - free(temp); - return res; + int res; + unsigned char *temp = (unsigned char *)malloc(len + 1); + memcpy(temp, str, len); + temp[len] = 0; + res = atoi((const char *)temp); + free(temp); + return res; } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c index f3546b9..f9ced4e 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/main.c @@ -6,27 +6,25 @@ */ #include + +#include "ble.h" +#include "driver/gpio.h" +#include "esp_event_loop.h" #include "esp_log.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" - #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/event_groups.h" - -#include "nvs_flash.h" +#include "freertos/task.h" +#include "my_list.h" +#include "my_uart.h" #include "nvs.h" - -#include "driver/gpio.h" -#include "utils.h" -#include "ble.h" +#include "nvs_flash.h" #include "udp_task.h" #include "user_config.h" -#include "my_uart.h" -#include "my_list.h" +#include "utils.h" -#define LED_GPIO 2 +#define LED_GPIO 2 static const char *TAG = "main"; static EventGroupHandle_t wifi_event_group; @@ -49,298 +47,327 @@ extern void connect_server(const char *ip, int port); static void show_copyright(void) { - ESP_LOGI(TAG, "################################"); - ESP_LOGI(TAG, "## Test app ##"); - ESP_LOGI(TAG, "## 2017.4.12 ##"); - ESP_LOGI(TAG, "################################"); + ESP_LOGI(TAG, "################################"); + ESP_LOGI(TAG, "## Test app ##"); + ESP_LOGI(TAG, "## 2017.4.12 ##"); + ESP_LOGI(TAG, "################################"); } -void set_panic(void) -{ - panic = true; -} +void set_panic(void) { panic = true; } -void clear_panic(void) -{ - panic = false; -} +void clear_panic(void) { panic = false; } esp_err_t save_string(const char *key, char *str) { - esp_err_t err = nvs_set_str (my_nvs_handle, key, str); - nvs_commit(my_nvs_handle); - return err; + esp_err_t err = nvs_set_str(my_nvs_handle, key, str); + nvs_commit(my_nvs_handle); + return err; } esp_err_t save_int32(const char *key, int data) { - esp_err_t err = nvs_set_i32 (my_nvs_handle, key, data); - nvs_commit(my_nvs_handle); - return err; + esp_err_t err = nvs_set_i32(my_nvs_handle, key, data); + nvs_commit(my_nvs_handle); + return err; } int get_int32(const char *key) { - int out_value; - nvs_get_i32 (my_nvs_handle, key, &out_value); - return out_value; + int out_value; + nvs_get_i32(my_nvs_handle, key, &out_value); + return out_value; } -void get_string(const char* key, char* out_value, size_t* length) +void get_string(const char *key, char *out_value, size_t *length) { - nvs_get_str (my_nvs_handle, key, out_value, length); + nvs_get_str(my_nvs_handle, key, out_value, length); } void clear_storage(void) { - nvs_erase_all(my_nvs_handle); - nvs_commit(my_nvs_handle); + nvs_erase_all(my_nvs_handle); + nvs_commit(my_nvs_handle); } -void close_nvs(void) -{ - nvs_close(my_nvs_handle); -} +void close_nvs(void) { nvs_close(my_nvs_handle); } static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; } return ESP_OK; } void initialise_wifi(void) { - if (is_task_running) { + if (is_task_running) + { #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGE(TAG, "task was running, no need to init again"); + ESP_LOGE(TAG, "task was running, no need to init again"); #endif - send_all_data(); + send_all_data(); - //restart scanning + // restart scanning #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "###############################################"); - ESP_LOGI(TAG, "restart scanning ......"); + ESP_LOGI(TAG, "###############################################"); + ESP_LOGI(TAG, "restart scanning ......"); #endif - vTaskDelay(1000 / portTICK_PERIOD_MS); - ble_start_scanning(); - return; - } - - if (strlen((const char *)wifi_ssid) == 0) { - ESP_LOGE(TAG, "expected ssid"); - } - - if (strlen((const char *)wifi_pass) == 0) { - ESP_LOGE(TAG, "expected password"); - } + vTaskDelay(1000 / portTICK_PERIOD_MS); + ble_start_scanning(); + return; + } + + if (strlen((const char *)wifi_ssid) == 0) + { + ESP_LOGE(TAG, "expected ssid"); + } + + if (strlen((const char *)wifi_pass) == 0) + { + ESP_LOGE(TAG, "expected password"); + } tcpip_adapter_init(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); wifi_config_t wifi_config = { - .sta = { - .ssid = {0}, - .password = {0}, - }, - }; - memcpy(wifi_config.sta.ssid, wifi_ssid, strlen((const char *)wifi_ssid)); - memcpy(wifi_config.sta.password, wifi_pass, strlen((const char *)wifi_pass)); + .sta = + { + .ssid = {0}, + .password = {0}, + }, + }; + memcpy(wifi_config.sta.ssid, wifi_ssid, strlen((const char *)wifi_ssid)); + memcpy(wifi_config.sta.password, wifi_pass, strlen((const char *)wifi_pass)); ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...PASS %s", wifi_config.sta.ssid, wifi_config.sta.password); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); - if (er != ESP_OK) { - ESP_LOGE(TAG, "get wifi MAC failed"); - } else { - ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5]); - } + esp_err_t er = esp_wifi_get_mac(ESP_IF_WIFI_STA, wifi_mac); + if (er != ESP_OK) + { + ESP_LOGE(TAG, "get wifi MAC failed"); + } + else + { + ESP_LOGI(TAG, "WiFi MAC: %02x%02x%02x%02x%02x%02x", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], + wifi_mac[4], wifi_mac[5]); + } - ESP_ERROR_CHECK( esp_wifi_start() ); + ESP_ERROR_CHECK(esp_wifi_start()); - wifi_check = true; // start wifi checking + wifi_check = true; // start wifi checking } static void tmp_task(void *pvParameters) { - is_task_running = true; - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + is_task_running = true; + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) + { ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "IP:" IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:" IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:" IPSTR, IP2STR(&ip_info.gw)); ESP_LOGI(TAG, "~~~~~~~~~~~"); } - wifi_check = false; // stop wifi checking - - if (strlen((const char *)srv_ip) == 0) { - ESP_LOGE(TAG, "expected server IP, reset board to setup again!"); - break; - } - - if (srv_port == 0) { - ESP_LOGE(TAG, "expected server port, reset board to setup again!"); - break; - } - - // start espconn - connect_server((const char *)srv_ip, srv_port); - - while(1) { - vTaskDelay(3000 / portTICK_RATE_MS); // prevent trigger watch dog - } - } - vTaskDelete(NULL); - is_task_running = false; + wifi_check = false; // stop wifi checking + + if (strlen((const char *)srv_ip) == 0) + { + ESP_LOGE(TAG, "expected server IP, reset board to setup again!"); + break; + } + + if (srv_port == 0) + { + ESP_LOGE(TAG, "expected server port, reset board to setup again!"); + break; + } + + // start espconn + connect_server((const char *)srv_ip, srv_port); + + while (1) + { + vTaskDelay(3000 / portTICK_RATE_MS); // prevent trigger watch dog + } + } + vTaskDelete(NULL); + is_task_running = false; } void wifi_init_task(void) { - if (is_task_running) { + if (is_task_running) + { #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGE(TAG, "task was running"); + ESP_LOGE(TAG, "task was running"); #endif - return; - } - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); + return; + } + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); } static void led_task(void *pvParameters) { - while(1) { - if (panic) { - if (toggle) { - gpio_set_level(LED_GPIO, 1); - } else { - gpio_set_level(LED_GPIO, 0); - } - toggle = !toggle; - vTaskDelay(1000 / portTICK_RATE_MS); - } else { - //ESP_LOGI(TAG, "tmp_task loop"); - vTaskDelay(1000 / portTICK_RATE_MS); // prevent trigger watch dog - } - - if (wifi_check) { - wifi_check_count++; - if (wifi_check_count >= WIFI_CHECK_TIMEOUT) { - set_panic(); - wifi_check_count = 0; - } - } - } - vTaskDelete(NULL); + while (1) + { + if (panic) + { + if (toggle) + { + gpio_set_level(LED_GPIO, 1); + } + else + { + gpio_set_level(LED_GPIO, 0); + } + toggle = !toggle; + vTaskDelay(1000 / portTICK_RATE_MS); + } + else + { + // ESP_LOGI(TAG, "tmp_task loop"); + vTaskDelay(1000 / portTICK_RATE_MS); // prevent trigger watch dog + } + + if (wifi_check) + { + wifi_check_count++; + if (wifi_check_count >= WIFI_CHECK_TIMEOUT) + { + set_panic(); + wifi_check_count = 0; + } + } + } + vTaskDelete(NULL); } static void led_task_init(void) { - gpio_pad_select_gpio(LED_GPIO); - /* Set the GPIO as a push/pull output */ + gpio_pad_select_gpio(LED_GPIO); + /* Set the GPIO as a push/pull output */ gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(LED_GPIO, 1); - xTaskCreate(&led_task, "led_task", LED_TASK_STACK_SIZE, NULL, LED_TASK_PRIO, NULL); + xTaskCreate(&led_task, "led_task", LED_TASK_STACK_SIZE, NULL, LED_TASK_PRIO, NULL); } static void nvs_init(void) { - nvs_flash_init(); - esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_nvs_handle); - if (err != ESP_OK) { + nvs_flash_init(); + esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_nvs_handle); + if (err != ESP_OK) + { ESP_LOGE(TAG, "Error (%d) opening NVS!\n", err); - } else { - ESP_LOGI(TAG, "NVS open OK"); - } - + } + else + { + ESP_LOGI(TAG, "NVS open OK"); + } } static void load_config(void) { - size_t length = WIFI_SSID_MAX_LEN; - esp_err_t er; - er = nvs_get_str (my_nvs_handle, CMD_SSID, (char*)wifi_ssid, &length); - ESP_LOGI(TAG, "load ssid: %s", wifi_ssid); - if (er != ESP_OK) { - ESP_LOGE(TAG, "SSID not saved before"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset SSID: %s", wifi_ssid); - } - - er = nvs_get_str (my_nvs_handle, CMD_PASS, (char*)wifi_pass, &length); - ESP_LOGI(TAG, "load password: %s", wifi_pass); - if (er != ESP_OK) { - ESP_LOGE(TAG, "password not saved before"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset password: %s", wifi_pass); - } - - length = SRV_IP_MAX_LEN; - er = nvs_get_str (my_nvs_handle, CMD_IP, (char*)srv_ip, &length); - ESP_LOGI(TAG, "load ip: %s", srv_ip); - if (length == 0 || er != ESP_OK) { - ESP_LOGE(TAG, "ip not saved before"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset IP: %s", srv_ip); - } - - char port[SRV_IP_MAX_LEN] = {0}; - er = nvs_get_str (my_nvs_handle, CMD_PORT, (char*)port, &length); - if (er != ESP_OK) { - ESP_LOGE(TAG, "port get failed"); - goto load_config_err; - } else { - ESP_LOGI(TAG, "preset port: %s", port); - } - srv_port = str2num((const char *)port, strlen(port)); - ESP_LOGI(TAG, "preset port in num: %d", srv_port); - - // ble scan and connect to wifi directly - ESP_LOGI(TAG, "BLE scanning ......"); - ble_client_app_register(); - return; + size_t length = WIFI_SSID_MAX_LEN; + esp_err_t er; + er = nvs_get_str(my_nvs_handle, CMD_SSID, (char *)wifi_ssid, &length); + ESP_LOGI(TAG, "load ssid: %s", wifi_ssid); + if (er != ESP_OK) + { + ESP_LOGE(TAG, "SSID not saved before"); + goto load_config_err; + } + else + { + ESP_LOGI(TAG, "preset SSID: %s", wifi_ssid); + } + + er = nvs_get_str(my_nvs_handle, CMD_PASS, (char *)wifi_pass, &length); + ESP_LOGI(TAG, "load password: %s", wifi_pass); + if (er != ESP_OK) + { + ESP_LOGE(TAG, "password not saved before"); + goto load_config_err; + } + else + { + ESP_LOGI(TAG, "preset password: %s", wifi_pass); + } + + length = SRV_IP_MAX_LEN; + er = nvs_get_str(my_nvs_handle, CMD_IP, (char *)srv_ip, &length); + ESP_LOGI(TAG, "load ip: %s", srv_ip); + if (length == 0 || er != ESP_OK) + { + ESP_LOGE(TAG, "ip not saved before"); + goto load_config_err; + } + else + { + ESP_LOGI(TAG, "preset IP: %s", srv_ip); + } + + char port[SRV_IP_MAX_LEN] = {0}; + er = nvs_get_str(my_nvs_handle, CMD_PORT, (char *)port, &length); + if (er != ESP_OK) + { + ESP_LOGE(TAG, "port get failed"); + goto load_config_err; + } + else + { + ESP_LOGI(TAG, "preset port: %s", port); + } + srv_port = str2num((const char *)port, strlen(port)); + ESP_LOGI(TAG, "preset port in num: %d", srv_port); + + // ble scan and connect to wifi directly + ESP_LOGI(TAG, "BLE scanning ......"); + ble_client_app_register(); + return; load_config_err: - ESP_LOGE(TAG, "some parameters not set"); - //set_panic(); - return; + ESP_LOGE(TAG, "some parameters not set"); + // set_panic(); + return; } void app_main() { - ESP_LOGI(TAG, "App started"); - nvs_init(); + ESP_LOGI(TAG, "App started"); + nvs_init(); + + show_copyright(); - show_copyright(); - - list_init(); - ble_init(); - uart_init(); + list_init(); + ble_init(); + uart_init(); - led_task_init(); + led_task_init(); - wifi_event_group = xEventGroupCreate(); + wifi_event_group = xEventGroupCreate(); - show_help_info(); - load_config(); + show_help_info(); + load_config(); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/udp_task.c b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/udp_task.c index a2a527b..3809506 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/udp_task.c +++ b/LuaNode_Esp32/LuaNode32/examples/ble_to_udp_server/main/udp_task.c @@ -1,17 +1,18 @@ +#include "udp_task.h" + #include #include -#include "udp_task.h" -#include "lwip/api.h" +#include "ble.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_log.h" -#include "utils.h" +#include "lwip/api.h" #include "my_list.h" -#include "ble.h" #include "user_config.h" +#include "utils.h" -#define LOCAL_PORT 9999 +#define LOCAL_PORT 9999 extern uint8_t wifi_mac[6]; extern void ble_client_app_register(void); @@ -22,87 +23,92 @@ static struct netconn *conn; static void ip_str2num(const char *ip, int *res) { - int len = strlen(ip), i = 0; - int start = 0; - for (i = 0; i < len; i++) { - if (ip[i] == '.') { - *res = str2num((ip+start), (i-start)); - res++; - start = i+1; - ESP_LOGI(TAG, "%s", ip+start); - } - } - // last value - *res = str2num((ip+start), (i-start)); + int len = strlen(ip), i = 0; + int start = 0; + for (i = 0; i < len; i++) + { + if (ip[i] == '.') + { + *res = str2num((ip + start), (i - start)); + res++; + start = i + 1; + ESP_LOGI(TAG, "%s", ip + start); + } + } + // last value + *res = str2num((ip + start), (i - start)); } void send_all_data(void) { - // send BLE scan results one by one - char buff[94] = {0}; - scan_list_t *h = list_get_head(); - scan_list_t *iterator = h->pNext; - while (iterator != NULL) { - memset(buff, 0, 94); - sprintf(buff, "%02x%02x%02x%02x%02x%02x, %s, %s, %d\r\n", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], wifi_mac[4], wifi_mac[5], - iterator->bda, iterator->uuid, iterator->rssi); - send_data((const char *)buff, 71); + // send BLE scan results one by one + char buff[94] = {0}; + scan_list_t *h = list_get_head(); + scan_list_t *iterator = h->pNext; + while (iterator != NULL) + { + memset(buff, 0, 94); + sprintf(buff, "%02x%02x%02x%02x%02x%02x, %s, %s, %d\r\n", wifi_mac[0], wifi_mac[1], wifi_mac[2], wifi_mac[3], + wifi_mac[4], wifi_mac[5], iterator->bda, iterator->uuid, iterator->rssi); + send_data((const char *)buff, 71); #ifdef ENABLE_SCAN_OUTPUT - ESP_LOGI(TAG, "%s", buff); + ESP_LOGI(TAG, "%s", buff); #endif - iterator = iterator->pNext; - vTaskDelay(400 / portTICK_PERIOD_MS); - send_data((const char *)"\r\n", strlen("\r\n")); - vTaskDelay(200 / portTICK_PERIOD_MS); - } - list_destroy(); + iterator = iterator->pNext; + vTaskDelay(400 / portTICK_PERIOD_MS); + send_data((const char *)"\r\n", strlen("\r\n")); + vTaskDelay(200 / portTICK_PERIOD_MS); + } + list_destroy(); } void connect_server(const char *ip, int port) { - conn = netconn_new(NETCONN_UDP); - ip_addr_t serverip; - int ip_val[4] = {0}; - ip_str2num(ip, ip_val); - ESP_LOGI(TAG, "IP -> %d.%d.%d.%d", ip_val[0], ip_val[1], ip_val[2], ip_val[3]); - IP_ADDR4(&serverip, ip_val[0], ip_val[1], ip_val[2], ip_val[3]); - - if (conn == NULL) { - ESP_LOGE(TAG, "Create conn failed"); - return; - } - netconn_bind(conn, NULL, LOCAL_PORT); - err_t er; - while ((er = netconn_connect(conn, &serverip, port)) != ERR_OK) { - ESP_LOGE(TAG, "Connect server failed, error code: %d, try again 1 seconds", er); - set_panic(); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - - clear_panic(); - ESP_LOGI(TAG, "Connected to UDP server"); - //send_data((const char *)"test", 4); - - //ble_client_app_register(); - - send_all_data(); - - //restart scanning - ESP_LOGI(TAG, "###############################################"); - ESP_LOGI(TAG, "restart scanning ......"); - vTaskDelay(1000 / portTICK_PERIOD_MS); - ble_start_scanning(); + conn = netconn_new(NETCONN_UDP); + ip_addr_t serverip; + int ip_val[4] = {0}; + ip_str2num(ip, ip_val); + ESP_LOGI(TAG, "IP -> %d.%d.%d.%d", ip_val[0], ip_val[1], ip_val[2], ip_val[3]); + IP_ADDR4(&serverip, ip_val[0], ip_val[1], ip_val[2], ip_val[3]); + + if (conn == NULL) + { + ESP_LOGE(TAG, "Create conn failed"); + return; + } + netconn_bind(conn, NULL, LOCAL_PORT); + err_t er; + while ((er = netconn_connect(conn, &serverip, port)) != ERR_OK) + { + ESP_LOGE(TAG, "Connect server failed, error code: %d, try again 1 seconds", er); + set_panic(); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + clear_panic(); + ESP_LOGI(TAG, "Connected to UDP server"); + // send_data((const char *)"test", 4); + + // ble_client_app_register(); + + send_all_data(); + + // restart scanning + ESP_LOGI(TAG, "###############################################"); + ESP_LOGI(TAG, "restart scanning ......"); + vTaskDelay(1000 / portTICK_PERIOD_MS); + ble_start_scanning(); } void send_data(const char *data, int len) { - struct netbuf *TCPNetbuf =netbuf_new(); - netbuf_ref(TCPNetbuf, data, len); - netconn_send(conn,TCPNetbuf); - netbuf_free(TCPNetbuf); + struct netbuf *TCPNetbuf = netbuf_new(); + netbuf_ref(TCPNetbuf, data, len); + netconn_send(conn, TCPNetbuf); + netbuf_free(TCPNetbuf); } void disconnect_server() { - // not implement + // not implement } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/app_main.c b/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/app_main.c index 8cb941a..fd4f5c9 100644 --- a/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/bluetooth_scanner/main/app_main.c @@ -1,22 +1,21 @@ /** * A bluetooth scanner sample - * + * * Nicholas3388 * 2017.02.24 */ -#include -#include - #include #include #include #include +#include +#include #include "sdkconfig.h" -#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" -#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] +#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] static const char *bt_event_type_to_string(uint32_t eventType); static const char *bt_gap_search_event_type_to_string(uint32_t searchEvt); @@ -25,191 +24,205 @@ static const char *bt_dev_type_to_string(esp_bt_dev_type_t type); static const char tag[] = "ble1"; -static void dump_adv_payload(uint8_t *payload) { - uint8_t length; - uint8_t ad_type; - uint8_t sizeConsumed = 0; - int finished = 0; - int i; - char text[31*2+1]; - //sprintf(text, "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x") - while(!finished) { - length = *payload; - payload++; - if (length != 0) { - ad_type = *payload; - payload += length; - ESP_LOGD(tag, "Type: 0x%.2x, length: %d", ad_type, length); - - } - - sizeConsumed = 1 + length; - if (sizeConsumed >=31 || length == 0) { - finished = 1; - } - } // !finished -} // dump_adv_payload - - -static void gap_event_handler(uint32_t event, void *param) { - ESP_LOGI(tag, "Received a GAP event: %s", bt_event_type_to_string(event)); - esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param; - switch (event) { - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: - ESP_LOGI(tag, "status: %d", p->scan_param_cmpl.status); - break; - case ESP_GAP_BLE_SCAN_RESULT_EVT: +static void dump_adv_payload(uint8_t *payload) +{ + uint8_t length; + uint8_t ad_type; + uint8_t sizeConsumed = 0; + int finished = 0; + int i; + char text[31 * 2 + 1]; + // sprintf(text, "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x") + while (!finished) + { + length = *payload; + payload++; + if (length != 0) { - ESP_LOGI(tag, "device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", BT_BD_ADDR_HEX(p->scan_rst.bda)); - ESP_LOGI(tag, "device type: %s", bt_dev_type_to_string(p->scan_rst.dev_type)); - ESP_LOGI(tag, "search_evt: %s", bt_gap_search_event_type_to_string(p->scan_rst.search_evt)); - ESP_LOGI(tag, "addr_type: %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type)); - ESP_LOGI(tag, "rssi: %d", p->scan_rst.rssi); - ESP_LOGI(tag, "flag: %d", p->scan_rst.flag); - ESP_LOGI(tag, "num_resps: %d", p->scan_rst.num_resps); - - if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) { - ESP_LOGI(tag, "payload:"); - uint8_t len; - uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &len); - ESP_LOGI(tag, "len: %d, %.*s", len, len, data); - ESP_LOGI(tag, "dump -"); - dump_adv_payload(p->scan_rst.ble_adv); - } - ESP_LOGI(tag, ""); - } - break; - default: + ad_type = *payload; + payload += length; + ESP_LOGD(tag, "Type: 0x%.2x, length: %d", ad_type, length); + } + + sizeConsumed = 1 + length; + if (sizeConsumed >= 31 || length == 0) + { + finished = 1; + } + } // !finished +} // dump_adv_payload + +static void gap_event_handler(uint32_t event, void *param) +{ + ESP_LOGI(tag, "Received a GAP event: %s", bt_event_type_to_string(event)); + esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param; + switch (event) + { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + ESP_LOGI(tag, "status: %d", p->scan_param_cmpl.status); + break; + case ESP_GAP_BLE_SCAN_RESULT_EVT: + { + ESP_LOGI(tag, "device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", BT_BD_ADDR_HEX(p->scan_rst.bda)); + ESP_LOGI(tag, "device type: %s", bt_dev_type_to_string(p->scan_rst.dev_type)); + ESP_LOGI(tag, "search_evt: %s", bt_gap_search_event_type_to_string(p->scan_rst.search_evt)); + ESP_LOGI(tag, "addr_type: %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type)); + ESP_LOGI(tag, "rssi: %d", p->scan_rst.rssi); + ESP_LOGI(tag, "flag: %d", p->scan_rst.flag); + ESP_LOGI(tag, "num_resps: %d", p->scan_rst.num_resps); + + if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) + { + ESP_LOGI(tag, "payload:"); + uint8_t len; + uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &len); + ESP_LOGI(tag, "len: %d, %.*s", len, len, data); + ESP_LOGI(tag, "dump -"); + dump_adv_payload(p->scan_rst.ble_adv); + } + ESP_LOGI(tag, ""); + } break; + default: + break; + } + +} // gap_event_handler + +static const char *bt_dev_type_to_string(esp_bt_dev_type_t type) +{ + switch (type) + { + case ESP_BT_DEVICE_TYPE_BREDR: + return "ESP_BT_DEVICE_TYPE_BREDR"; + case ESP_BT_DEVICE_TYPE_BLE: + return "ESP_BT_DEVICE_TYPE_BLE"; + case ESP_BT_DEVICE_TYPE_DUMO: + return "ESP_BT_DEVICE_TYPE_DUMO"; + default: + return "Unknown"; + } +} // bt_dev_type_to_string + +static const char *bt_addr_t_to_string(esp_ble_addr_type_t type) +{ + switch (type) + { + case BLE_ADDR_TYPE_PUBLIC: + return "BLE_ADDR_TYPE_PUBLIC"; + case BLE_ADDR_TYPE_RANDOM: + return "BLE_ADDR_TYPE_RANDOM"; + case BLE_ADDR_TYPE_RPA_PUBLIC: + return "BLE_ADDR_TYPE_RPA_PUBLIC"; + case BLE_ADDR_TYPE_RPA_RANDOM: + return "BLE_ADDR_TYPE_RPA_RANDOM"; + default: + return "Unknown addr_t"; } - -} // gap_event_handler - -static const char *bt_dev_type_to_string(esp_bt_dev_type_t type) { - switch(type) { - case ESP_BT_DEVICE_TYPE_BREDR: - return "ESP_BT_DEVICE_TYPE_BREDR"; - case ESP_BT_DEVICE_TYPE_BLE: - return "ESP_BT_DEVICE_TYPE_BLE"; - case ESP_BT_DEVICE_TYPE_DUMO: - return "ESP_BT_DEVICE_TYPE_DUMO"; - default: - return "Unknown"; - } -} // bt_dev_type_to_string - -static const char *bt_addr_t_to_string(esp_ble_addr_type_t type) { - switch(type) { - case BLE_ADDR_TYPE_PUBLIC: - return "BLE_ADDR_TYPE_PUBLIC"; - case BLE_ADDR_TYPE_RANDOM: - return "BLE_ADDR_TYPE_RANDOM"; - case BLE_ADDR_TYPE_RPA_PUBLIC: - return "BLE_ADDR_TYPE_RPA_PUBLIC"; - case BLE_ADDR_TYPE_RPA_RANDOM: - return "BLE_ADDR_TYPE_RPA_RANDOM"; - default: - return "Unknown addr_t"; - } -} // bt_addr_t_to_string - -static const char *bt_gap_search_event_type_to_string(uint32_t searchEvt) { - switch(searchEvt) { - case ESP_GAP_SEARCH_INQ_RES_EVT: - return "ESP_GAP_SEARCH_INQ_RES_EVT"; - case ESP_GAP_SEARCH_INQ_CMPL_EVT: - return "ESP_GAP_SEARCH_INQ_CMPL_EVT"; - case ESP_GAP_SEARCH_DISC_RES_EVT: - return "ESP_GAP_SEARCH_DISC_RES_EVT"; - case ESP_GAP_SEARCH_DISC_BLE_RES_EVT: - return "ESP_GAP_SEARCH_DISC_BLE_RES_EVT"; - case ESP_GAP_SEARCH_DISC_CMPL_EVT: - return "ESP_GAP_SEARCH_DISC_CMPL_EVT"; - case ESP_GAP_SEARCH_DI_DISC_CMPL_EVT: - return "ESP_GAP_SEARCH_DI_DISC_CMPL_EVT"; - case ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT: - return "ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT"; - default: - return "Unknown event type"; - } -} // bt_gap_search_event_type_to_string +} // bt_addr_t_to_string + +static const char *bt_gap_search_event_type_to_string(uint32_t searchEvt) +{ + switch (searchEvt) + { + case ESP_GAP_SEARCH_INQ_RES_EVT: + return "ESP_GAP_SEARCH_INQ_RES_EVT"; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + return "ESP_GAP_SEARCH_INQ_CMPL_EVT"; + case ESP_GAP_SEARCH_DISC_RES_EVT: + return "ESP_GAP_SEARCH_DISC_RES_EVT"; + case ESP_GAP_SEARCH_DISC_BLE_RES_EVT: + return "ESP_GAP_SEARCH_DISC_BLE_RES_EVT"; + case ESP_GAP_SEARCH_DISC_CMPL_EVT: + return "ESP_GAP_SEARCH_DISC_CMPL_EVT"; + case ESP_GAP_SEARCH_DI_DISC_CMPL_EVT: + return "ESP_GAP_SEARCH_DI_DISC_CMPL_EVT"; + case ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT: + return "ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT"; + default: + return "Unknown event type"; + } +} // bt_gap_search_event_type_to_string /* * Convert a BT GAP event type to a string representation. */ -static const char *bt_event_type_to_string(uint32_t eventType) { - switch(eventType) { - case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - return "ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT"; - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: - return "ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT"; - case ESP_GAP_BLE_SCAN_RESULT_EVT: - return "ESP_GAP_BLE_SCAN_RESULT_EVT"; - case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: - return "ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT"; - default: - return "Unknown event type"; - } -} // bt_event_type_to_string - - -void bt_task(void *ignore) { - int errRc; - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - esp_bt_controller_init(&bt_cfg); - int ret = esp_bluedroid_init(); - if (ret) { +static const char *bt_event_type_to_string(uint32_t eventType) +{ + switch (eventType) + { + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + return "ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT"; + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + return "ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT"; + case ESP_GAP_BLE_SCAN_RESULT_EVT: + return "ESP_GAP_BLE_SCAN_RESULT_EVT"; + case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: + return "ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT"; + default: + return "Unknown event type"; + } +} // bt_event_type_to_string + +void bt_task(void *ignore) +{ + int errRc; + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + esp_bt_controller_init(&bt_cfg); + int ret = esp_bluedroid_init(); + if (ret) + { ESP_LOGE(tag, "init bluedroid failed\n"); return; } ret = esp_bluedroid_enable(); - if (ret) { + if (ret) + { ESP_LOGE(tag, "init bluedroid failed2\n"); return; } - errRc = esp_ble_gap_register_callback(gap_event_handler); - if (errRc != ESP_OK) { - ESP_LOGE(tag, "esp_ble_gap_register_callback: rc=%d", errRc); - goto end; - } - static esp_ble_scan_params_t ble_scan_params = { - .scan_type = BLE_SCAN_TYPE_ACTIVE, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x80, - .scan_window = 0x30 - }; - errRc = esp_ble_gap_set_scan_params(&ble_scan_params); - if (errRc != ESP_OK) { - ESP_LOGE(tag, "esp_ble_gap_set_scan_params: rc=%d", errRc); - goto end; - } - - while (1) { - ESP_LOGI(tag, "Start scanning ..."); - ESP_LOGI(tag, ""); - errRc = esp_ble_gap_start_scanning(15); - if (errRc != ESP_OK) { - ESP_LOGE(tag, "esp_ble_gap_start_scanning: rc=%d", errRc); - goto end; - } - vTaskDelay(15000 / portTICK_PERIOD_MS); - - int i; - for (i=10; i>0; i--) { - ESP_LOGI(tag, "Rescan countdown %d", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - } - -end: - vTaskDelete(NULL); -} // bt_task + errRc = esp_ble_gap_register_callback(gap_event_handler); + if (errRc != ESP_OK) + { + ESP_LOGE(tag, "esp_ble_gap_register_callback: rc=%d", errRc); + goto end; + } + static esp_ble_scan_params_t ble_scan_params = {.scan_type = BLE_SCAN_TYPE_ACTIVE, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x80, + .scan_window = 0x30}; + errRc = esp_ble_gap_set_scan_params(&ble_scan_params); + if (errRc != ESP_OK) + { + ESP_LOGE(tag, "esp_ble_gap_set_scan_params: rc=%d", errRc); + goto end; + } + while (1) + { + ESP_LOGI(tag, "Start scanning ..."); + ESP_LOGI(tag, ""); + errRc = esp_ble_gap_start_scanning(15); + if (errRc != ESP_OK) + { + ESP_LOGE(tag, "esp_ble_gap_start_scanning: rc=%d", errRc); + goto end; + } + vTaskDelay(15000 / portTICK_PERIOD_MS); -void app_main(void) -{ - xTaskCreatePinnedToCore(&bt_task, "btTask", 2048, NULL, 5, NULL, 0); -} + int i; + for (i = 10; i > 0; i--) + { + ESP_LOGI(tag, "Rescan countdown %d", i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } + +end: + vTaskDelete(NULL); +} // bt_task + +void app_main(void) { xTaskCreatePinnedToCore(&bt_task, "btTask", 2048, NULL, 5, NULL, 0); } diff --git a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/camera.c b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/camera.c index 9f481e0..2292fae 100644 --- a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/camera.c +++ b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/camera.c @@ -1,9 +1,9 @@ /* - * Portions of this file come from OpenMV project (see sensor_* functions in the end of file) - * Here is the copyright for these parts: - * This file is part of the OpenMV project. - * Copyright (c) 2013/2014 Ibrahim Abdelkader - * This work is licensed under the MIT license, see the file LICENSE for details. + * Portions of this file come from OpenMV project (see sensor_* functions in the + * end of file) Here is the copyright for these parts: This file is part of the + * OpenMV project. Copyright (c) 2013/2014 Ibrahim Abdelkader + * This work is licensed under the MIT license, see the + * file LICENSE for details. * * * Rest of the functions are licensed under Apache license as found below: @@ -23,30 +23,32 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "camera.h" + #include +#include +#include + +#include "driver/gpio.h" +#include "driver/ledc.h" +#include "driver/periph_ctrl.h" +#include "esp_intr_alloc.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/semphr.h" -#include "soc/soc.h" +#include "freertos/task.h" +#include "ov7725.h" +#include "rom/lldesc.h" #include "sccb.h" -#include "wiring.h" -#include "driver/gpio.h" -#include "driver/ledc.h" +#include "sensor.h" #include "soc/gpio_sig_map.h" #include "soc/i2s_reg.h" #include "soc/i2s_struct.h" #include "soc/io_mux_reg.h" -#include "sensor.h" -#include "ov7725.h" -#include -#include -#include "rom/lldesc.h" -#include "esp_intr_alloc.h" -#include "camera.h" -#include "esp_log.h" -#include "driver/periph_ctrl.h" +#include "soc/soc.h" +#include "wiring.h" -# define ENABLE_TEST_PATTERN CONFIG_ENABLE_TEST_PATTERN +#define ENABLE_TEST_PATTERN CONFIG_ENABLE_TEST_PATTERN static const char* TAG = "camera"; @@ -60,20 +62,20 @@ static size_t s_fb_size; static volatile bool s_i2s_running = 0; const int resolution[][2] = { - {40, 30 }, /* 40x30 */ - {64, 32 }, /* 64x32 */ - {64, 64 }, /* 64x64 */ - {88, 72 }, /* QQCIF */ - {160, 120}, /* QQVGA */ - {128, 160}, /* QQVGA2*/ - {176, 144}, /* QCIF */ - {240, 160}, /* HQVGA */ - {320, 240}, /* QVGA */ - {352, 288}, /* CIF */ - {640, 480}, /* VGA */ - {800, 600}, /* SVGA */ - {1280, 1024}, /* SXGA */ - {1600, 1200}, /* UXGA */ + {40, 30}, /* 40x30 */ + {64, 32}, /* 64x32 */ + {64, 64}, /* 64x64 */ + {88, 72}, /* QQCIF */ + {160, 120}, /* QQVGA */ + {128, 160}, /* QQVGA2*/ + {176, 144}, /* QCIF */ + {240, 160}, /* HQVGA */ + {320, 240}, /* QVGA */ + {352, 288}, /* CIF */ + {640, 480}, /* VGA */ + {800, 600}, /* SVGA */ + {1280, 1024}, /* SXGA */ + {1600, 1200}, /* UXGA */ }; static void output_pin_setting(); @@ -82,7 +84,8 @@ static void get_frame(size_t line_width, int height); esp_err_t camera_init(const camera_config_t* config) { - if (s_initialized) { + if (s_initialized) + { return ESP_ERR_INVALID_STATE; } @@ -90,14 +93,15 @@ esp_err_t camera_init(const camera_config_t* config) ESP_LOGD(TAG, "Initializing SSCB"); SCCB_Init(s_config.pin_sscb_sda, s_config.pin_sscb_scl); ESP_LOGD(TAG, "lock FIFO"); - output_pin_setting(); - delay(5); - gpio_set_level(s_config.pin_wen, 0); - gpio_set_level(s_config.pin_oe, 1); + output_pin_setting(); + delay(5); + gpio_set_level(s_config.pin_wen, 0); + gpio_set_level(s_config.pin_oe, 1); delay(12); ESP_LOGD(TAG, "Searching for camera address"); uint8_t addr = SCCB_Probe(); - if (addr == 0) { + if (addr == 0) + { ESP_LOGE(TAG, "Camera address not found"); return ESP_ERR_CAMERA_NOT_DETECTED; } @@ -105,13 +109,12 @@ esp_err_t camera_init(const camera_config_t* config) s_sensor.slv_addr = addr; ov7725_init(&s_sensor); - ESP_LOGD(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x", - s_sensor.id.pid, s_sensor.id.ver, s_sensor.id.midh, - s_sensor.id.midl); + ESP_LOGD(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x", s_sensor.id.pid, s_sensor.id.ver, + s_sensor.id.midh, s_sensor.id.midl); ESP_LOGD(TAG, "Doing SW reset of sensor"); - //s_sensor.reset(&s_sensor); - s_sensor.set_pixformat(&s_sensor, PIXFORMAT_RGB565); + // s_sensor.reset(&s_sensor); + s_sensor.set_pixformat(&s_sensor, PIXFORMAT_RGB565); #if ENABLE_TEST_PATTERN /* Test pattern may get handy @@ -127,16 +130,17 @@ esp_err_t camera_init(const camera_config_t* config) s_fb_w = resolution[framesize][0]; s_fb_h = resolution[framesize][1]; ESP_LOGD(TAG, "Setting frame size at %dx%d", s_fb_w, s_fb_h); - if (s_sensor.set_framesize(&s_sensor, framesize) != 0) { + if (s_sensor.set_framesize(&s_sensor, framesize) != 0) + { ESP_LOGE(TAG, "Failed to set frame size"); return ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE; } s_fb_size = s_fb_w * s_fb_h * 2; - ESP_LOGD(TAG, "Allocating frame buffer (%dx%d, %d bytes)", s_fb_w, s_fb_h, - s_fb_size); - s_fb = (uint8_t*) malloc(s_fb_size); - if (s_fb == NULL) { + ESP_LOGD(TAG, "Allocating frame buffer (%dx%d, %d bytes)", s_fb_w, s_fb_h, s_fb_size); + s_fb = (uint8_t*)malloc(s_fb_size); + if (s_fb == NULL) + { ESP_LOGE(TAG, "Failed to allocate frame buffer"); return ESP_ERR_NO_MEM; } @@ -144,15 +148,9 @@ esp_err_t camera_init(const camera_config_t* config) input_pin_setting(); // skip at least one frame after changing camera settings - while (gpio_get_level(s_config.pin_vsync) == 0) { - ; - } - while (gpio_get_level(s_config.pin_vsync) != 0) { - ; - } - while (gpio_get_level(s_config.pin_vsync) == 0) { - ; - } + while (gpio_get_level(s_config.pin_vsync) == 0) { ; } + while (gpio_get_level(s_config.pin_vsync) != 0) { ; } + while (gpio_get_level(s_config.pin_vsync) == 0) { ; } ESP_LOGD(TAG, "Init done"); s_initialized = true; @@ -161,7 +159,8 @@ esp_err_t camera_init(const camera_config_t* config) uint8_t* camera_get_fb() { - if (!s_initialized) { + if (!s_initialized) + { return NULL; } return s_fb; @@ -169,7 +168,8 @@ uint8_t* camera_get_fb() int camera_get_fb_width() { - if (!s_initialized) { + if (!s_initialized) + { return 0; } return s_fb_w; @@ -177,7 +177,8 @@ int camera_get_fb_width() int camera_get_fb_height() { - if (!s_initialized) { + if (!s_initialized) + { return 0; } return s_fb_h; @@ -185,7 +186,8 @@ int camera_get_fb_height() esp_err_t camera_run() { - if (!s_initialized) { + if (!s_initialized) + { return ESP_ERR_INVALID_STATE; } get_frame(s_fb_w, s_fb_h); @@ -194,26 +196,38 @@ esp_err_t camera_run() void camera_print_fb() { - /* Number of pixels to skip - in order to fit into terminal screen. - Assumed picture to be 80 columns wide. - Skip twice as more rows as they look higher. - */ - int pixels_to_skip = s_fb_w / 80; - - for (int ih = 0; ih < s_fb_h; ih += pixels_to_skip * 2){ - for (int iw = 0; iw < s_fb_w * 2; iw += pixels_to_skip){ - uint8_t px = (s_fb[iw + (ih * s_fb_w * 2)]); - if (px < 26) printf(" "); - else if (px < 51) printf("."); - else if (px < 77) printf(":"); - else if (px < 102) printf("-"); - else if (px < 128) printf("="); - else if (px < 154) printf("+"); - else if (px < 179) printf("*"); - else if (px < 205) printf("#"); - else if (px < 230) printf("%%"); - else printf("@"); + /* Number of pixels to skip + in order to fit into terminal screen. + Assumed picture to be 80 columns wide. + Skip twice as more rows as they look higher. + */ + int pixels_to_skip = s_fb_w / 80; + + for (int ih = 0; ih < s_fb_h; ih += pixels_to_skip * 2) + { + for (int iw = 0; iw < s_fb_w * 2; iw += pixels_to_skip) + { + uint8_t px = (s_fb[iw + (ih * s_fb_w * 2)]); + if (px < 26) + printf(" "); + else if (px < 51) + printf("."); + else if (px < 77) + printf(":"); + else if (px < 102) + printf("-"); + else if (px < 128) + printf("="); + else if (px < 154) + printf("+"); + else if (px < 179) + printf("*"); + else if (px < 205) + printf("#"); + else if (px < 230) + printf("%%"); + else + printf("@"); } printf("\n"); } @@ -221,20 +235,13 @@ void camera_print_fb() static void output_pin_setting() { - gpio_num_t pins[] = { - s_config.pin_wen, - s_config.pin_rrst, - s_config.pin_wrst, - s_config.pin_rclk, - s_config.pin_oe - }; - gpio_config_t conf = { - .mode = GPIO_MODE_OUTPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE - }; - for (int i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) { + gpio_num_t pins[] = {s_config.pin_wen, s_config.pin_rrst, s_config.pin_wrst, s_config.pin_rclk, s_config.pin_oe}; + gpio_config_t conf = {.mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE}; + for (int i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) + { conf.pin_bit_mask = 1LL << pins[i]; gpio_config(&conf); } @@ -243,71 +250,60 @@ static void output_pin_setting() static void input_pin_setting() { // Configure input GPIOs - gpio_num_t pins[] = { - s_config.pin_d7, - s_config.pin_d6, - s_config.pin_d5, - s_config.pin_d4, - s_config.pin_d3, - s_config.pin_d2, - s_config.pin_d1, - s_config.pin_d0, - s_config.pin_vsync - }; - gpio_config_t conf = { - .mode = GPIO_MODE_INPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE - }; - for (int i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) { + gpio_num_t pins[] = {s_config.pin_d7, s_config.pin_d6, s_config.pin_d5, s_config.pin_d4, s_config.pin_d3, + s_config.pin_d2, s_config.pin_d1, s_config.pin_d0, s_config.pin_vsync}; + gpio_config_t conf = {.mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE}; + for (int i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) + { conf.pin_bit_mask = 1LL << pins[i]; gpio_config(&conf); } - } static void get_frame(size_t line_width, int height) { - while (gpio_get_level(s_config.pin_vsync) == 0) {} - while (gpio_get_level(s_config.pin_vsync) != 0) {} - ESP_LOGD(TAG, "Got VSYNC, start writing new frame"); - gpio_set_level(s_config.pin_wrst, 0); // reset write point - gpio_set_level(s_config.pin_wen, 1); - gpio_set_level(s_config.pin_wen, 1); - gpio_set_level(s_config.pin_wrst, 1); - - while (gpio_get_level(s_config.pin_vsync) == 0) {} - while (gpio_get_level(s_config.pin_vsync) != 0) {} - ESP_LOGD(TAG, "Got VSYNC, start saving a frame"); - gpio_set_level(s_config.pin_wen, 0); // lock FIFO - gpio_set_level(s_config.pin_rrst, 0); // reset read point - gpio_set_level(s_config.pin_rclk, 0); - gpio_set_level(s_config.pin_rclk, 1); - gpio_set_level(s_config.pin_rrst, 1); - gpio_set_level(s_config.pin_wen, 0); // lock FIFO - gpio_set_level(s_config.pin_oe, 0); - - int i, j; - unsigned char dat = 0x0; - int len = line_width * height * 2; - for (i = 0; i < len; i++) { - gpio_set_level(s_config.pin_rclk, 0); - - dat |= (gpio_get_level(s_config.pin_d7) << 7); - dat |= (gpio_get_level(s_config.pin_d6) << 6); - dat |= (gpio_get_level(s_config.pin_d5) << 5); - dat |= (gpio_get_level(s_config.pin_d4) << 4); - dat |= (gpio_get_level(s_config.pin_d3) << 3); - dat |= (gpio_get_level(s_config.pin_d2) << 2); - dat |= (gpio_get_level(s_config.pin_d1) << 1); - dat |= gpio_get_level(s_config.pin_d0); - s_fb[i] = dat; - dat = 0x0; - - gpio_set_level(s_config.pin_rclk, 1); - } - gpio_set_level(s_config.pin_oe, 1); - ESP_LOGD(TAG, "Frame done"); - + while (gpio_get_level(s_config.pin_vsync) == 0) {} + while (gpio_get_level(s_config.pin_vsync) != 0) {} + ESP_LOGD(TAG, "Got VSYNC, start writing new frame"); + gpio_set_level(s_config.pin_wrst, 0); // reset write point + gpio_set_level(s_config.pin_wen, 1); + gpio_set_level(s_config.pin_wen, 1); + gpio_set_level(s_config.pin_wrst, 1); + + while (gpio_get_level(s_config.pin_vsync) == 0) {} + while (gpio_get_level(s_config.pin_vsync) != 0) {} + ESP_LOGD(TAG, "Got VSYNC, start saving a frame"); + gpio_set_level(s_config.pin_wen, 0); // lock FIFO + gpio_set_level(s_config.pin_rrst, 0); // reset read point + gpio_set_level(s_config.pin_rclk, 0); + gpio_set_level(s_config.pin_rclk, 1); + gpio_set_level(s_config.pin_rrst, 1); + gpio_set_level(s_config.pin_wen, 0); // lock FIFO + gpio_set_level(s_config.pin_oe, 0); + + int i, j; + unsigned char dat = 0x0; + int len = line_width * height * 2; + for (i = 0; i < len; i++) + { + gpio_set_level(s_config.pin_rclk, 0); + + dat |= (gpio_get_level(s_config.pin_d7) << 7); + dat |= (gpio_get_level(s_config.pin_d6) << 6); + dat |= (gpio_get_level(s_config.pin_d5) << 5); + dat |= (gpio_get_level(s_config.pin_d4) << 4); + dat |= (gpio_get_level(s_config.pin_d3) << 3); + dat |= (gpio_get_level(s_config.pin_d2) << 2); + dat |= (gpio_get_level(s_config.pin_d1) << 1); + dat |= gpio_get_level(s_config.pin_d0); + s_fb[i] = dat; + dat = 0x0; + + gpio_set_level(s_config.pin_rclk, 1); + } + gpio_set_level(s_config.pin_oe, 1); + ESP_LOGD(TAG, "Frame done"); } diff --git a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/ov7725.c b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/ov7725.c index 7e181aa..d115060 100644 --- a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/ov7725.c +++ b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/ov7725.c @@ -1,121 +1,123 @@ /* * This file is part of the OpenMV project. * Copyright (c) 2013/2014 Ibrahim Abdelkader - * This work is licensed under the MIT license, see the file LICENSE for details. + * This work is licensed under the MIT license, see the file LICENSE for + * details. * * OV7725 driver. * */ +#include "ov7725.h" + #include +#include #include #include -#include "sccb.h" -#include "ov7725.h" + #include "ov7725_regs.h" -#include +#include "sccb.h" static const uint8_t default_regs[][2] = { - {COM3, COM3_SWAP_YUV}, - {COM7, COM7_RES_QVGA | COM7_FMT_YUV}, + {COM3, COM3_SWAP_YUV}, + {COM7, COM7_RES_QVGA | COM7_FMT_YUV}, - {COM4, 0x01}, /* bypass PLL */ - {CLKRC, 0xC0}, /* Res/Bypass pre-scalar */ + {COM4, 0x01}, /* bypass PLL */ + {CLKRC, 0xC0}, /* Res/Bypass pre-scalar */ // QVGA Window Size - {HSTART, 0x3F}, - {HSIZE, 0x50}, - {VSTART, 0x03}, - {VSIZE, 0x78}, - {HREF, 0x00}, + {HSTART, 0x3F}, + {HSIZE, 0x50}, + {VSTART, 0x03}, + {VSIZE, 0x78}, + {HREF, 0x00}, // Scale down to QVGA Resolution - {HOUTSIZE, 0x50}, - {VOUTSIZE, 0x78}, - - {COM12, 0x03}, - {EXHCH, 0x00}, - {TGT_B, 0x7F}, - {FIXGAIN, 0x09}, - {AWB_CTRL0, 0xE0}, - {DSP_CTRL1, 0xFF}, - - {DSP_CTRL2, DSP_CTRL2_VDCW_EN | DSP_CTRL2_HDCW_EN | DSP_CTRL2_HZOOM_EN | DSP_CTRL2_VZOOM_EN}, - - {DSP_CTRL3, 0x00}, - {DSP_CTRL4, 0x00}, - {DSPAUTO, 0xFF}, - - {COM8, 0xF0}, - {COM6, 0xC5}, - {COM9, 0x11}, - {COM10, (1 << 1) | (1 << 5)}, - {BDBASE, 0x7F}, - {DBSTEP, 0x03}, - {AEW, 0x96}, - {AEB, 0x64}, - {VPT, 0xA1}, - {EXHCL, 0x00}, - {AWB_CTRL3, 0xAA}, - {COM8, 0xFF}, - - //Gamma - {GAM1, 0x0C}, - {GAM2, 0x16}, - {GAM3, 0x2A}, - {GAM4, 0x4E}, - {GAM5, 0x61}, - {GAM6, 0x6F}, - {GAM7, 0x7B}, - {GAM8, 0x86}, - {GAM9, 0x8E}, - {GAM10, 0x97}, - {GAM11, 0xA4}, - {GAM12, 0xAF}, - {GAM13, 0xC5}, - {GAM14, 0xD7}, - {GAM15, 0xE8}, - - {SLOP, 0x20}, - {EDGE1, 0x05}, - {EDGE2, 0x03}, - {EDGE3, 0x00}, - {DNSOFF, 0x01}, - - {MTX1, 0xB0}, - {MTX2, 0x9D}, - {MTX3, 0x13}, - {MTX4, 0x16}, - {MTX5, 0x7B}, - {MTX6, 0x91}, - {MTX_CTRL, 0x1E}, - - {BRIGHTNESS, 0x08}, - {CONTRAST, 0x30}, - {UVADJ0, 0x81}, - {SDE, (SDE_CONT_BRIGHT_EN | SDE_SATURATION_EN)}, + {HOUTSIZE, 0x50}, + {VOUTSIZE, 0x78}, + + {COM12, 0x03}, + {EXHCH, 0x00}, + {TGT_B, 0x7F}, + {FIXGAIN, 0x09}, + {AWB_CTRL0, 0xE0}, + {DSP_CTRL1, 0xFF}, + + {DSP_CTRL2, DSP_CTRL2_VDCW_EN | DSP_CTRL2_HDCW_EN | DSP_CTRL2_HZOOM_EN | DSP_CTRL2_VZOOM_EN}, + + {DSP_CTRL3, 0x00}, + {DSP_CTRL4, 0x00}, + {DSPAUTO, 0xFF}, + + {COM8, 0xF0}, + {COM6, 0xC5}, + {COM9, 0x11}, + {COM10, (1 << 1) | (1 << 5)}, + {BDBASE, 0x7F}, + {DBSTEP, 0x03}, + {AEW, 0x96}, + {AEB, 0x64}, + {VPT, 0xA1}, + {EXHCL, 0x00}, + {AWB_CTRL3, 0xAA}, + {COM8, 0xFF}, + + // Gamma + {GAM1, 0x0C}, + {GAM2, 0x16}, + {GAM3, 0x2A}, + {GAM4, 0x4E}, + {GAM5, 0x61}, + {GAM6, 0x6F}, + {GAM7, 0x7B}, + {GAM8, 0x86}, + {GAM9, 0x8E}, + {GAM10, 0x97}, + {GAM11, 0xA4}, + {GAM12, 0xAF}, + {GAM13, 0xC5}, + {GAM14, 0xD7}, + {GAM15, 0xE8}, + + {SLOP, 0x20}, + {EDGE1, 0x05}, + {EDGE2, 0x03}, + {EDGE3, 0x00}, + {DNSOFF, 0x01}, + + {MTX1, 0xB0}, + {MTX2, 0x9D}, + {MTX3, 0x13}, + {MTX4, 0x16}, + {MTX5, 0x7B}, + {MTX6, 0x91}, + {MTX_CTRL, 0x1E}, + + {BRIGHTNESS, 0x08}, + {CONTRAST, 0x30}, + {UVADJ0, 0x81}, + {SDE, (SDE_CONT_BRIGHT_EN | SDE_SATURATION_EN)}, // For 30 fps/60Hz - {DM_LNL, 0x00}, - {DM_LNH, 0x00}, - {BDBASE, 0x7F}, - {DBSTEP, 0x03}, + {DM_LNL, 0x00}, + {DM_LNH, 0x00}, + {BDBASE, 0x7F}, + {DBSTEP, 0x03}, // Lens Correction, should be tuned with real camera module - {LC_RADI, 0x10}, - {LC_COEF, 0x10}, - {LC_COEFB, 0x14}, - {LC_COEFR, 0x17}, - {LC_CTR, 0x05}, - {COM5, 0xF5}, //0x65 - - {0x00, 0x00}, + {LC_RADI, 0x10}, + {LC_COEF, 0x10}, + {LC_COEFB, 0x14}, + {LC_COEFR, 0x17}, + {LC_CTR, 0x05}, + {COM5, 0xF5}, // 0x65 + + {0x00, 0x00}, }; - static int reset(sensor_t *sensor) { - int i=0; - const uint8_t (*regs)[2]; + int i = 0; + const uint8_t(*regs)[2]; // Reset all registers SCCB_Write(sensor->slv_addr, COM7, COM7_RESET); @@ -124,9 +126,7 @@ static int reset(sensor_t *sensor) systick_sleep(10); // Write default regsiters - for (i=0, regs = default_regs; regs[i][0]; i++) { - SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]); - } + for (i = 0, regs = default_regs; regs[i][0]; i++) { SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]); } // Delay systick_sleep(30); @@ -134,20 +134,20 @@ static int reset(sensor_t *sensor) return 0; } - static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) { - int ret=0; + int ret = 0; // Read register COM7 uint8_t reg = SCCB_Read(sensor->slv_addr, COM7); - switch (pixformat) { + switch (pixformat) + { case PIXFORMAT_RGB565: - reg = COM7_SET_FMT(reg, COM7_FMT_RGB); + reg = COM7_SET_FMT(reg, COM7_FMT_RGB); break; case PIXFORMAT_YUV422: case PIXFORMAT_GRAYSCALE: - reg = COM7_SET_FMT(reg, COM7_FMT_YUV); + reg = COM7_SET_FMT(reg, COM7_FMT_YUV); break; default: return -1; @@ -164,21 +164,24 @@ static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) static int set_framesize(sensor_t *sensor, framesize_t framesize) { - int ret=0; + int ret = 0; uint16_t w = resolution[framesize][0]; uint16_t h = resolution[framesize][1]; // Write MSBs - ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2); - ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1); + ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w >> 2); + ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h >> 1); // Write LSBs - ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2))); + ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w & 0x3) | ((h & 0x1) << 2))); - if (framesize < FRAMESIZE_VGA) { + if (framesize < FRAMESIZE_VGA) + { // Enable auto-scaling/zooming factors ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xFF); - } else { + } + else + { // Disable auto-scaling/zooming factors ret |= SCCB_Write(sensor->slv_addr, DSPAUTO, 0xF3); @@ -191,7 +194,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) // Delay systick_sleep(30); - if (ret == 0) { + if (ret == 0) + { sensor->framesize = framesize; } @@ -200,7 +204,7 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) static int set_colorbar(sensor_t *sensor, int enable) { - int ret=0; + int ret = 0; uint8_t reg; // Read reg COM3 diff --git a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.c b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.c index a606e46..fedb247 100644 --- a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.c +++ b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/sccb.c @@ -1,21 +1,24 @@ /* * This file is part of the OpenMV project. * Copyright (c) 2013/2014 Ibrahim Abdelkader - * This work is licensed under the MIT license, see the file LICENSE for details. + * This work is licensed under the MIT license, see the file LICENSE for + * details. * * SCCB (I2C like) driver. * */ -#include -#include "wiring.h" #include "sccb.h" -#include "twi.h" + +#include #include -#define SCCB_FREQ (100000) // We don't need fast I2C. 100KHz is fine here. -#define TIMEOUT (1000) /* Can't be sure when I2C routines return. Interrupts -while polling hardware may result in unknown delays. */ +#include "twi.h" +#include "wiring.h" +#define SCCB_FREQ (100000) // We don't need fast I2C. 100KHz is fine here. +#define TIMEOUT \ + (1000) /* Can't be sure when I2C routines return. Interrupts \ +while polling hardware may result in unknown delays. */ int SCCB_Init(int pin_sda, int pin_scl) { @@ -28,14 +31,17 @@ uint8_t SCCB_Probe() uint8_t reg = 0x00; uint8_t slv_addr = 0x00; - for (uint8_t i=0; i<127; i++) { - if (twi_writeTo(i, ®, 1, true) == 0) { + for (uint8_t i = 0; i < 127; i++) + { + if (twi_writeTo(i, ®, 1, true) == 0) + { slv_addr = i; break; } - if (i!=126) { - systick_sleep(1); // Necessary for OV7725 camera (not for OV2640). + if (i != 126) + { + systick_sleep(1); // Necessary for OV7725 camera (not for OV2640). } } return slv_addr; @@ -43,21 +49,25 @@ uint8_t SCCB_Probe() uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg) { - uint8_t data=0; + uint8_t data = 0; __disable_irq(); int rc = twi_writeTo(slv_addr, ®, 1, true); - if (rc != 0) { + if (rc != 0) + { data = 0xff; } - else { + else + { rc = twi_readFrom(slv_addr, &data, 1, true); - if (rc != 0) { - data=0xFF; + if (rc != 0) + { + data = 0xFF; } } __enable_irq(); - if (rc != 0) { + if (rc != 0) + { printf("SCCB_Read [%02x] failed rc=%d\n", reg, rc); } return data; @@ -65,15 +75,17 @@ uint8_t SCCB_Read(uint8_t slv_addr, uint8_t reg) uint8_t SCCB_Write(uint8_t slv_addr, uint8_t reg, uint8_t data) { - uint8_t ret=0; + uint8_t ret = 0; uint8_t buf[] = {reg, data}; __disable_irq(); - if(twi_writeTo(slv_addr, buf, 2, true) != 0) { - ret=0xFF; + if (twi_writeTo(slv_addr, buf, 2, true) != 0) + { + ret = 0xFF; } __enable_irq(); - if (ret != 0) { + if (ret != 0) + { printf("SCCB_Write [%02x]=%02x failed\n", reg, data); } return ret; diff --git a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/twi.c b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/twi.c index 133177c..88dafac 100644 --- a/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/twi.c +++ b/LuaNode_Esp32/LuaNode32/examples/camera/components/camera/twi.c @@ -18,75 +18,93 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include #include "twi.h" + +#include +#include +#include + #include "soc/gpio_reg.h" #include "wiring.h" -#include unsigned char twi_dcount = 18; static unsigned char twi_sda, twi_scl; - -static inline void SDA_LOW() { - //Enable SDA (becomes output and since GPO is 0 for the pin, - // it will pull the line low) - if (twi_sda < 32) { - REG_WRITE(GPIO_ENABLE_W1TS_REG, BIT(twi_sda)); - } - else { - REG_WRITE(GPIO_ENABLE1_W1TS_REG, BIT(twi_sda - 32)); - } +static inline void SDA_LOW() +{ + // Enable SDA (becomes output and since GPO is 0 for the pin, + // it will pull the line low) + if (twi_sda < 32) + { + REG_WRITE(GPIO_ENABLE_W1TS_REG, BIT(twi_sda)); + } + else + { + REG_WRITE(GPIO_ENABLE1_W1TS_REG, BIT(twi_sda - 32)); + } } -static inline void SDA_HIGH() { - //Disable SDA (becomes input and since it has pullup it will go high) - if (twi_sda < 32) { - REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(twi_sda)); - } - else { - REG_WRITE(GPIO_ENABLE1_W1TC_REG, BIT(twi_sda - 32)); - } +static inline void SDA_HIGH() +{ + // Disable SDA (becomes input and since it has pullup it will go high) + if (twi_sda < 32) + { + REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(twi_sda)); + } + else + { + REG_WRITE(GPIO_ENABLE1_W1TC_REG, BIT(twi_sda - 32)); + } } -static inline uint32_t SDA_READ() { - if (twi_sda < 32) { - return (REG_READ(GPIO_IN_REG) & BIT(twi_sda)) != 0; - } - else { - return (REG_READ(GPIO_IN1_REG) & BIT(twi_sda - 32)) != 0; - } +static inline uint32_t SDA_READ() +{ + if (twi_sda < 32) + { + return (REG_READ(GPIO_IN_REG) & BIT(twi_sda)) != 0; + } + else + { + return (REG_READ(GPIO_IN1_REG) & BIT(twi_sda - 32)) != 0; + } } -static void SCL_LOW() { - if (twi_scl < 32) { - REG_WRITE(GPIO_ENABLE_W1TS_REG, BIT(twi_scl)); - } - else { - REG_WRITE(GPIO_ENABLE1_W1TS_REG, BIT(twi_scl - 32)); - } +static void SCL_LOW() +{ + if (twi_scl < 32) + { + REG_WRITE(GPIO_ENABLE_W1TS_REG, BIT(twi_scl)); + } + else + { + REG_WRITE(GPIO_ENABLE1_W1TS_REG, BIT(twi_scl - 32)); + } } -static void SCL_HIGH() { - if (twi_scl < 32) { - REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(twi_scl)); - } - else { - REG_WRITE(GPIO_ENABLE1_W1TC_REG, BIT(twi_scl - 32)); - } +static void SCL_HIGH() +{ + if (twi_scl < 32) + { + REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(twi_scl)); + } + else + { + REG_WRITE(GPIO_ENABLE1_W1TC_REG, BIT(twi_scl - 32)); + } } -static uint32_t SCL_READ() { - if (twi_scl < 32) { - return (REG_READ(GPIO_IN_REG) & BIT(twi_scl)) != 0; - } - else { - return (REG_READ(GPIO_IN1_REG) & BIT(twi_scl - 32)) != 0; - } +static uint32_t SCL_READ() +{ + if (twi_scl < 32) + { + return (REG_READ(GPIO_IN_REG) & BIT(twi_scl)) != 0; + } + else + { + return (REG_READ(GPIO_IN1_REG) & BIT(twi_scl - 32)) != 0; + } } - #ifndef FCPU80 #define FCPU80 80000000L #endif @@ -97,167 +115,221 @@ static uint32_t SCL_READ() { #define TWI_CLOCK_STRETCH 1600 #endif -void twi_setClock(unsigned int freq){ +void twi_setClock(unsigned int freq) +{ #if F_CPU == FCPU80 - if(freq <= 100000) twi_dcount = 19;//about 100KHz - else if(freq <= 200000) twi_dcount = 8;//about 200KHz - else if(freq <= 300000) twi_dcount = 3;//about 300KHz - else if(freq <= 400000) twi_dcount = 1;//about 400KHz - else twi_dcount = 1;//about 400KHz + if (freq <= 100000) + twi_dcount = 19; // about 100KHz + else if (freq <= 200000) + twi_dcount = 8; // about 200KHz + else if (freq <= 300000) + twi_dcount = 3; // about 300KHz + else if (freq <= 400000) + twi_dcount = 1; // about 400KHz + else + twi_dcount = 1; // about 400KHz #else - if(freq <= 100000) twi_dcount = 32;//about 100KHz - else if(freq <= 200000) twi_dcount = 14;//about 200KHz - else if(freq <= 300000) twi_dcount = 8;//about 300KHz - else if(freq <= 400000) twi_dcount = 5;//about 400KHz - else if(freq <= 500000) twi_dcount = 3;//about 500KHz - else if(freq <= 600000) twi_dcount = 2;//about 600KHz - else twi_dcount = 1;//about 700KHz + if (freq <= 100000) + twi_dcount = 32; // about 100KHz + else if (freq <= 200000) + twi_dcount = 14; // about 200KHz + else if (freq <= 300000) + twi_dcount = 8; // about 300KHz + else if (freq <= 400000) + twi_dcount = 5; // about 400KHz + else if (freq <= 500000) + twi_dcount = 3; // about 500KHz + else if (freq <= 600000) + twi_dcount = 2; // about 600KHz + else + twi_dcount = 1; // about 700KHz #endif } -void twi_init(unsigned char sda, unsigned char scl){ - twi_sda = sda; - twi_scl = scl; - pinMode(twi_sda, OUTPUT); - pinMode(twi_scl, OUTPUT); +void twi_init(unsigned char sda, unsigned char scl) +{ + twi_sda = sda; + twi_scl = scl; + pinMode(twi_sda, OUTPUT); + pinMode(twi_scl, OUTPUT); - digitalWrite(twi_sda, 0); - digitalWrite(twi_scl, 0); + digitalWrite(twi_sda, 0); + digitalWrite(twi_scl, 0); - pinMode(twi_sda, INPUT_PULLUP); - pinMode(twi_scl, INPUT_PULLUP); - twi_setClock(100000); + pinMode(twi_sda, INPUT_PULLUP); + pinMode(twi_scl, INPUT_PULLUP); + twi_setClock(100000); } -void twi_stop(void){ - pinMode(twi_sda, INPUT); - pinMode(twi_scl, INPUT); +void twi_stop(void) +{ + pinMode(twi_sda, INPUT); + pinMode(twi_scl, INPUT); } -static void twi_delay(unsigned char v){ - unsigned int i; +static void twi_delay(unsigned char v) +{ + unsigned int i; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-but-set-variable" - unsigned int reg; - for(i=0;i #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" - +#include "camera.h" #include "driver/gpio.h" - #include "esp_err.h" #include "esp_log.h" -#include "camera.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" static const char* TAG = "camera_demo"; - void app_main() { - camera_config_t config = { - .ledc_channel = LEDC_CHANNEL_0, - .ledc_timer = LEDC_TIMER_0, - .pin_d0 = 4, - .pin_d1 = 5, - .pin_d2 = 18, - .pin_d3 = 19, - .pin_d4 = 36, - .pin_d5 = 39, - .pin_d6 = 34, - .pin_d7 = 35, - .pin_rclk = 21, - .pin_vsync = 25, - .pin_sscb_sda = 26, - .pin_sscb_scl = 27, - .pin_rrst = 2, - .pin_wrst = 22, - .pin_wen = 23, - .pin_oe = 12 - }; + camera_config_t config = {.ledc_channel = LEDC_CHANNEL_0, + .ledc_timer = LEDC_TIMER_0, + .pin_d0 = 4, + .pin_d1 = 5, + .pin_d2 = 18, + .pin_d3 = 19, + .pin_d4 = 36, + .pin_d5 = 39, + .pin_d6 = 34, + .pin_d7 = 35, + .pin_rclk = 21, + .pin_vsync = 25, + .pin_sscb_sda = 26, + .pin_sscb_scl = 27, + .pin_rrst = 2, + .pin_wrst = 22, + .pin_wen = 23, + .pin_oe = 12}; - esp_err_t err = camera_init(&config); - if (err != ESP_OK) { + esp_err_t err = camera_init(&config); + if (err != ESP_OK) + { ESP_LOGE(TAG, "Camera init failed with error = %d", err); return; } - while(true){ + while (true) + { err = camera_run(); - if (err != ESP_OK){ - ESP_LOGD(TAG, "Camera capture failed with error = %d", err); - } else { - ESP_LOGD(TAG, "Done"); - camera_print_fb(); + if (err != ESP_OK) + { + ESP_LOGD(TAG, "Camera capture failed with error = %d", err); + } + else + { + ESP_LOGD(TAG, "Done"); + camera_print_fb(); } vTaskDelay(1000 / portTICK_RATE_MS); } } - diff --git a/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c b/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c index 5dffb77..48cc347 100644 --- a/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/dns_resolver/app_main.c @@ -1,251 +1,260 @@ #include -#include "lwip/sockets.h" -#include "lwip/err.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" - -#include "platform.h" -#include "tmr.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "esp_system.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "lwip/err.h" +#include "lwip/sockets.h" #include "nvs_flash.h" +#include "platform.h" #include "tcpip_adapter.h" +#include "tmr.h" + +#define UDP_DNS_PORT 53 +#define UDP_DATA_LEN 1024 +#define UDP_LOCAL_PORT 7 +#define SSID_AP "DOIT" +#define DNS_SERVER_TASK_PRIO 12 +#define TMP_TASK_PRIO 13 + +#define DNS_QR_QUERY 0 +#define DNS_QR_RESPONSE 1 +#define DNS_OPCODE_QUERY 0 -#define UDP_DNS_PORT 53 -#define UDP_DATA_LEN 1024 -#define UDP_LOCAL_PORT 7 -#define SSID_AP "DOIT" -#define DNS_SERVER_TASK_PRIO 12 -#define TMP_TASK_PRIO 13 - -#define DNS_QR_QUERY 0 -#define DNS_QR_RESPONSE 1 -#define DNS_OPCODE_QUERY 0 - -struct DNSHeader { - unsigned short ID; // identification number - unsigned char RD : 1; // recursion desired - unsigned char TC : 1; // truncated message - unsigned char AA : 1; // authoritive answer - unsigned char OPCode : 4; // message_type - unsigned char QR : 1; // query/response flag - unsigned char RCode : 4; // response code - unsigned char Z : 3; // its z! reserved - unsigned char RA : 1; // recursion available - unsigned short QDCount; // number of question entries - unsigned short ANCount; // number of answer entries - unsigned short NSCount; // number of authority entries - unsigned short ARCount; // number of resource entries +struct DNSHeader +{ + unsigned short ID; // identification number + unsigned char RD : 1; // recursion desired + unsigned char TC : 1; // truncated message + unsigned char AA : 1; // authoritive answer + unsigned char OPCode : 4; // message_type + unsigned char QR : 1; // query/response flag + unsigned char RCode : 4; // response code + unsigned char Z : 3; // its z! reserved + unsigned char RA : 1; // recursion available + unsigned short QDCount; // number of question entries + unsigned short ANCount; // number of answer entries + unsigned short NSCount; // number of authority entries + unsigned short ARCount; // number of resource entries }; static EventGroupHandle_t wifi_event_group; const int CONNECTED_BIT = BIT0; static const char *TAG = "main"; - -void led_blink(void) +void led_blink(void) { - if(platform_gpio_mode(2, 2) < 0) { - ESP_LOGI(TAG, "Led lightup failed"); - return; - } - platform_gpio_write(2, 1); // led on - tmr_delay_msec(250); - platform_gpio_write(2, 0); // led off - tmr_delay_msec(250); - platform_gpio_write(2, 1); - tmr_delay_msec(250); - platform_gpio_write(2, 0); - tmr_delay_msec(250); - platform_gpio_write(2, 1); + if (platform_gpio_mode(2, 2) < 0) + { + ESP_LOGI(TAG, "Led lightup failed"); + return; + } + platform_gpio_write(2, 1); // led on + tmr_delay_msec(250); + platform_gpio_write(2, 0); // led off + tmr_delay_msec(250); + platform_gpio_write(2, 1); + tmr_delay_msec(250); + platform_gpio_write(2, 0); + tmr_delay_msec(250); + platform_gpio_write(2, 1); } static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_AP_START: - ESP_LOGI(TAG, "AP start now"); - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STOP: - ESP_LOGI(TAG, "AP stop now"); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "Station connect"); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "Station disconnect"); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_AP_START: + ESP_LOGI(TAG, "AP start now"); + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_AP_STOP: + ESP_LOGI(TAG, "AP stop now"); + break; + case SYSTEM_EVENT_AP_STACONNECTED: + ESP_LOGI(TAG, "Station connect"); + break; + case SYSTEM_EVENT_AP_STADISCONNECTED: + ESP_LOGI(TAG, "Station disconnect"); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t config = { - .ap = { - .ssid = SSID_AP, - .ssid_len = strlen(SSID_AP), - .authmode = WIFI_AUTH_OPEN, - .max_connection = 10, - //.ssid_hidden = 0, - //.beacon_interval = 100, - }, - }; - - // set SSID - uint8_t mac[6]; - esp_wifi_get_mac(WIFI_IF_AP, mac); - sprintf(config.ap.ssid, SSID_AP "_%02X%02X%02X", mac[3], mac[4], mac[5]); - config.ap.ssid_len = strlen(config.ap.ssid); - - tcpip_adapter_init(); + wifi_config_t config = { + .ap = + { + .ssid = SSID_AP, .ssid_len = strlen(SSID_AP), .authmode = WIFI_AUTH_OPEN, .max_connection = 10, + //.ssid_hidden = 0, + //.beacon_interval = 100, + }, + }; + + // set SSID + uint8_t mac[6]; + esp_wifi_get_mac(WIFI_IF_AP, mac); + sprintf(config.ap.ssid, SSID_AP "_%02X%02X%02X", mac[3], mac[4], mac[5]); + config.ap.ssid_len = strlen(config.ap.ssid); + + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static bool req_includes_only_one_quest(struct DNSHeader *h) { - return (ntohs(h->QDCount) == 1 && h->ANCount == 0 && h->NSCount == 0 && h->ARCount == 0); + return (ntohs(h->QDCount) == 1 && h->ANCount == 0 && h->NSCount == 0 && h->ARCount == 0); } static void reply_with_ip(int32 sock_fd, struct DNSHeader *h, uint32_t len, struct sockaddr *toaddr, socklen_t tolen) { - h->QR = DNS_QR_RESPONSE; - h->ANCount = h->QDCount; - uint32_t length = len + 16; - - uint8_t *pkg_buf = (uint8_t *)malloc(length); - if (pkg_buf == NULL) { - ESP_LOGI(TAG, "UDP packet alloc failed!\n"); - return; - } - memset(pkg_buf, 0, length); - memcpy(pkg_buf, (void *)h, len); - - pkg_buf[len] = 192; // answer name is a pointer - pkg_buf[len+1] = 12; // pointer to offset at 0x00c - pkg_buf[len+2] = 0; // 0x0001 answer is type A query (host address) - pkg_buf[len+3] = 1; - pkg_buf[len+4] = 0; //0x0001 answer is class IN (internet address) - pkg_buf[len+5] = 1; - - // write ttl - uint32_t _ttl = htonl(60); - uint8_t *pttl = (uint8_t *)(&_ttl); - pkg_buf[len+6] = pttl[0]; - pkg_buf[len+7] = pttl[1]; - pkg_buf[len+8] = pttl[2]; - pkg_buf[len+9] = pttl[3]; - pkg_buf[len+10] = 0; - pkg_buf[len+11] = 4; - - // ip - pkg_buf[len+12] = 192; - pkg_buf[len+13] = 168; - pkg_buf[len+14] = 4; - pkg_buf[len+15] = 1; - - uint32_t ret = sendto(sock_fd, pkg_buf, length, 0, toaddr, tolen); - free(pkg_buf); + h->QR = DNS_QR_RESPONSE; + h->ANCount = h->QDCount; + uint32_t length = len + 16; + + uint8_t *pkg_buf = (uint8_t *)malloc(length); + if (pkg_buf == NULL) + { + ESP_LOGI(TAG, "UDP packet alloc failed!\n"); + return; + } + memset(pkg_buf, 0, length); + memcpy(pkg_buf, (void *)h, len); + + pkg_buf[len] = 192; // answer name is a pointer + pkg_buf[len + 1] = 12; // pointer to offset at 0x00c + pkg_buf[len + 2] = 0; // 0x0001 answer is type A query (host address) + pkg_buf[len + 3] = 1; + pkg_buf[len + 4] = 0; // 0x0001 answer is class IN (internet address) + pkg_buf[len + 5] = 1; + + // write ttl + uint32_t _ttl = htonl(60); + uint8_t *pttl = (uint8_t *)(&_ttl); + pkg_buf[len + 6] = pttl[0]; + pkg_buf[len + 7] = pttl[1]; + pkg_buf[len + 8] = pttl[2]; + pkg_buf[len + 9] = pttl[3]; + pkg_buf[len + 10] = 0; + pkg_buf[len + 11] = 4; + + // ip + pkg_buf[len + 12] = 192; + pkg_buf[len + 13] = 168; + pkg_buf[len + 14] = 4; + pkg_buf[len + 15] = 1; + + uint32_t ret = sendto(sock_fd, pkg_buf, length, 0, toaddr, tolen); + free(pkg_buf); } -static void reply_with_custom_code(struct DNSHeader *h) -{ - ESP_LOGI(TAG, "reply_with_custom_code"); -} +static void reply_with_custom_code(struct DNSHeader *h) { ESP_LOGI(TAG, "reply_with_custom_code"); } static void dns_server_task(void *pvParameters) { - int32 sock_fd; - int ret = 0; - struct sockaddr_in server_addr; - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_port = htons(UDP_DNS_PORT); - server_addr.sin_len = sizeof(server_addr); - - while ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - ESP_LOGI(TAG, "create socket failed"); - tmr_delay_msec(1000); - } - - while (bind(sock_fd, (struct sockaddr * )&server_addr, sizeof(server_addr)) != 0) { - ESP_LOGI(TAG, "socket bind failed"); - tmr_delay_msec(1000); - } - - char *udp_msg = (char *) malloc(UDP_DATA_LEN); - struct sockaddr_in from; - int fromlen = 0; - int nNetTimeout = 5; - memset(udp_msg, 0, UDP_DATA_LEN); - memset(&from, 0, sizeof(from)); - setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, sizeof(int)); //non-block - fromlen = sizeof(struct sockaddr_in); - - ESP_LOGI(TAG, "udp server at port:%d\r\n", UDP_DNS_PORT); - while (1) { - ret = recvfrom(sock_fd, (uint8 * )udp_msg, UDP_DATA_LEN, 0, (struct sockaddr * )&from, (socklen_t * )&fromlen); - if (ret > 0) { - struct DNSHeader *dns_header = (struct DNSHeader *)udp_msg; - - if (dns_header->QR == DNS_QR_QUERY && dns_header->OPCode == DNS_OPCODE_QUERY && req_includes_only_one_quest(dns_header)) { - reply_with_ip(sock_fd, dns_header, ret, (struct sockaddr *)&from, fromlen); - } else if (dns_header->QR == DNS_QR_QUERY) { - reply_with_custom_code(dns_header); - } - - memset(udp_msg, 0, UDP_DATA_LEN); - } else if (ret == 0) { - ESP_LOGI(TAG, "recvfrom error!"); - break; - } - } - - if (udp_msg) { - free(udp_msg); - udp_msg = NULL; - } - - close(sock_fd); - vTaskDelete(NULL); + int32 sock_fd; + int ret = 0; + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(UDP_DNS_PORT); + server_addr.sin_len = sizeof(server_addr); + + while ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + { + ESP_LOGI(TAG, "create socket failed"); + tmr_delay_msec(1000); + } + + while (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) + { + ESP_LOGI(TAG, "socket bind failed"); + tmr_delay_msec(1000); + } + + char *udp_msg = (char *)malloc(UDP_DATA_LEN); + struct sockaddr_in from; + int fromlen = 0; + int nNetTimeout = 5; + memset(udp_msg, 0, UDP_DATA_LEN); + memset(&from, 0, sizeof(from)); + setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&nNetTimeout, + sizeof(int)); // non-block + fromlen = sizeof(struct sockaddr_in); + + ESP_LOGI(TAG, "udp server at port:%d\r\n", UDP_DNS_PORT); + while (1) + { + ret = recvfrom(sock_fd, (uint8 *)udp_msg, UDP_DATA_LEN, 0, (struct sockaddr *)&from, (socklen_t *)&fromlen); + if (ret > 0) + { + struct DNSHeader *dns_header = (struct DNSHeader *)udp_msg; + + if (dns_header->QR == DNS_QR_QUERY && dns_header->OPCode == DNS_OPCODE_QUERY && + req_includes_only_one_quest(dns_header)) + { + reply_with_ip(sock_fd, dns_header, ret, (struct sockaddr *)&from, fromlen); + } + else if (dns_header->QR == DNS_QR_QUERY) + { + reply_with_custom_code(dns_header); + } + + memset(udp_msg, 0, UDP_DATA_LEN); + } + else if (ret == 0) + { + ESP_LOGI(TAG, "recvfrom error!"); + break; + } + } + + if (udp_msg) + { + free(udp_msg); + udp_msg = NULL; + } + + close(sock_fd); + vTaskDelete(NULL); } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "AP started"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - xTaskCreate(dns_server_task, "dns_server_task", 2048, NULL, DNS_SERVER_TASK_PRIO, NULL); - break; - } - vTaskDelete(NULL); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + ESP_LOGI(TAG, "AP started"); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + xTaskCreate(dns_server_task, "dns_server_task", 2048, NULL, DNS_SERVER_TASK_PRIO, NULL); + break; + } + vTaskDelete(NULL); } void app_main() { - led_blink(); // led flashing - nvs_flash_init(); + led_blink(); // led flashing + nvs_flash_init(); initialise_wifi(); - xTaskCreate(tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIO, NULL); + xTaskCreate(tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIO, NULL); - return 0; + return 0; } diff --git a/LuaNode_Esp32/LuaNode32/examples/ds1307/components/bsp/ds1307.c b/LuaNode_Esp32/LuaNode32/examples/ds1307/components/bsp/ds1307.c index b8b3aee..abc43f2 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ds1307/components/bsp/ds1307.c +++ b/LuaNode_Esp32/LuaNode32/examples/ds1307/components/bsp/ds1307.c @@ -1,54 +1,52 @@ #include "ds1307.h" + #include #include #include #include #include -#include #include +#include #include #include #include "sdkconfig.h" -#define tag "ds1307" +#define tag "ds1307" extern EventGroupHandle_t station_event_group; extern const int STA_GOTIP_BIT; -static uint8_t intToBCD(uint8_t num) -{ - return ((num / 10) << 4) | (num%10); -} +static uint8_t intToBCD(uint8_t num) { return ((num / 10) << 4) | (num % 10); } -static uint8_t bcdToInt(uint8_t bcd) +static uint8_t bcdToInt(uint8_t bcd) { - // 0x10 - return ((bcd >> 4) * 10) + (bcd & 0x0f);; + // 0x10 + return ((bcd >> 4) * 10) + (bcd & 0x0f); + ; } -static void startSNTP() +static void startSNTP() { - //ip_addr_t addr; - sntp_setoperatingmode(SNTP_OPMODE_POLL); - //inet_pton(AF_INET, "129.6.15.28", &addr); - //sntp_setserver(0, &addr); - sntp_setservername(0, "pool.ntp.org"); - sntp_init(); + // ip_addr_t addr; + sntp_setoperatingmode(SNTP_OPMODE_POLL); + // inet_pton(AF_INET, "129.6.15.28", &addr); + // sntp_setserver(0, &addr); + sntp_setservername(0, "pool.ntp.org"); + sntp_init(); } - -static void initI2C() +static void initI2C() { - i2c_config_t conf; - conf.mode = I2C_MODE_MASTER; - conf.sda_io_num = SDA_PIN; - conf.scl_io_num = SCL_PIN; - conf.sda_pullup_en = GPIO_PULLUP_ENABLE; - conf.scl_pullup_en = GPIO_PULLUP_ENABLE; - conf.master.clk_speed = 100000; - ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_1, &conf)); - ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0)); + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = SDA_PIN; + conf.scl_io_num = SCL_PIN; + conf.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf.master.clk_speed = 100000; + ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_1, &conf)); + ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0)); } /* @@ -62,97 +60,100 @@ static void initI2C() * 6 - Year - 00-99 * */ -time_t readValue() +time_t readValue() { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - ESP_ERROR_CHECK(i2c_master_start(cmd)); - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (DS1307_ADDRESS << 1) | I2C_MASTER_WRITE, 1 /* expect ack */)); - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x0, 1)); - ESP_ERROR_CHECK(i2c_master_start(cmd)); - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (DS1307_ADDRESS << 1) | I2C_MASTER_READ, 1 /* expect ack */)); - uint8_t data[7]; - ESP_ERROR_CHECK(i2c_master_read(cmd, data, 7, 0)); - ESP_ERROR_CHECK(i2c_master_stop(cmd)); - ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000/portTICK_PERIOD_MS)); - i2c_cmd_link_delete(cmd); - - int i; - for (i=0; i<7; i++) { - ESP_LOGD(tag, "%d: 0x%.2x", i, data[i]); - } - - struct tm tm; - tm.tm_sec = bcdToInt(data[0]); - tm.tm_min = bcdToInt(data[1]); - tm.tm_hour = bcdToInt(data[2]); - tm.tm_mday = bcdToInt(data[4]); - tm.tm_mon = bcdToInt(data[5]) - 1; // 0-11 - Note: The month on the DS1307 is 1-12. - tm.tm_year = bcdToInt(data[6]) + 100; // Years since 1900 - time_t readTime = mktime(&tm); - ESP_LOGI(tag, "time: %d.%d.%d, %d:%d:%d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - return readTime; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + ESP_ERROR_CHECK(i2c_master_start(cmd)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (DS1307_ADDRESS << 1) | I2C_MASTER_WRITE, 1 /* expect ack */)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x0, 1)); + ESP_ERROR_CHECK(i2c_master_start(cmd)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (DS1307_ADDRESS << 1) | I2C_MASTER_READ, 1 /* expect ack */)); + uint8_t data[7]; + ESP_ERROR_CHECK(i2c_master_read(cmd, data, 7, 0)); + ESP_ERROR_CHECK(i2c_master_stop(cmd)); + ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_PERIOD_MS)); + i2c_cmd_link_delete(cmd); + + int i; + for (i = 0; i < 7; i++) { ESP_LOGD(tag, "%d: 0x%.2x", i, data[i]); } + + struct tm tm; + tm.tm_sec = bcdToInt(data[0]); + tm.tm_min = bcdToInt(data[1]); + tm.tm_hour = bcdToInt(data[2]); + tm.tm_mday = bcdToInt(data[4]); + tm.tm_mon = bcdToInt(data[5]) - 1; // 0-11 - Note: The month on the DS1307 is 1-12. + tm.tm_year = bcdToInt(data[6]) + 100; // Years since 1900 + time_t readTime = mktime(&tm); + ESP_LOGI(tag, "time: %d.%d.%d, %d:%d:%d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, + tm.tm_sec); + return readTime; } -void writeValue(time_t newTime) +void writeValue(time_t newTime) { - ESP_LOGI(tag, ">> writeValue: %ld", newTime); - struct tm tm; - gmtime_r(&newTime, &tm); - char buf[30]; - ESP_LOGI(tag, " - %s", asctime_r(&tm, buf)); - - esp_err_t errRc; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - ESP_ERROR_CHECK(i2c_master_start(cmd)); - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (DS1307_ADDRESS << 1) | I2C_MASTER_WRITE, 1 /* expect ack */)); - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x0, 1)); - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_sec), 1)); // seconds - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_min), 1 )); // minutes - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_hour), 1 )); // hours - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_wday+1), 1 )); // week day - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_mday), 1)); // date of month - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_mon+1), 1)); // month - ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_year-100), 1)); // year - ESP_ERROR_CHECK(i2c_master_stop(cmd)); - errRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000/portTICK_PERIOD_MS); - if (errRc != 0) { - ESP_LOGE(tag, "i2c_master_cmd_begin: %d", errRc); - } - i2c_cmd_link_delete(cmd); + ESP_LOGI(tag, ">> writeValue: %ld", newTime); + struct tm tm; + gmtime_r(&newTime, &tm); + char buf[30]; + ESP_LOGI(tag, " - %s", asctime_r(&tm, buf)); + + esp_err_t errRc; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + ESP_ERROR_CHECK(i2c_master_start(cmd)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (DS1307_ADDRESS << 1) | I2C_MASTER_WRITE, 1 /* expect ack */)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 0x0, 1)); + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_sec), 1)); // seconds + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_min), 1)); // minutes + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_hour), 1)); // hours + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_wday + 1), 1)); // week day + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_mday), 1)); // date of month + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_mon + 1), 1)); // month + ESP_ERROR_CHECK(i2c_master_write_byte(cmd, intToBCD(tm.tm_year - 100), 1)); // year + ESP_ERROR_CHECK(i2c_master_stop(cmd)); + errRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_PERIOD_MS); + if (errRc != 0) + { + ESP_LOGE(tag, "i2c_master_cmd_begin: %d", errRc); + } + i2c_cmd_link_delete(cmd); } -static void task_ds1307(void *ignore) +static void task_ds1307(void *ignore) { - ESP_LOGI(tag, ">> ds1307"); - initI2C(); - startSNTP(); - time_t t; - int count = 0; - while(time(&t) < 1000 && count < 10) { - ESP_LOGE(tag, "Waiting for SNTP ..."); - count++; - vTaskDelay(1000/portTICK_PERIOD_MS); - } - - if (count >= 10) { - ESP_LOGE(tag, "SNTP timeout, restart now"); - esp_restart(); // do not write to ds1307 when timeout - } - writeValue(t); - - while(1) { - time_t t = time(NULL); - ESP_LOGI(tag, "time: %ld", t); - t = readValue(); - ESP_LOGI(tag, "Read from DS1307: %ld", t); - vTaskDelay(1000/portTICK_PERIOD_MS); - } + ESP_LOGI(tag, ">> ds1307"); + initI2C(); + startSNTP(); + time_t t; + int count = 0; + while (time(&t) < 1000 && count < 10) + { + ESP_LOGE(tag, "Waiting for SNTP ..."); + count++; + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + + if (count >= 10) + { + ESP_LOGE(tag, "SNTP timeout, restart now"); + esp_restart(); // do not write to ds1307 when timeout + } + writeValue(t); + + while (1) + { + time_t t = time(NULL); + ESP_LOGI(tag, "time: %ld", t); + t = readValue(); + ESP_LOGI(tag, "Read from DS1307: %ld", t); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } } -void initDS1307(void) +void initDS1307(void) { - xEventGroupWaitBits(station_event_group, STA_GOTIP_BIT, false, true, portMAX_DELAY); - xEventGroupClearBits(station_event_group, STA_GOTIP_BIT); - ESP_LOGI(tag, "ds1307 init"); - xTaskCreatePinnedToCore(&task_ds1307, "task_ds1307", 2048, NULL, 5, NULL, 0); + xEventGroupWaitBits(station_event_group, STA_GOTIP_BIT, false, true, portMAX_DELAY); + xEventGroupClearBits(station_event_group, STA_GOTIP_BIT); + ESP_LOGI(tag, "ds1307 init"); + xTaskCreatePinnedToCore(&task_ds1307, "task_ds1307", 2048, NULL, 5, NULL, 0); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ds1307/main/main.c b/LuaNode_Esp32/LuaNode32/examples/ds1307/main/main.c index 5e5514e..ef8edc6 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ds1307/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/ds1307/main/main.c @@ -1,62 +1,64 @@ -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" - +#include "driver/gpio.h" +#include "ds1307.h" +#include "esp_event.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "esp_wifi.h" #include "esp_system.h" -#include "esp_event.h" -#include "esp_event_loop.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" #include "nvs_flash.h" -#include "driver/gpio.h" -#include "ds1307.h" -#define TAG "main" +#define TAG "main" -#define DEFAULT_SSID "Doit" -#define DEFAULT_PASS "doit3305" +#define DEFAULT_SSID "Doit" +#define DEFAULT_PASS "doit3305" EventGroupHandle_t station_event_group; const int STA_GOTIP_BIT = BIT0; - static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START:// station start - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: {//station disconnect from ap - ESP_LOGI(TAG, "Station disconnected"); - break; - } - case SYSTEM_EVENT_STA_CONNECTED: //station connect to ap - ESP_LOGI(TAG, "Station connected to AP"); - break; - case SYSTEM_EVENT_STA_GOT_IP: { //station get ip - ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(station_event_group, STA_GOTIP_BIT); - //create_tcp_client("192.168.9.115", 5556); - break; - } - case SYSTEM_EVENT_AP_STACONNECTED:// a station connect to ap - ESP_LOGI(TAG, "station:"MACSTR" join,AID=%d\n", MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid); - //xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED://a station disconnect from ap - ESP_LOGI(TAG, "station:"MACSTR"leave,AID=%d\n", MAC2STR(event->event_info.sta_disconnected.mac), event->event_info.sta_disconnected.aid); - //xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_ETH_CONNECTED: - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - //xEventGroupClearBits(eth_event_group, ETH_CONNECTED_BIT); - //xEventGroupClearBits(eth_event_group, ETH_GOTIP_BIT); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: // station start + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + { // station disconnect from ap + ESP_LOGI(TAG, "Station disconnected"); + break; + } + case SYSTEM_EVENT_STA_CONNECTED: // station connect to ap + ESP_LOGI(TAG, "Station connected to AP"); + break; + case SYSTEM_EVENT_STA_GOT_IP: + { // station get ip + ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); + xEventGroupSetBits(station_event_group, STA_GOTIP_BIT); + // create_tcp_client("192.168.9.115", 5556); + break; + } + case SYSTEM_EVENT_AP_STACONNECTED: // a station connect to ap + ESP_LOGI(TAG, "station:" MACSTR " join,AID=%d\n", MAC2STR(event->event_info.sta_connected.mac), + event->event_info.sta_connected.aid); + // xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT); + break; + case SYSTEM_EVENT_AP_STADISCONNECTED: // a station disconnect from ap + ESP_LOGI(TAG, "station:" MACSTR "leave,AID=%d\n", MAC2STR(event->event_info.sta_disconnected.mac), + event->event_info.sta_disconnected.aid); + // xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + // xEventGroupClearBits(eth_event_group, ETH_CONNECTED_BIT); + // xEventGroupClearBits(eth_event_group, ETH_GOTIP_BIT); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + break; + default: + break; } return ESP_OK; } @@ -65,20 +67,18 @@ void app_main(void) { nvs_flash_init(); tcpip_adapter_init(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - wifi_config_t sta_config = { - .sta = { - .ssid = DEFAULT_SSID, - .password = DEFAULT_PASS, - } - }; - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); - //ESP_ERROR_CHECK( esp_wifi_connect() ); - station_event_group = xEventGroupCreate(); - initDS1307(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + wifi_config_t sta_config = {.sta = { + .ssid = DEFAULT_SSID, + .password = DEFAULT_PASS, + }}; + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + // ESP_ERROR_CHECK( esp_wifi_connect() ); + station_event_group = xEventGroupCreate(); + initDS1307(); } diff --git a/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c b/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c index af5f20f..2c72e38 100644 --- a/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/easy_mem/app_main.c @@ -1,32 +1,33 @@ -#include #include -#include "esp_log.h" -#include "esp_system.h" +#include + #include "easy_heap.h" #include "easy_mem.h" +#include "esp_log.h" +#include "esp_system.h" -#define BUF_SIZE 10 +#define BUF_SIZE 10 static const char *TAG = "main"; void app_main() { - easy_heap_init(); - easy_mem_init(); + easy_heap_init(); + easy_mem_init(); - unsigned char *addr1 = (unsigned char*)easy_heap_alloc(BUF_SIZE); - memset(addr1, 0, BUF_SIZE); - memcpy(addr1, "hello", 5); - printf("%s\n", addr1); - easy_heap_free(addr1); + unsigned char *addr1 = (unsigned char *)easy_heap_alloc(BUF_SIZE); + memset(addr1, 0, BUF_SIZE); + memcpy(addr1, "hello", 5); + printf("%s\n", addr1); + easy_heap_free(addr1); - unsigned char *addr2 = (unsigned char*)easy_mem_alloc(BUF_SIZE); - memset(addr2, 0, BUF_SIZE); - memcpy(addr2, "world", 5); - printf("%s\n", addr2); - easy_mem_free(addr2); + unsigned char *addr2 = (unsigned char *)easy_mem_alloc(BUF_SIZE); + memset(addr2, 0, BUF_SIZE); + memcpy(addr2, "world", 5); + printf("%s\n", addr2); + easy_mem_free(addr2); - // print statistics - easy_heap_statistics(); - easy_mem_statistics(); + // print statistics + easy_heap_statistics(); + easy_mem_statistics(); } diff --git a/LuaNode_Esp32/LuaNode32/examples/esp32_ble_gatt_server_led_control_for_phone/main/gatts_demo.c b/LuaNode_Esp32/LuaNode32/examples/esp32_ble_gatt_server_led_control_for_phone/main/gatts_demo.c index bab03b6..3ad1e60 100644 --- a/LuaNode_Esp32/LuaNode32/examples/esp32_ble_gatt_server_led_control_for_phone/main/gatts_demo.c +++ b/LuaNode_Esp32/LuaNode32/examples/esp32_ble_gatt_server_led_control_for_phone/main/gatts_demo.c @@ -15,76 +15,102 @@ #include #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_log.h" -#include "nvs_flash.h" + #include "bt.h" #include "bta_api.h" - -#include "esp_gap_ble_api.h" -#include "esp_gatts_api.h" +#include "driver/gpio.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" -#include "esp_bt_main.h" - -#include "driver/gpio.h" - +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_log.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "sdkconfig.h" #define GATTS_TAG "GATTS_DEMO" #define BLINK_GPIO 2 +/// Declare the static function +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param); +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param); -///Declare the static function -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); - -#define GATTS_SERVICE_UUID_TEST_A 0x00FF -#define GATTS_CHAR_UUID_TEST_A 0xFF01 -#define GATTS_DESCR_UUID_TEST_A 0x3333 -#define GATTS_NUM_HANDLE_TEST_A 4 +#define GATTS_SERVICE_UUID_TEST_A 0x00FF +#define GATTS_CHAR_UUID_TEST_A 0xFF01 +#define GATTS_DESCR_UUID_TEST_A 0x3333 +#define GATTS_NUM_HANDLE_TEST_A 4 -#define GATTS_SERVICE_UUID_TEST_B 0x00EE -#define GATTS_CHAR_UUID_TEST_B 0xEE01 -#define GATTS_DESCR_UUID_TEST_B 0x2222 -#define GATTS_NUM_HANDLE_TEST_B 4 +#define GATTS_SERVICE_UUID_TEST_B 0x00EE +#define GATTS_CHAR_UUID_TEST_B 0xEE01 +#define GATTS_DESCR_UUID_TEST_B 0x2222 +#define GATTS_NUM_HANDLE_TEST_B 4 -#define TEST_DEVICE_NAME "Spark32" -#define TEST_MANUFACTURER_DATA_LEN 17 +#define TEST_DEVICE_NAME "Spark32" +#define TEST_MANUFACTURER_DATA_LEN 17 #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 -uint8_t char1_str[] = {0x11,0x22,0x33}; -esp_attr_value_t gatts_demo_char1_val = -{ +uint8_t char1_str[] = {0x11, 0x22, 0x33}; +esp_attr_value_t gatts_demo_char1_val = { .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX, - .attr_len = sizeof(char1_str), - .attr_value = char1_str, + .attr_len = sizeof(char1_str), + .attr_value = char1_str, }; #ifdef CONFIG_SET_RAW_ADV_DATA -static uint8_t raw_adv_data[] = { - 0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd -}; -static uint8_t raw_scan_rsp_data[] = { - 0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd -}; +static uint8_t raw_adv_data[] = {0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, + 0x53, 0x5f, 0x44, 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd}; +static uint8_t raw_scan_rsp_data[] = {0x02, 0x01, 0x06, 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, + 0x53, 0x5f, 0x44, 0x45, 0x4d, 0x4f, 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd}; #else static uint8_t test_service_uuid128[32] = { - /* LSB <--------------------------------------------------------------------------------> MSB */ - //first uuid, 16bit, [12],[13] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0x00, 0x00, - //second uuid, 32bit, [12], [13], [14], [15] is the value - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD, + /* LSB + <--------------------------------------------------------------------------------> + MSB */ + // first uuid, 16bit, [12],[13] is the value + 0xfb, + 0x34, + 0x9b, + 0x5f, + 0x80, + 0x00, + 0x00, + 0x80, + 0x00, + 0x10, + 0x00, + 0x00, + 0xAB, + 0xCD, + 0x00, + 0x00, + // second uuid, 32bit, [12], [13], [14], [15] is the value + 0xfb, + 0x34, + 0x9b, + 0x5f, + 0x80, + 0x00, + 0x00, + 0x80, + 0x00, + 0x10, + 0x00, + 0x00, + 0xAB, + 0xCD, + 0xAB, + 0xCD, }; -//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56}; +// static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, +// 0x45, 0x56}; static esp_ble_adv_data_t test_adv_data = { .set_scan_rsp = false, .include_name = true, @@ -92,8 +118,8 @@ static esp_ble_adv_data_t test_adv_data = { .min_interval = 0x20, .max_interval = 0x40, .appearance = 0x00, - .manufacturer_len = 0, //TEST_MANUFACTURER_DATA_LEN, - .p_manufacturer_data = NULL, //&test_manufacturer[0], + .manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN, + .p_manufacturer_data = NULL, //&test_manufacturer[0], .service_data_len = 0, .p_service_data = NULL, .service_uuid_len = 32, @@ -103,13 +129,13 @@ static esp_ble_adv_data_t test_adv_data = { #endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t test_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, - .adv_type = ADV_TYPE_IND, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .adv_int_min = 0x20, + .adv_int_max = 0x40, + .adv_type = ADV_TYPE_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, //.peer_addr = //.peer_addr_type = - .channel_map = ADV_CHNL_ALL, + .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; @@ -117,7 +143,8 @@ static esp_ble_adv_params_t test_adv_params = { #define PROFILE_A_APP_ID 0 #define PROFILE_B_APP_ID 1 -struct gatts_profile_inst { +struct gatts_profile_inst +{ esp_gatts_cb_t gatts_cb; uint16_t gatts_if; uint16_t app_id; @@ -132,83 +159,97 @@ struct gatts_profile_inst { esp_bt_uuid_t descr_uuid; }; -/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */ +/* One gatt-based profile one app_id and one gatts_if, this array will store the + * gatts_if returned by ESP_GATTS_REG_EVT */ static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = { - [PROFILE_A_APP_ID] = { - .gatts_cb = gatts_profile_a_event_handler, - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, - [PROFILE_B_APP_ID] = { - .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, similar as profile A */ - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, + [PROFILE_A_APP_ID] = + { + .gatts_cb = gatts_profile_a_event_handler, .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial + is ESP_GATT_IF_NONE */ + }, + [PROFILE_B_APP_ID] = + { + .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, + similar as profile A */ + .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is + ESP_GATT_IF_NONE */ + }, }; static uint8_t led_state = 0; - static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { - switch (event) { - case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: - //advertising start complete event to indicate advertising start successfully or failed - if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); - } - break; - default: - break; + switch (event) + { + case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + // advertising start complete event to indicate advertising start + // successfully or failed + if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) + { + ESP_LOGE(GATTS_TAG, "Advertising start failed\n"); + } + break; + default: + break; } } -static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; - - esp_ble_gap_set_device_name(TEST_DEVICE_NAME); +static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) + { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A; + + esp_ble_gap_set_device_name(TEST_DEVICE_NAME); #ifdef CONFIG_SET_RAW_ADV_DATA - esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); - esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); + esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data)); + esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data)); #else - esp_ble_gap_config_adv_data(&test_adv_data); + esp_ble_gap_config_adv_data(&test_adv_data); #endif - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A); - break; - case ESP_GATTS_READ_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); - esp_gatt_rsp_t rsp; - memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); - rsp.attr_value.handle = param->read.handle; - rsp.attr_value.len = 1; - rsp.attr_value.value[0] = led_state; - rsp.attr_value.value[1] = 0xed; - rsp.attr_value.value[2] = 0xbe; - rsp.attr_value.value[3] = 0xef; - esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, - ESP_GATT_OK, &rsp); - break; - } - case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %02x\n", param->write.len, param->write.value[0]); - esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); - led_state = ((param->write.value[0]) ? 1 : 0); - gpio_set_level(BLINK_GPIO, led_state); - #if 0 + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, + GATTS_NUM_HANDLE_TEST_A); + break; + case ESP_GATTS_READ_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, + param->read.trans_id, param->read.handle); + esp_gatt_rsp_t rsp; + memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); + rsp.attr_value.handle = param->read.handle; + rsp.attr_value.len = 1; + rsp.attr_value.value[0] = led_state; + rsp.attr_value.value[1] = 0xed; + rsp.attr_value.value[2] = 0xbe; + rsp.attr_value.value[3] = 0xef; + esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); + break; + } + case ESP_GATTS_WRITE_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, + param->write.trans_id, param->write.handle); + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %02x\n", param->write.len, param->write.value[0]); + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); + led_state = ((param->write.value[0]) ? 1 : 0); + gpio_set_level(BLINK_GPIO, led_state); +#if 0 uint32_t cmd = *(uint32_t *)param->write.value; ESP_LOGI(GATTS_TAG, "Received Command: %d\n", (int)cmd); if(0 == cmd) @@ -221,113 +262,123 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i ESP_LOGI(GATTS_TAG, "Received Command: LED On\n"); gpio_set_level(BLINK_GPIO, led_state); } - #endif - break; - } - case ESP_GATTS_EXEC_WRITE_EVT: - case ESP_GATTS_MTU_EVT: - case ESP_GATTS_CONF_EVT: - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_CREATE_EVT: - ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; - - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); - - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - &gatts_demo_char1_val, NULL); - break; - case ESP_GATTS_ADD_INCL_SRVC_EVT: - break; - case ESP_GATTS_ADD_CHAR_EVT: { - uint16_t length = 0; - const uint8_t *prf_char; - - ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); - - ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); - for(int i = 0; i < length; i++){ - ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n",i,prf_char[i]); +#endif + break; } - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); - break; - } - case ESP_GATTS_ADD_CHAR_DESCR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", - param->start.status, param->start.service_handle); - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", - param->connect.conn_id, - param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], - param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], - param->connect.is_connected); - gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; - break; - case ESP_GATTS_DISCONNECT_EVT: - esp_ble_gap_start_advertising(&test_adv_params); - break; - case ESP_GATTS_OPEN_EVT: - case ESP_GATTS_CANCEL_OPEN_EVT: - case ESP_GATTS_CLOSE_EVT: - case ESP_GATTS_LISTEN_EVT: - case ESP_GATTS_CONGEST_EVT: - default: - break; + case ESP_GATTS_EXEC_WRITE_EVT: + case ESP_GATTS_MTU_EVT: + case ESP_GATTS_CONF_EVT: + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_CREATE_EVT: + ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, + param->create.service_handle); + gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A; + + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle); + + esp_ble_gatts_add_char( + gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, + &gatts_demo_char1_val, NULL); + break; + case ESP_GATTS_ADD_INCL_SRVC_EVT: + break; + case ESP_GATTS_ADD_CHAR_EVT: + { + uint16_t length = 0; + const uint8_t *prf_char; + + ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char); + + ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length); + for (int i = 0; i < length; i++) { ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n", i, prf_char[i]); } + esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, + &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + break; + } + case ESP_GATTS_ADD_CHAR_DESCR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status, + param->start.service_handle); + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TAG, + "SERVICE_START_EVT, conn_id %d, remote " + "%02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", + param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], + param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], + param->connect.remote_bda[5], param->connect.is_connected); + gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id; + break; + case ESP_GATTS_DISCONNECT_EVT: + esp_ble_gap_start_advertising(&test_adv_params); + break; + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + default: + break; } } -static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); - gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; - - esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B); - break; - case ESP_GATTS_READ_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle); - esp_gatt_rsp_t rsp; - memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); - rsp.attr_value.handle = param->read.handle; - rsp.attr_value.len = 1; - rsp.attr_value.value[0] = led_state; - rsp.attr_value.value[1] = 0xed; - rsp.attr_value.value[2] = 0xbe; - rsp.attr_value.value[3] = 0xef; - esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, - ESP_GATT_OK, &rsp); - break; - } - case ESP_GATTS_WRITE_EVT: { - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle); - ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %02x\n", param->write.len, param->write.value[0]); - esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); - led_state = ((param->write.value[0]) ? 1 : 0); - gpio_set_level(BLINK_GPIO, led_state); - #if 0 +static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t *param) +{ + switch (event) + { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id); + gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B; + + esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, + GATTS_NUM_HANDLE_TEST_B); + break; + case ESP_GATTS_READ_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, + param->read.trans_id, param->read.handle); + esp_gatt_rsp_t rsp; + memset(&rsp, 0, sizeof(esp_gatt_rsp_t)); + rsp.attr_value.handle = param->read.handle; + rsp.attr_value.len = 1; + rsp.attr_value.value[0] = led_state; + rsp.attr_value.value[1] = 0xed; + rsp.attr_value.value[2] = 0xbe; + rsp.attr_value.value[3] = 0xef; + esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp); + break; + } + case ESP_GATTS_WRITE_EVT: + { + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, + param->write.trans_id, param->write.handle); + ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value %02x\n", param->write.len, param->write.value[0]); + esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); + led_state = ((param->write.value[0]) ? 1 : 0); + gpio_set_level(BLINK_GPIO, led_state); +#if 0 uint32_t cmd = *(uint32_t *)param->write.value; ESP_LOGI(GATTS_TAG, "Received Command: %d\n", (int)cmd); if(0 == cmd) @@ -340,93 +391,103 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i ESP_LOGI(GATTS_TAG, "Received Command: LED On\n"); gpio_set_level(BLINK_GPIO, led_state); } - #endif - break; - } - case ESP_GATTS_EXEC_WRITE_EVT: - case ESP_GATTS_MTU_EVT: - case ESP_GATTS_CONF_EVT: - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_CREATE_EVT: - ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle); - gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; - gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; - - esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); - - esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, - NULL, NULL); - break; - case ESP_GATTS_ADD_INCL_SRVC_EVT: - break; - case ESP_GATTS_ADD_CHAR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - - gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; - gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; - gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; - esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, - ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, - NULL, NULL); - break; - case ESP_GATTS_ADD_CHAR_DESCR_EVT: - ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", - param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle); - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", - param->start.status, param->start.service_handle); - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: - ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", - param->connect.conn_id, - param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2], - param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5], - param->connect.is_connected); - gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; - break; - case ESP_GATTS_DISCONNECT_EVT: - case ESP_GATTS_OPEN_EVT: - case ESP_GATTS_CANCEL_OPEN_EVT: - case ESP_GATTS_CLOSE_EVT: - case ESP_GATTS_LISTEN_EVT: - case ESP_GATTS_CONGEST_EVT: - default: - break; +#endif + break; + } + case ESP_GATTS_EXEC_WRITE_EVT: + case ESP_GATTS_MTU_EVT: + case ESP_GATTS_CONF_EVT: + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_CREATE_EVT: + ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, + param->create.service_handle); + gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B; + + esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle); + + esp_ble_gatts_add_char( + gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, + ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY, NULL, NULL); + break; + case ESP_GATTS_ADD_INCL_SRVC_EVT: + break; + case ESP_GATTS_ADD_CHAR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + + gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16; + gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; + esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, + &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid, + ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL); + break; + case ESP_GATTS_ADD_CHAR_DESCR_EVT: + ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n", param->add_char.status, + param->add_char.attr_handle, param->add_char.service_handle); + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n", param->start.status, + param->start.service_handle); + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + ESP_LOGI(GATTS_TAG, + "SERVICE_START_EVT, conn_id %d, remote " + "%02x:%02x:%02x:%02x:%02x:%02x:, is_conn %d\n", + param->connect.conn_id, param->connect.remote_bda[0], param->connect.remote_bda[1], + param->connect.remote_bda[2], param->connect.remote_bda[3], param->connect.remote_bda[4], + param->connect.remote_bda[5], param->connect.is_connected); + gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id; + break; + case ESP_GATTS_DISCONNECT_EVT: + case ESP_GATTS_OPEN_EVT: + case ESP_GATTS_CANCEL_OPEN_EVT: + case ESP_GATTS_CLOSE_EVT: + case ESP_GATTS_LISTEN_EVT: + case ESP_GATTS_CONGEST_EVT: + default: + break; } } static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { /* If event is register event, store the gatts_if for each profile */ - if (event == ESP_GATTS_REG_EVT) { - if (param->reg.status == ESP_GATT_OK) { + if (event == ESP_GATTS_REG_EVT) + { + if (param->reg.status == ESP_GATT_OK) + { gl_profile_tab[param->reg.app_id].gatts_if = gatts_if; - } else { - ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", - param->reg.app_id, - param->reg.status); + } + else + { + ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status); return; } } /* If the gatts_if equal to profile A, call profile A cb handler, * so here call each profile's callback */ - do { + do + { int idx; - for (idx = 0; idx < PROFILE_NUM; idx++) { - if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */ - gatts_if == gl_profile_tab[idx].gatts_if) { - if (gl_profile_tab[idx].gatts_cb) { + for (idx = 0; idx < PROFILE_NUM; idx++) + { + if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a + certain gatt_if, need to call every + profile cb function */ + gatts_if == gl_profile_tab[idx].gatts_if) + { + if (gl_profile_tab[idx].gatts_cb) + { gl_profile_tab[idx].gatts_cb(event, gatts_if, param); } } @@ -446,17 +507,20 @@ void app_main() esp_bt_controller_init(); ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s enable controller failed\n", __func__); return; } ret = esp_bluedroid_init(); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s init bluetooth failed\n", __func__); return; } ret = esp_bluedroid_enable(); - if (ret) { + if (ret) + { ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed\n", __func__); return; } diff --git a/LuaNode_Esp32/LuaNode32/examples/esp32_nrf51822_ble_conn/main/gattc_demo.c b/LuaNode_Esp32/LuaNode32/examples/esp32_nrf51822_ble_conn/main/gattc_demo.c index 783852f..2e9736b 100644 --- a/LuaNode_Esp32/LuaNode32/examples/esp32_nrf51822_ble_conn/main/gattc_demo.c +++ b/LuaNode_Esp32/LuaNode32/examples/esp32_nrf51822_ble_conn/main/gattc_demo.c @@ -13,36 +13,33 @@ // See the License for the specific language governing permissions and // limitations under the License. - - /**************************************************************************** -* -* This file is for gatt client. It can scan ble device, connect one device, -* -****************************************************************************/ + * + * This file is for gatt client. It can scan ble device, connect one device, + * + ****************************************************************************/ -#include -#include #include +#include #include -#include "controller.h" +#include #include "bt.h" #include "bt_trace.h" #include "bt_types.h" -#include "btm_api.h" #include "bta_api.h" #include "bta_gatt_api.h" +#include "btm_api.h" +#include "controller.h" +#include "esp_bt_main.h" #include "esp_gap_ble_api.h" -#include "esp_gattc_api.h" #include "esp_gatt_defs.h" -#include "esp_bt_main.h" - +#include "esp_gattc_api.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" -#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] +#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] static esp_gatt_if_t client_if; static uint16_t client_conn = 0; @@ -53,34 +50,44 @@ uint16_t simpleClient_id = 0xEE; const char device_name[] = "Nordic_UART"; static char tar_dev_mac[6] = {0xff, 0xb5, 0x30, 0x4e, 0x0a, 0xcb}; static char tar_dev_mac2[6] = {0xd7, 0x63, 0x2b, 0x40, 0x13, 0x7c}; -static const char tar_char[] = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e}; -static const char write_char[] = {0x6e, 0x40, 0x00, 0x03, 0xb5, 0xa3, 0xf3, 0x93, 0xe0, 0xa9, 0xe5, 0x0e, 0x24, 0xdc, 0xca, 0x9e}; - +static const char tar_char[] = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, + 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e}; +static const char write_char[] = {0x6e, 0x40, 0x00, 0x03, 0xb5, 0xa3, 0xf3, 0x93, + 0xe0, 0xa9, 0xe5, 0x0e, 0x24, 0xdc, 0xca, 0x9e}; -static esp_ble_scan_params_t ble_scan_params = { - .scan_type = BLE_SCAN_TYPE_PASSIVE, - .own_addr_type = ESP_PUBLIC_ADDR, - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, - .scan_interval = 0x640, - .scan_window = 0x640 -}; +static esp_ble_scan_params_t ble_scan_params = {.scan_type = BLE_SCAN_TYPE_PASSIVE, + .own_addr_type = ESP_PUBLIC_ADDR, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_interval = 0x640, + .scan_window = 0x640}; static esp_gatt_srvc_id_t nrf51_service_id = { - .id = { - .uuid = { - .len = ESP_UUID_LEN_128, - .uuid = {.uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e},}, + .id = + { + .uuid = + { + .len = ESP_UUID_LEN_128, + .uuid = + { + .uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, + 0x00, 0x40, 0x6e}, + }, + }, + .inst_id = 0, }, - .inst_id = 0, - }, .is_primary = true, }; static esp_gatt_id_t char_id = { - .uuid = { - .len = ESP_UUID_LEN_128, - .uuid = {.uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e},}, - }, + .uuid = + { + .len = ESP_UUID_LEN_128, + .uuid = + { + .uuid128 = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, + 0x40, 0x6e}, + }, + }, .inst_id = 0, }; @@ -93,558 +100,741 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp static void get_characteristic_property(uint32_t flag) { - int i; - ESP_LOGI(TAG, "======================================="); - for (i = 0; i < 8; i ++) { - switch (flag & (2 << i)) - { - case ESP_GATT_CHAR_PROP_BIT_BROADCAST: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_BROADCAST"); - break; - case ESP_GATT_CHAR_PROP_BIT_READ: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_READ"); - break; - case ESP_GATT_CHAR_PROP_BIT_WRITE_NR: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE_NR"); - break; - case ESP_GATT_CHAR_PROP_BIT_WRITE: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE"); - break; - case ESP_GATT_CHAR_PROP_BIT_NOTIFY: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_NOTIFY"); - break; - case ESP_GATT_CHAR_PROP_BIT_INDICATE: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_INDICATE"); - break; - case ESP_GATT_CHAR_PROP_BIT_AUTH: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_AUTH"); - break; - case ESP_GATT_CHAR_PROP_BIT_EXT_PROP: - ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_EXT_PROP"); - break; - default: - break; - } - } - ESP_LOGI(TAG, "======================================="); + int i; + ESP_LOGI(TAG, "======================================="); + for (i = 0; i < 8; i++) + { + switch (flag & (2 << i)) + { + case ESP_GATT_CHAR_PROP_BIT_BROADCAST: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_BROADCAST"); + break; + case ESP_GATT_CHAR_PROP_BIT_READ: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_READ"); + break; + case ESP_GATT_CHAR_PROP_BIT_WRITE_NR: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE_NR"); + break; + case ESP_GATT_CHAR_PROP_BIT_WRITE: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_WRITE"); + break; + case ESP_GATT_CHAR_PROP_BIT_NOTIFY: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_NOTIFY"); + break; + case ESP_GATT_CHAR_PROP_BIT_INDICATE: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_INDICATE"); + break; + case ESP_GATT_CHAR_PROP_BIT_AUTH: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_AUTH"); + break; + case ESP_GATT_CHAR_PROP_BIT_EXT_PROP: + ESP_LOGI(TAG, "==> CHAR PROP ESP_GATT_CHAR_PROP_BIT_EXT_PROP"); + break; + default: + break; + } + } + ESP_LOGI(TAG, "======================================="); } static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { uint8_t *adv_name = NULL; uint8_t adv_name_len = 0; - switch (event) { - case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second - uint32_t duration = 10; - esp_ble_gap_start_scanning(duration); - break; - } - case ESP_GAP_BLE_SCAN_RESULT_EVT: { - esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.search_evt) { - case ESP_GAP_SEARCH_INQ_RES_EVT: - switch (scan_result->scan_rst.dev_type) { - case ESP_BT_DEVICE_TYPE_BREDR: - ESP_LOGI(TAG, "==> Connected Device type BREDR"); - break; - case ESP_BT_DEVICE_TYPE_BLE: - ESP_LOGI(TAG, "==> Connected Device type BLE"); - break; - case ESP_BT_DEVICE_TYPE_DUMO: - ESP_LOGI(TAG, "==> Connected Device type DUMO"); - break; - default: - break; - } - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - int equ = 1; - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); - LOG_INFO("adv_name_len=%x\n", adv_name_len); - - if (adv_name_len == strlen(device_name)) { - for (int i = 0; i < adv_name_len; i++) { - ESP_LOGI(TAG, ":%c", adv_name[i]); - if (device_name[i] != adv_name[i]) { - equ = 0; - } - } - } else { - ESP_LOGI(TAG, "==> device not found"); - break; - } - - - if (equ == 1 && connet == false) { - connet = true; - //char name[32] = {0}; - //sprintf(name, "==> address type: %d, dev name: %s", scan_result->scan_rst.ble_addr_type, adv_name); - //ESP_LOGI(TAG, "%s", name); - LOG_INFO("Connet to the remote device."); - esp_ble_gap_stop_scanning(); - esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); - //memcpy(tar_dev_mac, scan_result->scan_rst.bda, 6); - } else { - ESP_LOGI(TAG, "==> device not found or device is connected"); - } + switch (event) + { + case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: + { + // the unit of the duration is second + uint32_t duration = 10; + esp_ble_gap_start_scanning(duration); break; - case ESP_GAP_SEARCH_INQ_CMPL_EVT: - //esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.ble_evt_type) { - case ESP_BLE_EVT_CONN_ADV: - ESP_LOGI(TAG, "==> CONN_ADV"); - ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); - ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); - break; - case ESP_BLE_EVT_CONN_DIR_ADV: - ESP_LOGI(TAG, "==> CONN_DIR_ADV"); - break; - case ESP_BLE_EVT_DISC_ADV: - ESP_LOGI(TAG, "==> DISC_ADV"); - break; - case ESP_BLE_EVT_NON_CONN_ADV: - ESP_LOGI(TAG, "==> NON_CONN_ADV"); - break; - case ESP_BLE_EVT_SCAN_RSP: - ESP_LOGI(TAG, "==> receive scan response"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - } + } + case ESP_GAP_BLE_SCAN_RESULT_EVT: + { + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.search_evt) + { + case ESP_GAP_SEARCH_INQ_RES_EVT: + switch (scan_result->scan_rst.dev_type) + { + case ESP_BT_DEVICE_TYPE_BREDR: + ESP_LOGI(TAG, "==> Connected Device type BREDR"); + break; + case ESP_BT_DEVICE_TYPE_BLE: + ESP_LOGI(TAG, "==> Connected Device type BLE"); + break; + case ESP_BT_DEVICE_TYPE_DUMO: + ESP_LOGI(TAG, "==> Connected Device type DUMO"); + break; + default: + break; + } + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + int equ = 1; + adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); + LOG_INFO("adv_name_len=%x\n", adv_name_len); + + if (adv_name_len == strlen(device_name)) + { + for (int i = 0; i < adv_name_len; i++) + { + ESP_LOGI(TAG, ":%c", adv_name[i]); + if (device_name[i] != adv_name[i]) + { + equ = 0; + } + } + } + else + { + ESP_LOGI(TAG, "==> device not found"); + break; + } + + if (equ == 1 && connet == false) + { + connet = true; + // char name[32] = {0}; + // sprintf(name, "==> address type: %d, dev name: %s", + // scan_result->scan_rst.ble_addr_type, adv_name); + // ESP_LOGI(TAG, "%s", name); + LOG_INFO("Connet to the remote device."); + esp_ble_gap_stop_scanning(); + esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); + // memcpy(tar_dev_mac, scan_result->scan_rst.bda, 6); + } + else + { + ESP_LOGI(TAG, "==> device not found or device is connected"); + } + break; + case ESP_GAP_SEARCH_INQ_CMPL_EVT: + // esp_ble_gap_cb_param_t *scan_result = + // (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.ble_evt_type) + { + case ESP_BLE_EVT_CONN_ADV: + ESP_LOGI(TAG, "==> CONN_ADV"); + ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], + scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); + ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); + break; + case ESP_BLE_EVT_CONN_DIR_ADV: + ESP_LOGI(TAG, "==> CONN_DIR_ADV"); + break; + case ESP_BLE_EVT_DISC_ADV: + ESP_LOGI(TAG, "==> DISC_ADV"); + break; + case ESP_BLE_EVT_NON_CONN_ADV: + ESP_LOGI(TAG, "==> NON_CONN_ADV"); + break; + case ESP_BLE_EVT_SCAN_RSP: + ESP_LOGI(TAG, "==> receive scan response"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], + scan_result->scan_rst.bda[1], scan_result->scan_rst.bda[2], + scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + } + break; + default: + break; + } break; + } default: break; - } - break; - } - default: - break; } } - static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) { uint16_t conn_id = 0; esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param; LOG_INFO("esp_gattc_cb, event = %x", event); - switch (event) { - case ESP_GATTC_REG_EVT: - status = p_data->reg.status; - LOG_INFO("ESP_GATTC_REG_EVT status = %x, client_if = %x", status, gattc_if); - if (status == ESP_GATT_OK) { - client_if = gattc_if; - } else { - LOG_INFO("ESP_GATTC_REG failed!"); - } - break; - case ESP_GATTC_OPEN_EVT: - conn_id = p_data->open.conn_id; - LOG_INFO("ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d", conn_id, gattc_if, p_data->open.status); - if (p_data->open.status != 0) { - LOG_INFO("==> open GATTC error, closed"); - esp_ble_gattc_close(gattc_if, conn_id); - esp_ble_gattc_open(gattc_if, (uint8_t *)tar_dev_mac, true); - break; - } - esp_ble_gattc_search_service(gattc_if, conn_id, NULL); - client_conn = conn_id; - break; - case ESP_GATTC_CLOSE_EVT: - LOG_INFO("==> GATTC closed"); - task_run = false; - client_conn = 0; - break; - case ESP_GATTC_READ_CHAR_EVT: { - // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; - esp_gatt_id_t *char_id = &p_data->read.char_id; - conn_id = p_data->open.conn_id; - LOG_INFO("READ CHAR: open.conn_id = %x search_res.conn_id = %x read.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->read.conn_id); - LOG_INFO("READ CHAR: read.status = %x inst_id = %x", p_data->read.status, char_id->inst_id); - if (p_data->read.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); - } - for (int i = 0; i < p_data->read.value_len; i++) { - LOG_INFO("%x:", p_data->read.value[i]); + switch (event) + { + case ESP_GATTC_REG_EVT: + status = p_data->reg.status; + LOG_INFO("ESP_GATTC_REG_EVT status = %x, client_if = %x", status, gattc_if); + if (status == ESP_GATT_OK) + { + client_if = gattc_if; + } + else + { + LOG_INFO("ESP_GATTC_REG failed!"); + } + break; + case ESP_GATTC_OPEN_EVT: + conn_id = p_data->open.conn_id; + LOG_INFO("ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d", conn_id, gattc_if, p_data->open.status); + if (p_data->open.status != 0) + { + LOG_INFO("==> open GATTC error, closed"); + esp_ble_gattc_close(gattc_if, conn_id); + esp_ble_gattc_open(gattc_if, (uint8_t *)tar_dev_mac, true); + break; + } + esp_ble_gattc_search_service(gattc_if, conn_id, NULL); + client_conn = conn_id; + break; + case ESP_GATTC_CLOSE_EVT: + LOG_INFO("==> GATTC closed"); + task_run = false; + client_conn = 0; + break; + case ESP_GATTC_READ_CHAR_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; + esp_gatt_id_t *char_id = &p_data->read.char_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "READ CHAR: open.conn_id = %x search_res.conn_id = %x " + "read.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->read.conn_id); + LOG_INFO("READ CHAR: read.status = %x inst_id = %x", p_data->read.status, char_id->inst_id); + if (p_data->read.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); + } + for (int i = 0; i < p_data->read.value_len; i++) { LOG_INFO("%x:", p_data->read.value[i]); } } + break; } - break; - } - case ESP_GATTC_WRITE_CHAR_EVT: { - // esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; - esp_gatt_id_t *char_id = &p_data->write.char_id; - esp_gatt_id_t *descr_id = &p_data->write.descr_id; - conn_id = p_data->open.conn_id; - LOG_INFO("WRITE CHAR: open.conn_id = %x search_res.conn_id = %x write.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->write.conn_id); - LOG_INFO("WRITE CHAR: write.status = %x inst_id = %x", p_data->write.status, char_id->inst_id); - if (p_data->write.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); - } - if (descr_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); - } else if (descr_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); - } else if (descr_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Decr UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", descr_id->uuid.uuid.uuid128[0], - descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], descr_id->uuid.uuid.uuid128[3], - descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], descr_id->uuid.uuid.uuid128[6], - descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], descr_id->uuid.uuid.uuid128[9], - descr_id->uuid.uuid.uuid128[10], descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], - descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], descr_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); - } + case ESP_GATTC_WRITE_CHAR_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; + esp_gatt_id_t *char_id = &p_data->write.char_id; + esp_gatt_id_t *descr_id = &p_data->write.descr_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "WRITE CHAR: open.conn_id = %x search_res.conn_id = %x " + "write.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->write.conn_id); + LOG_INFO("WRITE CHAR: write.status = %x inst_id = %x", p_data->write.status, char_id->inst_id); + if (p_data->write.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); + } + if (descr_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Decr UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + descr_id->uuid.uuid.uuid128[0], descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], + descr_id->uuid.uuid.uuid128[3], descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], + descr_id->uuid.uuid.uuid128[6], descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], + descr_id->uuid.uuid.uuid128[9], descr_id->uuid.uuid.uuid128[10], + descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], + descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], + descr_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); + } + } + break; } - break; - } - case ESP_GATTC_SEARCH_RES_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; - conn_id = p_data->open.conn_id; - LOG_INFO("SEARCH RES: open.conn_id = %x search_res.conn_id = %x", conn_id,p_data->search_res.conn_id); - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", srvc_id->id.uuid.uuid.uuid128[0], - srvc_id->id.uuid.uuid.uuid128[1], srvc_id->id.uuid.uuid.uuid128[2], srvc_id->id.uuid.uuid.uuid128[3], - srvc_id->id.uuid.uuid.uuid128[4], srvc_id->id.uuid.uuid.uuid128[5], srvc_id->id.uuid.uuid.uuid128[6], - srvc_id->id.uuid.uuid.uuid128[7], srvc_id->id.uuid.uuid.uuid128[8], srvc_id->id.uuid.uuid.uuid128[9], - srvc_id->id.uuid.uuid.uuid128[10], srvc_id->id.uuid.uuid.uuid128[11], srvc_id->id.uuid.uuid.uuid128[12], - srvc_id->id.uuid.uuid.uuid128[13], srvc_id->id.uuid.uuid.uuid128[14], srvc_id->id.uuid.uuid.uuid128[15]); - esp_ble_gattc_get_characteristic(gattc_if, p_data->search_res.conn_id, srvc_id, NULL); - } else { - LOG_ERROR("UNKNOWN LEN %d", srvc_id->id.uuid.len); + case ESP_GATTC_SEARCH_RES_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->search_res.srvc_id; + conn_id = p_data->open.conn_id; + LOG_INFO("SEARCH RES: open.conn_id = %x search_res.conn_id = %x", conn_id, p_data->search_res.conn_id); + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("UUID16: %x", srvc_id->id.uuid.uuid.uuid16); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("UUID32: %x", srvc_id->id.uuid.uuid.uuid32); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", srvc_id->id.uuid.uuid.uuid128[0], + srvc_id->id.uuid.uuid.uuid128[1], srvc_id->id.uuid.uuid.uuid128[2], + srvc_id->id.uuid.uuid.uuid128[3], srvc_id->id.uuid.uuid.uuid128[4], + srvc_id->id.uuid.uuid.uuid128[5], srvc_id->id.uuid.uuid.uuid128[6], + srvc_id->id.uuid.uuid.uuid128[7], srvc_id->id.uuid.uuid.uuid128[8], + srvc_id->id.uuid.uuid.uuid128[9], srvc_id->id.uuid.uuid.uuid128[10], + srvc_id->id.uuid.uuid.uuid128[11], srvc_id->id.uuid.uuid.uuid128[12], + srvc_id->id.uuid.uuid.uuid128[13], srvc_id->id.uuid.uuid.uuid128[14], + srvc_id->id.uuid.uuid.uuid128[15]); + esp_ble_gattc_get_characteristic(gattc_if, p_data->search_res.conn_id, srvc_id, NULL); + } + else + { + LOG_ERROR("UNKNOWN LEN %d", srvc_id->id.uuid.len); + } + break; } - break; - } - case ESP_GATTC_WRITE_DESCR_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; - esp_gatt_id_t *char_id = &p_data->write.char_id; - esp_gatt_id_t *descr_id = &p_data->write.descr_id; - conn_id = p_data->open.conn_id; - LOG_INFO("WRITE DESCR: open.conn_id = %x search_res.conn_id = %x write.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->write.conn_id); - LOG_INFO("WRITE DESCR: write.status = %x inst_id = %x open.gatt_if = %x", p_data->write.status, char_id->inst_id,gattc_if); - if (p_data->write.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); - } - if (descr_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); - } else if (descr_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); - } else if (descr_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Decr UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", descr_id->uuid.uuid.uuid128[0], - descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], descr_id->uuid.uuid.uuid128[3], - descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], descr_id->uuid.uuid.uuid128[6], - descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], descr_id->uuid.uuid.uuid128[9], - descr_id->uuid.uuid.uuid128[10], descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], - descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], descr_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); - } - if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("SRVC UUID16: %x", srvc_id->id.uuid.uuid.uuid16); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("SRVC UUID32: %x", srvc_id->id.uuid.uuid.uuid32); - } else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("SRVC UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", srvc_id->id.uuid.uuid.uuid128[0], - srvc_id->id.uuid.uuid.uuid128[1], srvc_id->id.uuid.uuid.uuid128[2], srvc_id->id.uuid.uuid.uuid128[3], - srvc_id->id.uuid.uuid.uuid128[4], srvc_id->id.uuid.uuid.uuid128[5], srvc_id->id.uuid.uuid.uuid128[6], - srvc_id->id.uuid.uuid.uuid128[7], srvc_id->id.uuid.uuid.uuid128[8], srvc_id->id.uuid.uuid.uuid128[9], - srvc_id->id.uuid.uuid.uuid128[10], srvc_id->id.uuid.uuid.uuid128[11], srvc_id->id.uuid.uuid.uuid128[12], - srvc_id->id.uuid.uuid.uuid128[13], srvc_id->id.uuid.uuid.uuid128[14], srvc_id->id.uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("SRVC UNKNOWN LEN %d", srvc_id->id.uuid.len); - } - LOG_INFO("WRITE DESCR: gattc_if = %x",gattc_if); - LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:",p_data->open.remote_bda[0], - p_data->open.remote_bda[1],p_data->open.remote_bda[2], - p_data->open.remote_bda[3],p_data->open.remote_bda[4], - p_data->open.remote_bda[5]); + case ESP_GATTC_WRITE_DESCR_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->write.srvc_id; + esp_gatt_id_t *char_id = &p_data->write.char_id; + esp_gatt_id_t *descr_id = &p_data->write.descr_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "WRITE DESCR: open.conn_id = %x search_res.conn_id = %x " + "write.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->write.conn_id); + LOG_INFO("WRITE DESCR: write.status = %x inst_id = %x open.gatt_if = %x", p_data->write.status, + char_id->inst_id, gattc_if); + if (p_data->write.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); + } + if (descr_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Decr UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + descr_id->uuid.uuid.uuid128[0], descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], + descr_id->uuid.uuid.uuid128[3], descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], + descr_id->uuid.uuid.uuid128[6], descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], + descr_id->uuid.uuid.uuid128[9], descr_id->uuid.uuid.uuid128[10], + descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], + descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], + descr_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); + } + if (srvc_id->id.uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("SRVC UUID16: %x", srvc_id->id.uuid.uuid.uuid16); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("SRVC UUID32: %x", srvc_id->id.uuid.uuid.uuid32); + } + else if (srvc_id->id.uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "SRVC UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + srvc_id->id.uuid.uuid.uuid128[0], srvc_id->id.uuid.uuid.uuid128[1], + srvc_id->id.uuid.uuid.uuid128[2], srvc_id->id.uuid.uuid.uuid128[3], + srvc_id->id.uuid.uuid.uuid128[4], srvc_id->id.uuid.uuid.uuid128[5], + srvc_id->id.uuid.uuid.uuid128[6], srvc_id->id.uuid.uuid.uuid128[7], + srvc_id->id.uuid.uuid.uuid128[8], srvc_id->id.uuid.uuid.uuid128[9], + srvc_id->id.uuid.uuid.uuid128[10], srvc_id->id.uuid.uuid.uuid128[11], + srvc_id->id.uuid.uuid.uuid128[12], srvc_id->id.uuid.uuid.uuid128[13], + srvc_id->id.uuid.uuid.uuid128[14], srvc_id->id.uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("SRVC UNKNOWN LEN %d", srvc_id->id.uuid.len); + } + LOG_INFO("WRITE DESCR: gattc_if = %x", gattc_if); + LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:", p_data->open.remote_bda[0], p_data->open.remote_bda[1], + p_data->open.remote_bda[2], p_data->open.remote_bda[3], p_data->open.remote_bda[4], + p_data->open.remote_bda[5]); + } + break; } - break; - } - case ESP_GATTC_NOTIFY_EVT: { - // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; - esp_gatt_id_t *char_id = &p_data->notify.char_id; - conn_id = p_data->open.conn_id; - LOG_INFO("NOTIFY: open.conn_id = %x search_res.conn_id = %x notify.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->notify.conn_id); - LOG_INFO("NOTIFY: notify.is_notify = %x inst_id = %x", p_data->notify.is_notify, char_id->inst_id); - if (p_data->notify.is_notify==1) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); - } - for (int i = 0; i < p_data->notify.value_len; i++) { - LOG_INFO("NOTIFY: V%d %x:", i, p_data->notify.value[i]); + case ESP_GATTC_NOTIFY_EVT: + { + // esp_gatt_srvc_id_t *srvc_id = &p_data->read.srvc_id; + esp_gatt_id_t *char_id = &p_data->notify.char_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "NOTIFY: open.conn_id = %x search_res.conn_id = %x " + "notify.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->notify.conn_id); + LOG_INFO("NOTIFY: notify.is_notify = %x inst_id = %x", p_data->notify.is_notify, char_id->inst_id); + if (p_data->notify.is_notify == 1) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d\n", char_id->uuid.len); + } + for (int i = 0; i < p_data->notify.value_len; i++) + { LOG_INFO("NOTIFY: V%d %x:", i, p_data->notify.value[i]); } } + break; } - break; - } - case ESP_GATTC_GET_CHAR_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->get_char.srvc_id; - esp_gatt_id_t *char_id = &p_data->get_char.char_id; - conn_id = p_data->open.conn_id; - LOG_INFO("GET CHAR: open.conn_id = %x search_res.conn_id = %x get_char.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->get_char.conn_id); - LOG_INFO("GET CHAR: get_char.char_prop = %x get_char.status = %x inst_id = %x open.gatt_if = %x", p_data->get_char.char_prop, p_data->get_char.status, char_id->inst_id,gattc_if); - LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:",p_data->open.remote_bda[0], - p_data->open.remote_bda[1],p_data->open.remote_bda[2], - p_data->open.remote_bda[3],p_data->open.remote_bda[4], - p_data->open.remote_bda[5]); - if (p_data->get_char.status==0) { - get_characteristic_property(p_data->get_char.char_prop); - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - - - int equ = 1; - for (int i = 0; i < 16; i++) { - if (tar_char[i] != char_id->uuid.uuid.uuid128[i]) { - equ = 0; - break; - } - } - if (equ == 1) { - ESP_LOGI(TAG, "start task ......"); - task_run = true; - } - /*if (strncmp((char *)char_id->uuid.uuid.uuid128, tar_char, 16) == 0) { - task_run = true; - }*/ - } else { - LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); - } - esp_ble_gattc_get_descriptor(gattc_if, conn_id, srvc_id, char_id, NULL); - esp_ble_gattc_get_characteristic(gattc_if, conn_id, srvc_id, char_id); + case ESP_GATTC_GET_CHAR_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->get_char.srvc_id; + esp_gatt_id_t *char_id = &p_data->get_char.char_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "GET CHAR: open.conn_id = %x search_res.conn_id = %x " + "get_char.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->get_char.conn_id); + LOG_INFO( + "GET CHAR: get_char.char_prop = %x get_char.status = %x " + "inst_id = %x open.gatt_if = %x", + p_data->get_char.char_prop, p_data->get_char.status, char_id->inst_id, gattc_if); + LOG_INFO("remote_bda %x,%x,%x,%x,%x,%x:", p_data->open.remote_bda[0], p_data->open.remote_bda[1], + p_data->open.remote_bda[2], p_data->open.remote_bda[3], p_data->open.remote_bda[4], + p_data->open.remote_bda[5]); + if (p_data->get_char.status == 0) + { + get_characteristic_property(p_data->get_char.char_prop); + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + + int equ = 1; + for (int i = 0; i < 16; i++) + { + if (tar_char[i] != char_id->uuid.uuid.uuid128[i]) + { + equ = 0; + break; + } + } + if (equ == 1) + { + ESP_LOGI(TAG, "start task ......"); + task_run = true; + } + /*if (strncmp((char *)char_id->uuid.uuid.uuid128, tar_char, + 16) == 0) { task_run = true; + }*/ + } + else + { + LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); + } + esp_ble_gattc_get_descriptor(gattc_if, conn_id, srvc_id, char_id, NULL); + esp_ble_gattc_get_characteristic(gattc_if, conn_id, srvc_id, char_id); + } + break; } - break; - } - case ESP_GATTC_GET_DESCR_EVT: { - esp_gatt_srvc_id_t *srvc_id = &p_data->get_descr.srvc_id; - esp_gatt_id_t *char_id = &p_data->get_descr.char_id; - esp_gatt_id_t *descr_id = &p_data->get_descr.descr_id; - conn_id = p_data->open.conn_id; - LOG_INFO("GET DESCR: open.conn_id = %x search_res.conn_id = %x get_descr.conn_id = %x", conn_id,p_data->search_res.conn_id,p_data->get_descr.conn_id); - LOG_INFO("GET DESCR: get_descr.status = %x inst_id = %x open.gatt_if = %x", p_data->get_descr.status, char_id->inst_id,gattc_if); - uint8_t value[2]; - value[0]=0x01; - value[1]=0x00; - if (p_data->get_descr.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Char UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); - } - if (descr_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); - } else if (descr_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); - } else if (descr_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("Decr UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", descr_id->uuid.uuid.uuid128[0], - descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], descr_id->uuid.uuid.uuid128[3], - descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], descr_id->uuid.uuid.uuid128[6], - descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], descr_id->uuid.uuid.uuid128[9], - descr_id->uuid.uuid.uuid128[10], descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], - descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], descr_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); - } - esp_ble_gattc_get_descriptor(gattc_if, conn_id, srvc_id, char_id, descr_id); - //esp_ble_gattc_write_char_descr (gattc_if,conn_id,srvc_id,char_id,descr_id,2,&value[0],ESP_GATT_WRITE_TYPE_NO_RSP,ESP_GATT_AUTH_REQ_NONE); + case ESP_GATTC_GET_DESCR_EVT: + { + esp_gatt_srvc_id_t *srvc_id = &p_data->get_descr.srvc_id; + esp_gatt_id_t *char_id = &p_data->get_descr.char_id; + esp_gatt_id_t *descr_id = &p_data->get_descr.descr_id; + conn_id = p_data->open.conn_id; + LOG_INFO( + "GET DESCR: open.conn_id = %x search_res.conn_id = %x " + "get_descr.conn_id = %x", + conn_id, p_data->search_res.conn_id, p_data->get_descr.conn_id); + LOG_INFO( + "GET DESCR: get_descr.status = %x inst_id = %x open.gatt_if = " + "%x", + p_data->get_descr.status, char_id->inst_id, gattc_if); + uint8_t value[2]; + value[0] = 0x01; + value[1] = 0x00; + if (p_data->get_descr.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Char UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Char UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Char UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Char UNKNOWN LEN %d", char_id->uuid.len); + } + if (descr_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("Decr UUID16: %x", descr_id->uuid.uuid.uuid16); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("Decr UUID32: %x", descr_id->uuid.uuid.uuid32); + } + else if (descr_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "Decr UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + descr_id->uuid.uuid.uuid128[0], descr_id->uuid.uuid.uuid128[1], descr_id->uuid.uuid.uuid128[2], + descr_id->uuid.uuid.uuid128[3], descr_id->uuid.uuid.uuid128[4], descr_id->uuid.uuid.uuid128[5], + descr_id->uuid.uuid.uuid128[6], descr_id->uuid.uuid.uuid128[7], descr_id->uuid.uuid.uuid128[8], + descr_id->uuid.uuid.uuid128[9], descr_id->uuid.uuid.uuid128[10], + descr_id->uuid.uuid.uuid128[11], descr_id->uuid.uuid.uuid128[12], + descr_id->uuid.uuid.uuid128[13], descr_id->uuid.uuid.uuid128[14], + descr_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("Decr UNKNOWN LEN %d", descr_id->uuid.len); + } + esp_ble_gattc_get_descriptor(gattc_if, conn_id, srvc_id, char_id, descr_id); + // esp_ble_gattc_write_char_descr + // (gattc_if,conn_id,srvc_id,char_id,descr_id,2,&value[0],ESP_GATT_WRITE_TYPE_NO_RSP,ESP_GATT_AUTH_REQ_NONE); + } + break; } - break; - } - case ESP_GATTC_REG_FOR_NOTIFY_EVT: { - LOG_INFO("NOTIFY_EVT: open.conn_id = %x ", p_data->open.conn_id); - LOG_INFO("NOTIFY_EVT: reg_for_notify.status = %x ", p_data->reg_for_notify.status); - esp_gatt_id_t *char_id = &p_data->reg_for_notify.char_id; - if (p_data->reg_for_notify.status==0) { - if (char_id->uuid.len == ESP_UUID_LEN_16) { - LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); - } else if (char_id->uuid.len == ESP_UUID_LEN_32) { - LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); - } else if (char_id->uuid.len == ESP_UUID_LEN_128) { - LOG_INFO("UUID128: %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", char_id->uuid.uuid.uuid128[0], - char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], char_id->uuid.uuid.uuid128[3], - char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], char_id->uuid.uuid.uuid128[6], - char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], char_id->uuid.uuid.uuid128[9], - char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], char_id->uuid.uuid.uuid128[12], - char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], char_id->uuid.uuid.uuid128[15]); - } else { - LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); - } + case ESP_GATTC_REG_FOR_NOTIFY_EVT: + { + LOG_INFO("NOTIFY_EVT: open.conn_id = %x ", p_data->open.conn_id); + LOG_INFO("NOTIFY_EVT: reg_for_notify.status = %x ", p_data->reg_for_notify.status); + esp_gatt_id_t *char_id = &p_data->reg_for_notify.char_id; + if (p_data->reg_for_notify.status == 0) + { + if (char_id->uuid.len == ESP_UUID_LEN_16) + { + LOG_INFO("UUID16: %x", char_id->uuid.uuid.uuid16); + } + else if (char_id->uuid.len == ESP_UUID_LEN_32) + { + LOG_INFO("UUID32: %x", char_id->uuid.uuid.uuid32); + } + else if (char_id->uuid.len == ESP_UUID_LEN_128) + { + LOG_INFO( + "UUID128: " + "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", + char_id->uuid.uuid.uuid128[0], char_id->uuid.uuid.uuid128[1], char_id->uuid.uuid.uuid128[2], + char_id->uuid.uuid.uuid128[3], char_id->uuid.uuid.uuid128[4], char_id->uuid.uuid.uuid128[5], + char_id->uuid.uuid.uuid128[6], char_id->uuid.uuid.uuid128[7], char_id->uuid.uuid.uuid128[8], + char_id->uuid.uuid.uuid128[9], char_id->uuid.uuid.uuid128[10], char_id->uuid.uuid.uuid128[11], + char_id->uuid.uuid.uuid128[12], char_id->uuid.uuid.uuid128[13], char_id->uuid.uuid.uuid128[14], + char_id->uuid.uuid.uuid128[15]); + } + else + { + LOG_ERROR("UNKNOWN LEN %d", char_id->uuid.len); + } + } + break; } - break; - } - case ESP_GATTC_SEARCH_CMPL_EVT: - conn_id = p_data->search_cmpl.conn_id; - LOG_INFO("SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); - esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; - switch (scan_result->scan_rst.ble_evt_type) { - case ESP_BLE_EVT_CONN_ADV: - ESP_LOGI(TAG, "==> CONN_ADV"); - ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); - ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); - /*esp_ble_gap_stop_scanning(); - esp_err_t err = esp_ble_gattc_open(client_if, scan_result->scan_rst.bda, true); - ESP_LOGI(TAG, "==> esp_ble_gattc_open %d", err);*/ - break; - case ESP_BLE_EVT_CONN_DIR_ADV: - ESP_LOGI(TAG, "==> CONN_DIR_ADV"); - break; - case ESP_BLE_EVT_DISC_ADV: - ESP_LOGI(TAG, "==> DISC_ADV"); - break; - case ESP_BLE_EVT_NON_CONN_ADV: - ESP_LOGI(TAG, "==> NON_CONN_ADV"); - break; - case ESP_BLE_EVT_SCAN_RSP: - ESP_LOGI(TAG, "==> receive scan response"); - LOG_INFO("BDA %x,%x,%x,%x,%x,%x:",scan_result->scan_rst.bda[0], - scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2], - scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4], - scan_result->scan_rst.bda[5]); - break; - } - break; - default: - break; + case ESP_GATTC_SEARCH_CMPL_EVT: + conn_id = p_data->search_cmpl.conn_id; + LOG_INFO("SEARCH_CMPL: conn_id = %x, status %d", conn_id, p_data->search_cmpl.status); + esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; + switch (scan_result->scan_rst.ble_evt_type) + { + case ESP_BLE_EVT_CONN_ADV: + ESP_LOGI(TAG, "==> CONN_ADV"); + ESP_LOGI(TAG, "BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + ESP_LOGI(TAG, "==> RSSI: %d", scan_result->scan_rst.rssi); + ESP_LOGI(TAG, "==> address type: %d", scan_result->scan_rst.ble_addr_type); + /*esp_ble_gap_stop_scanning(); + esp_err_t err = esp_ble_gattc_open(client_if, + scan_result->scan_rst.bda, true); ESP_LOGI(TAG, "==> + esp_ble_gattc_open %d", err);*/ + break; + case ESP_BLE_EVT_CONN_DIR_ADV: + ESP_LOGI(TAG, "==> CONN_DIR_ADV"); + break; + case ESP_BLE_EVT_DISC_ADV: + ESP_LOGI(TAG, "==> DISC_ADV"); + break; + case ESP_BLE_EVT_NON_CONN_ADV: + ESP_LOGI(TAG, "==> NON_CONN_ADV"); + break; + case ESP_BLE_EVT_SCAN_RSP: + ESP_LOGI(TAG, "==> receive scan response"); + LOG_INFO("BDA %x,%x,%x,%x,%x,%x:", scan_result->scan_rst.bda[0], scan_result->scan_rst.bda[1], + scan_result->scan_rst.bda[2], scan_result->scan_rst.bda[3], scan_result->scan_rst.bda[4], + scan_result->scan_rst.bda[5]); + break; + } + break; + default: + break; } } static void led_task(void *arg) { - while (1) { - ESP_LOGI(TAG, "led_task is running"); - if (task_run) { - if (toggle == 0) { - uint8_t val[] = {'o', 'n'}; - esp_err_t err = esp_ble_gattc_write_char(client_if, - client_conn, - &nrf51_service_id, - &char_id, - sizeof(val), - val, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - if (err != 0) { - ESP_LOGE(TAG, "BLE charateristic write failed"); - } - toggle = 1; - ESP_LOGE(TAG, "BLE charateristic write on"); - } else { - uint8_t val[] = {'o', 'f', 'f'}; - esp_err_t err = esp_ble_gattc_write_char(client_if, - client_conn, - &nrf51_service_id, - &char_id, - sizeof(val), - val, - ESP_GATT_WRITE_TYPE_RSP, - ESP_GATT_AUTH_REQ_NONE); - if (err != 0) { - ESP_LOGE(TAG, "BLE charateristic write failed"); - } - toggle = 0; - ESP_LOGE(TAG, "BLE charateristic write off"); - } - } - vTaskDelay(2000 / portTICK_RATE_MS); - } - vTaskDelete(NULL); + while (1) + { + ESP_LOGI(TAG, "led_task is running"); + if (task_run) + { + if (toggle == 0) + { + uint8_t val[] = {'o', 'n'}; + esp_err_t err = + esp_ble_gattc_write_char(client_if, client_conn, &nrf51_service_id, &char_id, sizeof(val), val, + ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + if (err != 0) + { + ESP_LOGE(TAG, "BLE charateristic write failed"); + } + toggle = 1; + ESP_LOGE(TAG, "BLE charateristic write on"); + } + else + { + uint8_t val[] = {'o', 'f', 'f'}; + esp_err_t err = + esp_ble_gattc_write_char(client_if, client_conn, &nrf51_service_id, &char_id, sizeof(val), val, + ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); + if (err != 0) + { + ESP_LOGE(TAG, "BLE charateristic write failed"); + } + toggle = 0; + ESP_LOGE(TAG, "BLE charateristic write off"); + } + } + vTaskDelay(2000 / portTICK_RATE_MS); + } + vTaskDelete(NULL); } void ble_client_appRegister(void) { LOG_INFO("register callback"); - //register the scan callback function to the Generic Access Profile (GAP) module - if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) { + // register the scan callback function to the Generic Access Profile (GAP) + // module + if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) + { LOG_ERROR("gap register error, error code = %x", status); return; } - //register the callback function to the Generic Attribute Profile (GATT) Client (GATTC) module - if ((status = esp_ble_gattc_register_callback(esp_gattc_cb)) != ESP_OK) { + // register the callback function to the Generic Attribute Profile (GATT) + // Client (GATTC) module + if ((status = esp_ble_gattc_register_callback(esp_gattc_cb)) != ESP_OK) + { LOG_ERROR("gattc register error, error code = %x", status); return; } @@ -665,6 +855,5 @@ void app_main() esp_bt_controller_enable(ESP_BT_MODE_BTDM); gattc_client_test(); - xTaskCreate(&led_task, "led_task", 2048, NULL, 6, &ledTaskHandle); + xTaskCreate(&led_task, "led_task", 2048, NULL, 6, &ledTaskHandle); } - diff --git a/LuaNode_Esp32/LuaNode32/examples/free80211send/app_main.c b/LuaNode_Esp32/LuaNode32/examples/free80211send/app_main.c index 7cdaa66..179e78c 100644 --- a/LuaNode_Esp32/LuaNode32/examples/free80211send/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/free80211send/app_main.c @@ -1,42 +1,77 @@ -#include "freertos/FreeRTOS.h" - +#include "esp_event.h" #include "esp_event_loop.h" #include "esp_system.h" -#include "esp_event.h" #include "esp_wifi.h" - +#include "free80211.h" +#include "freertos/FreeRTOS.h" #include "nvs_flash.h" #include "string.h" -#include "free80211.h" - uint8_t beacon_raw[] = { - 0x80, 0x00, // 0-1: Frame Control - 0x00, 0x00, // 2-3: Duration - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 4-9: Destination address (broadcast) - 0xba, 0xde, 0xaf, 0xfe, 0x00, 0x06, // 10-15: Source address - 0xba, 0xde, 0xaf, 0xfe, 0x00, 0x06, // 16-21: BSSID - 0x00, 0x00, // 22-23: Sequence / fragment number - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 24-31: Timestamp (GETS OVERWRITTEN TO 0 BY HARDWARE) - 0x64, 0x00, // 32-33: Beacon interval - 0x31, 0x04, // 34-35: Capability info - 0x00, 0x00, /* FILL CONTENT HERE */ // 36-38: SSID parameter set, 0x00:length:content - 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, // 39-48: Supported rates - 0x03, 0x01, 0x01, // 49-51: DS Parameter set, current channel 1 (= 0x01), - 0x05, 0x04, 0x01, 0x02, 0x00, 0x00, // 52-57: Traffic Indication Map - + 0x80, + 0x00, // 0-1: Frame Control + 0x00, + 0x00, // 2-3: Duration + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, // 4-9: Destination address (broadcast) + 0xba, + 0xde, + 0xaf, + 0xfe, + 0x00, + 0x06, // 10-15: Source address + 0xba, + 0xde, + 0xaf, + 0xfe, + 0x00, + 0x06, // 16-21: BSSID + 0x00, + 0x00, // 22-23: Sequence / fragment number + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, // 24-31: Timestamp (GETS OVERWRITTEN TO 0 BY HARDWARE) + 0x64, + 0x00, // 32-33: Beacon interval + 0x31, + 0x04, // 34-35: Capability info + 0x00, + 0x00, + /* FILL CONTENT HERE */ // 36-38: SSID parameter set, 0x00:length:content + 0x01, + 0x08, + 0x82, + 0x84, + 0x8b, + 0x96, + 0x0c, + 0x12, + 0x18, + 0x24, // 39-48: Supported rates + 0x03, + 0x01, + 0x01, // 49-51: DS Parameter set, current channel 1 (= 0x01), + 0x05, + 0x04, + 0x01, + 0x02, + 0x00, + 0x00, // 52-57: Traffic Indication Map + }; char *rick_ssids[] = { - "01 Never gonna give you up", - "02 Never gonna let you down", - "03 Never gonna run around", - "04 and desert you", - "05 Never gonna make you cry", - "06 Never gonna say goodbye", - "07 Never gonna tell a lie", - "08 and hurt you" -}; + "01 Never gonna give you up", "02 Never gonna let you down", "03 Never gonna run around", "04 and desert you", + "05 Never gonna make you cry", "06 Never gonna say goodbye", "07 Never gonna tell a lie", "08 and hurt you"}; #define BEACON_SSID_OFFSET 38 #define SRCADDR_OFFSET 10 @@ -44,74 +79,74 @@ char *rick_ssids[] = { #define SEQNUM_OFFSET 22 #define TOTAL_LINES (sizeof(rick_ssids) / sizeof(char *)) -esp_err_t event_handler(void *ctx, system_event_t *event) { - return ESP_OK; -} +esp_err_t event_handler(void *ctx, system_event_t *event) { return ESP_OK; } -void spam_task(void *pvParameter) { - uint8_t line = 0; +void spam_task(void *pvParameter) +{ + uint8_t line = 0; - // Keep track of beacon sequence numbers on a per-songline-basis - uint16_t seqnum[TOTAL_LINES] = { 0 }; + // Keep track of beacon sequence numbers on a per-songline-basis + uint16_t seqnum[TOTAL_LINES] = {0}; - for (;;) { - vTaskDelay(100 / TOTAL_LINES / portTICK_PERIOD_MS); + for (;;) + { + vTaskDelay(100 / TOTAL_LINES / portTICK_PERIOD_MS); - // Insert line of Rick Astley's "Never Gonna Give You Up" into beacon packet - printf("%i %i %s\r\n", strlen(rick_ssids[line]), TOTAL_LINES, rick_ssids[line]); + // Insert line of Rick Astley's "Never Gonna Give You Up" into beacon + // packet + printf("%i %i %s\r\n", strlen(rick_ssids[line]), TOTAL_LINES, rick_ssids[line]); - uint8_t beacon_rick[200]; - memcpy(beacon_rick, beacon_raw, BEACON_SSID_OFFSET - 1); - beacon_rick[BEACON_SSID_OFFSET - 1] = strlen(rick_ssids[line]); - memcpy(&beacon_rick[BEACON_SSID_OFFSET], rick_ssids[line], strlen(rick_ssids[line])); - memcpy(&beacon_rick[BEACON_SSID_OFFSET + strlen(rick_ssids[line])], &beacon_raw[BEACON_SSID_OFFSET], sizeof(beacon_raw) - BEACON_SSID_OFFSET); + uint8_t beacon_rick[200]; + memcpy(beacon_rick, beacon_raw, BEACON_SSID_OFFSET - 1); + beacon_rick[BEACON_SSID_OFFSET - 1] = strlen(rick_ssids[line]); + memcpy(&beacon_rick[BEACON_SSID_OFFSET], rick_ssids[line], strlen(rick_ssids[line])); + memcpy(&beacon_rick[BEACON_SSID_OFFSET + strlen(rick_ssids[line])], &beacon_raw[BEACON_SSID_OFFSET], + sizeof(beacon_raw) - BEACON_SSID_OFFSET); - // Last byte of source address / BSSID will be line number - emulate multiple APs broadcasting one song line each - beacon_rick[SRCADDR_OFFSET + 5] = line; - beacon_rick[BSSID_OFFSET + 5] = line; + // Last byte of source address / BSSID will be line number - emulate + // multiple APs broadcasting one song line each + beacon_rick[SRCADDR_OFFSET + 5] = line; + beacon_rick[BSSID_OFFSET + 5] = line; - // Update sequence number - beacon_rick[SEQNUM_OFFSET] = (seqnum[line] & 0x0f) << 4; - beacon_rick[SEQNUM_OFFSET + 1] = (seqnum[line] & 0xff0) >> 4; - seqnum[line]++; - if (seqnum[line] > 0xfff) - seqnum[line] = 0; + // Update sequence number + beacon_rick[SEQNUM_OFFSET] = (seqnum[line] & 0x0f) << 4; + beacon_rick[SEQNUM_OFFSET + 1] = (seqnum[line] & 0xff0) >> 4; + seqnum[line]++; + if (seqnum[line] > 0xfff) + seqnum[line] = 0; - free80211_send(beacon_rick, sizeof(beacon_raw) + strlen(rick_ssids[line])); + free80211_send(beacon_rick, sizeof(beacon_raw) + strlen(rick_ssids[line])); - if (++line >= TOTAL_LINES) - line = 0; - } + if (++line >= TOTAL_LINES) + line = 0; + } } -void app_main(void) { - nvs_flash_init(); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - - // Init dummy AP to get WiFi hardware into a mode where we can send the actual - // fake beacon frames. - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - wifi_config_t ap_config = { - .ap = { - .ssid = "esp32-beaconspam", - .ssid_len = 0, - .password = "dummypassword", - .channel = 1, - .authmode = WIFI_AUTH_WPA2_PSK, - .ssid_hidden = 1, - .max_connection = 4, - .beacon_interval = 60000 - } - }; - - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); - - xTaskCreate(&spam_task, "spam_task", 2048, NULL, 5, NULL); +void app_main(void) +{ + nvs_flash_init(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + + // Init dummy AP to get WiFi hardware into a mode where we can send the + // actual fake beacon frames. + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + wifi_config_t ap_config = {.ap = {.ssid = "esp32-beaconspam", + .ssid_len = 0, + .password = "dummypassword", + .channel = 1, + .authmode = WIFI_AUTH_WPA2_PSK, + .ssid_hidden = 1, + .max_connection = 4, + .beacon_interval = 60000}}; + + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); + + xTaskCreate(&spam_task, "spam_task", 2048, NULL, 5, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/json/main/main.c b/LuaNode_Esp32/LuaNode32/examples/json/main/main.c index d491545..e005311 100644 --- a/LuaNode_Esp32/LuaNode32/examples/json/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/json/main/main.c @@ -5,115 +5,127 @@ #include #include -#include "esp_log.h" -#include "cJSON.h" +#include "cJSON.h" +#include "esp_log.h" static const char *TAG = "main"; // return unformated json string static char *json_encode(void) { - cJSON *json = cJSON_CreateObject(); - cJSON_AddStringToObject(json, "name", "Jack"); - - cJSON *subArray = cJSON_CreateArray(); - - cJSON *subItem1 = cJSON_CreateObject(); - cJSON_AddStringToObject(subItem1, "sex", "male"); - cJSON *subItem2 = cJSON_CreateObject(); - cJSON_AddStringToObject(subItem2, "address", "Beijing"); - cJSON *subItem3 = cJSON_CreateObject(); - cJSON_AddBoolToObject(subItem3, "has_children", true); - cJSON *subItem4 = cJSON_CreateObject(); - cJSON_AddItemToObject(subItem4, "weight", cJSON_CreateNumber(62)); // or cJSON_AddNumberToObject(subItem4, 62) - cJSON *subItem5 = cJSON_CreateObject(); - cJSON_AddItemToObject(subItem5, "height", cJSON_CreateDouble(1.80, 2)); - - cJSON_AddItemToArray(subArray, subItem1); - cJSON_AddItemToArray(subArray, subItem2); - cJSON_AddItemToArray(subArray, subItem3); - cJSON_AddItemToArray(subArray, subItem4); - cJSON_AddItemToArray(subArray, subItem5); - - cJSON_AddItemToObject(json, "subArray", subArray); - - char *formated_str = cJSON_Print(json); - char *unformated_str = cJSON_PrintUnformatted(json); - ESP_LOGI(TAG, "----------- formated -----------"); - ESP_LOGI(TAG, "%s", formated_str); - ESP_LOGI(TAG, "----------- unformated -----------"); - ESP_LOGI(TAG, "%s", unformated_str); - - free(formated_str); // do not forget to free string buffer - - if ( NULL != json ) { - cJSON_Delete(json); - json = NULL; + cJSON *json = cJSON_CreateObject(); + cJSON_AddStringToObject(json, "name", "Jack"); + + cJSON *subArray = cJSON_CreateArray(); + + cJSON *subItem1 = cJSON_CreateObject(); + cJSON_AddStringToObject(subItem1, "sex", "male"); + cJSON *subItem2 = cJSON_CreateObject(); + cJSON_AddStringToObject(subItem2, "address", "Beijing"); + cJSON *subItem3 = cJSON_CreateObject(); + cJSON_AddBoolToObject(subItem3, "has_children", true); + cJSON *subItem4 = cJSON_CreateObject(); + cJSON_AddItemToObject(subItem4, "weight", + cJSON_CreateNumber(62)); // or cJSON_AddNumberToObject(subItem4, 62) + cJSON *subItem5 = cJSON_CreateObject(); + cJSON_AddItemToObject(subItem5, "height", cJSON_CreateDouble(1.80, 2)); + + cJSON_AddItemToArray(subArray, subItem1); + cJSON_AddItemToArray(subArray, subItem2); + cJSON_AddItemToArray(subArray, subItem3); + cJSON_AddItemToArray(subArray, subItem4); + cJSON_AddItemToArray(subArray, subItem5); + + cJSON_AddItemToObject(json, "subArray", subArray); + + char *formated_str = cJSON_Print(json); + char *unformated_str = cJSON_PrintUnformatted(json); + ESP_LOGI(TAG, "----------- formated -----------"); + ESP_LOGI(TAG, "%s", formated_str); + ESP_LOGI(TAG, "----------- unformated -----------"); + ESP_LOGI(TAG, "%s", unformated_str); + + free(formated_str); // do not forget to free string buffer + + if (NULL != json) + { + cJSON_Delete(json); + json = NULL; } - return unformated_str; + return unformated_str; } static void json_decode(char *unformated_string) { - int i; - cJSON *json = cJSON_Parse(unformated_string); - if ( NULL != json ) { - cJSON *temp = cJSON_GetObjectItem(json, "name"); - if (NULL != temp) { - ESP_LOGI(TAG, "name : %s", temp->valuestring); - } - - temp = cJSON_GetObjectItem(json, "subArray"); - if (NULL != temp) { - ESP_LOGI(TAG, "subArray : ["); - int len = cJSON_GetArraySize(temp); - for (i = 0; i < len; i++) { - cJSON *subItem = cJSON_GetArrayItem(temp, i); - if (NULL != subItem) { - cJSON *sex = cJSON_GetObjectItem(subItem, "sex"); - if (NULL != sex) { - ESP_LOGI(TAG, "\tsex : %s", sex->valuestring); - } - cJSON *addr = cJSON_GetObjectItem(subItem, "address"); - if (NULL != addr) { - ESP_LOGI(TAG, "\taddress : %s", addr->valuestring); - } - cJSON *child = cJSON_GetObjectItem(subItem, "has_children"); - if (NULL != child) { - switch (child->type) - { - case cJSON_False: - ESP_LOGI(TAG, "\thas_children : false"); - break; - case cJSON_True: - ESP_LOGI(TAG, "\thas_children : true"); - break; - } - } - cJSON *weight = cJSON_GetObjectItem(subItem, "weight"); - if (NULL != weight) { - ESP_LOGI(TAG, "\tweight : %d", weight->valueint); - } - cJSON *height = cJSON_GetObjectItem(subItem, "height"); - if (NULL != height) { - ESP_LOGI(TAG, "\theight : %lf", height->valuedouble); - } - } - } - ESP_LOGI(TAG, "]"); - } - } + int i; + cJSON *json = cJSON_Parse(unformated_string); + if (NULL != json) + { + cJSON *temp = cJSON_GetObjectItem(json, "name"); + if (NULL != temp) + { + ESP_LOGI(TAG, "name : %s", temp->valuestring); + } + + temp = cJSON_GetObjectItem(json, "subArray"); + if (NULL != temp) + { + ESP_LOGI(TAG, "subArray : ["); + int len = cJSON_GetArraySize(temp); + for (i = 0; i < len; i++) + { + cJSON *subItem = cJSON_GetArrayItem(temp, i); + if (NULL != subItem) + { + cJSON *sex = cJSON_GetObjectItem(subItem, "sex"); + if (NULL != sex) + { + ESP_LOGI(TAG, "\tsex : %s", sex->valuestring); + } + cJSON *addr = cJSON_GetObjectItem(subItem, "address"); + if (NULL != addr) + { + ESP_LOGI(TAG, "\taddress : %s", addr->valuestring); + } + cJSON *child = cJSON_GetObjectItem(subItem, "has_children"); + if (NULL != child) + { + switch (child->type) + { + case cJSON_False: + ESP_LOGI(TAG, "\thas_children : false"); + break; + case cJSON_True: + ESP_LOGI(TAG, "\thas_children : true"); + break; + } + } + cJSON *weight = cJSON_GetObjectItem(subItem, "weight"); + if (NULL != weight) + { + ESP_LOGI(TAG, "\tweight : %d", weight->valueint); + } + cJSON *height = cJSON_GetObjectItem(subItem, "height"); + if (NULL != height) + { + ESP_LOGI(TAG, "\theight : %lf", height->valuedouble); + } + } + } + ESP_LOGI(TAG, "]"); + } + } } void app_main(void) { - ESP_LOGI(TAG, "enter main"); - - char *json_str = json_encode(); - ESP_LOGI(TAG, "=================================="); - json_decode(json_str); + ESP_LOGI(TAG, "enter main"); + + char *json_str = json_encode(); + ESP_LOGI(TAG, "=================================="); + json_decode(json_str); - free(json_str); // do not forget to free string buffer + free(json_str); // do not forget to free string buffer } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/lcd_nokia5110_driver/app_main.c b/LuaNode_Esp32/LuaNode32/examples/lcd_nokia5110_driver/app_main.c index 6ff08b5..bf9f083 100644 --- a/LuaNode_Esp32/LuaNode32/examples/lcd_nokia5110_driver/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/lcd_nokia5110_driver/app_main.c @@ -1,206 +1,909 @@ -#include "esp_system.h" -#include "esp_log.h" #include "driver/gpio.h" - +#include "esp_log.h" +#include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#define GPIO_CE GPIO_NUM_2 -#define GPIO_RESET GPIO_NUM_4 -#define GPIO_DC GPIO_NUM_5 -#define GPIO_DIN GPIO_NUM_18 -#define GPIO_CLK GPIO_NUM_19 -#define GPIO_BL GPIO_NUM_21 +#define GPIO_CE GPIO_NUM_2 +#define GPIO_RESET GPIO_NUM_4 +#define GPIO_DC GPIO_NUM_5 +#define GPIO_DIN GPIO_NUM_18 +#define GPIO_CLK GPIO_NUM_19 +#define GPIO_BL GPIO_NUM_21 // delay seconds -#define DELAY(s) {vTaskDelay(1000 * s / portTICK_RATE_MS);} +#define DELAY(s) \ + { \ + vTaskDelay(1000 * s / portTICK_RATE_MS); \ + } static const char *TAG = "main"; -uint8_t shuzi[]={ -/*-- letter: 0 --*/ -0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, - -/*-- letter: 1 --*/ -0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, - -/*-- letter: 2 --*/ -0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, - -/*-- letter: 3 --*/ -0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, - -/*-- letter: 4 --*/ -0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, - -/*-- letter: 5 --*/ -0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, - -/*-- letter: 6 --*/ -0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, - -/*-- letter: 7 --*/ -0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, - -/*-- letter: 8 --*/ -0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, - -/*-- letter: 9 --*/ -0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, - -/*-- letter: a --10*/ -0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20, - -/*-- letter: b --11*/ -0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00, - -/*-- letter: c --12*/ -0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00, - -/*-- letter: d --13*/ -0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20, - -/*-- letter: e --*/ -0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00, - -/*-- letter: f --*/ -0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, - -/*-- letter: g --16*/ -0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00, - -/*-- letter: h --*/ -0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, - -/*-- letter: i --*/ -0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, - -/*-- letter: j --19*/ -0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00, - -/*-- letter: k --*/ -0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00, - -/*-- letter: l --*/ -0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, - -/*-- letter: m --22*/ -0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F, - -/*-- letter: n --23*/ -0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, +uint8_t shuzi[] = { + /*-- letter: 0 --*/ + 0x00, + 0xE0, + 0x10, + 0x08, + 0x08, + 0x10, + 0xE0, + 0x00, + 0x00, + 0x0F, + 0x10, + 0x20, + 0x20, + 0x10, + 0x0F, + 0x00, + + /*-- letter: 1 --*/ + 0x00, + 0x10, + 0x10, + 0xF8, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x20, + 0x3F, + 0x20, + 0x20, + 0x00, + 0x00, + + /*-- letter: 2 --*/ + 0x00, + 0x70, + 0x08, + 0x08, + 0x08, + 0x88, + 0x70, + 0x00, + 0x00, + 0x30, + 0x28, + 0x24, + 0x22, + 0x21, + 0x30, + 0x00, + + /*-- letter: 3 --*/ + 0x00, + 0x30, + 0x08, + 0x88, + 0x88, + 0x48, + 0x30, + 0x00, + 0x00, + 0x18, + 0x20, + 0x20, + 0x20, + 0x11, + 0x0E, + 0x00, + + /*-- letter: 4 --*/ + 0x00, + 0x00, + 0xC0, + 0x20, + 0x10, + 0xF8, + 0x00, + 0x00, + 0x00, + 0x07, + 0x04, + 0x24, + 0x24, + 0x3F, + 0x24, + 0x00, + + /*-- letter: 5 --*/ + 0x00, + 0xF8, + 0x08, + 0x88, + 0x88, + 0x08, + 0x08, + 0x00, + 0x00, + 0x19, + 0x21, + 0x20, + 0x20, + 0x11, + 0x0E, + 0x00, + + /*-- letter: 6 --*/ + 0x00, + 0xE0, + 0x10, + 0x88, + 0x88, + 0x18, + 0x00, + 0x00, + 0x00, + 0x0F, + 0x11, + 0x20, + 0x20, + 0x11, + 0x0E, + 0x00, + + /*-- letter: 7 --*/ + 0x00, + 0x38, + 0x08, + 0x08, + 0xC8, + 0x38, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + 0x3F, + 0x00, + 0x00, + 0x00, + 0x00, + + /*-- letter: 8 --*/ + 0x00, + 0x70, + 0x88, + 0x08, + 0x08, + 0x88, + 0x70, + 0x00, + 0x00, + 0x1C, + 0x22, + 0x21, + 0x21, + 0x22, + 0x1C, + 0x00, + + /*-- letter: 9 --*/ + 0x00, + 0xE0, + 0x10, + 0x08, + 0x08, + 0x10, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x31, + 0x22, + 0x22, + 0x11, + 0x0F, + 0x00, + + /*-- letter: a --10*/ + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x19, + 0x24, + 0x22, + 0x22, + 0x22, + 0x3F, + 0x20, + + /*-- letter: b --11*/ + 0x08, + 0xF8, + 0x00, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x3F, + 0x11, + 0x20, + 0x20, + 0x11, + 0x0E, + 0x00, + + /*-- letter: c --12*/ + 0x00, + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x0E, + 0x11, + 0x20, + 0x20, + 0x20, + 0x11, + 0x00, + + /*-- letter: d --13*/ + 0x00, + 0x00, + 0x00, + 0x80, + 0x80, + 0x88, + 0xF8, + 0x00, + 0x00, + 0x0E, + 0x11, + 0x20, + 0x20, + 0x10, + 0x3F, + 0x20, + + /*-- letter: e --*/ + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x1F, + 0x22, + 0x22, + 0x22, + 0x22, + 0x13, + 0x00, + + /*-- letter: f --*/ + 0x00, + 0x80, + 0x80, + 0xF0, + 0x88, + 0x88, + 0x88, + 0x18, + 0x00, + 0x20, + 0x20, + 0x3F, + 0x20, + 0x20, + 0x00, + 0x00, + + /*-- letter: g --16*/ + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x6B, + 0x94, + 0x94, + 0x94, + 0x93, + 0x60, + 0x00, + + /*-- letter: h --*/ + 0x08, + 0xF8, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x20, + 0x3F, + 0x21, + 0x00, + 0x00, + 0x20, + 0x3F, + 0x20, + + /*-- letter: i --*/ + 0x00, + 0x80, + 0x98, + 0x98, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x20, + 0x3F, + 0x20, + 0x20, + 0x00, + 0x00, + + /*-- letter: j --19*/ + 0x00, + 0x00, + 0x00, + 0x80, + 0x98, + 0x98, + 0x00, + 0x00, + 0x00, + 0xC0, + 0x80, + 0x80, + 0x80, + 0x7F, + 0x00, + 0x00, + + /*-- letter: k --*/ + 0x08, + 0xF8, + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x20, + 0x3F, + 0x24, + 0x02, + 0x2D, + 0x30, + 0x20, + 0x00, + + /*-- letter: l --*/ + 0x00, + 0x08, + 0x08, + 0xF8, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x20, + 0x3F, + 0x20, + 0x20, + 0x00, + 0x00, + + /*-- letter: m --22*/ + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x20, + 0x3F, + 0x20, + 0x00, + 0x3F, + 0x20, + 0x00, + 0x3F, + + /*-- letter: n --23*/ + 0x80, + 0x80, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x20, + 0x3F, + 0x21, + 0x00, + 0x00, + 0x20, + 0x3F, + 0x20, + + /*-- letter: o --24*/ + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x1F, + 0x20, + 0x20, + 0x20, + 0x20, + 0x1F, + 0x00, + + /*-- letter: p --*/ + 0x80, + 0x80, + 0x00, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x80, + 0xFF, + 0xA1, + 0x20, + 0x20, + 0x11, + 0x0E, + 0x00, + + /*-- letter: q --*/ + 0x00, + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x0E, + 0x11, + 0x20, + 0x20, + 0xA0, + 0xFF, + 0x80, + + /*-- letter: r --*/ + 0x80, + 0x80, + 0x80, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x20, + 0x20, + 0x3F, + 0x21, + 0x20, + 0x00, + 0x01, + 0x00, + + /*-- letter: s --*/ + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x33, + 0x24, + 0x24, + 0x24, + 0x24, + 0x19, + 0x00, + + /*-- letter: t --*/ + 0x00, + 0x80, + 0x80, + 0xE0, + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x1F, + 0x20, + 0x20, + 0x00, + 0x00, + + /*-- letter: u --30*/ + 0x80, + 0x80, + 0x00, + 0x00, + 0x00, + 0x80, + 0x80, + 0x00, + 0x00, + 0x1F, + 0x20, + 0x20, + 0x20, + 0x10, + 0x3F, + 0x20, + + /*-- letter: v --*/ + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x01, + 0x0E, + 0x30, + 0x08, + 0x06, + 0x01, + 0x00, + + /*-- letter: w --*/ + 0x80, + 0x80, + 0x00, + 0x80, + 0x00, + 0x80, + 0x80, + 0x80, + 0x0F, + 0x30, + 0x0C, + 0x03, + 0x0C, + 0x30, + 0x0F, + 0x00, + + /*-- letter: x --*/ + 0x00, + 0x80, + 0x80, + 0x00, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x20, + 0x31, + 0x2E, + 0x0E, + 0x31, + 0x20, + 0x00, + + /*-- letter: y --*/ + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x81, + 0x8E, + 0x70, + 0x18, + 0x06, + 0x01, + 0x00, + + /*-- letter: z --35*/ + 0x00, + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x80, + 0x00, + 0x00, + 0x21, + 0x30, + 0x2C, + 0x22, + 0x21, + 0x30, + 0x00, + + /*-- letter: - --*/ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + + /*-- letter: = --*/ + 0x40, + 0x40, + 0x40, + 0x40, + 0x40, + 0x40, + 0x40, + 0x00, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x00, + + /*-- letter: \ --*/ + 0x00, + 0x0C, + 0x30, + 0xC0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x06, + 0x38, + 0xC0, + 0x00, + + /*-- letter: --39*/ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /*-- letter: [ --*/ + 0x00, + 0x00, + 0x00, + 0xFE, + 0x02, + 0x02, + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x40, + 0x40, + 0x40, + 0x00, + + /*-- letter: ] --*/ + 0x00, + 0x02, + 0x02, + 0x02, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x40, + 0x40, + 0x7F, + 0x00, + 0x00, + 0x00, + + /*-- letter: ; --*/ + 0x00, + 0x00, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x80, + 0x60, + 0x00, + 0x00, + 0x00, + 0x00, + + /*-- letter: ' --*/ + 0x10, + 0x16, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /*-- letter: , --*/ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x80, + 0xB0, + 0x70, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /*-- letter: . --45*/ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x30, + 0x30, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + + /*-- letter: / --*/ + 0x00, + 0x00, + 0x00, + 0x00, + 0x80, + 0x60, + 0x18, + 0x04, + 0x00, + 0x60, + 0x18, + 0x06, + 0x01, + 0x00, + 0x00, + 0x00, -/*-- letter: o --24*/ -0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00, - -/*-- letter: p --*/ -0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00, - -/*-- letter: q --*/ -0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80, - -/*-- letter: r --*/ -0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00, - -/*-- letter: s --*/ -0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00, - -/*-- letter: t --*/ -0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00, - -/*-- letter: u --30*/ -0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20, - -/*-- letter: v --*/ -0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00, - -/*-- letter: w --*/ -0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00, - -/*-- letter: x --*/ -0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00, - -/*-- letter: y --*/ -0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00, - -/*-- letter: z --35*/ -0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00, - -/*-- letter: - --*/ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - -/*-- letter: = --*/ -0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00, - -/*-- letter: \ --*/ -0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00, - -/*-- letter: --39*/ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - -/*-- letter: [ --*/ -0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00, - -/*-- letter: ] --*/ -0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, - -/*-- letter: ; --*/ -0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00, - -/*-- letter: ' --*/ -0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - -/*-- letter: , --*/ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00, - -/*-- letter: . --45*/ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00, - -/*-- letter: / --*/ -0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00, - }; void lcd_write_byte(uint8_t dat, uint8_t command) { - int i; - gpio_set_level(GPIO_CE, 0); - gpio_set_level(GPIO_DC, command); - for(i = 0; i < 8; i++) { - if(dat & 0x80) { - gpio_set_level(GPIO_DIN, 1); - } else { - gpio_set_level(GPIO_DIN, 0); - } - dat = dat << 1; - gpio_set_level(GPIO_CLK, 0); - gpio_set_level(GPIO_CLK, 1); - } - gpio_set_level(GPIO_DC, 1); - gpio_set_level(GPIO_CE, 1); - gpio_set_level(GPIO_DIN, 1); + int i; + gpio_set_level(GPIO_CE, 0); + gpio_set_level(GPIO_DC, command); + for (i = 0; i < 8; i++) + { + if (dat & 0x80) + { + gpio_set_level(GPIO_DIN, 1); + } + else + { + gpio_set_level(GPIO_DIN, 0); + } + dat = dat << 1; + gpio_set_level(GPIO_CLK, 0); + gpio_set_level(GPIO_CLK, 1); + } + gpio_set_level(GPIO_DC, 1); + gpio_set_level(GPIO_CE, 1); + gpio_set_level(GPIO_DIN, 1); } void pin_init(void) { - int i; - gpio_num_t pins[] = { - GPIO_CE, - GPIO_RESET, - GPIO_DC, - GPIO_DIN, - GPIO_CLK, - GPIO_BL - }; - - gpio_config_t conf = { - .mode = GPIO_MODE_OUTPUT, - .pull_up_en = GPIO_PULLUP_DISABLE, - .pull_down_en = GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE - }; - - for (i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) { + int i; + gpio_num_t pins[] = {GPIO_CE, GPIO_RESET, GPIO_DC, GPIO_DIN, GPIO_CLK, GPIO_BL}; + + gpio_config_t conf = {.mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE}; + + for (i = 0; i < sizeof(pins) / sizeof(gpio_num_t); ++i) + { conf.pin_bit_mask = 1LL << pins[i]; gpio_config(&conf); } @@ -208,79 +911,74 @@ void pin_init(void) void lcd_init(void) { - ESP_LOGI(TAG, "LCD init"); - gpio_set_level(GPIO_BL, 1); - lcd_write_byte(0x21,0); - lcd_write_byte(0xd0,0); - lcd_write_byte(0x20,0); - lcd_write_byte(0x0C,0); + ESP_LOGI(TAG, "LCD init"); + gpio_set_level(GPIO_BL, 1); + lcd_write_byte(0x21, 0); + lcd_write_byte(0xd0, 0); + lcd_write_byte(0x20, 0); + lcd_write_byte(0x0C, 0); } void lcd_set_xy(unsigned char x, unsigned char y) { - lcd_write_byte(0x40 | y, 0);// column - lcd_write_byte(0x80 | x, 0);// row + lcd_write_byte(0x40 | y, 0); // column + lcd_write_byte(0x80 | x, 0); // row } void clear_screen(void) { - uint8_t t, k; - lcd_set_xy(0, 0); - for(t = 0; t < 6; t++) { - for(k = 0; k < 84; k++) { - lcd_write_byte(0x00, 1); - } - } + uint8_t t, k; + lcd_set_xy(0, 0); + for (t = 0; t < 6; t++) + { + for (k = 0; k < 84; k++) { lcd_write_byte(0x00, 1); } + } } void lcd_write_letter(uint8_t row, uint8_t page, uint8_t c) { - int i; - - lcd_set_xy(row*8, page); - for(i = 0; i < 8; i++) { - lcd_write_byte(shuzi[c*16+i],1); - } - - lcd_set_xy(row*8, page+1); - for(i = 8; i < 16; i++) { - lcd_write_byte(shuzi[c*16+i],1); - } + int i; + + lcd_set_xy(row * 8, page); + for (i = 0; i < 8; i++) { lcd_write_byte(shuzi[c * 16 + i], 1); } + + lcd_set_xy(row * 8, page + 1); + for (i = 8; i < 16; i++) { lcd_write_byte(shuzi[c * 16 + i], 1); } } void app_main() { - DELAY(1); - gpio_set_level(GPIO_RESET, 0); - DELAY(0.5); - gpio_set_level(GPIO_RESET, 1); - DELAY(0.5); - pin_init(); - lcd_init(); - clear_screen(); - - - /*lcd_write_letter(1, 2, 13); //d - lcd_write_letter(2, 2, 24); //o - lcd_write_letter(3, 2, 18); //i - lcd_write_letter(4, 2, 29); //t - lcd_write_letter(5, 2, 45); //. - lcd_write_letter(6, 2, 10); //a - lcd_write_letter(7, 2, 22); //m - */ - lcd_write_letter(1, 1, 17); //h - lcd_write_letter(2, 1, 14); //e - lcd_write_letter(3, 1, 21); //l - lcd_write_letter(4, 1, 21); //l - lcd_write_letter(5, 1, 24); //o - lcd_write_letter(3, 3, 32); //w - lcd_write_letter(4, 3, 24); //o - lcd_write_letter(5, 3, 27); //r - lcd_write_letter(6, 3, 21); //l - lcd_write_letter(7, 3, 13); //d - - while (1) { - ESP_LOGI(TAG, "main loop"); - DELAY(3); - } + DELAY(1); + gpio_set_level(GPIO_RESET, 0); + DELAY(0.5); + gpio_set_level(GPIO_RESET, 1); + DELAY(0.5); + pin_init(); + lcd_init(); + clear_screen(); + + /*lcd_write_letter(1, 2, 13); //d + lcd_write_letter(2, 2, 24); //o + lcd_write_letter(3, 2, 18); //i + lcd_write_letter(4, 2, 29); //t + lcd_write_letter(5, 2, 45); //. + lcd_write_letter(6, 2, 10); //a + lcd_write_letter(7, 2, 22); //m + */ + lcd_write_letter(1, 1, 17); // h + lcd_write_letter(2, 1, 14); // e + lcd_write_letter(3, 1, 21); // l + lcd_write_letter(4, 1, 21); // l + lcd_write_letter(5, 1, 24); // o + lcd_write_letter(3, 3, 32); // w + lcd_write_letter(4, 3, 24); // o + lcd_write_letter(5, 3, 27); // r + lcd_write_letter(6, 3, 21); // l + lcd_write_letter(7, 3, 13); // d + + while (1) + { + ESP_LOGI(TAG, "main loop"); + DELAY(3); + } } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c b/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c index 730cab3..9a5f09f 100644 --- a/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/lwip_raw_api/app_main.c @@ -1,31 +1,31 @@ /** - * This is a LwIP Raw API sample. The sample create a TCP server listen port 11000. - * When received data, the server send the data back to client. + * This is a LwIP Raw API sample. The sample create a TCP server listen port + *11000. When received data, the server send the data back to client. * * Nicholas3388 **/ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "nvs_flash.h" +#include "esp_wifi.h" #include "espconn.h" -#include "tmr.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" #include "lwip/tcp.h" +#include "nvs_flash.h" +#include "tmr.h" -#define FEEDBACK_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define TCP_TASK_PRIORITY 12 -#define LOCAL_PORT 11000 -#define REMOTE_PORT 6000 +#define FEEDBACK_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define TCP_TASK_PRIORITY 12 +#define LOCAL_PORT 11000 +#define REMOTE_PORT 6000 static EventGroupHandle_t wifi_event_group; const int CONNECTED_BIT = BIT0; @@ -33,114 +33,120 @@ static const char *TAG = "main"; static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, }; - tcpip_adapter_init(); + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static err_t tcp_server_sent(void *arg, struct tcp_pcb *pcb, u16_t len) { - ESP_LOGI(TAG, "sent data"); - return ERR_OK; + ESP_LOGI(TAG, "sent data"); + return ERR_OK; } static err_t tcp_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { - ESP_LOGI(TAG, "received data"); - if (err == ERR_OK && p != NULL) { - uint8_t *data_ptr = NULL; - u32_t data_cntr = 0; - data_ptr = (uint8_t *)malloc(p ->tot_len + 1); - memset(data_ptr, 0, p->tot_len + 1); - data_cntr = pbuf_copy_partial(p, data_ptr, p ->tot_len, 0); + ESP_LOGI(TAG, "received data"); + if (err == ERR_OK && p != NULL) + { + uint8_t *data_ptr = NULL; + u32_t data_cntr = 0; + data_ptr = (uint8_t *)malloc(p->tot_len + 1); + memset(data_ptr, 0, p->tot_len + 1); + data_cntr = pbuf_copy_partial(p, data_ptr, p->tot_len, 0); pbuf_free(p); - if (data_cntr != 0) { - ESP_LOGI(TAG, "content: %s", data_ptr); - tcp_write(pcb, data_ptr, data_cntr, 1); // data is not sent yet, until tcp_output called - tcp_output(pcb); - } - free(data_ptr); + if (data_cntr != 0) + { + ESP_LOGI(TAG, "content: %s", data_ptr); + tcp_write(pcb, data_ptr, data_cntr, + 1); // data is not sent yet, until tcp_output called + tcp_output(pcb); + } + free(data_ptr); data_ptr = NULL; - } - return ERR_OK; + } + return ERR_OK; } static err_t tcp_server_poll(void *arg, struct tcp_pcb *pcb) { - ESP_LOGI(TAG, "poll"); - return ERR_OK; + ESP_LOGI(TAG, "poll"); + return ERR_OK; } static err_t tcp_accept_callback(void *arg, struct tcp_pcb *pcb, err_t err) { - ESP_LOGI(TAG, "client try connecting"); - tcp_sent(pcb, tcp_server_sent); - tcp_recv(pcb, tcp_server_recv); - tcp_poll(pcb, tcp_server_poll, 8); /* every 1 seconds */ - return ERR_OK; + ESP_LOGI(TAG, "client try connecting"); + tcp_sent(pcb, tcp_server_sent); + tcp_recv(pcb, tcp_server_recv); + tcp_poll(pcb, tcp_server_poll, 8); /* every 1 seconds */ + return ERR_OK; } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - struct tcp_pcb *pcb = tcp_new(); - if (pcb == NULL) { - ESP_LOGI(TAG, "tcp_pcb create failed"); - break; - } - tcp_bind(pcb, IP_ADDR_ANY, LOCAL_PORT); - pcb = tcp_listen(pcb); - //tcp_arg(pcb, (void *)params); - ESP_LOGI(TAG, "wait for client"); - tcp_accept(pcb, tcp_accept_callback); - break; - } - vTaskDelete(NULL); + struct tcp_pcb *pcb = tcp_new(); + if (pcb == NULL) + { + ESP_LOGI(TAG, "tcp_pcb create failed"); + break; + } + tcp_bind(pcb, IP_ADDR_ANY, LOCAL_PORT); + pcb = tcp_listen(pcb); + // tcp_arg(pcb, (void *)params); + ESP_LOGI(TAG, "wait for client"); + tcp_accept(pcb, tcp_accept_callback); + break; + } + vTaskDelete(NULL); } void app_main() { - nvs_flash_init(); + nvs_flash_init(); initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/ota/ota.c b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/ota/ota.c index 68fb553..45e052f 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/ota/ota.c +++ b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/ota/ota.c @@ -12,83 +12,82 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include -#include - #include "ota.h" -#include "user_config.h" -#include "utils.h" + +#include +#include #include "esp_log.h" #include "esp_ota_ops.h" #include "esp_partition.h" #include "esp_system.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" - #include "lwip/api.h" #include "lwip/sockets.h" +#include "user_config.h" +#include "utils.h" -#define PACKAGE_SIZE 512 // the server send 512 byte one time -#define RECV_BUFF_SIZE 768 +#define PACKAGE_SIZE 512 // the server send 512 byte one time +#define RECV_BUFF_SIZE 768 -#define KEY_TOTAL "total: " -#define KEY_LENGTH "length: " -#define HEADER_END "\r\n\r\n" -#define REQ_DATA "req0\r\n\r\n" -#define REQ_RESEND "req1\r\n\r\n" +#define KEY_TOTAL "total: " +#define KEY_LENGTH "length: " +#define HEADER_END "\r\n\r\n" +#define REQ_DATA "req0\r\n\r\n" +#define REQ_RESEND "req1\r\n\r\n" static const char *TAG = "ota"; static char recv_buff[RECV_BUFF_SIZE] = {0}; -static char ota_write_data[RECV_BUFF_SIZE] = { 0 }; +static char ota_write_data[RECV_BUFF_SIZE] = {0}; static char remote_ip[4] = {192, 168, 9, 154}; static int str2num(char *str, int len) { - int i, res = 0; - for (i = 0; i < len; i++) { - res += pow10(len - i - 1) * (str[i] - '0'); - } - return res; + int i, res = 0; + for (i = 0; i < len; i++) { res += pow10(len - i - 1) * (str[i] - '0'); } + return res; } static int get_length(char *s, int skip) { - int res = -1; - char *start = s + skip; - char buff[16] = {0}; - int i = 0; - while (*start != '\r' && *start != '\n') { - buff[i] = *start; - if (i > 16) { - ESP_LOGE(TAG, "total length is > 16"); - return -1; - } - i++; - start++; - } - res = str2num(buff, i); - - return res; + int res = -1; + char *start = s + skip; + char buff[16] = {0}; + int i = 0; + while (*start != '\r' && *start != '\n') + { + buff[i] = *start; + if (i > 16) + { + ESP_LOGE(TAG, "total length is > 16"); + return -1; + } + i++; + start++; + } + res = str2num(buff, i); + + return res; } static void ota_task(void *pvParameter) { - ESP_LOGI(TAG, "Starting OTA task..."); - esp_err_t err; - struct netbuf *recvbuf = NULL; - struct pbuf *q; - struct netconn *conn = NULL; - int data_len = 0; - int total_len = 0; - int recv_count = 0; - bool resend = false; - - /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */ - esp_ota_handle_t update_handle = 0 ; + ESP_LOGI(TAG, "Starting OTA task..."); + esp_err_t err; + struct netbuf *recvbuf = NULL; + struct pbuf *q; + struct netconn *conn = NULL; + int data_len = 0; + int total_len = 0; + int recv_count = 0; + bool resend = false; + + /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() + */ + esp_ota_handle_t update_handle = 0; const esp_partition_t *update_partition = NULL; ESP_LOGI(TAG, "Starting OTA example..."); @@ -96,144 +95,170 @@ static void ota_task(void *pvParameter) const esp_partition_t *configured = esp_ota_get_boot_partition(); const esp_partition_t *running = esp_ota_get_running_partition(); - assert(configured == running); /* fresh from reset, should be running from configured boot partition */ - ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", - configured->type, configured->subtype, configured->address); + assert(configured == running); /* fresh from reset, should be running from + configured boot partition */ + ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", configured->type, configured->subtype, + configured->address); - update_partition = esp_ota_get_next_update_partition(NULL); - ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", - update_partition->subtype, update_partition->address); + update_partition = esp_ota_get_next_update_partition(NULL); + ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype, + update_partition->address); assert(update_partition != NULL); err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle); - if (err != ESP_OK) { + if (err != ESP_OK) + { ESP_LOGE(TAG, "esp_ota_begin failed, error=%d", err); } ESP_LOGI(TAG, "esp_ota_begin succeeded"); + while ((conn = netconn_new(NETCONN_TCP)) == NULL) + { + ESP_LOGE(TAG, "Create conn failed"); + delay_ms(1000); + } + ip_addr_t serverip; + IP_ADDR4(&serverip, remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3]); + + netconn_bind(conn, NULL, LOCAL_PORT); + err_t er; + while ((er = netconn_connect(conn, &serverip, REMOTE_PORT)) != ERR_OK) + { + ESP_LOGE(TAG, "Connect server failed, error code: %d", er); + delay_ms(1000); + } + + while (1) + { + if (resend) + { + netconn_write(conn, REQ_RESEND, strlen(REQ_RESEND), + NETCONN_NOCOPY); // request server to send last package again + resend = false; + } + else + { + netconn_write(conn, REQ_DATA, strlen(REQ_DATA), + NETCONN_NOCOPY); // request server to send next package + } + + // ESP_LOGI(TAG, "waiting for server send data"); + netconn_recv(conn, &recvbuf); // wait for data comes + if (recvbuf != NULL) + { + // received data + memset(recv_buff, 0, RECV_BUFF_SIZE); + memset(ota_write_data, 0, RECV_BUFF_SIZE); + data_len = 0; + for (q = recvbuf->p; q != NULL; q = q->next) + { + if (q->len > (RECV_BUFF_SIZE - data_len)) + { + memcpy(recv_buff + data_len, q->payload, (RECV_BUFF_SIZE - data_len)); + } + else + { + memcpy(recv_buff + data_len, q->payload, q->len); + } + data_len += q->len; + if (data_len > RECV_BUFF_SIZE) + { + ESP_LOGE(TAG, "receive buffer overflow!!!"); + break; + } + } + + // ota handle here + // package format: "total: 123456\r\nlength: 123\r\n\r\n#@#$$%Q&#" + // package data start after "\r\n\r\n" + char *total_start; + char *pack_len_start; + char *data_start; + int pack_len = 0; + // extract total len + if (total_len == 0) + { + if ((total_start = strstr(recv_buff, KEY_TOTAL)) != NULL) + { + total_len = get_length(total_start, strlen(KEY_TOTAL)); + ESP_LOGI(TAG, "OTA file size: %d", total_len); + } + else + { + ESP_LOGE(TAG, "invalid package, resend later"); + netbuf_delete(recvbuf); + resend = true; + delay_ms(1000); + break; + } + } + + // extract current package length + if ((pack_len_start = strstr(recv_buff, KEY_LENGTH)) != NULL) + { + pack_len = get_length(pack_len_start, strlen(KEY_LENGTH)); + if ((data_start = strstr(recv_buff, HEADER_END)) != NULL) + { + data_start += strlen(HEADER_END); + memcpy(ota_write_data, data_start, pack_len); + err = esp_ota_write(update_handle, (const void *)ota_write_data, pack_len); + if (err != ESP_OK) + { + ESP_LOGE(TAG, + "Error: esp_ota_write failed! err=0x%x, " + "resend later", + err); + netbuf_delete(recvbuf); + resend = true; + delay_ms(1000); + break; + } + recv_count += pack_len; + printf("OTA progress: %%%d\r", (int)(recv_count * 100 / total_len)); + if (recv_count >= total_len) + { + printf("OTA progress: %%100\n"); + ESP_LOGI(TAG, "OTA recevied all data! OK"); + break; + } + } + } + else + { + ESP_LOGE(TAG, "invalid package length, resend later"); + netbuf_delete(recvbuf); + resend = true; + delay_ms(1000); + break; + } + + netbuf_delete(recvbuf); // do not forget to delete netbuf + recvbuf = NULL; + } + delay_ms(50); + } - while ((conn = netconn_new(NETCONN_TCP)) == NULL) { - ESP_LOGE(TAG, "Create conn failed"); - delay_ms(1000); - } - ip_addr_t serverip; - IP_ADDR4(&serverip, remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3]); - - netconn_bind(conn, NULL, LOCAL_PORT); - - err_t er; - while ((er = netconn_connect(conn, &serverip, REMOTE_PORT)) != ERR_OK) { - ESP_LOGE(TAG, "Connect server failed, error code: %d", er); - delay_ms(1000); - } - - while (1) - { - if (resend) { - netconn_write(conn, REQ_RESEND, strlen(REQ_RESEND), NETCONN_NOCOPY); // request server to send last package again - resend = false; - } else { - netconn_write(conn, REQ_DATA, strlen(REQ_DATA), NETCONN_NOCOPY); // request server to send next package - } - - //ESP_LOGI(TAG, "waiting for server send data"); - netconn_recv(conn, &recvbuf); // wait for data comes - if (recvbuf != NULL) { - // received data - memset(recv_buff, 0, RECV_BUFF_SIZE); - memset(ota_write_data, 0, RECV_BUFF_SIZE); - data_len = 0; - for(q=recvbuf->p; q!=NULL; q=q->next) { - if(q->len > (RECV_BUFF_SIZE-data_len)) { - memcpy(recv_buff+data_len, q->payload, (RECV_BUFF_SIZE-data_len)); - } else { - memcpy(recv_buff+data_len,q->payload,q->len); - } - data_len += q->len; - if(data_len > RECV_BUFF_SIZE) { - ESP_LOGE(TAG, "receive buffer overflow!!!"); - break; - } - } - - // ota handle here - // package format: "total: 123456\r\nlength: 123\r\n\r\n#@#$$%Q&#" package data start after "\r\n\r\n" - char *total_start; - char *pack_len_start; - char *data_start; - int pack_len = 0; - // extract total len - if (total_len == 0) { - if ((total_start = strstr(recv_buff, KEY_TOTAL)) != NULL) { - total_len = get_length(total_start, strlen(KEY_TOTAL)); - ESP_LOGI(TAG, "OTA file size: %d", total_len); - } else { - ESP_LOGE(TAG, "invalid package, resend later"); - netbuf_delete(recvbuf); - resend = true; - delay_ms(1000); - break; - } - } - - // extract current package length - if ((pack_len_start = strstr(recv_buff, KEY_LENGTH)) != NULL) { - pack_len = get_length(pack_len_start, strlen(KEY_LENGTH)); - if ((data_start = strstr(recv_buff, HEADER_END)) != NULL) { - data_start += strlen(HEADER_END); - memcpy(ota_write_data, data_start, pack_len); - err = esp_ota_write( update_handle, (const void *)ota_write_data, pack_len); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Error: esp_ota_write failed! err=0x%x, resend later", err); - netbuf_delete(recvbuf); - resend = true; - delay_ms(1000); - break; - } - recv_count += pack_len; - printf("OTA progress: %%%d\r", (int)(recv_count * 100 / total_len )); - if (recv_count >= total_len) { - printf("OTA progress: %%100\n"); - ESP_LOGI(TAG, "OTA recevied all data! OK"); - break; - } - } - } else { - ESP_LOGE(TAG, "invalid package length, resend later"); - netbuf_delete(recvbuf); - resend = true; - delay_ms(1000); - break; - } - - netbuf_delete(recvbuf); // do not forget to delete netbuf - recvbuf = NULL; - } - delay_ms(50); - } - - ESP_LOGI(TAG, "Total Write binary data length : %d", recv_count); - - if (esp_ota_end(update_handle) != ESP_OK) { + ESP_LOGI(TAG, "Total Write binary data length : %d", recv_count); + + if (esp_ota_end(update_handle) != ESP_OK) + { ESP_LOGE(TAG, "esp_ota_end failed!"); goto end_err_occur; } err = esp_ota_set_boot_partition(update_partition); - if (err != ESP_OK) { + if (err != ESP_OK) + { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err); goto end_err_occur; } ESP_LOGI(TAG, "Prepare to restart system!"); - esp_restart(); + esp_restart(); - ESP_LOGE(TAG, "some error ocurr"); - netbuf_delete(recvbuf); + ESP_LOGE(TAG, "some error ocurr"); + netbuf_delete(recvbuf); end_err_occur: - vTaskDelete(NULL); + vTaskDelete(NULL); } -void ota_init(void) -{ - xTaskCreate(&ota_task, "ota_task", OTA_TASK_STACK_SIZE, NULL, OTA_TASK_PRIO, NULL); -} \ No newline at end of file +void ota_init(void) { xTaskCreate(&ota_task, "ota_task", OTA_TASK_STACK_SIZE, NULL, OTA_TASK_PRIO, NULL); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/utils/utils.c b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/utils/utils.c index a6ca28d..4fc3815 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/utils/utils.c +++ b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/components/utils/utils.c @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "utils.h" + #include -#include "utils.h" #include "esp_log.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -24,21 +24,18 @@ static const char *TAG = "utils"; void printHex(char c) { - char buff[3] = {0x0}; - sprintf(buff, "%02X ", c); - ESP_LOGI(TAG, "%s", buff); + char buff[3] = {0x0}; + sprintf(buff, "%02X ", c); + ESP_LOGI(TAG, "%s", buff); } -void delay_ms(int ms) -{ - vTaskDelay(ms / portTICK_RATE_MS); -} +void delay_ms(int ms) { vTaskDelay(ms / portTICK_RATE_MS); } void ip_addr_to_num(unsigned char *res, ip_addr_t *addr) { - unsigned int ip = (addr->u_addr).ip4.addr; - res[0] = (unsigned char)(ip & 0xFF); - res[1] = (unsigned char)((ip >> 8) & 0xFF); - res[2] = (unsigned char)((ip >> 16) & 0xFF); - res[3] = (unsigned char)((ip >> 24) & 0xFF); + unsigned int ip = (addr->u_addr).ip4.addr; + res[0] = (unsigned char)(ip & 0xFF); + res[1] = (unsigned char)((ip >> 8) & 0xFF); + res[2] = (unsigned char)((ip >> 16) & 0xFF); + res[3] = (unsigned char)((ip >> 24) & 0xFF); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c index 7b6a6ad..c2b5c28 100644 --- a/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c +++ b/LuaNode_Esp32/LuaNode32/examples/ota_tcp_update/client/main/main.c @@ -18,21 +18,21 @@ * email: wangwei@doit.am */ -#include "ota.h" -#include "user_config.h" -#include "utils.h" - +#include "esp_event_loop.h" #include "esp_log.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/event_groups.h" +#include "freertos/task.h" +#include "ota.h" +#include "user_config.h" +#include "utils.h" static const char *TAG = "main"; -/* FreeRTOS event group to signal when we are connected & ready to make a request */ +/* FreeRTOS event group to signal when we are connected & ready to make a + * request */ static EventGroupHandle_t wifi_event_group; /* The event group allows multiple bits for each event, @@ -42,21 +42,22 @@ const int CONNECTED_BIT = BIT0; static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; } return ESP_OK; } @@ -65,36 +66,36 @@ static void initialise_wifi(void) { tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); wifi_config_t wifi_config = { - .sta = { - .ssid = WIFI_SSID, - .password = WIFI_PASS, - }, + .sta = + { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + }, }; ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static void tmp_task(void *pvParameter) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to OTA Server...."); - ota_init(); - vTaskDelete(NULL); + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to OTA Server...."); + ota_init(); + vTaskDelete(NULL); } void app_main(void) { - delay_ms(1000); - ESP_LOGI(TAG, "enter main"); - initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); - + delay_ms(1000); + ESP_LOGI(TAG, "enter main"); + initialise_wifi(); + xTaskCreate(&tmp_task, "tmp_task", TMP_TASK_STACK_SIZE, NULL, TMP_TASK_PRIO, NULL); } \ No newline at end of file diff --git a/LuaNode_Esp32/LuaNode32/examples/raw_flash_rw/app_main.c b/LuaNode_Esp32/LuaNode32/examples/raw_flash_rw/app_main.c index bc433a5..8c894d9 100644 --- a/LuaNode_Esp32/LuaNode32/examples/raw_flash_rw/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/raw_flash_rw/app_main.c @@ -1,49 +1,51 @@ #include #include + #include "esp_system.h" +#include "flash.h" #include "nvs_flash.h" #include "platform.h" -#include "flash.h" #include "tmr.h" -#define START_ADDR 0x110000 -#define USED_FLASH_SIZE 2048 -#define BUFF_SIZE 12 +#define START_ADDR 0x110000 +#define USED_FLASH_SIZE 2048 +#define BUFF_SIZE 12 -void led_blink(void) +void led_blink(void) { - int res = platform_gpio_mode(2, 2); // pin mode: OUTPUT - if(res < 0) { - printf("Led lightup failed\n"); - return; - } - platform_gpio_write(2, 1); // led on - tmr_delay_msec(250); - platform_gpio_write(2, 0); // led off - tmr_delay_msec(250); - platform_gpio_write(2, 1); - tmr_delay_msec(250); - platform_gpio_write(2, 0); - tmr_delay_msec(250); - platform_gpio_write(2, 1); + int res = platform_gpio_mode(2, 2); // pin mode: OUTPUT + if (res < 0) + { + printf("Led lightup failed\n"); + return; + } + platform_gpio_write(2, 1); // led on + tmr_delay_msec(250); + platform_gpio_write(2, 0); // led off + tmr_delay_msec(250); + platform_gpio_write(2, 1); + tmr_delay_msec(250); + platform_gpio_write(2, 0); + tmr_delay_msec(250); + platform_gpio_write(2, 1); } void app_main() { - nvs_flash_init(); - flash_init(); - led_blink(); + nvs_flash_init(); + flash_init(); + led_blink(); - flash_config *fc = flash_get_config(); - fc->hal_erase_f(START_ADDR, USED_FLASH_SIZE); - uint8_t str[10] = "helloworld"; - fc->hal_write_f(START_ADDR, strlen(str), str); + flash_config *fc = flash_get_config(); + fc->hal_erase_f(START_ADDR, USED_FLASH_SIZE); + uint8_t str[10] = "helloworld"; + fc->hal_write_f(START_ADDR, strlen(str), str); - tmr_delay_msec(1000); - uint8_t buff[BUFF_SIZE]; - memset(buff, 0, BUFF_SIZE); - fc->hal_read_f(START_ADDR, strlen(str), buff); - printf("==> Read content: %s\n", buff); + tmr_delay_msec(1000); + uint8_t buff[BUFF_SIZE]; + memset(buff, 0, BUFF_SIZE); + fc->hal_read_f(START_ADDR, strlen(str), buff); + printf("==> Read content: %s\n", buff); - return 0; + return 0; } diff --git a/LuaNode_Esp32/LuaNode32/examples/simple_http_server/app_main.c b/LuaNode_Esp32/LuaNode32/examples/simple_http_server/app_main.c index 5cb226e..2e158fe 100644 --- a/LuaNode_Esp32/LuaNode32/examples/simple_http_server/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/simple_http_server/app_main.c @@ -1,25 +1,24 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "lwip/sockets.h" - -#include "platform.h" -#include "tmr.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "esp_system.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "lwip/sockets.h" #include "nvs_flash.h" +#include "platform.h" #include "tcpip_adapter.h" +#include "tmr.h" -#define SSID_AP "DOIT" -#define HTTP_SERVER_PORT 80 -#define MAX_HTTP_CLIENT_CONN 1 -#define HTTP_CLIENT_BUFF_LEN 1024 +#define SSID_AP "DOIT" +#define HTTP_SERVER_PORT 80 +#define MAX_HTTP_CLIENT_CONN 1 +#define HTTP_CLIENT_BUFF_LEN 1024 static EventGroupHandle_t wifi_event_group; const int CONNECTED_BIT = BIT0; @@ -27,7 +26,7 @@ static const char *TAG = "main"; static uint8_t curentServerClient = 0; const uint8 webserver_str[] = -"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\ + "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\ \r\n\ \r\n\ \r\n\ @@ -40,192 +39,212 @@ const uint8 webserver_str[] = \r\n\ "; -void led_blink(void) +void led_blink(void) { - int res = platform_gpio_mode(2, 2); // pin mode: OUTPUT - if(res < 0) { - printf("Led lightup failed\n"); - return; - } - platform_gpio_write(2, 1); // led on - tmr_delay_msec(250); - platform_gpio_write(2, 0); // led off - tmr_delay_msec(250); - platform_gpio_write(2, 1); - tmr_delay_msec(250); - platform_gpio_write(2, 0); - tmr_delay_msec(250); - platform_gpio_write(2, 1); + int res = platform_gpio_mode(2, 2); // pin mode: OUTPUT + if (res < 0) + { + printf("Led lightup failed\n"); + return; + } + platform_gpio_write(2, 1); // led on + tmr_delay_msec(250); + platform_gpio_write(2, 0); // led off + tmr_delay_msec(250); + platform_gpio_write(2, 1); + tmr_delay_msec(250); + platform_gpio_write(2, 0); + tmr_delay_msec(250); + platform_gpio_write(2, 1); } static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_AP_START: - ESP_LOGI(TAG, "AP start now"); - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STOP: - ESP_LOGI(TAG, "AP stop now"); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "Station connect"); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "Station disconnect"); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_AP_START: + ESP_LOGI(TAG, "AP start now"); + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_AP_STOP: + ESP_LOGI(TAG, "AP stop now"); + break; + case SYSTEM_EVENT_AP_STACONNECTED: + ESP_LOGI(TAG, "Station connect"); + break; + case SYSTEM_EVENT_AP_STADISCONNECTED: + ESP_LOGI(TAG, "Station disconnect"); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t config = { - .ap = { - .ssid = SSID_AP, - //.password = "123", - .ssid_len = strlen(SSID_AP), - //.channel = 0, - .authmode = WIFI_AUTH_OPEN, - // Max number of stations allowed to connect in, default 4, max 4 - .max_connection = 10, - //.ssid_hidden = 0, - //.beacon_interval = 100, - }, - }; - - // set SSID - uint8_t mac[6]; - esp_wifi_get_mac(WIFI_IF_AP, mac); - sprintf(config.ap.ssid, SSID_AP "_%02X%02X%02X", mac[3], mac[4], mac[5]); - config.ap.ssid_len = strlen(config.ap.ssid); - - tcpip_adapter_init(); + wifi_config_t config = { + .ap = + { + .ssid = SSID_AP, + //.password = "123", + .ssid_len = strlen(SSID_AP), + //.channel = 0, + .authmode = WIFI_AUTH_OPEN, + // Max number of stations allowed to connect in, default 4, max + // 4 + .max_connection = 10, + //.ssid_hidden = 0, + //.beacon_interval = 100, + }, + }; + + // set SSID + uint8_t mac[6]; + esp_wifi_get_mac(WIFI_IF_AP, mac); + sprintf(config.ap.ssid, SSID_AP "_%02X%02X%02X", mac[3], mac[4], mac[5]); + config.ap.ssid_len = strlen(config.ap.ssid); + + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static int parse_http_request(int32 client, char *p, int len) { - if (NULL != strstr(p, "GET / HTTP/1.1")) { - ESP_LOGI(TAG, "socket write data"); - write(client, webserver_str, strlen(webserver_str)); - } - return 0; + if (NULL != strstr(p, "GET / HTTP/1.1")) + { + ESP_LOGI(TAG, "socket write data"); + write(client, webserver_str, strlen(webserver_str)); + } + return 0; } static void task_http_server_client(void *inFd) { - int32 client_sock = *(int *) inFd; - char *recv_buf = (char *) malloc(HTTP_CLIENT_BUFF_LEN); - int recbytes = 0; - - ESP_LOGI(TAG, "setup socket:(%d)", client_sock); - - //int nNetTimeout = 5; - //setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, - // sizeof(int)); //non-block - curentServerClient++; - while (1) { - recbytes = read(client_sock, recv_buf, HTTP_CLIENT_BUFF_LEN-1); - if (recbytes > 0) { - recv_buf[recbytes] = 0; - ESP_LOGI(TAG, "(socket:%d) recieve:(%d): %s", client_sock, recbytes, recv_buf); - if (parse_http_request(client_sock, recv_buf, recbytes) == 0) { - break; - } - } else if (recbytes == 0) { - break; - } - } - - free(recv_buf); - printf("task_http_server_client > close socket:(%d)\n", client_sock); - close(client_sock); - - curentServerClient--; + int32 client_sock = *(int *)inFd; + char *recv_buf = (char *)malloc(HTTP_CLIENT_BUFF_LEN); + int recbytes = 0; + + ESP_LOGI(TAG, "setup socket:(%d)", client_sock); + + // int nNetTimeout = 5; + // setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, (char * )&nNetTimeout, + // sizeof(int)); //non-block + curentServerClient++; + while (1) + { + recbytes = read(client_sock, recv_buf, HTTP_CLIENT_BUFF_LEN - 1); + if (recbytes > 0) + { + recv_buf[recbytes] = 0; + ESP_LOGI(TAG, "(socket:%d) recieve:(%d): %s", client_sock, recbytes, recv_buf); + if (parse_http_request(client_sock, recv_buf, recbytes) == 0) + { + break; + } + } + else if (recbytes == 0) + { + break; + } + } + + free(recv_buf); + printf("task_http_server_client > close socket:(%d)\n", client_sock); + close(client_sock); + + curentServerClient--; } static void task_http_server(void *pvParameters) { - int32 listenfd; - int32 ret; - struct sockaddr_in server_addr, remote_addr; - memset(&server_addr, 0, sizeof(server_addr)); - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = INADDR_ANY; - server_addr.sin_len = sizeof(server_addr); - server_addr.sin_port = htons(HTTP_SERVER_PORT); - - while ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ESP_LOGI(TAG, "socket create failed"); - tmr_delay_msec(1000); - } - - while (bind(listenfd, (struct sockaddr * )&server_addr, sizeof(server_addr)) != 0) { - ESP_LOGI(TAG, "socket bind failed"); - tmr_delay_msec(1000); - } - - while (listen(listenfd, MAX_HTTP_CLIENT_CONN) != 0) { - ESP_LOGI(TAG, "socket listen failed"); - tmr_delay_msec(1000); - } - - int32 client_sock; - int32 len = sizeof(struct sockaddr_in); - - while (1) { - ESP_LOGI(TAG, "wait client"); - if ((client_sock = accept(listenfd, (struct sockaddr * )&remote_addr, (socklen_t * )&len)) < 0) { - ESP_LOGI(TAG, "socket accept failed"); - continue; - } - - if (curentServerClient < MAX_HTTP_CLIENT_CONN) { - printf("ESP32 HTTP server task > Client from %s %d\n", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port)); - //xTaskCreate(task_http_server_client, "task_http_server_client", 1024, - // &client_sock, 1, NULL); - task_http_server_client(&client_sock); - } else { - close(client_sock); // close socket - tmr_delay_msec(1000); - } - } - - vTaskDelete(NULL); + int32 listenfd; + int32 ret; + struct sockaddr_in server_addr, remote_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_len = sizeof(server_addr); + server_addr.sin_port = htons(HTTP_SERVER_PORT); + + while ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + ESP_LOGI(TAG, "socket create failed"); + tmr_delay_msec(1000); + } + + while (bind(listenfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) + { + ESP_LOGI(TAG, "socket bind failed"); + tmr_delay_msec(1000); + } + + while (listen(listenfd, MAX_HTTP_CLIENT_CONN) != 0) + { + ESP_LOGI(TAG, "socket listen failed"); + tmr_delay_msec(1000); + } + + int32 client_sock; + int32 len = sizeof(struct sockaddr_in); + + while (1) + { + ESP_LOGI(TAG, "wait client"); + if ((client_sock = accept(listenfd, (struct sockaddr *)&remote_addr, (socklen_t *)&len)) < 0) + { + ESP_LOGI(TAG, "socket accept failed"); + continue; + } + + if (curentServerClient < MAX_HTTP_CLIENT_CONN) + { + printf("ESP32 HTTP server task > Client from %s %d\n", inet_ntoa(remote_addr.sin_addr), + htons(remote_addr.sin_port)); + // xTaskCreate(task_http_server_client, "task_http_server_client", + // 1024, &client_sock, 1, NULL); + task_http_server_client(&client_sock); + } + else + { + close(client_sock); // close socket + tmr_delay_msec(1000); + } + } + + vTaskDelete(NULL); } static void http_task(void *pvParameters) { - while(1) { - /* Wait for the callback to set the CONNECTED_BIT in the - event group. - */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + /* Wait for the callback to set the CONNECTED_BIT in the + event group. + */ + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "AP started"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - xTaskCreate(task_http_server, "task_http_server", 2048, NULL, 12, NULL); - break; - } - vTaskDelete(NULL); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + xTaskCreate(task_http_server, "task_http_server", 2048, NULL, 12, NULL); + break; + } + vTaskDelete(NULL); } void app_main() { - led_blink(); // led flashing - nvs_flash_init(); + led_blink(); // led flashing + nvs_flash_init(); initialise_wifi(); - xTaskCreate(&http_task, "http_task", 2048, NULL, 13, NULL); + xTaskCreate(&http_task, "http_task", 2048, NULL, 13, NULL); - return 0; + return 0; } diff --git a/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c b/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c index 7661d20..68aeb36 100644 --- a/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/tcp_client_espconn/app_main.c @@ -1,28 +1,28 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "nvs_flash.h" +#include "esp_wifi.h" #include "espconn.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "tmr.h" -#define FEEDBACK_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define SEND_TASK_PRIORITY 12 -#define REMOTE_PORT 11000 -static uint8 serverIP[] = { 192, 168, 1, 101 }; +#define FEEDBACK_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define SEND_TASK_PRIORITY 12 +#define REMOTE_PORT 11000 +static uint8 serverIP[] = {192, 168, 1, 101}; static struct espconn *_ptrUDPServer; static EventGroupHandle_t wifi_event_group; -static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour +static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour const int CONNECTED_BIT = BIT0; static const char *TAG = "main"; static int wifi_status = 0; @@ -30,133 +30,129 @@ static tcpip_adapter_ip_info_t ip_info; static esp_err_t event_handler(void *ctx, system_event_t *event) { - wifi_status = event->event_id; - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; + wifi_status = event->event_id; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; } return ESP_OK; } -uint8_t wifi_station_get_connect_status(void) -{ - return wifi_status; -} +uint8_t wifi_station_get_connect_status(void) { return wifi_status; } static void initialise_wifi(void) { - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, }; - tcpip_adapter_init(); + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static void send_task(void *pvParameters) { - struct espconn *pespconn = (struct espconn *) pvParameters; - while(1) { - tmr_delay_msec(2000); - espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); - } - vTaskDelete(NULL); + struct espconn *pespconn = (struct espconn *)pvParameters; + while (1) + { + tmr_delay_msec(2000); + espconn_sent(pespconn, (uint8 *)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + } + vTaskDelete(NULL); } -void disconnect_cb(void *arg) -{ - ESP_LOGI(TAG, "disconnected"); -} +void disconnect_cb(void *arg) { ESP_LOGI(TAG, "disconnected"); } void receive_cb(void *arg, char *pdata, unsigned short len) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); + // espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); } -void send_cb(void *arg) -{ - ESP_LOGI(TAG, "sent data"); -} +void send_cb(void *arg) { ESP_LOGI(TAG, "sent data"); } void connect_cb(void *arg) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "connected"); - espconn_regist_disconcb(pespconn, disconnect_cb); - espconn_regist_recvcb(pespconn, receive_cb); - espconn_regist_sentcb(pespconn, send_cb); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); - xTaskCreate(&send_task, "send_task", 4096, pespconn, TMP_TASK_PRIORITY, NULL); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "connected"); + espconn_regist_disconcb(pespconn, disconnect_cb); + espconn_regist_recvcb(pespconn, receive_cb); + espconn_regist_sentcb(pespconn, send_cb); + // espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + xTaskCreate(&send_task, "send_task", 4096, pespconn, TMP_TASK_PRIORITY, NULL); } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) { + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip_info) == 0) + { ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip_info.ip)); - ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip_info.netmask)); - ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip_info.gw)); + ESP_LOGI(TAG, "IP:" IPSTR, IP2STR(&ip_info.ip)); + ESP_LOGI(TAG, "MASK:" IPSTR, IP2STR(&ip_info.netmask)); + ESP_LOGI(TAG, "GW:" IPSTR, IP2STR(&ip_info.gw)); ESP_LOGI(TAG, "~~~~~~~~~~~"); } - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_TCP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); - _ptrUDPServer->proto.tcp->local_port = espconn_port(); - _ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; - memcpy(_ptrUDPServer->proto.tcp->remote_ip, serverIP, 4); - - espconn_regist_connectcb(_ptrUDPServer, connect_cb); - ESP_LOGI(TAG, "wait for client"); - - // connect to tcp server - espconn_connect(_ptrUDPServer); - - while(1) { - tmr_delay_msec(5000); - ESP_LOGI(TAG, "tmp_task loop"); - } - } - vTaskDelete(NULL); + // start espconn + _ptrUDPServer = (struct espconn *)malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_TCP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp)); + _ptrUDPServer->proto.tcp->local_port = espconn_port(); + _ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; + memcpy(_ptrUDPServer->proto.tcp->remote_ip, serverIP, 4); + + espconn_regist_connectcb(_ptrUDPServer, connect_cb); + ESP_LOGI(TAG, "wait for client"); + + // connect to tcp server + espconn_connect(_ptrUDPServer); + + while (1) + { + tmr_delay_msec(5000); + ESP_LOGI(TAG, "tmp_task loop"); + } + } + vTaskDelete(NULL); } void app_main() { - nvs_flash_init(); + nvs_flash_init(); initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c b/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c index ad96abc..b4810cf 100644 --- a/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/tcp_server_espconn/app_main.c @@ -1,135 +1,132 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "nvs_flash.h" +#include "esp_wifi.h" #include "espconn.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "tmr.h" -#define FEEDBACK_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define TCP_TASK_PRIORITY 12 -#define LOCAL_PORT 11000 -#define REMOTE_PORT 6000 +#define FEEDBACK_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define TCP_TASK_PRIORITY 12 +#define LOCAL_PORT 11000 +#define REMOTE_PORT 6000 static struct espconn *_ptrUDPServer; static EventGroupHandle_t wifi_event_group; -static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour +static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour const int CONNECTED_BIT = BIT0; static const char *TAG = "main"; static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, }; - tcpip_adapter_init(); + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } -void disconnect_cb(void *arg) -{ - ESP_LOGI(TAG, "disconnected"); -} +void disconnect_cb(void *arg) { ESP_LOGI(TAG, "disconnected"); } void receive_cb(void *arg, char *pdata, unsigned short len) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "received data"); - ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "received data"); + ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); + // espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); } -void send_cb(void *arg) -{ - ESP_LOGI(TAG, "sent data"); -} +void send_cb(void *arg) { ESP_LOGI(TAG, "sent data"); } void connect_cb(void *arg) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "connected"); - espconn_regist_disconcb(pespconn, disconnect_cb); - espconn_regist_recvcb(pespconn, receive_cb); - espconn_regist_sentcb(pespconn, send_cb); - //espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "connected"); + espconn_regist_disconcb(pespconn, disconnect_cb); + espconn_regist_recvcb(pespconn, receive_cb); + espconn_regist_sentcb(pespconn, send_cb); + // espconn_sent(pespconn, (uint8*)FEEDBACK_DATA, strlen(FEEDBACK_DATA)); } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_TCP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); - _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; - //_ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; - - espconn_regist_connectcb(_ptrUDPServer, connect_cb); - ESP_LOGI(TAG, "wait for client"); - espconn_accept(_ptrUDPServer); - espconn_regist_time(_ptrUDPServer, srv_timeout, 0); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - while(1) { - tmr_delay_msec(5000); - ESP_LOGI(TAG, "tmp_task loop"); - } - } - vTaskDelete(NULL); + // start espconn + _ptrUDPServer = (struct espconn *)malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_TCP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp)); + _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; + //_ptrUDPServer->proto.tcp->remote_port = REMOTE_PORT; + + espconn_regist_connectcb(_ptrUDPServer, connect_cb); + ESP_LOGI(TAG, "wait for client"); + espconn_accept(_ptrUDPServer); + espconn_regist_time(_ptrUDPServer, srv_timeout, 0); + + while (1) + { + tmr_delay_msec(5000); + ESP_LOGI(TAG, "tmp_task loop"); + } + } + vTaskDelete(NULL); } void app_main() { - nvs_flash_init(); + nvs_flash_init(); initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); - + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c b/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c index 13d6e67..8a302ad 100644 --- a/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/telnet_server/app_main.c @@ -1,165 +1,165 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "nvs_flash.h" +#include "esp_wifi.h" #include "espconn.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "tmr.h" -#define FEEDBACK1 "\r\nhello back\r\n" -#define FEEDBACK2 "\r\nok\r\n" -#define FEEDBACK3 "\r\ninvalid command\r\n" -#define PROMPT "You can input the following command:\r\n1. hello\r\n2. test\r\n" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define CMD1 "hello" -#define CMD2 "test" -#define TMP_TASK_PRIORITY 13 -#define TCP_TASK_PRIORITY 12 -#define LOCAL_PORT 23 // Telnet use port 23 -#define BUFF_SIZE 256 +#define FEEDBACK1 "\r\nhello back\r\n" +#define FEEDBACK2 "\r\nok\r\n" +#define FEEDBACK3 "\r\ninvalid command\r\n" +#define PROMPT "You can input the following command:\r\n1. hello\r\n2. test\r\n" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define CMD1 "hello" +#define CMD2 "test" +#define TMP_TASK_PRIORITY 13 +#define TCP_TASK_PRIORITY 12 +#define LOCAL_PORT 23 // Telnet use port 23 +#define BUFF_SIZE 256 static struct espconn *_ptrUDPServer; static EventGroupHandle_t wifi_event_group; -static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour +static int srv_timeout = 60 * 60; // disconnect when the server didn't receive data in the past 1 hour const int CONNECTED_BIT = BIT0; static const char *TAG = "main"; static char buff[BUFF_SIZE]; - static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.tcp); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.tcp); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, }; - tcpip_adapter_init(); + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } void parse(struct espconn *pespconn, char *pdata, unsigned short len) { - if (pdata[0] != 0x0a && pdata[0] != 0x0d) { // the input is not Enter key - int index = strlen(buff); - buff[index] = pdata[0]; - return; - } - - ESP_LOGI(TAG, "command: %s, len: %d", buff, strlen(buff)); - if (strstr(buff, CMD1)) { - espconn_sent(pespconn, (uint8 *)FEEDBACK1, strlen(FEEDBACK1)); - } else if (strstr(buff, CMD2)) { - espconn_sent(pespconn, (uint8 *)FEEDBACK2, strlen(FEEDBACK2)); - } else { - espconn_sent(pespconn, (uint8 *)FEEDBACK3, strlen(FEEDBACK3)); - } - memset(buff, 0, BUFF_SIZE); + if (pdata[0] != 0x0a && pdata[0] != 0x0d) + { // the input is not Enter key + int index = strlen(buff); + buff[index] = pdata[0]; + return; + } + + ESP_LOGI(TAG, "command: %s, len: %d", buff, strlen(buff)); + if (strstr(buff, CMD1)) + { + espconn_sent(pespconn, (uint8 *)FEEDBACK1, strlen(FEEDBACK1)); + } + else if (strstr(buff, CMD2)) + { + espconn_sent(pespconn, (uint8 *)FEEDBACK2, strlen(FEEDBACK2)); + } + else + { + espconn_sent(pespconn, (uint8 *)FEEDBACK3, strlen(FEEDBACK3)); + } + memset(buff, 0, BUFF_SIZE); } void disconnect_cb(void *arg) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "disconnected"); - espconn_disconnect(pespconn); - memset(buff, 0, BUFF_SIZE); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "disconnected"); + espconn_disconnect(pespconn); + memset(buff, 0, BUFF_SIZE); } void receive_cb(void *arg, char *pdata, unsigned short len) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); - parse(pespconn, pdata, len); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "received data: %s, len=%d", pdata, len); + parse(pespconn, pdata, len); } -void send_cb(void *arg) -{ - ESP_LOGI(TAG, "sent data"); -} +void send_cb(void *arg) { ESP_LOGI(TAG, "sent data"); } void connect_cb(void *arg) { - struct espconn *pespconn = (struct espconn *) arg; - ESP_LOGI(TAG, "connected"); - espconn_regist_disconcb(pespconn, disconnect_cb); - espconn_regist_recvcb(pespconn, receive_cb); - espconn_regist_sentcb(pespconn, send_cb); - espconn_sent(pespconn, (uint8 *)PROMPT, strlen(PROMPT)); + struct espconn *pespconn = (struct espconn *)arg; + ESP_LOGI(TAG, "connected"); + espconn_regist_disconcb(pespconn, disconnect_cb); + espconn_regist_recvcb(pespconn, receive_cb); + espconn_regist_sentcb(pespconn, send_cb); + espconn_sent(pespconn, (uint8 *)PROMPT, strlen(PROMPT)); } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_TCP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.tcp = (esp_tcp *) malloc(sizeof(esp_tcp)); - _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; - - espconn_regist_connectcb(_ptrUDPServer, connect_cb); - ESP_LOGI(TAG, "wait for client"); - espconn_accept(_ptrUDPServer); - espconn_regist_time(_ptrUDPServer, srv_timeout, 0); - - } - vTaskDelete(NULL); -} + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); -void app_init() -{ - memset(buff, 0, BUFF_SIZE); + // start espconn + _ptrUDPServer = (struct espconn *)malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_TCP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp)); + _ptrUDPServer->proto.tcp->local_port = LOCAL_PORT; + + espconn_regist_connectcb(_ptrUDPServer, connect_cb); + ESP_LOGI(TAG, "wait for client"); + espconn_accept(_ptrUDPServer); + espconn_regist_time(_ptrUDPServer, srv_timeout, 0); + } + vTaskDelete(NULL); } +void app_init() { memset(buff, 0, BUFF_SIZE); } + void app_main() { - nvs_flash_init(); - tcpip_adapter_init(); + nvs_flash_init(); + tcpip_adapter_init(); initialise_wifi(); - app_init(); - - xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); + app_init(); + xTaskCreate(&tmp_task, "tmp_task", 4096, NULL, TMP_TASK_PRIORITY, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c b/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c index 6eaf436..40bc2fe 100644 --- a/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/test_spiffs/app_main.c @@ -1,54 +1,60 @@ -#include #include +#include + #include "esp_log.h" #include "esp_system.h" -#include "spiffs.h" -#include "vfs.h" -#include "platform.h" +#include "flash_api.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "flash_api.h" +#include "platform.h" +#include "spiffs.h" +#include "vfs.h" static const char *TAG = "main"; static spiffs fs; void app_main() { - char buf[12] = {0}; - - if(flash_safe_get_size_byte() != flash_rom_get_size_byte()) { - ESP_LOGI(TAG, "Incorrect flash size reported, adjusting..."); - flash_rom_set_size_byte(flash_safe_get_size_byte()); - system_restart(); - return; - } + char buf[12] = {0}; + + if (flash_safe_get_size_byte() != flash_rom_get_size_byte()) + { + ESP_LOGI(TAG, "Incorrect flash size reported, adjusting..."); + flash_rom_set_size_byte(flash_safe_get_size_byte()); + system_restart(); + return; + } - ESP_LOGI (TAG, "Mounting flash filesystem..."); - if (!vfs_mount("/FLASH", 0)) { + ESP_LOGI(TAG, "Mounting flash filesystem..."); + if (!vfs_mount("/FLASH", 0)) + { // Failed to mount -- try reformat - ESP_LOGI(TAG, "Formatting file system. Please wait..."); - if (!vfs_format()) { - ESP_LOGI(TAG, "*** ERROR ***: unable to format. FS might be compromised." ); - ESP_LOGI(TAG, "It is advised to re-flash the NodeMCU image." ); + ESP_LOGI(TAG, "Formatting file system. Please wait..."); + if (!vfs_format()) + { + ESP_LOGI(TAG, "*** ERROR ***: unable to format. FS might be compromised."); + ESP_LOGI(TAG, "It is advised to re-flash the NodeMCU image."); } // Note that fs_format leaves the file system mounted } - spiffs_file fd = SPIFFS_open(&fs, "test_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); - ESP_LOGI(TAG, "fd=%d", fd); - if (SPIFFS_write(&fs, fd, (u8_t *)"Hello SPIFFS", 12) < 0) { - ESP_LOGI(TAG, "write errno %i", SPIFFS_errno(&fs)); - } - SPIFFS_close(&fs, fd); + spiffs_file fd = SPIFFS_open(&fs, "test_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); + ESP_LOGI(TAG, "fd=%d", fd); + if (SPIFFS_write(&fs, fd, (u8_t *)"Hello SPIFFS", 12) < 0) + { + ESP_LOGI(TAG, "write errno %i", SPIFFS_errno(&fs)); + } + SPIFFS_close(&fs, fd); - vTaskDelay(1000 / portTICK_RATE_MS); + vTaskDelay(1000 / portTICK_RATE_MS); - fd = SPIFFS_open(&fs, "test_file", SPIFFS_RDWR, 0); - ESP_LOGI(TAG, "fd=%d", fd); - if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) { - ESP_LOGI(TAG, "read errno %i", SPIFFS_errno(&fs)); - } - SPIFFS_close(&fs, fd); + fd = SPIFFS_open(&fs, "test_file", SPIFFS_RDWR, 0); + ESP_LOGI(TAG, "fd=%d", fd); + if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) + { + ESP_LOGI(TAG, "read errno %i", SPIFFS_errno(&fs)); + } + SPIFFS_close(&fs, fd); - ESP_LOGI(TAG, "--> %s <--", buf); + ESP_LOGI(TAG, "--> %s <--", buf); } diff --git a/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c b/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c index b39d062..b70fc48 100644 --- a/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/udp_broadcast/app_main.c @@ -1,114 +1,116 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "nvs_flash.h" +#include "esp_wifi.h" #include "espconn.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "tmr.h" -#define USER_DATA "ESP32_Data" +#define USER_DATA "ESP32_Data" #define EXAMPLE_WIFI_SSID "TP-LINK_router" #define EXAMPLE_WIFI_PASS "123456789" -#define TMP_TASK_PRIORITY 13 -#define SEND_TASK_PRIORITY 12 +#define TMP_TASK_PRIORITY 13 +#define SEND_TASK_PRIORITY 12 -static uint8 udpServerIP[] = { 192, 168, 1, 255 }; +static uint8 udpServerIP[] = {192, 168, 1, 255}; static struct espconn *_ptrUDPServer; static EventGroupHandle_t wifi_event_group; const int CONNECTED_BIT = BIT0; static const char *TAG = "main"; - static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, }; - tcpip_adapter_init(); + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static void send_task(void *pvParameters) { - espconn_create(_ptrUDPServer); - while(1) { - tmr_delay_msec(3000); - ESP_LOGI(TAG, "broadcast data"); - espconn_sent(_ptrUDPServer, (uint8 *) USER_DATA, (uint16) strlen(USER_DATA)); - } - espconn_delete(_ptrUDPServer); - vTaskDelete(NULL); + espconn_create(_ptrUDPServer); + while (1) + { + tmr_delay_msec(3000); + ESP_LOGI(TAG, "broadcast data"); + espconn_sent(_ptrUDPServer, (uint8 *)USER_DATA, (uint16)strlen(USER_DATA)); + } + espconn_delete(_ptrUDPServer); + vTaskDelete(NULL); } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_UDP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.udp = (esp_udp *) malloc(sizeof(esp_udp)); - _ptrUDPServer->proto.udp->local_port = espconn_port(); - _ptrUDPServer->proto.udp->remote_port = 11000; - memcpy(_ptrUDPServer->proto.udp->remote_ip, udpServerIP, 4); + // start espconn + _ptrUDPServer = (struct espconn *)malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_UDP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.udp = (esp_udp *)malloc(sizeof(esp_udp)); + _ptrUDPServer->proto.udp->local_port = espconn_port(); + _ptrUDPServer->proto.udp->remote_port = 11000; + memcpy(_ptrUDPServer->proto.udp->remote_ip, udpServerIP, 4); - xTaskCreate(&send_task, "send_task", 4096, NULL, SEND_TASK_PRIORITY, NULL); + xTaskCreate(&send_task, "send_task", 4096, NULL, SEND_TASK_PRIORITY, NULL); - break; - } - vTaskDelete(NULL); + break; + } + vTaskDelete(NULL); } void app_main() { - nvs_flash_init(); + nvs_flash_init(); initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", 1536, NULL, TMP_TASK_PRIORITY, NULL); - + xTaskCreate(&tmp_task, "tmp_task", 1536, NULL, TMP_TASK_PRIORITY, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c b/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c index d2c3d92..363a3e2 100644 --- a/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/udp_server_espconn/app_main.c @@ -1,23 +1,23 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" -#include "nvs_flash.h" +#include "esp_wifi.h" #include "espconn.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "nvs_flash.h" #include "tmr.h" -#define USER_DATA "ESP32_Data" -#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" -#define EXAMPLE_WIFI_PASS "123456" -#define TMP_TASK_PRIORITY 13 -#define LOCAL_PORT 11000 -#define BUFF_SIZE 128 +#define USER_DATA "ESP32_Data" +#define EXAMPLE_WIFI_SSID "TP-LINK_93D966" +#define EXAMPLE_WIFI_PASS "123456" +#define TMP_TASK_PRIORITY 13 +#define LOCAL_PORT 11000 +#define BUFF_SIZE 128 static struct espconn *_ptrUDPServer; static EventGroupHandle_t wifi_event_group; @@ -27,96 +27,96 @@ static const char *TAG = "main"; static esp_err_t event_handler(void *ctx, system_event_t *event) { - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "STA start"); - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - free(_ptrUDPServer); - free(_ptrUDPServer->proto.udp); - break; - default: - break; + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + ESP_LOGI(TAG, "STA start"); + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + free(_ptrUDPServer); + free(_ptrUDPServer->proto.udp); + break; + default: + break; } return ESP_OK; } static void initialise_wifi(void) { - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, }; - tcpip_adapter_init(); + tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(event_handler, NULL); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + esp_event_loop_init(event_handler, NULL); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); } static void udp_recv(void *arg, char *pdata, unsigned short length) { - struct espconn *pesp_conn = arg; - char buff[BUFF_SIZE]; - memset(buff, 0, BUFF_SIZE); - ESP_LOGI(TAG, "client %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->remote_ip[0], - pesp_conn->proto.udp->remote_ip[1],pesp_conn->proto.udp->remote_ip[2], - pesp_conn->proto.udp->remote_ip[3],pesp_conn->proto.udp->remote_port); - ESP_LOGI(TAG, "local %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->local_ip[0], - pesp_conn->proto.udp->local_ip[1],pesp_conn->proto.udp->local_ip[2], - pesp_conn->proto.udp->local_ip[3],pesp_conn->proto.udp->local_port); - ESP_LOGI(TAG, "received %d bytes of data", length); - if (length > BUFF_SIZE) { - ESP_LOGI(TAG, "received data out of bound"); - } - memcpy(buff, pdata, length); - ESP_LOGI(TAG, "content: %s", pdata); - + struct espconn *pesp_conn = arg; + char buff[BUFF_SIZE]; + memset(buff, 0, BUFF_SIZE); + ESP_LOGI(TAG, "client %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->remote_ip[0], pesp_conn->proto.udp->remote_ip[1], + pesp_conn->proto.udp->remote_ip[2], pesp_conn->proto.udp->remote_ip[3], pesp_conn->proto.udp->remote_port); + ESP_LOGI(TAG, "local %d.%d.%d.%d:%d -> ", pesp_conn->proto.udp->local_ip[0], pesp_conn->proto.udp->local_ip[1], + pesp_conn->proto.udp->local_ip[2], pesp_conn->proto.udp->local_ip[3], pesp_conn->proto.udp->local_port); + ESP_LOGI(TAG, "received %d bytes of data", length); + if (length > BUFF_SIZE) + { + ESP_LOGI(TAG, "received data out of bound"); + } + memcpy(buff, pdata, length); + ESP_LOGI(TAG, "content: %s", pdata); } static void tmp_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "Got IP"); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - // start espconn - _ptrUDPServer = (struct espconn *) malloc(sizeof(struct espconn)); - _ptrUDPServer->type = ESPCONN_UDP; - _ptrUDPServer->state = ESPCONN_NONE; - _ptrUDPServer->proto.udp = (esp_udp *) malloc(sizeof(esp_udp)); - memset(_ptrUDPServer->proto.udp, 0, sizeof(esp_udp)); - _ptrUDPServer->proto.udp->local_port = LOCAL_PORT; + // start espconn + _ptrUDPServer = (struct espconn *)malloc(sizeof(struct espconn)); + _ptrUDPServer->type = ESPCONN_UDP; + _ptrUDPServer->state = ESPCONN_NONE; + _ptrUDPServer->proto.udp = (esp_udp *)malloc(sizeof(esp_udp)); + memset(_ptrUDPServer->proto.udp, 0, sizeof(esp_udp)); + _ptrUDPServer->proto.udp->local_port = LOCAL_PORT; - espconn_regist_recvcb(_ptrUDPServer, udp_recv); - espconn_create(_ptrUDPServer); - ESP_LOGI(TAG, "Wait for client"); + espconn_regist_recvcb(_ptrUDPServer, udp_recv); + espconn_create(_ptrUDPServer); + ESP_LOGI(TAG, "Wait for client"); - break; - } - vTaskDelete(NULL); + break; + } + vTaskDelete(NULL); } void app_main() { - nvs_flash_init(); + nvs_flash_init(); initialise_wifi(); - xTaskCreate(&tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIORITY, NULL); - + xTaskCreate(&tmp_task, "tmp_task", 2048, NULL, TMP_TASK_PRIORITY, NULL); } diff --git a/LuaNode_Esp32/LuaNode32/examples/wifi_scan/app_main.c b/LuaNode_Esp32/LuaNode32/examples/wifi_scan/app_main.c index a8713d9..d6c6a73 100644 --- a/LuaNode_Esp32/LuaNode32/examples/wifi_scan/app_main.c +++ b/LuaNode_Esp32/LuaNode32/examples/wifi_scan/app_main.c @@ -1,108 +1,113 @@ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_system.h" #include "esp_event.h" #include "esp_event_loop.h" #include "esp_log.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" #include "nvs_flash.h" static EventGroupHandle_t wifi_event_group; const int SCAN_DONE_BIT = BIT0; -static wifi_scan_config_t scanConf = { - .ssid = NULL, - .bssid = NULL, - .channel = 0, - .show_hidden = true -}; +static wifi_scan_config_t scanConf = {.ssid = NULL, .bssid = NULL, .channel = 0, .show_hidden = true}; static const char *TAG = "example"; esp_err_t event_handler(void *ctx, system_event_t *event) { - if (event->event_id == SYSTEM_EVENT_SCAN_DONE) { - xEventGroupSetBits(wifi_event_group, SCAN_DONE_BIT); - } - return ESP_OK; + if (event->event_id == SYSTEM_EVENT_SCAN_DONE) + { + xEventGroupSetBits(wifi_event_group, SCAN_DONE_BIT); + } + return ESP_OK; } static void initialise_wifi(void) { - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_start()); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_start()); } static void scan_task(void *pvParameters) { - while(1) { - xEventGroupWaitBits(wifi_event_group, SCAN_DONE_BIT, false, true, portMAX_DELAY); + while (1) + { + xEventGroupWaitBits(wifi_event_group, SCAN_DONE_BIT, false, true, portMAX_DELAY); ESP_LOGI(TAG, "WIFI scan doen"); - xEventGroupClearBits(wifi_event_group, SCAN_DONE_BIT); - - uint16_t apCount = 0; - esp_wifi_scan_get_ap_num(&apCount); - printf("Number of access points found: %d\n", apCount); - if (apCount == 0) { - ESP_LOGI(TAG, "Nothing AP found"); - return; - } - wifi_ap_record_t *list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount); - ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, list)); - int i; - printf("======================================================================\n"); - printf(" SSID | RSSI | AUTH \n"); - printf("======================================================================\n"); - for (i=0; i #include + +#include "esp_spi_flash.h" +#include "esp_system.h" +#include "flash_api.h" +#include "flash_fs.h" #include "freertos/FreeRTOS.h" -#include "freertos/task.h" #include "freertos/queue.h" -#include "my_uart.h" +#include "freertos/task.h" #include "lua.h" -#include "flash_fs.h" -#include "vfs.h" -#include "esp_spi_flash.h" -#include "platform.h" +#include "my_uart.h" +#include "nodemcu_esp_event.h" #include "nvs_flash.h" -#include "esp_system.h" -#include "flash_api.h" +#include "platform.h" #include "task/task.h" -#include "nodemcu_esp_event.h" +#include "vfs.h" #ifdef USE_THREAD_MODULE #include "pthreadx.h" #endif @@ -25,113 +26,114 @@ extern nodemcu_esp_event_reg_t esp_event_cb_table; static task_handle_t esp_event_task; static QueueHandle_t esp_event_queue; - -void led_blink(void) +void led_blink(void) { - int res = platform_gpio_mode(2, PLATFORM_GPIO_OUTPUT, 0); // pin mode: OUTPUT - if(res < 0) { - printf("Led lightup failed\n"); - return; - } - platform_gpio_write(2, 1); // led on - vTaskDelay(250/portTICK_RATE_MS); - platform_gpio_write(2, 0); // led off - tmr_delay_msec(250); - platform_gpio_write(2, 1); - tmr_delay_msec(250); - platform_gpio_write(2, 0); - tmr_delay_msec(250); - platform_gpio_write(2, 1); + int res = platform_gpio_mode(2, PLATFORM_GPIO_OUTPUT, 0); // pin mode: OUTPUT + if (res < 0) + { + printf("Led lightup failed\n"); + return; + } + platform_gpio_write(2, 1); // led on + vTaskDelay(250 / portTICK_RATE_MS); + platform_gpio_write(2, 0); // led off + tmr_delay_msec(250); + platform_gpio_write(2, 1); + tmr_delay_msec(250); + platform_gpio_write(2, 0); + tmr_delay_msec(250); + platform_gpio_write(2, 1); } -esp_err_t esp_event_send (system_event_t *event) +esp_err_t esp_event_send(system_event_t *event) { - if (!event) - return ESP_ERR_INVALID_ARG; - - if (!esp_event_task || !esp_event_queue) - return ESP_ERR_INVALID_STATE; // too early! - - portBASE_TYPE ret = xQueueSendToBack (esp_event_queue, event, 0); - if (ret != pdPASS) - { - NODE_ERR("failed to queue esp event %d", event->event_id); - return ESP_FAIL; - } - - // If the task_post() fails, it only means the event gets delayed, hence - // we claim OK regardless. - task_post_medium (esp_event_task, 0); - return ESP_OK; + if (!event) + return ESP_ERR_INVALID_ARG; + + if (!esp_event_task || !esp_event_queue) + return ESP_ERR_INVALID_STATE; // too early! + + portBASE_TYPE ret = xQueueSendToBack(esp_event_queue, event, 0); + if (ret != pdPASS) + { + NODE_ERR("failed to queue esp event %d", event->event_id); + return ESP_FAIL; + } + + // If the task_post() fails, it only means the event gets delayed, hence + // we claim OK regardless. + task_post_medium(esp_event_task, 0); + return ESP_OK; } -static void handle_esp_event (task_param_t param, task_prio_t prio) +static void handle_esp_event(task_param_t param, task_prio_t prio) { - (void)param; - (void)prio; - - system_event_t evt; - while (xQueueReceive (esp_event_queue, &evt, 0) == pdPASS) - { - esp_err_t ret = esp_event_process_default (&evt); - if (ret != ESP_OK) - NODE_ERR("default event handler failed for %d", evt.event_id); - - nodemcu_esp_event_reg_t *evregs; - for (evregs = &esp_event_cb_table; evregs->callback; ++evregs) + (void)param; + (void)prio; + + system_event_t evt; + while (xQueueReceive(esp_event_queue, &evt, 0) == pdPASS) { - if (evregs->event_id == evt.event_id) - evregs->callback (&evt); + esp_err_t ret = esp_event_process_default(&evt); + if (ret != ESP_OK) + NODE_ERR("default event handler failed for %d", evt.event_id); + + nodemcu_esp_event_reg_t *evregs; + for (evregs = &esp_event_cb_table; evregs->callback; ++evregs) + { + if (evregs->event_id == evt.event_id) + evregs->callback(&evt); + } } - } } void app_main() { - uart_init(); + uart_init(); - esp_event_queue = - xQueueCreate (CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof (system_event_t)); - esp_event_task = task_get_id (handle_esp_event); + esp_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t)); + esp_event_task = task_get_id(handle_esp_event); - if(flash_safe_get_size_byte() != flash_rom_get_size_byte()) { - printf("Incorrect flash size reported, adjusting...\n"); - flash_rom_set_size_byte(flash_safe_get_size_byte()); - esp_restart(); - return; - } + if (flash_safe_get_size_byte() != flash_rom_get_size_byte()) + { + printf("Incorrect flash size reported, adjusting...\n"); + flash_rom_set_size_byte(flash_safe_get_size_byte()); + esp_restart(); + return; + } - printf ("Mounting flash filesystem...\n"); - if (!vfs_mount("/FLASH", 0)) { + printf("Mounting flash filesystem...\n"); + if (!vfs_mount("/FLASH", 0)) + { // Failed to mount -- try reformat - printf("Formatting file system. Please wait...\n"); - if (!vfs_format()) { - printf( "*** ERROR ***: unable to format. FS might be compromised.\n" ); - printf( "It is advised to re-flash the NodeMCU image.\n" ); + printf("Formatting file system. Please wait...\n"); + if (!vfs_format()) + { + printf("*** ERROR ***: unable to format. FS might be compromised.\n"); + printf("It is advised to re-flash the NodeMCU image.\n"); } // Note that fs_format leaves the file system mounted } - - nvs_flash_init(); - tcpip_adapter_init(); - platform_init(); + + nvs_flash_init(); + tcpip_adapter_init(); + platform_init(); #ifdef USE_TMR_MODULE - tmr_init(); + tmr_init(); #endif - printf("\n=======================================\n"); - printf("LuaNode: https://github.com/Nicholas3388/LuaNode\n"); - printf("Version: %s\n", VERSION); - printf("=======================================\n\n"); + printf("\n=======================================\n"); + printf("LuaNode: https://github.com/Nicholas3388/LuaNode\n"); + printf("Version: %s\n", VERSION); + printf("=======================================\n\n"); - char *lua_argv[] = {(char *)"lua", (char *)"-i", NULL}; + char *lua_argv[] = {(char *)"lua", (char *)"-i", NULL}; lua_main(2, lua_argv); #ifdef USE_THREAD_MODULE - _pthread_init(); + _pthread_init(); #endif - //led_blink(); // led flashing - task_pump_messages(); + // led_blink(); // led flashing + task_pump_messages(); } - From 1b39c18e286301c89bb5bc6334ee3d089f9f7474 Mon Sep 17 00:00:00 2001 From: William OLLIVIER Date: Wed, 11 Dec 2019 19:53:26 +0000 Subject: [PATCH 8/8] Fixed warnings and `node` functionality --- .../LuaNode32/components/modules/node.c | 209 ++++++++---------- 1 file changed, 94 insertions(+), 115 deletions(-) diff --git a/LuaNode_Esp32/LuaNode32/components/modules/node.c b/LuaNode_Esp32/LuaNode32/components/modules/node.c index 1c492fa..2c305df 100644 --- a/LuaNode_Esp32/LuaNode32/components/modules/node.c +++ b/LuaNode_Esp32/LuaNode32/components/modules/node.c @@ -21,73 +21,81 @@ #include "rom/uart.h" #include "user_interface.h" //#include "flash_api.h" +#include "bt.h" #include "esp_misc.h" #include "esp_system.h" +#include "esp_wifi.h" #include "flash_fs.h" #include "user_version.h" +#if BLUEDROID_ENABLED +#include "esp_bt_main.h" +#endif +#include "esp_spi_flash.h" #include "vfs.h" #define CPU80MHZ 80 #define CPU160MHZ 160 // Lua: restart() -static int node_restart(lua_State *L) +static int node_restart(lua_State* L) { - system_restart(); + esp_restart(); return 0; } // Lua: dsleep( us, option ) -static int node_dsleep(lua_State *L) +static int node_dsleep(lua_State* L) { uint64_t us = luaL_optinteger(L, 1, 0); - system_deep_sleep(us); +#if BT_ENABLED +#if BLUEDROID_ENABLED + esp_bluedroid_disable(); +#endif + esp_bt_controller_disable(ESP_BT_MODE_BTDM); +#endif +#if WIFI_ENABLED + esp_wifi_stop(); +#endif + esp_deep_sleep(us); return 0; } // Lua: dsleep_set_options // Combined to dsleep( us, option ) -// static int node_deepsleep_setoption( lua_State* L ) -// { -// s32 option; -// option = luaL_checkinteger( L, 1 ); -// if ( option < 0 || option > 4) -// return luaL_error( L, "wrong arg range" ); -// else -// deep_sleep_set_option( option ); -// return 0; -// } -// Lua: info() +static int node_deepsleep_setoption(lua_State* L) +{ + s32 option; + option = luaL_checkinteger(L, 1); + if (option < ESP_PD_OPTION_OFF || option > ESP_PD_OPTION_AUTO) + return luaL_error(L, "wrong arg range"); + else + esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, option); + esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, option); + esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, option); + return 0; +} -static int node_info(lua_State *L) +// Lua: info() +static int node_info(lua_State* L) { - // uint32_t fs = system_get_flash_size(); - uint32_t fs = 2; - uint8 id = 0; - // bool succeed = system_get_chip_id(&id); - uint32_t hs = system_get_free_heap_size(); - lua_getglobal(L, "print"); - switch (fs) - { - case 0: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "1MB", id, hs); - break; - case 1: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "2MB", id, hs); - break; - case 2: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "4MB", id, hs); - break; - case 3: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "8MB", id, hs); - break; - case 4: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "16MB", id, hs); - break; - default: - lua_pushfstring(L, "flash_size=%s, chip_id=%d, heap_size=%d", "32MB", id, hs); - break; + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + + size_t fs = spi_flash_get_chip_size(); + + uint8_t mac_address = 0; + esp_err_t mac_address_read_ok = esp_efuse_mac_get_default(&mac_address); + if (mac_address_read_ok != ESP_OK) + { + os_printf("Unable to get default MAC address (chip I/D): %d", mac_address_read_ok); } + + uint32_t hs = esp_get_free_heap_size(); + + lua_getglobal(L, "print"); + lua_pushfstring(L, "model=%d, cores=%d, rev=%d, flash_size=%sB, chip_id/mac_address=%X, free_heap_size=%d", + chip_info.model, chip_info.cores, chip_info.revision, fs, mac_address, hs); + int err = lua_pcall(L, 1, 1, 0); if (err != 0) { @@ -98,12 +106,16 @@ static int node_info(lua_State *L) } // Lua: chipid() -static int node_chipid(lua_State *L) +static int node_chipid(lua_State* L) { - uint8 id = 0; - // bool succeed = system_get_chip_id(&id); + uint8_t mac_address = 0; + esp_err_t mac_address_read_ok = esp_efuse_mac_get_default(&mac_address); + if (mac_address_read_ok != ESP_OK) + { + os_printf("Unable to get default MAC address (chip ID): %d", mac_address_read_ok); + } lua_getglobal(L, "print"); - lua_pushinteger(L, id); + lua_pushfstring(L, "%X", mac_address); int err = lua_pcall(L, 1, 1, 0); if (err != 0) { @@ -113,17 +125,8 @@ static int node_chipid(lua_State *L) return 0; } -// deprecated, moved to adc module -// Lua: readvdd33() -// static int node_readvdd33( lua_State* L ) -// { -// uint32_t vdd33 = readvdd33(); -// lua_pushinteger(L, vdd33); -// return 1; -// } - // Lua: flashid() -static int node_flashid(lua_State *L) +static int node_flashid(lua_State* L) { // uint32_t id = spi_flash_get_id(); // lua_pushinteger( L, id ); @@ -139,33 +142,11 @@ static int node_flashid(lua_State *L) } // Lua: flashsize() -static int node_flashsize(lua_State *L) +static int node_flashsize(lua_State* L) { - // uint32_t sz = system_get_flash_size(); - uint32_t sz = 2; + size_t fs = spi_flash_get_chip_size(); lua_getglobal(L, "print"); - switch (sz) - { - case 0: - lua_pushstring(L, "1MB"); - break; - case 1: - lua_pushstring(L, "2MB"); - break; - case 2: - lua_pushstring(L, "4MB"); - break; - case 3: - lua_pushstring(L, "8MB"); - break; - case 4: - lua_pushstring(L, "16MB"); - break; - default: - lua_pushstring(L, "32MB"); - break; - } - // lua_pushinteger(L, sz); + lua_pushfstring(L, "%dB", fs); int err = lua_pcall(L, 1, 1, 0); if (err != 0) { @@ -176,9 +157,9 @@ static int node_flashsize(lua_State *L) } // Lua: heap() -static int node_heap(lua_State *L) +static int node_heap(lua_State* L) { - uint32_t sz = system_get_free_heap_size(); + uint32_t sz = esp_get_free_heap_size(); lua_getglobal(L, "print"); lua_pushinteger(L, sz); int err = lua_pcall(L, 1, 1, 0); @@ -190,7 +171,7 @@ static int node_heap(lua_State *L) return 0; } -static int node_memusage(lua_State *L) +static int node_memusage(lua_State* L) { uint32_t usage = lua_gc(L, LUA_GCCOUNT, 0); lua_getglobal(L, "print"); @@ -204,7 +185,7 @@ static int node_memusage(lua_State *L) return 0; } -static lua_State *gL = NULL; +static lua_State* gL = NULL; #ifdef DEVKIT_VERSION_0_9 static int led_high_count = LED_HIGH_COUNT_DEFAULT; @@ -217,7 +198,7 @@ static os_timer_t keyled_timer; static int long_key_ref = LUA_NOREF; static int short_key_ref = LUA_NOREF; -static void default_long_press(void *arg) +static void default_long_press(void* arg) { if (led_high_count == 12 && led_low_count == 12) { @@ -229,13 +210,12 @@ static void default_long_press(void *arg) } // led_high_count = 1000 / READLINE_INTERVAL; // led_low_count = 1000 / READLINE_INTERVAL; - // NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", - // led_high_count, led_low_count); + // NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", led_high_count, led_low_count); } -static void default_short_press(void *arg) { system_restart(); } +static void default_short_press(void* arg) { esp_restart(); } -static void key_long_press(void *arg) +static void key_long_press(void* arg) { NODE_DBG("key_long_press is called.\n"); if (long_key_ref == LUA_NOREF) @@ -249,7 +229,7 @@ static void key_long_press(void *arg) lua_call(gL, 0, 0); } -static void key_short_press(void *arg) +static void key_short_press(void* arg) { NODE_DBG("key_short_press is called.\n"); if (short_key_ref == LUA_NOREF) @@ -263,7 +243,7 @@ static void key_short_press(void *arg) lua_call(gL, 0, 0); } -static void update_key_led(void *p) +static void update_key_led(void* p) { (void)p; uint8_t temp = 1, level = 1; @@ -321,7 +301,7 @@ static void prime_keyled_timer(void) } // Lua: led(low, high) -static int node_led(lua_State *L) +static int node_led(lua_State* L) { int low, high; if (lua_isnumber(L, 1)) @@ -355,12 +335,12 @@ static int node_led(lua_State *L) } // Lua: key(type, function) -static int node_key(lua_State *L) +static int node_key(lua_State* L) { - int *ref = NULL; + int* ref = NULL; size_t sl; - const char *str = luaL_checklstring(L, 1, &sl); + const char* str = luaL_checklstring(L, 1, &sl); if (str == NULL) return luaL_error(L, "wrong arg type"); @@ -399,13 +379,13 @@ static int node_key(lua_State *L) extern lua_Load gLoad; // Lua: input("string") -static int node_input(lua_State *L) +static int node_input(lua_State* L) { size_t l = 0; - const char *s = luaL_checklstring(L, 1, &l); + const char* s = luaL_checklstring(L, 1, &l); if (s != NULL && l > 0 && l < LUA_MAXINPUT - 1) { - lua_Load *load = &gLoad; + lua_Load* load = &gLoad; if (load->line_position == 0) { c_memcpy(load->line, s, l); @@ -423,7 +403,7 @@ static int node_input(lua_State *L) static int output_redir_ref = LUA_NOREF; static int serial_debug = 1; -void output_redirect(const char *str) +void output_redirect(const char* str) { // if(c_strlen(str)>=TX_BUFF_SIZE){ // NODE_ERR("output too long.\n"); @@ -447,7 +427,7 @@ void output_redirect(const char *str) } // Lua: output(function(c), debug) -static int node_output(lua_State *L) +static int node_output(lua_State* L) { gL = L; // luaL_checkanyfunction(L, 1); @@ -481,15 +461,15 @@ static int node_output(lua_State *L) return 0; } -static int writer(lua_State *L, const void *p, size_t size, void *u) +static int writer(lua_State* L, const void* p, size_t size, void* u) { UNUSED(L); - int file_fd = *((int *)u); + int file_fd = *((int*)u); if ((FS_OPEN_OK - 1) == file_fd) return 1; NODE_DBG("get fd:%d,size:%d\n", file_fd, size); - if (size != 0 && (size != vfs_write(file_fd, (const char *)p, size))) + if (size != 0 && (size != vfs_write(file_fd, (const char*)p, size))) return 1; NODE_DBG("write fd:%d,size:%d\n", file_fd, size); return 0; @@ -497,12 +477,12 @@ static int writer(lua_State *L, const void *p, size_t size, void *u) #define toproto(L, i) (clvalue(L->top + (i))->l.p) // Lua: compile(filename) -- compile lua file into lua bytecode, and save to .lc -static int node_compile(lua_State *L) +static int node_compile(lua_State* L) { - Proto *f; + Proto* f; int file_fd = FS_OPEN_OK - 1; size_t len; - const char *fname = luaL_checklstring(L, 1, &len); + const char* fname = luaL_checklstring(L, 1, &len); if (len > FS_NAME_MAX_LENGTH) return luaL_error(L, "filename too long"); @@ -587,11 +567,11 @@ static int node_bootreason (lua_State *L) #endif // Lua: restore() -static int node_restore(lua_State *L) +static int node_restore(lua_State* L) { // flash_init_data_default(); // flash_init_data_blank(); - system_restore(); + esp_wifi_restore(); return 0; } @@ -605,7 +585,7 @@ static int node_restore(lua_State *L) * If function is omitted, this is the default setting for future compiles * The function returns an estimated integer count of the bytes stripped. */ -static int node_stripdebug(lua_State *L) +static int node_stripdebug(lua_State* L) { int level; @@ -647,8 +627,7 @@ static int node_stripdebug(lua_State *L) int scope = luaL_checkint(L, 2); if (scope > 0) { - /* if the function parameter is a +ve integer then climb to find - * function */ + /* if the function parameter is a +ve integer then climb to find function */ lua_Debug ar; lua_pop(L, 1); /* pop level as getinfo will replace it by the function */ if (lua_getstack(L, scope, &ar)) @@ -661,7 +640,7 @@ static int node_stripdebug(lua_State *L) if (!lua_isfunction(L, 2) || lua_iscfunction(L, -1)) luaL_argerror(L, 2, "must be a Lua Function"); // lua_lock(L); - Proto *f = clvalue(L->base + 1)->l.p; + Proto* f = clvalue(L->base + 1)->l.p; // lua_unlock(L); lua_settop(L, 0); lua_pushinteger(L, luaG_stripdebug(L, f, level, 1)); @@ -697,10 +676,10 @@ const LUA_REG_TYPE node_map[] = {{LSTRKEY("restart"), LFUNCVAL(node_restart)}, #endif // Combined to dsleep(us, option) - // { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) }, + {LSTRKEY("dsleepsetoption"), LFUNCVAL(node_deepsleep_setoption)}, {LNILKEY, LNILVAL}}; -LUALIB_API int luaopen_node(lua_State *L) +LUALIB_API int luaopen_node(lua_State* L) { #if LUA_OPTIMIZE_MEMORY > 0 return 0;