From 3ca6af5da68678d809b34c7cd98bee71e0235039 Mon Sep 17 00:00:00 2001 From: Espressif Systems Date: Mon, 2 Nov 2015 19:42:55 +0800 Subject: [PATCH] NEW VERSION: 1.3.0 1. Add libssc.a, simple serial console lib. 2. Add libspiffs.a, SPI file system. 3. Add libwps.a to support WPS. 4. Add libespconn.a, Espressif connection lib. 5. Add libespnow.a to support Espressif ESP-NOW. 6. Add libmesh.a, Espressif mesh. 7. Add libnopoll.a, websocket. 8. Add make_lib.sh in "third_party" folder. 9. Add modem-sleep & light-sleep supported. 10. Update libcirom.a to support float IO. 11. Update gen_misc.sh & gen_misc.bat. 12. Update header files, add comments in doxygen style. 13. Update libsmartconfig.a to version 2.5.2. 14. Update libssl.a. 15. Updates driver (PWM/UART/GPIO/SPI/Hardware timer). 16. Update open source codes of third_party. 17. Modify "ld" files, "dram0 len" should be 0x18000 in RTOS SDK. 18. Remove header files in extra_include, which are already in compile folder. 19. Other APIs sync from non-OS SDK, more details in documentation "20B-ESP8266__RTOS_SDK_API Reference". 20. Other optimization to make the SDK more stable. --- Makefile | 1 + README.md | 34 +- bin/esp_init_data_default.bin | Bin 128 -> 128 bytes examples/driver_lib/driver/gpio.c | 58 +- examples/driver_lib/driver/hw_timer.c | 116 + examples/driver_lib/driver/uart.c | 61 +- examples/driver_lib/include/gpio.h | 222 +- examples/driver_lib/include/hw_timer.h | 85 + examples/driver_lib/include/uart.h | 187 +- examples/project_template/Makefile | 1 + examples/project_template/gen_misc.bat | 40 +- examples/project_template/gen_misc.sh | 17 +- .../project_template/include/user_config.h | 24 + examples/project_template/user/user_main.c | 28 +- examples/smart_config/Makefile | 1 + examples/smart_config/gen_misc.bat | 44 +- examples/smart_config/gen_misc.sh | 17 +- examples/smart_config/include/user_config.h | 24 + examples/smart_config/user/user_main.c | 28 +- examples/spiffs_test/Makefile | 121 ++ examples/spiffs_test/gen_misc.bat | 172 ++ examples/spiffs_test/gen_misc.sh | 176 ++ .../spiffs_test/include/spiffs_test_params.h | 22 + examples/spiffs_test/user/Makefile | 44 + examples/spiffs_test/user/test_bugreports.c | 331 +++ examples/spiffs_test/user/test_check.c | 419 ++++ examples/spiffs_test/user/test_dev.c | 122 ++ examples/spiffs_test/user/test_hydrogen.c | 1471 +++++++++++++ examples/spiffs_test/user/test_main.c | 59 + examples/spiffs_test/user/test_spiffs.c | 907 ++++++++ examples/spiffs_test/user/test_spiffs.h | 94 + examples/spiffs_test/user/testrunner.c | 215 ++ examples/spiffs_test/user/testrunner.h | 151 ++ examples/spiffs_test/user/testsuites.c | 15 + examples/websocket_demo/Makefile | 122 ++ examples/websocket_demo/gen_misc.bat | 172 ++ examples/websocket_demo/gen_misc.sh | 176 ++ examples/websocket_demo/user/Makefile | 44 + examples/websocket_demo/user/user_main.c | 40 + examples/websocket_demo/websocket/Makefile | 44 + examples/websocket_demo/websocket/websocket.c | 716 +++++++ extra_include/_ansi.h | 95 - extra_include/_syslist.h | 29 - extra_include/alloca.h | 19 - extra_include/ar.h | 69 - extra_include/argz.h | 22 - extra_include/assert.h | 29 - extra_include/ctype.h | 70 - extra_include/dirent.h | 15 - extra_include/envz.h | 16 - extra_include/errno.h | 11 - extra_include/fastmath.h | 13 - extra_include/fcntl.h | 1 - extra_include/grp.h | 94 - extra_include/iconv.h | 62 - extra_include/ieeefp.h | 249 --- extra_include/inttypes.h | 290 --- extra_include/langinfo.h | 140 -- extra_include/limits.h | 127 -- extra_include/locale.h | 59 - extra_include/machine/ansi.h | 1 - extra_include/machine/endian.h | 20 - extra_include/machine/fastmath.h | 100 - extra_include/machine/ieeefp.h | 283 --- extra_include/machine/malloc.h | 8 - extra_include/machine/param.h | 1 - extra_include/machine/setjmp-dj.h | 43 - extra_include/machine/setjmp.h | 273 --- extra_include/machine/stdlib.h | 8 - extra_include/machine/termios.h | 1 - extra_include/machine/time.h | 18 - extra_include/machine/types.h | 47 - extra_include/machine/xtensa-hal.h | 2 - extra_include/malloc.h | 169 -- extra_include/math.h | 442 ---- extra_include/memory.h | 8 - extra_include/newlib.h | 142 -- extra_include/paths.h | 7 - extra_include/process.h | 44 - extra_include/pthread.h | 300 --- extra_include/pwd.h | 78 - extra_include/reent.h | 101 - extra_include/regdef.h | 7 - extra_include/search.h | 59 - extra_include/setjmp.h | 20 - extra_include/signal.h | 27 - extra_include/stdint.h | 406 ---- extra_include/stdio.h | 468 ---- extra_include/stdlib.h | 235 -- extra_include/string.h | 100 - extra_include/sys/_types.h | 42 - extra_include/sys/cdefs.h | 123 -- extra_include/sys/config.h | 176 -- extra_include/sys/dirent.h | 15 - extra_include/sys/errno.h | 175 -- extra_include/sys/fcntl.h | 131 -- extra_include/sys/features.h | 96 - extra_include/sys/file.h | 33 - extra_include/sys/iconvnls.h | 77 - extra_include/sys/lock.h | 22 - extra_include/sys/param.h | 25 - extra_include/sys/queue.h | 471 ---- extra_include/sys/reent.h | 824 ------- extra_include/sys/resource.h | 15 - extra_include/sys/sched.h | 65 - extra_include/sys/signal.h | 310 --- extra_include/sys/stat.h | 147 -- extra_include/sys/stdio.h | 30 - extra_include/sys/syslimits.h | 65 - extra_include/sys/time.h | 83 - extra_include/sys/timeb.h | 39 - extra_include/sys/times.h | 28 - extra_include/sys/types.h | 375 ---- extra_include/sys/unistd.h | 339 --- extra_include/sys/utime.h | 22 - extra_include/sys/wait.h | 40 - extra_include/termios.h | 7 - extra_include/time.h | 255 --- extra_include/unctrl.h | 46 - extra_include/unistd.h | 13 - extra_include/utime.h | 12 - extra_include/utmp.h | 8 - extra_include/wchar.h | 83 - extra_include/wctype.h | 47 - include/espressif/c_types.h | 126 +- include/espressif/esp8266/eagle_soc.h | 41 +- include/espressif/esp8266/esp8266.h | 21 +- include/espressif/esp8266/ets_sys.h | 47 +- include/espressif/esp8266/gpio_register.h | 31 +- include/espressif/esp8266/pin_mux_register.h | 27 +- include/espressif/esp8266/spi_register.h | 21 +- include/espressif/esp8266/timer_register.h | 29 +- include/espressif/esp8266/uart_register.h | 21 +- include/espressif/esp_common.h | 88 +- include/espressif/esp_libc.h | 37 +- include/espressif/esp_misc.h | 87 +- include/espressif/esp_softap.h | 274 ++- include/espressif/esp_spiffs.h | 84 + include/espressif/esp_ssc.h | 125 ++ include/espressif/esp_sta.h | 356 ++- include/espressif/esp_system.h | 589 ++++- include/espressif/esp_timer.h | 81 +- include/espressif/esp_wifi.h | 1038 ++++++++- include/espressif/esp_wps.h | 139 ++ include/espressif/espconn.h | 691 ++++++ include/espressif/espnow.h | 351 +++ include/espressif/mesh.h | 274 +++ include/espressif/pwm.h | 122 +- include/espressif/queue.h | 296 +-- include/espressif/smartconfig.h | 154 +- include/espressif/spi_flash.h | 116 +- include/espressif/upgrade.h | 145 +- include/freertos/FreeRTOSConfig.h | 6 +- include/freertos/StackMacros.h | 2 +- include/freertos/portmacro.h | 3 +- include/freertos/task.h | 2 + include/lwip/arch/cc.h | 18 +- include/lwip/lwip/dhcpserver.h | 33 +- include/lwip/lwip/mem.h | 1 - include/lwip/lwip/netif.h | 5 + include/lwip/lwip/sockets.h | 17 + include/lwip/lwipopts.h | 37 +- include/nopoll/nopoll.h | 135 ++ include/nopoll/nopoll_config.h | 67 + include/nopoll/nopoll_conn.h | 198 ++ include/nopoll/nopoll_conn_opts.h | 73 + include/nopoll/nopoll_ctx.h | 106 + include/nopoll/nopoll_decl.h | 467 ++++ include/nopoll/nopoll_handlers.h | 329 +++ include/nopoll/nopoll_io.h | 52 + include/nopoll/nopoll_listener.h | 80 + include/nopoll/nopoll_log.h | 113 + include/nopoll/nopoll_loop.h | 52 + include/nopoll/nopoll_msg.h | 68 + include/nopoll/nopoll_private.h | 386 ++++ include/nopoll/nopoll_win32.h | 66 + include/spiffs/spiffs.h | 560 +++++ include/spiffs/spiffs_config.h | 218 ++ include/spiffs/spiffs_nucleus.h | 718 +++++++ include/ssl/ssl_bigint_impl.h | 2 +- include/ssl/ssl_compat-1.0.h | 100 + include/ssl/ssl_config.h | 5 +- include/ssl/ssl_crypto.h | 64 +- include/ssl/ssl_crypto_misc.h | 11 +- include/ssl/ssl_os_port.h | 38 + include/ssl/ssl_platform.h | 53 + include/ssl/ssl_tls1.h | 27 +- include/ssl/ssl_version.h | 2 +- ld/eagle.app.v6.ld | 2 +- ld/eagle.app.v6.new.1024.app1.ld | 2 +- ld/eagle.app.v6.new.1024.app2.ld | 2 +- ld/eagle.app.v6.new.2048.ld | 2 +- ld/eagle.app.v6.new.512.app1.ld | 2 +- ld/eagle.app.v6.new.512.app2.ld | 2 +- lib/libcirom.a | Bin 5003088 -> 5166588 bytes lib/libcrypto.a | Bin 0 -> 93492 bytes lib/libespconn.a | Bin 0 -> 79940 bytes lib/libespnow.a | Bin 0 -> 34984 bytes lib/libfreertos.a | Bin 66794 -> 68084 bytes lib/libjson.a | Bin 32038 -> 31982 bytes lib/liblwip.a | Bin 290234 -> 398404 bytes lib/libmain.a | Bin 149812 -> 166200 bytes lib/libmesh.a | Bin 0 -> 137232 bytes lib/libminic.a | Bin 16112 -> 16818 bytes lib/libnet80211.a | Bin 200172 -> 252124 bytes lib/libnopoll.a | Bin 0 -> 219718 bytes lib/libphy.a | Bin 195638 -> 194316 bytes lib/libpp.a | Bin 201732 -> 248318 bytes lib/libpwm.a | Bin 8658 -> 8646 bytes lib/libsmartconfig.a | Bin 105782 -> 107928 bytes lib/libspiffs.a | Bin 0 -> 136952 bytes lib/libssc.a | Bin 0 -> 13398 bytes lib/libssl.a | Bin 138056 -> 184810 bytes lib/libwpa.a | Bin 164152 -> 119386 bytes lib/libwps.a | Bin 0 -> 239462 bytes third_party/Makefile | 120 ++ third_party/freertos/heap_4.c | 10 +- third_party/freertos/port.c | 7 + third_party/freertos/tasks.c | 16 +- third_party/freertos/timers.c | 15 +- third_party/json/cJSON.c | 102 +- third_party/make_lib.sh | 22 + third_party/spiffs/Makefile | 44 + third_party/spiffs/esp_spiffs.c | 292 +++ third_party/spiffs/spiffs_cache.c | 303 +++ third_party/spiffs/spiffs_check.c | 973 +++++++++ third_party/spiffs/spiffs_gc.c | 568 +++++ third_party/spiffs/spiffs_hydrogen.c | 960 +++++++++ third_party/spiffs/spiffs_nucleus.c | 1899 +++++++++++++++++ third_party/ssl/crypto/sha256.c | 282 +++ third_party/ssl/crypto/sha384.c | 80 + third_party/ssl/crypto/sha512.c | 228 ++ third_party/ssl/crypto/ssl_aes.c | 47 +- third_party/ssl/crypto/ssl_crypto_misc.c | 60 +- third_party/ssl/crypto/ssl_md2.c | 160 -- third_party/ssl/crypto/ssl_rsa.c | 42 +- third_party/ssl/ssl/ssl_asn1.c | 170 +- third_party/ssl/ssl/ssl_gen_cert.c | 10 +- third_party/ssl/ssl/ssl_loader.c | 179 +- third_party/ssl/ssl/ssl_os_port.c | 54 +- third_party/ssl/ssl/ssl_platform.c | 1087 ++++++++++ third_party/ssl/ssl/ssl_tls1.c | 140 +- third_party/ssl/ssl/ssl_tls1_clnt.c | 10 +- third_party/ssl/ssl/ssl_tls1_svr.c | 41 +- third_party/ssl/ssl/ssl_x509.c | 124 +- 245 files changed, 23126 insertions(+), 10144 deletions(-) create mode 100644 examples/driver_lib/driver/hw_timer.c create mode 100644 examples/driver_lib/include/hw_timer.h create mode 100644 examples/spiffs_test/Makefile create mode 100644 examples/spiffs_test/gen_misc.bat create mode 100644 examples/spiffs_test/gen_misc.sh create mode 100644 examples/spiffs_test/include/spiffs_test_params.h create mode 100644 examples/spiffs_test/user/Makefile create mode 100644 examples/spiffs_test/user/test_bugreports.c create mode 100644 examples/spiffs_test/user/test_check.c create mode 100644 examples/spiffs_test/user/test_dev.c create mode 100644 examples/spiffs_test/user/test_hydrogen.c create mode 100644 examples/spiffs_test/user/test_main.c create mode 100644 examples/spiffs_test/user/test_spiffs.c create mode 100644 examples/spiffs_test/user/test_spiffs.h create mode 100644 examples/spiffs_test/user/testrunner.c create mode 100644 examples/spiffs_test/user/testrunner.h create mode 100644 examples/spiffs_test/user/testsuites.c create mode 100644 examples/websocket_demo/Makefile create mode 100644 examples/websocket_demo/gen_misc.bat create mode 100644 examples/websocket_demo/gen_misc.sh create mode 100644 examples/websocket_demo/user/Makefile create mode 100644 examples/websocket_demo/user/user_main.c create mode 100644 examples/websocket_demo/websocket/Makefile create mode 100644 examples/websocket_demo/websocket/websocket.c delete mode 100644 extra_include/_ansi.h delete mode 100644 extra_include/_syslist.h delete mode 100644 extra_include/alloca.h delete mode 100644 extra_include/ar.h delete mode 100644 extra_include/argz.h delete mode 100644 extra_include/assert.h delete mode 100644 extra_include/ctype.h delete mode 100644 extra_include/dirent.h delete mode 100644 extra_include/envz.h delete mode 100644 extra_include/errno.h delete mode 100644 extra_include/fastmath.h delete mode 100644 extra_include/fcntl.h delete mode 100644 extra_include/grp.h delete mode 100644 extra_include/iconv.h delete mode 100644 extra_include/ieeefp.h delete mode 100644 extra_include/inttypes.h delete mode 100644 extra_include/langinfo.h delete mode 100644 extra_include/limits.h delete mode 100644 extra_include/locale.h delete mode 100644 extra_include/machine/ansi.h delete mode 100644 extra_include/machine/endian.h delete mode 100644 extra_include/machine/fastmath.h delete mode 100644 extra_include/machine/ieeefp.h delete mode 100644 extra_include/machine/malloc.h delete mode 100644 extra_include/machine/param.h delete mode 100644 extra_include/machine/setjmp-dj.h delete mode 100644 extra_include/machine/setjmp.h delete mode 100644 extra_include/machine/stdlib.h delete mode 100644 extra_include/machine/termios.h delete mode 100644 extra_include/machine/time.h delete mode 100644 extra_include/machine/types.h delete mode 100644 extra_include/machine/xtensa-hal.h delete mode 100644 extra_include/malloc.h delete mode 100644 extra_include/math.h delete mode 100644 extra_include/memory.h delete mode 100644 extra_include/newlib.h delete mode 100644 extra_include/paths.h delete mode 100644 extra_include/process.h delete mode 100644 extra_include/pthread.h delete mode 100644 extra_include/pwd.h delete mode 100644 extra_include/reent.h delete mode 100644 extra_include/regdef.h delete mode 100644 extra_include/search.h delete mode 100644 extra_include/setjmp.h delete mode 100644 extra_include/signal.h delete mode 100644 extra_include/stdint.h delete mode 100644 extra_include/stdio.h delete mode 100644 extra_include/stdlib.h delete mode 100644 extra_include/string.h delete mode 100644 extra_include/sys/_types.h delete mode 100644 extra_include/sys/cdefs.h delete mode 100644 extra_include/sys/config.h delete mode 100644 extra_include/sys/dirent.h delete mode 100644 extra_include/sys/errno.h delete mode 100644 extra_include/sys/fcntl.h delete mode 100644 extra_include/sys/features.h delete mode 100644 extra_include/sys/file.h delete mode 100644 extra_include/sys/iconvnls.h delete mode 100644 extra_include/sys/lock.h delete mode 100644 extra_include/sys/param.h delete mode 100644 extra_include/sys/queue.h delete mode 100644 extra_include/sys/reent.h delete mode 100644 extra_include/sys/resource.h delete mode 100644 extra_include/sys/sched.h delete mode 100644 extra_include/sys/signal.h delete mode 100644 extra_include/sys/stat.h delete mode 100644 extra_include/sys/stdio.h delete mode 100644 extra_include/sys/syslimits.h delete mode 100644 extra_include/sys/time.h delete mode 100644 extra_include/sys/timeb.h delete mode 100644 extra_include/sys/times.h delete mode 100644 extra_include/sys/types.h delete mode 100644 extra_include/sys/unistd.h delete mode 100644 extra_include/sys/utime.h delete mode 100644 extra_include/sys/wait.h delete mode 100644 extra_include/termios.h delete mode 100644 extra_include/time.h delete mode 100644 extra_include/unctrl.h delete mode 100644 extra_include/unistd.h delete mode 100644 extra_include/utime.h delete mode 100644 extra_include/utmp.h delete mode 100644 extra_include/wchar.h delete mode 100644 extra_include/wctype.h create mode 100644 include/espressif/esp_spiffs.h create mode 100644 include/espressif/esp_ssc.h create mode 100644 include/espressif/esp_wps.h create mode 100644 include/espressif/espconn.h create mode 100644 include/espressif/espnow.h create mode 100644 include/espressif/mesh.h create mode 100644 include/nopoll/nopoll.h create mode 100644 include/nopoll/nopoll_config.h create mode 100644 include/nopoll/nopoll_conn.h create mode 100644 include/nopoll/nopoll_conn_opts.h create mode 100644 include/nopoll/nopoll_ctx.h create mode 100644 include/nopoll/nopoll_decl.h create mode 100644 include/nopoll/nopoll_handlers.h create mode 100644 include/nopoll/nopoll_io.h create mode 100644 include/nopoll/nopoll_listener.h create mode 100644 include/nopoll/nopoll_log.h create mode 100644 include/nopoll/nopoll_loop.h create mode 100644 include/nopoll/nopoll_msg.h create mode 100644 include/nopoll/nopoll_private.h create mode 100644 include/nopoll/nopoll_win32.h create mode 100644 include/spiffs/spiffs.h create mode 100644 include/spiffs/spiffs_config.h create mode 100644 include/spiffs/spiffs_nucleus.h create mode 100644 include/ssl/ssl_compat-1.0.h create mode 100644 include/ssl/ssl_platform.h create mode 100644 lib/libcrypto.a create mode 100644 lib/libespconn.a create mode 100644 lib/libespnow.a create mode 100644 lib/libmesh.a create mode 100644 lib/libnopoll.a create mode 100644 lib/libspiffs.a create mode 100644 lib/libssc.a create mode 100644 lib/libwps.a create mode 100644 third_party/Makefile create mode 100644 third_party/make_lib.sh create mode 100644 third_party/spiffs/Makefile create mode 100644 third_party/spiffs/esp_spiffs.c create mode 100644 third_party/spiffs/spiffs_cache.c create mode 100644 third_party/spiffs/spiffs_check.c create mode 100644 third_party/spiffs/spiffs_gc.c create mode 100644 third_party/spiffs/spiffs_hydrogen.c create mode 100644 third_party/spiffs/spiffs_nucleus.c create mode 100644 third_party/ssl/crypto/sha256.c create mode 100644 third_party/ssl/crypto/sha384.c create mode 100644 third_party/ssl/crypto/sha512.c delete mode 100644 third_party/ssl/crypto/ssl_md2.c create mode 100644 third_party/ssl/ssl/ssl_platform.c diff --git a/Makefile b/Makefile index 919c2418..9d2b589f 100644 --- a/Makefile +++ b/Makefile @@ -398,3 +398,4 @@ $(foreach image,$(GEN_IMAGES),$(eval $(call MakeImage,$(basename $(image))))) INCLUDES := $(INCLUDES) -I $(SDK_PATH)/include -I $(SDK_PATH)/extra_include INCLUDES += -I $(SDK_PATH)/include/lwip -I $(SDK_PATH)/include/lwip/ipv4 -I $(SDK_PATH)/include/lwip/ipv6 INCLUDES += -I $(SDK_PATH)/include/espressif +INCLUDES += -I $(SDK_PATH)/include/spiffs diff --git a/README.md b/README.md index b13317ad..83e87e05 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# esp_iot_rtos_sdk # +# ESP8266_RTOS_SDK # ---------- @@ -6,7 +6,7 @@ ESP8266 SDK based on FreeRTOS. ## Note ## -APIs of "esp_iot_rtos_sdk" are same as "esp_iot_sdk" +APIs of "ESP8266_RTOS_SDK" are same as "ESP8266_NONOS_SDK" More details in "Wiki" ! @@ -18,27 +18,31 @@ For gcc, please refer to [esp-open-sdk](https://github.com/pfalcon/esp-open-sdk) ## Compile ## -Clone esp_iot_rtos_sdk, e.g., to ~/esp_iot_rtos_sdk. +Clone ESP8266_RTOS_SDK, e.g., to ~/ESP8266_RTOS_SDK. - $git clone https://github.com/espressif/esp_iot_rtos_sdk.git + $git clone https://github.com/espressif/ESP8266_RTOS_SDK.git -Set sdk path: +Modify gen_misc.sh or gen_misc.bat: +For Linux£º - $export SDK_PATH=~/esp_iot_rtos_sdk + $export SDK_PATH=~/ESP8266_RTOS_SDK + $export BIN_PATH=~/ESP8266_BIN -Set bin path: +For Windows: - $export BIN_PATH=~/esp8266_bin + set SDK_PATH=/c/ESP8266_RTOS_SDK + set BIN_PATH=/c/ESP8266_BIN -Generated bins will be located here. - -SDK_PATH and BIN_PATH **MUST** be set firstly, you can write to .bashrc or other shell init sript. - -esp_iot_rtos_sdk/examples/project_template is a project template, you can copy this to anywhere, e.g., to ~/workspace/project_template. +ESP8266_RTOS_SDK/examples/project_template is a project template, you can copy this to anywhere, e.g., to ~/workspace/project_template. Generate bin: - - ./gen_misc.sh +For Linux: + + ./gen_misc.sh + +For Windows: + + gen_misc.bat Just follow the tips and steps. diff --git a/bin/esp_init_data_default.bin b/bin/esp_init_data_default.bin index 2936c7b7b82b893427a92bc204187cb535ad3d66..73d7453e85a9be2823ba340dcd15bf9bdb738890 100644 GIT binary patch delta 23 RcmZo*Y+#&FAi&Ik3IHk*0u}%O delta 9 QcmZo*Y+#&FFfl;@01qky1ONa4 diff --git a/examples/driver_lib/driver/gpio.c b/examples/driver_lib/driver/gpio.c index 4032e175..e55f2a07 100644 --- a/examples/driver_lib/driver/gpio.c +++ b/examples/driver_lib/driver/gpio.c @@ -1,5 +1,24 @@ /* - * Copyright (C) 2014 -2016 Espressif System + * 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. * */ @@ -8,8 +27,7 @@ #include "gpio.h" -void ICACHE_FLASH_ATTR -gpio_config(GPIO_ConfigTypeDef *pGPIOConfig) +void gpio_config(GPIO_ConfigTypeDef *pGPIOConfig) { uint16 gpio_pin_mask = pGPIOConfig->GPIO_Pin; uint32 io_reg; @@ -66,7 +84,6 @@ gpio_config(GPIO_ConfigTypeDef *pGPIOConfig) } while (io_num < 16); } - /* * Change GPIO pin output by setting, clearing, or disabling pins. * In general, it is expected that a bit will be set in at most one @@ -77,8 +94,7 @@ gpio_config(GPIO_ConfigTypeDef *pGPIOConfig) * writes is significant, calling code should divide a single call * into multiple calls. */ -void ICACHE_FLASH_ATTR -gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask) +void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask) { GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, set_mask); GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, clear_mask); @@ -89,8 +105,7 @@ gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 /* * Sample the value of GPIO input pins and returns a bitmask. */ -uint32 ICACHE_FLASH_ATTR -gpio_input_get(void) +uint32 gpio_input_get(void) { return GPIO_REG_READ(GPIO_IN_ADDRESS); } @@ -106,17 +121,15 @@ gpio_input_get(void) * application-specific handler may wish to use gpio_intr_pending * to check for any additional pending interrupts before it returns. */ -void ICACHE_FLASH_ATTR -gpio_intr_handler_register(void *fn) +void gpio_intr_handler_register(void *fn, void *arg) { - _xt_isr_attach(ETS_GPIO_INUM, fn); + _xt_isr_attach(ETS_GPIO_INUM, fn, arg); } /* only highlevel and lowlevel intr can use for wakeup */ -void ICACHE_FLASH_ATTR -gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state) +void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state) { uint32 pin_reg; @@ -133,8 +146,7 @@ gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state) } } -void ICACHE_FLASH_ATTR -gpio_pin_wakeup_disable(void) +void gpio_pin_wakeup_disable(void) { uint8 i; uint32 pin_reg; @@ -151,8 +163,7 @@ gpio_pin_wakeup_disable(void) } } -void ICACHE_FLASH_ATTR -gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state) +void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state) { uint32 pin_reg; @@ -166,8 +177,7 @@ gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state) portEXIT_CRITICAL(); } -void ICACHE_FLASH_ATTR -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 @@ -179,15 +189,13 @@ gpio16_output_conf(void) (READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe) | (uint32)0x1); //out enable } -void ICACHE_FLASH_ATTR -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)); } -void ICACHE_FLASH_ATTR -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 @@ -199,9 +207,7 @@ gpio16_input_conf(void) READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe); //out disable } -uint8 ICACHE_FLASH_ATTR -gpio16_input_get(void) +uint8 gpio16_input_get(void) { return (uint8)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1); } - diff --git a/examples/driver_lib/driver/hw_timer.c b/examples/driver_lib/driver/hw_timer.c new file mode 100644 index 00000000..d05bc57b --- /dev/null +++ b/examples/driver_lib/driver/hw_timer.c @@ -0,0 +1,116 @@ +/* + * 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. + * + */ + +#include "esp_common.h" + +#define US_TO_RTC_TIMER_TICKS(t) \ + ((t) ? \ + (((t) > 0x35A) ? \ + (((t) >> 2) * ((APB_CLK_FREQ >> 4) / 250000) + ((t)&0x3) * ((APB_CLK_FREQ >> 4) / 1000000)) : s\ + (((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \ + 0) + +#define FRC1_ENABLE_TIMER BIT7 +#define FRC1_AUTO_LOAD BIT6 + +typedef enum { // timer provided mode + DIVDED_BY_1 = 0, // timer clock + DIVDED_BY_16 = 4, // divided by 16 + DIVDED_BY_256 = 8, // divided by 256 +} TIMER_PREDIVED_MODE; + +typedef enum { // timer interrupt mode + TM_LEVEL_INT = 1, // level interrupt + TM_EDGE_INT = 0, // edge interrupt +} TIMER_INT_MODE; + +#define RTC_REG_WRITE(addr, val) WRITE_PERI_REG(addr, val) + +static void (* user_hw_timer_cb)(void) = NULL; + +static void hw_timer_isr_cb(void) +{ + if (user_hw_timer_cb != NULL) { + (*(user_hw_timer_cb))(); + } +} + +void hw_timer_arm(uint32 val) +{ + RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val)); +} + +void hw_timer_set_func(void (* user_hw_timer_cb_set)(void)) +{ + user_hw_timer_cb = user_hw_timer_cb_set; +} + +void hw_timer_init(uint8 req) +{ + if (req == 1) { + RTC_REG_WRITE(FRC1_CTRL_ADDRESS, + FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT); + } else { + RTC_REG_WRITE(FRC1_CTRL_ADDRESS, + DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT); + } + + _xt_isr_attach(ETS_FRC_TIMER1_INUM, hw_timer_isr_cb, NULL); + + TM1_EDGE_INT_ENABLE(); + _xt_isr_unmask(1 << ETS_FRC_TIMER1_INUM); +} + +//-------------------------------Test Code Below-------------------------------------- +#if 0 +#include "hw_timer.h" + +#define REG_WRITE(_r,_v) (*(volatile uint32 *)(_r)) = (_v) +#define REG_READ(_r) (*(volatile uint32 *)(_r)) +#define WDEV_NOW() REG_READ(0x3ff20c00) + +uint32 tick_now2 = 0; +void hw_test_timer_cb(void) +{ + static uint16 j = 0; + j++; + + if ((WDEV_NOW() - tick_now2) >= 1000000) { + static uint32 idx = 1; + tick_now2 = WDEV_NOW(); + os_printf("b%u:%d\n", idx++, j); + j = 0; + } + + //hw_timer_arm(50); +} + +void user_init(void) +{ + hw_timer_init(1); + hw_timer_set_func(hw_test_timer_cb); + hw_timer_arm(100); +} +#endif + diff --git a/examples/driver_lib/driver/uart.c b/examples/driver_lib/driver/uart.c index def2be29..b85beb7b 100644 --- a/examples/driver_lib/driver/uart.c +++ b/examples/driver_lib/driver/uart.c @@ -1,5 +1,24 @@ /* - * Copyright (C) 2014 -2016 Espressif System + * 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. * */ @@ -91,7 +110,7 @@ uart_rx_intr_handler_ssc(void) } #if 0 -LOCAL void ICACHE_FLASH_ATTR +LOCAL void uart_config(uint8 uart_no, UartDevice *uart) { if (uart_no == UART1) { @@ -130,7 +149,7 @@ uart_config(uint8 uart_no, UartDevice *uart) } #endif -LOCAL void ICACHE_FLASH_ATTR +LOCAL void uart_task(void *pvParameters) { os_event_t e; @@ -152,7 +171,7 @@ uart_task(void *pvParameters) } #if 0 -void ICACHE_FLASH_ATTR +void uart_init(void) { while (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); @@ -183,26 +202,26 @@ uart_init(void) //================================================================= -void ICACHE_FLASH_ATTR +void UART_SetWordLength(UART_Port uart_no, UART_WordLength len) { SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_BIT_NUM, len, UART_BIT_NUM_S); } -void ICACHE_FLASH_ATTR +void UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num) { SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_STOP_BIT_NUM, bit_num, UART_STOP_BIT_NUM_S); } -void ICACHE_FLASH_ATTR +void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) { CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); } -void ICACHE_FLASH_ATTR +void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) { CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN); @@ -213,14 +232,14 @@ UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) } } -void ICACHE_FLASH_ATTR +void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate) { uart_div_modify(uart_no, UART_CLK_FREQ / baud_rate); } //only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set. -void ICACHE_FLASH_ATTR +void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) { if (flow_ctrl & USART_HardwareFlowControl_RTS) { @@ -239,38 +258,38 @@ UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) } } -void ICACHE_FLASH_ATTR +void UART_WaitTxFifoEmpty(UART_Port uart_no) //do not use if tx flow control enabled { while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); } -void ICACHE_FLASH_ATTR +void UART_ResetFifo(UART_Port uart_no) { SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); } -void ICACHE_FLASH_ATTR +void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask) { WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); } -void ICACHE_FLASH_ATTR +void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask) { SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); } -void ICACHE_FLASH_ATTR -UART_intr_handler_register(void *fn) +void +UART_intr_handler_register(void *fn, void *arg) { - _xt_isr_attach(ETS_UART_INUM, fn); + _xt_isr_attach(ETS_UART_INUM, fn, arg); } -void ICACHE_FLASH_ATTR +void UART_SetPrintPort(UART_Port uart_no) { if (uart_no == 1) { @@ -280,7 +299,7 @@ UART_SetPrintPort(UART_Port uart_no) } } -void ICACHE_FLASH_ATTR +void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig) { if (uart_no == UART1) { @@ -304,7 +323,7 @@ UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig) UART_ResetFifo(uart_no); } -void ICACHE_FLASH_ATTR +void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf) { @@ -378,7 +397,7 @@ uart0_rx_intr_handler(void *para) } } -void ICACHE_FLASH_ATTR +void uart_init_new(void) { UART_WaitTxFifoEmpty(UART0); diff --git a/examples/driver_lib/include/gpio.h b/examples/driver_lib/include/gpio.h index e611eb4a..1be6c536 100644 --- a/examples/driver_lib/include/gpio.h +++ b/examples/driver_lib/include/gpio.h @@ -1,11 +1,34 @@ /* - * Copyright (C) 2014 -2016 Espressif System + * 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 __GPIO_H__ #define __GPIO_H__ +#ifdef __cplusplus +extern "C" { +#endif + #define GPIO_Pin_0 (BIT(0)) /* Pin 0 selected */ #define GPIO_Pin_1 (BIT(1)) /* Pin 1 selected */ #define GPIO_Pin_2 (BIT(2)) /* Pin 2 selected */ @@ -67,55 +90,218 @@ #define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) typedef enum { - GPIO_PIN_INTR_DISABLE = 0, - GPIO_PIN_INTR_POSEDGE = 1, - GPIO_PIN_INTR_NEGEDGE = 2, - GPIO_PIN_INTR_ANYEGDE = 3, - GPIO_PIN_INTR_LOLEVEL = 4, - GPIO_PIN_INTR_HILEVEL = 5 + GPIO_PIN_INTR_DISABLE = 0, /**< disable GPIO interrupt */ + GPIO_PIN_INTR_POSEDGE = 1, /**< GPIO interrupt type : rising edge */ + GPIO_PIN_INTR_NEGEDGE = 2, /**< GPIO interrupt type : falling edge */ + GPIO_PIN_INTR_ANYEDGE = 3, /**< GPIO interrupt type : bothe rising and falling edge */ + GPIO_PIN_INTR_LOLEVEL = 4, /**< GPIO interrupt type : low level */ + GPIO_PIN_INTR_HILEVEL = 5 /**< GPIO interrupt type : high level */ } GPIO_INT_TYPE; typedef enum { - GPIO_Mode_Input = 0x0, - GPIO_Mode_Out_OD, - GPIO_Mode_Output , - GPIO_Mode_Sigma_Delta , + GPIO_Mode_Input = 0x0, /**< GPIO mode : Input */ + GPIO_Mode_Out_OD, /**< GPIO mode : Output_OD */ + GPIO_Mode_Output , /**< GPIO mode : Output */ + GPIO_Mode_Sigma_Delta , /**< GPIO mode : Sigma_Delta */ } GPIOMode_TypeDef; typedef enum { - GPIO_PullUp_DIS = 0x0, - GPIO_PullUp_EN = 0x1, + GPIO_PullUp_DIS = 0x0, /**< disable GPIO pullup */ + GPIO_PullUp_EN = 0x1, /**< enable GPIO pullup */ } GPIO_Pullup_IF; typedef struct { - uint16 GPIO_Pin; - GPIOMode_TypeDef GPIO_Mode; - GPIO_Pullup_IF GPIO_Pullup; - GPIO_INT_TYPE GPIO_IntrType; + uint16 GPIO_Pin; /**< GPIO pin */ + GPIOMode_TypeDef GPIO_Mode; /**< GPIO mode */ + GPIO_Pullup_IF GPIO_Pullup; /**< GPIO pullup */ + GPIO_INT_TYPE GPIO_IntrType; /**< GPIO interrupt type */ } GPIO_ConfigTypeDef; +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup GPIO_Driver_APIs GPIO Driver APIs + * @brief GPIO APIs + */ + +/** @addtogroup GPIO_Driver_APIs + * @{ + */ + +/** + * @brief Set GPIO pin output level. + * + * @param gpio_no : The GPIO sequence number. + * @param bit_value : GPIO pin output level. + * + * @return null + */ #define GPIO_OUTPUT_SET(gpio_no, bit_value) \ gpio_output_conf(bit_value<>gpio_no)&BIT0) +/** + * @brief Enable GPIO16 output. + * + * @param null + * + * @return null + */ void gpio16_output_conf(void); + +/** + * @brief Set GPIO16 output level. + * + * @param uint8 value : GPIO16 output level. + * + * @return null + */ void gpio16_output_set(uint8 value); + +/** + * @brief Enable GPIO pin intput. + * + * @param null + * + * @return null + */ void gpio16_input_conf(void); + +/** + * @brief Sample the value of GPIO16 input. + * + * @param null + * + * @return the level of GPIO16 input. + */ uint8 gpio16_input_get(void); +/** + * @brief Configure Gpio pins out or input. + * + * @param uint32 set_mask : Set the output for the high bit, the + * corresponding bit is 1, the output of high, + * the corresponding bit is 0, do not change the state. + * @param uint32 set_mask : Set the output for the high bit, the + * corresponding bit is 1, the output of low, + * the corresponding bit is 0, do not change the state. + * @param uint32 enable_mask : Enable Output + * @param uint32 disable_mask : Enable Input + * + * @return null + */ void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask); -void gpio_intr_handler_register(void *fn); + +/** + * @brief Register an application-specific interrupt handler for GPIO pin interrupts. + * + * @param void *fn:interrupt handler for GPIO pin interrupts. + * @param void *arg:interrupt handler's arg + * + * @return null + */ +void gpio_intr_handler_register(void *fn, void *arg); + +/** + * @brief Configure GPIO wake up to light sleep,Only level way is effective. + * + * @param uint32 i : Gpio sequence number + * @param GPIO_INT_TYPE intr_state : the level of wake up to light sleep + * + * @return null + */ void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state); + +/** + * @brief Disable GPIO wake up to light sleep. + * + * @param null + * + * @return null + */ void gpio_pin_wakeup_disable(); + +/** + * @brief Config interrupt types of GPIO pin. + * + * @param uint32 i : The GPIO sequence number. + * @param GPIO_INT_TYPE intr_state : GPIO interrupt types. + * + * @return null + */ void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state); + +/** + * @brief Sample the value of GPIO input pins and returns a bitmask. + * + * @param null + * + * @return bitmask of GPIO pins input + */ uint32 gpio_input_get(void); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/examples/driver_lib/include/hw_timer.h b/examples/driver_lib/include/hw_timer.h new file mode 100644 index 00000000..e5f0564b --- /dev/null +++ b/examples/driver_lib/include/hw_timer.h @@ -0,0 +1,85 @@ +/* + * 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 __HW_TIMER_H__ +#define __HW_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup HW_Timer_APIs Hardware timer APIs + * @brief Hardware timer APIs + * + * @attention Hardware timer can not interrupt other ISRs. + * + */ + +/** @addtogroup HW_Timer_APIs + * @{ + */ + + +/** + * @brief Initialize the hardware ISR timer. + * + * @param uint8 req : 0, not autoload; 1, autoload mode. + * + * @return null + */ +void hw_timer_init(uint8 req); + +/** + * @brief Set a trigger timer delay to enable this timer. + * + * @param uint32 val : Timing + * - In autoload mode, range : 50 ~ 0x7fffff + * - In non-autoload mode, range : 10 ~ 0x7fffff + * + * @return null + */ +void hw_timer_arm(uint32 val); + +/** + * @brief Set timer callback function. + * + * For enabled timer, timer callback has to be set. + * + * @param uint32 val : Timing + * - In autoload mode, range : 50 ~ 0x7fffff + * - In non-autoload mode, range : 10 ~ 0x7fffff + * + * @return null + */ +void hw_timer_set_func(void (* user_hw_timer_cb_set)(void)); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/driver_lib/include/uart.h b/examples/driver_lib/include/uart.h index d6733d43..5da955fc 100644 --- a/examples/driver_lib/include/uart.h +++ b/examples/driver_lib/include/uart.h @@ -1,11 +1,34 @@ /* - * Copyright (C) 2010 -2011 Espressif System + * 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 __UART_H__ #define __UART_H__ +#ifdef __cplusplus +extern "C" { +#endif + #define ETS_UART_INTR_ENABLE() _xt_isr_unmask(1 << ETS_UART_INUM) #define ETS_UART_INTR_DISABLE() _xt_isr_mask(1 << ETS_UART_INUM) #define UART_INTR_MASK 0x1ff @@ -92,20 +115,180 @@ typedef struct { } UART_IntrConfTypeDef; //======================================= + +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup UART_Driver_APIs UART Driver APIs + * @brief UART driver APIs + */ + +/** @addtogroup UART_Driver_APIs + * @{ + */ + +/** + * @brief Wait uart tx fifo empty, do not use it if tx flow control enabled. + * + * @param UART_Port uart_no:UART0 or UART1 + * + * @return null + */ void UART_WaitTxFifoEmpty(UART_Port uart_no); //do not use if tx flow control enabled + +/** + * @brief Clear uart tx fifo and rx fifo. + * + * @param UART_Port uart_no : UART0 or UART1 + * + * @return null + */ void UART_ResetFifo(UART_Port uart_no); + +/** + * @brief Clear uart interrupt flags. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param uint32 clr_mask : To clear the interrupt bits + * + * @return null + */ void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask); + +/** + * @brief Enable uart interrupts . + * + * @param UART_Port uart_no : UART0 or UART1 + * @param uint32 ena_mask : To enable the interrupt bits + * + * @return null + */ void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask); -void UART_intr_handler_register(void *fn); + +/** + * @brief Register an application-specific interrupt handler for Uarts interrupts. + * + * @param void *fn : interrupt handler for Uart interrupts. + * @param void *arg : interrupt handler's arg. + * + * @return null + */ +void UART_intr_handler_register(void *fn, void *arg); + +/** + * @brief Config from which serial output printf function. + * + * @param UART_Port uart_no : UART0 or UART1 + * + * @return null + */ void UART_SetPrintPort(UART_Port uart_no); + +/** + * @brief Config Common parameters of serial ports. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_ConfigTypeDef *pUARTConfig : parameters structure + * + * @return null + */ void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig); + +/** + * @brief Config types of uarts. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_IntrConfTypeDef *pUARTIntrConf : parameters structure + * + * @return null + */ void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf); + +/** + * @brief Config the length of the uart communication data bits. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_WordLength len : the length of the uart communication data bits + * + * @return null + */ void UART_SetWordLength(UART_Port uart_no, UART_WordLength len); + +/** + * @brief Config the length of the uart communication stop bits. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_StopBits bit_num : the length uart communication stop bits + * + * @return null + */ void UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num); + +/** + * @brief Configure whether to open the parity. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_ParityMode Parity_mode : the enum of uart parity configuration + * + * @return null + */ void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) ; + +/** + * @brief Configure the Baud rate. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param uint32 baud_rate : the Baud rate + * + * @return null + */ void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate); + +/** + * @brief Configure Hardware flow control. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_HwFlowCtrl flow_ctrl : Hardware flow control mode + * @param uint8 rx_thresh : threshold of Hardware flow control + * + * @return null + */ void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh); + +/** + * @brief Configure trigging signal of uarts. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_LineLevelInverse inverse_mask : Choose need to flip the IO + * + * @return null + */ void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) ; + +/** + * @brief An example illustrates how to configure the serial port. + * + * @param null + * + * @return null + */ void uart_init_new(void); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/examples/project_template/Makefile b/examples/project_template/Makefile index ddb4c7ba..602a8674 100644 --- a/examples/project_template/Makefile +++ b/examples/project_template/Makefile @@ -65,6 +65,7 @@ LINKFLAGS_eagle.app.v6 = \ -lpp \ -lnet80211 \ -lwpa \ + -lcrypto \ -lmain \ -lfreertos \ -llwip \ diff --git a/examples/project_template/gen_misc.bat b/examples/project_template/gen_misc.bat index 5a5e0c1d..fd0b44fe 100644 --- a/examples/project_template/gen_misc.bat +++ b/examples/project_template/gen_misc.bat @@ -1,8 +1,43 @@ @echo off -echo gen_misc.bat version 20150819 +Rem ******NOTICE****** +Rem MUST set SDK_PATH & BIN_PATH firstly!!! +Rem example: +Rem set SDK_PATH=/c/esp_iot_sdk_freertos +Rem set BIN_PATH=/c/esp8266_bin + +set SDK_PATH="" +set BIN_PATH="" + +echo gen_misc.bat version 20150911 echo . +if not %SDK_PATH% == "" ( + echo SDK_PATH: %SDK_PATH% +) else ( + echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +if not %BIN_PATH% == "" ( + echo BIN_PATH: %BIN_PATH% +) else ( + echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +echo . +echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: +set input=default +set /p input= + +if not %input% == Y ( + if not %input% == y ( + goto end + ) +) + +echo . echo Please follow below steps(1-5) to generate specific bin(s): echo STEP 1: use boot_v1.2+ by default set boot=new @@ -132,5 +167,6 @@ echo. make clean -make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE=%spi_size_map% +make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% +:end \ No newline at end of file diff --git a/examples/project_template/gen_misc.sh b/examples/project_template/gen_misc.sh index 9a185bd1..b24f63c1 100644 --- a/examples/project_template/gen_misc.sh +++ b/examples/project_template/gen_misc.sh @@ -1,6 +1,17 @@ #!/bin/bash -echo "gen_misc.sh version 20150826" +:< + * + * 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__ diff --git a/examples/project_template/user/user_main.c b/examples/project_template/user/user_main.c index 7f22b79c..d0fabaf9 100644 --- a/examples/project_template/user/user_main.c +++ b/examples/project_template/user/user_main.c @@ -1,13 +1,27 @@ -/****************************************************************************** - * Copyright 2013-2014 Espressif Systems (Wuxi) +/* + * ESPRSSIF MIT License * - * FileName: user_main.c + * Copyright (c) 2015 * - * Description: entry file of user application + * 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. * - * Modification history: - * 2014/12/1, v1.0 create this file. -*******************************************************************************/ + */ + #include "esp_common.h" /****************************************************************************** diff --git a/examples/smart_config/Makefile b/examples/smart_config/Makefile index 1a44133a..bf3926de 100644 --- a/examples/smart_config/Makefile +++ b/examples/smart_config/Makefile @@ -63,6 +63,7 @@ LINKFLAGS_eagle.app.v6 = \ -lpp \ -lnet80211 \ -lwpa \ + -lcrypto \ -lmain \ -lfreertos \ -llwip \ diff --git a/examples/smart_config/gen_misc.bat b/examples/smart_config/gen_misc.bat index ec8a52a8..fd0b44fe 100644 --- a/examples/smart_config/gen_misc.bat +++ b/examples/smart_config/gen_misc.bat @@ -1,8 +1,43 @@ @echo off -echo gen_misc.bat version 20150819 +Rem ******NOTICE****** +Rem MUST set SDK_PATH & BIN_PATH firstly!!! +Rem example: +Rem set SDK_PATH=/c/esp_iot_sdk_freertos +Rem set BIN_PATH=/c/esp8266_bin + +set SDK_PATH="" +set BIN_PATH="" + +echo gen_misc.bat version 20150911 echo . +if not %SDK_PATH% == "" ( + echo SDK_PATH: %SDK_PATH% +) else ( + echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +if not %BIN_PATH% == "" ( + echo BIN_PATH: %BIN_PATH% +) else ( + echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +echo . +echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: +set input=default +set /p input= + +if not %input% == Y ( + if not %input% == y ( + goto end + ) +) + +echo . echo Please follow below steps(1-5) to generate specific bin(s): echo STEP 1: use boot_v1.2+ by default set boot=new @@ -126,11 +161,12 @@ if %input% equ 2 ( ) ) -touch user/user_main.c - echo. echo start... echo. -make BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE=%spi_size_map% +make clean +make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% + +:end \ No newline at end of file diff --git a/examples/smart_config/gen_misc.sh b/examples/smart_config/gen_misc.sh index 9a185bd1..b24f63c1 100644 --- a/examples/smart_config/gen_misc.sh +++ b/examples/smart_config/gen_misc.sh @@ -1,6 +1,17 @@ #!/bin/bash -echo "gen_misc.sh version 20150826" +:< + * + * 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__ diff --git a/examples/smart_config/user/user_main.c b/examples/smart_config/user/user_main.c index 6e2bfa7c..03ccc957 100644 --- a/examples/smart_config/user/user_main.c +++ b/examples/smart_config/user/user_main.c @@ -1,13 +1,27 @@ -/****************************************************************************** - * Copyright 2013-2014 Espressif Systems (Wuxi) +/* + * ESPRSSIF MIT License * - * FileName: user_main.c + * Copyright (c) 2015 * - * Description: entry file of user application + * 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. * - * Modification history: - * 2014/12/1, v1.0 create this file. -*******************************************************************************/ + */ + #include "esp_common.h" #include "freertos/FreeRTOS.h" diff --git a/examples/spiffs_test/Makefile b/examples/spiffs_test/Makefile new file mode 100644 index 00000000..28d4c237 --- /dev/null +++ b/examples/spiffs_test/Makefile @@ -0,0 +1,121 @@ +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lcirom \ + -lgcc \ + -lhal \ + -lphy \ + -lpp \ + -lnet80211 \ + -lwpa \ + -lcrypto \ + -lmain \ + -lfreertos \ + -llwip \ + -lssc \ + -lspiffs \ + $(DEP_LIBS_eagle.app.v6) \ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +CONFIGURATION_DEFINES = -DICACHE_FLASH -DSSC_INT_DRIVE + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include -I $(SDK_PATH)/include/spiffs +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/examples/spiffs_test/gen_misc.bat b/examples/spiffs_test/gen_misc.bat new file mode 100644 index 00000000..fd0b44fe --- /dev/null +++ b/examples/spiffs_test/gen_misc.bat @@ -0,0 +1,172 @@ +@echo off + +Rem ******NOTICE****** +Rem MUST set SDK_PATH & BIN_PATH firstly!!! +Rem example: +Rem set SDK_PATH=/c/esp_iot_sdk_freertos +Rem set BIN_PATH=/c/esp8266_bin + +set SDK_PATH="" +set BIN_PATH="" + +echo gen_misc.bat version 20150911 +echo . + +if not %SDK_PATH% == "" ( + echo SDK_PATH: %SDK_PATH% +) else ( + echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +if not %BIN_PATH% == "" ( + echo BIN_PATH: %BIN_PATH% +) else ( + echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +echo . +echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: +set input=default +set /p input= + +if not %input% == Y ( + if not %input% == y ( + goto end + ) +) + +echo . +echo Please follow below steps(1-5) to generate specific bin(s): +echo STEP 1: use boot_v1.2+ by default +set boot=new + +echo boot mode: %boot% +echo. + +echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin) +set input=default +set /p input=enter (0/1/2, default 0): + +if %input% equ 1 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=1 + echo generate bin: user1.bin + ) +) else ( +if %input% equ 2 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=2 + echo generate bin: user2.bin + ) +) else ( + if %boot% neq none ( + set boot=none + echo ignore boot + ) + set app=0 + echo generate bin: eagle.flash.bin+eagle.irom0text.bin +)) + +echo. + +echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz) +set input=default +set /p input=enter (0/1/2/3, default 2): + +if %input% equ 0 ( + set spi_speed=20 +) else ( +if %input% equ 1 ( + set spi_speed=26.7 +) else ( +if %input% equ 3 ( + set spi_speed=80 +) else ( + set spi_speed=40 +))) + +echo spi speed: %spi_speed% MHz +echo. + +echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT) +set input=default +set /p input=enter (0/1/2/3, default 0): + +if %input% equ 1 ( + set spi_mode=QOUT +) else ( +if %input% equ 2 ( + set spi_mode=DIO +) else ( +if %input% equ 3 ( + set spi_mode=DOUT +) else ( + set spi_mode=QIO +))) + +echo spi mode: %spi_mode% +echo. + +echo STEP 5: choose flash size and map +echo 0= 512KB( 256KB+ 256KB) +echo 2=1024KB( 512KB+ 512KB) +echo 3=2048KB( 512KB+ 512KB) +echo 4=4096KB( 512KB+ 512KB) +echo 5=2048KB(1024KB+1024KB) +echo 6=4096KB(1024KB+1024KB) +set input=default +set /p input=enter (0/1/2/3/4/5/6, default 0): + +if %input% equ 2 ( + set spi_size_map=2 + echo spi size: 1024KB + echo spi ota map: 512KB + 512KB +) else ( + if %input% equ 3 ( + set spi_size_map=3 + echo spi size: 2048KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 4 ( + set spi_size_map=4 + echo spi size: 4096KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 5 ( + set spi_size_map=5 + echo spi size: 2048KB + echo spi ota map: 1024KB + 1024KB + ) else ( + if %input% equ 6 ( + set spi_size_map=6 + echo spi size: 4096KB + echo spi ota map: 1024KB + 1024KB + ) else ( + set spi_size_map=0 + echo spi size: 512KB + echo spi ota map: 256KB + 256KB + ) + ) + ) + ) +) + +echo. +echo start... +echo. + +make clean + +make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% + +:end \ No newline at end of file diff --git a/examples/spiffs_test/gen_misc.sh b/examples/spiffs_test/gen_misc.sh new file mode 100644 index 00000000..b24f63c1 --- /dev/null +++ b/examples/spiffs_test/gen_misc.sh @@ -0,0 +1,176 @@ +#!/bin/bash + +:< +#include +#include +//#include +#include + +SUITE(bug_tests) +void setup() { + _setup_test_only(); +} +void teardown() { + _teardown(); +} + +TEST(nodemcu_full_fs_1) { + fs_reset_specific(0, 1280*1024, 4096*20, 4096, 4096, 128); + + 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, 1280*1024, 4096*22, 4096, 4096, 128); + + 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); +#if 0 + // before gc in v3.1 + 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); +#else + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_FULL); + SPIFFS_clearerr(FS); +#endif + printf(" remove files\n"); + res = SPIFFS_remove(FS, "test1.txt"); + TEST_CHECK(res == SPIFFS_OK); +#if 0 + res = SPIFFS_remove(FS, "test2.txt"); + TEST_CHECK(res == SPIFFS_OK); +#endif + + 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(magic_test) { + // one obj lu page, not full + fs_reset_specific(0, 1280*1024, 4096*16, 4096, 4096*1, 128); + TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS)); + // one obj lu page, full + fs_reset_specific(0, 1280*1024, 4096*16, 4096, 4096*2, 128); + TEST_CHECK(!SPIFFS_CHECK_MAGIC_POSSIBLE(FS)); + // two obj lu pages, not full + fs_reset_specific(0, 1280*1024, 4096*16, 4096, 4096*4, 128); + TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS)); + + return TEST_RES_OK; + +} TEST_END(magic_test) + +TEST(nodemcu_309) { + fs_reset_specific(0, 1280*1024, 4096*20, 4096, 4096, 128); + + int res; + spiffs_file fd; + int j; + + for (j = 1; j <= 3; j++) { + char fname[32]; + sprintf(fname, "20K%i.txt", j); + fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_DIRECT, 0); + TEST_CHECK(fd > 0); + int i; + spiffs_stat s; + res = SPIFFS_OK; + u8_t err = 0; + for (i = 1; i <= 1280; i++) { + char *buf = "0123456789ABCDE\n"; + res = SPIFFS_write(FS, fd, buf, strlen(buf)); + if (!err && res < 0) { + printf("err @ %i,%i\n", i, j); + err = 1; + } + } + } + + int errno = SPIFFS_errno(FS); + TEST_CHECK(errno == SPIFFS_ERR_FULL); + + u32_t total; + u32_t used; + + SPIFFS_info(FS, &total, &used); + printf("total:%i\nused:%i\nremain:%i\nerrno:%i\n", total, used, total-used, errno); + TEST_CHECK(total-used < 11000); + + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + + SPIFFS_opendir(FS, "/", &d); + int spoon_guard = 0; + while ((pe = SPIFFS_readdir(&d, pe))) { + printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); + TEST_CHECK(spoon_guard++ < 3); + } + TEST_CHECK(spoon_guard == 3); + SPIFFS_closedir(&d); + + return TEST_RES_OK; + +} TEST_END(nodemcu_309) + + +TEST(robert) { + // create a clean file system starting at address 0, 2 megabytes big, + // sector size 65536, block size 65536, page size 256 + fs_reset_specific(0, 1280*1024, 128*1024, 4096, 4096, 128); + + int res; + spiffs_file fd; + char fname[32]; + + sprintf(fname, "test.txt"); + fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC, 0); + TEST_CHECK(fd > 0); + int i; + res = SPIFFS_OK; + char buf[500]; + memset(buf, 0xaa, 500); + res = SPIFFS_write(FS, fd, buf, 500); + TEST_CHECK(res >= SPIFFS_OK); + SPIFFS_close(FS, fd); + + int errno = SPIFFS_errno(FS); + TEST_CHECK(errno == SPIFFS_OK); + + //SPIFFS_vis(FS); + // unmount + SPIFFS_unmount(FS); + + // remount + res = fs_mount_specific(1280*1024, 256*1024, 4096, 4096, 128); + TEST_CHECK(res== SPIFFS_OK); + + //SPIFFS_vis(FS); + + spiffs_stat s; + TEST_CHECK(SPIFFS_stat(FS, fname, &s) == SPIFFS_OK); + printf("file %s stat size %i\n", s.name, s.size); + TEST_CHECK(s.size == 500); + + return TEST_RES_OK; + +} TEST_END(robert) + + +TEST(spiffs_12) { + fs_reset_specific(0, 1280*1024, 128*1024, 4096, 4096, 128); + + int res; + spiffs_file fd; + int j = 1; + + while (1) { + char fname[32]; + sprintf(fname, "file%i.txt", j); + fd = SPIFFS_open(FS, fname, SPIFFS_RDWR | SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_DIRECT, 0); + if (fd <=0) break; + + int i; + res = SPIFFS_OK; + for (i = 1; i <= 100; i++) { + char *buf = "0123456789ABCDE\n"; + res = SPIFFS_write(FS, fd, buf, strlen(buf)); + if (res < 0) break; + } + SPIFFS_close(FS, fd); + j++; + } + + int errno = SPIFFS_errno(FS); + TEST_CHECK(errno == SPIFFS_ERR_FULL); + + u32_t total; + u32_t used; + + SPIFFS_info(FS, &total, &used); + printf("total:%i (%iK)\nused:%i (%iK)\nremain:%i (%iK)\nerrno:%i\n", total, total/1024, used, used/1024, total-used, (total-used)/1024, errno); + + spiffs_DIR d; + struct spiffs_dirent e; + struct spiffs_dirent *pe = &e; + + SPIFFS_opendir(FS, "/", &d); + while ((pe = SPIFFS_readdir(&d, pe))) { + printf("%s [%04x] size:%i\n", pe->name, pe->obj_id, pe->size); + } + SPIFFS_closedir(&d); + + //SPIFFS_vis(FS); + + //dump_page(FS, 0); + //dump_page(FS, 1); + + return TEST_RES_OK; + +} TEST_END(spiffs_12) + + +SUITE_END(bug_tests) diff --git a/examples/spiffs_test/user/test_check.c b/examples/spiffs_test/user/test_check.c new file mode 100644 index 00000000..b7439469 --- /dev/null +++ b/examples/spiffs_test/user/test_check.c @@ -0,0 +1,419 @@ +/* + * test_dev.c + * + * Created on: Jul 14, 2013 + * Author: petera + */ + + +#include "testrunner.h" +#include "test_spiffs.h" +#include "spiffs_nucleus.h" +#include "spiffs.h" +#include +#include +#include +//#include +#include + + +SUITE(check_tests) +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); + MALLOC_CHECK(corruption != NULL, data_range); + memrand(corruption, data_range); + u32_t addr = 0 * SPIFFS_CFG_LOG_PAGE_SZ(FS) * SPIFFS_OBJ_LOOKUP_PAGES(FS) + SPIFFS_CFG_PHYS_ADDR(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)); + +#if SPIFFS_CACHE + 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 +#if SPIFFS_CACHE + 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_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; +#endif + + SPIFFS_check(FS); + + 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 +#if SPIFFS_CACHE + 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_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; +#endif + + SPIFFS_check(FS); + + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + 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; +#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); + + // 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; +#endif + SPIFFS_check(FS); + + res = read_and_verify("file"); + TEST_CHECK(res >= 0); + + 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; +#endif + SPIFFS_check(FS); + + 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); + +#if SPIFFS_CACHE + spiffs_cache *cache = spiffs_get_cache(FS); + cache->cpage_use_map = 0; +#endif + SPIFFS_check(FS); + + return TEST_RES_OK; +} TEST_END(index_cons4) + + + +SUITE_END(check_tests) diff --git a/examples/spiffs_test/user/test_dev.c b/examples/spiffs_test/user/test_dev.c new file mode 100644 index 00000000..957a6d84 --- /dev/null +++ b/examples/spiffs_test/user/test_dev.c @@ -0,0 +1,122 @@ +/* + * test_dev.c + * + * Created on: Jul 14, 2013 + * Author: petera + */ + + +#include "testrunner.h" +#include "test_spiffs.h" +#include "spiffs_nucleus.h" +#include "spiffs.h" +#include +#include +#include +//#include +#include + + +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); + MALLOC_CHECK(buf != NULL, 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); + + clear_flash_ops_log(); + +#if SPIFFS_CACHE + // 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); + + 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); + MALLOC_CHECK(buf2 != NULL, 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); + } + SPIFFS_close(FS, fd); + + + printf(" FS check\n"); + SPIFFS_check(FS); + + 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); + + free(buf); + + return TEST_RES_OK; + +} TEST_END(interrupted_write) + +SUITE_END(dev_tests) diff --git a/examples/spiffs_test/user/test_hydrogen.c b/examples/spiffs_test/user/test_hydrogen.c new file mode 100644 index 00000000..5902a38e --- /dev/null +++ b/examples/spiffs_test/user/test_hydrogen.c @@ -0,0 +1,1471 @@ +/* + * test_suites.c + * + * Created on: Jun 19, 2013 + * Author: petera + */ + + +#include "testrunner.h" +#include "test_spiffs.h" +#include "spiffs_nucleus.h" +#include "spiffs.h" +#include +#include +#include +//#include +#include + +SUITE(hydrogen_tests) +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; +} +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; +} +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; +} +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; +} +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; +} +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; +} +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; +} +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; +} +TEST_END(file_by_creat) + +TEST(list_dir) +{ + int res; + + 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); + } + + 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); + + TEST_CHECK(found == file_cnt); + + return TEST_RES_OK; +} +TEST_END(list_dir) + + +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; + + 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); + + found = 0; + SPIFFS_opendir(FS, "/", &d); + while ((pe = SPIFFS_readdir(&d, pe))) { + found++; + } + SPIFFS_closedir(&d); + + TEST_CHECK(found == 0); + + return TEST_RES_OK; + +} TEST_END(open_by_dirent) + + +TEST(rename) { + int res; + + char *src_name = "baah"; + char *dst_name = "booh"; + char *dst_name2 = "beeh"; + int size = SPIFFS_DATA_PAGE_SIZE(FS); + + res = test_create_and_write_file(src_name, size, size); + TEST_CHECK(res >= 0); + + res = SPIFFS_rename(FS, src_name, dst_name); + 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_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; +} +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; +} +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; +} +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; +} +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; +} +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; +} +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) / 2; + 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; +} +TEST_END(write_big_files_chunks_huge) + + +TEST(truncate_big_file) +{ + int size = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS) / 2; + 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); + + 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; + + 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); + + 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); + + TEST_CHECK(rdata == data3); + + return TEST_RES_OK; +} +TEST_END(simultaneous_write) + + +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) + +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; + + u8_t *buf = malloc(size); + MALLOC_CHECK_RETURN_1(buf != NULL, 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); + + spiffs_stat stat; + res = SPIFFS_fstat(FS, fd, &stat); + CHECK(res >= 0); + CHECK(stat.size == size); + + SPIFFS_close(FS, fd); + + fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); + CHECK(fd >= 0); + + u8_t *rbuf = malloc(size); + MALLOC_CHECK_RETURN_1(rbuf != NULL, 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; + } + + CHECK(memcmp(&rbuf[0], &buf[0], size) == 0); + + SPIFFS_close(FS, fd); + + free(rbuf); + free(buf); + + 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_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_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_END(read_chunk_index) + + +TEST(read_chunk_huge) +{ + int sz = (2*(FS)->cfg.phys_size)/15; + 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; + + u8_t *buf = malloc(size); + MALLOC_CHECK(buf != NULL, 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); + + spiffs_stat stat; + res = SPIFFS_fstat(FS, fd, &stat); + CHECK(res >= 0); + CHECK(stat.size == size); + + SPIFFS_close(FS, fd); + + fd = SPIFFS_open(FS, name, SPIFFS_RDONLY, 0); + CHECK(fd >= 0); + + u8_t *rbuf = malloc(size+10); + MALLOC_CHECK(rbuf != NULL, size+10); + res = SPIFFS_read(FS, fd, rbuf, size+10); + + SPIFFS_close(FS, fd); + + free(rbuf); + free(buf); + + TEST_CHECK(res == size); + + 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); + + 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, 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; +#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) + + +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); + + // 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)); + +#if SPIFFS_CACHE + // 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); + MALLOC_CHECK(buf != NULL, 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); + MALLOC_CHECK(buf != NULL, 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_simple_modification) + + +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); + MALLOC_CHECK(buf != NULL, 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); + MALLOC_CHECK(buf != NULL, 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) + + +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); + MALLOC_CHECK(buf != NULL, 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); + + 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); + MALLOC_CHECK(buf != NULL, 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_multi) + + +TEST(lseek_read) { + int res; + spiffs_file fd; + char *fname = "seekfile"; + int len = (FS_PURE_DATA_PAGES(FS) / 2) * SPIFFS_DATA_PAGE_SIZE(FS) / 2; + int runs = 100000; + + fd = SPIFFS_open(FS, fname, SPIFFS_TRUNC | SPIFFS_CREAT | SPIFFS_RDWR, 0); + TEST_CHECK(fd > 0); + u8_t *refbuf = malloc(len); + MALLOC_CHECK(refbuf != NULL, len); + memrand(refbuf, len); + res = SPIFFS_write(FS, fd, refbuf, len); + TEST_CHECK(res >= 0); + + int offs = 0; + res = SPIFFS_lseek(FS, fd, 0, SPIFFS_SEEK_SET); + TEST_CHECK(res >= 0); + + 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); + } + + free(refbuf); + SPIFFS_close(FS, fd); + + return TEST_RES_OK; +} +TEST_END(lseek_read) + + +TEST(gc_quick) +{ + char name[32]; + int f; + int size = SPIFFS_DATA_PAGE_SIZE(FS); + int files = (SPIFFS_PAGES_PER_BLOCK(FS) - SPIFFS_OBJ_LOOKUP_PAGES(FS))/2; + int res; + + // negative, try quick gc on clean sys + res = SPIFFS_gc_quick(FS, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NO_DELETED_BLOCKS); + + // fill block with files + for (f = 0; f < files; f++) { + sprintf(name, "file%i", f); + res = test_create_and_write_file(name, size, 1); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files; f++) { + sprintf(name, "file%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + // remove all files in block + for (f = 0; f < files; f++) { + sprintf(name, "file%i", f); + res = SPIFFS_remove(FS, name); + TEST_CHECK(res >= 0); + } + + // do a quick gc + res = SPIFFS_gc_quick(FS, 0); + TEST_CHECK(res >= 0); + + // fill another block with files but two pages + for (f = 0; f < files - 1; f++) { + sprintf(name, "file%i", f); + res = test_create_and_write_file(name, size, 1); + TEST_CHECK(res >= 0); + } + for (f = 0; f < files - 1; f++) { + sprintf(name, "file%i", f); + res = read_and_verify(name); + TEST_CHECK(res >= 0); + } + // remove all files in block leaving two free pages in block + for (f = 0; f < files - 1; f++) { + sprintf(name, "file%i", f); + res = SPIFFS_remove(FS, name); + TEST_CHECK(res >= 0); + } + + // negative, try quick gc where no fully deleted blocks exist + res = SPIFFS_gc_quick(FS, 0); + TEST_CHECK(res < 0); + TEST_CHECK(SPIFFS_errno(FS) == SPIFFS_ERR_NO_DELETED_BLOCKS); + + // positive, try quick gc where allowing two free pages + res = SPIFFS_gc_quick(FS, 2); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; +} +TEST_END(gc_quick) + + +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); + + 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; +} +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; +} +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; +} +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, 1); + 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, 1); + 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; +} +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); + TEST_CHECK(res >= 0); + } + printf("\n"); + + res = read_and_verify("long_clobber"); + TEST_CHECK(res >= 0); + + res = SPIFFS_check(FS); + TEST_CHECK(res >= 0); + + return TEST_RES_OK; +} +TEST_END(long_run) + +SUITE_END(hydrogen_tests) + diff --git a/examples/spiffs_test/user/test_main.c b/examples/spiffs_test/user/test_main.c new file mode 100644 index 00000000..be3bbc85 --- /dev/null +++ b/examples/spiffs_test/user/test_main.c @@ -0,0 +1,59 @@ +#include "esp_common.h" +#include "testrunner.h" +#include +#include "spiffs_test_params.h" + +enum { + CMD_SPIFFS, + CMD_END, +}; + +#define SSC_CMD_N (CMD_END + 1) + +LOCAL void spiffs_test_init(void); + +LOCAL ssc_cmd_t sscCmdSet[SSC_CMD_N] = { + {"fs", CMD_T_SYNC, CMD_SPIFFS, spiffs_test_init, NULL}, + {"", CMD_T_ASYNC, CMD_END, NULL, NULL} +}; + +void spiffs_test_init(void) +{ + char *argv[10], pLine[128]; + int argc; + + strcpy(pLine, ssc_param_str()); + argc = ssc_parse_param(pLine, argv); + + run_tests(argc, argv); +} + +void spiffs_test_help(void) +{ + printf("\nhelp:\n"); + printf("$ fs \n"); +} + +void spiffs_fs1_init(void) +{ + struct esp_spiffs_config config; + + config.phys_size = FS1_FLASH_SIZE; + config.phys_addr = FS1_FLASH_ADDR; + config.phys_erase_block = SECTOR_SIZE; + config.log_block_size = LOG_BLOCK; + config.log_page_size = LOG_PAGE; + config.fd_buf_size = FD_BUF_SIZE * 2; + config.cache_buf_size = CACHE_BUF_SIZE; + + esp_spiffs_init(&config); +} + +void user_init(void) +{ + spiffs_fs1_init(); + + ssc_attach(SSC_BR_74880); + ssc_register(sscCmdSet, SSC_CMD_N, spiffs_test_help); +} + diff --git a/examples/spiffs_test/user/test_spiffs.c b/examples/spiffs_test/user/test_spiffs.c new file mode 100644 index 00000000..f8519876 --- /dev/null +++ b/examples/spiffs_test/user/test_spiffs.c @@ -0,0 +1,907 @@ +/* + * test_spiffs.c + * + * Created on: Jun 19, 2013 + * Author: petera + */ + + +#include +#include +#include + +#include "spiffs.h" +#include "spiffs_nucleus.h" + +#include "testrunner.h" + +#include "test_spiffs.h" + +#include +#include +#include +//#include +#include +#include "spiffs_test_params.h" + +//#define AREA(x) area[(x) - addr_offset] + +//static unsigned char area[PHYS_FLASH_SIZE]; +static u32_t addr_offset = 0; + +static int erases[FS2_FLASH_SIZE/SECTOR_SIZE]; +static char _path[256]; +static u32_t bytes_rd = 0; +static u32_t bytes_wr = 0; +static u32_t reads = 0; +static u32_t writes = 0; +static u32_t error_after_bytes_written = 0; +static u32_t error_after_bytes_read = 0; +static char error_after_bytes_written_once_only = 0; +static char error_after_bytes_read_once_only = 0; +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 _fds[FD_BUF_SIZE * 2]; +static u8_t _cache[CACHE_BUF_SIZE]; + +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; +} + +void clear_test_path() { +//TODO: need to add later +#if 0 + 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); + } +#endif +} + +#define FLASH_UNIT_SIZE 4 + +static s32_t esp_spiffs_readwrite(u32_t addr, u32_t size, u8_t *p, int write) +{ + /* + * With proper configurarion spiffs never reads or writes more than + * LOG_PAGE_SIZE + */ + + if (size > __fs.cfg.log_page_size) { + printf("Invalid size provided to read/write (%d)\n\r", (int) size); + return SPIFFS_ERR_NOT_CONFIGURED; + } + + char tmp_buf[__fs.cfg.log_page_size + FLASH_UNIT_SIZE * 2]; + u32_t aligned_addr = addr & (-FLASH_UNIT_SIZE); + u32_t aligned_size = + ((size + (FLASH_UNIT_SIZE - 1)) & -FLASH_UNIT_SIZE) + FLASH_UNIT_SIZE; + + int res = spi_flash_read(aligned_addr, (u32_t *) tmp_buf, aligned_size); + + if (res != 0) { + printf("spi_flash_read failed: %d (%d, %d)\n\r", res, (int) aligned_addr, + (int) aligned_size); + return res; + } + + if (!write) { + memcpy(p, tmp_buf + (addr - aligned_addr), size); + return SPIFFS_OK; + } + + memcpy(tmp_buf + (addr - aligned_addr), p, size); + + res = spi_flash_write(aligned_addr, (u32_t *) tmp_buf, aligned_size); + + if (res != 0) { +// printf("spi_flash_write failed: %d (%d, %d)\n\r", res, +// (int) aligned_addr, (int) aligned_size); + return res; + } + + return SPIFFS_OK; +} + +static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) +{ + return esp_spiffs_readwrite(addr, size, dst, 0); +} + +static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) +{ + return esp_spiffs_readwrite(addr, size, src, 1); +} + +static s32_t esp_spiffs_erase(u32_t addr, u32_t size) +{ + /* + * With proper configurarion spiffs always + * provides here sector address & sector size + */ + if (size != __fs.cfg.phys_erase_block || addr % __fs.cfg.phys_erase_block != 0) { + printf("Invalid size provided to esp_spiffs_erase (%d, %d)\n\r", + (int) addr, (int) size); + return SPIFFS_ERR_NOT_CONFIGURED; + } + + return spi_flash_erase_sector(addr / __fs.cfg.phys_erase_block); +} + + +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, FS2_FLASH_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, FS2_FLASH_ADDR + FS2_FLASH_SIZE); + exit(0); + } + + return esp_spiffs_read(addr, size, dst); +} + +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, FS2_FLASH_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, FS2_FLASH_ADDR + FS2_FLASH_SIZE); + exit(0); + } + +#if 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]; + } +#endif + + return esp_spiffs_write(addr, size, src); +} + +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]++; + return esp_spiffs_erase(addr, size); +} + +void hexdump_mem(u8_t *b, u32_t len) { + while (len--) { + if ((((int)b)&0x1f) == 0) { + printf("\n"); + } + printf("%02x", *b++); + } + printf("\n"); +} + +void hexdump(u32_t addr, u32_t len) { +//TODO: need to add later +#if 0 + 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)); + } + } + printf("\n"); +#endif +} + +void dump_page(spiffs *fs, spiffs_page_ix p) { +//TODO: need to add later +#if 0 + 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); +#endif +} + +void area_write(u32_t addr, u8_t *buf, u32_t size) { + u32_t phys_erase_block = __fs.cfg.phys_erase_block; + u32_t addr_align = addr & ~(phys_erase_block - 1); + u8_t sec_num = (addr + size - addr_align - 1) / phys_erase_block + 1; + u32_t buf_index = 0; + u8_t *bbuf = malloc(phys_erase_block); + + MALLOC_CHECK_RETURN(bbuf != NULL, phys_erase_block); + + int i, j; + for (i = 0; i < sec_num; i++) { + spi_flash_read(addr_align + i * phys_erase_block, (u32_t *)bbuf, phys_erase_block); + spi_flash_erase_sector((addr_align + i * phys_erase_block) / phys_erase_block); + + for (j = buf_index; + ((addr - i * phys_erase_block) % phys_erase_block + j) < phys_erase_block && j < size; + j++) { + bbuf[addr % phys_erase_block + j] = buf[j]; + } + + buf_index = j; + spi_flash_write(addr_align + i * phys_erase_block, (u32_t *)bbuf, phys_erase_block); + } + + free(bbuf); +} + +void area_read(u32_t addr, u8_t *buf, u32_t size) { + u32_t addr_align = addr & ~(3); + u8_t read_num = (addr + size - addr_align - 1) / 4 + 1; + u8_t *bbuf = malloc(read_num * 4); + + MALLOC_CHECK_RETURN(bbuf != NULL, read_num * 4); + + spi_flash_read(addr, (u32_t *)bbuf, read_num * 4); + memcpy(buf, &bbuf[addr & 3], size); + free(bbuf); +} + +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"); +} + +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("??"); + } + printf("\n"); + } +} + +void fs_set_addr_offset(u32_t offset) { + addr_offset = offset; +} + +s32_t fs_mount_specific(u32_t phys_addr, u32_t phys_size, + u32_t phys_sector_size, + u32_t log_block_size, u32_t log_page_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; + + return SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f); +} + +void fs_reset_specific(u32_t addr_offset, u32_t phys_addr, u32_t phys_size, + u32_t phys_sector_size, + u32_t log_block_size, u32_t log_page_size) { + fs_set_addr_offset(addr_offset); + + u8_t i; + for (i = 0; i < phys_size / phys_sector_size; i++) { + spi_flash_erase_sector(phys_addr / phys_sector_size + i); + } + + memset(&__fs, 0, sizeof(__fs)); + + memset(erases,0,sizeof(erases)); + memset(_cache,0,sizeof(_cache)); + + s32_t res = fs_mount_specific(phys_addr, phys_size, phys_sector_size, log_block_size, log_page_size); + +#if SPIFFS_USE_MAGIC + if (res == SPIFFS_OK) { + SPIFFS_unmount(&__fs); + } + res = SPIFFS_format(&__fs); + if (res != SPIFFS_OK) { + printf("format failed, %i\n", SPIFFS_errno(&__fs)); + } + res = fs_mount_specific(phys_addr, phys_size, phys_sector_size, log_block_size, log_page_size); + if (res != SPIFFS_OK) { + printf("mount failed, %i\n", SPIFFS_errno(&__fs)); + } +#endif + + clear_flash_ops_log(); + log_flash_ops = 1; + fs_check_fixes = 0; +} + +void fs_reset() { + esp_spiffs_deinit(1); + spiffs_fs1_init(); + fs_reset_specific(0, FS2_FLASH_ADDR, FS2_FLASH_SIZE, SECTOR_SIZE, SECTOR_SIZE, LOG_PAGE); +} + +void fs_load_dump(char *fname) { + int pfd = open(fname, O_RDONLY, S_IRUSR | S_IWUSR); + +//too large +#if 0 + read(pfd, area, sizeof(area)); +#endif + + close(pfd); +} + +void set_flash_ops_log(int enable) { + log_flash_ops = enable; +} + +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; +} + +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; +} + +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(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); +} + +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 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); + + return 0; +} + +static void test_on_stop(test *t) { + printf(" spiffs errno:%i\n", SPIFFS_errno(&__fs)); +#if SPIFFS_TEST_VISUALISATION + 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; +} + +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); + MALLOC_CHECK_RETURN_1(buf != NULL, 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); + } + 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 SPIFFS_CACHE +#if SPIFFS_CACHE_STATS +static u32_t chits_tot = 0; +static u32_t cmiss_tot = 0; +#endif +#endif + +void _setup_test_only() { + fs_set_validate_flashing(1); + test_init(test_on_stop); +} + +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); +#if SPIFFS_GC_STATS + 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 = 0; + cmiss_tot = 0; +#endif +#endif + dump_flash_access_stats(); + clear_flash_ops_log(); +#if SPIFFS_GC_STATS + 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: + 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)))/2; + case LARGE: + return (FS)->cfg.phys_size/40; + } + 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); + MALLOC_CHECK_RETURN_1(tfiles != NULL, 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); + MALLOC_CHECK_RETURN_1(buf != NULL, 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); + MALLOC_CHECK_RETURN_1(buf != NULL, 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); + MALLOC_CHECK_RETURN_1(buf != NULL, 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); + MALLOC_CHECK_RETURN_1(buf != NULL, 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++; + } + free(tfiles); + return 0; +} + + + diff --git a/examples/spiffs_test/user/test_spiffs.h b/examples/spiffs_test/user/test_spiffs.h new file mode 100644 index 00000000..3fd1991c --- /dev/null +++ b/examples/spiffs_test/user/test_spiffs.h @@ -0,0 +1,94 @@ +/* + * test_spiffs.h + * + * Created on: Jun 19, 2013 + * Author: petera + */ + +#ifndef TEST_SPIFFS_H_ +#define TEST_SPIFFS_H_ + +#include "spiffs.h" + +#define FS &__fs + +extern spiffs __fs; + + +#define CHECK(r) if (!(r)) return -1; +#define CHECK_RES(r) if (r < 0) return -1; +#define FS_PURE_DATA_PAGES(fs) \ + ((fs)->cfg.phys_size / (fs)->cfg.log_page_size - (fs)->block_count * SPIFFS_OBJ_LOOKUP_PAGES(fs)) +#define FS_PURE_DATA_SIZE(fs) \ + FS_PURE_DATA_PAGES(fs) * SPIFFS_DATA_PAGE_SIZE(fs) + +typedef enum { + EMPTY, + SMALL, + MEDIUM, + LARGE, +} tfile_size; + +typedef enum { + UNTAMPERED, + APPENDED, + MODIFIED, + REWRITTEN, +} tfile_type; + +typedef enum { + SHORT = 4, + NORMAL = 20, + LONG = 100, +} tfile_life; + +typedef struct { + tfile_size tsize; + tfile_type ttype; + tfile_life tlife; +} tfile_conf; + +typedef struct { + int state; + spiffs_file fd; + tfile_conf cfg; + char name[32]; +} tfile; + + +void fs_reset(); +void fs_reset_specific(u32_t addr_offset, u32_t phys_addr, u32_t phys_size, + u32_t phys_sector_size, + u32_t log_block_size, u32_t log_page_size); +s32_t fs_mount_specific(u32_t phys_addr, u32_t phys_size, + u32_t phys_sector_size, + u32_t log_block_size, u32_t log_page_size); +void fs_set_addr_offset(u32_t offset); +int read_and_verify(char *name); +int read_and_verify_fd(spiffs_file fd, char *name); +void dump_page(spiffs *fs, spiffs_page_ix p); +void hexdump(u32_t addr, u32_t len); +char *make_test_fname(const char *name); +void clear_test_path(); +void area_write(u32_t addr, u8_t *buf, u32_t size); +void area_read(u32_t addr, u8_t *buf, u32_t size); +void dump_erase_counts(spiffs *fs); +void dump_flash_access_stats(); +void set_flash_ops_log(int enable); +void clear_flash_ops_log(); +u32_t get_flash_ops_log_read_bytes(); +u32_t get_flash_ops_log_write_bytes(); +void invoke_error_after_read_bytes(u32_t b, char once_only); +void invoke_error_after_write_bytes(u32_t b, char once_only); + +void memrand(u8_t *b, int len); +int test_create_file(char *name); +int test_create_and_write_file(char *name, int size, int chunk_size); +void _setup(); +void _setup_test_only(); +void _teardown(); +u32_t tfile_get_size(tfile_size s); +int run_file_config(int cfg_count, tfile_conf* cfgs, int max_runs, int max_concurrent_files, int dbg); + + +#endif /* TEST_SPIFFS_H_ */ diff --git a/examples/spiffs_test/user/testrunner.c b/examples/spiffs_test/user/testrunner.c new file mode 100644 index 00000000..3b7915ae --- /dev/null +++ b/examples/spiffs_test/user/testrunner.c @@ -0,0 +1,215 @@ +/* + * testrunner.c + * + * Created on: Jun 18, 2013 + * Author: petera + */ + + +#include +#include +#include + +#include +#include +#include +//#include +#include + +#include "esp_common.h" +#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; + char incl_filter[256]; + char excl_filter[256]; +} test_main; + +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(line)-1) == 0) { + free(line); + return 1; + } + } + free(line); + return 0; + } else { + return 1; + } +} + +static char check_incl_filter(char *name) { + if (strlen(test_main.incl_filter)== 0) return 1; + return strstr(name, test_main.incl_filter) == 0 ? 0 : 1; +} + +static char check_excl_filter(char *name) { + if (strlen(test_main.excl_filter)== 0) return 1; + return strstr(name, test_main.excl_filter) == 0 ? 1 : 0; +} + +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; + if (!check_incl_filter(name)) return; + if (!check_excl_filter(name)) return; + DBGT("adding test %s\n", name); + test *t = malloc(sizeof(test)); + MALLOC_CHECK_RETURN(t != NULL, 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)); + MALLOC_CHECK_RETURN(t != NULL, sizeof(test)); + 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; + } +} + +int run_tests(int argc, char **args) { + memset(&test_main, 0, sizeof(test_main)); + int arg; + int incl_filter = 0; + int excl_filter = 0; + for (arg = 0; arg < argc; arg++) { + if (strlen(args[arg]) == 0) continue; + if (0 == strcmp("-f", args[arg])) { + incl_filter = 1; + continue; + } + if (0 == strcmp("-e", args[arg])) { + excl_filter = 1; + continue; + } + if (incl_filter) { + strcpy(test_main.incl_filter, args[arg]); + incl_filter = 0; + } else if (excl_filter) { + strcpy(test_main.excl_filter, args[arg]); + excl_filter = 0; + } else { + printf("running tests from %s\n", args[arg]); + FILE *fd = fopen(args[1], "r"); + if (fd == NULL) { + printf("%s not found\n", args[arg]); + return -2; + } + 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); + } + + if (test_main.test_count == 0) { + printf("No tests to run\n"); + return 0; + } + + 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->test_result = res; + 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"); + return -1; + } else { + printf("\nALL TESTS OK\n"); + return 0; + } +} diff --git a/examples/spiffs_test/user/testrunner.h b/examples/spiffs_test/user/testrunner.h new file mode 100644 index 00000000..25819ea2 --- /dev/null +++ b/examples/spiffs_test/user/testrunner.h @@ -0,0 +1,151 @@ +/* + * testrunner.h + * + * Created on: Jun 19, 2013 + * Author: petera + */ + +/* + +SUITE(mysuite) + +void setup(test *t) {} + +void teardown(test *t) {} + +TEST(mytest) { + printf("mytest runs now..\n"); + return 0; +} TEST_END(mytest) + +SUITE_END(mysuite) + + + +SUITE(mysuite2) + +void setup(test *t) {} + +void teardown(test *t) {} + +TEST(mytest2a) { + printf("mytest2a runs now..\n"); + return 0; +} TEST_END(mytest2a) + +TEST(mytest2b) { + printf("mytest2b runs now..\n"); + return 0; +} TEST_END(mytest2b) + +SUITE_END(mysuite2) + + + +void add_suites() { + ADD_SUITE(mysuite); + ADD_SUITE(mysuite2); +} + */ + +#ifndef TESTRUNNER_H_ +#define TESTRUNNER_H_ + +#define TEST_RES_OK 0 +#define TEST_RES_FAIL -1 +#define TEST_RES_ASSERT -2 + +struct test_s; + +typedef int (*test_f)(struct test_s *t); + +typedef struct test_s { + test_f f; + char name[64]; + void *data; + void (*setup)(struct test_s *t); + void (*teardown)(struct test_s *t); + struct test_s *_next; + unsigned char test_result; +} test; + +typedef struct test_res_s { + char name[256]; + struct test_res_s *_next; +} test_res; + +#define MALLOC_CHECK(x, y) if (!(x)) { \ + printf(" MALLOC %i FAIL %s:%i, FREE %i\n", y, __FILE__, __LINE__, system_get_free_heap_size()); \ + goto __fail_stop; \ +} + +#define MALLOC_CHECK_RETURN(x, y) if (!(x)) { \ + printf(" MALLOC %i FAIL %s:%i, FREE %i\n", y, __FILE__, __LINE__, system_get_free_heap_size()); \ + return; \ +} + +#define MALLOC_CHECK_RETURN_1(x, y) if (!(x)) { \ + printf(" MALLOC %i FAIL %s:%i, FREE %i\n", y, __FILE__, __LINE__, system_get_free_heap_size()); \ + return -1; \ +} + +#define TEST_CHECK(x) if (!(x)) { \ + printf(" TEST FAIL %s:%i\n", __FILE__, __LINE__); \ + goto __fail_stop; \ +} +#define TEST_CHECK_EQ(x, y) if ((x) != (y)) { \ + printf(" TEST FAIL %s:%i, %i != %i\n", __FILE__, __LINE__, (x), (y)); \ + goto __fail_stop; \ +} +#define TEST_CHECK_NEQ(x, y) if ((x) == (y)) { \ + printf(" TEST FAIL %s:%i, %i == %i\n", __FILE__, __LINE__, (x), (y)); \ + goto __fail_stop; \ +} +#define TEST_CHECK_GT(x, y) if ((x) <= (y)) { \ + printf(" TEST FAIL %s:%i, %i <= %i\n", __FILE__, __LINE__, (x), (y)); \ + goto __fail_stop; \ +} +#define TEST_CHECK_LT(x, y) if ((x) >= (y)) { \ + printf(" TEST FAIL %s:%i, %i >= %i\n", __FILE__, __LINE__, (x), (y)); \ + goto __fail_stop; \ +} +#define TEST_CHECK_GE(x, y) if ((x) < (y)) { \ + printf(" TEST FAIL %s:%i, %i < %i\n", __FILE__, __LINE__, (x), (y)); \ + goto __fail_stop; \ +} +#define TEST_CHECK_LE(x, y) if ((x) > (y)) { \ + printf(" TEST FAIL %s:%i, %i > %i\n", __FILE__, __LINE__, (x), (y)); \ + goto __fail_stop; \ +} +#define TEST_ASSERT(x) if (!(x)) { \ + printf(" TEST ASSERT %s:%i\n", __FILE__, __LINE__); \ + goto __fail_assert; \ +} + +#define DBGT(...) os_printf(__VA_ARGS__) + +#define str(s) #s + +#define SUITE(sui) \ + extern void __suite_##sui() { +#define SUITE_END(sui) \ + } +#define ADD_SUITE(sui) \ + __suite_##sui(); +#define TEST(tf) \ + int tf(struct test_s *t) { do +#define TEST_END(tf) \ + while(0); \ + __fail_stop: return TEST_RES_FAIL; \ + __fail_assert: return TEST_RES_ASSERT; \ + } \ + add_test(tf, str(tf), setup, teardown); + + +void add_suites(); +void test_init(void (*on_stop)(test *t)); +void add_test(test_f f, char *name, void (*setup)(test *t), void (*teardown)(test *t)); +// returns 0 if all tests ok, -1 if any test failed, -2 on badness +int run_tests(int argc, char **args); + +#endif /* TESTRUNNER_H_ */ diff --git a/examples/spiffs_test/user/testsuites.c b/examples/spiffs_test/user/testsuites.c new file mode 100644 index 00000000..7627db06 --- /dev/null +++ b/examples/spiffs_test/user/testsuites.c @@ -0,0 +1,15 @@ +/* + * testsuites.c + * + * Created on: Jun 19, 2013 + * Author: petera + */ + +#include "testrunner.h" + +void add_suites() { + //ADD_SUITE(dev_tests); + ADD_SUITE(check_tests); + ADD_SUITE(hydrogen_tests) + ADD_SUITE(bug_tests) +} diff --git a/examples/websocket_demo/Makefile b/examples/websocket_demo/Makefile new file mode 100644 index 00000000..3c8b45be --- /dev/null +++ b/examples/websocket_demo/Makefile @@ -0,0 +1,122 @@ +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user \ + websocket + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a \ + websocket/libwebsocket.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lminic \ + -lgcc \ + -lhal \ + -lphy \ + -lpp \ + -lnet80211 \ + -lwpa \ + -lcrypto \ + -lmain \ + -lfreertos \ + -llwip \ + -lsmartconfig \ + $(DEP_LIBS_eagle.app.v6) \ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +CONFIGURATION_DEFINES = -DICACHE_FLASH + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/examples/websocket_demo/gen_misc.bat b/examples/websocket_demo/gen_misc.bat new file mode 100644 index 00000000..fd0b44fe --- /dev/null +++ b/examples/websocket_demo/gen_misc.bat @@ -0,0 +1,172 @@ +@echo off + +Rem ******NOTICE****** +Rem MUST set SDK_PATH & BIN_PATH firstly!!! +Rem example: +Rem set SDK_PATH=/c/esp_iot_sdk_freertos +Rem set BIN_PATH=/c/esp8266_bin + +set SDK_PATH="" +set BIN_PATH="" + +echo gen_misc.bat version 20150911 +echo . + +if not %SDK_PATH% == "" ( + echo SDK_PATH: %SDK_PATH% +) else ( + echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +if not %BIN_PATH% == "" ( + echo BIN_PATH: %BIN_PATH% +) else ( + echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +echo . +echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: +set input=default +set /p input= + +if not %input% == Y ( + if not %input% == y ( + goto end + ) +) + +echo . +echo Please follow below steps(1-5) to generate specific bin(s): +echo STEP 1: use boot_v1.2+ by default +set boot=new + +echo boot mode: %boot% +echo. + +echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin) +set input=default +set /p input=enter (0/1/2, default 0): + +if %input% equ 1 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=1 + echo generate bin: user1.bin + ) +) else ( +if %input% equ 2 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=2 + echo generate bin: user2.bin + ) +) else ( + if %boot% neq none ( + set boot=none + echo ignore boot + ) + set app=0 + echo generate bin: eagle.flash.bin+eagle.irom0text.bin +)) + +echo. + +echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz) +set input=default +set /p input=enter (0/1/2/3, default 2): + +if %input% equ 0 ( + set spi_speed=20 +) else ( +if %input% equ 1 ( + set spi_speed=26.7 +) else ( +if %input% equ 3 ( + set spi_speed=80 +) else ( + set spi_speed=40 +))) + +echo spi speed: %spi_speed% MHz +echo. + +echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT) +set input=default +set /p input=enter (0/1/2/3, default 0): + +if %input% equ 1 ( + set spi_mode=QOUT +) else ( +if %input% equ 2 ( + set spi_mode=DIO +) else ( +if %input% equ 3 ( + set spi_mode=DOUT +) else ( + set spi_mode=QIO +))) + +echo spi mode: %spi_mode% +echo. + +echo STEP 5: choose flash size and map +echo 0= 512KB( 256KB+ 256KB) +echo 2=1024KB( 512KB+ 512KB) +echo 3=2048KB( 512KB+ 512KB) +echo 4=4096KB( 512KB+ 512KB) +echo 5=2048KB(1024KB+1024KB) +echo 6=4096KB(1024KB+1024KB) +set input=default +set /p input=enter (0/1/2/3/4/5/6, default 0): + +if %input% equ 2 ( + set spi_size_map=2 + echo spi size: 1024KB + echo spi ota map: 512KB + 512KB +) else ( + if %input% equ 3 ( + set spi_size_map=3 + echo spi size: 2048KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 4 ( + set spi_size_map=4 + echo spi size: 4096KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 5 ( + set spi_size_map=5 + echo spi size: 2048KB + echo spi ota map: 1024KB + 1024KB + ) else ( + if %input% equ 6 ( + set spi_size_map=6 + echo spi size: 4096KB + echo spi ota map: 1024KB + 1024KB + ) else ( + set spi_size_map=0 + echo spi size: 512KB + echo spi ota map: 256KB + 256KB + ) + ) + ) + ) +) + +echo. +echo start... +echo. + +make clean + +make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% + +:end \ No newline at end of file diff --git a/examples/websocket_demo/gen_misc.sh b/examples/websocket_demo/gen_misc.sh new file mode 100644 index 00000000..b24f63c1 --- /dev/null +++ b/examples/websocket_demo/gen_misc.sh @@ -0,0 +1,176 @@ +#!/bin/bash + +:< + * + * 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. + * + */ + +#include "esp_common.h" + +char test_mode = 4; + +/****************************************************************************** + * FunctionName : user_init + * Description : entry of user application, init user function here + * Parameters : none + * Returns : none +*******************************************************************************/ +void user_init(void) +{ + os_printf("SDK version:%s\n", system_get_sdk_version()); + wifi_set_opmode(STATION_MODE); + websocket_start(&test_mode); +} diff --git a/examples/websocket_demo/websocket/Makefile b/examples/websocket_demo/websocket/Makefile new file mode 100644 index 00000000..64c648d2 --- /dev/null +++ b/examples/websocket_demo/websocket/Makefile @@ -0,0 +1,44 @@ + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libwebsocket.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/websocket_demo/websocket/websocket.c b/examples/websocket_demo/websocket/websocket.c new file mode 100644 index 00000000..6fca63bb --- /dev/null +++ b/examples/websocket_demo/websocket/websocket.c @@ -0,0 +1,716 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#include +#include "ssl_compat.h" +#include "esp_common.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +nopoll_bool debug = nopoll_false; +nopoll_bool show_critical_only = nopoll_false; +LOCAL xQueueHandle Web_QueueStop = NULL; + +#define local_host_name "iot.espressif.cn" +#define local_host_url "v1/datastreams/tem_hum/datapoint" +#define local_host_port "9000" +#define local_host_ports "9443" + +nopoll_bool test_sending_and_check_echo (noPollConn * conn, const char * label, const char * msg) +{ + char buffer[1024]; + int length = strlen (msg); + int bytes_read; + + /* wait for the reply */ + while (nopoll_true) { + if (nopoll_conn_is_ready (conn)) + break; + nopoll_sleep (10000); + } /* end if */ + + /* send content text(utf-8) */ + printf ("%s: sending content..\n", label); + if (nopoll_conn_send_text (conn, msg, length) != length) { + printf ("ERROR: Expected to find proper send operation..\n"); + return nopoll_false; + } + + /* wait for the reply (try to read 1024, blocking and with a 3 seconds timeout) */ + bytes_read = nopoll_conn_read (conn, buffer, length, nopoll_true, 3000); + if (bytes_read > 0) + buffer[bytes_read] = 0; + + if (bytes_read != length) { + printf ("ERROR: expected to find 14 bytes but found %d..\n", bytes_read); + return nopoll_false; + } /* end if */ + + /* check content received */ + if (! nopoll_cmp (buffer, msg)) { + printf ("ERROR: expected to find message 'This is a test' but something different was received: '%s'..\n", + buffer); + return nopoll_false; + } /* end if */ + + printf ("%s: received reply and echo matches..\n", label); + + /* return that we sent and received the echo reply */ + return nopoll_true; +} + +void __report_critical (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data) +{ + if (level == NOPOLL_LEVEL_CRITICAL) { + printf ("CRITICAL: %s\n", log_msg); + } + return; +} + +noPollCtx * create_ctx (void) { + + /* create a context */ + noPollCtx * ctx = nopoll_ctx_new (); + nopoll_log_enable (ctx, debug); + nopoll_log_color_enable (ctx, debug); + + /* configure handler */ + if (show_critical_only) + nopoll_log_set_handler (ctx, __report_critical, NULL); + return ctx; +} + +nopoll_bool test_02 (void) { + noPollCtx * ctx; + noPollConn * conn; + noPollMsg * msg; + int iter; + + /* create context */ + ctx = create_ctx (); + + /* check connections registered */ + if (nopoll_ctx_conns (ctx) != 0) { + printf ("ERROR: expected to find 0 registered connections but found: %d\n", nopoll_ctx_conns (ctx)); + return nopoll_false; + } /* end if */ + + nopoll_ctx_unref (ctx); + + /* reinit again */ + ctx = create_ctx (); + + /* call to create a connection */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error.. (conn=%p, conn->session=%d, NOPOLL_INVALID_SOCKET=%d, errno=%d, strerr=%s)..\n", + conn, (int) nopoll_conn_socket (conn), (int) NOPOLL_INVALID_SOCKET, errno, strerror (errno)); + return nopoll_false; + } + + printf ("Test 02: sending basic content..\n"); + + /* send content text(utf-8) */ + if (nopoll_conn_send_text (conn, "This is a test", 14) != 14) { + printf ("ERROR: Expected to find proper send operation..\n"); + return nopoll_false; + } + + /* wait for the reply */ + iter = 0; + while ((msg = nopoll_conn_get_msg (conn)) == NULL) { + + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: received websocket connection close during wait reply..\n"); + return nopoll_false; + } + + nopoll_sleep (10000); + + if (iter > 10) + break; + } /* end if */ + + /* check content received */ + if (! nopoll_cmp ((char*) nopoll_msg_get_payload (msg), "This is a test")) { + printf ("ERROR: expected to find message 'This is a test' but something different was received: '%s'..\n", + (const char *) nopoll_msg_get_payload (msg)); + return nopoll_false; + } /* end if */ + + /* unref message */ + nopoll_msg_unref (msg); + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +nopoll_bool test_03 (void) { + noPollCtx * ctx; + noPollConn * conn; + char buffer[1024]; + int bytes_read; + + memset (buffer, 0, 1024); + + /* create context */ + ctx = create_ctx (); + + /* check connections registered */ + if (nopoll_ctx_conns (ctx) != 0) { + printf ("ERROR: expected to find 0 registered connections but found: %d\n", nopoll_ctx_conns (ctx)); + return nopoll_false; + } /* end if */ + + nopoll_ctx_unref (ctx); + + /* reinit again */ + ctx = create_ctx (); + + /* call to create a connection */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } + + printf ("Test 03: sending basic content..\n"); + + /* send content text(utf-8) */ + if (nopoll_conn_send_text (conn, "This is a test", 14) != 14) { + printf ("ERROR: Expected to find proper send operation..\n"); + return nopoll_false; + } + + /* wait for the reply (try to read 1024, blocking and with a 3 seconds timeout) */ + printf ("Test 03: now reading reply..\n"); + bytes_read = nopoll_conn_read (conn, buffer, 14, nopoll_true, 3000); + + if (bytes_read != 14) { + printf ("ERROR: expected to find 14 bytes but found %d..\n", bytes_read); + return nopoll_false; + } /* end if */ + + /* check content received */ + if (! nopoll_ncmp (buffer, "This is a test", 14)) { + printf ("ERROR: expected to find message 'This is a test' but something different was received: '%s'..\n", + buffer); + return nopoll_false; + } /* end if */ + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +nopoll_bool test_04a (void) { + noPollCtx * ctx; + noPollConn * conn; + char buffer[1024]; + int result; + + /* reinit again */ + ctx = create_ctx (); + + /* call to create a connection */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } + + /* attempt to read without blocking */ + printf ("Test 04-a: checking non-blocking API..\n"); + result = nopoll_conn_read (conn, buffer, 1024, nopoll_false, 0); + if (result != -1) { + printf ("ERROR: expected return result -1(%d)\n", result); + return nopoll_false; + } + + printf ("Test 04-a: ok, operation not blocked, result %d\n", result); + if (result != -1) { + printf ("ERROR: expected return result -1(%d)\n", result); + return nopoll_false; + } + + result = nopoll_conn_read (conn, buffer, 1024, nopoll_false, 300); + if (result != -1) { + printf ("ERROR: expected return result -1(%d)\n", result); + return nopoll_false; + } + + printf ("Test 04-a: ok, operation not blocked, result %d\n", result); + + result = nopoll_conn_read (conn, buffer, 1024, nopoll_false, 1000); + if (result != -1) { + printf ("ERROR: expected return result -1(%d)\n", result); + return nopoll_false; + } + + printf ("Test 04-a: ok, operation not blocked, result %d\n", result); + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + + return nopoll_true; +} + +nopoll_bool test_04b (void) { + noPollCtx * ctx; + noPollConn * conn; + int iterator; + int length; + int bytes_written; + const char * msg = NULL; + /* reinit again */ + ctx = create_ctx (); + + /* call to create a connection */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } + + printf ("Test 04-b: waiting until connection is ok\n"); + nopoll_conn_wait_until_connection_ready (conn, 5); + + printf ("Test 04-b: sending was quick as possible to flood local buffers..\n"); + + /* get message length */ + length = strlen (msg); + iterator = 0; + while (iterator < 100) { + /* send a message */ + if (nopoll_conn_send_text (conn, msg, length) != length) { + if (errno == 0) { + printf ("ERROR: expected to find errno value but found 0..\n"); + } + printf ("Test 04-b: found expected error, checking errno=%d..\n", errno); + break; + } /* end if */ + + /* next iterator */ + iterator ++; + } /* end while */ + + if (errno != NOPOLL_EWOULDBLOCK && errno != EINPROGRESS) { + printf ("ERROR: expected to find errno=%d, but found errno=%d : %s\n", + (int)NOPOLL_EWOULDBLOCK, (int)errno, strerror (errno)); + return nopoll_false; + } /* end if */ + + /* write pending content */ + if (nopoll_conn_pending_write_bytes (conn) == 0) { + printf ("ERROR: expected to have pending bytes to be written.. but found 0..\n"); + return nopoll_false; + } /* end if */ + + iterator = 0; + while (iterator < 10) { + printf ("Test 04-b: found pending write bytes=%d\n", nopoll_conn_pending_write_bytes (conn)); + + /* call to flush bytes */ + nopoll_conn_complete_pending_write (conn); + + if (nopoll_conn_pending_write_bytes (conn) == 0) { + printf ("Test 04-b: all bytes written..\n"); + break; + } /* end if */ + + /* sleep a bit */ + nopoll_sleep (1000000); + + /* next iterator */ + iterator++; + } + + if (nopoll_conn_pending_write_bytes (conn) != 0) { + printf ("Test 04-b: expected to find no pending bytes waiting to be written but found: %d\n", nopoll_conn_pending_write_bytes (conn)); + return nopoll_false; + } /* end if */ + + nopoll_conn_close (conn); + + /* call to create a connection */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } + + printf ("Test 04-b: waiting until connection is ok\n"); + nopoll_conn_wait_until_connection_ready (conn, 5); + + /* send a cleanup message */ + bytes_written = nopoll_conn_send_text (conn, "release-message", 15); + if (bytes_written != 15) { + printf ("Test 04-b: unable to send release message, bytes_written=%d, but expected=%d..\n", + bytes_written, 15); + return nopoll_false; + } /* end if */ + + printf ("Test 04-b: waiting a second before finishing test..\n"); + nopoll_sleep (1000000); + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +nopoll_bool test_05 (void) { + + noPollCtx * ctx; + noPollConn * conn; + char buffer[1024]; + int bytes_read; + const char * msg = " klasdfkla akldfj klafklajetqkljt kjlwergklwejry90246tkgwr kñljwrglkjdfg lksdjglskg slkg camión adsfasdf pruébasdfad España asdfaklsjdflk jasfkjaslfjetql tjñqgkjadgklj aglkjalk jafkjaslfkjaskj asjaslfkjasfklajg klajefñlqkjetrlkqj lqkj ñlskdfjañlk asldfjñlafj añlfj ñdfjkjt4ñqlkjt lkj34tlkjañlgjañlkgjañlkgjw"; + + memset (buffer, 0, 1024); + + /* reinit again */ + ctx = create_ctx (); + + /* call to create a connection */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } + + printf ("Test 05: sending UTF-8 content..\n"); + + /* send content text(utf-8) */ + if (nopoll_conn_send_text (conn, msg, -1) <= 0) { + printf ("ERROR: Expected to find proper send operation (nopoll_conn_send_test) returned less or 0..\n"); + return nopoll_false; + } + + /* wait for the reply (try to read 322, blocking and with a 3 seconds timeout) */ + bytes_read = nopoll_conn_read (conn, buffer, 322, nopoll_true, 3000); + if (bytes_read != 322) { + printf ("ERROR: expected to receive 322 bytes, but received %d\n", bytes_read); + return nopoll_false; + } + + if (! nopoll_ncmp (buffer, msg, 322)) { + printf ("ERROR: expected to receive another content....\n"); + printf ("Expected: %s\n", msg); + printf ("Received: %s\n", buffer); + + return nopoll_false; + } + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +nopoll_bool test_06 (void) { + + noPollCtx * ctx; + noPollConn * conn; + noPollConnOpts * opts; + + /* reinit again */ + ctx = create_ctx (); + + /* disable verification */ + opts = nopoll_conn_opts_new (); + nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); + + /* call to create a connection */ + conn = nopoll_conn_tls_new (ctx, opts, local_host_name, local_host_ports, NULL, local_host_url, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } + + /* check if the connection already finished its connection + handshake */ + while (! nopoll_conn_is_ready (conn)) { + + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR (4.1 jg72): expected to find proper connection handshake finished, but found connection is broken: session=%d, errno=%d : %s..\n", + (int) nopoll_conn_socket (conn), errno, strerror (errno)); + return nopoll_false; + } /* end if */ + + /* wait a bit 10ms */ + nopoll_sleep (100); + } /* end if */ + + if (! nopoll_conn_is_tls_on (conn)) { + printf ("ERROR (5): expected to find TLS enabled on the connection but found it isn't..\n"); + return nopoll_false; + } /* end if */ + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +nopoll_bool test_07 (void) { + + noPollCtx * ctx; + noPollConn * conn; + noPollConnOpts * opts; + + /* reinit again */ + ctx = create_ctx (); + + /* disable verification */ + opts = nopoll_conn_opts_new (); + nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); + + /* call to create a connection */ + conn = nopoll_conn_tls_new (ctx, opts, local_host_name, local_host_ports, NULL, NULL, NULL, NULL); + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR: Expected to find proper client connection status, but found error..\n"); + return nopoll_false; + } /* end if */ + + /* check if the connection already finished its connection + handshake */ + while (! nopoll_conn_is_ready (conn)) { + + if (! nopoll_conn_is_ok (conn)) { + printf ("ERROR (4.1 dk45): expected to find proper connection handshake finished, but found connection is broken: session=%d, errno=%d : %s..\n", + (int) nopoll_conn_socket (conn), errno, strerror (errno)); + return nopoll_false; + } /* end if */ + + /* wait a bit 10ms */ + nopoll_sleep (10000); + } /* end if */ + + printf ("Test 07: testing sending TLS content over the wire..\n"); + if (! test_sending_and_check_echo (conn, "Test 07", "This is a test")) + return nopoll_false; + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +nopoll_bool test_08 (void) { + + noPollCtx * ctx; + noPollConn * conn; + + /* reinit again */ + ctx = create_ctx (); + + /* call to connect to TLS port expecting non-TLS protocol */ + conn = nopoll_conn_new (ctx, local_host_name, local_host_port, NULL, NULL, NULL, NULL); + + /* wait a bit 100ms */ + nopoll_sleep (100000); + + if (nopoll_conn_is_ready (conn)) { + printf ("ERROR: Expected a FAILING connection status, but found error..\n"); + return nopoll_false; + } /* end if */ + + /* finish connection */ + nopoll_conn_close (conn); + + /* finish */ + nopoll_ctx_unref (ctx); + + return nopoll_true; +} + +LOCAL int websocket_main (char *argv) +{ + int iterator = *argv; + + switch (iterator) { + + case 2: + if (test_02()) { + printf("Test 02: Simple request/reply [ OK ]\n"); + } else { + printf("Test 02: Simple request/reply [ FAILED ]\n"); + } + + break; + + case 4: + if (test_04a()) { + printf( + "Test 04-a: check non-blocking streaming and message based API [ OK ]\n"); + } else { + printf( + "Test 04-a: check non-blocking streaming and message based API [ FAILED ]\n"); + } + break; + case 5: + if (test_05()) { + printf("Test 05: sending utf-8 content [ OK ]\n"); + } else { + printf("Test 05: sending utf-8 content [ FAILED ]\n"); + } + + break; + case 6: + if (test_06()) { + printf("Test 06: testing basic TLS connect [ OK ]\n"); + } else { + printf("Test 06: testing basic TLS connect [ FAILED ]\n"); + } + + break; + case 7: + if (test_07()) { + printf("Test 07: testing TLS request/reply [ OK ]\n"); + } else { + printf("Test 07: testing TLS request/reply [ FAILED ]\n"); + } + + break; + case 8: + if (test_08()) { + printf("Test 08: test normal connect to TLS port [ OK ]\n"); + } else { + printf("Test 08: test normal connect to TLS port [ FAILED ]\n"); + } + + break; + + default: + break; + } + + /* call to cleanup */ + nopoll_cleanup_library (); + printf ("All tests ok!!\n"); + + return 0; +} + +LOCAL void websocket_task(void *pvParameters) +{ + bool ValueFromReceive = false; + portBASE_TYPE xStatus; + struct ip_info ip_config; + struct station_config sta_config; + bzero(&sta_config, sizeof(struct station_config)); + + sprintf(sta_config.ssid, "B-LINK_845R"); + sprintf(sta_config.password, "000"); + wifi_station_set_config(&sta_config); + os_printf("%s\n", __func__); + wifi_get_ip_info(STATION_IF, &ip_config); + while(ip_config.ip.addr == 0){ + vTaskDelay(1000 / portTICK_RATE_MS); + wifi_get_ip_info(STATION_IF, &ip_config); + } + websocket_main((char*)pvParameters); + + while (1) { + xStatus = xQueueReceive(Web_QueueStop,&ValueFromReceive,0); + if (xStatus == pdPASS && ValueFromReceive == true){ + printf("websocket_task exit signal\n"); + break; + } + vTaskDelay(200 / portTICK_RATE_MS); + printf("websocket_task\n"); + } + vQueueDelete(Web_QueueStop); + Web_QueueStop = NULL; + vTaskDelete(NULL); + printf("delete the websocket_task\n"); +} + +/*start the websocket task*/ +void websocket_start(void *optarg) +{ + if (Web_QueueStop == NULL) + Web_QueueStop = xQueueCreate(1,1); + + if (Web_QueueStop != NULL) + xTaskCreate(websocket_task, "websocket_task", 512, optarg, 4, NULL); +} + +/*stop the websocket task*/ +sint8 websocket_stop(void) +{ + bool ValueToSend = true; + portBASE_TYPE xStatus; + + if (Web_QueueStop == NULL) + return -1; + + xStatus = xQueueSend(Web_QueueStop,&ValueToSend,0); + if (xStatus != pdPASS) + return -1; + else + return pdPASS; +} +/* end-of-file-found */ diff --git a/extra_include/_ansi.h b/extra_include/_ansi.h deleted file mode 100644 index b8e53390..00000000 --- a/extra_include/_ansi.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Provide support for both ANSI and non-ANSI environments. */ - -/* Some ANSI environments are "broken" in the sense that __STDC__ cannot be - relied upon to have it's intended meaning. Therefore we must use our own - concoction: _HAVE_STDC. Always use _HAVE_STDC instead of __STDC__ in newlib - sources! - - To get a strict ANSI C environment, define macro __STRICT_ANSI__. This will - "comment out" the non-ANSI parts of the ANSI header files (non-ANSI header - files aren't affected). */ - -#ifndef _ANSIDECL_H_ -#define _ANSIDECL_H_ - -#include -#include - -/* First try to figure out whether we really are in an ANSI C environment. */ -/* FIXME: This probably needs some work. Perhaps sys/config.h can be - prevailed upon to give us a clue. */ - -#ifdef __STDC__ -#define _HAVE_STDC -#endif - -#ifdef _HAVE_STDC -#define _PTR void * -#define _AND , -#define _NOARGS void -#define _CONST const -#define _VOLATILE volatile -#define _SIGNED signed -#define _DOTS , ... -#define _VOID void -#ifdef __CYGWIN__ -#define _EXFUN(name, proto) __cdecl name proto -#define _EXPARM(name, proto) (* __cdecl name) proto -#else -#define _EXFUN(name, proto) name proto -#define _EXPARM(name, proto) (* name) proto -#endif -#define _DEFUN(name, arglist, args) name(args) -#define _DEFUN_VOID(name) name(_NOARGS) -#define _CAST_VOID (void) -#ifndef _LONG_DOUBLE -#define _LONG_DOUBLE long double -#endif -#ifndef _PARAMS -#define _PARAMS(paramlist) paramlist -#endif -#else -#define _PTR char * -#define _AND ; -#define _NOARGS -#define _CONST -#define _VOLATILE -#define _SIGNED -#define _DOTS -#define _VOID void -#define _EXFUN(name, proto) name() -#define _DEFUN(name, arglist, args) name arglist args; -#define _DEFUN_VOID(name) name() -#define _CAST_VOID -#define _LONG_DOUBLE double -#ifndef _PARAMS -#define _PARAMS(paramlist) () -#endif -#endif - -/* Support gcc's __attribute__ facility. */ - -#ifdef __GNUC__ -#define _ATTRIBUTE(attrs) __attribute__ (attrs) -#else -#define _ATTRIBUTE(attrs) -#endif - -/* ISO C++. */ - -#ifdef __cplusplus -#if !(defined(_BEGIN_STD_C) && defined(_END_STD_C)) -#ifdef _HAVE_STD_CXX -#define _BEGIN_STD_C namespace std { extern "C" { -#define _END_STD_C } } -#else -#define _BEGIN_STD_C extern "C" { -#define _END_STD_C } -#endif -#endif -#else -#define _BEGIN_STD_C -#define _END_STD_C -#endif - -#endif /* _ANSIDECL_H_ */ diff --git a/extra_include/_syslist.h b/extra_include/_syslist.h deleted file mode 100644 index 48a17b8c..00000000 --- a/extra_include/_syslist.h +++ /dev/null @@ -1,29 +0,0 @@ -/* internal use only -- mapping of "system calls" for libraries that lose - and only provide C names, so that we end up in violation of ANSI */ -#ifndef __SYSLIST_H -#define __SYSLIST_H -#ifdef MISSING_SYSCALL_NAMES -#define _close close -#define _execve execve -#define _fcntl fcntl -#define _fork fork -#define _fstat fstat -#define _getpid getpid -#define _gettimeofday gettimeofday -#define _kill kill -#define _link link -#define _lseek lseek -#define _open open -#define _read read -#define _sbrk sbrk -#define _stat stat -#define _times times -#define _unlink unlink -#define _wait wait -#define _write write -/* functions not yet sysfaked */ -#define _opendir opendir -#define _readdir readdir -#define _closedir closedir -#endif -#endif diff --git a/extra_include/alloca.h b/extra_include/alloca.h deleted file mode 100644 index 15a10ca6..00000000 --- a/extra_include/alloca.h +++ /dev/null @@ -1,19 +0,0 @@ -/* libc/include/alloca.h - Allocate memory on stack */ - -/* Written 2000 by Werner Almesberger */ -/* Rearranged for general inclusion by stdlib.h. - 2001, Corinna Vinschen */ - -#ifndef _NEWLIB_ALLOCA_H -#define _NEWLIB_ALLOCA_H - -#include "_ansi.h" -#include - -#ifdef __GNUC__ -#define alloca(size) __builtin_alloca(size) -#else -void * _EXFUN(alloca,(size_t)); -#endif - -#endif diff --git a/extra_include/ar.h b/extra_include/ar.h deleted file mode 100644 index e2529eb1..00000000 --- a/extra_include/ar.h +++ /dev/null @@ -1,69 +0,0 @@ -/* $NetBSD: ar.h,v 1.4 1994/10/26 00:55:43 cgd Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * This code is derived from software contributed to Berkeley by - * Hugh Smith at The University of Guelph. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)ar.h 8.2 (Berkeley) 1/21/94 - */ - -#ifndef _AR_H_ -#define _AR_H_ - -/* Pre-4BSD archives had these magic numbers in them. */ -#define OARMAG1 0177555 -#define OARMAG2 0177545 - -#define ARMAG "!\n" /* ar "magic number" */ -#define SARMAG 8 /* strlen(ARMAG); */ - -#define AR_EFMT1 "#1/" /* extended format #1 */ - -struct ar_hdr { - char ar_name[16]; /* name */ - char ar_date[12]; /* modification time */ - char ar_uid[6]; /* user id */ - char ar_gid[6]; /* group id */ - char ar_mode[8]; /* octal file permissions */ - char ar_size[10]; /* size in bytes */ -#define ARFMAG "`\n" - char ar_fmag[2]; /* consistency check */ -}; - -#endif /* !_AR_H_ */ diff --git a/extra_include/argz.h b/extra_include/argz.h deleted file mode 100644 index 79e70de5..00000000 --- a/extra_include/argz.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - -#include -#include - -/* The newlib implementation of these functions assumes that sizeof(char) == 1. */ -error_t argz_create (char *const argv[], char **argz, size_t *argz_len); -error_t argz_create_sep (const char *string, int sep, char **argz, size_t *argz_len); -size_t argz_count (const char *argz, size_t argz_len); -void argz_extract (char *argz, size_t argz_len, char **argv); -void argz_stringify (char *argz, size_t argz_len, int sep); -error_t argz_add (char **argz, size_t *argz_len, const char *str); -error_t argz_add_sep (char **argz, size_t *argz_len, const char *str, int sep); -error_t argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len); -error_t argz_delete (char **argz, size_t *argz_len, char *entry); -error_t argz_insert (char **argz, size_t *argz_len, char *before, const char *entry); -char * argz_next (char *argz, size_t argz_len, const char *entry); -error_t argz_replace (char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count); diff --git a/extra_include/assert.h b/extra_include/assert.h deleted file mode 100644 index c68bcaac..00000000 --- a/extra_include/assert.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - assert.h -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "_ansi.h" - -#undef assert - -#ifdef NDEBUG /* required by ANSI standard */ -#define assert(p) ((void)0) -#else - -#ifdef __STDC__ -#define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e)) -#else /* PCC */ -#define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, "e")) -#endif - -#endif /* NDEBUG */ - -void _EXFUN(__assert,(const char *, int, const char *)); - -#ifdef __cplusplus -} -#endif diff --git a/extra_include/ctype.h b/extra_include/ctype.h deleted file mode 100644 index cf50c02f..00000000 --- a/extra_include/ctype.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _CTYPE_H_ -#define _CTYPE_H_ - -#include "_ansi.h" - -_BEGIN_STD_C - -int _EXFUN(isalnum, (int __c)); -int _EXFUN(isalpha, (int __c)); -int _EXFUN(iscntrl, (int __c)); -int _EXFUN(isdigit, (int __c)); -int _EXFUN(isgraph, (int __c)); -int _EXFUN(islower, (int __c)); -int _EXFUN(isprint, (int __c)); -int _EXFUN(ispunct, (int __c)); -int _EXFUN(isspace, (int __c)); -int _EXFUN(isupper, (int __c)); -int _EXFUN(isxdigit,(int __c)); -int _EXFUN(tolower, (int __c)); -int _EXFUN(toupper, (int __c)); - -#ifndef __STRICT_ANSI__ -int _EXFUN(isblank, (int __c)); -int _EXFUN(isascii, (int __c)); -int _EXFUN(toascii, (int __c)); -int _EXFUN(_tolower, (int __c)); -int _EXFUN(_toupper, (int __c)); -#endif - -#define _U 01 -#define _L 02 -#define _N 04 -#define _S 010 -#define _P 020 -#define _C 040 -#define _X 0100 -#define _B 0200 - -extern __IMPORT _CONST char _ctype_[]; - -#ifndef __cplusplus -#define isalpha(c) ((_ctype_+1)[(unsigned)(c)]&(_U|_L)) -#define isupper(c) ((_ctype_+1)[(unsigned)(c)]&_U) -#define islower(c) ((_ctype_+1)[(unsigned)(c)]&_L) -#define isdigit(c) ((_ctype_+1)[(unsigned)(c)]&_N) -#define isxdigit(c) ((_ctype_+1)[(unsigned)(c)]&(_X|_N)) -#define isspace(c) ((_ctype_+1)[(unsigned)(c)]&_S) -#define ispunct(c) ((_ctype_+1)[(unsigned)(c)]&_P) -#define isalnum(c) ((_ctype_+1)[(unsigned)(c)]&(_U|_L|_N)) -#define isprint(c) ((_ctype_+1)[(unsigned)(c)]&(_P|_U|_L|_N|_B)) -#define isgraph(c) ((_ctype_+1)[(unsigned)(c)]&(_P|_U|_L|_N)) -#define iscntrl(c) ((_ctype_+1)[(unsigned)(c)]&_C) -/* Non-gcc versions will get the library versions, and will be - slightly slower */ -#ifdef __GNUC__ -# define toupper(c) \ - __extension__ ({ int __x = (c); islower(__x) ? (__x - 'a' + 'A') : __x;}) -# define tolower(c) \ - __extension__ ({ int __x = (c); isupper(__x) ? (__x - 'A' + 'a') : __x;}) -#endif -#endif /* !__cplusplus */ - -#ifndef __STRICT_ANSI__ -#define isascii(c) ((unsigned)(c)<=0177) -#define toascii(c) ((c)&0177) -#endif - -_END_STD_C - -#endif /* _CTYPE_H_ */ diff --git a/extra_include/dirent.h b/extra_include/dirent.h deleted file mode 100644 index 3cf8d908..00000000 --- a/extra_include/dirent.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _DIRENT_H_ -#define _DIRENT_H_ -#ifdef __cplusplus -extern "C" { -#endif -#include - -#if !defined(MAXNAMLEN) && !defined(_POSIX_SOURCE) -#define MAXNAMLEN 1024 -#endif - -#ifdef __cplusplus -} -#endif -#endif /*_DIRENT_H_*/ diff --git a/extra_include/envz.h b/extra_include/envz.h deleted file mode 100644 index 9d9430bb..00000000 --- a/extra_include/envz.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - -#include -#include - -/* The newlib implementation of these functions assumes that sizeof(char) == 1. */ -char * envz_entry (const char *envz, size_t envz_len, const char *name); -char * envz_get (const char *envz, size_t envz_len, const char *name); -error_t envz_add (char **envz, size_t *envz_len, const char *name, const char *value); -error_t envz_merge (char **envz, size_t *envz_len, const char *envz2, size_t envz2_len, int override); -void envz_remove(char **envz, size_t *envz_len, const char *name); -void envz_strip (char **envz, size_t *envz_len); diff --git a/extra_include/errno.h b/extra_include/errno.h deleted file mode 100644 index f540ae56..00000000 --- a/extra_include/errno.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __ERRNO_H__ -#define __ERRNO_H__ - -#ifndef __error_t_defined -typedef int error_t; -#define __error_t_defined 1 -#endif - -#include - -#endif /* !__ERRNO_H__ */ diff --git a/extra_include/fastmath.h b/extra_include/fastmath.h deleted file mode 100644 index 94305fda..00000000 --- a/extra_include/fastmath.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _FASTMATH_H_ -#ifdef __cplusplus -extern "C" { -#endif -#define _FASTMATH_H_ - -#include -#include - -#ifdef __cplusplus -} -#endif -#endif /* _FASTMATH_H_ */ diff --git a/extra_include/fcntl.h b/extra_include/fcntl.h deleted file mode 100644 index b9f559e0..00000000 --- a/extra_include/fcntl.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/extra_include/grp.h b/extra_include/grp.h deleted file mode 100644 index c508fee4..00000000 --- a/extra_include/grp.h +++ /dev/null @@ -1,94 +0,0 @@ -/* $NetBSD: grp.h,v 1.7 1995/04/29 05:30:40 cgd Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)grp.h 8.2 (Berkeley) 1/21/94 - */ - -#ifndef _GRP_H_ -#define _GRP_H_ - -#include -#ifdef __CYGWIN__ -#include -#endif - -#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) -#define _PATH_GROUP "/etc/group" -#endif - -struct group { - char *gr_name; /* group name */ - char *gr_passwd; /* group password */ - gid_t gr_gid; /* group id */ - char **gr_mem; /* group members */ -}; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __INSIDE_CYGWIN__ -struct group *getgrgid (gid_t); -struct group *getgrnam (const char *); -int getgrnam_r (const char *, struct group *, - char *, size_t, struct group **); -int getgrgid_r (gid_t, struct group *, - char *, size_t, struct group **); -#ifndef _POSIX_SOURCE -struct group *getgrent (void); -void setgrent (void); -void endgrent (void); -#ifndef __CYGWIN__ -void setgrfile (const char *); -#endif /* !__CYGWIN__ */ -#ifndef _XOPEN_SOURCE -#ifndef __CYGWIN__ -char *group_from_gid (gid_t, int); -int setgroupent (int); -#endif /* !__CYGWIN__ */ -int initgroups (const char *, gid_t); -#endif /* !_XOPEN_SOURCE */ -#endif /* !_POSIX_SOURCE */ -#endif /* !__INSIDE_CYGWIN__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* !_GRP_H_ */ diff --git a/extra_include/iconv.h b/extra_include/iconv.h deleted file mode 100644 index 69cad0f8..00000000 --- a/extra_include/iconv.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2003-2004, Artem B. Bityuckiy, SoftMine Corporation. - * Rights transferred to Franklin Electronic Publishers. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ -#ifndef _ICONV_H_ -#define _ICONV_H_ - -#include <_ansi.h> -#include -#include -#include - -/* iconv_t: charset conversion descriptor type */ -typedef _iconv_t iconv_t; - -_BEGIN_STD_C - -#ifndef _REENT_ONLY -iconv_t -_EXFUN(iconv_open, (_CONST char *, _CONST char *)); - -size_t -_EXFUN(iconv, (iconv_t, _CONST char **, size_t *, char **, size_t *)); - -int -_EXFUN(iconv_close, (iconv_t)); -#endif - -iconv_t -_EXFUN(_iconv_open_r, (struct _reent *, _CONST char *, _CONST char *)); - -size_t -_EXFUN(_iconv_r, (struct _reent *, iconv_t, _CONST char **, - size_t *, char **, size_t *)); - -int -_EXFUN(_iconv_close_r, (struct _reent *, iconv_t)); - -_END_STD_C - -#endif /* #ifndef _ICONV_H_ */ diff --git a/extra_include/ieeefp.h b/extra_include/ieeefp.h deleted file mode 100644 index e57ed1d0..00000000 --- a/extra_include/ieeefp.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef _IEEE_FP_H_ -#define _IEEE_FP_H_ - -#include "_ansi.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* FIXME FIXME FIXME: - Neither of __ieee_{float,double}_shape_tape seem to be used anywhere - except in libm/test. If that is the case, please delete these from here. - If that is not the case, please insert documentation here describing why - they're needed. */ - -#ifdef __IEEE_BIG_ENDIAN - -typedef union -{ - double value; - struct - { - unsigned int sign : 1; - unsigned int exponent: 11; - unsigned int fraction0:4; - unsigned int fraction1:16; - unsigned int fraction2:16; - unsigned int fraction3:16; - - } number; - struct - { - unsigned int sign : 1; - unsigned int exponent: 11; - unsigned int quiet:1; - unsigned int function0:3; - unsigned int function1:16; - unsigned int function2:16; - unsigned int function3:16; - } nan; - struct - { - unsigned long msw; - unsigned long lsw; - } parts; - long aslong[2]; -} __ieee_double_shape_type; - -#endif - -#ifdef __IEEE_LITTLE_ENDIAN - -typedef union -{ - double value; - struct - { -#ifdef __SMALL_BITFIELDS - unsigned int fraction3:16; - unsigned int fraction2:16; - unsigned int fraction1:16; - unsigned int fraction0: 4; -#else - unsigned int fraction1:32; - unsigned int fraction0:20; -#endif - unsigned int exponent :11; - unsigned int sign : 1; - } number; - struct - { -#ifdef __SMALL_BITFIELDS - unsigned int function3:16; - unsigned int function2:16; - unsigned int function1:16; - unsigned int function0:3; -#else - unsigned int function1:32; - unsigned int function0:19; -#endif - unsigned int quiet:1; - unsigned int exponent: 11; - unsigned int sign : 1; - } nan; - struct - { - unsigned long lsw; - unsigned long msw; - } parts; - - long aslong[2]; - -} __ieee_double_shape_type; - -#endif - -#ifdef __IEEE_BIG_ENDIAN - -typedef union -{ - float value; - struct - { - unsigned int sign : 1; - unsigned int exponent: 8; - unsigned int fraction0: 7; - unsigned int fraction1: 16; - } number; - struct - { - unsigned int sign:1; - unsigned int exponent:8; - unsigned int quiet:1; - unsigned int function0:6; - unsigned int function1:16; - } nan; - long p1; - -} __ieee_float_shape_type; - -#endif - -#ifdef __IEEE_LITTLE_ENDIAN - -typedef union -{ - float value; - struct - { - unsigned int fraction0: 7; - unsigned int fraction1: 16; - unsigned int exponent: 8; - unsigned int sign : 1; - } number; - struct - { - unsigned int function1:16; - unsigned int function0:6; - unsigned int quiet:1; - unsigned int exponent:8; - unsigned int sign:1; - } nan; - long p1; - -} __ieee_float_shape_type; - -#endif - - - - - -/* FLOATING ROUNDING */ - -typedef int fp_rnd; -#define FP_RN 0 /* Round to nearest */ -#define FP_RM 1 /* Round down */ -#define FP_RP 2 /* Round up */ -#define FP_RZ 3 /* Round to zero (trunate) */ - -fp_rnd _EXFUN(fpgetround,(void)); -fp_rnd _EXFUN(fpsetround, (fp_rnd)); - -/* EXCEPTIONS */ - -typedef int fp_except; -#define FP_X_INV 0x10 /* Invalid operation */ -#define FP_X_DX 0x80 /* Divide by zero */ -#define FP_X_OFL 0x04 /* Overflow exception */ -#define FP_X_UFL 0x02 /* Underflow exception */ -#define FP_X_IMP 0x01 /* imprecise exception */ - -fp_except _EXFUN(fpgetmask,(void)); -fp_except _EXFUN(fpsetmask,(fp_except)); -fp_except _EXFUN(fpgetsticky,(void)); -fp_except _EXFUN(fpsetsticky, (fp_except)); - -/* INTEGER ROUNDING */ - -typedef int fp_rdi; -#define FP_RDI_TOZ 0 /* Round to Zero */ -#define FP_RDI_RD 1 /* Follow float mode */ - -fp_rdi _EXFUN(fpgetroundtoi,(void)); -fp_rdi _EXFUN(fpsetroundtoi,(fp_rdi)); - -int _EXFUN(isnan, (double)); -int _EXFUN(isinf, (double)); -int _EXFUN(finite, (double)); - - - -int _EXFUN(isnanf, (float)); -int _EXFUN(isinff, (float)); -int _EXFUN(finitef, (float)); - -#define __IEEE_DBL_EXPBIAS 1023 -#define __IEEE_FLT_EXPBIAS 127 - -#define __IEEE_DBL_EXPLEN 11 -#define __IEEE_FLT_EXPLEN 8 - - -#define __IEEE_DBL_FRACLEN (64 - (__IEEE_DBL_EXPLEN + 1)) -#define __IEEE_FLT_FRACLEN (32 - (__IEEE_FLT_EXPLEN + 1)) - -#define __IEEE_DBL_MAXPOWTWO ((double)(1L << 32 - 2) * (1L << (32-11) - 32 + 1)) -#define __IEEE_FLT_MAXPOWTWO ((float)(1L << (32-8) - 1)) - -#define __IEEE_DBL_NAN_EXP 0x7ff -#define __IEEE_FLT_NAN_EXP 0xff - - -#define isnanf(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \ - ((*(long *)&(x) & 0x007fffffL)!=0000000000L)) - -#define isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \ - ((*(long *)&(x) & 0x007fffffL)==0000000000L)) - -#define finitef(x) (((*(long *)&(x) & 0x7f800000L)!=0x7f800000L)) - -#ifdef _DOUBLE_IS_32BITS -#undef __IEEE_DBL_EXPBIAS -#define __IEEE_DBL_EXPBIAS __IEEE_FLT_EXPBIAS - -#undef __IEEE_DBL_EXPLEN -#define __IEEE_DBL_EXPLEN __IEEE_FLT_EXPLEN - -#undef __IEEE_DBL_FRACLEN -#define __IEEE_DBL_FRACLEN __IEEE_FLT_FRACLEN - -#undef __IEEE_DBL_MAXPOWTWO -#define __IEEE_DBL_MAXPOWTWO __IEEE_FLT_MAXPOWTWO - -#undef __IEEE_DBL_NAN_EXP -#define __IEEE_DBL_NAN_EXP __IEEE_FLT_NAN_EXP - -#undef __ieee_double_shape_type -#define __ieee_double_shape_type __ieee_float_shape_type - -#endif /* _DOUBLE_IS_32BITS */ - -#ifdef __cplusplus -} -#endif - -#endif /* _IEEE_FP_H_ */ diff --git a/extra_include/inttypes.h b/extra_include/inttypes.h deleted file mode 100644 index 2f2a0951..00000000 --- a/extra_include/inttypes.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2004, 2005 by - * Ralf Corsepius, Ulm/Germany. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - -/** - * @file inttypes.h - */ - -#ifndef _INTTYPES_H -#define _INTTYPES_H - -#include -#define __need_wchar_t -#include - -#define __STRINGIFY(a) #a - -/* 8-bit types */ -#define __PRI8(x) __STRINGIFY(x) -#define __SCN8(x) __STRINGIFY(hh##x) - - -#define PRId8 __PRI8(d) -#define PRIi8 __PRI8(i) -#define PRIo8 __PRI8(o) -#define PRIu8 __PRI8(u) -#define PRIx8 __PRI8(x) -#define PRIX8 __PRI8(X) - -#define SCNd8 __SCN8(d) -#define SCNi8 __SCN8(i) -#define SCNo8 __SCN8(o) -#define SCNu8 __SCN8(u) -#define SCNx8 __SCN8(x) - - -#define PRIdLEAST8 __PRI8(d) -#define PRIiLEAST8 __PRI8(i) -#define PRIoLEAST8 __PRI8(o) -#define PRIuLEAST8 __PRI8(u) -#define PRIxLEAST8 __PRI8(x) -#define PRIXLEAST8 __PRI8(X) - -#define SCNdLEAST8 __SCN8(d) -#define SCNiLEAST8 __SCN8(i) -#define SCNoLEAST8 __SCN8(o) -#define SCNuLEAST8 __SCN8(u) -#define SCNxLEAST8 __SCN8(x) - - -#define PRIdFAST8 __PRI8(d) -#define PRIiFAST8 __PRI8(i) -#define PRIoFAST8 __PRI8(o) -#define PRIuFAST8 __PRI8(u) -#define PRIxFAST8 __PRI8(x) -#define PRIXFAST8 __PRI8(X) - -#define SCNdFAST8 __SCN8(d) -#define SCNiFAST8 __SCN8(i) -#define SCNoFAST8 __SCN8(o) -#define SCNuFAST8 __SCN8(u) -#define SCNxFAST8 __SCN8(x) - -/* 16-bit types */ -#define __PRI16(x) __STRINGIFY(x) -#define __SCN16(x) __STRINGIFY(h##x) - - -#define PRId16 __PRI16(d) -#define PRIi16 __PRI16(i) -#define PRIo16 __PRI16(o) -#define PRIu16 __PRI16(u) -#define PRIx16 __PRI16(x) -#define PRIX16 __PRI16(X) - -#define SCNd16 __SCN16(d) -#define SCNi16 __SCN16(i) -#define SCNo16 __SCN16(o) -#define SCNu16 __SCN16(u) -#define SCNx16 __SCN16(x) - - -#define PRIdLEAST16 __PRI16(d) -#define PRIiLEAST16 __PRI16(i) -#define PRIoLEAST16 __PRI16(o) -#define PRIuLEAST16 __PRI16(u) -#define PRIxLEAST16 __PRI16(x) -#define PRIXLEAST16 __PRI16(X) - -#define SCNdLEAST16 __SCN16(d) -#define SCNiLEAST16 __SCN16(i) -#define SCNoLEAST16 __SCN16(o) -#define SCNuLEAST16 __SCN16(u) -#define SCNxLEAST16 __SCN16(x) - - -#define PRIdFAST16 __PRI16(d) -#define PRIiFAST16 __PRI16(i) -#define PRIoFAST16 __PRI16(o) -#define PRIuFAST16 __PRI16(u) -#define PRIxFAST16 __PRI16(x) -#define PRIXFAST16 __PRI16(X) - -#define SCNdFAST16 __SCN16(d) -#define SCNiFAST16 __SCN16(i) -#define SCNoFAST16 __SCN16(o) -#define SCNuFAST16 __SCN16(u) -#define SCNxFAST16 __SCN16(x) - -/* 32-bit types */ -#if __have_long32 -#define __PRI32(x) __STRINGIFY(l##x) -#define __SCN32(x) __STRINGIFY(l##x) -#else -#define __PRI32(x) __STRINGIFY(x) -#define __SCN32(x) __STRINGIFY(x) -#endif - -#define PRId32 __PRI32(d) -#define PRIi32 __PRI32(i) -#define PRIo32 __PRI32(o) -#define PRIu32 __PRI32(u) -#define PRIx32 __PRI32(x) -#define PRIX32 __PRI32(X) - -#define SCNd32 __SCN32(d) -#define SCNi32 __SCN32(i) -#define SCNo32 __SCN32(o) -#define SCNu32 __SCN32(u) -#define SCNx32 __SCN32(x) - - -#define PRIdLEAST32 __PRI32(d) -#define PRIiLEAST32 __PRI32(i) -#define PRIoLEAST32 __PRI32(o) -#define PRIuLEAST32 __PRI32(u) -#define PRIxLEAST32 __PRI32(x) -#define PRIXLEAST32 __PRI32(X) - -#define SCNdLEAST32 __SCN32(d) -#define SCNiLEAST32 __SCN32(i) -#define SCNoLEAST32 __SCN32(o) -#define SCNuLEAST32 __SCN32(u) -#define SCNxLEAST32 __SCN32(x) - - -#define PRIdFAST32 __PRI32(d) -#define PRIiFAST32 __PRI32(i) -#define PRIoFAST32 __PRI32(o) -#define PRIuFAST32 __PRI32(u) -#define PRIxFAST32 __PRI32(x) -#define PRIXFAST32 __PRI32(X) - -#define SCNdFAST32 __SCN32(d) -#define SCNiFAST32 __SCN32(i) -#define SCNoFAST32 __SCN32(o) -#define SCNuFAST32 __SCN32(u) -#define SCNxFAST32 __SCN32(x) - - -/* 64-bit types */ -#if __have_longlong64 -#define __PRI64(x) __STRINGIFY(ll##x) -#define __SCN64(x) __STRINGIFY(ll##x) -#elif __have_long64 -#define __PRI64(x) __STRINGIFY(l##x) -#define __SCN64(x) __STRINGIFY(l##x) -#else -#define __PRI64(x) __STRINGIFY(x) -#define __SCN64(x) __STRINGIFY(x) -#endif - -#define PRId64 __PRI64(d) -#define PRIi64 __PRI64(i) -#define PRIo64 __PRI64(o) -#define PRIu64 __PRI64(u) -#define PRIx64 __PRI64(x) -#define PRIX64 __PRI64(X) - -#define SCNd64 __SCN64(d) -#define SCNi64 __SCN64(i) -#define SCNo64 __SCN64(o) -#define SCNu64 __SCN64(u) -#define SCNx64 __SCN64(x) - -#if __int64_t_defined -#define PRIdLEAST64 __PRI64(d) -#define PRIiLEAST64 __PRI64(i) -#define PRIoLEAST64 __PRI64(o) -#define PRIuLEAST64 __PRI64(u) -#define PRIxLEAST64 __PRI64(x) -#define PRIXLEAST64 __PRI64(X) - -#define SCNdLEAST64 __SCN64(d) -#define SCNiLEAST64 __SCN64(i) -#define SCNoLEAST64 __SCN64(o) -#define SCNuLEAST64 __SCN64(u) -#define SCNxLEAST64 __SCN64(x) - - -#define PRIdFAST64 __PRI64(d) -#define PRIiFAST64 __PRI64(i) -#define PRIoFAST64 __PRI64(o) -#define PRIuFAST64 __PRI64(u) -#define PRIxFAST64 __PRI64(x) -#define PRIXFAST64 __PRI64(X) - -#define SCNdFAST64 __SCN64(d) -#define SCNiFAST64 __SCN64(i) -#define SCNoFAST64 __SCN64(o) -#define SCNuFAST64 __SCN64(u) -#define SCNxFAST64 __SCN64(x) -#endif - -/* max-bit types */ -#if __have_longlong64 -#define __PRIMAX(x) __STRINGIFY(ll##x) -#define __SCNMAX(x) __STRINGIFY(ll##x) -#elif __have_long64 -#define __PRIMAX(x) __STRINGIFY(l##x) -#define __SCNMAX(x) __STRINGIFY(l##x) -#else -#define __PRIMAX(x) __STRINGIFY(x) -#define __SCNMAX(x) __STRINGIFY(x) -#endif - -#define PRIdMAX __PRIMAX(d) -#define PRIiMAX __PRIMAX(i) -#define PRIoMAX __PRIMAX(o) -#define PRIuMAX __PRIMAX(u) -#define PRIxMAX __PRIMAX(x) -#define PRIXMAX __PRIMAX(X) - -#define SCNdMAX __SCNMAX(d) -#define SCNiMAX __SCNMAX(i) -#define SCNoMAX __SCNMAX(o) -#define SCNuMAX __SCNMAX(u) -#define SCNxMAX __SCNMAX(x) - -/* ptr types */ -#if __have_longlong64 -#define __PRIPTR(x) __STRINGIFY(ll##x) -#define __SCNPTR(x) __STRINGIFY(ll##x) -#elif __have_long64 -#define __PRIPTR(x) __STRINGIFY(l##x) -#define __SCNPTR(x) __STRINGIFY(l##x) -#else -#define __PRIPTR(x) __STRINGIFY(x) -#define __SCNPTR(x) __STRINGIFY(x) -#endif - -#define PRIdPTR __PRIPTR(d) -#define PRIiPTR __PRIPTR(i) -#define PRIoPTR __PRIPTR(o) -#define PRIuPTR __PRIPTR(u) -#define PRIxPTR __PRIPTR(x) -#define PRIXPTR __PRIPTR(X) - -#define SCNdPTR __SCNPTR(d) -#define SCNiPTR __SCNPTR(i) -#define SCNoPTR __SCNPTR(o) -#define SCNuPTR __SCNPTR(u) -#define SCNxPTR __SCNPTR(x) - - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -#ifdef __cplusplus -extern "C" { -#endif - -extern intmax_t imaxabs(intmax_t j); -extern imaxdiv_t imaxdiv(intmax_t numer, intmax_t denomer); -extern intmax_t strtoimax(const char *__restrict, char **__restrict, int); -extern uintmax_t strtoumax(const char *__restrict, char **__restrict, int); -extern intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int); -extern uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extra_include/langinfo.h b/extra_include/langinfo.h deleted file mode 100644 index 31add149..00000000 --- a/extra_include/langinfo.h +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * Copyright (c) 2001 Alexey Zelkin - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD: src/include/langinfo.h,v 1.5 2002/03/23 17:24:53 imp Exp $ - */ - -#ifndef _LANGINFO_H_ -#define _LANGINFO_H_ - -#include - -typedef int nl_item; - -/* Extract the category and item index from a constructed `nl_item' value. */ -#define _NL_ITEM_CATEGORY(item) ((int) (item) >> 16) -#define _NL_ITEM_INDEX(item) ((int) (item) & 0xffff) - -#define CODESET 0 /* codeset name */ -#define D_T_FMT 1 /* string for formatting date and time */ -#define D_FMT 2 /* date format string */ -#define T_FMT 3 /* time format string */ -#define T_FMT_AMPM 4 /* a.m. or p.m. time formatting string */ -#define AM_STR 5 /* Ante Meridian affix */ -#define PM_STR 6 /* Post Meridian affix */ - -/* week day names */ -#define DAY_1 7 -#define DAY_2 8 -#define DAY_3 9 -#define DAY_4 10 -#define DAY_5 11 -#define DAY_6 12 -#define DAY_7 13 - -/* abbreviated week day names */ -#define ABDAY_1 14 -#define ABDAY_2 15 -#define ABDAY_3 16 -#define ABDAY_4 17 -#define ABDAY_5 18 -#define ABDAY_6 19 -#define ABDAY_7 20 - -/* month names */ -#define MON_1 21 -#define MON_2 22 -#define MON_3 23 -#define MON_4 24 -#define MON_5 25 -#define MON_6 26 -#define MON_7 27 -#define MON_8 28 -#define MON_9 29 -#define MON_10 30 -#define MON_11 31 -#define MON_12 32 - -/* abbreviated month names */ -#define ABMON_1 33 -#define ABMON_2 34 -#define ABMON_3 35 -#define ABMON_4 36 -#define ABMON_5 37 -#define ABMON_6 38 -#define ABMON_7 39 -#define ABMON_8 40 -#define ABMON_9 41 -#define ABMON_10 42 -#define ABMON_11 43 -#define ABMON_12 44 - -#define ERA 45 /* era description segments */ -#define ERA_D_FMT 46 /* era date format string */ -#define ERA_D_T_FMT 47 /* era date and time format string */ -#define ERA_T_FMT 48 /* era time format string */ -#define ALT_DIGITS 49 /* alternative symbols for digits */ - -#define RADIXCHAR 50 /* radix char */ -#define THOUSEP 51 /* separator for thousands */ - -#define YESEXPR 52 /* affirmative response expression */ -#define NOEXPR 53 /* negative response expression */ -#define YESSTR 54 /* affirmative response for yes/no queries */ -#define NOSTR 55 /* negative response for yes/no queries */ - -#define CRNCYSTR 56 /* currency symbol */ - -#define D_MD_ORDER 57 /* month/day order (local extension) */ - -#define _NL_CTYPE_TRANSLIT_TAB_SIZE 58 -#define _NL_CTYPE_TRANSLIT_FROM_IDX 59 -#define _NL_CTYPE_TRANSLIT_FROM_TBL 60 -#define _NL_CTYPE_TRANSLIT_TO_IDX 61 -#define _NL_CTYPE_TRANSLIT_TO_TBL 62 -#define _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN 63 -#define _NL_CTYPE_TRANSLIT_DEFAULT_MISSING 64 -#define _NL_CTYPE_TRANSLIT_IGNORE_LEN 65 -#define _NL_CTYPE_TRANSLIT_IGNORE 66 -#define _NL_CTYPE_EXTRA_MAP_1 70 -#define _NL_CTYPE_EXTRA_MAP_2 71 -#define _NL_CTYPE_EXTRA_MAP_3 72 -#define _NL_CTYPE_EXTRA_MAP_4 73 -#define _NL_CTYPE_EXTRA_MAP_5 74 -#define _NL_CTYPE_EXTRA_MAP_6 75 -#define _NL_CTYPE_EXTRA_MAP_7 76 -#define _NL_CTYPE_EXTRA_MAP_8 77 -#define _NL_CTYPE_EXTRA_MAP_9 78 -#define _NL_CTYPE_EXTRA_MAP_10 79 -#define _NL_CTYPE_EXTRA_MAP_11 80 -#define _NL_CTYPE_EXTRA_MAP_12 81 -#define _NL_CTYPE_EXTRA_MAP_13 82 -#define _NL_CTYPE_EXTRA_MAP_14 83 - -__BEGIN_DECLS -char *nl_langinfo(nl_item); -__END_DECLS - -#endif /* !_LANGINFO_H_ */ diff --git a/extra_include/limits.h b/extra_include/limits.h deleted file mode 100644 index 9c4b5854..00000000 --- a/extra_include/limits.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _LIBC_LIMITS_H_ -# define _LIBC_LIMITS_H_ 1 - -#include - -# ifdef _MB_LEN_MAX -# define MB_LEN_MAX _MB_LEN_MAX -# else -# define MB_LEN_MAX 1 -# endif - -/* if do not have #include_next support, then we - have to define the limits here. */ -# if !defined __GNUC__ || __GNUC__ < 2 - -# ifndef _LIMITS_H -# define _LIMITS_H 1 - -# include - -/* Number of bits in a `char'. */ -# undef CHAR_BIT -# define CHAR_BIT 8 - -/* Minimum and maximum values a `signed char' can hold. */ -# undef SCHAR_MIN -# define SCHAR_MIN (-128) -# undef SCHAR_MAX -# define SCHAR_MAX 127 - -/* Maximum value an `unsigned char' can hold. (Minimum is 0). */ -# undef UCHAR_MAX -# define UCHAR_MAX 255 - -/* Minimum and maximum values a `char' can hold. */ -# ifdef __CHAR_UNSIGNED__ -# undef CHAR_MIN -# define CHAR_MIN 0 -# undef CHAR_MAX -# define CHAR_MAX 255 -# else -# undef CHAR_MIN -# define CHAR_MIN (-128) -# undef CHAR_MAX -# define CHAR_MAX 127 -# endif - -/* Minimum and maximum values a `signed short int' can hold. */ -# undef SHRT_MIN -/* For the sake of 16 bit hosts, we may not use -32768 */ -# define SHRT_MIN (-32767-1) -# undef SHRT_MAX -# define SHRT_MAX 32767 - -/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */ -# undef USHRT_MAX -# define USHRT_MAX 65535 - -/* Minimum and maximum values a `signed int' can hold. */ -# ifndef __INT_MAX__ -# define __INT_MAX__ 2147483647 -# endif -# undef INT_MIN -# define INT_MIN (-INT_MAX-1) -# undef INT_MAX -# define INT_MAX __INT_MAX__ - -/* Maximum value an `unsigned int' can hold. (Minimum is 0). */ -# undef UINT_MAX -# define UINT_MAX (INT_MAX * 2U + 1) - -/* Minimum and maximum values a `signed long int' can hold. - (Same as `int'). */ -# ifndef __LONG_MAX__ -# if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9) -# define __LONG_MAX__ 9223372036854775807L -# else -# define __LONG_MAX__ 2147483647L -# endif /* __alpha__ || sparc64 */ -# endif -# undef LONG_MIN -# define LONG_MIN (-LONG_MAX-1) -# undef LONG_MAX -# define LONG_MAX __LONG_MAX__ - -/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ -# undef ULONG_MAX -# define ULONG_MAX (LONG_MAX * 2UL + 1) - -# ifndef __LONG_LONG_MAX__ -# define __LONG_LONG_MAX__ 9223372036854775807LL -# endif - -# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -/* Minimum and maximum values a `signed long long int' can hold. */ -# undef LLONG_MIN -# define LLONG_MIN (-LLONG_MAX-1) -# undef LLONG_MAX -# define LLONG_MAX __LONG_LONG_MAX__ - -/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ -# undef ULLONG_MAX -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1) -# endif - -# if defined (__GNU_LIBRARY__) ? defined (__USE_GNU) : !defined (__STRICT_ANSI__) -/* Minimum and maximum values a `signed long long int' can hold. */ -# undef LONG_LONG_MIN -# define LONG_LONG_MIN (-LONG_LONG_MAX-1) -# undef LONG_LONG_MAX -# define LONG_LONG_MAX __LONG_LONG_MAX__ - -/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ -# undef ULONG_LONG_MAX -# define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1) -# endif - -# endif /* _LIMITS_H */ -# endif /* GCC 2. */ - -#endif /* !_LIBC_LIMITS_H_ */ - -#if defined __GNUC__ && !defined _GCC_LIMITS_H_ -/* `_GCC_LIMITS_H_' is what GCC's file defines. */ -# include_next -#endif /* __GNUC__ && !_GCC_LIMITS_H_ */ - diff --git a/extra_include/locale.h b/extra_include/locale.h deleted file mode 100644 index 46e7c6b5..00000000 --- a/extra_include/locale.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - locale.h - Values appropriate for the formatting of monetary and other - numberic quantities. -*/ - -#ifndef _LOCALE_H_ -#define _LOCALE_H_ - -#include "_ansi.h" - -#ifndef NULL -#define NULL 0 -#endif - -#define LC_ALL 0 -#define LC_COLLATE 1 -#define LC_CTYPE 2 -#define LC_MONETARY 3 -#define LC_NUMERIC 4 -#define LC_TIME 5 -#define LC_MESSAGES 6 - -_BEGIN_STD_C - -struct lconv -{ - char *decimal_point; - char *thousands_sep; - char *grouping; - char *int_curr_symbol; - char *currency_symbol; - char *mon_decimal_point; - char *mon_thousands_sep; - char *mon_grouping; - char *positive_sign; - char *negative_sign; - char int_frac_digits; - char frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; -}; - -#ifndef _REENT_ONLY -char *_EXFUN(setlocale,(int category, const char *locale)); -struct lconv *_EXFUN(localeconv,(void)); -#endif - -struct _reent; -char *_EXFUN(_setlocale_r,(struct _reent *, int category, const char *locale)); -struct lconv *_EXFUN(_localeconv_r,(struct _reent *)); - -_END_STD_C - -#endif /* _LOCALE_H_ */ diff --git a/extra_include/machine/ansi.h b/extra_include/machine/ansi.h deleted file mode 100644 index c75a5ba5..00000000 --- a/extra_include/machine/ansi.h +++ /dev/null @@ -1 +0,0 @@ -/* dummy header file to support BSD compiler */ diff --git a/extra_include/machine/endian.h b/extra_include/machine/endian.h deleted file mode 100644 index 57661ef1..00000000 --- a/extra_include/machine/endian.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __MACHINE_ENDIAN_H__ - -#include - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif - -#ifndef BYTE_ORDER -#ifdef __IEEE_LITTLE_ENDIAN -#define BYTE_ORDER LITTLE_ENDIAN -#else -#define BYTE_ORDER BIG_ENDIAN -#endif -#endif - -#endif /* __MACHINE_ENDIAN_H__ */ diff --git a/extra_include/machine/fastmath.h b/extra_include/machine/fastmath.h deleted file mode 100644 index e31d810e..00000000 --- a/extra_include/machine/fastmath.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifdef __sysvnecv70_target -double EXFUN(fast_sin,(double)); -double EXFUN(fast_cos,(double)); -double EXFUN(fast_tan,(double)); - -double EXFUN(fast_asin,(double)); -double EXFUN(fast_acos,(double)); -double EXFUN(fast_atan,(double)); - -double EXFUN(fast_sinh,(double)); -double EXFUN(fast_cosh,(double)); -double EXFUN(fast_tanh,(double)); - -double EXFUN(fast_asinh,(double)); -double EXFUN(fast_acosh,(double)); -double EXFUN(fast_atanh,(double)); - -double EXFUN(fast_abs,(double)); -double EXFUN(fast_sqrt,(double)); -double EXFUN(fast_exp2,(double)); -double EXFUN(fast_exp10,(double)); -double EXFUN(fast_expe,(double)); -double EXFUN(fast_log10,(double)); -double EXFUN(fast_log2,(double)); -double EXFUN(fast_loge,(double)); - - -#define sin(x) fast_sin(x) -#define cos(x) fast_cos(x) -#define tan(x) fast_tan(x) -#define asin(x) fast_asin(x) -#define acos(x) fast_acos(x) -#define atan(x) fast_atan(x) -#define sinh(x) fast_sinh(x) -#define cosh(x) fast_cosh(x) -#define tanh(x) fast_tanh(x) -#define asinh(x) fast_asinh(x) -#define acosh(x) fast_acosh(x) -#define atanh(x) fast_atanh(x) -#define abs(x) fast_abs(x) -#define sqrt(x) fast_sqrt(x) -#define exp2(x) fast_exp2(x) -#define exp10(x) fast_exp10(x) -#define expe(x) fast_expe(x) -#define log10(x) fast_log10(x) -#define log2(x) fast_log2(x) -#define loge(x) fast_loge(x) - -#ifdef _HAVE_STDC -/* These functions are in assembler, they really do take floats. This - can only be used with a real ANSI compiler */ - -float EXFUN(fast_sinf,(float)); -float EXFUN(fast_cosf,(float)); -float EXFUN(fast_tanf,(float)); - -float EXFUN(fast_asinf,(float)); -float EXFUN(fast_acosf,(float)); -float EXFUN(fast_atanf,(float)); - -float EXFUN(fast_sinhf,(float)); -float EXFUN(fast_coshf,(float)); -float EXFUN(fast_tanhf,(float)); - -float EXFUN(fast_asinhf,(float)); -float EXFUN(fast_acoshf,(float)); -float EXFUN(fast_atanhf,(float)); - -float EXFUN(fast_absf,(float)); -float EXFUN(fast_sqrtf,(float)); -float EXFUN(fast_exp2f,(float)); -float EXFUN(fast_exp10f,(float)); -float EXFUN(fast_expef,(float)); -float EXFUN(fast_log10f,(float)); -float EXFUN(fast_log2f,(float)); -float EXFUN(fast_logef,(float)); -#define sinf(x) fast_sinf(x) -#define cosf(x) fast_cosf(x) -#define tanf(x) fast_tanf(x) -#define asinf(x) fast_asinf(x) -#define acosf(x) fast_acosf(x) -#define atanf(x) fast_atanf(x) -#define sinhf(x) fast_sinhf(x) -#define coshf(x) fast_coshf(x) -#define tanhf(x) fast_tanhf(x) -#define asinhf(x) fast_asinhf(x) -#define acoshf(x) fast_acoshf(x) -#define atanhf(x) fast_atanhf(x) -#define absf(x) fast_absf(x) -#define sqrtf(x) fast_sqrtf(x) -#define exp2f(x) fast_exp2f(x) -#define exp10f(x) fast_exp10f(x) -#define expef(x) fast_expef(x) -#define log10f(x) fast_log10f(x) -#define log2f(x) fast_log2f(x) -#define logef(x) fast_logef(x) -#endif -/* Override the functions defined in math.h */ -#endif /* __sysvnecv70_target */ - diff --git a/extra_include/machine/ieeefp.h b/extra_include/machine/ieeefp.h deleted file mode 100644 index ede3cfdc..00000000 --- a/extra_include/machine/ieeefp.h +++ /dev/null @@ -1,283 +0,0 @@ -#ifndef __IEEE_BIG_ENDIAN -#ifndef __IEEE_LITTLE_ENDIAN - -/* This file can define macros to choose variations of the IEEE float - format: - - _FLT_LARGEST_EXPONENT_IS_NORMAL - - Defined if the float format uses the largest exponent for finite - numbers rather than NaN and infinity representations. Such a - format cannot represent NaNs or infinities at all, but it's FLT_MAX - is twice the IEEE value. - - _FLT_NO_DENORMALS - - Defined if the float format does not support IEEE denormals. Every - float with a zero exponent is taken to be a zero representation. - - ??? At the moment, there are no equivalent macros above for doubles and - the macros are not fully supported by --enable-newlib-hw-fp. - - __IEEE_BIG_ENDIAN - - Defined if the float format is big endian. This is mutually exclusive - with __IEEE_LITTLE_ENDIAN. - - __IEEE_LITTLE_ENDIAN - - Defined if the float format is little endian. This is mutually exclusive - with __IEEE_BIG_ENDIAN. - - Note that one of __IEEE_BIG_ENDIAN or __IEEE_LITTLE_ENDIAN must be specified for a - platform or error will occur. - - __IEEE_BYTES_LITTLE_ENDIAN - - This flag is used in conjunction with __IEEE_BIG_ENDIAN to describe a situation - whereby multiple words of an IEEE floating point are in big endian order, but the - words themselves are little endian with respect to the bytes. - - _DOUBLE_IS_32_BITS - - This is used on platforms that support double by using the 32-bit IEEE - float type. - - _FLOAT_ARG - - This represents what type a float arg is passed as. It is used when the type is - not promoted to double. - -*/ - -#if (defined(__arm__) || defined(__thumb__)) && !defined(__MAVERICK__) -/* ARM traditionally used big-endian words; and within those words the - byte ordering was big or little endian depending upon the target. - Modern floating-point formats are naturally ordered; in this case - __VFP_FP__ will be defined, even if soft-float. */ -#ifdef __VFP_FP__ -# ifdef __ARMEL__ -# define __IEEE_LITTLE_ENDIAN -# else -# define __IEEE_BIG_ENDIAN -# endif -#else -# define __IEEE_BIG_ENDIAN -# ifdef __ARMEL__ -# define __IEEE_BYTES_LITTLE_ENDIAN -# endif -#endif -#endif - -#ifdef __hppa__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __sparc__ -#ifdef __LITTLE_ENDIAN_DATA__ -#define __IEEE_LITTLE_ENDIAN -#else -#define __IEEE_BIG_ENDIAN -#endif -#endif - -#if defined(__m68k__) || defined(__mc68000__) -#define __IEEE_BIG_ENDIAN -#endif - -#if defined(__mc68hc11__) || defined(__mc68hc12__) || defined(__mc68hc1x__) -#define __IEEE_BIG_ENDIAN -#ifdef __HAVE_SHORT_DOUBLE__ -# define _DOUBLE_IS_32BITS -#endif -#endif - -#if defined (__H8300__) || defined (__H8300H__) || defined (__H8300S__) || defined (__H8500__) || defined (__H8300SX__) -#define __IEEE_BIG_ENDIAN -#define _FLOAT_ARG float -#define _DOUBLE_IS_32BITS -#endif - -#ifdef __sh__ -#ifdef __LITTLE_ENDIAN__ -#define __IEEE_LITTLE_ENDIAN -#else -#define __IEEE_BIG_ENDIAN -#endif -#if defined(__SH2E__) || defined(__SH3E__) || defined(__SH4_SINGLE_ONLY__) || defined(__SH2A_SINGLE_ONLY__) -#define _DOUBLE_IS_32BITS -#endif -#endif - -#ifdef _AM29K -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef _WIN32 -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __i386__ -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __i960__ -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __M32R__ -#define __IEEE_BIG_ENDIAN -#endif - -#if defined(_C4x) || defined(_C3x) -#define __IEEE_BIG_ENDIAN -#define _DOUBLE_IS_32BITS -#endif - -#ifdef __TIC80__ -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __MIPSEL__ -#define __IEEE_LITTLE_ENDIAN -#endif -#ifdef __MIPSEB__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __MMIX__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __D30V__ -#define __IEEE_BIG_ENDIAN -#endif - -/* necv70 was __IEEE_LITTLE_ENDIAN. */ - -#ifdef __W65__ -#define __IEEE_LITTLE_ENDIAN -#define _DOUBLE_IS_32BITS -#endif - -#if defined(__Z8001__) || defined(__Z8002__) -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __m88k__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __mn10300__ -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __mn10200__ -#define __IEEE_LITTLE_ENDIAN -#define _DOUBLE_IS_32BITS -#endif - -#ifdef __v800 -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __v850 -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __D10V__ -#define __IEEE_BIG_ENDIAN -#if __DOUBLE__ == 32 -#define _DOUBLE_IS_32BITS -#endif -#endif - -#ifdef __PPC__ -#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) -#define __IEEE_BIG_ENDIAN -#else -#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(_WIN32) && _WIN32) -#define __IEEE_LITTLE_ENDIAN -#endif -#endif -#endif - -#ifdef __xstormy16__ -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __arc__ -#ifdef __big_endian__ -#define __IEEE_BIG_ENDIAN -#else -#define __IEEE_LITTLE_ENDIAN -#endif -#endif - -#ifdef __CRX__ -#define __IEEE_LITTLE_ENDIAN -#endif - -#ifdef __fr30__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __mcore__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __frv__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __ia64__ -#ifdef __BIG_ENDIAN__ -#define __IEEE_BIG_ENDIAN -#else -#define __IEEE_LITTLE_ENDIAN -#endif -#endif - -#ifdef __AVR__ -#define __IEEE_LITTLE_ENDIAN -#define _DOUBLE_IS_32BITS -#endif - -#if defined(__or32__) || defined(__or1k__) || defined(__or16__) -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __IP2K__ -#define __IEEE_BIG_ENDIAN -#define __SMALL_BITFIELDS -#define _DOUBLE_IS_32BITS -#endif - -#ifdef __iq2000__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifdef __MAVERICK__ -#ifdef __ARMEL__ -# define __IEEE_LITTLE_ENDIAN -#else /* must be __ARMEB__ */ -# define __IEEE_BIG_ENDIAN -#endif /* __ARMEL__ */ -#endif /* __MAVERICK__ */ - -#ifdef __XTENSA_EL__ -#define __IEEE_LITTLE_ENDIAN -#endif -#ifdef __XTENSA_EB__ -#define __IEEE_BIG_ENDIAN -#endif - -#ifndef __IEEE_BIG_ENDIAN -#ifndef __IEEE_LITTLE_ENDIAN -#error Endianess not declared!! -#endif /* not __IEEE_LITTLE_ENDIAN */ -#endif /* not __IEEE_BIG_ENDIAN */ - -#endif /* not __IEEE_LITTLE_ENDIAN */ -#endif /* not __IEEE_BIG_ENDIAN */ - diff --git a/extra_include/machine/malloc.h b/extra_include/machine/malloc.h deleted file mode 100644 index 1b2e54bb..00000000 --- a/extra_include/machine/malloc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _MACHMALLOC_H_ -#define _MACHMALLOC_H_ - -/* place holder so platforms may add malloc.h extensions */ - -#endif /* _MACHMALLOC_H_ */ - - diff --git a/extra_include/machine/param.h b/extra_include/machine/param.h deleted file mode 100644 index 65807862..00000000 --- a/extra_include/machine/param.h +++ /dev/null @@ -1 +0,0 @@ -/* Place holder for machine-specific param.h. */ diff --git a/extra_include/machine/setjmp-dj.h b/extra_include/machine/setjmp-dj.h deleted file mode 100644 index ab0d0d65..00000000 --- a/extra_include/machine/setjmp-dj.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 1991 DJ Delorie - * All rights reserved. - * - * Redistribution and use in source and binary forms is permitted - * provided that the above copyright notice and following paragraph are - * duplicated in all such forms. - * - * This file is distributed WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* Modified to use SETJMP_DJ_H rather than SETJMP_H to avoid - conflicting with setjmp.h. Ian Taylor, Cygnus support, April, - 1993. */ - -#ifndef _SETJMP_DJ_H_ -#define _SETJMP_DJ_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned long eax; - unsigned long ebx; - unsigned long ecx; - unsigned long edx; - unsigned long esi; - unsigned long edi; - unsigned long ebp; - unsigned long esp; - unsigned long eip; -} jmp_buf[1]; - -extern int setjmp(jmp_buf); -extern void longjmp(jmp_buf, int); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extra_include/machine/setjmp.h b/extra_include/machine/setjmp.h deleted file mode 100644 index 40a9bafd..00000000 --- a/extra_include/machine/setjmp.h +++ /dev/null @@ -1,273 +0,0 @@ - -_BEGIN_STD_C - -#if defined(__arm__) || defined(__thumb__) -/* - * All callee preserved registers: - * v1 - v7, fp, ip, sp, lr, f4, f5, f6, f7 - */ -#define _JBLEN 23 -#endif - -#if defined(__AVR__) -#define _JBLEN 24 -#endif - -#ifdef __sparc__ -/* - * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext). - * All else recovered by under/over(flow) handling. - */ -#define _JBLEN 13 -#endif - -/* necv70 was 9 as well. */ - -#ifdef __mc68000__ -/* - * onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6, - * fp2-fp7 for 68881. - * All else recovered by under/over(flow) handling. - */ -#define _JBLEN 34 -#endif - -#if defined(__mc68hc11__) || defined(__mc68hc12__) || defined(__mc68hc1x__) -/* - * D, X, Y are not saved. - * Only take into account the pseudo soft registers (max 32). - */ -#define _JBLEN 32 -#endif - -#if defined(__Z8001__) || defined(__Z8002__) -/* 16 regs + pc */ -#define _JBLEN 20 -#endif - -#ifdef _AM29K -/* - * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext). - * All else recovered by under/over(flow) handling. - */ -#define _JBLEN 9 -#endif - -#if defined(__CYGWIN__) && !defined (_JBLEN) -#define _JBLEN (13 * 4) -#elif defined (__i386__) -#if defined(__unix__) || defined(__rtems__) -# define _JBLEN 9 -#else -#include "setjmp-dj.h" -#endif -#endif - -#ifdef __i960__ -#define _JBLEN 35 -#endif - -#ifdef __M32R__ -/* Only 8 words are currently needed. 10 gives us some slop if we need - to expand. */ -#define _JBLEN 10 -#endif - -#ifdef __mips__ -#ifdef __mips64 -#define _JBTYPE long long -#endif -#ifdef __mips_soft_float -#define _JBLEN 11 -#else -#define _JBLEN 23 -#endif -#endif - -#ifdef __m88000__ -#define _JBLEN 21 -#endif - -#ifdef __H8300__ -#define _JBLEN 5 -#define _JBTYPE int -#endif - -#ifdef __H8300H__ -/* same as H8/300 but registers are twice as big */ -#define _JBLEN 5 -#define _JBTYPE long -#endif - -#if defined (__H8300S__) || defined (__H8300SX__) -/* same as H8/300 but registers are twice as big */ -#define _JBLEN 5 -#define _JBTYPE long -#endif - -#ifdef __H8500__ -#define _JBLEN 4 -#endif - -#ifdef __sh__ -#if __SH5__ -#define _JBLEN 50 -#define _JBTYPE long long -#else -#define _JBLEN 20 -#endif /* __SH5__ */ -#endif - -#ifdef __v800 -#define _JBLEN 28 -#endif - -#ifdef __PPC__ -#ifdef __ALTIVEC__ -#define _JBLEN 64 -#else -#define _JBLEN 32 -#endif -#define _JBTYPE double -#endif - -#ifdef __hppa__ -/* %r30, %r2-%r18, %r27, pad, %fr12-%fr15. - Note space exists for the FP registers, but they are not - saved. */ -#define _JBLEN 28 -#endif - -#if defined(__mn10300__) || defined(__mn10200__) -#ifdef __AM33_2__ -#define _JBLEN 26 -#else -/* A guess */ -#define _JBLEN 10 -#endif -#endif - -#ifdef __v850 -/* I think our setjmp is saving 15 regs at the moment. Gives us one word - slop if we need to expand. */ -#define _JBLEN 16 -#endif - -#if defined(_C4x) -#define _JBLEN 10 -#endif -#if defined(_C3x) -#define _JBLEN 9 -#endif - -#ifdef __TIC80__ -#define _JBLEN 13 -#endif - -#ifdef __D10V__ -#define _JBLEN 8 -#endif - -#ifdef __D30V__ -#define _JBLEN ((64 /* GPR */ + (2*2) /* ACs */ + 18 /* CRs */) / 2) -#define _JBTYPE double -#endif - -#ifdef __frv__ -#define _JBLEN (68/2) /* room for 68 32-bit regs */ -#define _JBTYPE double -#endif - -#ifdef __CRX__ -#define _JBLEN 9 -#endif - -#ifdef __fr30__ -#define _JBLEN 10 -#endif - -#ifdef __iq2000__ -#define _JBLEN 32 -#endif - -#ifdef __mcore__ -#define _JBLEN 16 -#endif - -#ifdef __MMIX__ -/* Using a layout compatible with GCC's built-in. */ -#define _JBLEN 5 -#define _JBTYPE unsigned long -#endif - -#ifdef __xstormy16__ -/* 4 GPRs plus SP plus PC. */ -#define _JBLEN 8 -#endif - -#ifdef __XTENSA__ -#if __XTENSA_WINDOWED_ABI__ - -/* The jmp_buf structure for Xtensa windowed ABI holds the following - (where "proc" is the procedure that calls setjmp): 4-12 registers - from the window of proc, the 4 words from the save area at proc's $sp - (in case a subsequent alloca in proc moves $sp), and the return - address within proc. Everything else is saved on the stack in the - normal save areas. The jmp_buf structure is: - - struct jmp_buf { - int regs[12]; - int save[4]; - void *return_address; - } - - See the setjmp code for details. */ - -#define _JBLEN 17 /* 12 + 4 + 1 */ - -#else /* __XTENSA_CALL0_ABI__ */ - -#define _JBLEN 6 /* a0, a1, a12, a13, a14, a15 */ - -#endif /* __XTENSA_CALL0_ABI__ */ -#endif /* __XTENSA__ */ - -#ifdef _JBLEN -#ifdef _JBTYPE -typedef _JBTYPE jmp_buf[_JBLEN]; -#else -typedef int jmp_buf[_JBLEN]; -#endif -#endif - -_END_STD_C - -#if defined(__CYGWIN__) || defined(__rtems__) -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* POSIX sigsetjmp/siglongjmp macros */ -typedef int sigjmp_buf[_JBLEN+2]; - -#define _SAVEMASK _JBLEN -#define _SIGMASK (_JBLEN+1) - -#ifdef __CYGWIN__ -# define _CYGWIN_WORKING_SIGSETJMP -#endif - -#define sigsetjmp(env, savemask) ((env)[_SAVEMASK] = savemask,\ - sigprocmask (SIG_SETMASK, 0, (sigset_t *) ((env) + _SIGMASK)),\ - setjmp (env)) - -#define siglongjmp(env, val) ((((env)[_SAVEMASK])?\ - sigprocmask (SIG_SETMASK, (sigset_t *) ((env) + _SIGMASK), 0):0),\ - longjmp (env, val)) - -#ifdef __cplusplus -} -#endif -#endif /* __CYGWIN__ or __rtems__ */ diff --git a/extra_include/machine/stdlib.h b/extra_include/machine/stdlib.h deleted file mode 100644 index 211c322d..00000000 --- a/extra_include/machine/stdlib.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _MACHSTDLIB_H_ -#define _MACHSTDLIB_H_ - -/* place holder so platforms may add stdlib.h extensions */ - -#endif /* _MACHSTDLIB_H_ */ - - diff --git a/extra_include/machine/termios.h b/extra_include/machine/termios.h deleted file mode 100644 index cb4f522a..00000000 --- a/extra_include/machine/termios.h +++ /dev/null @@ -1 +0,0 @@ -#define __MAX_BAUD B4000000 diff --git a/extra_include/machine/time.h b/extra_include/machine/time.h deleted file mode 100644 index d8e78ec2..00000000 --- a/extra_include/machine/time.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _MACHTIME_H_ -#define _MACHTIME_H_ - -#if defined(__rtems__) -#define _CLOCKS_PER_SEC_ sysconf(_SC_CLK_TCK) -#else /* !__rtems__ */ -#if defined(__arm__) || defined(__thumb__) -#define _CLOCKS_PER_SEC_ 100 -#endif -#if defined(__XTENSA__) -/* Use the value mandated by POSIX:XSI. */ -#define _CLOCKS_PER_SEC_ 1000000 -#endif -#endif /* !__rtems__ */ - -#endif /* _MACHTIME_H_ */ - - diff --git a/extra_include/machine/types.h b/extra_include/machine/types.h deleted file mode 100644 index f6e03aa7..00000000 --- a/extra_include/machine/types.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _MACHTYPES_H_ -#define _MACHTYPES_H_ - -/* - * The following section is RTEMS specific and is needed to more - * closely match the types defined in the BSD machine/types.h. - * This is needed to let the RTEMS/BSD TCP/IP stack compile. - */ - -#if defined(__rtems__) -typedef signed long long int64_t; -#if defined( __h8300__) -typedef signed long int32_t; -#else -typedef signed int int32_t; -#endif -typedef signed short int16_t; -typedef signed char int8_t; - -typedef unsigned long long u_int64_t; -#if defined( __h8300__) -typedef unsigned long u_int32_t; -#else -typedef unsigned int u_int32_t; -#endif -typedef unsigned short u_int16_t; -typedef unsigned char u_int8_t; -#endif - -#define _CLOCK_T_ unsigned long /* clock() */ -#define _TIME_T_ long /* time() */ -#define _CLOCKID_T_ unsigned long -#define _TIMER_T_ unsigned long - -#ifndef _HAVE_SYSTYPES -typedef long int __off_t; -typedef int __pid_t; -#ifdef __GNUC__ -__extension__ typedef long long int __loff_t; -#else -typedef long int __loff_t; -#endif -#endif - -#endif /* _MACHTYPES_H_ */ - - diff --git a/extra_include/machine/xtensa-hal.h b/extra_include/machine/xtensa-hal.h deleted file mode 100644 index 05b1363a..00000000 --- a/extra_include/machine/xtensa-hal.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/extra_include/malloc.h b/extra_include/malloc.h deleted file mode 100644 index 8e5d1d4d..00000000 --- a/extra_include/malloc.h +++ /dev/null @@ -1,169 +0,0 @@ -/* malloc.h -- header file for memory routines. */ - -#ifndef _INCLUDE_MALLOC_H_ -#define _INCLUDE_MALLOC_H_ - -#include <_ansi.h> -#include - -#define __need_size_t -#include - -/* include any machine-specific extensions */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* This version of struct mallinfo must match the one in - libc/stdlib/mallocr.c. */ - -struct mallinfo { - int arena; /* total space allocated from system */ - int ordblks; /* number of non-inuse chunks */ - int smblks; /* unused -- always zero */ - int hblks; /* number of mmapped regions */ - int hblkhd; /* total space in mmapped regions */ - int usmblks; /* unused -- always zero */ - int fsmblks; /* unused -- always zero */ - int uordblks; /* total allocated space */ - int fordblks; /* total non-inuse space */ - int keepcost; /* top-most, releasable (via malloc_trim) space */ -}; - -/* The routines. */ - -extern _PTR malloc _PARAMS ((size_t)); -#ifdef __CYGWIN__ -#undef _malloc_r -#define _malloc_r(r, s) malloc (s) -#else -extern _PTR _malloc_r _PARAMS ((struct _reent *, size_t)); -#endif - -extern _VOID free _PARAMS ((_PTR)); -#ifdef __CYGWIN__ -#undef _free_r -#define _free_r(r, p) free (p) -#else -extern _VOID _free_r _PARAMS ((struct _reent *, _PTR)); -#endif - -extern _PTR realloc _PARAMS ((_PTR, size_t)); -#ifdef __CYGWIN__ -#undef _realloc_r -#define _realloc_r(r, p, s) realloc (p, s) -#else -extern _PTR _realloc_r _PARAMS ((struct _reent *, _PTR, size_t)); -#endif - -extern _PTR calloc _PARAMS ((size_t, size_t)); -#ifdef __CYGWIN__ -#undef _calloc_r -#define _calloc_r(r, s1, s2) calloc (s1, s2); -#else -extern _PTR _calloc_r _PARAMS ((struct _reent *, size_t, size_t)); -#endif - -extern _PTR memalign _PARAMS ((size_t, size_t)); -#ifdef __CYGWIN__ -#undef _memalign_r -#define _memalign_r(r, s1, s2) memalign (s1, s2); -#else -extern _PTR _memalign_r _PARAMS ((struct _reent *, size_t, size_t)); -#endif - -extern struct mallinfo mallinfo _PARAMS ((void)); -#ifdef __CYGWIN__ -#undef _mallinfo_r -#define _mallinfo_r(r) mallinfo () -#else -extern struct mallinfo _mallinfo_r _PARAMS ((struct _reent *)); -#endif - -extern void malloc_stats _PARAMS ((void)); -#ifdef __CYGWIN__ -#undef _malloc_stats_r -#define _malloc_stats_r(r) malloc_stats () -#else -extern void _malloc_stats_r _PARAMS ((struct _reent *)); -#endif - -extern int mallopt _PARAMS ((int, int)); -#ifdef __CYGWIN__ -#undef _mallopt_r -#define _mallopt_r(i1, i2) mallopt (i1, i2) -#else -extern int _mallopt_r _PARAMS ((struct _reent *, int, int)); -#endif - -extern size_t malloc_usable_size _PARAMS ((_PTR)); -#ifdef __CYGWIN__ -#undef _malloc_usable_size_r -#define _malloc_usable_size_r(r, p) malloc_usable_size (p) -#else -extern size_t _malloc_usable_size_r _PARAMS ((struct _reent *, _PTR)); -#endif - -/* These aren't too useful on an embedded system, but we define them - anyhow. */ - -extern _PTR valloc _PARAMS ((size_t)); -#ifdef __CYGWIN__ -#undef _valloc_r -#define _valloc_r(r, s) valloc (s) -#else -extern _PTR _valloc_r _PARAMS ((struct _reent *, size_t)); -#endif - -extern _PTR pvalloc _PARAMS ((size_t)); -#ifdef __CYGWIN__ -#undef _pvalloc_r -#define _pvalloc_r(r, s) pvalloc (s) -#else -extern _PTR _pvalloc_r _PARAMS ((struct _reent *, size_t)); -#endif - -extern int malloc_trim _PARAMS ((size_t)); -#ifdef __CYGWIN__ -#undef _malloc_trim_r -#define _malloc_trim_r(r, s) malloc_trim (s) -#else -extern int _malloc_trim_r _PARAMS ((struct _reent *, size_t)); -#endif - -/* A compatibility routine for an earlier version of the allocator. */ - -extern _VOID mstats _PARAMS ((char *)); -#ifdef __CYGWIN__ -#undef _mstats_r -#define _mstats_r(r, p) mstats (p) -#else -extern _VOID _mstats_r _PARAMS ((struct _reent *, char *)); -#endif - -/* SVID2/XPG mallopt options */ - -#define M_MXFAST 1 /* UNUSED in this malloc */ -#define M_NLBLKS 2 /* UNUSED in this malloc */ -#define M_GRAIN 3 /* UNUSED in this malloc */ -#define M_KEEP 4 /* UNUSED in this malloc */ - -/* mallopt options that actually do something */ - -#define M_TRIM_THRESHOLD -1 -#define M_TOP_PAD -2 -#define M_MMAP_THRESHOLD -3 -#define M_MMAP_MAX -4 - -#ifndef __CYGWIN__ -/* Some systems provide this, so do too for compatibility. */ -extern void cfree _PARAMS ((_PTR)); -#endif /* __CYGWIN__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _INCLUDE_MALLOC_H_ */ diff --git a/extra_include/math.h b/extra_include/math.h deleted file mode 100644 index e8a475d7..00000000 --- a/extra_include/math.h +++ /dev/null @@ -1,442 +0,0 @@ -/* math.h -- Definitions for the math floating point package. */ - -#ifndef _MATH_H_ -#define _MATH_H_ - -#include -#include -#include "_ansi.h" - -_BEGIN_STD_C - -#ifndef HUGE_VAL - -/* Define HUGE_VAL as infinity, unless HUGE_VAL is already defined - (which might have been done by something like math-68881.h). */ - -union __dmath -{ - __ULong i[2]; - double d; -}; - -/* Declare this as an array without bounds so that no matter what small data - support a port and/or library has, this reference will be via the general - method for accessing globals. */ -extern __IMPORT const union __dmath __infinity[]; - -#if defined(__GNUC__) && \ - ( (__GNUC__ >= 4) || \ - ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 3) ) ) - - /* gcc >= 3.3 implicitly defines builtins for HUGE_VALx values. */ - -# ifndef HUGE_VAL -# define HUGE_VAL (__builtin_huge_val()) -# endif - -# ifndef HUGE_VALF -# define HUGE_VALF (__builtin_huge_valf()) -# endif - -# ifndef HUGE_VALL -# define HUGE_VALL (__builtin_huge_vall()) -# endif - -# ifndef INFINITY -# define INFINITY (__builtin_inff()) -# endif - -# ifndef NAN -# define NAN (__builtin_nanf("")) -# endif - -#else /* !gcc >= 3.3 */ - - /* No builtins. Use fixed defines instead. (All 3 HUGE plus the INFINITY - * and NAN macros are required to be constant expressions. Using a variable-- - * even a static const--does not meet this requirement, as it cannot be - * evaluated at translation time.) - * The infinities are done using numbers that are far in excess of - * something that would be expected to be encountered in a floating-point - * implementation. (A more certain way uses values from float.h, but that is - * avoided because system includes are not supposed to include each other.) - * This method might produce warnings from some compilers. (It does in - * newer GCCs, but not for ones that would hit this #else.) If this happens, - * please report details to the Newlib mailing list. */ - - #ifndef HUGE_VAL - #define HUGE_VAL (1.0e999999999) - #endif - - #ifndef HUGE_VALF - #define HUGE_VALF (1.0e999999999F) - #endif - - #if !defined(HUGE_VALL) && defined(_HAVE_LONG_DOUBLE) - #define HUGE_VALL (1.0e999999999L) - #endif - - #if !defined(INFINITY) - #define INFINITY (HUGE_VALF) - #endif - - #if !defined(NAN) - #if defined(__GNUC__) && defined(__cplusplus) - /* Exception: older g++ versions warn about the divide by 0 used in the - * normal case (even though older gccs do not). This trick suppresses the - * warning, but causes errors for plain gcc, so is only used in the one - * special case. */ - static const union { __ULong __i[1]; float __d; } __Nanf = {0x7FC00000}; - #define NAN (__Nanf.__d) - #else - #define NAN (0.0F/0.0F) - #endif - #endif - -#endif /* !gcc >= 3.3 */ - -#endif /* ! defined (HUGE_VAL) */ - -/* Reentrant ANSI C functions. */ - -#ifndef __math_68881 -extern double atan _PARAMS((double)); -extern double cos _PARAMS((double)); -extern double sin _PARAMS((double)); -extern double tan _PARAMS((double)); -extern double tanh _PARAMS((double)); -extern double frexp _PARAMS((double, int *)); -extern double modf _PARAMS((double, double *)); -extern double ceil _PARAMS((double)); -extern double fabs _PARAMS((double)); -extern double floor _PARAMS((double)); -#endif /* ! defined (__math_68881) */ - -/* Non reentrant ANSI C functions. */ - -#ifndef _REENT_ONLY -#ifndef __math_6881 -extern double acos _PARAMS((double)); -extern double asin _PARAMS((double)); -extern double atan2 _PARAMS((double, double)); -extern double cosh _PARAMS((double)); -extern double sinh _PARAMS((double)); -extern double exp _PARAMS((double)); -extern double ldexp _PARAMS((double, int)); -extern double log _PARAMS((double)); -extern double log10 _PARAMS((double)); -extern double pow _PARAMS((double, double)); -extern double sqrt _PARAMS((double)); -extern double fmod _PARAMS((double, double)); -#endif /* ! defined (__math_68881) */ -#endif /* ! defined (_REENT_ONLY) */ - -#ifndef __STRICT_ANSI__ - -/* ISO C99 types and macros. */ - -#ifndef FLT_EVAL_METHOD -#define FLT_EVAL_METHOD 0 -typedef float float_t; -typedef double double_t; -#endif /* FLT_EVAL_METHOD */ - -#define FP_NAN 0 -#define FP_INFINITE 1 -#define FP_ZERO 2 -#define FP_SUBNORMAL 3 -#define FP_NORMAL 4 - -extern int __fpclassifyf (float x); -extern int __fpclassifyd (double x); -extern int __signbitf (float x); -extern int __signbitd (double x); - -#define fpclassify(x) \ - (__extension__ ({__typeof__(x) __x = (x); \ - (sizeof (__x) == sizeof (float)) ? __fpclassifyf(__x) : __fpclassifyd(__x);})) - -#define isfinite(x) \ - (__extension__ ({__typeof__(x) __x = (x); \ - fpclassify(__x) != FP_INFINITE && fpclassify(__x) != FP_NAN;})) -#define isnormal(x) \ - (__extension__ ({__typeof__(x) __x = (x); \ - fpclassify(__x) == FP_NORMAL;})) -#define signbit(x) \ - (__extension__ ({__typeof__(x) __x = (x); \ - (sizeof(__x) == sizeof(float)) ? __signbitf(__x) : __signbitd(__x);})) - -#define isgreater(x,y) \ - (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x,__y) && (__x > __y);})) -#define isgreaterequal(x,y) \ - (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x,__y) && (__x >= __y);})) -#define isless(x,y) \ - (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x,__y) && (__x < __y);})) -#define islessequal(x,y) \ - (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x,__y) && (__x <= __y);})) -#define islessgreater(x,y) \ - (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x,__y) && (__x < __y || __x > __y);})) - -#define isunordered(x,y) \ - (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - fpclassify(__x) == FP_NAN || fpclassify(__y) == FP_NAN;})) - -/* Non ANSI double precision functions. */ - -extern double infinity _PARAMS((void)); -extern double nan _PARAMS((const char *)); -extern int isnan _PARAMS((double)); -extern int isinf _PARAMS((double)); -extern int finite _PARAMS((double)); -extern double copysign _PARAMS((double, double)); -extern int ilogb _PARAMS((double)); - -extern double asinh _PARAMS((double)); -extern double cbrt _PARAMS((double)); -extern double nextafter _PARAMS((double, double)); -extern double rint _PARAMS((double)); -extern double scalbn _PARAMS((double, int)); - -extern double exp2 _PARAMS((double)); -extern double scalbln _PARAMS((double, long int)); -extern double tgamma _PARAMS((double)); -extern double nearbyint _PARAMS((double)); -extern long int lrint _PARAMS((double)); -extern double round _PARAMS((double)); -extern long int lround _PARAMS((double)); -extern double trunc _PARAMS((double)); -extern double remquo _PARAMS((double, double, int *)); -extern double copysign _PARAMS((double, double)); -extern double fdim _PARAMS((double, double)); -extern double fmax _PARAMS((double, double)); -extern double fmin _PARAMS((double, double)); -extern double fma _PARAMS((double, double, double)); -extern void sincos _PARAMS((double, double *, double *)); - -#ifndef __math_68881 -extern double log1p _PARAMS((double)); -extern double expm1 _PARAMS((double)); -#endif /* ! defined (__math_68881) */ - -#ifndef _REENT_ONLY -extern double acosh _PARAMS((double)); -extern double atanh _PARAMS((double)); -extern double remainder _PARAMS((double, double)); -extern double gamma _PARAMS((double)); -extern double gamma_r _PARAMS((double, int *)); -extern double lgamma _PARAMS((double)); -extern double lgamma_r _PARAMS((double, int *)); -extern double erf _PARAMS((double)); -extern double erfc _PARAMS((double)); -extern double y0 _PARAMS((double)); -extern double y1 _PARAMS((double)); -extern double yn _PARAMS((int, double)); -extern double j0 _PARAMS((double)); -extern double j1 _PARAMS((double)); -extern double jn _PARAMS((int, double)); -#define log2(x) (log (x) / M_LOG2_E) - -#ifndef __math_68881 -extern double hypot _PARAMS((double, double)); -#endif - -extern double cabs(); -extern double drem _PARAMS((double, double)); - -#endif /* ! defined (_REENT_ONLY) */ - -#endif /* ! defined (__STRICT_ANSI__) */ - -#if !defined(__STRICT_ANSI__) || defined(__cplusplus) - -/* Single precision versions of ANSI functions. */ - -extern float atanf _PARAMS((float)); -extern float cosf _PARAMS((float)); -extern float sinf _PARAMS((float)); -extern float tanf _PARAMS((float)); -extern float tanhf _PARAMS((float)); -extern float frexpf _PARAMS((float, int *)); -extern float modff _PARAMS((float, float *)); -extern float ceilf _PARAMS((float)); -extern float fabsf _PARAMS((float)); -extern float floorf _PARAMS((float)); - -#ifndef _REENT_ONLY -extern float acosf _PARAMS((float)); -extern float asinf _PARAMS((float)); -extern float atan2f _PARAMS((float, float)); -extern float coshf _PARAMS((float)); -extern float sinhf _PARAMS((float)); -extern float expf _PARAMS((float)); -extern float ldexpf _PARAMS((float, int)); -extern float logf _PARAMS((float)); -extern float log10f _PARAMS((float)); -extern float powf _PARAMS((float, float)); -extern float sqrtf _PARAMS((float)); -extern float fmodf _PARAMS((float, float)); -#endif /* ! defined (_REENT_ONLY) */ - -#endif /* !defined(__STRICT_ANSI__) || defined(__cplusplus) */ - -#ifndef __STRICT_ANSI__ - -/* Other single precision functions. */ - -extern float exp2f _PARAMS((float)); -extern float scalblnf _PARAMS((float, long int)); -extern float tgammaf _PARAMS((float)); -extern float nearbyintf _PARAMS((float)); -extern long int lrintf _PARAMS((float)); -extern float roundf _PARAMS((float)); -extern long int lroundf _PARAMS((float)); -extern float truncf _PARAMS((float)); -extern float remquof _PARAMS((float, float, int *)); -extern float copysignf _PARAMS((float, float)); -extern float fdimf _PARAMS((float, float)); -extern float fmaxf _PARAMS((float, float)); -extern float fminf _PARAMS((float, float)); -extern float fmaf _PARAMS((float, float, float)); - -extern float infinityf _PARAMS((void)); -extern float nanf _PARAMS((const char *)); -extern int isnanf _PARAMS((float)); -extern int isinff _PARAMS((float)); -extern int finitef _PARAMS((float)); -extern float copysignf _PARAMS((float, float)); -extern int ilogbf _PARAMS((float)); - -extern float asinhf _PARAMS((float)); -extern float cbrtf _PARAMS((float)); -extern float nextafterf _PARAMS((float, float)); -extern float rintf _PARAMS((float)); -extern float scalbnf _PARAMS((float, int)); -extern float log1pf _PARAMS((float)); -extern float expm1f _PARAMS((float)); -extern void sincosf _PARAMS((float, float *, float *)); - -#ifndef _REENT_ONLY -extern float acoshf _PARAMS((float)); -extern float atanhf _PARAMS((float)); -extern float remainderf _PARAMS((float, float)); -extern float gammaf _PARAMS((float)); -extern float gammaf_r _PARAMS((float, int *)); -extern float lgammaf _PARAMS((float)); -extern float lgammaf_r _PARAMS((float, int *)); -extern float erff _PARAMS((float)); -extern float erfcf _PARAMS((float)); -extern float y0f _PARAMS((float)); -extern float y1f _PARAMS((float)); -extern float ynf _PARAMS((int, float)); -extern float j0f _PARAMS((float)); -extern float j1f _PARAMS((float)); -extern float jnf _PARAMS((int, float)); -#define log2f(x) (logf (x) / (float) M_LOG2_E) -extern float hypotf _PARAMS((float, float)); - -extern float cabsf(); -extern float dremf _PARAMS((float, float)); - -#endif /* ! defined (_REENT_ONLY) */ - -/* The gamma functions use a global variable, signgam. */ -#ifndef _REENT_ONLY -#define signgam (*__signgam()) -extern int *__signgam _PARAMS((void)); -#endif /* ! defined (_REENT_ONLY) */ - -#define __signgam_r(ptr) _REENT_SIGNGAM(ptr) - -/* The exception structure passed to the matherr routine. */ - -#ifdef __cplusplus -struct __exception -#else -struct exception -#endif -{ - int type; - char *name; - double arg1; - double arg2; - double retval; - int err; -}; - -#ifdef __cplusplus -extern int matherr _PARAMS((struct __exception *e)); -#else -extern int matherr _PARAMS((struct exception *e)); -#endif - -/* Values for the type field of struct exception. */ - -#define DOMAIN 1 -#define SING 2 -#define OVERFLOW 3 -#define UNDERFLOW 4 -#define TLOSS 5 -#define PLOSS 6 - -/* Useful constants. */ - -#define MAXFLOAT 3.40282347e+38F - -#define M_E 2.7182818284590452354 -#define M_LOG2E 1.4426950408889634074 -#define M_LOG10E 0.43429448190325182765 -#define M_LN2 0.69314718055994530942 -#define M_LN10 2.30258509299404568402 -#define M_PI 3.14159265358979323846 -#define M_TWOPI (M_PI * 2.0) -#define M_PI_2 1.57079632679489661923 -#define M_PI_4 0.78539816339744830962 -#define M_3PI_4 2.3561944901923448370E0 -#define M_SQRTPI 1.77245385090551602792981 -#define M_1_PI 0.31830988618379067154 -#define M_2_PI 0.63661977236758134308 -#define M_2_SQRTPI 1.12837916709551257390 -#define M_SQRT2 1.41421356237309504880 -#define M_SQRT1_2 0.70710678118654752440 -#define M_LN2LO 1.9082149292705877000E-10 -#define M_LN2HI 6.9314718036912381649E-1 -#define M_SQRT3 1.73205080756887719000 -#define M_IVLN10 0.43429448190325182765 /* 1 / log(10) */ -#define M_LOG2_E 0.693147180559945309417 -#define M_INVLN2 1.4426950408889633870E0 /* 1 / log(2) */ - -/* Global control over fdlibm error handling. */ - -enum __fdlibm_version -{ - __fdlibm_ieee = -1, - __fdlibm_svid, - __fdlibm_xopen, - __fdlibm_posix -}; - -#define _LIB_VERSION_TYPE enum __fdlibm_version -#define _LIB_VERSION __fdlib_version - -extern __IMPORT _CONST _LIB_VERSION_TYPE _LIB_VERSION; - -#define _IEEE_ __fdlibm_ieee -#define _SVID_ __fdlibm_svid -#define _XOPEN_ __fdlibm_xopen -#define _POSIX_ __fdlibm_posix - -#endif /* ! defined (__STRICT_ANSI__) */ - -_END_STD_C - -#ifdef __FAST_MATH__ -#include -#endif - -#endif /* _MATH_H_ */ diff --git a/extra_include/memory.h b/extra_include/memory.h deleted file mode 100644 index 9bc9119c..00000000 --- a/extra_include/memory.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _MEMORY_H_ -#define _MEMORY_H_ - -#ifndef _STRING_H_ -# include -#endif /* _STRING_H_ */ - -#endif /* _MEMORY_H_ */ diff --git a/extra_include/newlib.h b/extra_include/newlib.h deleted file mode 100644 index 6c311044..00000000 --- a/extra_include/newlib.h +++ /dev/null @@ -1,142 +0,0 @@ -/* newlib.h. Generated automatically by configure. */ -#ifndef __NEWLIB_H__ - -#define __NEWLIB_H__ 1 - -/* EL/IX level */ -/* #undef _ELIX_LEVEL */ - -/* Newlib version */ -#define _NEWLIB_VERSION "1.13.0" - -/* long long type support in IO functions like printf/scanf enabled */ -#define _WANT_IO_LONG_LONG 1 - -/* long double type support in IO functions like printf/scanf enabled */ -/* #undef _WANT_IO_LONG_DOUBLE */ - -/* Positional argument support in printf functions enabled. */ -/* #undef _WANT_IO_POS_ARGS */ - -/* Multibyte supported */ -/* #undef _MB_CAPABLE */ - -/* MB_LEN_MAX */ -#define _MB_LEN_MAX 1 - -/* ICONV enabled */ -/* #undef _ICONV_ENABLED */ - -/* Enable ICONV external CCS files loading capabilities */ -/* #undef _ICONV_ENABLE_EXTERNAL_CCS */ - -/* - * Iconv encodings enabled ("to" direction) - */ -/* #undef _ICONV_TO_ENCODING_BIG5 */ -/* #undef _ICONV_TO_ENCODING_CP775 */ -/* #undef _ICONV_TO_ENCODING_CP850 */ -/* #undef _ICONV_TO_ENCODING_CP852 */ -/* #undef _ICONV_TO_ENCODING_CP855 */ -/* #undef _ICONV_TO_ENCODING_CP866 */ -/* #undef _ICONV_TO_ENCODING_EUC_JP */ -/* #undef _ICONV_TO_ENCODING_EUC_TW */ -/* #undef _ICONV_TO_ENCODING_EUC_KR */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_1 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_10 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_11 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_13 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_14 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_15 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_2 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_3 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_4 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_5 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_6 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_7 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_8 */ -/* #undef _ICONV_TO_ENCODING_ISO_8859_9 */ -/* #undef _ICONV_TO_ENCODING_ISO_IR_111 */ -/* #undef _ICONV_TO_ENCODING_KOI8_R */ -/* #undef _ICONV_TO_ENCODING_KOI8_RU */ -/* #undef _ICONV_TO_ENCODING_KOI8_U */ -/* #undef _ICONV_TO_ENCODING_KOI8_UNI */ -/* #undef _ICONV_TO_ENCODING_UCS_2 */ -/* #undef _ICONV_TO_ENCODING_UCS_2_INTERNAL */ -/* #undef _ICONV_TO_ENCODING_UCS_2BE */ -/* #undef _ICONV_TO_ENCODING_UCS_2LE */ -/* #undef _ICONV_TO_ENCODING_UCS_4 */ -/* #undef _ICONV_TO_ENCODING_UCS_4_INTERNAL */ -/* #undef _ICONV_TO_ENCODING_UCS_4BE */ -/* #undef _ICONV_TO_ENCODING_UCS_4LE */ -/* #undef _ICONV_TO_ENCODING_US_ASCII */ -/* #undef _ICONV_TO_ENCODING_UTF_16 */ -/* #undef _ICONV_TO_ENCODING_UTF_16BE */ -/* #undef _ICONV_TO_ENCODING_UTF_16LE */ -/* #undef _ICONV_TO_ENCODING_UTF_8 */ -/* #undef _ICONV_TO_ENCODING_WIN_1250 */ -/* #undef _ICONV_TO_ENCODING_WIN_1251 */ -/* #undef _ICONV_TO_ENCODING_WIN_1252 */ -/* #undef _ICONV_TO_ENCODING_WIN_1253 */ -/* #undef _ICONV_TO_ENCODING_WIN_1254 */ -/* #undef _ICONV_TO_ENCODING_WIN_1255 */ -/* #undef _ICONV_TO_ENCODING_WIN_1256 */ -/* #undef _ICONV_TO_ENCODING_WIN_1257 */ -/* #undef _ICONV_TO_ENCODING_WIN_1258 */ - -/* - * Iconv encodings enabled ("from" direction) - */ -/* #undef _ICONV_FROM_ENCODING_BIG5 */ -/* #undef _ICONV_FROM_ENCODING_CP775 */ -/* #undef _ICONV_FROM_ENCODING_CP850 */ -/* #undef _ICONV_FROM_ENCODING_CP852 */ -/* #undef _ICONV_FROM_ENCODING_CP855 */ -/* #undef _ICONV_FROM_ENCODING_CP866 */ -/* #undef _ICONV_FROM_ENCODING_EUC_JP */ -/* #undef _ICONV_FROM_ENCODING_EUC_TW */ -/* #undef _ICONV_FROM_ENCODING_EUC_KR */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_1 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_10 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_11 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_13 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_14 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_15 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_2 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_3 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_4 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_5 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_6 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_7 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_8 */ -/* #undef _ICONV_FROM_ENCODING_ISO_8859_9 */ -/* #undef _ICONV_FROM_ENCODING_ISO_IR_111 */ -/* #undef _ICONV_FROM_ENCODING_KOI8_R */ -/* #undef _ICONV_FROM_ENCODING_KOI8_RU */ -/* #undef _ICONV_FROM_ENCODING_KOI8_U */ -/* #undef _ICONV_FROM_ENCODING_KOI8_UNI */ -/* #undef _ICONV_FROM_ENCODING_UCS_2 */ -/* #undef _ICONV_FROM_ENCODING_UCS_2_INTERNAL */ -/* #undef _ICONV_FROM_ENCODING_UCS_2BE */ -/* #undef _ICONV_FROM_ENCODING_UCS_2LE */ -/* #undef _ICONV_FROM_ENCODING_UCS_4 */ -/* #undef _ICONV_FROM_ENCODING_UCS_4_INTERNAL */ -/* #undef _ICONV_FROM_ENCODING_UCS_4BE */ -/* #undef _ICONV_FROM_ENCODING_UCS_4LE */ -/* #undef _ICONV_FROM_ENCODING_US_ASCII */ -/* #undef _ICONV_FROM_ENCODING_UTF_16 */ -/* #undef _ICONV_FROM_ENCODING_UTF_16BE */ -/* #undef _ICONV_FROM_ENCODING_UTF_16LE */ -/* #undef _ICONV_FROM_ENCODING_UTF_8 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1250 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1251 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1252 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1253 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1254 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1255 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1256 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1257 */ -/* #undef _ICONV_FROM_ENCODING_WIN_1258 */ - -#endif /* !__NEWLIB_H__ */ - diff --git a/extra_include/paths.h b/extra_include/paths.h deleted file mode 100644 index 148070a7..00000000 --- a/extra_include/paths.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _PATHS_H_ -#define _PATHS_H_ - -#define _PATH_DEV "/dev/" -#define _PATH_BSHELL "/bin/sh" - -#endif /* _PATHS_H_ */ diff --git a/extra_include/process.h b/extra_include/process.h deleted file mode 100644 index 902d78f9..00000000 --- a/extra_include/process.h +++ /dev/null @@ -1,44 +0,0 @@ -/* process.h. This file comes with MSDOS and WIN32 systems. */ - -#ifndef __PROCESS_H_ -#define __PROCESS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -int execl(const char *path, const char *argv0, ...); -int execle(const char *path, const char *argv0, ... /*, char * const *envp */); -int execlp(const char *path, const char *argv0, ...); -int execlpe(const char *path, const char *argv0, ... /*, char * const *envp */); - -int execv(const char *path, char * const *argv); -int execve(const char *path, char * const *argv, char * const *envp); -int execvp(const char *path, char * const *argv); -int execvpe(const char *path, char * const *argv, char * const *envp); - -int spawnl(int mode, const char *path, const char *argv0, ...); -int spawnle(int mode, const char *path, const char *argv0, ... /*, char * const *envp */); -int spawnlp(int mode, const char *path, const char *argv0, ...); -int spawnlpe(int mode, const char *path, const char *argv0, ... /*, char * const *envp */); - -int spawnv(int mode, const char *path, const char * const *argv); -int spawnve(int mode, const char *path, const char * const *argv, const char * const *envp); -int spawnvp(int mode, const char *path, const char * const *argv); -int spawnvpe(int mode, const char *path, const char * const *argv, const char * const *envp); - -int cwait(int *, int, int); - -#define _P_WAIT 1 -#define _P_NOWAIT 2 /* always generates error */ -#define _P_OVERLAY 3 -#define _P_NOWAITO 4 -#define _P_DETACH 5 - -#define WAIT_CHILD 1 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extra_include/pthread.h b/extra_include/pthread.h deleted file mode 100644 index 94580592..00000000 --- a/extra_include/pthread.h +++ /dev/null @@ -1,300 +0,0 @@ -/* pthread.h - * - * Written by Joel Sherrill . - * - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION - * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS - * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - * $Id: pthread.h,v 1.3 2002/10/08 13:03:07 joel Exp $ - */ - -#ifndef __PTHREAD_h -#define __PTHREAD_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#if defined(_POSIX_THREADS) - -#include -#include -#include - -/* Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27 - - If an OS does not support processes, then it falls under this provision - and may not provide pthread_atfork(): - - "Either the implementation shall support the pthread_atfork() function - as described above or the pthread_atfork() funciton shall not be - provided." - - NOTE: RTEMS does not provide pthread_atfork(). */ - -#if !defined(__rtems__) -#warning "Add pthread_atfork() prototype" -#endif - -/* Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 */ - -int _EXFUN(pthread_mutexattr_init, (pthread_mutexattr_t *attr)); -int _EXFUN(pthread_mutexattr_destroy, (pthread_mutexattr_t *attr)); -int _EXFUN(pthread_mutexattr_getpshared, - (const pthread_mutexattr_t *attr, int *pshared)); -int _EXFUN(pthread_mutexattr_setpshared, - (pthread_mutexattr_t *attr, int pshared)); - -/* Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 */ - -int _EXFUN(pthread_mutex_init, - (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)); -int _EXFUN(pthread_mutex_destroy, (pthread_mutex_t *mutex)); - -/* This is used to statically initialize a pthread_mutex_t. Example: - - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - */ - -#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFF) - -/* Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 - NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 */ - -int _EXFUN(pthread_mutex_lock, (pthread_mutex_t *mutex)); -int _EXFUN(pthread_mutex_trylock, (pthread_mutex_t *mutex)); -int _EXFUN(pthread_mutex_unlock, (pthread_mutex_t *mutex)); - -#if defined(_POSIX_TIMEOUTS) - -int _EXFUN(pthread_mutex_timedlock, - (pthread_mutex_t *mutex, const struct timespec *timeout)); - -#endif /* _POSIX_TIMEOUTS */ - -/* Condition Variable Initialization Attributes, P1003.1c/Draft 10, p. 96 */ - -int _EXFUN(pthread_condattr_init, (pthread_condattr_t *attr)); -int _EXFUN(pthread_condattr_destroy, (pthread_condattr_t *attr)); -int _EXFUN(pthread_condattr_getpshared, - (const pthread_condattr_t *attr, int *pshared)); -int _EXFUN(pthread_condattr_setpshared, - (pthread_condattr_t *attr, int pshared)); - -/* Initializing and Destroying a Condition Variable, P1003.1c/Draft 10, p. 87 */ - -int _EXFUN(pthread_cond_init, - (pthread_cond_t *cond, const pthread_condattr_t *attr)); -int _EXFUN(pthread_cond_destroy, (pthread_cond_t *mutex)); - -/* This is used to statically initialize a pthread_cond_t. Example: - - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - */ - -#define PTHREAD_COND_INITIALIZER ((pthread_mutex_t) 0xFFFFFFFF) - -/* Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101 */ - -int _EXFUN(pthread_cond_signal, (pthread_cond_t *cond)); -int _EXFUN(pthread_cond_broadcast, (pthread_cond_t *cond)); - -/* Waiting on a Condition, P1003.1c/Draft 10, p. 105 */ - -int _EXFUN(pthread_cond_wait, - (pthread_cond_t *cond, pthread_mutex_t *mutex)); - -int _EXFUN(pthread_cond_timedwait, - (pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime)); - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - -/* Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 */ - -int _EXFUN(pthread_attr_setscope, - (pthread_attr_t *attr, int contentionscope)); -int _EXFUN(pthread_attr_getscope, - (const pthread_attr_t *attr, int *contentionscope)); -int _EXFUN(pthread_attr_setinheritsched, - (pthread_attr_t *attr, int inheritsched)); -int _EXFUN(pthread_attr_getinheritsched, - (const pthread_attr_t *attr, int *inheritsched)); -int _EXFUN(pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy)); -int _EXFUN(pthread_attr_getschedpolicy, - (const pthread_attr_t *attr, int *policy)); - -#endif /* defined(_POSIX_THREAD_PRIORITY_SCHEDULING) */ - -int _EXFUN(pthread_attr_setschedparam, - (pthread_attr_t *attr, const struct sched_param *param)); -int _EXFUN(pthread_attr_getschedparam, - (const pthread_attr_t *attr, struct sched_param *param)); - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - -/* Dynamic Thread Scheduling Parameters Access, P1003.1c/Draft 10, p. 124 */ - -int _EXFUN(pthread_getschedparam, - (pthread_t thread, int *policy, struct sched_param *param)); -int _EXFUN(pthread_setschedparam, - (pthread_t thread, int policy, struct sched_param *param)); - -#endif /* defined(_POSIX_THREAD_PRIORITY_SCHEDULING) */ - -#if defined(_POSIX_THREAD_PRIO_INHERIT) || defined(_POSIX_THREAD_PRIO_PROTECT) - -/* Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 */ - -int _EXFUN(pthread_mutexattr_setprotocol, - (pthread_mutexattr_t *attr, int protocol)); -int _EXFUN(pthread_mutexattr_getprotocol, - (const pthread_mutexattr_t *attr, int *protocol)); -int _EXFUN(pthread_mutexattr_setprioceiling, - (pthread_mutexattr_t *attr, int prioceiling)); -int _EXFUN(pthread_mutexattr_getprioceiling, - (const pthread_mutexattr_t *attr, int *prioceiling)); - -#endif /* _POSIX_THREAD_PRIO_INHERIT || _POSIX_THREAD_PRIO_PROTECT */ - -#if defined(_POSIX_THREAD_PRIO_PROTECT) - -/* Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131 */ - -int _EXFUN(pthread_mutex_setprioceiling, - (pthread_mutex_t *mutex, int prioceiling, int *old_ceiling)); -int _EXFUN(pthread_mutex_getprioceiling, - (pthread_mutex_t *mutex, int *prioceiling)); - -#endif /* _POSIX_THREAD_PRIO_PROTECT */ - -/* Thread Creation Attributes, P1003.1c/Draft 10, p, 140 */ - -int _EXFUN(pthread_attr_init, (pthread_attr_t *attr)); -int _EXFUN(pthread_attr_destroy, (pthread_attr_t *attr)); -int _EXFUN(pthread_attr_getstacksize, - (const pthread_attr_t *attr, size_t *stacksize)); -int _EXFUN(pthread_attr_setstacksize, - (pthread_attr_t *attr, size_t stacksize)); -int _EXFUN(pthread_attr_getstackaddr, - (const pthread_attr_t *attr, void **stackaddr)); -int _EXFUN(pthread_attr_setstackaddr, - (pthread_attr_t *attr, void *stackaddr)); -int _EXFUN(pthread_attr_getdetachstate, - (const pthread_attr_t *attr, int *detachstate)); -int _EXFUN(pthread_attr_setdetachstate, - (pthread_attr_t *attr, int detachstate)); - -/* Thread Creation, P1003.1c/Draft 10, p. 144 */ - -int _EXFUN(pthread_create, - (pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine)( void * ), void *arg)); - -/* Wait for Thread Termination, P1003.1c/Draft 10, p. 147 */ - -int _EXFUN(pthread_join, (pthread_t thread, void **value_ptr)); - -/* Detaching a Thread, P1003.1c/Draft 10, p. 149 */ - -int _EXFUN(pthread_detach, (pthread_t thread)); - -/* Thread Termination, p1003.1c/Draft 10, p. 150 */ - -void _EXFUN(pthread_exit, (void *value_ptr)); - -/* Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX */ - -pthread_t _EXFUN(pthread_self, (void)); - -/* Compare Thread IDs, p1003.1c/Draft 10, p. 153 */ - -int _EXFUN(pthread_equal, (pthread_t t1, pthread_t t2)); - -/* Dynamic Package Initialization */ - -/* This is used to statically initialize a pthread_once_t. Example: - - pthread_once_t once = PTHREAD_ONCE_INIT; - - NOTE: This is named inconsistently -- it should be INITIALIZER. */ - -#define PTHREAD_ONCE_INIT { 1, 0 } /* is initialized and not run */ - -int _EXFUN(pthread_once, - (pthread_once_t *once_control, void (*init_routine)(void))); - -/* Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163 */ - -int _EXFUN(pthread_key_create, - (pthread_key_t *key, void (*destructor)( void * ))); - -/* Thread-Specific Data Management, P1003.1c/Draft 10, p. 165 */ - -int _EXFUN(pthread_setspecific, (pthread_key_t key, const void *value)); -void * _EXFUN(pthread_getspecific, (pthread_key_t key)); - -/* Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 */ - -int _EXFUN(pthread_key_delete, (pthread_key_t key)); - -/* Execution of a Thread, P1003.1c/Draft 10, p. 181 */ - -#define PTHREAD_CANCEL_ENABLE 0 -#define PTHREAD_CANCEL_DISABLE 1 - -#define PTHREAD_CANCEL_DEFERRED 0 -#define PTHREAD_CANCEL_ASYNCHRONOUS 1 - -#define PTHREAD_CANCELED ((void *) -1) - -int _EXFUN(pthread_cancel, (pthread_t thread)); - -/* Setting Cancelability State, P1003.1c/Draft 10, p. 183 */ - -int _EXFUN(pthread_setcancelstate, (int state, int *oldstate)); -int _EXFUN(pthread_setcanceltype, (int type, int *oldtype)); -void _EXFUN(pthread_testcancel, (void)); - -/* Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184 */ - -void _EXFUN(pthread_cleanup_push, (void (*routine)( void * ), void *arg)); -void _EXFUN(pthread_cleanup_pop, (int execute)); - -#if defined(_POSIX_THREAD_CPUTIME) - -/* Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58 */ - -int _EXFUN(pthread_getcpuclockid, - (pthread_t thread_id, clockid_t *clock_id)); - -/* CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59 */ - -int _EXFUN(pthread_attr_setcputime, - (pthread_attr_t *attr, int clock_allowed)); - -int _EXFUN(pthread_attr_getcputime, - (pthread_attr_t *attr, int *clock_allowed)); - -#endif /* defined(_POSIX_THREAD_CPUTIME) */ - -#endif /* defined(_POSIX_THREADS) */ - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ diff --git a/extra_include/pwd.h b/extra_include/pwd.h deleted file mode 100644 index 09a6dd0e..00000000 --- a/extra_include/pwd.h +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * Copyright (c) 1989 The Regents of the University of California. - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)pwd.h 5.13 (Berkeley) 5/28/91 - */ - -#ifndef _PWD_H_ -#ifdef __cplusplus -extern "C" { -#endif -#define _PWD_H_ - -#include - -#ifndef _POSIX_SOURCE -#define _PATH_PASSWD "/etc/passwd" - -#define _PASSWORD_LEN 128 /* max length, not counting NULL */ -#endif - -struct passwd { - char *pw_name; /* user name */ - char *pw_passwd; /* encrypted password */ - int pw_uid; /* user uid */ - int pw_gid; /* user gid */ - char *pw_comment; /* comment */ - char *pw_gecos; /* Honeywell login info */ - char *pw_dir; /* home directory */ - char *pw_shell; /* default shell */ -}; - -#ifndef __INSIDE_CYGWIN__ -struct passwd *getpwuid (uid_t); -struct passwd *getpwnam (const char *); -int getpwnam_r (const char *, struct passwd *, - char *, size_t , struct passwd **); -int getpwuid_r (uid_t, struct passwd *, char *, - size_t, struct passwd **); -#ifndef _POSIX_SOURCE -struct passwd *getpwent (void); -void setpwent (void); -void endpwent (void); -#endif -#endif - -#ifdef __cplusplus -} -#endif -#endif /* _PWD_H_ */ diff --git a/extra_include/reent.h b/extra_include/reent.h deleted file mode 100644 index dbc55a88..00000000 --- a/extra_include/reent.h +++ /dev/null @@ -1,101 +0,0 @@ -/* This header file provides the reentrancy. */ - -/* The reentrant system calls here serve two purposes: - - 1) Provide reentrant versions of the system calls the ANSI C library - requires. - 2) Provide these system calls in a namespace clean way. - - It is intended that *all* system calls that the ANSI C library needs - be declared here. It documents them all in one place. All library access - to the system is via some form of these functions. - - There are three ways a target may provide the needed syscalls. - - 1) Define the reentrant versions of the syscalls directly. - (eg: _open_r, _close_r, etc.). Please keep the namespace clean. - When you do this, set "syscall_dir" to "syscalls" and add - -DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host. - - 2) Define namespace clean versions of the system calls by prefixing - them with '_' (eg: _open, _close, etc.). Technically, there won't be - true reentrancy at the syscall level, but the library will be namespace - clean. - When you do this, set "syscall_dir" to "syscalls" in configure.host. - - 3) Define or otherwise provide the regular versions of the syscalls - (eg: open, close, etc.). The library won't be reentrant nor namespace - clean, but at least it will work. - When you do this, add -DMISSING_SYSCALL_NAMES to newlib_cflags in - configure.host. - - Stubs of the reentrant versions of the syscalls exist in the libc/reent - source directory and are used if REENTRANT_SYSCALLS_PROVIDED isn't defined. - They use the native system calls: _open, _close, etc. if they're available - (MISSING_SYSCALL_NAMES is *not* defined), otherwise open, close, etc. - (MISSING_SYSCALL_NAMES *is* defined). */ - -/* WARNING: All identifiers here must begin with an underscore. This file is - included by stdio.h and others and we therefore must only use identifiers - in the namespace allotted to us. */ - -#ifndef _REENT_H_ -#ifdef __cplusplus -extern "C" { -#endif -#define _REENT_H_ - -#include -#include -#include - -#define __need_size_t -#define __need_ptrdiff_t -#include - -/* FIXME: not namespace clean */ -struct stat; -struct tms; -struct timeval; -struct timezone; - -/* Reentrant versions of system calls. */ - -extern int _close_r _PARAMS ((struct _reent *, int)); -extern int _execve_r _PARAMS ((struct _reent *, char *, char **, char **)); -extern int _fcntl_r _PARAMS ((struct _reent *, int, int, int)); -extern int _fork_r _PARAMS ((struct _reent *)); -extern int _fstat_r _PARAMS ((struct _reent *, int, struct stat *)); -extern int _getpid_r _PARAMS ((struct _reent *)); -extern int _kill_r _PARAMS ((struct _reent *, int, int)); -extern int _link_r _PARAMS ((struct _reent *, const char *, const char *)); -extern _off_t _lseek_r _PARAMS ((struct _reent *, int, _off_t, int)); -extern int _open_r _PARAMS ((struct _reent *, const char *, int, int)); -extern _ssize_t _read_r _PARAMS ((struct _reent *, int, void *, size_t)); -extern void *_sbrk_r _PARAMS ((struct _reent *, ptrdiff_t)); -extern int _stat_r _PARAMS ((struct _reent *, const char *, struct stat *)); -extern _CLOCK_T_ _times_r _PARAMS ((struct _reent *, struct tms *)); -extern int _unlink_r _PARAMS ((struct _reent *, const char *)); -extern int _wait_r _PARAMS ((struct _reent *, int *)); -extern _ssize_t _write_r _PARAMS ((struct _reent *, int, const void *, size_t)); - -/* This one is not guaranteed to be available on all targets. */ -extern int _gettimeofday_r _PARAMS ((struct _reent *, struct timeval *tp, struct timezone *tzp)); - -#ifdef __LARGE64_FILES - -#if defined(__CYGWIN__) && defined(_COMPILING_NEWLIB) -#define stat64 __stat64 -#endif - -struct stat64; - -extern _off64_t _lseek64_r _PARAMS ((struct _reent *, int, _off64_t, int)); -extern int _fstat64_r _PARAMS ((struct _reent *, int, struct stat64 *)); -extern int _open64_r _PARAMS ((struct _reent *, const char *, int, int)); -#endif - -#ifdef __cplusplus -} -#endif -#endif /* _REENT_H_ */ diff --git a/extra_include/regdef.h b/extra_include/regdef.h deleted file mode 100644 index 1651cee9..00000000 --- a/extra_include/regdef.h +++ /dev/null @@ -1,7 +0,0 @@ -/* regdef.h -- define register names. */ - -/* This is a standard include file for MIPS targets. Other target - probably don't define it, and attempts to include this file will - fail. */ - -#include diff --git a/extra_include/search.h b/extra_include/search.h deleted file mode 100644 index 719556cf..00000000 --- a/extra_include/search.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ */ -/* $FreeBSD: src/include/search.h,v 1.4 2002/03/23 17:24:53 imp Exp $ */ - -/* - * Written by J.T. Conklin - * Public domain. - */ - -#ifndef _SEARCH_H_ -#define _SEARCH_H_ - -#include -#include -#include - -typedef struct entry { - char *key; - void *data; -} ENTRY; - -typedef enum { - FIND, ENTER -} ACTION; - -typedef enum { - preorder, - postorder, - endorder, - leaf -} VISIT; - -#ifdef _SEARCH_PRIVATE -typedef struct node { - char *key; - struct node *llink, *rlink; -} node_t; -#endif - -struct hsearch_data -{ - struct internal_head *htable; - size_t htablesize; -}; - -__BEGIN_DECLS -int hcreate(size_t); -void hdestroy(void); -ENTRY *hsearch(ENTRY, ACTION); -int hcreate_r(size_t, struct hsearch_data *); -void hdestroy_r(struct hsearch_data *); -int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *); -void *tdelete(const void *, void **, int (*)(const void *, const void *)); -void tdestroy (void *, void (*)(void *)); -void *tfind(const void *, void **, int (*)(const void *, const void *)); -void *tsearch(const void *, void **, int (*)(const void *, const void *)); -void twalk(const void *, void (*)(const void *, VISIT, int)); -__END_DECLS - -#endif /* !_SEARCH_H_ */ diff --git a/extra_include/setjmp.h b/extra_include/setjmp.h deleted file mode 100644 index 1a8bf1e7..00000000 --- a/extra_include/setjmp.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - setjmp.h - stubs for future use. -*/ - -#ifndef _SETJMP_H_ -#define _SETJMP_H_ - -#include "_ansi.h" -#include - -_BEGIN_STD_C - -void _EXFUN(longjmp,(jmp_buf __jmpb, int __retval)); -int _EXFUN(setjmp,(jmp_buf __jmpb)); - -_END_STD_C - -#endif /* _SETJMP_H_ */ - diff --git a/extra_include/signal.h b/extra_include/signal.h deleted file mode 100644 index af55a0b6..00000000 --- a/extra_include/signal.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _SIGNAL_H_ -#define _SIGNAL_H_ - -#include "_ansi.h" -#include - -_BEGIN_STD_C - -typedef int sig_atomic_t; /* Atomic entity type (ANSI) */ - -#define SIG_DFL ((_sig_func_ptr)0) /* Default action */ -#define SIG_IGN ((_sig_func_ptr)1) /* Ignore action */ -#define SIG_ERR ((_sig_func_ptr)-1) /* Error return */ - -struct _reent; - -_sig_func_ptr _EXFUN(_signal_r, (struct _reent *, int, _sig_func_ptr)); -int _EXFUN(_raise_r, (struct _reent *, int)); - -#ifndef _REENT_ONLY -_sig_func_ptr _EXFUN(signal, (int, _sig_func_ptr)); -int _EXFUN(raise, (int)); -#endif - -_END_STD_C - -#endif /* _SIGNAL_H_ */ diff --git a/extra_include/stdint.h b/extra_include/stdint.h deleted file mode 100644 index 6b663c90..00000000 --- a/extra_include/stdint.h +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (c) 2004, 2005 by - * Ralf Corsepius, Ulm/Germany. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software - * is freely granted, provided that this notice is preserved. - */ - -/* - * @todo - Add support for wint_t types. - */ - -#ifndef _STDINT_H -#define _STDINT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) && \ - ( (__GNUC__ >= 4) || \ - ( (__GNUC__ >= 3) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 2) ) ) -/* gcc > 3.2 implicitly defines the values we are interested */ -#define __STDINT_EXP(x) __##x##__ -#else -#define __STDINT_EXP(x) x -#include -#endif - -/* Check if "long long" is 64bit wide */ -/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */ -#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \ - || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) ) -#define __have_longlong64 1 -#endif - -/* Check if "long" is 64bit or 32bit wide */ -#if __STDINT_EXP(LONG_MAX) > 0x7fffffff -#define __have_long64 1 -#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__) -#define __have_long32 1 -#endif - -#if __STDINT_EXP(SCHAR_MAX) == 0x7f -typedef signed char int8_t ; -typedef unsigned char uint8_t ; -#define __int8_t_defined 1 -#endif - -#if __int8_t_defined -typedef signed char int_least8_t; -typedef unsigned char uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if __STDINT_EXP(SHRT_MAX) == 0x7fff -typedef signed short int16_t; -typedef unsigned short uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fff -typedef signed int int16_t; -typedef unsigned int uint16_t; -#define __int16_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fff -typedef signed char int16_t; -typedef unsigned char uint16_t; -#define __int16_t_defined 1 -#endif - -#if __int16_t_defined -typedef int16_t int_least16_t; -typedef uint16_t uint_least16_t; -#define __int_least16_t_defined 1 - -#if !__int_least8_t_defined -typedef int16_t int_least8_t; -typedef uint16_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif -#endif - -#if __have_long32 -#if TENSILICA || 1 -typedef signed int int32_t; -typedef unsigned int uint32_t; -#else -typedef signed long int32_t; -typedef unsigned long uint32_t; -#endif -#define __int32_t_defined 1 -#elif __STDINT_EXP(INT_MAX) == 0x7fffffffL -typedef signed int int32_t; -typedef unsigned int uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SHRT_MAX) == 0x7fffffffL -typedef signed short int32_t; -typedef unsigned short uint32_t; -#define __int32_t_defined 1 -#elif __STDINT_EXP(SCHAR_MAX) == 0x7fffffffL -typedef signed char int32_t; -typedef unsigned char uint32_t; -#define __int32_t_defined 1 -#endif - -#if __int32_t_defined -typedef int32_t int_least32_t; -typedef uint32_t uint_least32_t; -#define __int_least32_t_defined 1 - -#if !__int_least8_t_defined -typedef int32_t int_least8_t; -typedef uint32_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int32_t int_least16_t; -typedef uint32_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif -#endif - -#if __have_long64 -typedef signed long int64_t; -typedef unsigned long uint64_t; -#define __int64_t_defined 1 -#elif __have_longlong64 -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#define __int64_t_defined 1 -#elif __STDINT_EXP(INT_MAX) > 0x7fffffff -typedef signed int int64_t; -typedef unsigned int uint64_t; -#define __int64_t_defined 1 -#endif - -#if __int64_t_defined -typedef int64_t int_least64_t; -typedef uint64_t uint_least64_t; -#define __int_least64_t_defined 1 - -#if !__int_least8_t_defined -typedef int64_t int_least8_t; -typedef uint64_t uint_least8_t; -#define __int_least8_t_defined 1 -#endif - -#if !__int_least16_t_defined -typedef int64_t int_least16_t; -typedef uint64_t uint_least16_t; -#define __int_least16_t_defined 1 -#endif - -#if !__int_least32_t_defined -typedef int64_t int_least32_t; -typedef uint64_t uint_least32_t; -#define __int_least32_t_defined 1 -#endif -#endif - -/* - * Fastest minimum-width integer types - * - * Assume int to be the fastest type for all types with a width - * less than __INT_MAX__ rsp. INT_MAX - */ -#if __STDINT_EXP(INT_MAX) >= 0x7f - typedef signed int int_fast8_t; - typedef unsigned int uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fff - typedef signed int int_fast16_t; - typedef unsigned int uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) >= 0x7fffffff - typedef signed int int_fast32_t; - typedef unsigned int uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif - -#if __STDINT_EXP(INT_MAX) > 0x7fffffff - typedef signed int int_fast64_t; - typedef unsigned int uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif - -/* - * Fall back to [u]int_least_t for [u]int_fast_t types - * not having been defined, yet. - * Leave undefined, if [u]int_least_t should not be available. - */ -#if !__int_fast8_t_defined -#if __int_least8_t_defined - typedef int_least8_t int_fast8_t; - typedef uint_least8_t uint_fast8_t; -#define __int_fast8_t_defined 1 -#endif -#endif - -#if !__int_fast16_t_defined -#if __int_least16_t_defined - typedef int_least16_t int_fast16_t; - typedef uint_least16_t uint_fast16_t; -#define __int_fast16_t_defined 1 -#endif -#endif - -#if !__int_fast32_t_defined -#if __int_least32_t_defined - typedef int_least32_t int_fast32_t; - typedef uint_least32_t uint_fast32_t; -#define __int_fast32_t_defined 1 -#endif -#endif - -#if !__int_fast64_t_defined -#if __int_least64_t_defined - typedef int_least64_t int_fast64_t; - typedef uint_least64_t uint_fast64_t; -#define __int_fast64_t_defined 1 -#endif -#endif - -/* Greatest-width integer types */ -/* Modern GCCs provide __INTMAX_TYPE__ */ -#if defined(__INTMAX_TYPE__) - typedef __INTMAX_TYPE__ intmax_t; -#elif __have_longlong64 - typedef signed long long intmax_t; -#else - typedef signed long intmax_t; -#endif - -/* Modern GCCs provide __UINTMAX_TYPE__ */ -#if defined(__UINTMAX_TYPE__) - typedef __UINTMAX_TYPE__ uintmax_t; -#elif __have_longlong64 - typedef unsigned long long uintmax_t; -#else - typedef unsigned long uintmax_t; -#endif - -/* - * GCC doesn't provide an appropriate macro for [u]intptr_t - * For now, use __PTRDIFF_TYPE__ - */ -#if defined(__PTRDIFF_TYPE__) -typedef signed __PTRDIFF_TYPE__ intptr_t; -typedef unsigned __PTRDIFF_TYPE__ uintptr_t; -#else -/* - * Fallback to hardcoded values, - * should be valid on cpu's with 32bit int/32bit void* - */ -typedef signed long intptr_t; -typedef unsigned long uintptr_t; -#endif - -/* Limits of Specified-Width Integer Types */ - -#if __int8_t_defined -#define INT8_MIN -128 -#define INT8_MAX 127 -#define UINT8_MAX 255 -#endif - -#if __int_least8_t_defined -#define INT_LEAST8_MIN -128 -#define INT_LEAST8_MAX 127 -#define UINT_LEAST8_MAX 255 -#else -#error required type int_least8_t missing -#endif - -#if __int16_t_defined -#define INT16_MIN -32768 -#define INT16_MAX 32767 -#define UINT16_MAX 65535 -#endif - -#if __int_least16_t_defined -#define INT_LEAST16_MIN -32768 -#define INT_LEAST16_MAX 32767 -#define UINT_LEAST16_MAX 65535 -#else -#error required type int_least16_t missing -#endif - -#if __int32_t_defined -#define INT32_MIN (-2147483647-1) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U -#endif - -#if __int_least32_t_defined -#define INT_LEAST32_MIN (-2147483647-1) -#define INT_LEAST32_MAX 2147483647 -#define UINT_LEAST32_MAX 4294967295U -#else -#error required type int_least32_t missing -#endif - -#if __int64_t_defined -#if __have_long64 -#define INT64_MIN (-9223372036854775807L-1L) -#define INT64_MAX 9223372036854775807L -#define UINT64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT64_MIN (-9223372036854775807LL-1LL) -#define INT64_MAX 9223372036854775807LL -#define UINT64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_least64_t_defined -#if __have_long64 -#define INT_LEAST64_MIN (-9223372036854775807L-1L) -#define INT_LEAST64_MAX 9223372036854775807L -#define UINT_LEAST64_MAX 18446744073709551615U -#elif __have_longlong64 -#define INT_LEAST64_MIN (-9223372036854775807LL-1LL) -#define INT_LEAST64_MAX 9223372036854775807LL -#define UINT_LEAST64_MAX 18446744073709551615ULL -#endif -#endif - -#if __int_fast8_t_defined -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define UINT_FAST8_MAX UINT8_MAX -#endif - -#if __int_fast16_t_defined -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define UINT_FAST16_MAX UINT16_MAX -#endif - -#if __int_fast32_t_defined -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define UINT_FAST32_MAX UINT32_MAX -#endif - -#if __int_fast64_t_defined -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST64_MAX UINT64_MAX -#endif - -/* This must match size_t in stddef.h, currently long unsigned int */ -#define SIZE_MIN (-__STDINT_EXP(LONG_MAX) - 1L) -#define SIZE_MAX __STDINT_EXP(LONG_MAX) - -/* This must match sig_atomic_t in (currently int) */ -#define SIG_ATOMIC_MIN (-__STDINT_EXP(INT_MAX) - 1) -#define SIG_ATOMIC_MAX __STDINT_EXP(INT_MAX) - -/* This must match ptrdiff_t in (currently long int) */ -#define PTRDIFF_MIN (-__STDINT_EXP(LONG_MAX) - 1L) -#define PTRDIFF_MAX __STDINT_EXP(LONG_MAX) - -/** Macros for minimum-width integer constant expressions */ -#define INT8_C(x) x -#define UINT8_C(x) x##U - -#define INT16_C(x) x -#define UINT16_C(x) x##U - -#if __have_long32 -#define INT32_C(x) x##L -#define UINT32_C(x) x##UL -#else -#define INT32_C(x) x -#define UINT32_C(x) x##U -#endif - -#if __int64_t_defined -#if __have_longlong64 -#define INT64_C(x) x##LL -#define UINT64_C(x) x##ULL -#else -#define INT64_C(x) x##L -#define UINT64_C(x) x##UL -#endif -#endif - -/** Macros for greatest-width integer constant expression */ -#if __have_longlong64 -#define INTMAX_C(x) x##LL -#define UINTMAX_C(x) x##ULL -#else -#define INTMAX_C(x) x##L -#define UINTMAX_C(x) x##UL -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _STDINT_H */ diff --git a/extra_include/stdio.h b/extra_include/stdio.h deleted file mode 100644 index ca0f40e6..00000000 --- a/extra_include/stdio.h +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#)stdio.h 5.3 (Berkeley) 3/15/86 - */ - -/* - * NB: to fit things in six character monocase externals, the - * stdio code uses the prefix `__s' for stdio objects, typically - * followed by a three-character attempt at a mnemonic. - */ - -#ifndef _STDIO_H_ -#define _STDIO_H_ - -#include "_ansi.h" - -#define _FSTDIO /* ``function stdio'' */ - -#define __need_size_t -#include - -#define __need___va_list -#include - -/* - * defines __FILE, _fpos_t. - * They must be defined there because struct _reent needs them (and we don't - * want reent.h to include this file. - */ - -#include -#include - -_BEGIN_STD_C - -typedef __FILE FILE; - -#ifdef __CYGWIN__ -#ifdef __CYGWIN_USE_BIG_TYPES__ -typedef _fpos64_t fpos_t; -#else -typedef _fpos_t fpos_t; -#endif -#else -typedef _fpos_t fpos_t; -#ifdef __LARGE64_FILES -typedef _fpos64_t fpos64_t; -#endif -#endif /* !__CYGWIN__ */ - -#include - -#define __SLBF 0x0001 /* line buffered */ -#define __SNBF 0x0002 /* unbuffered */ -#define __SRD 0x0004 /* OK to read */ -#define __SWR 0x0008 /* OK to write */ - /* RD and WR are never simultaneously asserted */ -#define __SRW 0x0010 /* open for reading & writing */ -#define __SEOF 0x0020 /* found EOF */ -#define __SERR 0x0040 /* found error */ -#define __SMBF 0x0080 /* _buf is from malloc */ -#define __SAPP 0x0100 /* fdopen()ed in append mode - so must write to end */ -#define __SSTR 0x0200 /* this is an sprintf/snprintf string */ -#define __SOPT 0x0400 /* do fseek() optimisation */ -#define __SNPT 0x0800 /* do not do fseek() optimisation */ -#define __SOFF 0x1000 /* set iff _offset is in fact correct */ -#define __SMOD 0x2000 /* true => fgetline modified _p text */ -#if defined(__CYGWIN__) -# define __SCLE 0x4000 /* convert line endings CR/LF <-> NL */ -#endif -#define __SL64 0x8000 /* is 64-bit offset large file */ - -/* - * The following three definitions are for ANSI C, which took them - * from System V, which stupidly took internal interface macros and - * made them official arguments to setvbuf(), without renaming them. - * Hence, these ugly _IOxxx names are *supposed* to appear in user code. - * - * Although these happen to match their counterparts above, the - * implementation does not rely on that (so these could be renumbered). - */ -#define _IOFBF 0 /* setvbuf should set fully buffered */ -#define _IOLBF 1 /* setvbuf should set line buffered */ -#define _IONBF 2 /* setvbuf should set unbuffered */ - -#ifndef NULL -#define NULL 0 -#endif - -#define EOF (-1) - -#ifdef __BUFSIZ__ -#define BUFSIZ __BUFSIZ__ -#else -#define BUFSIZ 1024 -#endif - -#ifdef __FOPEN_MAX__ -#define FOPEN_MAX __FOPEN_MAX__ -#else -#define FOPEN_MAX 20 -#endif - -#ifdef __FILENAME_MAX__ -#define FILENAME_MAX __FILENAME_MAX__ -#else -#define FILENAME_MAX 1024 -#endif - -#ifdef __L_tmpnam__ -#define L_tmpnam __L_tmpnam__ -#else -#define L_tmpnam FILENAME_MAX -#endif - -#ifndef __STRICT_ANSI__ -#define P_tmpdir "/tmp" -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 /* set file offset to offset */ -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 /* set file offset to current plus offset */ -#endif -#ifndef SEEK_END -#define SEEK_END 2 /* set file offset to EOF plus offset */ -#endif - -#define TMP_MAX 26 - -#ifndef _REENT_ONLY -#define stdin (_REENT->_stdin) -#define stdout (_REENT->_stdout) -#define stderr (_REENT->_stderr) -#else /* _REENT_ONLY */ -#define stdin (_impure_ptr->_stdin) -#define stdout (_impure_ptr->_stdout) -#define stderr (_impure_ptr->_stderr) -#endif /* _REENT_ONLY */ - -#define _stdin_r(x) ((x)->_stdin) -#define _stdout_r(x) ((x)->_stdout) -#define _stderr_r(x) ((x)->_stderr) - -/* - * Functions defined in ANSI C standard. - */ - -#ifdef __GNUC__ -#define __VALIST __gnuc_va_list -#else -#define __VALIST char* -#endif - -FILE * _EXFUN(tmpfile, (void)); -char * _EXFUN(tmpnam, (char *)); -int _EXFUN(fclose, (FILE *)); -int _EXFUN(fflush, (FILE *)); -FILE * _EXFUN(freopen, (const char *, const char *, FILE *)); -void _EXFUN(setbuf, (FILE *, char *)); -int _EXFUN(setvbuf, (FILE *, char *, int, size_t)); -int _EXFUN(fprintf, (FILE *, const char *, ...)); -int _EXFUN(fscanf, (FILE *, const char *, ...)); -int _EXFUN(printf, (const char *, ...)); -int _EXFUN(scanf, (const char *, ...)); -int _EXFUN(sscanf, (const char *, const char *, ...)); -int _EXFUN(vfprintf, (FILE *, const char *, __VALIST)); -int _EXFUN(vprintf, (const char *, __VALIST)); -int _EXFUN(vsprintf, (char *, const char *, __VALIST)); -int _EXFUN(fgetc, (FILE *)); -char * _EXFUN(fgets, (char *, int, FILE *)); -int _EXFUN(fputc, (int, FILE *)); -int _EXFUN(fputs, (const char *, FILE *)); -int _EXFUN(getc, (FILE *)); -int _EXFUN(getchar, (void)); -char * _EXFUN(gets, (char *)); -int _EXFUN(putc, (int, FILE *)); -int _EXFUN(putchar, (int)); -int _EXFUN(puts, (const char *)); -int _EXFUN(ungetc, (int, FILE *)); -size_t _EXFUN(fread, (_PTR, size_t _size, size_t _n, FILE *)); -size_t _EXFUN(fwrite, (const _PTR , size_t _size, size_t _n, FILE *)); -#ifdef _COMPILING_NEWLIB -int _EXFUN(fgetpos, (FILE *, _fpos_t *)); -#else -int _EXFUN(fgetpos, (FILE *, fpos_t *)); -#endif -int _EXFUN(fseek, (FILE *, long, int)); -#ifdef _COMPILING_NEWLIB -int _EXFUN(fsetpos, (FILE *, const _fpos_t *)); -#else -int _EXFUN(fsetpos, (FILE *, const fpos_t *)); -#endif -long _EXFUN(ftell, ( FILE *)); -void _EXFUN(rewind, (FILE *)); -void _EXFUN(clearerr, (FILE *)); -int _EXFUN(feof, (FILE *)); -int _EXFUN(ferror, (FILE *)); -void _EXFUN(perror, (const char *)); -#ifndef _REENT_ONLY -FILE * _EXFUN(fopen, (const char *_name, const char *_type)); -int _EXFUN(sprintf, (char *, const char *, ...)); -int _EXFUN(remove, (const char *)); -int _EXFUN(rename, (const char *, const char *)); -#endif -#ifndef __STRICT_ANSI__ -#ifdef _COMPILING_NEWLIB -int _EXFUN(fseeko, (FILE *, _off_t, int)); -_off_t _EXFUN(ftello, ( FILE *)); -#else -int _EXFUN(fseeko, (FILE *, off_t, int)); -off_t _EXFUN(ftello, ( FILE *)); -#endif -#ifndef _REENT_ONLY -int _EXFUN(asiprintf, (char **, const char *, ...)); -int _EXFUN(asprintf, (char **, const char *, ...)); -int _EXFUN(fcloseall, (_VOID)); -int _EXFUN(fiprintf, (FILE *, const char *, ...)); -int _EXFUN(iprintf, (const char *, ...)); -int _EXFUN(siprintf, (char *, const char *, ...)); -int _EXFUN(snprintf, (char *, size_t, const char *, ...)); -int _EXFUN(sniprintf, (char *, size_t, const char *, ...)); -char * _EXFUN(tempnam, (const char *, const char *)); -int _EXFUN(vasiprintf, (char **, const char *, __VALIST)); -int _EXFUN(vasprintf, (char **, const char *, __VALIST)); -int _EXFUN(vsniprintf, (char *, size_t, const char *, __VALIST)); -int _EXFUN(vsnprintf, (char *, size_t, const char *, __VALIST)); -int _EXFUN(vfiprintf, (FILE *, const char *, __VALIST)); -int _EXFUN(vfiscanf, (FILE *, const char *, __VALIST)); -int _EXFUN(vfscanf, (FILE *, const char *, __VALIST)); -int _EXFUN(viscanf, (const char *, __VALIST)); -int _EXFUN(vscanf, (const char *, __VALIST)); -int _EXFUN(vsiscanf, (const char *, const char *, __VALIST)); -int _EXFUN(vsscanf, (const char *, const char *, __VALIST)); -#endif -#endif - -/* - * Routines in POSIX 1003.1. - */ - -#ifndef __STRICT_ANSI__ -#ifndef _REENT_ONLY -FILE * _EXFUN(fdopen, (int, const char *)); -#endif -int _EXFUN(fileno, (FILE *)); -int _EXFUN(getw, (FILE *)); -int _EXFUN(pclose, (FILE *)); -FILE * _EXFUN(popen, (const char *, const char *)); -int _EXFUN(putw, (int, FILE *)); -void _EXFUN(setbuffer, (FILE *, char *, int)); -int _EXFUN(setlinebuf, (FILE *)); -int _EXFUN(getc_unlocked, (FILE *)); -int _EXFUN(getchar_unlocked, (void)); -void _EXFUN(flockfile, (FILE *)); -int _EXFUN(ftrylockfile, (FILE *)); -void _EXFUN(funlockfile, (FILE *)); -int _EXFUN(putc_unlocked, (int, FILE *)); -int _EXFUN(putchar_unlocked, (int)); -#endif - -/* - * Recursive versions of the above. - */ - -int _EXFUN(_asiprintf_r, (struct _reent *, char **, const char *, ...)); -int _EXFUN(_asprintf_r, (struct _reent *, char **, const char *, ...)); -int _EXFUN(_fcloseall_r, (struct _reent *)); -FILE * _EXFUN(_fdopen_r, (struct _reent *, int, const char *)); -FILE * _EXFUN(_fopen_r, (struct _reent *, const char *, const char *)); -int _EXFUN(_fclose_r, (struct _reent *, FILE *)); -int _EXFUN(_fiscanf_r, (struct _reent *, FILE *, const char *, ...)); -int _EXFUN(_fscanf_r, (struct _reent *, FILE *, const char *, ...)); -int _EXFUN(_fseek_r, (struct _reent *, FILE *, long, int)); -long _EXFUN(_ftell_r, (struct _reent *, FILE *)); -int _EXFUN(_getchar_r, (struct _reent *)); -char * _EXFUN(_gets_r, (struct _reent *, char *)); -int _EXFUN(_iprintf_r, (struct _reent *, const char *, ...)); -int _EXFUN(_iscanf_r, (struct _reent *, const char *, ...)); -int _EXFUN(_mkstemp_r, (struct _reent *, char *)); -char * _EXFUN(_mktemp_r, (struct _reent *, char *)); -void _EXFUN(_perror_r, (struct _reent *, const char *)); -int _EXFUN(_printf_r, (struct _reent *, const char *, ...)); -int _EXFUN(_putchar_r, (struct _reent *, int)); -int _EXFUN(_puts_r, (struct _reent *, const char *)); -int _EXFUN(_remove_r, (struct _reent *, const char *)); -int _EXFUN(_rename_r, (struct _reent *, - const char *_old, const char *_new)); -int _EXFUN(_scanf_r, (struct _reent *, const char *, ...)); -int _EXFUN(_siprintf_r, (struct _reent *, char *, const char *, ...)); -int _EXFUN(_siscanf_r, (struct _reent *, const char *, const char *, ...)); -int _EXFUN(_sniprintf_r, (struct _reent *, char *, size_t, const char *, ...)); -int _EXFUN(_snprintf_r, (struct _reent *, char *, size_t, const char *, ...)); -int _EXFUN(_sprintf_r, (struct _reent *, char *, const char *, ...)); -int _EXFUN(_sscanf_r, (struct _reent *, const char *, const char *, ...)); -char * _EXFUN(_tempnam_r, (struct _reent *, const char *, const char *)); -FILE * _EXFUN(_tmpfile_r, (struct _reent *)); -char * _EXFUN(_tmpnam_r, (struct _reent *, char *)); -int _EXFUN(_ungetc_r, (struct _reent *, int, FILE *)); -int _EXFUN(_vasiprintf_r, (struct _reent *, char **, const char *, __VALIST)); -int _EXFUN(_vasprintf_r, (struct _reent *, char **, const char *, __VALIST)); -int _EXFUN(_vfiprintf_r, (struct _reent *, FILE *, const char *, __VALIST)); -int _EXFUN(_vfprintf_r, (struct _reent *, FILE *, const char *, __VALIST)); -int _EXFUN(_viprintf_r, (struct _reent *, const char *, __VALIST)); -int _EXFUN(_vprintf_r, (struct _reent *, const char *, __VALIST)); -int _EXFUN(_vsiprintf_r, (struct _reent *, char *, const char *, __VALIST)); -int _EXFUN(_vsprintf_r, (struct _reent *, char *, const char *, __VALIST)); -int _EXFUN(_vsniprintf_r, (struct _reent *, char *, size_t, const char *, __VALIST)); -int _EXFUN(_vsnprintf_r, (struct _reent *, char *, size_t, const char *, __VALIST)); -int _EXFUN(_vfiscanf_r, (struct _reent *, FILE *, const char *, __VALIST)); -int _EXFUN(_vfscanf_r, (struct _reent *, FILE *, const char *, __VALIST)); -int _EXFUN(_viscanf_r, (struct _reent *, const char *, __VALIST)); -int _EXFUN(_vscanf_r, (struct _reent *, const char *, __VALIST)); -int _EXFUN(_vsscanf_r, (struct _reent *, const char *, const char *, __VALIST)); -int _EXFUN(_vsiscanf_r, (struct _reent *, const char *, const char *, __VALIST)); - -ssize_t _EXFUN(__getdelim, (char **, size_t *, int, FILE *)); -ssize_t _EXFUN(__getline, (char **, size_t *, FILE *)); - -#ifdef __LARGE64_FILES -#if !defined(__CYGWIN__) || defined(_COMPILING_NEWLIB) -FILE * _EXFUN(fdopen64, (int, const char *)); -FILE * _EXFUN(fopen64, (const char *, const char *)); -_off64_t _EXFUN(ftello64, (FILE *)); -_off64_t _EXFUN(fseeko64, (FILE *, _off64_t, int)); -int _EXFUN(fgetpos64, (FILE *, _fpos64_t *)); -int _EXFUN(fsetpos64, (FILE *, const _fpos64_t *)); -FILE * _EXFUN(tmpfile64, (void)); - -FILE * _EXFUN(_fdopen64_r, (struct _reent *, int, const char *)); -FILE * _EXFUN(_fopen64_r, (struct _reent *,const char *, const char *)); -_off64_t _EXFUN(_ftello64_r, (struct _reent *, FILE *)); -_off64_t _EXFUN(_fseeko64_r, (struct _reent *, FILE *, _off64_t, int)); -int _EXFUN(_fgetpos64_r, (struct _reent *, FILE *, _fpos64_t *)); -int _EXFUN(_fsetpos64_r, (struct _reent *, FILE *, const _fpos64_t *)); -FILE * _EXFUN(_tmpfile64_r, (struct _reent *)); -#endif /* !__CYGWIN__ */ -#endif /* __LARGE64_FILES */ - -/* - * Routines internal to the implementation. - */ - -int _EXFUN(__srget, (FILE *)); -int _EXFUN(__swbuf, (int, FILE *)); - -/* - * Stdio function-access interface. - */ - -#ifndef __STRICT_ANSI__ -FILE *_EXFUN(funopen,(const _PTR _cookie, - int (*readfn)(_PTR _cookie, char *_buf, int _n), - int (*writefn)(_PTR _cookie, const char *_buf, int _n), - fpos_t (*seekfn)(_PTR _cookie, fpos_t _off, int _whence), - int (*closefn)(_PTR _cookie))); - -#define fropen(cookie, fn) funopen(cookie, fn, (int (*)())0, (fpos_t (*)())0, (int (*)())0) -#define fwopen(cookie, fn) funopen(cookie, (int (*)())0, fn, (fpos_t (*)())0, (int (*)())0) -#endif - -/* - * The __sfoo macros are here so that we can - * define function versions in the C library. - */ -#define __sgetc_raw(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) - -#ifdef __SCLE -static __inline__ int __sgetc(FILE *__p) - { - int __c = __sgetc_raw(__p); - if ((__p->_flags & __SCLE) && (__c == '\r')) - { - int __c2 = __sgetc_raw(__p); - if (__c2 == '\n') - __c = __c2; - else - ungetc(__c2, __p); - } - return __c; - } -#else -#define __sgetc(p) __sgetc_raw(p) -#endif - -#ifdef _never /* __GNUC__ */ -/* If this inline is actually used, then systems using coff debugging - info get hopelessly confused. 21sept93 rich@cygnus.com. */ -static __inline int __sputc(int _c, FILE *_p) { - if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) - return (*_p->_p++ = _c); - else - return (__swbuf(_c, _p)); -} -#else -/* - * This has been tuned to generate reasonable code on the vax using pcc - */ -#define __sputc_raw(c, p) \ - (--(p)->_w < 0 ? \ - (p)->_w >= (p)->_lbfsize ? \ - (*(p)->_p = (c)), *(p)->_p != '\n' ? \ - (int)*(p)->_p++ : \ - __swbuf('\n', p) : \ - __swbuf((int)(c), p) : \ - (*(p)->_p = (c), (int)*(p)->_p++)) -#ifdef __SCLE -#define __sputc(c, p) \ - ((((p)->_flags & __SCLE) && ((c) == '\n')) \ - ? __sputc_raw('\r', (p)) : 0 , \ - __sputc_raw((c), (p))) -#else -#define __sputc(c, p) __sputc_raw(c, p) -#endif -#endif - -#define __sfeof(p) (((p)->_flags & __SEOF) != 0) -#define __sferror(p) (((p)->_flags & __SERR) != 0) -#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) -#define __sfileno(p) ((p)->_file) - -#define feof(p) __sfeof(p) -#define ferror(p) __sferror(p) -#define clearerr(p) __sclearerr(p) - -#if 0 /*ndef __STRICT_ANSI__ - FIXME: must initialize stdio first, use fn */ -#define fileno(p) __sfileno(p) -#endif - -#ifndef __CYGWIN__ -#ifndef lint -#define getc(fp) __sgetc(fp) -#define putc(x, fp) __sputc(x, fp) -#endif /* lint */ -#endif /* __CYGWIN__ */ - -#define getchar() getc(stdin) -#define putchar(x) putc(x, stdout) - -#ifndef __STRICT_ANSI__ -/* fast always-buffered version, true iff error */ -#define fast_putc(x,p) (--(p)->_w < 0 ? \ - __swbuf((int)(x), p) == EOF : (*(p)->_p = (x), (p)->_p++, 0)) - -#define L_cuserid 9 /* posix says it goes in stdio.h :( */ -#ifdef __CYGWIN__ -#define L_ctermid 16 -#endif -#endif - -_END_STD_C - -#endif /* _STDIO_H_ */ diff --git a/extra_include/stdlib.h b/extra_include/stdlib.h deleted file mode 100644 index 84964d1d..00000000 --- a/extra_include/stdlib.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * stdlib.h - * - * Definitions for common types, variables, and functions. - */ - -#ifndef _STDLIB_H_ -#define _STDLIB_H_ - -#include "_ansi.h" - -#define __need_size_t -#define __need_wchar_t -#include - -#include -#include -#ifndef __STRICT_ANSI__ -#include -#endif - -_BEGIN_STD_C - -typedef struct -{ - int quot; /* quotient */ - int rem; /* remainder */ -} div_t; - -typedef struct -{ - long quot; /* quotient */ - long rem; /* remainder */ -} ldiv_t; - -#ifndef __STRICT_ANSI__ -typedef struct -{ - long long int quot; /* quotient */ - long long int rem; /* remainder */ -} lldiv_t; -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#define EXIT_FAILURE 1 -#define EXIT_SUCCESS 0 - -#define RAND_MAX __RAND_MAX - -extern __IMPORT int __mb_cur_max; - -#define MB_CUR_MAX __mb_cur_max - -_VOID _EXFUN(abort,(_VOID) _ATTRIBUTE ((noreturn))); -int _EXFUN(abs,(int)); -int _EXFUN(atexit,(_VOID (*__func)(_VOID))); -double _EXFUN(atof,(const char *__nptr)); -#ifndef __STRICT_ANSI__ -float _EXFUN(atoff,(const char *__nptr)); -#endif -int _EXFUN(atoi,(const char *__nptr)); -int _EXFUN(_atoi_r,(struct _reent *, const char *__nptr)); -long _EXFUN(atol,(const char *__nptr)); -long _EXFUN(_atol_r,(struct _reent *, const char *__nptr)); -_PTR _EXFUN(bsearch,(const _PTR __key, - const _PTR __base, - size_t __nmemb, - size_t __size, - int _EXPARM(_compar,(const _PTR, const _PTR)))); -_PTR _EXFUN(calloc,(size_t __nmemb, size_t __size)); -div_t _EXFUN(div,(int __numer, int __denom)); -_VOID _EXFUN(exit,(int __status) _ATTRIBUTE ((noreturn))); -_VOID _EXFUN(free,(_PTR)); -char * _EXFUN(getenv,(const char *__string)); -char * _EXFUN(_getenv_r,(struct _reent *, const char *__string)); -#ifdef __CYGWIN__ -const char *_EXFUN(getprogname,(void)); -#endif -char * _EXFUN(_findenv,(_CONST char *, int *)); -char * _EXFUN(_findenv_r,(struct _reent *, _CONST char *, int *)); -long _EXFUN(labs,(long)); -ldiv_t _EXFUN(ldiv,(long __numer, long __denom)); -_PTR _EXFUN(malloc,(size_t __size)); -int _EXFUN(mblen,(const char *, size_t)); -int _EXFUN(_mblen_r,(struct _reent *, const char *, size_t, _mbstate_t *)); -int _EXFUN(mbtowc,(wchar_t *, const char *, size_t)); -int _EXFUN(_mbtowc_r,(struct _reent *, wchar_t *, const char *, size_t, _mbstate_t *)); -int _EXFUN(wctomb,(char *, wchar_t)); -int _EXFUN(_wctomb_r,(struct _reent *, char *, wchar_t, _mbstate_t *)); -size_t _EXFUN(mbstowcs,(wchar_t *, const char *, size_t)); -size_t _EXFUN(_mbstowcs_r,(struct _reent *, wchar_t *, const char *, size_t, _mbstate_t *)); -size_t _EXFUN(wcstombs,(char *, const wchar_t *, size_t)); -size_t _EXFUN(_wcstombs_r,(struct _reent *, char *, const wchar_t *, size_t, _mbstate_t *)); -#ifndef __STRICT_ANSI__ -#ifndef _REENT_ONLY -int _EXFUN(mkstemp,(char *)); -char * _EXFUN(mktemp,(char *)); -#endif -#endif -_VOID _EXFUN(qsort,(_PTR __base, size_t __nmemb, size_t __size, int(*_compar)(const _PTR, const _PTR))); -int _EXFUN(rand,(_VOID)); -_PTR _EXFUN(realloc,(_PTR __r, size_t __size)); -#ifdef __CYGWIN__ -void _EXFUN(setprogname,(const char *)); -#endif -_VOID _EXFUN(srand,(unsigned __seed)); -double _EXFUN(strtod,(const char *__n, char **__end_PTR)); -double _EXFUN(_strtod_r,(struct _reent *,const char *__n, char **__end_PTR)); -float _EXFUN(strtof,(const char *__n, char **__end_PTR)); -#ifndef __STRICT_ANSI__ -/* the following strtodf interface is deprecated...use strtof instead */ -# ifndef strtodf -# define strtodf strtof -# endif -#endif -long _EXFUN(strtol,(const char *__n, char **__end_PTR, int __base)); -long _EXFUN(_strtol_r,(struct _reent *,const char *__n, char **__end_PTR, int __base)); -unsigned long _EXFUN(strtoul,(const char *__n, char **__end_PTR, int __base)); -unsigned long _EXFUN(_strtoul_r,(struct _reent *,const char *__n, char **__end_PTR, int __base)); - -int _EXFUN(system,(const char *__string)); - -#ifndef __STRICT_ANSI__ -long _EXFUN(a64l,(const char *__input)); -char * _EXFUN(l64a,(long __input)); -char * _EXFUN(_l64a_r,(struct _reent *,long __input)); -int _EXFUN(on_exit,(_VOID (*__func)(int, _PTR),_PTR __arg)); -_VOID _EXFUN(_Exit,(int __status) _ATTRIBUTE ((noreturn))); -int _EXFUN(putenv,(char *__string)); -int _EXFUN(_putenv_r,(struct _reent *, char *__string)); -int _EXFUN(setenv,(const char *__string, const char *__value, int __overwrite)); -int _EXFUN(_setenv_r,(struct _reent *, const char *__string, const char *__value, int __overwrite)); - -char * _EXFUN(gcvt,(double,int,char *)); -char * _EXFUN(gcvtf,(float,int,char *)); -char * _EXFUN(fcvt,(double,int,int *,int *)); -char * _EXFUN(fcvtf,(float,int,int *,int *)); -char * _EXFUN(ecvt,(double,int,int *,int *)); -char * _EXFUN(ecvtbuf,(double, int, int*, int*, char *)); -char * _EXFUN(fcvtbuf,(double, int, int*, int*, char *)); -char * _EXFUN(ecvtf,(float,int,int *,int *)); -char * _EXFUN(dtoa,(double, int, int, int *, int*, char**)); -int _EXFUN(rand_r,(unsigned *__seed)); - -double _EXFUN(drand48,(_VOID)); -double _EXFUN(_drand48_r,(struct _reent *)); -double _EXFUN(erand48,(unsigned short [3])); -double _EXFUN(_erand48_r,(struct _reent *, unsigned short [3])); -long _EXFUN(jrand48,(unsigned short [3])); -long _EXFUN(_jrand48_r,(struct _reent *, unsigned short [3])); -_VOID _EXFUN(lcong48,(unsigned short [7])); -_VOID _EXFUN(_lcong48_r,(struct _reent *, unsigned short [7])); -long _EXFUN(lrand48,(_VOID)); -long _EXFUN(_lrand48_r,(struct _reent *)); -long _EXFUN(mrand48,(_VOID)); -long _EXFUN(_mrand48_r,(struct _reent *)); -long _EXFUN(nrand48,(unsigned short [3])); -long _EXFUN(_nrand48_r,(struct _reent *, unsigned short [3])); -unsigned short * - _EXFUN(seed48,(unsigned short [3])); -unsigned short * - _EXFUN(_seed48_r,(struct _reent *, unsigned short [3])); -_VOID _EXFUN(srand48,(long)); -_VOID _EXFUN(_srand48_r,(struct _reent *, long)); -long long _EXFUN(atoll,(const char *__nptr)); -long long _EXFUN(_atoll_r,(struct _reent *, const char *__nptr)); -long long _EXFUN(llabs,(long long)); -lldiv_t _EXFUN(lldiv,(long long __numer, long long __denom)); -long long _EXFUN(strtoll,(const char *__n, char **__end_PTR, int __base)); -long long _EXFUN(_strtoll_r,(struct _reent *, const char *__n, char **__end_PTR, int __base)); -unsigned long long _EXFUN(strtoull,(const char *__n, char **__end_PTR, int __base)); -unsigned long long _EXFUN(_strtoull_r,(struct _reent *, const char *__n, char **__end_PTR, int __base)); - -#ifndef __CYGWIN__ -_VOID _EXFUN(cfree,(_PTR)); -#else -char * _EXFUN(realpath,(const char *, char *)); -void _EXFUN(unsetenv,(const char *__string)); -void _EXFUN(_unsetenv_r,(struct _reent *, const char *__string)); -int _EXFUN(random,(_VOID)); -long _EXFUN(srandom,(unsigned __seed)); -char * _EXFUN(ptsname, (int)); -int _EXFUN(grantpt, (int)); -int _EXFUN(unlockpt,(int)); -#endif - -#endif /* ! __STRICT_ANSI__ */ - -char * _EXFUN(_dtoa_r,(struct _reent *, double, int, int, int *, int*, char**)); -#ifndef __CYGWIN__ -_PTR _EXFUN(_malloc_r,(struct _reent *, size_t)); -_PTR _EXFUN(_calloc_r,(struct _reent *, size_t, size_t)); -_VOID _EXFUN(_free_r,(struct _reent *, _PTR)); -_PTR _EXFUN(_realloc_r,(struct _reent *, _PTR, size_t)); -_VOID _EXFUN(_mstats_r,(struct _reent *, char *)); -#endif -int _EXFUN(_system_r,(struct _reent *, const char *)); - -_VOID _EXFUN(__eprintf,(const char *, const char *, unsigned int, const char *)); - -#ifdef __CYGWIN__ -#undef _malloc_r -#define _malloc_r(r, s) malloc (s) -#undef _free_r -#define _free_r(r, p) free (p) -#undef _realloc_r -#define _realloc_r(r, p, s) realloc (p, s) -#undef _calloc_r -#define _calloc_r(r, s1, s2) calloc (s1, s2); -#undef _memalign_r -#define _memalign_r(r, s1, s2) memalign (s1, s2); -#undef _mallinfo_r -#define _mallinfo_r(r) mallinfo () -#undef _malloc_stats_r -#define _malloc_stats_r(r) malloc_stats () -#undef _mallopt_r -#define _mallopt_r(i1, i2) mallopt (i1, i2) -#undef _malloc_usable_size_r -#define _malloc_usable_size_r(r, p) malloc_usable_size (p) -#undef _valloc_r -#define _valloc_r(r, s) valloc (s) -#undef _pvalloc_r -#define _pvalloc_r(r, s) pvalloc (s) -#undef _malloc_trim_r -#define _malloc_trim_r(r, s) malloc_trim (s) -#undef _mstats_r -#define _mstats_r(r, p) mstats (p) -#endif - -_END_STD_C - -#endif /* _STDLIB_H_ */ diff --git a/extra_include/string.h b/extra_include/string.h deleted file mode 100644 index e1d5ae16..00000000 --- a/extra_include/string.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * string.h - * - * Definitions for memory and string functions. - */ - -#ifndef _STRING_H_ -#define _STRING_H_ - -#include "_ansi.h" -#include - -#define __need_size_t -#include - -#ifndef NULL -#define NULL 0 -#endif - -_BEGIN_STD_C - -_PTR _EXFUN(memchr,(const _PTR, int, size_t)); -int _EXFUN(memcmp,(const _PTR, const _PTR, size_t)); -_PTR _EXFUN(memcpy,(_PTR, const _PTR, size_t)); -_PTR _EXFUN(memmove,(_PTR, const _PTR, size_t)); -_PTR _EXFUN(memset,(_PTR, int, size_t)); -char *_EXFUN(strcat,(char *, const char *)); -char *_EXFUN(strchr,(const char *, int)); -int _EXFUN(strcmp,(const char *, const char *)); -int _EXFUN(strcoll,(const char *, const char *)); -char *_EXFUN(strcpy,(char *, const char *)); -size_t _EXFUN(strcspn,(const char *, const char *)); -char *_EXFUN(strerror,(int)); -size_t _EXFUN(strlen,(const char *)); -char *_EXFUN(strncat,(char *, const char *, size_t)); -int _EXFUN(strncmp,(const char *, const char *, size_t)); -char *_EXFUN(strncpy,(char *, const char *, size_t)); -char *_EXFUN(strpbrk,(const char *, const char *)); -char *_EXFUN(strrchr,(const char *, int)); -size_t _EXFUN(strspn,(const char *, const char *)); -char *_EXFUN(strstr,(const char *, const char *)); - -#ifndef _REENT_ONLY -char *_EXFUN(strtok,(char *, const char *)); -#endif - -size_t _EXFUN(strxfrm,(char *, const char *, size_t)); - -#ifndef __STRICT_ANSI__ -char *_EXFUN(strtok_r,(char *, const char *, char **)); - -int _EXFUN(bcmp,(const void *, const void *, size_t)); -void _EXFUN(bcopy,(const void *, void *, size_t)); -void _EXFUN(bzero,(void *, size_t)); -int _EXFUN(ffs,(int)); -char *_EXFUN(index,(const char *, int)); -_PTR _EXFUN(memccpy,(_PTR, const _PTR, int, size_t)); -_PTR _EXFUN(mempcpy,(_PTR, const _PTR, size_t)); -char *_EXFUN(rindex,(const char *, int)); -int _EXFUN(strcasecmp,(const char *, const char *)); -char *_EXFUN(strdup,(const char *)); -char *_EXFUN(_strdup_r,(struct _reent *, const char *)); -char *_EXFUN(strndup,(const char *, size_t)); -char *_EXFUN(_strndup_r,(struct _reent *, const char *, size_t)); -char *_EXFUN(strerror_r,(int, char *, size_t)); -size_t _EXFUN(strlcat,(char *, const char *, size_t)); -size_t _EXFUN(strlcpy,(char *, const char *, size_t)); -int _EXFUN(strncasecmp,(const char *, const char *, size_t)); -size_t _EXFUN(strnlen,(const char *, size_t)); -char *_EXFUN(strsep,(char **, const char *)); -char *_EXFUN(strlwr,(char *)); -char *_EXFUN(strupr,(char *)); -#ifdef __CYGWIN__ -#ifndef DEFS_H /* Kludge to work around problem compiling in gdb */ -const char *_EXFUN(strsignal, (int __signo)); -#endif -int _EXFUN(strtosigno, (const char *__name)); -#elif defined(__linux__) -char *_EXFUN(strsignal, (int __signo)); -#endif - -/* These function names are used on Windows and perhaps other systems. */ -#ifndef strcmpi -#define strcmpi strcasecmp -#endif -#ifndef stricmp -#define stricmp strcasecmp -#endif -#ifndef strncmpi -#define strncmpi strncasecmp -#endif -#ifndef strnicmp -#define strnicmp strncasecmp -#endif - -#endif /* ! __STRICT_ANSI__ */ - -_END_STD_C - -#endif /* _STRING_H_ */ diff --git a/extra_include/sys/_types.h b/extra_include/sys/_types.h deleted file mode 100644 index 73a4a81b..00000000 --- a/extra_include/sys/_types.h +++ /dev/null @@ -1,42 +0,0 @@ -/* ANSI C namespace clean utility typedefs */ - -/* This file defines various typedefs needed by the system calls that support - the C library. Basically, they're just the POSIX versions with an '_' - prepended. This file lives in the `sys' directory so targets can provide - their own if desired (or they can put target dependant conditionals here). -*/ - -#ifndef _SYS__TYPES_H -#define _SYS__TYPES_H - -#include - -typedef long _off_t; -__extension__ typedef long long _off64_t; - -#if defined(__INT_MAX__) && __INT_MAX__ == 2147483647 -typedef int _ssize_t; -#else -typedef long _ssize_t; -#endif - -#define __need_wint_t -#include - -/* Conversion state information. */ -typedef struct -{ - int __count; - union - { - wint_t __wch; - unsigned char __wchb[4]; - } __value; /* Value so far. */ -} _mbstate_t; - -typedef _LOCK_RECURSIVE_T _flock_t; - -/* Iconv descriptor type */ -typedef void *_iconv_t; - -#endif /* _SYS__TYPES_H */ diff --git a/extra_include/sys/cdefs.h b/extra_include/sys/cdefs.h deleted file mode 100644 index a5f4fa26..00000000 --- a/extra_include/sys/cdefs.h +++ /dev/null @@ -1,123 +0,0 @@ -/* libc/sys/linux/sys/cdefs.h - Helper macros for K&R vs. ANSI C compat. */ - -/* Written 2000 by Werner Almesberger */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Berkeley Software Design, Inc. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 - * $FreeBSD: src/sys/sys/cdefs.h,v 1.54 2002/05/11 03:58:24 alfred Exp $ - */ - -#ifndef _SYS_CDEFS_H -#define _SYS_CDEFS_H - -#define __FBSDID(x) /* nothing */ -/* - * Note: the goal here is not compatibility to K&R C. Since we know that we - * have GCC which understands ANSI C perfectly well, we make use of this. - */ - -#define __P(args) args -#define __PMT(args) args -#define __const const -#define __signed signed -#define __volatile volatile -#define __DOTS , ... -#define __THROW - -#define __ptr_t void * -#define __long_double_t long double - -#define __attribute_malloc__ -#define __attribute_pure__ -#define __attribute_format_strfmon__(a,b) -#define __flexarr [0] - -#ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -#else -# define __BEGIN_DECLS -# define __END_DECLS -#endif - -#ifndef __BOUNDED_POINTERS__ -# define __bounded /* nothing */ -# define __unbounded /* nothing */ -# define __ptrvalue /* nothing */ -#endif - -#ifdef __GNUC__ -#define __strong_reference(sym,aliassym) \ - extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))); -#ifdef __ELF__ -#ifdef __STDC__ -#define __weak_reference(sym,alias) \ - __asm__(".weak " #alias); \ - __asm__(".equ " #alias ", " #sym) -#define __warn_references(sym,msg) \ - __asm__(".section .gnu.warning." #sym); \ - __asm__(".asciz \"" msg "\""); \ - __asm__(".previous") -#else -#define __weak_reference(sym,alias) \ - __asm__(".weak alias"); \ - __asm__(".equ alias, sym") -#define __warn_references(sym,msg) \ - __asm__(".section .gnu.warning.sym"); \ - __asm__(".asciz \"msg\""); \ - __asm__(".previous") -#endif /* __STDC__ */ -#else /* !__ELF__ */ -#ifdef __STDC__ -#define __weak_reference(sym,alias) \ - __asm__(".stabs \"_" #alias "\",11,0,0,0"); \ - __asm__(".stabs \"_" #sym "\",1,0,0,0") -#define __warn_references(sym,msg) \ - __asm__(".stabs \"" msg "\",30,0,0,0"); \ - __asm__(".stabs \"_" #sym "\",1,0,0,0") -#else -#define __weak_reference(sym,alias) \ - __asm__(".stabs \"_/**/alias\",11,0,0,0"); \ - __asm__(".stabs \"_/**/sym\",1,0,0,0") -#define __warn_references(sym,msg) \ - __asm__(".stabs msg,30,0,0,0"); \ - __asm__(".stabs \"_/**/sym\",1,0,0,0") -#endif /* __STDC__ */ -#endif /* __ELF__ */ -#endif /* __GNUC__ */ - -#endif /* _SYS_CDEFS_H */ diff --git a/extra_include/sys/config.h b/extra_include/sys/config.h deleted file mode 100644 index fc0a4a77..00000000 --- a/extra_include/sys/config.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef __SYS_CONFIG_H__ -#define __SYS_CONFIG_H__ - -#include /* floating point macros */ - -/* exceptions first */ -#if defined(__H8500__) || defined(__W65__) -#define __SMALL_BITFIELDS -/* ??? This conditional is true for the h8500 and the w65, defining H8300 - in those cases probably isn't the right thing to do. */ -#define H8300 1 -#endif - -/* 16 bit integer machines */ -#if defined(__Z8001__) || defined(__Z8002__) || defined(__H8500__) || defined(__W65__) || defined (__mn10200__) || defined (__AVR__) - -#undef INT_MAX -#undef UINT_MAX -#define INT_MAX 32767 -#define UINT_MAX 65535 -#endif - -#if defined (__H8300__) || defined (__H8300H__) || defined(__H8300S__) || defined (__H8300SX__) -#define __SMALL_BITFIELDS -#define H8300 1 -#undef INT_MAX -#undef UINT_MAX -#define INT_MAX __INT_MAX__ -#define UINT_MAX (__INT_MAX__ * 2U + 1) -#endif - -#ifdef __W65__ -#define __SMALL_BITFIELDS -#endif - -#if defined(__D10V__) -#define __SMALL_BITFIELDS -#undef INT_MAX -#undef UINT_MAX -#define INT_MAX __INT_MAX__ -#define UINT_MAX (__INT_MAX__ * 2U + 1) -#define _POINTER_INT short -#endif - -#if defined(__mc68hc11__) || defined(__mc68hc12__) || defined(__mc68hc1x__) -#undef INT_MAX -#undef UINT_MAX -#define INT_MAX __INT_MAX__ -#define UINT_MAX (__INT_MAX__ * 2U + 1) -#define _POINTER_INT short -#endif - -#ifdef ___AM29K__ -#define _FLOAT_RET double -#endif - -#ifdef __i386__ -#ifndef __unix__ -/* in other words, go32 */ -#define _FLOAT_RET double -#endif -#ifdef __linux__ -/* we want the reentrancy structure to be returned by a function */ -#define __DYNAMIC_REENT__ -#define HAVE_GETDATE -#define _HAVE_SYSTYPES -#define _READ_WRITE_RETURN_TYPE _ssize_t -#define __LARGE64_FILES 1 -/* we use some glibc header files so turn on glibc large file feature */ -#define _LARGEFILE64_SOURCE 1 -#endif -#endif - -#ifdef __mn10200__ -#define __SMALL_BITFIELDS -#endif - -#ifdef __AVR__ -#define __SMALL_BITFIELDS -#define _POINTER_INT short -#endif - -#ifdef __v850 -#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__sda__)) -#endif - -/* For the PowerPC eabi, force the _impure_ptr to be in .sdata */ -#if defined(__PPC__) -#if defined(_CALL_SYSV) -#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__section__(".sdata"))) -#endif -#ifdef __SPE__ -#define _LONG_DOUBLE double -#endif -#endif - -#ifdef __xstormy16__ -#define __SMALL_BITFIELDS -#undef INT_MAX -#undef UINT_MAX -#define INT_MAX __INT_MAX__ -#define UINT_MAX (__INT_MAX__ * 2U + 1) -#define MALLOC_ALIGNMENT 8 -#define _POINTER_INT short -#define __BUFSIZ__ 16 -#define _REENT_SMALL -#endif - -/* This block should be kept in sync with GCC's limits.h. The point - of having these definitions here is to not include limits.h, which - would pollute the user namespace, while still using types of the - the correct widths when deciding how to define __int32_t and - __int64_t. */ -#ifndef __INT_MAX__ -# ifdef INT_MAX -# define __INT_MAX__ INT_MAX -# else -# define __INT_MAX__ 2147483647 -# endif -#endif - -#ifndef __LONG_MAX__ -# ifdef LONG_MAX -# define __LONG_MAX__ LONG_MAX -# else -# if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) \ - || defined (__sparcv9) -# define __LONG_MAX__ 9223372036854775807L -# else -# define __LONG_MAX__ 2147483647L -# endif /* __alpha__ || sparc64 */ -# endif -#endif -/* End of block that should be kept in sync with GCC's limits.h. */ - -#ifndef _POINTER_INT -#define _POINTER_INT long -#endif - -#ifdef __frv__ -#define __ATTRIBUTE_IMPURE_PTR__ __attribute__((__section__(".sdata"))) -#endif -#undef __RAND_MAX -#if __INT_MAX__ == 32767 -#define __RAND_MAX 32767 -#else -#define __RAND_MAX 0x7fffffff -#endif - -#if defined(__CYGWIN__) -#include -#endif - -#if defined(__rtems__) -#define __FILENAME_MAX__ 255 -#define _READ_WRITE_RETURN_TYPE _ssize_t -#endif - -#ifndef __IMPORT -#define __IMPORT -#endif - -/* Define return type of read/write routines. In POSIX, the return type - for read()/write() is "ssize_t" but legacy newlib code has been using - "int" for some time. If not specified, "int" is defaulted. */ -#ifndef _READ_WRITE_RETURN_TYPE -#define _READ_WRITE_RETURN_TYPE int -#endif - -#ifndef __WCHAR_MAX__ -#if __INT_MAX__ == 32767 || defined (_WIN32) -#define __WCHAR_MAX__ 0xffffu -#endif -#endif - -#endif /* __SYS_CONFIG_H__ */ diff --git a/extra_include/sys/dirent.h b/extra_include/sys/dirent.h deleted file mode 100644 index f55d7cb5..00000000 --- a/extra_include/sys/dirent.h +++ /dev/null @@ -1,15 +0,0 @@ -/* includes , which is this file. On a - system which supports , this file is overridden by - dirent.h in the libc/sys/.../sys directory. On a system which does - not support , we will get this file which tries to find - any other which may be lurking around. If there isn't - one, the user will get an error indicating that there is no - . */ - -#ifdef __cplusplus -extern "C" { -#endif -#include_next -#ifdef __cplusplus -} -#endif diff --git a/extra_include/sys/errno.h b/extra_include/sys/errno.h deleted file mode 100644 index b899165f..00000000 --- a/extra_include/sys/errno.h +++ /dev/null @@ -1,175 +0,0 @@ -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 2003-2006 Tensilica Inc. ALL RIGHTS RESERVED. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 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 TENSILICA - INCORPORATED 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. */ - -/* errno is not a global variable, because that would make using it - non-reentrant. Instead, its address is returned by the function - __errno. */ - -#ifndef _SYS_ERRNO_H_ -#ifdef __cplusplus -extern "C" { -#endif -#define _SYS_ERRNO_H_ - -#include -#include - -#ifndef _REENT_ONLY -#define errno (*__errno()) -extern int *__errno _PARAMS ((void)); -#endif - -#define __errno_r(ptr) ((ptr)->_errno) - -#define EPERM _SIMC_EPERM -#define ENOENT _SIMC_ENOENT -#define ESRCH _SIMC_ESRCH -#define EINTR _SIMC_EINTR -#define EIO _SIMC_EIO -#define ENXIO _SIMC_ENXIO -#define E2BIG _SIMC_E2BIG -#define ENOEXEC _SIMC_ENOEXEC -#define EBADF _SIMC_EBADF -#define ECHILD _SIMC_ECHILD -#define EAGAIN _SIMC_EAGAIN -#define ENOMEM _SIMC_ENOMEM -#define EACCES _SIMC_EACCES -#define EFAULT _SIMC_EFAULT -#define ENOTBLK _SIMC_ENOTBLK -#define EBUSY _SIMC_EBUSY -#define EEXIST _SIMC_EEXIST -#define EXDEV _SIMC_EXDEV -#define ENODEV _SIMC_ENODEV -#define ENOTDIR _SIMC_ENOTDIR -#define EISDIR _SIMC_EISDIR -#define EINVAL _SIMC_EINVAL -#define ENFILE _SIMC_ENFILE -#define EMFILE _SIMC_EMFILE -#define ENOTTY _SIMC_ENOTTY -#define ETXTBSY _SIMC_ETXTBSY -#define EFBIG _SIMC_EFBIG -#define ENOSPC _SIMC_ENOSPC -#define ESPIPE _SIMC_ESPIPE -#define EROFS _SIMC_EROFS -#define EMLINK _SIMC_EMLINK -#define EPIPE _SIMC_EPIPE -#define EDOM _SIMC_EDOM -#define ERANGE _SIMC_ERANGE -#define ENOMSG _SIMC_ENOMSG -#define EIDRM _SIMC_EIDRM -#define ECHRNG _SIMC_ECHRNG -#define EL2NSYNC _SIMC_EL2NSYNC -#define EL3HLT _SIMC_EL3HLT -#define EL3RST _SIMC_EL3RST -#define ELNRNG _SIMC_ELNRNG -#define EUNATCH _SIMC_EUNATCH -#define ENOCSI _SIMC_ENOCSI -#define EL2HLT _SIMC_EL2HLT -#define EDEADLK _SIMC_EDEADLK -#define ENOLCK _SIMC_ENOLCK -#define EBADE _SIMC_EBADE -#define EBADR _SIMC_EBADR -#define EXFULL _SIMC_EXFULL -#define ENOANO _SIMC_ENOANO -#define EBADRQC _SIMC_EBADRQC -#define EBADSLT _SIMC_EBADSLT -#define EDEADLOCK _SIMC_EDEADLOCK -#define EBFONT _SIMC_EBFONT -#define ENOSTR _SIMC_ENOSTR -#define ENODATA _SIMC_ENODATA -#define ETIME _SIMC_ETIME -#define ENOSR _SIMC_ENOSR -#define ENONET _SIMC_ENONET -#define ENOPKG _SIMC_ENOPKG -#define EREMOTE _SIMC_EREMOTE -#define ENOLINK _SIMC_ENOLINK -#define EADV _SIMC_EADV -#define ESRMNT _SIMC_ESRMNT -#define ECOMM _SIMC_ECOMM -#define EPROTO _SIMC_EPROTO -#define EMULTIHOP _SIMC_EMULTIHOP -#define ELBIN _SIMC_ELBIN -#define EDOTDOT _SIMC_EDOTDOT -#define EBADMSG _SIMC_EBADMSG -#define EFTYPE _SIMC_EFTYPE -#define ENOTUNIQ _SIMC_ENOTUNIQ -#define EBADFD _SIMC_EBADFD -#define EREMCHG _SIMC_EREMCHG -#define ELIBACC _SIMC_ELIBACC -#define ELIBBAD _SIMC_ELIBBAD -#define ELIBSCN _SIMC_ELIBSCN -#define ELIBMAX _SIMC_ELIBMAX -#define ELIBEXEC _SIMC_ELIBEXEC -#define ENOSYS _SIMC_ENOSYS -#define ENMFILE _SIMC_ENMFILE -#define ENOTEMPTY _SIMC_ENOTEMPTY -#define ENAMETOOLONG _SIMC_ENAMETOOLONG -#define ELOOP _SIMC_ELOOP -#define EOPNOTSUPP _SIMC_EOPNOTSUPP -#define EPFNOSUPPORT _SIMC_EPFNOSUPPORT -#define ECONNRESET _SIMC_ECONNRESET -#define ENOBUFS _SIMC_ENOBUFS -#define EAFNOSUPPORT _SIMC_EAFNOSUPPORT -#define EPROTOTYPE _SIMC_EPROTOTYPE -#define ENOTSOCK _SIMC_ENOTSOCK -#define ENOPROTOOPT _SIMC_ENOPROTOOPT -#define ESHUTDOWN _SIMC_ESHUTDOWN -#define ECONNREFUSED _SIMC_ECONNREFUSED -#define EADDRINUSE _SIMC_EADDRINUSE -#define ECONNABORTED _SIMC_ECONNABORTED -#define ENETUNREACH _SIMC_ENETUNREACH -#define ENETDOWN _SIMC_ENETDOWN -#define ETIMEDOUT _SIMC_ETIMEDOUT -#define EHOSTDOWN _SIMC_EHOSTDOWN -#define EHOSTUNREACH _SIMC_EHOSTUNREACH -#define EINPROGRESS _SIMC_EINPROGRESS -#define EALREADY _SIMC_EALREADY -#define EDESTADDRREQ _SIMC_EDESTADDRREQ -#define EMSGSIZE _SIMC_EMSGSIZE -#define EPROTONOSUPPORT _SIMC_EPROTONOSUPPORT -#define ESOCKTNOSUPPORT _SIMC_ESOCKTNOSUPPORT -#define EADDRNOTAVAIL _SIMC_EADDRNOTAVAIL -#define ENETRESET _SIMC_ENETRESET -#define EISCONN _SIMC_EISCONN -#define ENOTCONN _SIMC_ENOTCONN -#define ETOOMANYREFS _SIMC_ETOOMANYREFS -#define EPROCLIM _SIMC_EPROCLIM -#define EUSERS _SIMC_EUSERS -#define EDQUOT _SIMC_EDQUOT -#define ESTALE _SIMC_ESTALE -#define ENOTSUP _SIMC_ENOTSUP -#define ENOMEDIUM _SIMC_ENOMEDIUM -#define ENOSHARE _SIMC_ENOSHARE -#define ECASECLASH _SIMC_ECASECLASH -#define EILSEQ _SIMC_EILSEQ -#define EOVERFLOW _SIMC_EOVERFLOW - -#define EWOULDBLOCK EAGAIN - -#define __ELASTERROR 2000 /* Users can add values starting here */ - -#ifdef __cplusplus -} -#endif -#endif /* _SYS_ERRNO_H */ diff --git a/extra_include/sys/fcntl.h b/extra_include/sys/fcntl.h deleted file mode 100644 index 46b65ec2..00000000 --- a/extra_include/sys/fcntl.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 1998-2006 Tensilica Inc. ALL RIGHTS RESERVED. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 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 TENSILICA - INCORPORATED 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. */ - -#ifndef _FCNTL_ -#ifdef __cplusplus -extern "C" { -#endif -#define _FCNTL_ -#include <_ansi.h> -#include -#define _FOPEN (-1) /* from sys/file.h, kernel use only */ -#define _FREAD 0x0001 /* read enabled */ -#define _FWRITE 0x0002 /* write enabled */ -#define _FAPPEND _SIMC_O_APPEND /* append */ -#define _FCREAT _SIMC_O_CREAT /* open with file create */ -#define _FTRUNC _SIMC_O_TRUNC /* open with truncation */ -#define _FEXCL _SIMC_O_EXCL /* error on open if file exists */ -#define _FNONBLOCK _SIMC_O_NONBLOCK /* non blocking I/O (POSIX style) */ -#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */ - -#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) - -/* - * Flag values for open(2) and fcntl(2) - * The kernel adds 1 to the open modes to turn it into some - * combination of FREAD and FWRITE. - */ -#define O_RDONLY 0 /* +1 == FREAD */ -#define O_WRONLY 1 /* +1 == FWRITE */ -#define O_RDWR 2 /* +1 == FREAD|FWRITE */ -#define O_APPEND _FAPPEND -#define O_CREAT _FCREAT -#define O_TRUNC _FTRUNC -#define O_EXCL _FEXCL -#define O_NDELAY _FNDELAY -#define O_NONBLOCK _FNONBLOCK - -#define _FBINARY _SIMC_O_BINARY -#define _FTEXT _SIMC_O_TEXT - -#define O_BINARY _FBINARY -#define O_TEXT _FTEXT - -#ifndef _POSIX_SOURCE - -/* - * Flags that work for fcntl(fd, F_SETFL, FXXXX) - */ -#define FAPPEND _FAPPEND -#define FNONBIO _FNONBLOCK /* XXX fix to be NONBLOCK everywhere */ -#define FNDELAY _FNDELAY - -/* - * Flags that are disallowed for fcntl's (FCNTLCANT); - * used for opens, internal state, or locking. - */ -#define FREAD _FREAD -#define FWRITE _FWRITE - -/* - * The rest of the flags, used only for opens - */ -#define FOPEN _FOPEN -#define FCREAT _FCREAT -#define FTRUNC _FTRUNC -#define FEXCL _FEXCL - -#endif /* !_POSIX_SOURCE */ - -/* XXX close on exec request; must match UF_EXCLOSE in user.h */ -#define FD_CLOEXEC 1 /* posix */ - -/* fcntl(2) requests */ -/* TENSILICA: ISS semihosting does not support fcntl() but it is useful to - * define these anyway (e.g., to compile some versions of GNU libiberty). */ -#define F_DUPFD 0 /* Duplicate fildes */ -#define F_GETFD 1 /* Get fildes flags (close on exec) */ -#define F_SETFD 2 /* Set fildes flags (close on exec) */ -#define F_GETFL 3 /* Get file flags */ -#define F_SETFL 4 /* Set file flags */ -#ifndef _POSIX_SOURCE -#define F_GETOWN 5 /* Get owner - for ASYNC */ -#define F_SETOWN 6 /* Set owner - for ASYNC */ -#endif /* !_POSIX_SOURCE */ -#define F_GETLK 7 /* Get record-locking information */ -#define F_SETLK 8 /* Set or Clear a record-lock (Non-Blocking) */ -#define F_SETLKW 9 /* Set or Clear a record-lock (Blocking) */ -#ifndef _POSIX_SOURCE -#define F_RGETLK 10 /* Test a remote lock to see if it is blocked */ -#define F_RSETLK 11 /* Set or unlock a remote lock */ -#define F_CNVT 12 /* Convert a fhandle to an open fd */ -#define F_RSETLKW 13 /* Set or Clear remote record-lock(Blocking) */ -#endif /* !_POSIX_SOURCE */ - -#include -#include /* sigh. for the mode bits for open/creat */ - -extern int open _PARAMS ((const char *, int, ...)); -extern int creat _PARAMS ((const char *, mode_t)); -extern int fcntl _PARAMS ((int, int, ...)); - -/* Provide _ prototypes for functions provided by some versions - of newlib. */ -extern int _open _PARAMS ((const char *, int, ...)); -extern int _fcntl _PARAMS ((int, int, ...)); - -#ifdef __cplusplus -} -#endif -#endif /* !_FCNTL_ */ diff --git a/extra_include/sys/features.h b/extra_include/sys/features.h deleted file mode 100644 index a560c4b6..00000000 --- a/extra_include/sys/features.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Written by Joel Sherrill . - * - * COPYRIGHT (c) 1989-2000. - * - * On-Line Applications Research Corporation (OAR). - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION - * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS - * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - * $Id: features.h,v 1.6 2004/02/09 02:22:01 cgf Exp $ - */ - -#ifndef _SYS_FEATURES_H -#define _SYS_FEATURES_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* RTEMS adheres to POSIX -- 1003.1b with some features from annexes. */ - -#ifdef __rtems__ -#define _POSIX_JOB_CONTROL 1 -#define _POSIX_SAVED_IDS 1 -#define _POSIX_VERSION 199309L -#define _POSIX_ASYNCHRONOUS_IO 1 -#define _POSIX_FSYNC 1 -#define _POSIX_MAPPED_FILES 1 -#define _POSIX_MEMLOCK 1 -#define _POSIX_MEMLOCK_RANGE 1 -#define _POSIX_MEMORY_PROTECTION 1 -#define _POSIX_MESSAGE_PASSING 1 -#define _POSIX_PRIORITIZED_IO 1 -#define _POSIX_PRIORITY_SCHEDULING 1 -#define _POSIX_REALTIME_SIGNALS 1 -#define _POSIX_SEMAPHORES 1 -#define _POSIX_SHARED_MEMORY_OBJECTS 1 -#define _POSIX_SYNCHRONIZED_IO 1 -#define _POSIX_TIMERS 1 - - -/* In P1003.1b but defined by drafts at least as early as P1003.1c/D10 */ -#define _POSIX_THREADS 1 -#define _POSIX_THREAD_ATTR_STACKADDR 1 -#define _POSIX_THREAD_ATTR_STACKSIZE 1 -#define _POSIX_THREAD_PRIORITY_SCHEDULING 1 -#define _POSIX_THREAD_PRIO_INHERIT 1 -#define _POSIX_THREAD_PRIO_PROTECT 1 -#define _POSIX_THREAD_PROCESS_SHARED 1 -#define _POSIX_THREAD_SAFE_FUNCTIONS 1 - -/* P1003.4b/D8 defines the constants below this comment. */ -#define _POSIX_SPAWN 1 -#define _POSIX_TIMEOUTS 1 -#define _POSIX_CPUTIME 1 -#define _POSIX_THREAD_CPUTIME 1 -#define _POSIX_SPORADIC_SERVER 1 -#define _POSIX_THREAD_SPORADIC_SERVER 1 -#define _POSIX_DEVICE_CONTROL 1 -#define _POSIX_DEVCTL_DIRECTION 1 -#define _POSIX_INTERRUPT_CONTROL 1 -#define _POSIX_ADVISORY_INFO 1 - -#endif - -#ifdef __svr4__ -# define _POSIX_JOB_CONTROL 1 -# define _POSIX_SAVED_IDS 1 -# define _POSIX_VERSION 199009L -#endif - -#ifdef __CYGWIN__ -# define _POSIX_JOB_CONTROL 1 -# define _POSIX_SAVED_IDS 0 -# define _POSIX_VERSION 199009L -# define _POSIX_THREADS 1 -# define _POSIX_THREAD_PROCESS_SHARED 1 -# define _POSIX_THREAD_SAFE_FUNCTIONS 1 -# define _POSIX_THREAD_PRIORITY_SCHEDULING 1 -# define _POSIX_THREAD_ATTR_STACKSIZE 1 -# define _POSIX_SEMAPHORES 1 -# define _POSIX_TIMERS 1 -#endif - -#ifdef __cplusplus -} -#endif -#endif /* _SYS_FEATURES_H */ diff --git a/extra_include/sys/file.h b/extra_include/sys/file.h deleted file mode 100644 index 55d58cf1..00000000 --- a/extra_include/sys/file.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 2005-2006 Tensilica Inc. ALL RIGHTS RESERVED. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 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 TENSILICA - INCORPORATED 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 - -/* Alternate names for values for the WHENCE argument to `lseek'. - These are the same as SEEK_SET, SEEK_CUR, and SEEK_END, respectively. */ -#ifndef L_SET -#define L_SET 0 /* Seek from beginning of file. */ -#define L_INCR 1 /* Seek from current position. */ -#define L_XTND 2 /* Seek from end of file. */ -#endif diff --git a/extra_include/sys/iconvnls.h b/extra_include/sys/iconvnls.h deleted file mode 100644 index f310de29..00000000 --- a/extra_include/sys/iconvnls.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2003-2004, Artem B. Bityuckiy. - * Rights transferred to Franklin Electronic Publishers. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -/* - * Funtions, macros, etc implimented in iconv library but used by other - * NLS-related subsystems too. - */ -#ifndef __SYS_ICONVNLS_H__ -#define __SYS_ICONVNLS_H__ - -#include <_ansi.h> -#include -#include -#include - -/* Iconv data path environment variable name */ -#define NLS_ENVVAR_NAME "NLSPATH" -/* Default NLSPATH value */ -#define ICONV_DEFAULT_NLSPATH "/usr/locale" -/* Direction markers */ -#define ICONV_NLS_FROM 0 -#define ICONV_NLS_TO 1 - -_VOID -_EXFUN(_iconv_nls_get_state, (iconv_t cd, mbstate_t *ps, int direction)); - -int -_EXFUN(_iconv_nls_set_state, (iconv_t cd, mbstate_t *ps, int direction)); - -int -_EXFUN(_iconv_nls_is_stateful, (iconv_t cd, int direction)); - -int -_EXFUN(_iconv_nls_get_mb_cur_max, (iconv_t cd, int direction)); - -size_t -_EXFUN(_iconv_nls_conv, (struct _reent *rptr, iconv_t cd, - _CONST char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft)); - -_CONST char * -_EXFUN(_iconv_nls_construct_filename, (struct _reent *rptr, _CONST char *file, - _CONST char *dir, _CONST char *ext)); - - -int -_EXFUN(_iconv_nls_open, (struct _reent *rptr, _CONST char *encoding, - iconv_t *towc, iconv_t *fromwc, int flag)); - -char * -_EXFUN(_iconv_resolve_encoding_name, (struct _reent *rptr, _CONST char *ca)); - -#endif /* __SYS_ICONVNLS_H__ */ - diff --git a/extra_include/sys/lock.h b/extra_include/sys/lock.h deleted file mode 100644 index 0aed2e58..00000000 --- a/extra_include/sys/lock.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __SYS_LOCK_H__ -#define __SYS_LOCK_H__ - -/* dummy lock routines for single-threaded aps */ - -typedef int _LOCK_T; -typedef int _LOCK_RECURSIVE_T; - -#define __LOCK_INIT(class,lock) static int lock = 0; -#define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0; -#define __lock_init(lock) (0) -#define __lock_init_recursive(lock) (0) -#define __lock_close(lock) (0) -#define __lock_close_recursive(lock) (0) -#define __lock_acquire(lock) (0) -#define __lock_acquire_recursive(lock) (0) -#define __lock_try_acquire(lock) (0) -#define __lock_try_acquire_recursive(lock) (0) -#define __lock_release(lock) (0) -#define __lock_release_recursive(lock) (0) - -#endif /* __SYS_LOCK_H__ */ diff --git a/extra_include/sys/param.h b/extra_include/sys/param.h deleted file mode 100644 index 0abf08b1..00000000 --- a/extra_include/sys/param.h +++ /dev/null @@ -1,25 +0,0 @@ -/* This is a dummy file, not customized for any - particular system. If there is a param.h in libc/sys/SYSDIR/sys, - it will override this one. */ - -#ifndef _SYS_PARAM_H -# define _SYS_PARAM_H - -#include -#include -#include - -#ifndef HZ -# define HZ (60) -#endif -#ifndef NOFILE -# define NOFILE (60) -#endif -#ifndef PATHSIZE -# define PATHSIZE (1024) -#endif - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -#endif diff --git a/extra_include/sys/queue.h b/extra_include/sys/queue.h deleted file mode 100644 index d221bb11..00000000 --- a/extra_include/sys/queue.h +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.48 2002/04/17 14:00:37 tmm Exp $ - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -#include /* for __offsetof */ - -/* - * This file defines four types of data structures: singly-linked lists, - * singly-linked tail queues, lists and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ - * _HEAD + + + + - * _HEAD_INITIALIZER + + + + - * _ENTRY + + + + - * _INIT + + + + - * _EMPTY + + + + - * _FIRST + + + + - * _NEXT + + + + - * _PREV - - - + - * _LAST - - + + - * _FOREACH + + + + - * _FOREACH_REVERSE - - - + - * _INSERT_HEAD + + + + - * _INSERT_BEFORE - + - + - * _INSERT_AFTER + + + + - * _INSERT_TAIL - - + + - * _CONCAT - - + + - * _REMOVE_HEAD + - + - - * _REMOVE + + + + - * - */ - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ - } \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ -} while (0) - -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ -} while (0) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *) \ - ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ - } \ -} while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ -} while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - } \ -} while (0) - -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ -} while (0) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ -} while (0) - - -#ifdef _KERNEL - -/* - * XXX insque() and remque() are an old way of handling certain queues. - * They bogusly assumes that all queue heads look alike. - */ - -struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; -}; - -#ifdef __GNUC__ - -static __inline void -insque(void *a, void *b) -{ - struct quehead *element = (struct quehead *)a, - *head = (struct quehead *)b; - - element->qh_link = head->qh_link; - element->qh_rlink = head; - head->qh_link = element; - element->qh_link->qh_rlink = element; -} - -static __inline void -remque(void *a) -{ - struct quehead *element = (struct quehead *)a; - - element->qh_link->qh_rlink = element->qh_rlink; - element->qh_rlink->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -#else /* !__GNUC__ */ - -void insque(void *a, void *b); -void remque(void *a); - -#endif /* __GNUC__ */ - -#endif /* _KERNEL */ - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/extra_include/sys/reent.h b/extra_include/sys/reent.h deleted file mode 100644 index 8c39193f..00000000 --- a/extra_include/sys/reent.h +++ /dev/null @@ -1,824 +0,0 @@ -/* This header file provides the reentrancy. */ - -/* WARNING: All identifiers here must begin with an underscore. This file is - included by stdio.h and others and we therefore must only use identifiers - in the namespace allotted to us. */ - -#ifndef _SYS_REENT_H_ -#ifdef __cplusplus -extern "C" { -#endif -#define _SYS_REENT_H_ - -#include <_ansi.h> -#include - -#ifndef __Long -#if __LONG_MAX__ == 2147483647L -#define __Long long -typedef unsigned __Long __ULong; -#elif __INT_MAX__ == 2147483647 -#define __Long int -typedef unsigned __Long __ULong; -#endif -#endif - -#if !defined( __Long) -#include -#endif - -#ifndef __Long -#define __Long __int32_t -typedef __uint32_t __ULong; -#endif - -/* - * If _REENT_SMALL is defined, we make struct _reent as small as possible, - * by having nearly everything possible allocated at first use. - */ - -struct _Bigint -{ - struct _Bigint *_next; - int _k, _maxwds, _sign, _wds; - __ULong _x[1]; -}; - -/* needed by reentrant structure */ -struct __tm -{ - int __tm_sec; - int __tm_min; - int __tm_hour; - int __tm_mday; - int __tm_mon; - int __tm_year; - int __tm_wday; - int __tm_yday; - int __tm_isdst; -}; - -/* - * atexit() support. - */ - -#define _ATEXIT_SIZE 32 /* must be at least 32 to guarantee ANSI conformance */ - -struct _on_exit_args { - void * _fnargs[_ATEXIT_SIZE]; /* user fn args */ - void * _dso_handle[_ATEXIT_SIZE]; - /* Bitmask is set if user function takes arguments. */ - __ULong _fntypes; /* type of exit routine - - Must have at least _ATEXIT_SIZE bits */ - /* Bitmask is set if function was registered via __cxa_atexit. */ - __ULong _is_cxa; -}; - -#ifdef _REENT_SMALL -struct _atexit { - struct _atexit *_next; /* next in list */ - int _ind; /* next index in this table */ - void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */ - struct _on_exit_args * _on_exit_args_ptr; -}; -#else -struct _atexit { - struct _atexit *_next; /* next in list */ - int _ind; /* next index in this table */ - /* Some entries may already have been called, and will be NULL. */ - void (*_fns[_ATEXIT_SIZE])(void); /* the table itself */ - struct _on_exit_args _on_exit_args; -}; -#endif - -/* - * Stdio buffers. - * - * This and __FILE are defined here because we need them for struct _reent, - * but we don't want stdio.h included when stdlib.h is. - */ - -struct __sbuf { - unsigned char *_base; - int _size; -}; - -/* - * We need fpos_t for the following, but it doesn't have a leading "_", - * so we use _fpos_t instead. - */ - -typedef long _fpos_t; /* XXX must match off_t in */ - /* (and must be `long' for now) */ - -#ifdef __LARGE64_FILES -typedef _off64_t _fpos64_t; -#endif - -/* - * Stdio state variables. - * - * The following always hold: - * - * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), - * _lbfsize is -_bf._size, else _lbfsize is 0 - * if _flags&__SRD, _w is 0 - * if _flags&__SWR, _r is 0 - * - * This ensures that the getc and putc macros (or inline functions) never - * try to write or read from a file that is in `read' or `write' mode. - * (Moreover, they can, and do, automatically switch from read mode to - * write mode, and back, on "r+" and "w+" files.) - * - * _lbfsize is used only to make the inline line-buffered output stream - * code as compact as possible. - * - * _ub, _up, and _ur are used when ungetc() pushes back more characters - * than fit in the current _bf, or when ungetc() pushes back a character - * that does not match the previous one in _bf. When this happens, - * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff - * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. - */ - -#ifdef _REENT_SMALL -/* - * struct __sFILE_fake is the start of a struct __sFILE, with only the - * minimal fields allocated. In __sinit() we really allocate the 3 - * standard streams, etc., and point away from this fake. - */ -struct __sFILE_fake { - unsigned char *_p; /* current position in (some) buffer */ - int _r; /* read space left for getc() */ - int _w; /* write space left for putc() */ - short _flags; /* flags, below; this FILE is free if 0 */ - short _file; /* fileno, if Unix descriptor, else -1 */ - struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ - int _lbfsize; /* 0 or -_bf._size, for inline putc */ - - struct _reent *_data; -}; -/* CHECK_INIT() comes from stdio/local.h; be sure to include that. */ -# define _REENT_SMALL_CHECK_INIT(fp) CHECK_INIT(fp) -#else -# define _REENT_SMALL_CHECK_INIT(fp) /* nothing */ -#endif - -struct __sFILE { - unsigned char *_p; /* current position in (some) buffer */ - int _r; /* read space left for getc() */ - int _w; /* write space left for putc() */ - short _flags; /* flags, below; this FILE is free if 0 */ - short _file; /* fileno, if Unix descriptor, else -1 */ - struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ - int _lbfsize; /* 0 or -_bf._size, for inline putc */ - -#ifdef _REENT_SMALL - struct _reent *_data; -#endif - - /* operations */ - _PTR _cookie; /* cookie passed to io functions */ - - _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); - _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, - int _n)); - _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); - int _EXFUN((*_close),(_PTR _cookie)); - - /* separate buffer for long sequences of ungetc() */ - struct __sbuf _ub; /* ungetc buffer */ - unsigned char *_up; /* saved _p when _p is doing ungetc data */ - int _ur; /* saved _r when _r is counting ungetc data */ - - /* tricks to meet minimum requirements even when malloc() fails */ - unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ - unsigned char _nbuf[1]; /* guarantee a getc() buffer */ - - /* separate buffer for fgetline() when line crosses buffer boundary */ - struct __sbuf _lb; /* buffer for fgetline() */ - - /* Unix stdio files get aligned to block boundaries on fseek() */ - int _blksize; /* stat.st_blksize (may be != _bf._size) */ - int _offset; /* current lseek offset */ - -#ifndef _REENT_SMALL - struct _reent *_data; /* Here for binary compatibility? Remove? */ -#endif - -#ifndef __SINGLE_THREAD__ - _flock_t _lock; /* for thread-safety locking */ -#endif -}; - -#ifdef __LARGE64_FILES -struct __sFILE64 { - unsigned char *_p; /* current position in (some) buffer */ - int _r; /* read space left for getc() */ - int _w; /* write space left for putc() */ - short _flags; /* flags, below; this FILE is free if 0 */ - short _file; /* fileno, if Unix descriptor, else -1 */ - struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ - int _lbfsize; /* 0 or -_bf._size, for inline putc */ - - struct _reent *_data; - - /* operations */ - _PTR _cookie; /* cookie passed to io functions */ - - _READ_WRITE_RETURN_TYPE _EXFUN((*_read),(_PTR _cookie, char *_buf, int _n)); - _READ_WRITE_RETURN_TYPE _EXFUN((*_write),(_PTR _cookie, const char *_buf, - int _n)); - _fpos_t _EXFUN((*_seek),(_PTR _cookie, _fpos_t _offset, int _whence)); - int _EXFUN((*_close),(_PTR _cookie)); - - /* separate buffer for long sequences of ungetc() */ - struct __sbuf _ub; /* ungetc buffer */ - unsigned char *_up; /* saved _p when _p is doing ungetc data */ - int _ur; /* saved _r when _r is counting ungetc data */ - - /* tricks to meet minimum requirements even when malloc() fails */ - unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ - unsigned char _nbuf[1]; /* guarantee a getc() buffer */ - - /* separate buffer for fgetline() when line crosses buffer boundary */ - struct __sbuf _lb; /* buffer for fgetline() */ - - /* Unix stdio files get aligned to block boundaries on fseek() */ - int _blksize; /* stat.st_blksize (may be != _bf._size) */ - int _flags2; /* for future use */ - - _off64_t _offset; /* current lseek offset */ - _fpos64_t _EXFUN((*_seek64),(_PTR _cookie, _fpos64_t _offset, int _whence)); - -#ifndef __SINGLE_THREAD__ - _flock_t _lock; /* for thread-safety locking */ -#endif -}; -typedef struct __sFILE64 __FILE; -#else -typedef struct __sFILE __FILE; -#endif /* __LARGE64_FILES */ - -struct _glue -{ - struct _glue *_next; - int _niobs; - __FILE *_iobs; -}; - -/* - * rand48 family support - * - * Copyright (c) 1993 Martin Birgmeier - * All rights reserved. - * - * You may redistribute unmodified or modified versions of this source - * code provided that the above copyright notice and this and the - * following conditions are retained. - * - * This software is provided ``as is'', and comes with no warranties - * of any kind. I shall in no event be liable for anything that happens - * to anyone/anything when using this software. - */ -#define _RAND48_SEED_0 (0x330e) -#define _RAND48_SEED_1 (0xabcd) -#define _RAND48_SEED_2 (0x1234) -#define _RAND48_MULT_0 (0xe66d) -#define _RAND48_MULT_1 (0xdeec) -#define _RAND48_MULT_2 (0x0005) -#define _RAND48_ADD (0x000b) -struct _rand48 { - unsigned short _seed[3]; - unsigned short _mult[3]; - unsigned short _add; -#ifdef _REENT_SMALL - /* Put this in here as well, for good luck. */ - __extension__ unsigned long long _rand_next; -#endif -}; - -/* How big the some arrays are. */ -#define _REENT_EMERGENCY_SIZE 25 -#define _REENT_ASCTIME_SIZE 26 -#define _REENT_SIGNAL_SIZE 24 - -/* - * struct _reent - * - * This structure contains *all* globals needed by the library. - * It's raison d'etre is to facilitate threads by making all library routines - * reentrant. IE: All state information is contained here. - */ - -#ifdef _REENT_SMALL - -struct _mprec -{ - /* used by mprec routines */ - struct _Bigint *_result; - int _result_k; - struct _Bigint *_p5s; - struct _Bigint **_freelist; -}; - - -struct _misc_reent -{ - /* miscellaneous reentrant data */ - char *_strtok_last; - _mbstate_t _mblen_state; - _mbstate_t _wctomb_state; - _mbstate_t _mbtowc_state; - char _l64a_buf[8]; - int _getdate_err; - _mbstate_t _mbrlen_state; - _mbstate_t _mbrtowc_state; - _mbstate_t _mbsrtowcs_state; - _mbstate_t _wcrtomb_state; - _mbstate_t _wcsrtombs_state; -}; - -/* This version of _reent is layed our with "int"s in pairs, to help - * ports with 16-bit int's but 32-bit pointers, align nicely. */ -struct _reent -{ - - /* FILE is a big struct and may change over time. To try to achieve binary - compatibility with future versions, put stdin,stdout,stderr here. - These are pointers into member __sf defined below. */ - __FILE *_stdin, *_stdout, *_stderr; /* XXX */ - - int _errno; /* local copy of errno */ - - int _inc; /* used by tmpnam */ - - char *_emergency; - - int __sdidinit; /* 1 means stdio has been init'd */ - - int _current_category; /* used by setlocale */ - _CONST char *_current_locale; - - struct _mprec *_mp; - - void _EXFUN((*__cleanup),(struct _reent *)); - - int _gamma_signgam; - - /* used by some fp conversion routines */ - int _cvtlen; /* should be size_t */ - char *_cvtbuf; - - struct _rand48 *_r48; - struct __tm *_localtime_buf; - char *_asctime_buf; - - /* signal info */ - void (**(_sig_func))(int); - - /* atexit stuff */ - struct _atexit *_atexit; - struct _atexit _atexit0; - - struct _glue __sglue; /* root of glue chain */ - __FILE *__sf; /* file descriptors */ - struct __sFILE_fake __sf_fake; /* fake initial stdin/out/err */ - struct _misc_reent *_misc; /* strtok, multibyte states */ - char *_signal_buf; /* strsignal */ -}; - -#define _REENT_INIT(var) \ - { (__FILE *)&var.__sf_fake, \ - (__FILE *)&var.__sf_fake, \ - (__FILE *)&var.__sf_fake, \ - 0, \ - 0, \ - _NULL, \ - 0, \ - 0, \ - "C", \ - _NULL, \ - _NULL, \ - 0, \ - 0, \ - _NULL, \ - _NULL, \ - _NULL, \ - _NULL, \ - _NULL, \ - _NULL, \ - {_NULL, 0, {_NULL}, _NULL}, \ - {_NULL, 0, _NULL}, \ - _NULL, \ - {_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL}, \ - _NULL, \ - _NULL \ - } - -#define _REENT_INIT_PTR(var) \ - { var->_stdin = (__FILE *)&var->__sf_fake; \ - var->_stdout = (__FILE *)&var->__sf_fake; \ - var->_stderr = (__FILE *)&var->__sf_fake; \ - var->_errno = 0; \ - var->_inc = 0; \ - var->_emergency = _NULL; \ - var->__sdidinit = 0; \ - var->_current_category = 0; \ - var->_current_locale = "C"; \ - var->_mp = _NULL; \ - var->__cleanup = _NULL; \ - var->_gamma_signgam = 0; \ - var->_cvtlen = 0; \ - var->_cvtbuf = _NULL; \ - var->_r48 = _NULL; \ - var->_localtime_buf = _NULL; \ - var->_asctime_buf = _NULL; \ - var->_sig_func = _NULL; \ - var->_atexit = _NULL; \ - var->_atexit0._next = _NULL; \ - var->_atexit0._ind = 0; \ - var->_atexit0._fns[0] = _NULL; \ - var->_atexit0._on_exit_args_ptr = _NULL; \ - var->__sglue._next = _NULL; \ - var->__sglue._niobs = 0; \ - var->__sglue._iobs = _NULL; \ - var->__sf = 0; \ - var->__sf_fake._p = _NULL; \ - var->__sf_fake._r = 0; \ - var->__sf_fake._w = 0; \ - var->__sf_fake._flags = 0; \ - var->__sf_fake._file = 0; \ - var->__sf_fake._bf._base = _NULL; \ - var->__sf_fake._bf._size = 0; \ - var->__sf_fake._lbfsize = 0; \ - var->__sf_fake._data = _NULL; \ - var->_misc = _NULL; \ - var->_signal_buf = _NULL; \ - } - -/* Only built the assert() calls if we are built with debugging. */ -#if DEBUG -#include -#else -#define assert(x) ((void)0) -#endif - -/* Generic _REENT check macro. */ -#define _REENT_CHECK(var, what, type, size, init) do { \ - struct _reent *_r = (var); \ - if (_r->what == NULL) { \ - _r->what = (type)malloc(size); \ - assert(_r->what); \ - init; \ - } \ -} while (0) - -#define _REENT_CHECK_TM(var) \ - _REENT_CHECK(var, _localtime_buf, struct __tm *, sizeof *((var)->_localtime_buf), \ - /* nothing */) - -#define _REENT_CHECK_ASCTIME_BUF(var) \ - _REENT_CHECK(var, _asctime_buf, char *, _REENT_ASCTIME_SIZE, \ - memset((var)->_asctime_buf, 0, _REENT_ASCTIME_SIZE)) - -/* Handle the dynamically allocated rand48 structure. */ -#define _REENT_INIT_RAND48(var) do { \ - struct _reent *_r = (var); \ - _r->_r48->_seed[0] = _RAND48_SEED_0; \ - _r->_r48->_seed[1] = _RAND48_SEED_1; \ - _r->_r48->_seed[2] = _RAND48_SEED_2; \ - _r->_r48->_mult[0] = _RAND48_MULT_0; \ - _r->_r48->_mult[1] = _RAND48_MULT_1; \ - _r->_r48->_mult[2] = _RAND48_MULT_2; \ - _r->_r48->_add = _RAND48_ADD; \ -} while (0) -#define _REENT_CHECK_RAND48(var) \ - _REENT_CHECK(var, _r48, struct _rand48 *, sizeof *((var)->_r48), _REENT_INIT_RAND48((var))) - -#define _REENT_INIT_MP(var) do { \ - struct _reent *_r = (var); \ - _r->_mp->_result_k = 0; \ - _r->_mp->_result = _r->_mp->_p5s = _NULL; \ - _r->_mp->_freelist = _NULL; \ -} while (0) -#define _REENT_CHECK_MP(var) \ - _REENT_CHECK(var, _mp, struct _mprec *, sizeof *((var)->_mp), _REENT_INIT_MP(var)) - -#define _REENT_CHECK_EMERGENCY(var) \ - _REENT_CHECK(var, _emergency, char *, _REENT_EMERGENCY_SIZE, /* nothing */) - -#define _REENT_INIT_MISC(var) do { \ - struct _reent *_r = (var); \ - _r->_misc->_strtok_last = _NULL; \ - _r->_misc->_mblen_state.__count = 0; \ - _r->_misc->_mblen_state.__value.__wch = 0; \ - _r->_misc->_wctomb_state.__count = 0; \ - _r->_misc->_wctomb_state.__value.__wch = 0; \ - _r->_misc->_mbtowc_state.__count = 0; \ - _r->_misc->_mbtowc_state.__value.__wch = 0; \ - _r->_misc->_mbrlen_state.__count = 0; \ - _r->_misc->_mbrlen_state.__value.__wch = 0; \ - _r->_misc->_mbrtowc_state.__count = 0; \ - _r->_misc->_mbrtowc_state.__value.__wch = 0; \ - _r->_misc->_mbsrtowcs_state.__count = 0; \ - _r->_misc->_mbsrtowcs_state.__value.__wch = 0; \ - _r->_misc->_wcrtomb_state.__count = 0; \ - _r->_misc->_wcrtomb_state.__value.__wch = 0; \ - _r->_misc->_wcsrtombs_state.__count = 0; \ - _r->_misc->_wcsrtombs_state.__value.__wch = 0; \ - _r->_misc->_l64a_buf[0] = '\0'; \ - _r->_misc->_getdate_err = 0; \ -} while (0) -#define _REENT_CHECK_MISC(var) \ - _REENT_CHECK(var, _misc, struct _misc_reent *, sizeof *((var)->_misc), _REENT_INIT_MISC(var)) - -#define _REENT_CHECK_SIGNAL_BUF(var) \ - _REENT_CHECK(var, _signal_buf, char *, _REENT_SIGNAL_SIZE, /* nothing */) - -#define _REENT_SIGNGAM(ptr) ((ptr)->_gamma_signgam) -#define _REENT_RAND_NEXT(ptr) ((ptr)->_r48->_rand_next) -#define _REENT_RAND48_SEED(ptr) ((ptr)->_r48->_seed) -#define _REENT_RAND48_MULT(ptr) ((ptr)->_r48->_mult) -#define _REENT_RAND48_ADD(ptr) ((ptr)->_r48->_add) -#define _REENT_MP_RESULT(ptr) ((ptr)->_mp->_result) -#define _REENT_MP_RESULT_K(ptr) ((ptr)->_mp->_result_k) -#define _REENT_MP_P5S(ptr) ((ptr)->_mp->_p5s) -#define _REENT_MP_FREELIST(ptr) ((ptr)->_mp->_freelist) -#define _REENT_ASCTIME_BUF(ptr) ((ptr)->_asctime_buf) -#define _REENT_TM(ptr) ((ptr)->_localtime_buf) -#define _REENT_EMERGENCY(ptr) ((ptr)->_emergency) -#define _REENT_STRTOK_LAST(ptr) ((ptr)->_misc->_strtok_last) -#define _REENT_MBLEN_STATE(ptr) ((ptr)->_misc->_mblen_state) -#define _REENT_MBTOWC_STATE(ptr)((ptr)->_misc->_mbtowc_state) -#define _REENT_WCTOMB_STATE(ptr)((ptr)->_misc->_wctomb_state) -#define _REENT_MBRLEN_STATE(ptr) ((ptr)->_misc->_mbrlen_state) -#define _REENT_MBRTOWC_STATE(ptr) ((ptr)->_misc->_mbrtowc_state) -#define _REENT_MBSRTOWCS_STATE(ptr) ((ptr)->_misc->_mbsrtowcs_state) -#define _REENT_WCRTOMB_STATE(ptr) ((ptr)->_misc->_wcrtomb_state) -#define _REENT_WCSRTOMBS_STATE(ptr) ((ptr)->_misc->_wcsrtombs_state) -#define _REENT_L64A_BUF(ptr) ((ptr)->_misc->_l64a_buf) -#define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_misc->_getdate_err)) -#define _REENT_SIGNAL_BUF(ptr) ((ptr)->_signal_buf) - -#else /* !_REENT_SMALL */ - -struct _reent -{ - int _errno; /* local copy of errno */ - - /* FILE is a big struct and may change over time. To try to achieve binary - compatibility with future versions, put stdin,stdout,stderr here. - These are pointers into member __sf defined below. */ - __FILE *_stdin, *_stdout, *_stderr; - - int _inc; /* used by tmpnam */ - char _emergency[_REENT_EMERGENCY_SIZE]; - - int _current_category; /* used by setlocale */ - _CONST char *_current_locale; - - int __sdidinit; /* 1 means stdio has been init'd */ - - void _EXFUN((*__cleanup),(struct _reent *)); - - /* used by mprec routines */ - struct _Bigint *_result; - int _result_k; - struct _Bigint *_p5s; - struct _Bigint **_freelist; - - /* used by some fp conversion routines */ - int _cvtlen; /* should be size_t */ - char *_cvtbuf; - - union - { - struct - { - unsigned int _unused_rand; - char * _strtok_last; - char _asctime_buf[_REENT_ASCTIME_SIZE]; - struct __tm _localtime_buf; - int _gamma_signgam; - __extension__ unsigned long long _rand_next; - struct _rand48 _r48; - _mbstate_t _mblen_state; - _mbstate_t _mbtowc_state; - _mbstate_t _wctomb_state; - char _l64a_buf[8]; - char _signal_buf[_REENT_SIGNAL_SIZE]; - int _getdate_err; - _mbstate_t _mbrlen_state; - _mbstate_t _mbrtowc_state; - _mbstate_t _mbsrtowcs_state; - _mbstate_t _wcrtomb_state; - _mbstate_t _wcsrtombs_state; - } _reent; - /* Two next two fields were once used by malloc. They are no longer - used. They are used to preserve the space used before so as to - allow addition of new reent fields and keep binary compatibility. */ - struct - { -#define _N_LISTS 30 - unsigned char * _nextf[_N_LISTS]; - unsigned int _nmalloc[_N_LISTS]; - } _unused; - } _new; - - /* atexit stuff */ - struct _atexit *_atexit; /* points to head of LIFO stack */ - struct _atexit _atexit0; /* one guaranteed table, required by ANSI */ - - /* signal info */ - void (**(_sig_func))(int); - - /* These are here last so that __FILE can grow without changing the offsets - of the above members (on the off chance that future binary compatibility - would be broken otherwise). */ - struct _glue __sglue; /* root of glue chain */ - __FILE __sf[3]; /* first three file descriptors */ -}; - -#define _REENT_INIT(var) \ - { 0, \ - &var.__sf[0], \ - &var.__sf[1], \ - &var.__sf[2], \ - 0, \ - "", \ - 0, \ - "C", \ - 0, \ - _NULL, \ - _NULL, \ - 0, \ - _NULL, \ - _NULL, \ - 0, \ - _NULL, \ - { \ - { \ - 0, \ - _NULL, \ - "", \ - {0, 0, 0, 0, 0, 0, 0, 0, 0}, \ - 0, \ - 1, \ - { \ - {_RAND48_SEED_0, _RAND48_SEED_1, _RAND48_SEED_2}, \ - {_RAND48_MULT_0, _RAND48_MULT_1, _RAND48_MULT_2}, \ - _RAND48_ADD \ - }, \ - {0, {0}}, \ - {0, {0}}, \ - {0, {0}}, \ - "", \ - "", \ - 0, \ - {0, {0}}, \ - {0, {0}}, \ - {0, {0}}, \ - {0, {0}}, \ - {0, {0}} \ - } \ - }, \ - _NULL, \ - {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}, \ - _NULL, \ - {_NULL, 0, _NULL} \ - } - -#define _REENT_INIT_PTR(var) \ - { var->_errno = 0; \ - var->_stdin = &var->__sf[0]; \ - var->_stdout = &var->__sf[1]; \ - var->_stderr = &var->__sf[2]; \ - var->_inc = 0; \ - memset(&var->_emergency, 0, sizeof(var->_emergency)); \ - var->_current_category = 0; \ - var->_current_locale = "C"; \ - var->__sdidinit = 0; \ - var->__cleanup = _NULL; \ - var->_result = _NULL; \ - var->_result_k = 0; \ - var->_p5s = _NULL; \ - var->_freelist = _NULL; \ - var->_cvtlen = 0; \ - var->_cvtbuf = _NULL; \ - var->_new._reent._unused_rand = 0; \ - var->_new._reent._strtok_last = _NULL; \ - var->_new._reent._asctime_buf[0] = 0; \ - memset(&var->_new._reent._localtime_buf, 0, sizeof(var->_new._reent._localtime_buf)); \ - var->_new._reent._gamma_signgam = 0; \ - var->_new._reent._rand_next = 1; \ - var->_new._reent._r48._seed[0] = _RAND48_SEED_0; \ - var->_new._reent._r48._seed[1] = _RAND48_SEED_1; \ - var->_new._reent._r48._seed[2] = _RAND48_SEED_2; \ - var->_new._reent._r48._mult[0] = _RAND48_MULT_0; \ - var->_new._reent._r48._mult[1] = _RAND48_MULT_1; \ - var->_new._reent._r48._mult[2] = _RAND48_MULT_2; \ - var->_new._reent._r48._add = _RAND48_ADD; \ - var->_new._reent._mblen_state.__count = 0; \ - var->_new._reent._mblen_state.__value.__wch = 0; \ - var->_new._reent._mbtowc_state.__count = 0; \ - var->_new._reent._mbtowc_state.__value.__wch = 0; \ - var->_new._reent._wctomb_state.__count = 0; \ - var->_new._reent._wctomb_state.__value.__wch = 0; \ - var->_new._reent._mbrlen_state.__count = 0; \ - var->_new._reent._mbrlen_state.__value.__wch = 0; \ - var->_new._reent._mbrtowc_state.__count = 0; \ - var->_new._reent._mbrtowc_state.__value.__wch = 0; \ - var->_new._reent._mbsrtowcs_state.__count = 0; \ - var->_new._reent._mbsrtowcs_state.__value.__wch = 0; \ - var->_new._reent._wcrtomb_state.__count = 0; \ - var->_new._reent._wcrtomb_state.__value.__wch = 0; \ - var->_new._reent._wcsrtombs_state.__count = 0; \ - var->_new._reent._wcsrtombs_state.__value.__wch = 0; \ - var->_new._reent._l64a_buf[0] = '\0'; \ - var->_new._reent._signal_buf[0] = '\0'; \ - var->_new._reent._getdate_err = 0; \ - var->_atexit = _NULL; \ - var->_atexit0._next = _NULL; \ - var->_atexit0._ind = 0; \ - var->_atexit0._fns[0] = _NULL; \ - var->_atexit0._on_exit_args._fntypes = 0; \ - var->_atexit0._on_exit_args._fnargs[0] = _NULL; \ - var->_sig_func = _NULL; \ - var->__sglue._next = _NULL; \ - var->__sglue._niobs = 0; \ - var->__sglue._iobs = _NULL; \ - memset(&var->__sf, 0, sizeof(var->__sf)); \ - } - -#define _REENT_CHECK_RAND48(ptr) /* nothing */ -#define _REENT_CHECK_MP(ptr) /* nothing */ -#define _REENT_CHECK_TM(ptr) /* nothing */ -#define _REENT_CHECK_ASCTIME_BUF(ptr) /* nothing */ -#define _REENT_CHECK_EMERGENCY(ptr) /* nothing */ -#define _REENT_CHECK_MISC(ptr) /* nothing */ -#define _REENT_CHECK_SIGNAL_BUF(ptr) /* nothing */ - -#define _REENT_SIGNGAM(ptr) ((ptr)->_new._reent._gamma_signgam) -#define _REENT_RAND_NEXT(ptr) ((ptr)->_new._reent._rand_next) -#define _REENT_RAND48_SEED(ptr) ((ptr)->_new._reent._r48._seed) -#define _REENT_RAND48_MULT(ptr) ((ptr)->_new._reent._r48._mult) -#define _REENT_RAND48_ADD(ptr) ((ptr)->_new._reent._r48._add) -#define _REENT_MP_RESULT(ptr) ((ptr)->_result) -#define _REENT_MP_RESULT_K(ptr) ((ptr)->_result_k) -#define _REENT_MP_P5S(ptr) ((ptr)->_p5s) -#define _REENT_MP_FREELIST(ptr) ((ptr)->_freelist) -#define _REENT_ASCTIME_BUF(ptr) ((ptr)->_new._reent._asctime_buf) -#define _REENT_TM(ptr) (&(ptr)->_new._reent._localtime_buf) -#define _REENT_EMERGENCY(ptr) ((ptr)->_emergency) -#define _REENT_STRTOK_LAST(ptr) ((ptr)->_new._reent._strtok_last) -#define _REENT_MBLEN_STATE(ptr) ((ptr)->_new._reent._mblen_state) -#define _REENT_MBTOWC_STATE(ptr)((ptr)->_new._reent._mbtowc_state) -#define _REENT_WCTOMB_STATE(ptr)((ptr)->_new._reent._wctomb_state) -#define _REENT_MBRLEN_STATE(ptr)((ptr)->_new._reent._mbrlen_state) -#define _REENT_MBRTOWC_STATE(ptr)((ptr)->_new._reent._mbrtowc_state) -#define _REENT_MBSRTOWCS_STATE(ptr)((ptr)->_new._reent._mbsrtowcs_state) -#define _REENT_WCRTOMB_STATE(ptr)((ptr)->_new._reent._wcrtomb_state) -#define _REENT_WCSRTOMBS_STATE(ptr)((ptr)->_new._reent._wcsrtombs_state) -#define _REENT_L64A_BUF(ptr) ((ptr)->_new._reent._l64a_buf) -#define _REENT_SIGNAL_BUF(ptr) ((ptr)->_new._reent._signal_buf) -#define _REENT_GETDATE_ERR_P(ptr) (&((ptr)->_new._reent._getdate_err)) - -#endif /* !_REENT_SMALL */ - -#define _NULL 0 - -/* - * All references to struct _reent are via this pointer. - * Internally, newlib routines that need to reference it should use _REENT. - */ - -#ifndef __ATTRIBUTE_IMPURE_PTR__ -#define __ATTRIBUTE_IMPURE_PTR__ -#endif - -extern struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__; -extern struct _reent *_CONST _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__; - -void _reclaim_reent _PARAMS ((struct _reent *)); - -/* #define _REENT_ONLY define this to get only reentrant routines */ - -#ifndef _REENT_ONLY - -#if defined(__DYNAMIC_REENT__) && !defined(__SINGLE_THREAD__) -#ifndef __getreent - struct _reent * _EXFUN(__getreent, (void)); -#endif -# define _REENT (__getreent()) -#else /* __SINGLE_THREAD__ || !__DYNAMIC_REENT__ */ -# define _REENT _impure_ptr -#endif /* __SINGLE_THREAD__ || !__DYNAMIC_REENT__ */ - -#endif /* !_REENT_ONLY */ - -#define _GLOBAL_REENT _global_impure_ptr - -#ifdef __cplusplus -} -#endif -#endif /* _SYS_REENT_H_ */ diff --git a/extra_include/sys/resource.h b/extra_include/sys/resource.h deleted file mode 100644 index 152e331f..00000000 --- a/extra_include/sys/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _SYS_RESOURCE_H_ -#define _SYS_RESOURCE_H_ - -#include - -#define RUSAGE_SELF 0 /* calling process */ -#define RUSAGE_CHILDREN -1 /* terminated child processes */ - -struct rusage { - struct timeval ru_utime; /* user time used */ - struct timeval ru_stime; /* system time used */ -}; - -#endif - diff --git a/extra_include/sys/sched.h b/extra_include/sys/sched.h deleted file mode 100644 index bb226c5a..00000000 --- a/extra_include/sys/sched.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Written by Joel Sherrill . - * - * COPYRIGHT (c) 1989-2000. - * On-Line Applications Research Corporation (OAR). - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION - * OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS - * SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - * $Id: sched.h,v 1.2 2002/06/20 19:51:24 fitzsim Exp $ - */ - - -#ifndef __POSIX_SYS_SCHEDULING_h -#define __POSIX_SYS_SCHEDULING_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include - -/* Scheduling Policies, P1003.1b-1993, p. 250 - NOTE: SCHED_SPORADIC added by P1003.4b/D8, p. 34. */ - -#define SCHED_OTHER 0 -#define SCHED_FIFO 1 -#define SCHED_RR 2 - -#if defined(_POSIX_SPORADIC_SERVER) -#define SCHED_SPORADIC 3 -#endif - -/* Scheduling Parameters, P1003.1b-1993, p. 249 - NOTE: Fields whose name begins with "ss_" added by P1003.4b/D8, p. 33. */ - -struct sched_param { - int sched_priority; /* Process execution scheduling priority */ - -#if defined(_POSIX_SPORADIC_SERVER) - int ss_low_priority; /* Low scheduling priority for sporadic */ - /* server */ - struct timespec ss_replenish_period; - /* Replenishment period for sporadic server */ - struct timespec ss_initial_budget; /* Initial budget for sporadic server */ -#endif -}; - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ - diff --git a/extra_include/sys/signal.h b/extra_include/sys/signal.h deleted file mode 100644 index 01f63c75..00000000 --- a/extra_include/sys/signal.h +++ /dev/null @@ -1,310 +0,0 @@ -/* sys/signal.h */ - -#ifndef _SYS_SIGNAL_H -#define _SYS_SIGNAL_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "_ansi.h" -#include - -/* #ifndef __STRICT_ANSI__*/ - -#if defined(_POSIX_THREADS) -#include /* for pthread data types */ -#endif - -typedef unsigned long sigset_t; - -#if defined(__rtems__) - -#if defined(_POSIX_REALTIME_SIGNALS) - -/* sigev_notify values - NOTE: P1003.1c/D10, p. 34 adds SIGEV_THREAD. */ - -#define SIGEV_NONE 1 /* No asynchronous notification shall be delivered */ - /* when the event of interest occurs. */ -#define SIGEV_SIGNAL 2 /* A queued signal, with an application defined */ - /* value, shall be delivered when the event of */ - /* interest occurs. */ -#define SIGEV_THREAD 3 /* A notification function shall be called to */ - /* perform notification. */ - -/* Signal Generation and Delivery, P1003.1b-1993, p. 63 - NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and - sigev_notify_attributes to the sigevent structure. */ - -union sigval { - int sival_int; /* Integer signal value */ - void *sival_ptr; /* Pointer signal value */ -}; - -struct sigevent { - int sigev_notify; /* Notification type */ - int sigev_signo; /* Signal number */ - union sigval sigev_value; /* Signal value */ - -#if defined(_POSIX_THREADS) - void (*sigev_notify_function)( union sigval ); - /* Notification function */ - pthread_attr_t *sigev_notify_attributes; /* Notification Attributes */ -#endif -}; - -/* Signal Actions, P1003.1b-1993, p. 64 */ -/* si_code values, p. 66 */ - -#define SI_USER 1 /* Sent by a user. kill(), abort(), etc */ -#define SI_QUEUE 2 /* Sent by sigqueue() */ -#define SI_TIMER 3 /* Sent by expiration of a timer_settime() timer */ -#define SI_ASYNCIO 4 /* Indicates completion of asycnhronous IO */ -#define SI_MESGQ 5 /* Indicates arrival of a message at an empty queue */ - -typedef struct { - int si_signo; /* Signal number */ - int si_code; /* Cause of the signal */ - union sigval si_value; /* Signal value */ -} siginfo_t; -#endif - -/* 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 */ - -#define SA_NOCLDSTOP 1 /* Do not generate SIGCHLD when children stop */ -#define SA_SIGINFO 2 /* Invoke the signal catching function with */ - /* three arguments instead of one. */ - -/* struct sigaction notes from POSIX: - * - * (1) Routines stored in sa_handler should take a single int as - * their argument although the POSIX standard does not require this. - * (2) The fields sa_handler and sa_sigaction may overlap, and a conforming - * application should not use both simultaneously. - */ - -typedef void (*_sig_func_ptr)(); - -struct sigaction { - int sa_flags; /* Special flags to affect behavior of signal */ - sigset_t sa_mask; /* Additional set of signals to be blocked */ - /* during execution of signal-catching */ - /* function. */ - union { - _sig_func_ptr _handler; /* SIG_DFL, SIG_IGN, or pointer to a function */ -#if defined(_POSIX_REALTIME_SIGNALS) - void (*_sigaction)( int, siginfo_t *, void * ); -#endif - } _signal_handlers; -}; - -#define sa_handler _signal_handlers._handler -#if defined(_POSIX_REALTIME_SIGNALS) -#define sa_sigaction _signal_handlers._sigaction -#endif - -#elif defined(__CYGWIN__) -#include -#else -#define SA_NOCLDSTOP 1 /* only value supported now for sa_flags */ - -typedef void (*_sig_func_ptr)(int); - -struct sigaction -{ - _sig_func_ptr sa_handler; - sigset_t sa_mask; - int sa_flags; -}; -#endif /* defined(__rtems__) */ - -#define SIG_SETMASK 0 /* set mask with sigprocmask() */ -#define SIG_BLOCK 1 /* set of signals to block */ -#define SIG_UNBLOCK 2 /* set of signals to, well, unblock */ - -/* These depend upon the type of sigset_t, which right now - is always a long.. They're in the POSIX namespace, but - are not ANSI. */ -#define sigaddset(what,sig) (*(what) |= (1<<(sig))) -#define sigemptyset(what) (*(what) = 0) - -int _EXFUN(sigprocmask, (int how, const sigset_t *set, sigset_t *oset)); - -#if defined(_POSIX_THREADS) -int _EXFUN(pthread_sigmask, (int how, const sigset_t *set, sigset_t *oset)); -#endif - -/* protos for functions found in winsup sources for CYGWIN */ -#if defined(__CYGWIN__) || defined(__rtems__) -#undef sigaddset -#undef sigemptyset -/* The first argument to kill should be pid_t. Right now - always defines pid_t to be int. If that ever - changes, then we will need to do something else, perhaps along the - lines of . */ -int _EXFUN(kill, (int, int)); -int _EXFUN(killpg, (pid_t, int)); -int _EXFUN(sigaction, (int, const struct sigaction *, struct sigaction *)); -int _EXFUN(sigaddset, (sigset_t *, const int)); -int _EXFUN(sigdelset, (sigset_t *, const int)); -int _EXFUN(sigismember, (const sigset_t *, int)); -int _EXFUN(sigfillset, (sigset_t *)); -int _EXFUN(sigemptyset, (sigset_t *)); -int _EXFUN(sigpending, (sigset_t *)); -int _EXFUN(sigsuspend, (const sigset_t *)); -int _EXFUN(sigpause, (int)); - -#if defined(_POSIX_THREADS) -#ifdef __CYGWIN__ -# ifndef _CYGWIN_TYPES_H -# error You need the winsup sources or a cygwin installation to compile the cygwin version of newlib. -# endif -#endif -int _EXFUN(pthread_kill, (pthread_t thread, int sig)); -#endif - -#if defined(_POSIX_REALTIME_SIGNALS) - -/* 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 - NOTE: P1003.1c/D10, p. 39 adds sigwait(). */ - -int _EXFUN(sigwaitinfo, (const sigset_t *set, siginfo_t *info)); -int _EXFUN(sigtimedwait, - (const sigset_t *set, siginfo_t *info, const struct timespec *timeout) -); -int _EXFUN(sigwait, (const sigset_t *set, int *sig)); - -/* 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 */ -int _EXFUN(sigqueue, (pid_t pid, int signo, const union sigval value)); - -#endif /* defined(_POSIX_REALTIME_SIGNALS) */ - -#endif /* defined(__CYGWIN__) || defined(__rtems__) */ - -/* #endif __STRICT_ANSI__ */ - -#if defined(___AM29K__) -/* These all need to be defined for ANSI C, but I don't think they are - meaningful. */ -#define SIGABRT 1 -#define SIGFPE 1 -#define SIGILL 1 -#define SIGINT 1 -#define SIGSEGV 1 -#define SIGTERM 1 -/* These need to be defined for POSIX, and some others do too. */ -#define SIGHUP 1 -#define SIGQUIT 1 -#define NSIG 2 -#elif defined(__GO32__) -#define SIGINT 1 -#define SIGKILL 2 -#define SIGPIPE 3 -#define SIGFPE 4 -#define SIGHUP 5 -#define SIGTERM 6 -#define SIGSEGV 7 -#define SIGTSTP 8 -#define SIGQUIT 9 -#define SIGTRAP 10 -#define SIGILL 11 -#define SIGEMT 12 -#define SIGALRM 13 -#define SIGBUS 14 -#define SIGLOST 15 -#define SIGSTOP 16 -#define SIGABRT 17 -#define SIGUSR1 18 -#define SIGUSR2 19 -#define NSIG 20 -#elif !defined(SIGTRAP) -#define SIGHUP 1 /* hangup */ -#define SIGINT 2 /* interrupt */ -#define SIGQUIT 3 /* quit */ -#define SIGILL 4 /* illegal instruction (not reset when caught) */ -#define SIGTRAP 5 /* trace trap (not reset when caught) */ -#define SIGIOT 6 /* IOT instruction */ -#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */ -#define SIGEMT 7 /* EMT instruction */ -#define SIGFPE 8 /* floating point exception */ -#define SIGKILL 9 /* kill (cannot be caught or ignored) */ -#define SIGBUS 10 /* bus error */ -#define SIGSEGV 11 /* segmentation violation */ -#define SIGSYS 12 /* bad argument to system call */ -#define SIGPIPE 13 /* write on a pipe with no one to read it */ -#define SIGALRM 14 /* alarm clock */ -#define SIGTERM 15 /* software termination signal from kill */ - -#if defined(__rtems__) -#define SIGURG 16 /* urgent condition on IO channel */ -#define SIGSTOP 17 /* sendable stop signal not from tty */ -#define SIGTSTP 18 /* stop signal from tty */ -#define SIGCONT 19 /* continue a stopped process */ -#define SIGCHLD 20 /* to parent on child stop or exit */ -#define SIGCLD 20 /* System V name for SIGCHLD */ -#define SIGTTIN 21 /* to readers pgrp upon background tty read */ -#define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ -#define SIGIO 23 /* input/output possible signal */ -#define SIGPOLL SIGIO /* System V name for SIGIO */ -#define SIGWINCH 24 /* window changed */ -#define SIGUSR1 25 /* user defined signal 1 */ -#define SIGUSR2 26 /* user defined signal 2 */ - -/* Real-Time Signals Range, P1003.1b-1993, p. 61 - NOTE: By P1003.1b-1993, this should be at least RTSIG_MAX - (which is a minimum of 8) signals. - */ -#define SIGRTMIN 27 -#define SIGRTMAX 31 -#define __SIGFIRSTNOTRT SIGHUP -#define __SIGLASTNOTRT SIGUSR2 - -#define NSIG 32 /* signal 0 implied */ - -#elif defined(__svr4__) -/* svr4 specifics. different signals above 15, and sigaction. */ -#define SIGUSR1 16 -#define SIGUSR2 17 -#define SIGCLD 18 -#define SIGPWR 19 -#define SIGWINCH 20 -#define SIGPOLL 22 /* 20 for x.out binaries!!!! */ -#define SIGSTOP 23 /* sendable stop signal not from tty */ -#define SIGTSTP 24 /* stop signal from tty */ -#define SIGCONT 25 /* continue a stopped process */ -#define SIGTTIN 26 /* to readers pgrp upon background tty read */ -#define SIGTTOU 27 /* like TTIN for output if (tp->t_local<OSTOP) */ -#define NSIG 28 -#else -#define SIGURG 16 /* urgent condition on IO channel */ -#define SIGSTOP 17 /* sendable stop signal not from tty */ -#define SIGTSTP 18 /* stop signal from tty */ -#define SIGCONT 19 /* continue a stopped process */ -#define SIGCHLD 20 /* to parent on child stop or exit */ -#define SIGCLD 20 /* System V name for SIGCHLD */ -#define SIGTTIN 21 /* to readers pgrp upon background tty read */ -#define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ -#define SIGIO 23 /* input/output possible signal */ -#define SIGPOLL SIGIO /* System V name for SIGIO */ -#define SIGXCPU 24 /* exceeded CPU time limit */ -#define SIGXFSZ 25 /* exceeded file size limit */ -#define SIGVTALRM 26 /* virtual time alarm */ -#define SIGPROF 27 /* profiling time alarm */ -#define SIGWINCH 28 /* window changed */ -#define SIGLOST 29 /* resource lost (eg, record-lock lost) */ -#define SIGUSR1 30 /* user defined signal 1 */ -#define SIGUSR2 31 /* user defined signal 2 */ -#define NSIG 32 /* signal 0 implied */ -#endif -#endif - -#ifdef __cplusplus -} -#endif - -#ifndef _SIGNAL_H_ -/* Some applications take advantage of the fact that - * and are equivalent in glibc. Allow for that here. */ -#include -#endif -#endif /* _SYS_SIGNAL_H */ diff --git a/extra_include/sys/stat.h b/extra_include/sys/stat.h deleted file mode 100644 index 544c10d5..00000000 --- a/extra_include/sys/stat.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef _SYS_STAT_H -#define _SYS_STAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <_ansi.h> -#include -#include - -/* dj's stat defines _STAT_H_ */ -#ifndef _STAT_H_ - -/* It is intended that the layout of this structure not change when the - sizes of any of the basic types change (short, int, long) [via a compile - time option]. */ - -#ifdef __CYGWIN__ -#include -#ifdef _COMPILING_NEWLIB -#define stat64 __stat64 -#endif -#else -struct stat -{ - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - /* SysV/sco doesn't have the rest... But Solaris, eabi does. */ -#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__) - time_t st_atime; - time_t st_mtime; - time_t st_ctime; -#else - time_t st_atime; - long st_spare1; - time_t st_mtime; - long st_spare2; - time_t st_ctime; - long st_spare3; - long st_blksize; - long st_blocks; - long st_spare4[2]; -#endif -}; -#endif - -#define _IFMT 0170000 /* type of file */ -#define _IFDIR 0040000 /* directory */ -#define _IFCHR 0020000 /* character special */ -#define _IFBLK 0060000 /* block special */ -#define _IFREG 0100000 /* regular */ -#define _IFLNK 0120000 /* symbolic link */ -#define _IFSOCK 0140000 /* socket */ -#define _IFIFO 0010000 /* fifo */ - -#define S_BLKSIZE 1024 /* size of a block */ - -#define S_ISUID 0004000 /* set user id on execution */ -#define S_ISGID 0002000 /* set group id on execution */ -#ifndef _POSIX_SOURCE -#define S_ISVTX 0001000 /* save swapped text even after use */ -#define S_IREAD 0000400 /* read permission, owner */ -#define S_IWRITE 0000200 /* write permission, owner */ -#define S_IEXEC 0000100 /* execute/search permission, owner */ -#define S_ENFMT 0002000 /* enforcement-mode locking */ - -#define S_IFMT _IFMT -#define S_IFDIR _IFDIR -#define S_IFCHR _IFCHR -#define S_IFBLK _IFBLK -#define S_IFREG _IFREG -#define S_IFLNK _IFLNK -#define S_IFSOCK _IFSOCK -#define S_IFIFO _IFIFO -#endif /* !_POSIX_SOURCE */ - -#ifdef _WIN32 -/* The Windows header files define _S_ forms of these, so we do too - for easier portability. */ -#define _S_IFMT _IFMT -#define _S_IFDIR _IFDIR -#define _S_IFCHR _IFCHR -#define _S_IFIFO _IFIFO -#define _S_IFREG _IFREG -#define _S_IREAD 0000400 -#define _S_IWRITE 0000200 -#define _S_IEXEC 0000100 -#endif - -#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) -#define S_IRUSR 0000400 /* read permission, owner */ -#define S_IWUSR 0000200 /* write permission, owner */ -#define S_IXUSR 0000100/* execute/search permission, owner */ -#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) -#define S_IRGRP 0000040 /* read permission, group */ -#define S_IWGRP 0000020 /* write permission, grougroup */ -#define S_IXGRP 0000010/* execute/search permission, group */ -#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) -#define S_IROTH 0000004 /* read permission, other */ -#define S_IWOTH 0000002 /* write permission, other */ -#define S_IXOTH 0000001/* execute/search permission, other */ - -#define S_ISBLK(m) (((m)&_IFMT) == _IFBLK) -#define S_ISCHR(m) (((m)&_IFMT) == _IFCHR) -#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR) -#define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO) -#define S_ISREG(m) (((m)&_IFMT) == _IFREG) -#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK) -#define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK) - - -int _EXFUN(chmod,( const char *__path, mode_t __mode )); -int _EXFUN(fchmod,(int __fd, mode_t __mode)); -int _EXFUN(fstat,( int __fd, struct stat *__sbuf )); -int _EXFUN(mkdir,( const char *_path, mode_t __mode )); -int _EXFUN(mkfifo,( const char *__path, mode_t __mode )); -int _EXFUN(stat,( const char *__path, struct stat *__sbuf )); -mode_t _EXFUN(umask,( mode_t __mask )); - -#if defined(__rtems__) || defined(__CYGWIN__) && !defined(__INSIDE_CYGWIN__) -int _EXFUN(lstat,( const char *__path, struct stat *__buf )); -int _EXFUN(mknod,( const char *__path, mode_t __mode, dev_t __dev )); -#endif - -/* Provide prototypes for most of the _ names that are - provided in newlib for some compilers. */ -#ifdef _COMPILING_NEWLIB -int _EXFUN(_fstat,( int __fd, struct stat *__sbuf )); -int _EXFUN(_stat,( const char *__path, struct stat *__sbuf )); -#ifdef __LARGE64_FILES -struct stat64; -int _EXFUN(_fstat64,( int __fd, struct stat64 *__sbuf )); -#endif -#endif - -#endif /* !_STAT_H_ */ -#ifdef __cplusplus -} -#endif -#endif /* _SYS_STAT_H */ diff --git a/extra_include/sys/stdio.h b/extra_include/sys/stdio.h deleted file mode 100644 index 1b887f89..00000000 --- a/extra_include/sys/stdio.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _NEWLIB_STDIO_H -#define _NEWLIB_STDIO_H - -#include -#include - -/* Internal locking macros, used to protect stdio functions. In the - general case, expand to nothing. Use __SSTR flag in FILE _flags to - detect if FILE is private to sprintf/sscanf class of functions; if - set then do nothing as lock is not initialised. */ -#if !defined(_flockfile) -#ifndef __SINGLE_THREAD__ -# define _flockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_acquire_recursive((fp)->_lock)) -#else -# define _flockfile(fp) -#endif -#endif - -#if !defined(_funlockfile) -#ifndef __SINGLE_THREAD__ -# define _funlockfile(fp) (((fp)->_flags & __SSTR) ? 0 : __lock_release_recursive((fp)->_lock)) -#else -# define _funlockfile(fp) -#endif -#endif - -#define getline __getline -#define getdelim __getdelim - -#endif /* _NEWLIB_STDIO_H */ diff --git a/extra_include/sys/syslimits.h b/extra_include/sys/syslimits.h deleted file mode 100644 index 179bc9d8..00000000 --- a/extra_include/sys/syslimits.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1988, 1993 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)syslimits.h 8.1 (Berkeley) 6/2/93 - * $FreeBSD: src/sys/sys/syslimits.h,v 1.10 2001/06/18 20:24:54 wollman Exp $ - */ - -#ifndef _SYS_SYSLIMITS_H_ -#define _SYS_SYSLIMITS_H_ - -#define ARG_MAX 65536 /* max bytes for an exec function */ -#ifndef CHILD_MAX -#define CHILD_MAX 40 /* max simultaneous processes */ -#endif -#define LINK_MAX 32767 /* max file link count */ -#define MAX_CANON 255 /* max bytes in term canon input line */ -#define MAX_INPUT 255 /* max bytes in terminal input */ -#define NAME_MAX 255 /* max bytes in a file name */ -#define NGROUPS_MAX 16 /* max supplemental group id's */ -#ifndef OPEN_MAX -#define OPEN_MAX 64 /* max open files per process */ -#endif -#define PATH_MAX 1024 /* max bytes in pathname */ -#define PIPE_BUF 512 /* max bytes for atomic pipe writes */ -#define IOV_MAX 1024 /* max elements in i/o vector */ - -#define BC_BASE_MAX 99 /* max ibase/obase values in bc(1) */ -#define BC_DIM_MAX 2048 /* max array elements in bc(1) */ -#define BC_SCALE_MAX 99 /* max scale value in bc(1) */ -#define BC_STRING_MAX 1000 /* max const string length in bc(1) */ -#define COLL_WEIGHTS_MAX 0 /* max weights for order keyword */ -#define EXPR_NEST_MAX 32 /* max expressions nested in expr(1) */ -#define LINE_MAX 2048 /* max bytes in an input line */ -#define RE_DUP_MAX 255 /* max RE's in interval notation */ - -#endif diff --git a/extra_include/sys/time.h b/extra_include/sys/time.h deleted file mode 100644 index 380a6d78..00000000 --- a/extra_include/sys/time.h +++ /dev/null @@ -1,83 +0,0 @@ -/* time.h -- An implementation of the standard Unix file. - Written by Geoffrey Noer - Public domain; no rights reserved. */ - -#ifndef _SYS_TIME_H_ -#define _SYS_TIME_H_ - -#include <_ansi.h> -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _WINSOCK_H -struct timeval { - long tv_sec; - long tv_usec; -}; - -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; - -#ifdef __CYGWIN__ -#include -#endif /* __CYGWIN__ */ - -#endif /* _WINSOCK_H */ - -#define ITIMER_REAL 0 -#define ITIMER_VIRTUAL 1 -#define ITIMER_PROF 2 - -struct itimerval { - struct timeval it_interval; - struct timeval it_value; -}; - -/* BSD time macros used by RTEMS code */ -#if defined (__rtems__) || defined (__CYGWIN__) - -/* Convenience macros for operations on timevals. - NOTE: `timercmp' does not work for >= or <=. */ -#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) -#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) -#define timercmp(a, b, CMP) \ - (((a)->tv_sec == (b)->tv_sec) ? \ - ((a)->tv_usec CMP (b)->tv_usec) : \ - ((a)->tv_sec CMP (b)->tv_sec)) -#define timeradd(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ - if ((result)->tv_usec >= 1000000) \ - { \ - ++(result)->tv_sec; \ - (result)->tv_usec -= 1000000; \ - } \ - } while (0) -#define timersub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ - } while (0) -#endif /* defined (__rtems__) || defined (__CYGWIN__) */ - -int _EXFUN(gettimeofday, (struct timeval *__p, struct timezone *__z)); -int _EXFUN(settimeofday, (const struct timeval *, const struct timezone *)); -int _EXFUN(utimes, (const char *__path, struct timeval *__tvp)); -int _EXFUN(getitimer, (int __which, struct itimerval *__value)); -int _EXFUN(setitimer, (int __which, const struct itimerval *__value, - struct itimerval *__ovalue)); - -#ifdef __cplusplus -} -#endif -#endif /* _SYS_TIME_H_ */ diff --git a/extra_include/sys/timeb.h b/extra_include/sys/timeb.h deleted file mode 100644 index 99fc9db4..00000000 --- a/extra_include/sys/timeb.h +++ /dev/null @@ -1,39 +0,0 @@ -/* timeb.h -- An implementation of the standard Unix file. - Written by Ian Lance Taylor - Public domain; no rights reserved. - - declares the structure used by the ftime function, as - well as the ftime function itself. Newlib does not provide an - implementation of ftime. */ - -#ifndef _SYS_TIMEB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define _SYS_TIMEB_H - -#include <_ansi.h> -#include - -#ifndef __time_t_defined -typedef _TIME_T_ time_t; -#define __time_t_defined -#endif - -struct timeb -{ - time_t time; - unsigned short millitm; - short timezone; - short dstflag; -}; - -extern int ftime _PARAMS ((struct timeb *)); - -#ifdef __cplusplus -} -#endif - -#endif /* ! defined (_SYS_TIMEB_H) */ diff --git a/extra_include/sys/times.h b/extra_include/sys/times.h deleted file mode 100644 index f87edb9a..00000000 --- a/extra_include/sys/times.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _SYS_TIMES_H -#ifdef __cplusplus -extern "C" { -#endif -#define _SYS_TIMES_H - -#include <_ansi.h> -#include - -#ifndef __clock_t_defined -typedef _CLOCK_T_ clock_t; -#define __clock_t_defined -#endif - -/* Get Process Times, P1003.1b-1993, p. 92 */ -struct tms { - clock_t tms_utime; /* user time */ - clock_t tms_stime; /* system time */ - clock_t tms_cutime; /* user time, children */ - clock_t tms_cstime; /* system time, children */ -}; - -clock_t _EXFUN(times,(struct tms *)); - -#ifdef __cplusplus -} -#endif -#endif /* !_SYS_TIMES_H */ diff --git a/extra_include/sys/types.h b/extra_include/sys/types.h deleted file mode 100644 index 75a4f4a5..00000000 --- a/extra_include/sys/types.h +++ /dev/null @@ -1,375 +0,0 @@ -/* unified sys/types.h: - start with sef's sysvi386 version. - merge go32 version -- a few ifdefs. - h8300hms, h8300xray, and sysvnecv70 disagree on the following types: - - typedef int gid_t; - typedef int uid_t; - typedef int dev_t; - typedef int ino_t; - typedef int mode_t; - typedef int caddr_t; - - however, these aren't "reasonable" values, the sysvi386 ones make far - more sense, and should work sufficiently well (in particular, h8300 - doesn't have a stat, and the necv70 doesn't matter.) -- eichin - */ - -#ifndef _SYS_TYPES_H - -#include <_ansi.h> - -#ifndef __INTTYPES_DEFINED__ -#define __INTTYPES_DEFINED__ -typedef short int __int16_t; -typedef unsigned short int __uint16_t; - -#if __INT_MAX__ == 32767 -typedef long int __int32_t; -typedef unsigned long int __uint32_t; -#else -typedef int __int32_t; -typedef unsigned int __uint32_t; -#endif - -#if __LONG_MAX__ > 2147483647 || !defined(__GNUC__) -typedef long int __int64_t; -typedef unsigned long int __uint64_t; -#else -__extension__ typedef long long __int64_t; -__extension__ typedef unsigned long long __uint64_t; -#endif -#endif /* ! __INTTYPES_DEFINED */ - -#ifndef __need_inttypes - -#define _SYS_TYPES_H -#include - -#ifdef __i386__ -#if defined (GO32) || defined (__MSDOS__) -#define __MS_types__ -#endif -#endif - -# include -# include - -/* To ensure the stat struct's layout doesn't change when sizeof(int), etc. - changes, we assume sizeof short and long never change and have all types - used to define struct stat use them and not int where possible. - Where not possible, _ST_INTxx are used. It would be preferable to not have - such assumptions, but until the extra fluff is necessary, it's avoided. - No 64 bit targets use stat yet. What to do about them is postponed - until necessary. */ -#ifdef __GNUC__ -#define _ST_INT32 __attribute__ ((__mode__ (__SI__))) -#else -#define _ST_INT32 -#endif - -# ifndef _POSIX_SOURCE - -# define physadr physadr_t -# define quad quad_t - -#ifndef _BSDTYPES_DEFINED -/* also defined in mingw/gmon.h and in w32api/winsock[2].h */ -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned int u_int; -typedef unsigned long u_long; -#define _BSDTYPES_DEFINED -#endif - -typedef unsigned short ushort; /* System V compatibility */ -typedef unsigned int uint; /* System V compatibility */ -# endif /*!_POSIX_SOURCE */ - -#ifndef __clock_t_defined -typedef _CLOCK_T_ clock_t; -#define __clock_t_defined -#endif - -#ifndef __time_t_defined -typedef _TIME_T_ time_t; -#define __time_t_defined - -/* Time Value Specification Structures, P1003.1b-1993, p. 261 */ - -struct timespec { - time_t tv_sec; /* Seconds */ - long tv_nsec; /* Nanoseconds */ -}; - -struct itimerspec { - struct timespec it_interval; /* Timer period */ - struct timespec it_value; /* Timer expiration */ -}; -#endif - -typedef long daddr_t; -typedef char * caddr_t; - -#ifndef __CYGWIN__ -#if defined(__MS_types__) || defined(__rtems__) -typedef unsigned long ino_t; -#else -#ifdef __sparc__ -typedef unsigned long ino_t; -#else -typedef unsigned short ino_t; -#endif -#endif -#endif /*__CYGWIN__*/ - -#ifdef __MS_types__ -typedef unsigned long vm_offset_t; -typedef unsigned long vm_size_t; - -#define __BIT_TYPES_DEFINED__ - -typedef signed char int8_t; -typedef unsigned char u_int8_t; -typedef short int16_t; -typedef unsigned short u_int16_t; -typedef int int32_t; -typedef unsigned int u_int32_t; -typedef long long int64_t; -typedef unsigned long long u_int64_t; -typedef int32_t register_t; -#endif /* __MS_types__ */ - -/* - * All these should be machine specific - right now they are all broken. - * However, for all of Cygnus' embedded targets, we want them to all be - * the same. Otherwise things like sizeof (struct stat) might depend on - * how the file was compiled (e.g. -mint16 vs -mint32, etc.). - */ - -#if defined(__rtems__) -/* device numbers are 32-bit major and and 32-bit minor */ -typedef unsigned long long dev_t; -#else -#ifndef __CYGWIN__ -typedef short dev_t; -#endif -#endif - -#ifndef __CYGWIN__ /* which defines these types in it's own types.h. */ -typedef long off_t; - -typedef unsigned short uid_t; -typedef unsigned short gid_t; -#endif - -typedef int pid_t; -#ifndef __CYGWIN__ -typedef long key_t; -#endif -typedef _ssize_t ssize_t; - -#ifndef __CYGWIN__ -#ifdef __MS_types__ -typedef char * addr_t; -typedef int mode_t; -#else -#if defined (__sparc__) && !defined (__sparc_v9__) -#ifdef __svr4__ -typedef unsigned long mode_t; -#else -typedef unsigned short mode_t; -#endif -#else -typedef unsigned int mode_t _ST_INT32; -#endif -#endif /* ! __MS_types__ */ -#endif /*__CYGWIN__*/ - -typedef unsigned short nlink_t; - -/* We don't define fd_set and friends if we are compiling POSIX - source, or if we have included (or may include as indicated - by __USE_W32_SOCKETS) the W32api winsock[2].h header which - defines Windows versions of them. Note that a program which - includes the W32api winsock[2].h header must know what it is doing; - it must not call the cygwin32 select function. -*/ -# if !(defined (_POSIX_SOURCE) || defined (_WINSOCK_H) || defined (__USE_W32_SOCKETS)) -# define _SYS_TYPES_FD_SET -# define NBBY 8 /* number of bits in a byte */ -/* - * Select uses bit masks of file descriptors in longs. - * These macros manipulate such bit fields (the filesystem macros use chars). - * FD_SETSIZE may be defined by the user, but the default here - * should be >= NOFILE (param.h). - */ -# ifndef FD_SETSIZE -# define FD_SETSIZE 64 -# endif - -typedef long fd_mask; -# define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */ -# ifndef howmany -# define howmany(x,y) (((x)+((y)-1))/(y)) -# endif - -/* We use a macro for fd_set so that including Sockets.h afterwards - can work. */ -typedef struct _types_fd_set { - fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; -} _types_fd_set; - -#define fd_set _types_fd_set - -# define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS))) -# define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS))) -# define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS))) -# define FD_ZERO(p) (__extension__ (void)({ \ - size_t __i; \ - char *__tmp = (char *)p; \ - for (__i = 0; __i < sizeof (*(p)); ++__i) \ - *__tmp++ = 0; \ -})) - -# endif /* !(defined (_POSIX_SOURCE) || defined (_WINSOCK_H) || defined (__USE_W32_SOCKETS)) */ - -#undef __MS_types__ -#undef _ST_INT32 - -/* The following are actually standard POSIX 1003.1b-1993 threads, mutexes, - condition variables, and keys. But since RTEMS is currently the only - newlib user of these, the ifdef is just on RTEMS. */ - -#if defined(__rtems__) || defined(__CYGWIN__) - -#ifndef __clockid_t_defined -typedef _CLOCKID_T_ clockid_t; -#define __clockid_t_defined -#endif - -#ifndef __timer_t_defined -typedef _TIMER_T_ timer_t; -#define __timer_t_defined -#endif - -#if defined(__CYGWIN__) || defined(__rtems__) -typedef long useconds_t; -#endif - -#include - - -/* Cygwin will probably never have full posix compliance due to little things - * like an inability to set the stackaddress. Cygwin is also using void * - * pointers rather than structs to ensure maximum binary compatability with - * previous releases. - * This means that we don't use the types defined here, but rather in - * - */ -#if defined(_POSIX_THREADS) && !defined(__CYGWIN__) - -#include - -/* - * 2.5 Primitive System Data Types, P1003.1c/D10, p. 19. - */ - -typedef __uint32_t pthread_t; /* identify a thread */ - -/* P1003.1c/D10, p. 118-119 */ -#define PTHREAD_SCOPE_PROCESS 0 -#define PTHREAD_SCOPE_SYSTEM 1 - -/* P1003.1c/D10, p. 111 */ -#define PTHREAD_INHERIT_SCHED 1 /* scheduling policy and associated */ - /* attributes are inherited from */ - /* the calling thread. */ -#define PTHREAD_EXPLICIT_SCHED 2 /* set from provided attribute object */ - -/* P1003.1c/D10, p. 141 */ -#define PTHREAD_CREATE_DETACHED 0 -#define PTHREAD_CREATE_JOINABLE 1 - -typedef struct { - int is_initialized; - void *stackaddr; - int stacksize; - int contentionscope; - int inheritsched; - int schedpolicy; - struct sched_param schedparam; - - /* P1003.4b/D8, p. 54 adds cputime_clock_allowed attribute. */ -#if defined(_POSIX_THREAD_CPUTIME) - int cputime_clock_allowed; /* see time.h */ -#endif - int detachstate; - -} pthread_attr_t; - -#if defined(_POSIX_THREAD_PROCESS_SHARED) -/* NOTE: P1003.1c/D10, p. 81 defines following values for process_shared. */ - -#define PTHREAD_PROCESS_PRIVATE 0 /* visible within only the creating process */ -#define PTHREAD_PROCESS_SHARED 1 /* visible too all processes with access to */ - /* the memory where the resource is */ - /* located */ -#endif - -#if defined(_POSIX_THREAD_PRIO_PROTECT) -/* Mutexes */ - -/* Values for blocking protocol. */ - -#define PTHREAD_PRIO_NONE 0 -#define PTHREAD_PRIO_INHERIT 1 -#define PTHREAD_PRIO_PROTECT 2 -#endif - -typedef __uint32_t pthread_mutex_t; /* identify a mutex */ - -typedef struct { - int is_initialized; -#if defined(_POSIX_THREAD_PROCESS_SHARED) - int process_shared; /* allow mutex to be shared amongst processes */ -#endif -#if defined(_POSIX_THREAD_PRIO_PROTECT) - int prio_ceiling; - int protocol; -#endif - int recursive; -} pthread_mutexattr_t; - -/* Condition Variables */ - -typedef __uint32_t pthread_cond_t; /* identify a condition variable */ - -typedef struct { - int is_initialized; -#if defined(_POSIX_THREAD_PROCESS_SHARED) - int process_shared; /* allow this to be shared amongst processes */ -#endif -} pthread_condattr_t; /* a condition attribute object */ - -/* Keys */ - -typedef __uint32_t pthread_key_t; /* thread-specific data keys */ - -typedef struct { - int is_initialized; /* is this structure initialized? */ - int init_executed; /* has the initialization routine been run? */ -} pthread_once_t; /* dynamic package initialization */ -#else -#if defined (__CYGWIN__) -#include -#endif -#endif /* defined(_POSIX_THREADS) */ - -#endif /* defined(__rtems__) */ - -#endif /* !__need_inttypes */ - -#undef __need_inttypes - -#endif /* _SYS_TYPES_H */ diff --git a/extra_include/sys/unistd.h b/extra_include/sys/unistd.h deleted file mode 100644 index 54ecc259..00000000 --- a/extra_include/sys/unistd.h +++ /dev/null @@ -1,339 +0,0 @@ -#ifndef _SYS_UNISTD_H -#define _SYS_UNISTD_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <_ansi.h> -#include -#include -#define __need_size_t -#define __need_ptrdiff_t -#include - -extern char **environ; - -void _EXFUN(_exit, (int __status ) _ATTRIBUTE ((noreturn))); - -int _EXFUN(access,(const char *__path, int __amode )); -unsigned _EXFUN(alarm, (unsigned __secs )); -int _EXFUN(chdir, (const char *__path )); -int _EXFUN(chmod, (const char *__path, mode_t __mode )); -#if !defined(__INSIDE_CYGWIN__) -int _EXFUN(chown, (const char *__path, uid_t __owner, gid_t __group )); -#endif -#if defined(__CYGWIN__) || defined(__rtems__) -int _EXFUN(chroot, (const char *__path )); -#endif -int _EXFUN(close, (int __fildes )); -char _EXFUN(*ctermid, (char *__s )); -char _EXFUN(*cuserid, (char *__s )); -#if defined(__CYGWIN__) -int _EXFUN(daemon, (int nochdir, int noclose)); -#endif -int _EXFUN(dup, (int __fildes )); -int _EXFUN(dup2, (int __fildes, int __fildes2 )); -#if defined(__CYGWIN__) -void _EXFUN(endusershell, (void)); -#endif -int _EXFUN(execl, (const char *__path, const char *, ... )); -int _EXFUN(execle, (const char *__path, const char *, ... )); -int _EXFUN(execlp, (const char *__file, const char *, ... )); -int _EXFUN(execv, (const char *__path, char * const __argv[] )); -int _EXFUN(execve, (const char *__path, char * const __argv[], char * const __envp[] )); -int _EXFUN(execvp, (const char *__file, char * const __argv[] )); -#if defined(__CYGWIN__) || defined(__rtems__) -int _EXFUN(fchdir, (int __fildes)); -#endif -int _EXFUN(fchmod, (int __fildes, mode_t __mode )); -#if !defined(__INSIDE_CYGWIN__) -int _EXFUN(fchown, (int __fildes, uid_t __owner, gid_t __group )); -#endif -pid_t _EXFUN(fork, (void )); -long _EXFUN(fpathconf, (int __fd, int __name )); -int _EXFUN(fsync, (int __fd)); -#ifndef __CYGWIN__ -int _EXFUN(fdatasync, (int __fd)); -#endif -char _EXFUN(*getcwd, (char *__buf, size_t __size )); -#if defined(__CYGWIN__) -int _EXFUN(getdomainname ,(char *__name, size_t __len)); -#endif -#if !defined(__INSIDE_CYGWIN__) -gid_t _EXFUN(getegid, (void )); -uid_t _EXFUN(geteuid, (void )); -gid_t _EXFUN(getgid, (void )); -#endif -int _EXFUN(getgroups, (int __gidsetsize, gid_t __grouplist[] )); -#if defined(__CYGWIN__) -long _EXFUN(gethostid, (void)); -#endif -char _EXFUN(*getlogin, (void )); -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) -int _EXFUN(getlogin_r, (char *name, size_t namesize) ); -#endif -char _EXFUN(*getpass, (const char *__prompt)); -size_t _EXFUN(getpagesize, (void)); -pid_t _EXFUN(getpgid, (pid_t)); -pid_t _EXFUN(getpgrp, (void )); -pid_t _EXFUN(getpid, (void )); -pid_t _EXFUN(getppid, (void )); -#ifdef __CYGWIN__ -pid_t _EXFUN(getsid, (pid_t)); -#endif -#if !defined(__INSIDE_CYGWIN__) -uid_t _EXFUN(getuid, (void )); -#endif -#ifdef __CYGWIN__ -char * _EXFUN(getusershell, (void)); -char _EXFUN(*getwd, (char *__buf )); -int _EXFUN(iruserok, (unsigned long raddr, int superuser, const char *ruser, const char *luser)); -#endif -int _EXFUN(isatty, (int __fildes )); -#if !defined(__INSIDE_CYGWIN__) -int _EXFUN(lchown, (const char *__path, uid_t __owner, gid_t __group )); -#endif -int _EXFUN(link, (const char *__path1, const char *__path2 )); -int _EXFUN(nice, (int __nice_value )); -#if !defined(__INSIDE_CYGWIN__) -off_t _EXFUN(lseek, (int __fildes, off_t __offset, int __whence )); -#endif -long _EXFUN(pathconf, (const char *__path, int __name )); -int _EXFUN(pause, (void )); -#ifdef __CYGWIN__ -int _EXFUN(pthread_atfork, (void (*)(void), void (*)(void), void (*)(void))); -#endif -int _EXFUN(pipe, (int __fildes[2] )); -ssize_t _EXFUN(pread, (int __fd, void *__buf, size_t __nbytes, off_t __offset)); -ssize_t _EXFUN(pwrite, (int __fd, const void *__buf, size_t __nbytes, off_t __offset)); -_READ_WRITE_RETURN_TYPE _EXFUN(read, (int __fd, void *__buf, size_t __nbyte )); -#if defined(__CYGWIN__) -int _EXFUN(rresvport, (int *__alport)); -int _EXFUN(revoke, (char *__path)); -#endif -int _EXFUN(rmdir, (const char *__path )); -#if defined(__CYGWIN__) -int _EXFUN(ruserok, (const char *rhost, int superuser, const char *ruser, const char *luser)); -#endif -void * _EXFUN(sbrk, (ptrdiff_t __incr)); -#if !defined(__INSIDE_CYGWIN__) -#if defined(__CYGWIN__) -int _EXFUN(setegid, (gid_t __gid )); -int _EXFUN(seteuid, (uid_t __uid )); -#endif -int _EXFUN(setgid, (gid_t __gid )); -#endif -#if defined(__CYGWIN__) -int _EXFUN(setgroups, (int ngroups, const gid_t *grouplist )); -#endif -int _EXFUN(setpgid, (pid_t __pid, pid_t __pgid )); -int _EXFUN(setpgrp, (void )); -#if defined(__CYGWIN__) && !defined(__INSIDE_CYGWIN__) -int _EXFUN(setregid, (gid_t __rgid, gid_t __egid)); -int _EXFUN(setreuid, (uid_t __ruid, uid_t __euid)); -#endif -pid_t _EXFUN(setsid, (void )); -#if !defined(__INSIDE_CYGWIN__) -int _EXFUN(setuid, (uid_t __uid )); -#endif -#if defined(__CYGWIN__) -void _EXFUN(setusershell, (void)); -#endif -unsigned _EXFUN(sleep, (unsigned int __seconds )); -void _EXFUN(swab, (const void *, void *, ssize_t)); -long _EXFUN(sysconf, (int __name )); -pid_t _EXFUN(tcgetpgrp, (int __fildes )); -int _EXFUN(tcsetpgrp, (int __fildes, pid_t __pgrp_id )); -char _EXFUN(*ttyname, (int __fildes )); -#if defined(__CYGWIN__) -int _EXFUN(ttyname_r, (int, char *, size_t)); -#endif -int _EXFUN(unlink, (const char *__path )); -int _EXFUN(vhangup, (void )); -_READ_WRITE_RETURN_TYPE _EXFUN(write, (int __fd, const void *__buf, size_t __nbyte )); - -#ifdef __CYGWIN__ -# define __UNISTD_GETOPT__ -# include -# undef __UNISTD_GETOPT__ -#else -extern char *optarg; /* getopt(3) external variables */ -extern int optind, opterr, optopt; -int getopt(int, char * const [], const char *); -extern int optreset; /* getopt(3) external variable */ -#endif - -#ifndef _POSIX_SOURCE -pid_t _EXFUN(vfork, (void )); - -extern char *suboptarg; /* getsubopt(3) external variable */ -int getsubopt(char **, char * const *, char **); -#endif /* _POSIX_SOURCE */ - -#ifdef _COMPILING_NEWLIB -/* Provide prototypes for most of the _ names that are - provided in newlib for some compilers. */ -int _EXFUN(_close, (int __fildes )); -pid_t _EXFUN(_fork, (void )); -pid_t _EXFUN(_getpid, (void )); -int _EXFUN(_link, (const char *__path1, const char *__path2 )); -_off_t _EXFUN(_lseek, (int __fildes, _off_t __offset, int __whence )); -#ifdef __LARGE64_FILES -_off64_t _EXFUN(_lseek64, (int __filedes, _off64_t __offset, int __whence )); -#endif -_READ_WRITE_RETURN_TYPE _EXFUN(_read, (int __fd, void *__buf, size_t __nbyte )); -void * _EXFUN(_sbrk, (ptrdiff_t __incr)); -int _EXFUN(_unlink, (const char *__path )); -_READ_WRITE_RETURN_TYPE _EXFUN(_write, (int __fd, const void *__buf, size_t __nbyte )); -int _EXFUN(_execve, (const char *__path, char * const __argv[], char * const __envp[] )); -#endif - -#if defined(__CYGWIN__) || defined(__rtems__) || defined(__sh__) -#if !defined(__INSIDE_CYGWIN__) -int _EXFUN(ftruncate, (int __fd, off_t __length)); -int _EXFUN(truncate, (const char *, off_t __length)); -#endif -#endif -#if defined(__CYGWIN__) || defined(__rtems__) -int _EXFUN(getdtablesize, (void)); -int _EXFUN(setdtablesize, (int)); -useconds_t _EXFUN(ualarm, (useconds_t __useconds, useconds_t __interval)); -unsigned _EXFUN(usleep, (unsigned int __useconds)); -#if !(defined (_WINSOCK_H) || defined (__USE_W32_SOCKETS)) -/* winsock[2].h defines as __stdcall, and with int as 2nd arg */ - int _EXFUN(gethostname, (char *__name, size_t __len)); -#endif -char * _EXFUN(mktemp, (char *)); -#if defined(__CYGWIN__) -void _EXFUN(sync, (void)); -#else /* defined(__rtems__) */ -int _EXFUN(sync, (void)); -#endif -int _EXFUN(readlink, (const char *__path, char *__buf, int __buflen)); -int _EXFUN(symlink, (const char *__name1, const char *__name2)); -#endif - -#define F_OK 0 -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 - -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 - -#include - -#define STDIN_FILENO 0 /* standard input file descriptor */ -#define STDOUT_FILENO 1 /* standard output file descriptor */ -#define STDERR_FILENO 2 /* standard error file descriptor */ - -/* - * 4.8.1 Get Configurable System Variables, P1003.1b-1993, p. 96 - * - * NOTE: Table 4-2, Configurable System Variables, p. 96 - */ - -#define _SC_ARG_MAX 0 -#define _SC_CHILD_MAX 1 -#define _SC_CLK_TCK 2 -#define _SC_NGROUPS_MAX 3 -#define _SC_OPEN_MAX 4 - /* no _SC_STREAM_MAX */ -#define _SC_JOB_CONTROL 5 -#define _SC_SAVED_IDS 6 -#define _SC_VERSION 7 -#define _SC_PAGESIZE 8 -/* CYGWIN-specific values .. do not touch */ -#define _SC_NPROCESSORS_CONF 9 -#define _SC_NPROCESSORS_ONLN 10 -#define _SC_PHYS_PAGES 11 -#define _SC_AVPHYS_PAGES 12 -/* end of CYGWIN-specific values */ -#define _SC_MQ_OPEN_MAX 13 -#define _SC_MQ_PRIO_MAX 14 -#define _SC_RTSIG_MAX 15 -#define _SC_SEM_NSEMS_MAX 16 -#define _SC_SEM_VALUE_MAX 17 -#define _SC_SIGQUEUE_MAX 18 -#define _SC_TIMER_MAX 19 -#define _SC_TZNAME_MAX 20 - -#define _SC_ASYNCHRONOUS_IO 21 -#define _SC_FSYNC 22 -#define _SC_MAPPED_FILES 23 -#define _SC_MEMLOCK 24 -#define _SC_MEMLOCK_RANGE 25 -#define _SC_MEMORY_PROTECTION 26 -#define _SC_MESSAGE_PASSING 27 -#define _SC_PRIORITIZED_IO 28 -#define _SC_REALTIME_SIGNALS 29 -#define _SC_SEMAPHORES 30 -#define _SC_SHARED_MEMORY_OBJECTS 31 -#define _SC_SYNCHRONIZED_IO 32 -#define _SC_TIMERS 33 -#define _SC_AIO_LISTIO_MAX 34 -#define _SC_AIO_MAX 35 -#define _SC_AIO_PRIO_DELTA_MAX 36 -#define _SC_DELAYTIMER_MAX 37 - -/* - * P1003.1c/D10, p. 52 adds the following. - */ - -#define _SC_THREAD_KEYS_MAX 38 -#define _SC_THREAD_STACK_MIN 39 -#define _SC_THREAD_THREADS_MAX 40 -#define _SC_TTY_NAME_MAX 41 - -#define _SC_THREADS 42 -#define _SC_THREAD_ATTR_STACKADDR 43 -#define _SC_THREAD_ATTR_STACKSIZE 44 -#define _SC_THREAD_PRIORITY_SCHEDULING 45 -#define _SC_THREAD_PRIO_INHERIT 46 -/* _SC_THREAD_PRIO_PROTECT was _SC_THREAD_PRIO_CEILING in early drafts */ -#define _SC_THREAD_PRIO_PROTECT 47 -#define _SC_THREAD_PRIO_CEILING _SC_THREAD_PRIO_PROTECT -#define _SC_THREAD_PROCESS_SHARED 48 -#define _SC_THREAD_SAFE_FUNCTIONS 49 -#define _SC_GETGR_R_SIZE_MAX 50 -#define _SC_GETPW_R_SIZE_MAX 51 -#define _SC_LOGIN_NAME_MAX 52 -#define _SC_THREAD_DESTRUCTOR_ITERATIONS 53 - -#if !defined(__CYGWIN__) && !defined(__rtems__) -#define _SC_STREAM_MAX 100 -#define _SC_PRIORITY_SCHEDULING 101 -#endif - -# define _PC_LINK_MAX 0 -# define _PC_MAX_CANON 1 -# define _PC_MAX_INPUT 2 -# define _PC_NAME_MAX 3 -# define _PC_PATH_MAX 4 -# define _PC_PIPE_BUF 5 -# define _PC_CHOWN_RESTRICTED 6 -# define _PC_NO_TRUNC 7 -# define _PC_VDISABLE 8 -# define _PC_ASYNC_IO 9 -# define _PC_PRIO_IO 10 -# define _PC_SYNC_IO 11 -#ifdef __CYGWIN__ -/* Ask for POSIX permission bits support. */ -# define _PC_POSIX_PERMISSIONS 90 -/* Ask for full POSIX permission support including uid/gid settings. */ -# define _PC_POSIX_SECURITY 91 -#endif - -/* FIXME: This is temporary until winsup gets sorted out. */ -#ifdef __CYGWIN__ -#define MAXPATHLEN (260 - 1 /* NUL */) -#else -# define MAXPATHLEN 1024 -#endif - -#ifdef __cplusplus -} -#endif -#endif /* _SYS_UNISTD_H */ diff --git a/extra_include/sys/utime.h b/extra_include/sys/utime.h deleted file mode 100644 index 989726df..00000000 --- a/extra_include/sys/utime.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _SYS_UTIME_H -#define _SYS_UTIME_H - -/* This is a dummy file, not customized for any - particular system. If there is a utime.h in libc/sys/SYSDIR/sys, - it will override this one. */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct utimbuf -{ - time_t actime; - time_t modtime; -}; - -#ifdef __cplusplus -}; -#endif - -#endif /* _SYS_UTIME_H */ diff --git a/extra_include/sys/wait.h b/extra_include/sys/wait.h deleted file mode 100644 index 863c11ac..00000000 --- a/extra_include/sys/wait.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _SYS_WAIT_H -#define _SYS_WAIT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define WNOHANG 1 -#define WUNTRACED 2 - -/* A status looks like: - <2 bytes info> <2 bytes code> - - == 0, child has exited, info is the exit value - == 1..7e, child has exited, info is the signal number. - == 7f, child has stopped, info was the signal number. - == 80, there was a core dump. -*/ - -#define WIFEXITED(w) (((w) & 0xff) == 0) -#define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f)) -#define WIFSTOPPED(w) (((w) & 0xff) == 0x7f) -#define WEXITSTATUS(w) (((w) >> 8) & 0xff) -#define WTERMSIG(w) ((w) & 0x7f) -#define WSTOPSIG WEXITSTATUS - -pid_t wait (int *); -pid_t waitpid (pid_t, int *, int); - -/* Provide prototypes for most of the _ names that are - provided in newlib for some compilers. */ -pid_t _wait (int *); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/extra_include/termios.h b/extra_include/termios.h deleted file mode 100644 index f31d0ecc..00000000 --- a/extra_include/termios.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#endif diff --git a/extra_include/time.h b/extra_include/time.h deleted file mode 100644 index 71bb91c7..00000000 --- a/extra_include/time.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * time.h - * - * Struct and function declarations for dealing with time. - */ - -#ifndef _TIME_H_ -#define _TIME_H_ - -#include "_ansi.h" -#include - -#ifndef NULL -#define NULL 0 -#endif - -/* Get _CLOCKS_PER_SEC_ */ -#include - -#ifndef _CLOCKS_PER_SEC_ -#define _CLOCKS_PER_SEC_ 1000 -#endif - -#define CLOCKS_PER_SEC _CLOCKS_PER_SEC_ -#define CLK_TCK CLOCKS_PER_SEC -#define __need_size_t -#include - -#include - -_BEGIN_STD_C - -struct tm -{ - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; -}; - -clock_t _EXFUN(clock, (void)); -double _EXFUN(difftime, (time_t _time2, time_t _time1)); -time_t _EXFUN(mktime, (struct tm *_timeptr)); -time_t _EXFUN(time, (time_t *_timer)); -#ifndef _REENT_ONLY -char *_EXFUN(asctime, (const struct tm *_tblock)); -char *_EXFUN(ctime, (const time_t *_time)); -struct tm *_EXFUN(gmtime, (const time_t *_timer)); -struct tm *_EXFUN(localtime,(const time_t *_timer)); -#endif -size_t _EXFUN(strftime, (char *_s, size_t _maxsize, const char *_fmt, const struct tm *_t)); - -char *_EXFUN(asctime_r, (const struct tm *, char *)); -char *_EXFUN(ctime_r, (const time_t *, char *)); -struct tm *_EXFUN(gmtime_r, (const time_t *, struct tm *)); -struct tm *_EXFUN(localtime_r, (const time_t *, struct tm *)); - -_END_STD_C - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __STRICT_ANSI__ -char *_EXFUN(strptime, (const char *, const char *, struct tm *)); -_VOID _EXFUN(tzset, (_VOID)); -_VOID _EXFUN(_tzset_r, (struct _reent *)); - -/* getdate functions */ - -#ifdef HAVE_GETDATE -#ifndef _REENT_ONLY -#define getdate_err (*__getdate_err()) -int *_EXFUN(__getdate_err,(_VOID)); - -struct tm * _EXFUN(getdate, (const char *)); -/* getdate_err is set to one of the following values to indicate the error. - 1 the DATEMSK environment variable is null or undefined, - 2 the template file cannot be opened for reading, - 3 failed to get file status information, - 4 the template file is not a regular file, - 5 an error is encountered while reading the template file, - 6 memory allication failed (not enough memory available), - 7 there is no line in the template that matches the input, - 8 invalid input specification */ -#endif /* !_REENT_ONLY */ - -/* getdate_r returns the error code as above */ -int _EXFUN(getdate_r, (const char *, struct tm *)); -#endif /* HAVE_GETDATE */ - -/* defines for the opengroup specifications Derived from Issue 1 of the SVID. */ -extern __IMPORT time_t _timezone; -extern __IMPORT int _daylight; -extern __IMPORT char *_tzname[2]; - -/* POSIX defines the external tzname being defined in time.h */ -#ifndef tzname -#define tzname _tzname -#endif - -/* CYGWIN also exposes daylight and timezone in the name space */ -#ifdef __CYGWIN__ -#ifndef daylight -#define daylight _daylight -#endif -#ifdef timezonevar -#ifndef timezone -#define timezone ((long int) _timezone) -#endif -#else -char *_EXFUN(timezone, (void)); -#endif -#endif /* __CYGWIN__ */ -#endif /* !__STRICT_ANSI__ */ - -#ifdef __cplusplus -} -#endif - -#include - -#if defined(_POSIX_TIMERS) - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Clocks, P1003.1b-1993, p. 263 */ - -int _EXFUN(clock_settime, (clockid_t clock_id, const struct timespec *tp)); -int _EXFUN(clock_gettime, (clockid_t clock_id, struct timespec *tp)); -int _EXFUN(clock_getres, (clockid_t clock_id, struct timespec *res)); - -/* Create a Per-Process Timer, P1003.1b-1993, p. 264 */ - -int _EXFUN(timer_create, - (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)); - -/* Delete a Per_process Timer, P1003.1b-1993, p. 266 */ - -int _EXFUN(timer_delete, (timer_t timerid)); - -/* Per-Process Timers, P1003.1b-1993, p. 267 */ - -int _EXFUN(timer_settime, - (timer_t timerid, int flags, const struct itimerspec *value, - struct itimerspec *ovalue)); -int _EXFUN(timer_gettime, (timer_t timerid, struct itimerspec *value)); -int _EXFUN(timer_getoverrun, (timer_t timerid)); - -/* High Resolution Sleep, P1003.1b-1993, p. 269 */ - -int _EXFUN(nanosleep, (const struct timespec *rqtp, struct timespec *rmtp)); - -#ifdef __cplusplus -} -#endif -#else -#ifdef __CYGWIN__ -#ifdef __cplusplus -extern "C" { -#endif -int _EXFUN(nanosleep, (const struct timespec *rqtp, struct timespec *rmtp)); -#ifdef __cplusplus -} -#endif -#endif /* __CYGWIN__ */ -#endif /* _POSIX_TIMERS */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* CPU-time Clock Attributes, P1003.4b/D8, p. 54 */ - -/* values for the clock enable attribute */ - -#define CLOCK_ENABLED 1 /* clock is enabled, i.e. counting execution time */ -#define CLOCK_DISABLED 0 /* clock is disabled */ - -/* values for the pthread cputime_clock_allowed attribute */ - -#define CLOCK_ALLOWED 1 /* If a thread is created with this value a */ - /* CPU-time clock attached to that thread */ - /* shall be accessible. */ -#define CLOCK_DISALLOWED 0 /* If a thread is created with this value, the */ - /* thread shall not have a CPU-time clock */ - /* accessible. */ - -/* Manifest Constants, P1003.1b-1993, p. 262 */ - -#define CLOCK_REALTIME (clockid_t)1 - -/* Flag indicating time is "absolute" with respect to the clock - associated with a time. */ - -#define TIMER_ABSTIME 4 -#ifdef __CYGWIN__ -# define TIMER_RELTIME 0 /* For compatibility with HP/UX, Solaris, - others? */ -#endif - -/* Manifest Constants, P1003.4b/D8, p. 55 */ - -#if defined(_POSIX_CPUTIME) - -/* When used in a clock or timer function call, this is interpreted as - the identifier of the CPU_time clock associated with the PROCESS - making the function call. */ - -#define CLOCK_PROCESS_CPUTIME (clockid_t)2 - -#endif - -#if defined(_POSIX_THREAD_CPUTIME) - -/* When used in a clock or timer function call, this is interpreted as - the identifier of the CPU_time clock associated with the THREAD - making the function call. */ - -#define CLOCK_THREAD_CPUTIME (clockid_t)3 - -#endif - -#if defined(_POSIX_CPUTIME) - -/* Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55 */ - -int _EXFUN(clock_getcpuclockid, (pid_t pid, clockid_t *clock_id)); - -#endif /* _POSIX_CPUTIME */ - -#if defined(_POSIX_CPUTIME) || defined(_POSIX_THREAD_CPUTIME) - -/* CPU-time Clock Attribute Access, P1003.4b/D8, p. 56 */ - -int _EXFUN(clock_setenable_attr, (clockid_t clock_id, int attr)); -int _EXFUN(clock_getenable_attr, (clockid_t clock_id, int *attr)); - -#endif /* _POSIX_CPUTIME or _POSIX_THREAD_CPUTIME */ - -#ifdef __cplusplus -} -#endif - -#endif /* _TIME_H_ */ - diff --git a/extra_include/unctrl.h b/extra_include/unctrl.h deleted file mode 100644 index ab070bb6..00000000 --- a/extra_include/unctrl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* From curses.h. */ -/* - * Copyright (c) 1981, 1993 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#ifndef _UNCTRL_H_ -#define _UNCTRL_H_ - -#include <_ansi.h> - -#define unctrl(c) __unctrl[(c) & 0xff] -#define unctrllen(ch) __unctrllen[(ch) & 0xff] - -extern __IMPORT _CONST char * _CONST __unctrl[256]; /* Control strings. */ -extern __IMPORT _CONST char __unctrllen[256]; /* Control strings length. */ - -#endif /* _UNCTRL_H_ */ diff --git a/extra_include/unistd.h b/extra_include/unistd.h deleted file mode 100644 index 3cd7ea8a..00000000 --- a/extra_include/unistd.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _UNISTD_H_ -#define _UNISTD_H_ - -# include - -#ifndef L_SET -/* Old BSD names for the same constants; just for compatibility. */ -#define L_SET SEEK_SET -#define L_INCR SEEK_CUR -#define L_XTND SEEK_END -#endif - -#endif /* _UNISTD_H_ */ diff --git a/extra_include/utime.h b/extra_include/utime.h deleted file mode 100644 index 54f2019b..00000000 --- a/extra_include/utime.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -#include <_ansi.h> - -/* The utime function is defined in libc/sys//sys if it exists. */ -#include - -#ifdef __cplusplus -} -#endif diff --git a/extra_include/utmp.h b/extra_include/utmp.h deleted file mode 100644 index b3f6dd8d..00000000 --- a/extra_include/utmp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#endif - diff --git a/extra_include/wchar.h b/extra_include/wchar.h deleted file mode 100644 index bea13f03..00000000 --- a/extra_include/wchar.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _WCHAR_H_ -#define _WCHAR_H_ - -#include <_ansi.h> - -#include - -#define __need_size_t -#define __need_wchar_t -#define __need_wint_t -#include - -/* For _mbstate_t definition. */ -#include - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef WEOF -# define WEOF ((wint_t)-1) -#endif - -#ifndef WCHAR_MIN -#define WCHAR_MIN 0 -#endif - -#ifndef WCHAR_MAX -#ifdef __WCHAR_MAX__ -#define WCHAR_MAX __WCHAR_MAX__ -#else -#define WCHAR_MAX 0x7fffffffu -#endif -#endif - -_BEGIN_STD_C - -#ifndef _MBSTATE_T -#define _MBSTATE_T -typedef _mbstate_t mbstate_t; -#endif /* _MBSTATE_T */ - -wint_t _EXFUN(btowc, (int)); -int _EXFUN(wctob, (wint_t)); -size_t _EXFUN(mbrlen, (const char * , size_t, mbstate_t *)); -size_t _EXFUN(mbrtowc, (wchar_t * , const char * , size_t, mbstate_t *)); -size_t _EXFUN(_mbrtowc_r, (struct _reent *, wchar_t * , const char * , - size_t, mbstate_t *)); -int _EXFUN(mbsinit, (const mbstate_t *)); -size_t _EXFUN(mbsrtowcs, (wchar_t * , const char ** , size_t, mbstate_t *)); -size_t _EXFUN(wcrtomb, (char * , wchar_t, mbstate_t *)); -size_t _EXFUN(_wcrtomb_r, (struct _reent *, char * , wchar_t, mbstate_t *)); -size_t _EXFUN(wcsrtombs, (char * , const wchar_t ** , size_t, mbstate_t *)); -size_t _EXFUN(_wcsrtombs_r, (struct _reent *, char * , const wchar_t ** , - size_t, mbstate_t *)); -wchar_t *_EXFUN(wcscat, (wchar_t * , const wchar_t *)); -wchar_t *_EXFUN(wcschr, (const wchar_t *, wchar_t)); -int _EXFUN(wcscmp, (const wchar_t *, const wchar_t *)); -int _EXFUN(wcscoll, (const wchar_t *, const wchar_t *)); -wchar_t *_EXFUN(wcscpy, (wchar_t * , const wchar_t *)); -size_t _EXFUN(wcscspn, (const wchar_t *, const wchar_t *)); -size_t _EXFUN(wcslcat, (wchar_t *, const wchar_t *, size_t)); -size_t _EXFUN(wcslcpy, (wchar_t *, const wchar_t *, size_t)); -size_t _EXFUN(wcslen, (const wchar_t *)); -wchar_t *_EXFUN(wcsncat, (wchar_t * , const wchar_t * , size_t)); -int _EXFUN(wcsncmp, (const wchar_t *, const wchar_t *, size_t)); -wchar_t *_EXFUN(wcsncpy, (wchar_t * , const wchar_t * , size_t)); -size_t _EXFUN(wcsnlen, (const wchar_t *, size_t)); -wchar_t *_EXFUN(wcspbrk, (const wchar_t *, const wchar_t *)); -wchar_t *_EXFUN(wcsrchr, (const wchar_t *, wchar_t)); -size_t _EXFUN(wcsspn, (const wchar_t *, const wchar_t *)); -wchar_t *_EXFUN(wcsstr, (const wchar_t *, const wchar_t *)); -int _EXFUN(wcswidth, (const wchar_t *, size_t)); -int _EXFUN(wcwidth, (const wchar_t)); -wchar_t *_EXFUN(wmemchr, (const wchar_t *, wchar_t, size_t)); -int _EXFUN(wmemcmp, (const wchar_t *, const wchar_t *, size_t)); -wchar_t *_EXFUN(wmemcpy, (wchar_t * , const wchar_t * , size_t)); -wchar_t *_EXFUN(wmemmove, (wchar_t *, const wchar_t *, size_t)); -wchar_t *_EXFUN(wmemset, (wchar_t *, wchar_t, size_t)); - -_END_STD_C - -#endif /* _WCHAR_H_ */ diff --git a/extra_include/wctype.h b/extra_include/wctype.h deleted file mode 100644 index bed6fd6b..00000000 --- a/extra_include/wctype.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _WCTYPE_H_ -#define _WCTYPE_H_ - -#include <_ansi.h> -#include - -#define __need_wint_t -#include - -#ifndef WEOF -# define WEOF ((wint_t)-1) -#endif - -_BEGIN_STD_C - -#ifndef _WCTYPE_T -#define _WCTYPE_T -typedef int wctype_t; -#endif - -#ifndef _WCTRANS_T -#define _WCTRANS_T -typedef int wctrans_t; -#endif - -int _EXFUN(iswalpha, (wint_t)); -int _EXFUN(iswalnum, (wint_t)); -int _EXFUN(iswblank, (wint_t)); -int _EXFUN(iswcntrl, (wint_t)); -int _EXFUN(iswctype, (wint_t, wctype_t)); -int _EXFUN(iswdigit, (wint_t)); -int _EXFUN(iswgraph, (wint_t)); -int _EXFUN(iswlower, (wint_t)); -int _EXFUN(iswprint, (wint_t)); -int _EXFUN(iswpunct, (wint_t)); -int _EXFUN(iswspace, (wint_t)); -int _EXFUN(iswupper, (wint_t)); -int _EXFUN(iswxdigit, (wint_t)); -wint_t _EXFUN(towctrans, (wint_t, wctrans_t)); -wint_t _EXFUN(towupper, (wint_t)); -wint_t _EXFUN(towlower, (wint_t)); -wctrans_t _EXFUN(wctrans, (const char *)); -wctype_t _EXFUN(wctype, (const char *)); - -_END_STD_C - -#endif /* _WCTYPE_H_ */ diff --git a/include/espressif/c_types.h b/include/espressif/c_types.h index 4e2666b8..599cc56d 100644 --- a/include/espressif/c_types.h +++ b/include/espressif/c_types.h @@ -1,58 +1,72 @@ /* - * Copyright (c) 2010 - 2011 Espressif System + * 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 _C_TYPES_H_ #define _C_TYPES_H_ -typedef unsigned char uint8_t; -typedef signed char sint8_t; -typedef signed char int8_t; -typedef unsigned short uint16_t; -typedef signed short sint16_t; -typedef signed short int16_t; -typedef unsigned long uint32_t; -typedef signed long sint32_t; -typedef signed long int32_t; -typedef signed long long sint64_t; -typedef unsigned long long uint64_t; -typedef unsigned long long u_int64_t; -typedef float real32_t; -typedef double real64_t; +#include +#include +#include -typedef unsigned char uint8; -typedef unsigned char u8; -typedef signed char sint8; -typedef signed char int8; -typedef signed char s8; -typedef unsigned short uint16; -typedef unsigned short u16; -typedef signed short sint16; -typedef signed short s16; -typedef unsigned int uint32; -typedef unsigned int u_int; -typedef unsigned int u32; -typedef signed int sint32; -typedef signed int s32; -typedef int int32; -typedef signed long long sint64; -typedef unsigned long long uint64; -typedef unsigned long long u64; -typedef float real32; -typedef double real64; +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t u8_t; +typedef int8_t s8_t; +typedef uint16_t u16_t; +typedef int16_t s16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; + +typedef uint8_t uint8; +typedef uint8_t u8; +typedef int8_t sint8; +typedef int8_t int8; +typedef int8_t s8; +typedef uint16_t uint16; +typedef uint16_t u16; +typedef int16_t sint16; +typedef int16_t s16; +typedef uint32_t uint32; +typedef uint32_t u_int; +typedef uint32_t u32; +typedef int32_t sint32; +typedef int32_t s32; +typedef int32_t int32; +typedef int64_t sint64; +typedef uint64_t uint64; +typedef uint64_t u64; +typedef float real32; +typedef double real64; #define __le16 u16 -typedef unsigned int size_t; -typedef int ssize_t; - -#define __packed __attribute__((packed)) - #define LOCAL static #ifndef NULL -#define NULL (void *)0 +#define NULL (void *)0 #endif /* NULL */ /* probably should not put STATUS here */ @@ -64,30 +78,32 @@ typedef enum { CANCEL, } STATUS; -#define BIT(nr) (1UL << (nr)) +#define BIT(nr) (1UL << (nr)) -#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b)) -#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b)) +#define REG_WRITE(_r, _v) (*(volatile uint32 *)(_r)) = (_v) +#define REG_READ(_r) (*(volatile uint32 *)(_r)) + +#define REG_SET_BIT(_r, _b) (*(volatile uint32 *)(_r) |= (_b)) +#define REG_CLR_BIT(_r, _b) (*(volatile uint32 *)(_r) &= ~(_b)) + +#define __packed __attribute__((packed)) +#define STORE_ATTR __attribute__((aligned(4))) -#define DMEM_ATTR __attribute__((section(".bss"))) #define SHMEM_ATTR - -#define IRAM_ATTR __attribute__((section(".text"))) - #define ICACHE_FLASH_ATTR -#define ICACHE_RODATA_ATTR __attribute__((section(".irom.text"))) -#define STORE_ATTR __attribute__((aligned(4))) +#define DMEM_ATTR __attribute__((section(".bss"))) +#define IRAM_ATTR __attribute__((section(".text"))) +#define ICACHE_RODATA_ATTR __attribute__((section(".irom.text"))) #ifndef __cplusplus -typedef unsigned char bool; #define BOOL bool -#define true (1) -#define false (0) #define TRUE true #define FALSE false - - #endif /* !__cplusplus */ +#ifdef __cplusplus +} +#endif + #endif /* _C_TYPES_H_ */ diff --git a/include/espressif/esp8266/eagle_soc.h b/include/espressif/esp8266/eagle_soc.h index 80ad70c5..8379280a 100644 --- a/include/espressif/esp8266/eagle_soc.h +++ b/include/espressif/esp8266/eagle_soc.h @@ -1,5 +1,24 @@ /* - * Copyright (c) Espressif System 2010 - 2012 + * 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. * */ @@ -43,21 +62,21 @@ //Registers Operation {{ #define ETS_UNCACHED_ADDR(addr) (addr) -#define ETS_CACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) -#define READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) -#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val) -#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask)))) -#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask))) -#define GET_PERI_REG_BITS(reg, hipos,lowpos) ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)) -#define SET_PERI_REG_BITS(reg,bit_map,value,shift) (WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|((value)<<(shift)) )) +#define READ_PERI_REG(addr) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) +#define WRITE_PERI_REG(addr, val) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) = (uint32)(val) +#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg) & (~(mask)))) +#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg) | (mask))) +#define GET_PERI_REG_BITS(reg, hipos, lowpos) ((READ_PERI_REG(reg) >> (lowpos)) & ((1 << ((hipos) - (lowpos) + 1)) - 1)) +#define SET_PERI_REG_BITS(reg, bit_map, value, shift) (WRITE_PERI_REG((reg), (READ_PERI_REG(reg) & (~((bit_map) << (shift)))) | ((value) << (shift)) )) //}} //Periheral Clock {{ -#define CPU_CLK_FREQ 80*1000000 // unit: Hz +#define CPU_CLK_FREQ 80 * 1000000 // unit: Hz #define APB_CLK_FREQ CPU_CLK_FREQ #define UART_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (APB_CLK_FREQ>>8) // divided by 256 +#define TIMER_CLK_FREQ (APB_CLK_FREQ >> 8) // divided by 256 //}} //Peripheral device base address define{{ @@ -81,7 +100,7 @@ //}} //Interrupt remap control registers define{{ -#define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR+0x04) +#define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) #define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) #define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) //}} diff --git a/include/espressif/esp8266/esp8266.h b/include/espressif/esp8266/esp8266.h index 1c7a6d26..1eb417f4 100644 --- a/include/espressif/esp8266/esp8266.h +++ b/include/espressif/esp8266/esp8266.h @@ -1,5 +1,24 @@ /* - * Copyright (c) 2014 - 2016 Espressif System + * 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. * */ diff --git a/include/espressif/esp8266/ets_sys.h b/include/espressif/esp8266/ets_sys.h index 55e04352..28736eb6 100644 --- a/include/espressif/esp8266/ets_sys.h +++ b/include/espressif/esp8266/ets_sys.h @@ -1,7 +1,24 @@ /* - * copyright (c) 2008 - 2011 Espressif System + * ESPRSSIF MIT License * - * Define user specified Event signals and Task priorities here + * 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. * */ @@ -17,4 +34,30 @@ #define ETS_WDT_INUM 8 #define ETS_FRC_TIMER1_INUM 9 +extern char NMIIrqIsOn; +extern uint32 WDEV_INTEREST_EVENT; + +#define INT_ENA_WDEV 0x3ff20c18 +#define WDEV_TSF0_REACH_INT (BIT(27)) + +#define ETS_INTR_LOCK() do { \ + if (NMIIrqIsOn == 0) { \ + vPortEnterCritical(); \ + char m = 10; \ + do { \ + REG_WRITE(INT_ENA_WDEV, 0); \ + m = 10; \ + for (; m > 0; m--) {} \ + REG_WRITE(INT_ENA_WDEV, WDEV_TSF0_REACH_INT); \ + } while(0); \ + } \ + } while(0) + +#define ETS_INTR_UNLOCK() do { \ + if (NMIIrqIsOn == 0) { \ + REG_WRITE(INT_ENA_WDEV, WDEV_INTEREST_EVENT); \ + vPortExitCritical(); \ + } \ + } while(0) + #endif /* _ETS_SYS_H */ diff --git a/include/espressif/esp8266/gpio_register.h b/include/espressif/esp8266/gpio_register.h index 9e8d7c45..90988128 100644 --- a/include/espressif/esp8266/gpio_register.h +++ b/include/espressif/esp8266/gpio_register.h @@ -1,5 +1,24 @@ /* - * copyright (c) Espressif System 2014 + * 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. * */ @@ -24,7 +43,7 @@ #define GPIO_OUT_DATA_MASK 0x0000ffff #define GPIO_ENABLE_ADDRESS 0x0c -#define GPIO_SDIO_SEL 0x0000003f +#define GPIO_SDIO_SEL 0x0000003f #define GPIO_SDIO_SEL_S 16 #define GPIO_ENABLE_DATA 0x0000ffff #define GPIO_ENABLE_DATA_S 0 @@ -36,7 +55,7 @@ #define GPIO_ENABLE_W1TC_ADDRESS 0x14 #define GPIO_ENABLE_DATA_W1TC 0x0000ffff #define GPIO_ENABLE_DATA_W1TC_S 0 -#define GPIO_ENABLE_DATA_DATA_MASK 0x0000ffff +#define GPIO_ENABLE_DATA_DATA_MASK 0x0000ffff #define GPIO_IN_ADDRESS 0x18 #define GPIO_STRAPPING 0x0000ffff @@ -55,7 +74,7 @@ #define GPIO_STATUS_W1TC_ADDRESS 0x24 #define GPIO_STATUS_INTERRUPT_W1TC 0x0000ffff #define GPIO_STATUS_INTERRUPT_W1TC_S 0 -#define GPIO_STATUS_INTERRUPT_DATA_MASK 0x0000ffff +#define GPIO_STATUS_INTERRUPT_DATA_MASK 0x0000ffff //Region1: used for gpio config for GPIO_PIN0_ADDRESS~GPIO_PIN15_ADDRESS #define GPIO_ID_PIN0 0 @@ -95,7 +114,7 @@ #define GPIO_PIN_SOURCE_MSB 0 #define GPIO_PIN_SOURCE_LSB 0 #define GPIO_PIN_SOURCE_MASK (0x00000001<> GPIO_PIN_INT_TYPE_LSB) +#define GPIO_PIN_SOURCE_GET(x) (((x) & GPIO_PIN_INT_TYPE_MASK) >> GPIO_PIN_INT_TYPE_LSB) #define GPIO_PIN_SOURCE_SET(x) (((x) << GPIO_PIN_SOURCE_LSB) & GPIO_PIN_SOURCE_MASK) //end of region1 @@ -254,7 +273,7 @@ #define GPIO_PIN12_DRIVER_S 2 #define GPIO_PIN12_SOURCE BIT0 #define GPIO_PIN12_SOURCE_S 0 - + #define GPIO_PIN13_ADDRESS 0x5c #define GPIO_PIN13_CONFIG 0x00000003 #define GPIO_PIN13_CONFIG_S 11 diff --git a/include/espressif/esp8266/pin_mux_register.h b/include/espressif/esp8266/pin_mux_register.h index 08dd40a6..33a2e769 100644 --- a/include/espressif/esp8266/pin_mux_register.h +++ b/include/espressif/esp8266/pin_mux_register.h @@ -1,12 +1,31 @@ /* - * Copyright (c) Espressif System 2010 - 2012 + * 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 _PIN_MUX_H_ #define _PIN_MUX_H_ -#define PERIPHS_IO_MUX 0x60000800 +#define PERIPHS_IO_MUX 0x60000800 #define PERIPHS_IO_MUX_FUNC 0x13 #define PERIPHS_IO_MUX_FUNC_S 4 @@ -126,8 +145,8 @@ #define PIN_PULLUP_EN(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME, PERIPHS_IO_MUX_PULLUP) #define PIN_FUNC_SELECT(PIN_NAME, FUNC) do { \ - CLEAR_PERI_REG_MASK(PIN_NAME, (PERIPHS_IO_MUX_FUNC< + * + * 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. * */ diff --git a/include/espressif/esp8266/timer_register.h b/include/espressif/esp8266/timer_register.h index a90c3669..24062202 100644 --- a/include/espressif/esp8266/timer_register.h +++ b/include/espressif/esp8266/timer_register.h @@ -1,13 +1,32 @@ - /* - * Copyright (c) 2010 - 2011 Espressif System +/* + * 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 _TIMER_REGISTER_H_ -#define _TIMER_REGISTER_H_ +#ifndef _TIMER_REGISTER_H_ +#define _TIMER_REGISTER_H_ #define PERIPHS_TIMER_BASEDDR 0x60000600 - + #define FRC1_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x0) #define TIMER_FRC1_LOAD_VALUE 0x007FFFFF #define TIMER_FRC1_LOAD_VALUE_S 0 diff --git a/include/espressif/esp8266/uart_register.h b/include/espressif/esp8266/uart_register.h index 89a8ec8b..a6a1a2a1 100644 --- a/include/espressif/esp8266/uart_register.h +++ b/include/espressif/esp8266/uart_register.h @@ -1,5 +1,24 @@ /* - * Copyright (c) 2010 - 2011 Espressif System + * 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. * */ diff --git a/include/espressif/esp_common.h b/include/espressif/esp_common.h index bc9ab59b..2f4ae1e0 100644 --- a/include/espressif/esp_common.h +++ b/include/espressif/esp_common.h @@ -1,11 +1,95 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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 __ESP_COMMON_H__ #define __ESP_COMMON_H__ +/** \mainpage esp_iot_rtos_sdk + * + * - Misc APIs : misc APIs + * - WiFi APIs : WiFi related APIs + * - SoftAP APIs : ESP8266 Soft-AP APIs + * - Station APIs : ESP8266 station APIs + * - Common APIs : WiFi common APIs + * - Force Sleep APIs : WiFi Force Sleep APIs + * - Rate Control APIs : WiFi Rate Control APIs + * - User IE APIs : WiFi User IE APIs + * - Sniffer APIs : WiFi sniffer APIs + * - WPS APIs : WiFi WPS APIs + * - Smartconfig APIs : SmartConfig APIs + * - Spiffs APIs : Spiffs APIs + * - SSC APIs : Simple Serial Command APIs + * - System APIs : System APIs + * - Boot APIs : Boot mode APIs + * - Upgrade APIs : Firmware upgrade (FOTA) APIs + * - Software timer APIs : Software timer APIs + * - Network Espconn APIs : Network espconn APIs + * - ESP-NOW APIs : ESP-NOW APIs + * - Mesh APIs : Mesh APIs + * - Driver APIs : Driver APIs + * - PWM Driver APIs : PWM driver APIs + * - UART Driver APIs : UART driver APIs + * - GPIO Driver APIs : GPIO driver APIs + * - SPI Driver APIs : SPI Flash APIs + * - Hardware timer APIs : Hardware timer APIs + * + * void user_init(void) is the entrance function of the application. + * @attention 1. It is recommended that users set the timer to the periodic mode + * for periodic checks. + * @attention (1). In freeRTOS timer or os_timer, do not delay by while(1) or + * in the manner that will block the thread. + * @attention (2). The timer callback should not occupy CPU more than 15ms. + * @attention (3). os_timer_t should not define a local variable, it has to be global varialbe + * or memory got by malloc. + * + * @attention 2. Since esp_iot_rtos_sdk_v1.0.4, functions are stored in CACHE by + * default, need not be added ICACHE_FLASH_ATTR any more. The interrupt + * functions can also be stored in CACHE. If users want to store some + * frequently called functions in RAM, please add IRAM_ATTR before + * functions' name. + * + * @attention 3. Network programming use socket, please do not bind to the same port. + * @attention (1). If users want to create 3 or more than 3 TCP connection, please add + * "TCP_WND = 2 x TCP_MSS;" in "user_init". + * + * @attention 4. Priority of the RTOS SDK is 15. xTaskCreate is an interface of + * freeRTOS. For details of the freeRTOS and APIs of the system, + * please visit http://www.freertos.org + * @attention (1). When using xTaskCreate to create a task, the task stack range is [176, 512]. + * @attention (2). If an array whose length is over 60 bytes is used in a task, + * it is suggested that users use malloc and free rather than local + * variable to allocate array. Large local variables could lead to + * task stack overflow. + * @attention (3). The RTOS SDK takes some priorities. Priority of the pp task is + * 13; priority of precise timer(ms) thread is 12; priority of the + * TCP/IP task is 10; priority of the freeRTOS timer is 2; priority of + * the idle task is 0. + * @attention (4). Users can use tasks with priorities from 1 to 9. + * @attention (5). Do not revise FreeRTOSConfig.h, configurations are decided by source code + * inside the RTOS SDK, users can not change it. + */ + #include "c_types.h" #include "esp_libc.h" #include "esp_misc.h" @@ -14,6 +98,8 @@ #include "esp_sta.h" #include "esp_system.h" #include "esp_timer.h" +#include "esp_ssc.h" +#include "esp_spiffs.h" #include "esp8266/esp8266.h" diff --git a/include/espressif/esp_libc.h b/include/espressif/esp_libc.h index f8ad2df6..c95e2afb 100644 --- a/include/espressif/esp_libc.h +++ b/include/espressif/esp_libc.h @@ -1,11 +1,34 @@ /* - * Copyright (c) 2010 - 2011 Espressif System + * 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 __ESP_LIBC_H__ #define __ESP_LIBC_H__ +#ifdef __cplusplus +extern "C" { +#endif + char *strcpy(char *dst, const char *src); char *strncpy(char *dst, const char *src, size_t n); int strcmp(const char *s1, const char *s2); @@ -50,9 +73,13 @@ unsigned long os_random(void); int os_get_random(unsigned char *buf, size_t len); /* NOTE: don't use printf_opt in irq handler, for test */ -#define os_printf(fmt, ...) do { \ - static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = fmt; \ - printf(flash_str, ##__VA_ARGS__); \ - } while(0) +#define os_printf(fmt, ...) do { \ + static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = fmt; \ + printf(flash_str, ##__VA_ARGS__); \ + } while(0) + +#ifdef __cplusplus +} +#endif #endif /* __LIBC_H__ */ diff --git a/include/espressif/esp_misc.h b/include/espressif/esp_misc.h index 881670da..177ee1e8 100644 --- a/include/espressif/esp_misc.h +++ b/include/espressif/esp_misc.h @@ -1,5 +1,24 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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. * */ @@ -8,6 +27,18 @@ #include "lwip/ip_addr.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Misc_APIs Misc APIs + * @brief misc APIs + */ + +/** @addtogroup Misc_APIs + * @{ + */ + #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" @@ -18,24 +49,60 @@ #define IPSTR "%d.%d.%d.%d" +/** + * @brief Delay function, maximum value: 65535 us. + * + * @param uint16 us : delay time, uint: us, maximum value: 65535 us + * + * @return null + */ void os_delay_us(uint16 us); +/** + * @brief Register the print output function. + * + * @attention os_install_putc1((void *)uart1_write_char) in uart_init will set + * printf to print from UART 1, otherwise, printf will start from + * UART 0 by default. + * + * @param void(*p)(char c) - pointer of print function + * + * @return null + */ void os_install_putc1(void (*p)(char c)); + +/** + * @brief Print a character. Start from from UART0 by default. + * + * @param char c - character to be printed + * + * @return null + */ void os_putc(char c); -enum dhcp_status{ - DHCP_STOPPED, - DHCP_STARTED +enum dhcp_status { + DHCP_STOPPED, /**< disable DHCP */ + DHCP_STARTED /**< enable DHCP */ }; struct dhcps_lease { - struct ip_addr start_ip; - struct ip_addr end_ip; + bool enable; /**< enable DHCP lease or not */ + struct ip_addr start_ip; /**< start IP of IP range */ + struct ip_addr end_ip; /**< end IP of IP range */ }; -enum dhcps_offer_option{ - OFFER_START = 0x00, - OFFER_ROUTER = 0x01, - OFFER_END +enum dhcps_offer_option { + OFFER_START = 0x00, /**< DHCP offer option start */ + OFFER_ROUTER = 0x01, /**< DHCP offer router, only support this option now */ + OFFER_END /**< DHCP offer option start */ }; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_softap.h b/include/espressif/esp_softap.h index 0078c486..bd3683fb 100644 --- a/include/espressif/esp_softap.h +++ b/include/espressif/esp_softap.h @@ -1,5 +1,24 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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. * */ @@ -8,37 +27,264 @@ #include "queue.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup SoftAP_APIs SoftAP APIs + * @brief ESP8266 Soft-AP APIs + * @attention To call APIs related to ESP8266 soft-AP has to enable soft-AP mode first (wifi_set_opmode) + */ + +/** @addtogroup SoftAP_APIs + * @{ + */ + struct softap_config { - uint8 ssid[32]; - uint8 password[64]; - uint8 ssid_len; - uint8 channel; - AUTH_MODE authmode; - uint8 ssid_hidden; - uint8 max_connection; - uint16 beacon_interval; + uint8 ssid[32]; /**< SSID of ESP8266 soft-AP */ + uint8 password[64]; /**< Password of ESP8266 soft-AP */ + uint8 ssid_len; /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */ + uint8 channel; /**< Channel of ESP8266 soft-AP */ + AUTH_MODE authmode; /**< Auth mode of ESP8266 soft-AP. Do not support AUTH_WEP in soft-AP mode */ + uint8 ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ + uint8 max_connection; /**< Max number of stations allowed to connect in, default 4, max 4 */ + uint16 beacon_interval; /**< Beacon interval, 100 ~ 60000 ms, default 100 */ }; struct station_info { - STAILQ_ENTRY(station_info) next; + STAILQ_ENTRY(station_info) next; /**< Information of next AP */ - u8 bssid[6]; - struct ip_addr ip; + uint8 bssid[6]; /**< BSSID of AP */ + struct ip_addr ip; /**< IP address of AP */ }; +/** + * @brief Get the current configuration of the ESP8266 WiFi soft-AP + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_get_config(struct softap_config *config); + +/** + * @brief Get the configuration of the ESP8266 WiFi soft-AP saved in the flash + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_get_config_default(struct softap_config *config); + +/** + * @brief Set the configuration of the WiFi soft-AP and save it to the Flash. + * + * @attention 1. This configuration will be saved in flash system parameter area if changed + * @attention 2. The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_set_config(struct softap_config *config); + +/** + * @brief Set the configuration of the WiFi soft-AP; the configuration will + * not be saved to the Flash. + * + * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_set_config_current(struct softap_config *config); +/** + * @brief Get the number of stations connected to the ESP8266 soft-AP. + * + * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param null + * + * @return the number of stations connected to the ESP8266 soft-AP + */ uint8 wifi_softap_get_station_num(void); -struct station_info * wifi_softap_get_station_info(void); + +/** + * @brief Get the information of stations connected to the ESP8266 soft-AP, + * including MAC and IP. + * + * @attention wifi_softap_get_station_info can not get the static IP, it can only + * be used when DHCP is enabled. + * + * @param null + * + * @return struct station_info* : station information structure + */ +struct station_info *wifi_softap_get_station_info(void); + +/** + * @brief Free the space occupied by station_info when wifi_softap_get_station_info is called. + * + * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param null + * + * @return null + */ void wifi_softap_free_station_info(void); +/** + * @brief Enable the ESP8266 soft-AP DHCP server. + * + * @attention 1. The DHCP is enabled by default. + * @attention 2. The DHCP and the static IP related API (wifi_set_ip_info) influence + * each other, if the DHCP is enabled, the static IP will be disabled; + * if the static IP is enabled, the DHCP will be disabled. + * It depends on the latest configuration. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_dhcps_start(void); + +/** + * @brief Disable the ESP8266 soft-AP DHCP server. The DHCP is enabled by default. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_dhcps_stop(void); + +/** + * @brief Get the ESP8266 soft-AP DHCP server status. + * + * @param null + * + * @return enum dhcp_status + */ enum dhcp_status wifi_softap_dhcps_status(void); + +/** + * @brief Query the IP range that can be got from the ESP8266 soft-AP DHCP server. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param struct dhcps_lease *please : IP range of the ESP8266 soft-AP DHCP server. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_get_dhcps_lease(struct dhcps_lease *please); + +/** + * @brief Set the IP range of the ESP8266 soft-AP DHCP server. + * + * @attention 1. The IP range should be in the same sub-net with the ESP8266 + * soft-AP IP address. + * @attention 2. This API should only be called when the DHCP server is disabled + * (wifi_softap_dhcps_stop). + * @attention 3. This configuration will only take effect the next time when the + * DHCP server is enabled (wifi_softap_dhcps_start). + * - If the DHCP server is disabled again, this API should be called to set the IP range. + * - Otherwise, when the DHCP server is enabled later, the default IP range will be used. + * + * @param struct dhcps_lease *please : IP range of the ESP8266 soft-AP DHCP server. + * + * @return true : succeed + * @return false : fail + */ bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please); -bool wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg); + +/** + * @brief Get ESP8266 soft-AP DHCP server lease time. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param null + * + * @return lease time, uint: minute. + */ +uint32 wifi_softap_get_dhcps_lease_time(void); + +/** + * @brief Set ESP8266 soft-AP DHCP server lease time, default is 120 minutes. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param uint32 minute : lease time, uint: minute, range:[1, 2880]. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_dhcps_lease_time(uint32 minute); + +/** + * @brief Reset ESP8266 soft-AP DHCP server lease time which is 120 minutes by default. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_reset_dhcps_lease_time(void); + +/** + * @brief Set the ESP8266 soft-AP DHCP server option. + * + * Example: + *
 
+  *         uint8 mode = 0;
+  *         wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode);
+  * 
+ * + * @param uint8 level : OFFER_ROUTER, set the router option. + * @param void* optarg : + * - bit0, 0 disable the router information; + * - bit0, 1 enable the router information. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_dhcps_offer_option(uint8 level, void *optarg); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif #endif diff --git a/include/espressif/esp_spiffs.h b/include/espressif/esp_spiffs.h new file mode 100644 index 00000000..2d83a5be --- /dev/null +++ b/include/espressif/esp_spiffs.h @@ -0,0 +1,84 @@ +/* + * 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 __ESP_SPIFFS_H__ +#define __ESP_SPIFFS_H__ + +#include "spiffs/spiffs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Spiffs_APIs Spiffs APIs + * @brief Spiffs APIs + * + * More details about spiffs on https://github.com/pellepl/spiffs + * + */ + +/** @addtogroup Spiffs_APIs + * @{ + */ + +struct esp_spiffs_config { + uint32 phys_size; /**< physical size of the SPI Flash */ + uint32 phys_addr; /**< physical offset in spi flash used for spiffs, must be on block boundary */ + uint32 phys_erase_block; /**< physical size when erasing a block */ + + uint32 log_block_size; /**< logical size of a block, must be on physical block size boundary and must never be less than a physical block */ + uint32 log_page_size; /**< logical size of a page, at least log_block_size/8 */ + + uint32 fd_buf_size; /**< file descriptor memory area size */ + uint32 cache_buf_size; /**< cache buffer size */ +}; + +/** + * @brief Initialize spiffs + * + * @param struct esp_spiffs_config *config : ESP8266 spiffs configuration + * + * @return 0 : succeed + * @return otherwise : fail + */ +sint32 esp_spiffs_init(struct esp_spiffs_config *config); + +/** + * @brief Deinitialize spiffs + * + * @param uint8 format : 0, only deinit; otherwise, deinit spiffs and format. + * + * @return null + */ +void esp_spiffs_deinit(uint8 format); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_SPIFFS_H__ */ diff --git a/include/espressif/esp_ssc.h b/include/espressif/esp_ssc.h new file mode 100644 index 00000000..a214566a --- /dev/null +++ b/include/espressif/esp_ssc.h @@ -0,0 +1,125 @@ +/* + * 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 __ESP_SSC_H__ +#define __ESP_SSC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define CMD_T_ASYNC 0x01 +#define CMD_T_SYNC 0x02 + +typedef struct cmd_s { + char *cmd_str; + uint8 flag; + uint8 id; + void (* cmd_func)(void); + void (* cmd_callback)(void *arg); +} ssc_cmd_t; + +#define MAX_LINE_N 127 + +typedef enum { + SSC_BR_9600 = 9600, + SSC_BR_19200 = 19200, + SSC_BR_38400 = 38400, + SSC_BR_57600 = 57600, + SSC_BR_74880 = 74880, + SSC_BR_115200 = 115200, + SSC_BR_230400 = 230400, + SSC_BR_460800 = 460800, + SSC_BR_921600 = 921600 +} SscBaudRate; + +/** \defgroup SSC_APIs SSC APIs + * @brief SSC APIs + * + * SSC means simple serial command. + * SSC APIs allows users to define their own command, users can refer to spiffs_test/test_main.c. + * + */ + +/** @addtogroup SSC_APIs + * @{ + */ + +/** + * @brief Initial the ssc function. + * + * @param SscBaudRate bandrate : baud rate + * + * @return null + */ +void ssc_attach(SscBaudRate bandrate); + +/** + * @brief Get the length of the simple serial command. + * + * @param null + * + * @return length of the command. + */ +int ssc_param_len(void); + +/** + * @brief Get the simple serial command string. + * + * @param null + * + * @return the command. + */ +char *ssc_param_str(void); + +/** + * @brief Parse the simple serial command (ssc). + * + * @param char *pLine : [input] the ssc string + * @param char *argv[] : [output] parameters of the ssc + * + * @return the number of parameters. + */ +int ssc_parse_param(char *pLine, char *argv[]); + +/** + * @brief Register the user-defined simple serial command (ssc) set. + * + * @param ssc_cmd_t *cmdset : the ssc set + * @param uint8 cmdnum : number of commands + * @param void (* help)(void) : callback of user-guide + * + * @return null + */ +void ssc_register(ssc_cmd_t *cmdset, uint8 cmdnum, void (* help)(void)); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_SSC_H__ */ diff --git a/include/espressif/esp_sta.h b/include/espressif/esp_sta.h index d4bf0af0..15a76128 100644 --- a/include/espressif/esp_sta.h +++ b/include/espressif/esp_sta.h @@ -1,5 +1,24 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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. * */ @@ -8,67 +27,348 @@ #include "queue.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup Station_APIs Station APIs + * @brief ESP8266 station APIs + * @attention To call APIs related to ESP8266 station has to enable station mode + * first (wifi_set_opmode) + */ + +/** @addtogroup Station_APIs + * @{ + */ + struct station_config { - uint8 ssid[32]; - uint8 password[64]; - uint8 bssid_set; - uint8 bssid[6]; + uint8 ssid[32]; /**< SSID of target AP*/ + uint8 password[64]; /**< password of target AP*/ + uint8 bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ + uint8 bssid[6]; /**< MAC address of target AP*/ }; +/** + * @brief Get the current configuration of the ESP8266 WiFi station. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_get_config(struct station_config *config); + +/** + * @brief Get the configuration parameters saved in the Flash of the ESP8266 WiFi station. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_get_config_default(struct station_config *config); + +/** + * @brief Set the configuration of the ESP8266 station and save it to the Flash. + * + * @attention 1. This API can be called only when the ESP8266 station is enabled. + * @attention 2. If wifi_station_set_config is called in user_init , there is no + * need to call wifi_station_connect. + * The ESP8266 station will automatically connect to the AP (router) + * after the system initialization. Otherwise, wifi_station_connect should be called. + * @attention 3. Generally, station_config.bssid_set needs to be 0; and it needs + * to be 1 only when users need to check the MAC address of the AP. + * @attention 4. This configuration will be saved in the Flash system parameter area if changed. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_set_config(struct station_config *config); + +/** + * @brief Set the configuration of the ESP8266 station. And the configuration + * will not be saved to the Flash. + * + * @attention 1. This API can be called only when the ESP8266 station is enabled. + * @attention 2. If wifi_station_set_config_current is called in user_init , there + * is no need to call wifi_station_connect. + * The ESP8266 station will automatically connect to the AP (router) + * after the system initialization. Otherwise, wifi_station_connect + * should be called. + * @attention 3. Generally, station_config.bssid_set needs to be 0; and it needs + * to be 1 only when users need to check the MAC address of the AP. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_set_config_current(struct station_config *config); +/** + * @brief Connect the ESP8266 WiFi station to the AP. + * + * @attention 1. This API should be called when the ESP8266 station is enabled, + * and the system initialization is completed. Do not call this API in user_init. + * @attention 2. If the ESP8266 is connected to an AP, call wifi_station_disconnect to disconnect. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_connect(void); + +/** + * @brief Disconnect the ESP8266 WiFi station from the AP. + * + * @attention This API should be called when the ESP8266 station is enabled, + * and the system initialization is completed. Do not call this API in user_init. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_disconnect(void); struct scan_config { - uint8 *ssid; - uint8 *bssid; - uint8 channel; - uint8 show_hidden; + uint8 *ssid; /**< SSID of AP */ + uint8 *bssid; /**< MAC address of AP */ + uint8 channel; /**< channel, scan the specific channel */ + uint8 show_hidden; /**< enable to scan AP whose SSID is hidden */ }; struct bss_info { - STAILQ_ENTRY(bss_info) next; + STAILQ_ENTRY(bss_info) next; /**< information of next AP */ - uint8 bssid[6]; - uint8 ssid[32]; - uint8 channel; - sint8 rssi; - AUTH_MODE authmode; - uint8 is_hidden; + uint8 bssid[6]; /**< MAC address of AP */ + uint8 ssid[32]; /**< SSID of AP */ + uint8 ssid_len; /**< SSID length */ + uint8 channel; /**< channel of AP */ + sint8 rssi; /**< single strength of AP */ + AUTH_MODE authmode; /**< authmode of AP */ + uint8 is_hidden; /**< SSID of current AP is hidden or not. */ + sint16 freq_offset; /**< frequency offset */ + sint16 freqcal_val; + uint8 *esp_mesh_ie; }; +/** + * @brief Callback function for wifi_station_scan. + * + * @param void *arg : information of APs that are found; save them as linked list; + * refer to struct bss_info + * @param STATUS status : status of scanning + * + * @return null + */ typedef void (* scan_done_cb_t)(void *arg, STATUS status); +/** + * @brief Scan all available APs. + * + * @attention This API should be called when the ESP8266 station is enabled, and + * the system initialization is completed. Do not call this API in user_init. + * + * @param struct scan_config *config : configuration of scanning + * @param struct scan_done_cb_t cb : callback of scanning + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb); -uint8 wifi_station_get_auto_connect(void); -bool wifi_station_set_auto_connect(uint8 set); +/** + * @brief Check if the ESP8266 station will connect to the recorded AP automatically + * when the power is on. + * + * @param null + * + * @return true : connect to the AP automatically + * @return false : not connect to the AP automatically + */ +bool wifi_station_get_auto_connect(void); -bool wifi_station_set_reconnect_policy(bool set); +/** + * @brief Set whether the ESP8266 station will connect to the recorded AP + * automatically when the power is on. It will do so by default. + * + * @attention 1. If this API is called in user_init, it is effective immediately + * after the power is on. If it is called in other places, it will + * be effective the next time when the power is on. + * @attention 2. This configuration will be saved in Flash system parameter area if changed. + * + * @param bool set : If it will automatically connect to the AP when the power is on + * - true : it will connect automatically + * - false: it will not connect automatically + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_auto_connect(bool set); + +/** + * @brief Check whether the ESP8266 station will reconnect to the AP after disconnection. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_get_reconnect_policy(void); -enum { - STATION_IDLE = 0, - STATION_CONNECTING, - STATION_WRONG_PASSWORD, - STATION_NO_AP_FOUND, - STATION_CONNECT_FAIL, - STATION_GOT_IP -}; +/** + * @brief Set whether the ESP8266 station will reconnect to the AP after disconnection. + * It will do so by default. + * + * @attention If users want to call this API, it is suggested that users call this API in user_init. + * + * @param bool set : if it's true, it will enable reconnection; if it's false, + * it will disable reconnection. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_reconnect_policy(bool set); -uint8 wifi_station_get_connect_status(void); +typedef enum { + STATION_IDLE = 0, /**< ESP8266 station idle */ + STATION_CONNECTING, /**< ESP8266 station is connecting to AP*/ + STATION_WRONG_PASSWORD, /**< the password is wrong*/ + STATION_NO_AP_FOUND, /**< ESP8266 station can not find the target AP*/ + STATION_CONNECT_FAIL, /**< ESP8266 station fail to connect to AP*/ + STATION_GOT_IP /**< ESP8266 station got IP address from AP*/ +} STATION_STATUS; +/** + * @brief Get the connection status of the ESP8266 WiFi station. + * + * @param null + * + * @return the status of connection + */ +STATION_STATUS wifi_station_get_connect_status(void); + +/** + * @brief Get the information of APs (5 at most) recorded by ESP8266 station. + * + * @param struct station_config config[] : information of the APs, the array size should be 5. + * + * @return The number of APs recorded. + */ uint8 wifi_station_get_current_ap_id(void); + +/** + * @brief Switch the ESP8266 station connection to a recorded AP. + * + * @param uint8 new_ap_id : AP's record id, start counting from 0. + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_ap_change(uint8 current_ap_id); + +/** + * @brief Set the number of APs that can be recorded in the ESP8266 station. + * When the ESP8266 station is connected to an AP, the SSID and password + * of the AP will be recorded. + * + * @attention This configuration will be saved in the Flash system parameter area if changed. + * + * @param uint8 ap_number : the number of APs that can be recorded (MAX: 5) + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_ap_number_set(uint8 ap_number); + +/** + * @brief Get the information of APs (5 at most) recorded by ESP8266 station. + * + * Example: + *
 
+  *         struct station_config config[5];
+  *         nt i = wifi_station_get_ap_info(config);
+  * 
+ * + * @param struct station_config config[] : information of the APs, the array size should be 5. + * + * @return The number of APs recorded. + */ uint8 wifi_station_get_ap_info(struct station_config config[]); +/** + * @brief Get rssi of the AP which ESP8266 station connected to. + * + * @param null + * + * @return 31 : fail, invalid value. + * @return others : succeed, value of rssi. In general, rssi value < 10 + */ +sint8 wifi_station_get_rssi(void); + +/** + * @brief Enable the ESP8266 station DHCP client. + * + * @attention 1. The DHCP is enabled by default. + * @attention 2. The DHCP and the static IP API ((wifi_set_ip_info)) influence each other, + * and if the DHCP is enabled, the static IP will be disabled; + * if the static IP is enabled, the DHCP will be disabled. + * It depends on the latest configuration. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_dhcpc_start(void); + +/** + * @brief Disable the ESP8266 station DHCP client. + * + * @attention 1. The DHCP is enabled by default. + * @attention 2. The DHCP and the static IP API ((wifi_set_ip_info)) influence each other, + * and if the DHCP is enabled, the static IP will be disabled; + * if the static IP is enabled, the DHCP will be disabled. + * It depends on the latest configuration. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool wifi_station_dhcpc_stop(void); + +/** + * @brief Get the ESP8266 station DHCP client status. + * + * @param null + * + * @return enum dhcp_status + */ enum dhcp_status wifi_station_dhcpc_status(void); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_system.h b/include/espressif/esp_system.h index 93288648..1cd257f8 100644 --- a/include/espressif/esp_system.h +++ b/include/espressif/esp_system.h @@ -1,5 +1,24 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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. * */ @@ -8,89 +27,559 @@ #include "c_types.h" -enum rst_reason { - REASON_DEFAULT_RST = 0, - REASON_WDT_RST, - REASON_EXCEPTION_RST, - REASON_SOFT_WDT_RST, - REASON_SOFT_RESTART, - REASON_DEEP_SLEEP_AWAKE, - REASON_EXT_SYS_RST +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup System_APIs System APIs + * @brief System APIs + */ + +/** @addtogroup System_APIs + * @{ + */ + +typedef enum { + REASON_DEFAULT_RST = 0, /**< normal startup by power on */ + REASON_WDT_RST, /**< hardware watch dog reset */ + REASON_EXCEPTION_RST, /**< exception reset, GPIO status won't change */ + REASON_SOFT_WDT_RST, /**< software watch dog reset, GPIO status won't change */ + REASON_SOFT_RESTART, /**< software restart ,system_restart , GPIO status won't change */ + REASON_DEEP_SLEEP_AWAKE, /**< wake up from deep-sleep */ + REASON_EXT_SYS_RST /**< external system reset */ +} rst_reason; + +struct rst_info { + rst_reason reason; /**< enum rst_reason */ + uint32 exccause; + uint32 epc1; + uint32 epc2; + uint32 epc3; + uint32 excvaddr; + uint32 depc; + uint32 rtn_addr; }; -struct rst_info{ - uint32 reason; - uint32 exccause; - uint32 epc1; - uint32 epc2; - uint32 epc3; - uint32 excvaddr; - uint32 depc; - uint32 rtn_addr; -}; +/** + * @brief Get the reason of restart. + * + * @param null + * + * @return struct rst_info* : information of the system restart + */ +struct rst_info *system_get_rst_info(void); -struct rst_info* system_get_rst_info(void); - -const char* system_get_sdk_version(void); +/** + * @brief Get information of the SDK version. + * + * @param null + * + * @return Information of the SDK version. + */ +const char *system_get_sdk_version(void); +/** + * @brief Reset to default settings. + * + * Reset to default settings of the following APIs : wifi_station_set_auto_connect, + * wifi_set_phy_mode, wifi_softap_set_config related, wifi_station_set_config + * related, and wifi_set_opmode. + * + * @param null + * + * @return null + */ void system_restore(void); + +/** + * @brief Restart system. + * + * @param null + * + * @return null + */ void system_restart(void); +/** + * @brief Set the chip to deep-sleep mode. + * + * The device will automatically wake up after the deep-sleep time set + * by the users. Upon waking up, the device boots up from user_init. + * + * @attention 1. XPD_DCDC should be connected to EXT_RSTB through 0 ohm resistor + * in order to support deep-sleep wakeup. + * @attention 2. system_deep_sleep(0): there is no wake up timer; in order to wake + * up, connect a GPIO to pin RST, the chip will wake up by a falling-edge + * on pin RST + * + * @param uint32 time_in_us : deep-sleep time, unit: microsecond + * + * @return null + */ void system_deep_sleep(uint32 time_in_us); + +/** + * @brief Call this API before system_deep_sleep to set the activity after the + * next deep-sleep wakeup. + * + * If this API is not called, default to be system_deep_sleep_set_option(1). + * + * @param uint8 option : + * @param 0 : Radio calibration after the deep-sleep wakeup is decided by byte + * 108 of esp_init_data_default.bin (0~127byte). + * @param 1 : Radio calibration will be done after the deep-sleep wakeup. This + * will lead to stronger current. + * @param 2 : Radio calibration will not be done after the deep-sleep wakeup. + * This will lead to weaker current. + * @param 4 : Disable radio calibration after the deep-sleep wakeup (the same + * as modem-sleep). This will lead to the weakest current, but the device + * can't receive or transmit data after waking up. + * + * @return true : succeed + * @return false : fail + */ bool system_deep_sleep_set_option(uint8 option); -#define SYS_BOOT_ENHANCE_MODE 0 -#define SYS_BOOT_NORMAL_MODE 1 - -#define SYS_BOOT_NORMAL_BIN 0 -#define SYS_BOOT_TEST_BIN 1 - -uint8 system_get_boot_version(void); -uint32 system_get_userbin_addr(void); -uint8 system_get_boot_mode(void); -bool system_restart_enhance(uint8 bin_type, uint32 bin_addr); - -uint8 system_upgrade_userbin_check(void); -void system_upgrade_reboot(void); -uint8 system_upgrade_flag_check(); -void system_upgrade_flag_set(uint8 flag); - +/** + * @brief Get system time, unit: microsecond. + * + * @param null + * + * @return System time, unit: microsecond. + */ uint32 system_get_time(void); +/** + * @brief Print the system memory distribution, including data/rodata/bss/heap. + * + * @param null + * + * @return null + */ void system_print_meminfo(void); +/** + * @brief Get the size of available heap. + * + * @param null + * + * @return Available heap size. + */ uint32 system_get_free_heap_size(void); + +/** + * @brief Get the chip ID. + * + * @param null + * + * @return The chip ID. + */ uint32 system_get_chip_id(void); +/** + * @brief Get the RTC clock cycle. + * + * @attention 1. The RTC clock cycle has decimal part. + * @attention 2. The RTC clock cycle will change according to the temperature, + * so RTC timer is not very precise. + * + * @param null + * + * @return RTC clock period (unit: microsecond), bit11~ bit0 are decimal. + */ uint32 system_rtc_clock_cali_proc(void); + +/** + * @brief Get RTC time, unit: RTC clock cycle. + * + * Example: + * If system_get_rtc_time returns 10 (it means 10 RTC cycles), and + * system_rtc_clock_cali_proc returns 5.75 (it means 5.75 microseconds per RTC clock cycle), + * (then the actual time is 10 x 5.75 = 57.5 microseconds. + * + * @attention System time will return to zero because of system_restart, but the + * RTC time still goes on. If the chip is reset by pin EXT_RST or pin + * CHIP_EN (including the deep-sleep wakeup), situations are shown as below: + * @attention 1. reset by pin EXT_RST : RTC memory won't change, RTC timer returns to zero + * @attention 2. watchdog reset : RTC memory won't change, RTC timer won't change + * @attention 3. system_restart : RTC memory won't change, RTC timer won't change + * @attention 4. power on : RTC memory is random value, RTC timer starts from zero + * @attention 5. reset by pin CHIP_EN : RTC memory is random value, RTC timer starts from zero + * + * @param null + * + * @return RTC time. + */ uint32 system_get_rtc_time(void); +/** + * @brief Read user data from the RTC memory. + * + * The user data segment (512 bytes, as shown below) is used to store user data. + * + * |<---- system data(256 bytes) ---->|<----------- user data(512 bytes) --------->| + * + * @attention Read and write unit for data stored in the RTC memory is 4 bytes. + * @attention src_addr is the block number (4 bytes per block). So when reading data + * at the beginning of the user data segment, src_addr will be 256/4 = 64, + * n will be data length. + * + * @param uint8 src : source address of rtc memory, src_addr >= 64 + * @param void *dst : data pointer + * @param uint16 n : data length, unit: byte + * + * @return true : succeed + * @return false : fail + */ bool system_rtc_mem_read(uint8 src, void *dst, uint16 n); + +/** + * @brief Write user data to the RTC memory. + * + * During deep-sleep, only RTC is working. So users can store their data + * in RTC memory if it is needed. The user data segment below (512 bytes) + * is used to store the user data. + * + * |<---- system data(256 bytes) ---->|<----------- user data(512 bytes) --------->| + * + * @attention Read and write unit for data stored in the RTC memory is 4 bytes. + * @attention src_addr is the block number (4 bytes per block). So when storing data + * at the beginning of the user data segment, src_addr will be 256/4 = 64, + * n will be data length. + * + * @param uint8 src : source address of rtc memory, src_addr >= 64 + * @param void *dst : data pointer + * @param uint16 n : data length, unit: byte + * + * @return true : succeed + * @return false : fail + */ bool system_rtc_mem_write(uint8 dst, const void *src, uint16 n); +/** + * @brief UART0 swap. + * + * Use MTCK as UART0 RX, MTDO as UART0 TX, so ROM log will not output from + * this new UART0. We also need to use MTDO (U0CTS) and MTCK (U0RTS) as UART0 in hardware. + * + * @param null + * + * @return null + */ void system_uart_swap(void); + +/** + * @brief Disable UART0 swap. + * + * Use the original UART0, not MTCK and MTDO. + * + * @param null + * + * @return null + */ void system_uart_de_swap(void); +/** + * @brief Measure the input voltage of TOUT pin 6, unit : 1/1024 V. + * + * @attention 1. system_adc_read can only be called when the TOUT pin is connected + * to the external circuitry, and the TOUT pin input voltage should + * be limited to 0~1.0V. + * @attention 2. When the TOUT pin is connected to the external circuitry, the 107th + * byte (vdd33_const) of esp_init_data_default.bin(0~127byte) should be + * set as the real power voltage of VDD3P3 pin 3 and 4. + * @attention 3. The unit of vdd33_const is 0.1V, the effective value range is [18, 36]; + * if vdd33_const is in [0, 18) or (36, 255), 3.3V is used to optimize RF by default. + * + * @param null + * + * @return Input voltage of TOUT pin 6, unit : 1/1024 V + */ uint16 system_adc_read(void); + +/** + * @brief Measure the power voltage of VDD3P3 pin 3 and 4, unit : 1/1024 V. + * + * @attention 1. system_get_vdd33 can only be called when TOUT pin is suspended. + * @attention 2. The 107th byte in esp_init_data_default.bin (0~127byte) is named + * as "vdd33_const", when TOUT pin is suspended vdd33_const must be + * set as 0xFF, that is 255. + * + * @param null + * + * @return Power voltage of VDD33, unit : 1/1024 V + */ uint16 system_get_vdd33(void); -enum flash_size_map { - FLASH_SIZE_4M_MAP_256_256 = 0, - FLASH_SIZE_2M, - FLASH_SIZE_8M_MAP_512_512, - FLASH_SIZE_16M_MAP_512_512, - FLASH_SIZE_32M_MAP_512_512, - FLASH_SIZE_16M_MAP_1024_1024, - FLASH_SIZE_32M_MAP_1024_1024 -}; - -enum flash_size_map system_get_flash_size_map(void); - +/** + * @brief Write data into flash with protection. + * + * Flash read/write has to be 4-bytes aligned. + * + * Protection of flash read/write : + * use 3 sectors (4KBytes per sector) to save 4KB data with protect, + * sector 0 and sector 1 are data sectors, back up each other, + * save data alternately, sector 2 is flag sector, point out which sector + * is keeping the latest data, sector 0 or sector 1. + * + * @param uint16 start_sec : start sector (sector 0) of the 3 sectors which are + * used for flash read/write protection. + * - For example, in IOT_Demo we can use the 3 sectors (3 * 4KB) starting from flash + * 0x3D000 for flash read/write protection, so the parameter start_sec should be 0x3D + * @param void *param : pointer of the data to be written + * @param uint16 len : data length, should be less than a sector, which is 4 * 1024 + * + * @return true : succeed + * @return false : fail + */ bool system_param_save_with_protect(uint16 start_sec, void *param, uint16 len); + +/** + * @brief Read the data saved into flash with the read/write protection. + * + * Flash read/write has to be 4-bytes aligned. + * + * Read/write protection of flash: + * use 3 sectors (4KB per sector) to save 4KB data with protect, sector + * 0 and sector 1 are data sectors, back up each other, save data alternately, + * sector 2 is flag sector, point out which sector is keeping the latest data, + * sector 0 or sector 1. + * + * @param uint16 start_sec : start sector (sector 0) of the 3 sectors used for + * flash read/write protection. It cannot be sector 1 or sector 2. + * - For example, in IOT_Demo, the 3 sectors (3 * 4KB) starting from flash 0x3D000 + * can be used for flash read/write protection. + * The parameter start_sec is 0x3D, and it cannot be 0x3E or 0x3F. + * @param uint16 offset : offset of data saved in sector + * @param void *param : data pointer + * @param uint16 len : data length, offset + len =< 4 * 1024 + * + * @return true : succeed + * @return false : fail + */ bool system_param_load(uint16 start_sec, uint16 offset, void *param, uint16 len); +/** + * @brief Set the maximum value of RF TX Power, unit : 0.25dBm. + * + * @param uint8 max_tpw : the maximum value of RF Tx Power, unit : 0.25dBm, range [0, 82]. + * It can be set refer to the 34th byte (target_power_qdb_0) + * of esp_init_data_default.bin(0~127byte) + * + * @return null + */ void system_phy_set_max_tpw(uint8 max_tpw); + +/** + * @brief Adjust the RF TX Power according to VDD33, unit : 1/1024 V. + * + * @attention 1. When TOUT pin is suspended, VDD33 can be measured by system_get_vdd33. + * @attention 2. When TOUT pin is connected to the external circuitry, system_get_vdd33 + * can not be used to measure VDD33. + * + * @param uint16 vdd33 : VDD33, unit : 1/1024V, range [1900, 3300] + * + * @return null + */ void system_phy_set_tpw_via_vdd33(uint16 vdd33); + +/** + * @brief Enable RF or not when wakeup from deep-sleep. + * + * @attention 1. This API can only be called in user_rf_pre_init. + * @attention 2. Function of this API is similar to system_deep_sleep_set_option, + * if they are both called, it will disregard system_deep_sleep_set_option + * which is called before deep-sleep, and refer to system_phy_set_rfoption + * which is called when deep-sleep wake up. + * @attention 3. Before calling this API, system_deep_sleep_set_option should be called + * once at least. + * + * @param uint8 option : + * - 0 : Radio calibration after deep-sleep wake up depends on esp_init_data_default.bin (0~127byte) byte 108. + * - 1 : Radio calibration is done after deep-sleep wake up; this increases the + * current consumption. + * - 2 : No radio calibration after deep-sleep wake up; this reduces the current consumption. + * - 4 : Disable RF after deep-sleep wake up, just like modem sleep; this has the + * least current consumption; the device is not able to transmit or receive + * data after wake up. + * + * @return null + */ void system_phy_set_rfoption(uint8 option); +/** @addtogroup Upgrade_APIs + * @{ + */ + +/** + * @brief Check the user bin. + * + * @param null + * + * @return 0x00 : UPGRADE_FW_BIN1, i.e. user1.bin + * @return 0x01 : UPGRADE_FW_BIN2, i.e. user2.bin + */ +uint8 system_upgrade_userbin_check(void); + +/** + * @brief Reboot system to use the new software. + * + * @param null + * + * @return null + */ +void system_upgrade_reboot(void); + +/** + * @brief Check the upgrade status flag. + * + * @param null + * + * @return #define UPGRADE_FLAG_IDLE 0x00 + * @return #define UPGRADE_FLAG_START 0x01 + * @return #define UPGRADE_FLAG_FINISH 0x02 + */ +uint8 system_upgrade_flag_check(); + +/** + * @brief Set the upgrade status flag. + * + * @attention After downloading new softwares, set the flag to UPGRADE_FLAG_FINISH + * and call system_upgrade_reboot to reboot the system in order to run + * the new software. + * + * @param uint8 flag: + * - UPGRADE_FLAG_IDLE 0x00 + * - UPGRADE_FLAG_START 0x01 + * - UPGRADE_FLAG_FINISH 0x02 + * + * @return null + */ +void system_upgrade_flag_set(uint8 flag); + +/** + * @} + */ + +/** \defgroup System_boot_APIs Boot APIs + * @brief boot APIs + */ + +/** @addtogroup System_boot_APIs + * @{ + */ + +#define SYS_BOOT_ENHANCE_MODE 0 /**< It can load and run firmware at any address, for Espressif factory test bin*/ +#define SYS_BOOT_NORMAL_MODE 1 /**< It can only load and run at some addresses of user1.bin (or user2.bin)*/ + +#define SYS_BOOT_NORMAL_BIN 0 /**< user1.bin or user2.bin*/ +#define SYS_BOOT_TEST_BIN 1 /**< can only be Espressif test bin*/ + +/** + * @brief Get information of the boot version. + * + * @attention If boot version >= 1.3 , users can enable the enhanced boot mode + * (refer to system_restart_enhance). + * + * @param null + * + * @return Information of the boot version. + */ +uint8 system_get_boot_version(void); + +/** + * @brief Get the address of the current running user bin (user1.bin or user2.bin). + * + * @param null + * + * @return The address of the current running user bin. + */ +uint32 system_get_userbin_addr(void); + +/** + * @brief Get the boot mode. + * + * @param null + * + * @return #define SYS_BOOT_ENHANCE_MODE 0 + * @return #define SYS_BOOT_NORMAL_MODE 1 + */ +uint8 system_get_boot_mode(void); + +/** + * @brief Restarts the system, and enters the enhanced boot mode. + * + * @attention SYS_BOOT_TEST_BIN is used for factory test during production; users + * can apply for the test bin from Espressif Systems. + * + * @param uint8 bin_type : type of bin + * - #define SYS_BOOT_NORMAL_BIN 0 // user1.bin or user2.bin + * - #define SYS_BOOT_TEST_BIN 1 // can only be Espressif test bin + * @param uint32 bin_addr : starting address of the bin file + * + * @return true : succeed + * @return false : fail + */ +bool system_restart_enhance(uint8 bin_type, uint32 bin_addr); + +typedef enum { + FLASH_SIZE_4M_MAP_256_256 = 0, /**< Flash size : 4Mbits. Map : 256KBytes + 256KBytes */ + FLASH_SIZE_2M, /**< Flash size : 2Mbits. Map : 256KBytes */ + FLASH_SIZE_8M_MAP_512_512, /**< Flash size : 8Mbits. Map : 512KBytes + 512KBytes */ + FLASH_SIZE_16M_MAP_512_512, /**< Flash size : 16Mbits. Map : 512KBytes + 512KBytes */ + FLASH_SIZE_32M_MAP_512_512, /**< Flash size : 32Mbits. Map : 512KBytes + 512KBytes */ + FLASH_SIZE_16M_MAP_1024_1024, /**< Flash size : 16Mbits. Map : 1024KBytes + 1024KBytes */ + FLASH_SIZE_32M_MAP_1024_1024 /**< Flash size : 32Mbits. Map : 1024KBytes + 1024KBytes */ +} flash_size_map; + +/** + * @brief Get the current Flash size and Flash map. + * + * Flash map depends on the selection when compiling, more details in document + * "2A-ESP8266__IOT_SDK_User_Manual" + * + * @param null + * + * @return enum flash_size_map + */ +flash_size_map system_get_flash_size_map(void); + +#define SYS_CPU_80MHZ 80 +#define SYS_CPU_160MHZ 160 + +/** + * @brief Set CPU frequency. Default is 80MHz. + * + * System bus frequency is 80MHz, will not be affected by CPU frequency. + * The frequency of UART, SPI, or other peripheral devices, are divided + * from system bus frequency, so they will not be affected by CPU frequency either. + * + * @param uint8 freq : CPU frequency, 80 or 160. + * + * @return true : succeed + * @return false : fail + */ +bool system_update_cpu_freq(uint8 freq); + +/** + * @brief Get CPU frequency. + * + * @param null + * + * @return CPU frequency, unit : MHz. + */ +uint8 system_get_cpu_freq(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_timer.h b/include/espressif/esp_timer.h index 42f9785c..74d1b84c 100644 --- a/include/espressif/esp_timer.h +++ b/include/espressif/esp_timer.h @@ -1,16 +1,39 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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 __ESP_TIMER_H__ #define __ESP_TIMER_H__ +#ifdef __cplusplus +extern "C" { +#endif + /* timer related */ typedef void os_timer_func_t(void *timer_arg); typedef struct _os_timer_t { - struct _os_timer_t *timer_next; + struct _os_timer_t *timer_next; void *timer_handle; uint32 timer_expire; uint32 timer_period; @@ -19,8 +42,60 @@ typedef struct _os_timer_t { void *timer_arg; } os_timer_t; +/** \defgroup Timer_APIs Software timer APIs + * @brief Software timer APIs + * + * Timers of the following interfaces are software timers. Functions of the timers are executed during the tasks. + * Since a task can be stopped, or be delayed because there are other tasks with higher priorities, the following os_timer interfaces cannot guarantee the precise execution of the timers. + * - For the same timer, os_timer_arm (or os_timer_arm_us) cannot be invoked repeatedly. os_timer_disarm should be invoked first. + * - os_timer_setfn can only be invoked when the timer is not enabled, i.e., after os_timer_disarm or before os_timer_arm (or os_timer_arm_us). + * + */ + +/** @addtogroup Timer_APIs + * @{ + */ + +/** + * @brief Set the timer callback function. + * + * @attention 1. The callback function must be set in order to enable the timer. + * @attention 2. Operating system scheduling is disabled in timer callback. + * + * @param os_timer_t *ptimer : Timer structure + * @param os_timer_func_t *pfunction : timer callback function + * @param void *parg : callback function parameter + * + * @return null + */ void os_timer_setfn(os_timer_t *ptimer, os_timer_func_t *pfunction, void *parg); -void os_timer_arm(os_timer_t *ptimer, uint32_t msec, bool repeat_flag); + +/** + * @brief Enable the millisecond timer. + * + * @param os_timer_t *ptimer : timer structure + * @param uint32_t milliseconds : Timing, unit: millisecond, the maximum value allowed is 0x41893 + * @param bool repeat_flag : Whether the timer will be invoked repeatedly or not + * + * @return null + */ +void os_timer_arm(os_timer_t *ptimer, uint32 msec, bool repeat_flag); + +/** + * @brief Disarm the timer + * + * @param os_timer_t *ptimer : Timer structure + * + * @return null + */ void os_timer_disarm(os_timer_t *ptimer); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h index 331cdc1a..ed791588 100644 --- a/include/espressif/esp_wifi.h +++ b/include/espressif/esp_wifi.h @@ -1,171 +1,989 @@ /* - * Copyright (C) 2013 -2014 Espressif System + * 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 __ESP_WIFI_H__ #define __ESP_WIFI_H__ -enum { - NULL_MODE = 0, - STATION_MODE, - SOFTAP_MODE, - STATIONAP_MODE, - MAX_MODE -}; +#ifdef __cplusplus +extern "C" { +#endif -typedef enum _auth_mode { - AUTH_OPEN = 0, - AUTH_WEP, - AUTH_WPA_PSK, - AUTH_WPA2_PSK, - AUTH_WPA_WPA2_PSK, +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WiFi_Common_APIs Common APIs + * @brief WiFi common APIs + * + * The Flash system parameter area is the last 16KB of the Flash. + * + */ + +/** @addtogroup WiFi_Common_APIs + * @{ + */ + +typedef enum { + NULL_MODE = 0, /**< null mode */ + STATION_MODE, /**< WiFi station mode */ + SOFTAP_MODE, /**< WiFi soft-AP mode */ + STATIONAP_MODE, /**< WiFi station + soft-AP mode */ + MAX_MODE +} WIFI_MODE; + +typedef enum { + AUTH_OPEN = 0, /**< authenticate mode : open */ + AUTH_WEP, /**< authenticate mode : WEP */ + AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */ + AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */ + AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */ AUTH_MAX } AUTH_MODE; -uint8 wifi_get_opmode(void); -uint8 wifi_get_opmode_default(void); -bool wifi_set_opmode(uint8 opmode); -bool wifi_set_opmode_current(uint8 opmode); +/** + * @brief Get the current operating mode of the WiFi. + * + * @param null + * + * @return WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + */ +WIFI_MODE wifi_get_opmode(void); -enum { - STATION_IF = 0, - SOFTAP_IF, - MAX_IF -}; +/** + * @brief Get the operating mode of the WiFi saved in the Flash. + * + * @param null + * + * @return WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + */ +WIFI_MODE wifi_get_opmode_default(void); + +/** + * @brief Set the WiFi operating mode, and save it to Flash. + * + * Set the WiFi operating mode as station, soft-AP or station+soft-AP, + * and save it to Flash. The default mode is soft-AP mode. + * + * @attention This configuration will be saved in the Flash system parameter area if changed. + * + * @param uint8 opmode : WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_opmode(WIFI_MODE opmode); + +/** + * @brief Set the WiFi operating mode, and will not save it to Flash. + * + * Set the WiFi operating mode as station, soft-AP or station+soft-AP, and + * the mode won't be saved to the Flash. + * + * @param uint8 opmode : WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_opmode_current(WIFI_MODE opmode); + +typedef enum { + STATION_IF = 0, /**< ESP8266 station interface */ + SOFTAP_IF, /**< ESP8266 soft-AP interface */ + MAX_IF +} WIFI_INTERFACE; struct ip_info { - struct ip_addr ip; - struct ip_addr netmask; - struct ip_addr gw; + struct ip_addr ip; /**< IP address */ + struct ip_addr netmask; /**< netmask */ + struct ip_addr gw; /**< gateway */ }; -bool wifi_get_ip_info(uint8 if_index, struct ip_info *info); -bool wifi_set_ip_info(uint8 if_index, struct ip_info *info); +/** + * @brief Get the IP address of the ESP8266 WiFi station or the soft-AP interface. + * + * @attention Users need to enable the target interface (station or soft-AP) by wifi_set_opmode first. + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param struct ip_info *info : the IP information obtained. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_get_ip_info(WIFI_INTERFACE if_index, struct ip_info *info); -bool wifi_get_macaddr(uint8 if_index, uint8 *macaddr); -bool wifi_set_macaddr(uint8 if_index, uint8 *macaddr); +/** + * @brief Set the IP address of the ESP8266 WiFi station or the soft-AP interface. + * + * @attention 1. Users need to enable the target interface (station or soft-AP) by + * wifi_set_opmode first. + * @attention 2. To set static IP, users need to disable DHCP first (wifi_station_dhcpc_stop + * or wifi_softap_dhcps_stop): + * - If the DHCP is enabled, the static IP will be disabled; if the static IP is enabled, + * the DHCP will be disabled. It depends on the latest configuration. + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param struct ip_info *info : the IP information obtained. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_ip_info(WIFI_INTERFACE if_index, struct ip_info *info); -uint8 wifi_get_channel(void); -bool wifi_set_channel(uint8 channel); +/** + * @brief Get MAC address of the ESP8266 WiFi station or the soft-AP interface. + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param uint8 *macaddr : the MAC address. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_get_macaddr(WIFI_INTERFACE if_index, uint8 *macaddr); +/** + * @brief Set MAC address of the ESP8266 WiFi station or the soft-AP interface. + * + * @attention 1. This API can only be called in user_init. + * @attention 2. Users need to enable the target interface (station or soft-AP) by wifi_set_opmode first. + * @attention 3. ESP8266 soft-AP and station have different MAC addresses, do not set them to be the same. + * - The bit0 of the first byte of ESP8266 MAC address can not be 1. For example, the MAC address + * can set to be "1a:XX:XX:XX:XX:XX", but can not be "15:XX:XX:XX:XX:XX". + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param uint8 *macaddr : the MAC address. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_macaddr(WIFI_INTERFACE if_index, uint8 *macaddr); + +/** + * @brief Install the WiFi status LED. + * + * @param uint8 gpio_id : GPIO ID + * @param uint8 gpio_name : GPIO mux name + * @param uint8 gpio_func : GPIO function + * + * @return null + */ void wifi_status_led_install(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func); + +/** + * @brief Uninstall the WiFi status LED. + * + * @param null + * + * @return null + */ void wifi_status_led_uninstall(void); -bool wifi_promiscuous_set_mac(const uint8_t *address); +typedef enum { + PHY_MODE_11B = 1, /**< 802.11b */ + PHY_MODE_11G = 2, /**< 802.11g */ + PHY_MODE_11N = 3 /**< 802.11n */ +} WIFI_PHY_MODE; -void wifi_promiscuous_enable(uint8 promiscuous); +/** + * @brief Get the ESP8266 physical mode (802.11b/g/n). + * + * @param null + * + * @return enum WIFI_PHY_MODE + */ +WIFI_PHY_MODE wifi_get_phy_mode(void); -typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len); +/** + * @brief Set the ESP8266 physical mode (802.11b/g/n). + * + * @attention The ESP8266 soft-AP only supports bg. + * + * @param WIFI_PHY_MODE mode : physical mode + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_phy_mode(WIFI_PHY_MODE mode); -void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); - -enum phy_mode { - PHY_MODE_11B = 1, - PHY_MODE_11G = 2, - PHY_MODE_11N = 3 -}; - -enum phy_mode wifi_get_phy_mode(void); -bool wifi_set_phy_mode(enum phy_mode mode); - -enum { - EVENT_STAMODE_SCAN_DONE = 0, - EVENT_STAMODE_CONNECTED, - EVENT_STAMODE_DISCONNECTED, - EVENT_STAMODE_AUTHMODE_CHANGE, - EVENT_STAMODE_GOT_IP, - EVENT_SOFTAPMODE_STACONNECTED, - EVENT_SOFTAPMODE_STADISCONNECTED, +typedef enum { + EVENT_STAMODE_SCAN_DONE = 0, /**< ESP8266 station finish scanning AP */ + EVENT_STAMODE_CONNECTED, /**< ESP8266 station connected to AP */ + EVENT_STAMODE_DISCONNECTED, /**< ESP8266 station disconnected to AP */ + EVENT_STAMODE_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP8266 station changed */ + EVENT_STAMODE_GOT_IP, /**< ESP8266 station got IP from connected AP */ + EVENT_STAMODE_DHCP_TIMEOUT, /**< ESP8266 station dhcp client got IP timeout */ + EVENT_SOFTAPMODE_STACONNECTED, /**< a station connected to ESP8266 soft-AP */ + EVENT_SOFTAPMODE_STADISCONNECTED, /**< a station disconnected to ESP8266 soft-AP */ + EVENT_SOFTAPMODE_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ EVENT_MAX -}; +} SYSTEM_EVENT; enum { - REASON_UNSPECIFIED = 1, - REASON_AUTH_EXPIRE = 2, - REASON_AUTH_LEAVE = 3, - REASON_ASSOC_EXPIRE = 4, - REASON_ASSOC_TOOMANY = 5, - REASON_NOT_AUTHED = 6, - REASON_NOT_ASSOCED = 7, - REASON_ASSOC_LEAVE = 8, - REASON_ASSOC_NOT_AUTHED = 9, - REASON_DISASSOC_PWRCAP_BAD = 10, - REASON_DISASSOC_SUPCHAN_BAD = 11, - REASON_IE_INVALID = 13, - REASON_MIC_FAILURE = 14, - REASON_4WAY_HANDSHAKE_TIMEOUT = 15, - REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, - REASON_IE_IN_4WAY_DIFFERS = 17, - REASON_GROUP_CIPHER_INVALID = 18, - REASON_PAIRWISE_CIPHER_INVALID = 19, - REASON_AKMP_INVALID = 20, - REASON_UNSUPP_RSN_IE_VERSION = 21, - REASON_INVALID_RSN_IE_CAP = 22, - REASON_802_1X_AUTH_FAILED = 23, - REASON_CIPHER_SUITE_REJECTED = 24, + REASON_UNSPECIFIED = 1, + REASON_AUTH_EXPIRE = 2, + REASON_AUTH_LEAVE = 3, + REASON_ASSOC_EXPIRE = 4, + REASON_ASSOC_TOOMANY = 5, + REASON_NOT_AUTHED = 6, + REASON_NOT_ASSOCED = 7, + REASON_ASSOC_LEAVE = 8, + REASON_ASSOC_NOT_AUTHED = 9, + REASON_DISASSOC_PWRCAP_BAD = 10, + REASON_DISASSOC_SUPCHAN_BAD = 11, + REASON_IE_INVALID = 13, + REASON_MIC_FAILURE = 14, + REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, + REASON_IE_IN_4WAY_DIFFERS = 17, + REASON_GROUP_CIPHER_INVALID = 18, + REASON_PAIRWISE_CIPHER_INVALID = 19, + REASON_AKMP_INVALID = 20, + REASON_UNSUPP_RSN_IE_VERSION = 21, + REASON_INVALID_RSN_IE_CAP = 22, + REASON_802_1X_AUTH_FAILED = 23, + REASON_CIPHER_SUITE_REJECTED = 24, - REASON_BEACON_TIMEOUT = 200, - REASON_NO_AP_FOUND = 201, + REASON_BEACON_TIMEOUT = 200, + REASON_NO_AP_FOUND = 201, + REASON_AUTH_FAIL = 202, + REASON_ASSOC_FAIL = 203, + REASON_HANDSHAKE_TIMEOUT = 204, }; typedef struct { - uint32 status; - struct bss_info *bss; + uint32 status; /**< status of scanning APs*/ + struct bss_info *bss; /**< list of APs found*/ } Event_StaMode_ScanDone_t; typedef struct { - uint8 ssid[32]; - uint8 ssid_len; - uint8 bssid[6]; - uint8 channel; + uint8 ssid[32]; /**< SSID of connected AP */ + uint8 ssid_len; /**< SSID length of connected AP */ + uint8 bssid[6]; /**< BSSID of connected AP*/ + uint8 channel; /**< channel of connected AP*/ } Event_StaMode_Connected_t; typedef struct { - uint8 ssid[32]; - uint8 ssid_len; - uint8 bssid[6]; - uint8 reason; -} Event_StaMode_Disconnected; + uint8 ssid[32]; /**< SSID of disconnected AP */ + uint8 ssid_len; /**< SSID length of disconnected AP */ + uint8 bssid[6]; /**< BSSID of disconnected AP */ + uint8 reason; /**< reason of disconnection */ +} Event_StaMode_Disconnected_t; typedef struct { - uint8 old_mode; - uint8 new_mode; + uint8 old_mode; /**< the old auth mode of AP */ + uint8 new_mode; /**< the new auth mode of AP */ } Event_StaMode_AuthMode_Change_t; typedef struct { - struct ip_addr ip; - struct ip_addr mask; - struct ip_addr gw; + struct ip_addr ip; /**< IP address that ESP8266 station got from connected AP */ + struct ip_addr mask; /**< netmask that ESP8266 station got from connected AP */ + struct ip_addr gw; /**< gateway that ESP8266 station got from connected AP */ } Event_StaMode_Got_IP_t; typedef struct { - uint8 mac[6]; - uint8 aid; + uint8 mac[6]; /**< MAC address of the station connected to ESP8266 soft-AP */ + uint8 aid; /**< the aid that ESP8266 soft-AP gives to the station connected to */ } Event_SoftAPMode_StaConnected_t; typedef struct { - uint8 mac[6]; - uint8 aid; + uint8 mac[6]; /**< MAC address of the station disconnects to ESP8266 soft-AP */ + uint8 aid; /**< the aid that ESP8266 soft-AP gave to the station disconnects to */ } Event_SoftAPMode_StaDisconnected_t; +typedef struct { + int rssi; /**< Received probe request signal strength */ + uint8 mac[6]; /**< MAC address of the station which send probe request */ +} Event_SoftAPMode_ProbeReqRecved_t; + typedef union { - Event_StaMode_ScanDone_t scan_done; - Event_StaMode_Connected_t connected; - Event_StaMode_Disconnected disconnected; - Event_StaMode_AuthMode_Change_t auth_change; - Event_StaMode_Got_IP_t got_ip; - Event_SoftAPMode_StaConnected_t sta_connected; - Event_SoftAPMode_StaDisconnected_t sta_disconnected; + Event_StaMode_ScanDone_t scan_done; /**< ESP8266 station scan (APs) done */ + Event_StaMode_Connected_t connected; /**< ESP8266 station connected to AP */ + Event_StaMode_Disconnected_t disconnected; /**< ESP8266 station disconnected to AP */ + Event_StaMode_AuthMode_Change_t auth_change; /**< the auth mode of AP ESP8266 station connected to changed */ + Event_StaMode_Got_IP_t got_ip; /**< ESP8266 station got IP */ + Event_SoftAPMode_StaConnected_t sta_connected; /**< a station connected to ESP8266 soft-AP */ + Event_SoftAPMode_StaDisconnected_t sta_disconnected; /**< a station disconnected to ESP8266 soft-AP */ + Event_SoftAPMode_ProbeReqRecved_t ap_probereqrecved; /**< ESP8266 softAP receive probe request packet */ } Event_Info_u; typedef struct _esp_event { - uint32 event_id; - Event_Info_u event_info; + SYSTEM_EVENT event_id; /**< even ID */ + Event_Info_u event_info; /**< event information */ } System_Event_t; +/** + * @brief The Wi-Fi event handler. + * + * @attention No complex operations are allowed in callback. + * If you want to execute any complex operations, please post message to another task instead. + * + * @param System_Event_t *event : WiFi event + * + * @return null + */ typedef void (* wifi_event_handler_cb_t)(System_Event_t *event); -void wifi_set_event_handler_cb(wifi_event_handler_cb_t cb); +/** + * @brief Register the Wi-Fi event handler. + * + * @param wifi_event_handler_cb_t cb : callback function + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_event_handler_cb(wifi_event_handler_cb_t cb); + +/** + * @brief Callback of sending user-define 802.11 packets. + * + * @param uint8 status : 0, packet sending succeed; otherwise, fail. + * + * @return null + */ +typedef void (*freedom_outside_cb_t)(uint8 status); + +/** + * @brief Register a callback for sending user-define 802.11 packets. + * + * @attention Only after the previous packet was sent, entered the freedom_outside_cb_t, + * the next packet is allowed to send. + * + * @param freedom_outside_cb_t cb : sent callback + * + * @return 0, succeed; + * @return -1, fail. + */ +sint32 wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb); + +/** + * @brief Unregister the callback for sending user-define 802.11 packets. + * + * @param null + * + * @return null + */ +void wifi_unregister_send_pkt_freedom_cb(void); + +/** + * @brief Send user-define 802.11 packets. + * + * @attention 1. Packet has to be the whole 802.11 packet, does not include the FCS. + * The length of the packet has to be longer than the minimum length + * of the header of 802.11 packet which is 24 bytes, and less than 1400 bytes. + * @attention 2. Duration area is invalid for user, it will be filled in SDK. + * @attention 3. The rate of sending packet is same as the management packet which + * is the same as the system rate of sending packets. + * @attention 4. Only after the previous packet was sent, entered the sent callback, + * the next packet is allowed to send. Otherwise, wifi_send_pkt_freedom + * will return fail. + * + * @param uint8 *buf : pointer of packet + * @param uint16 len : packet length + * @param bool sys_seq : follow the system's 802.11 packets sequence number or not, + * if it is true, the sequence number will be increased 1 every + * time a packet sent. + * + * @return 0, succeed; + * @return -1, fail. + */ +sint32 wifi_send_pkt_freedom(uint8 *buf, uint16 len, bool sys_seq); + +/** + * @brief Enable RFID LOCP (Location Control Protocol) to receive WDS packets. + * + * @param null + * + * @return 0, succeed; + * @return otherwise, fail. + */ +sint32 wifi_rfid_locp_recv_open(void); + +/** + * @brief Disable RFID LOCP (Location Control Protocol) . + * + * @param null + * + * @return null + */ +void wifi_rfid_locp_recv_close(void); + +/** + * @brief RFID LOCP (Location Control Protocol) receive callback . + * + * @param uint8 *frm : point to the head of 802.11 packet + * @param int len : packet length + * @param int rssi : signal strength + * + * @return null + */ +typedef void (*rfid_locp_cb_t)(uint8 *frm, int len, sint8 rssi); + +/** + * @brief Register a callback of receiving WDS packets. + * + * Register a callback of receiving WDS packets. Only if the first MAC + * address of the WDS packet is a multicast address. + * + * @param rfid_locp_cb_t cb : callback + * + * @return 0, succeed; + * @return otherwise, fail. + */ +sint32 wifi_register_rfid_locp_recv_cb(rfid_locp_cb_t cb); + +/** + * @brief Unregister the callback of receiving WDS packets. + * + * @param null + * + * @return null + */ +void wifi_unregister_rfid_locp_recv_cb(void); + +typedef enum { + NONE_SLEEP_T = 0, + LIGHT_SLEEP_T, + MODEM_SLEEP_T +} sleep_type; + +/** + * @brief Sets sleep type. + * + * Set NONE_SLEEP_T to disable sleep. Default to be Modem sleep. + * + * @attention Sleep function only takes effect in station-only mode. + * + * @param sleep_type type : sleep type + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_sleep_type(sleep_type type); + +/** + * @brief Gets sleep type. + * + * @param null + * + * @return sleep type + */ +sleep_type wifi_get_sleep_type(void); + +/** + * @} + */ + + +/** \defgroup WiFi_Force_Sleep_APIs Force Sleep APIs + * @brief WiFi Force Sleep APIs + */ + +/** @addtogroup WiFi_Force_Sleep_APIs + * @{ + */ + +/** + * @brief Enable force sleep function. + * + * @attention Force sleep function is disabled by default. + * + * @param null + * + * @return null + */ +void wifi_fpm_open(void); + +/** + * @brief Disable force sleep function. + * + * @param null + * + * @return null + */ +void wifi_fpm_close(void); + +/** + * @brief Wake ESP8266 up from MODEM_SLEEP_T force sleep. + * + * @attention This API can only be called when MODEM_SLEEP_T force sleep function + * is enabled, after calling wifi_fpm_open. + * This API can not be called after calling wifi_fpm_close. + * + * @param null + * + * @return null + */ +void wifi_fpm_do_wakeup(void); + +typedef void (*fpm_wakeup_cb)(void); + +/** + * @brief Set a callback of waken up from force sleep because of time out. + * + * @attention 1. This API can only be called when force sleep function is enabled, + * after calling wifi_fpm_open. This API can not be called after calling + * wifi_fpm_close. + * @attention 2. fpm_wakeup_cb_func will be called after system woke up only if the + * force sleep time out (wifi_fpm_do_sleep and the parameter is not 0xFFFFFFF). + * @attention 3. fpm_wakeup_cb_func will not be called if woke up by wifi_fpm_do_wakeup + * from MODEM_SLEEP_T type force sleep. + * + * @param void (*fpm_wakeup_cb_func)(void) : callback of waken up + * + * @return null + */ +void wifi_fpm_set_wakeup_cb(fpm_wakeup_cb cb); + +/** + * @brief Force ESP8266 enter sleep mode, and it will wake up automatically when time out. + * + * @attention 1. This API can only be called when force sleep function is enabled, after + * calling wifi_fpm_open. This API can not be called after calling wifi_fpm_close. + * @attention 2. If this API returned 0 means that the configuration is set successfully, + * but the ESP8266 will not enter sleep mode immediately, it is going to sleep + * in the system idle task. Please do not call other WiFi related function right + * after calling this API. + * + * @param uint32 sleep_time_in_us : sleep time, ESP8266 will wake up automatically + * when time out. Unit: us. Range: 10000 ~ 268435455(0xFFFFFFF). + * - If sleep_time_in_us is 0xFFFFFFF, the ESP8266 will sleep till + * - if wifi_fpm_set_sleep_type is set to be LIGHT_SLEEP_T, ESP8266 can wake up by GPIO. + * - if wifi_fpm_set_sleep_type is set to be MODEM_SLEEP_T, ESP8266 can wake up by wifi_fpm_do_wakeup. + * + * @return 0, setting succeed; + * @return -1, fail to sleep, sleep status error; + * @return -2, fail to sleep, force sleep function is not enabled. + */ +sint8 wifi_fpm_do_sleep(uint32 sleep_time_in_us); + +/** + * @brief Set sleep type for force sleep function. + * + * @attention This API can only be called before wifi_fpm_open. + * + * @param sleep_type type : sleep type + * + * @return null + */ +void wifi_fpm_set_sleep_type(sleep_type type); + +/** + * @brief Get sleep type of force sleep function. + * + * @param null + * + * @return sleep type + */ +sleep_type wifi_fpm_get_sleep_type(void); + +/** + * @} + */ + +/** \defgroup WiFi_Rate_Control_APIs Rate Control APIs + * @brief WiFi Rate Control APIs + */ + +/** @addtogroup WiFi_Rate_Control_APIs + * @{ + */ + +enum FIXED_RATE { + PHY_RATE_48 = 0x8, + PHY_RATE_24 = 0x9, + PHY_RATE_12 = 0xA, + PHY_RATE_6 = 0xB, + PHY_RATE_54 = 0xC, + PHY_RATE_36 = 0xD, + PHY_RATE_18 = 0xE, + PHY_RATE_9 = 0xF +}; + +#define FIXED_RATE_MASK_NONE 0x00 +#define FIXED_RATE_MASK_STA 0x01 +#define FIXED_RATE_MASK_AP 0x02 +#define FIXED_RATE_MASK_ALL 0x03 + +/** + * @brief Set the fixed rate and mask of sending data from ESP8266. + * + * @attention 1. Only if the corresponding bit in enable_mask is 1, ESP8266 station + * or soft-AP will send data in the fixed rate. + * @attention 2. If the enable_mask is 0, both ESP8266 station and soft-AP will not + * send data in the fixed rate. + * @attention 3. ESP8266 station and soft-AP share the same rate, they can not be + * set into the different rate. + * + * @param uint8 enable_mask : 0x00 - disable the fixed rate + * - 0x01 - use the fixed rate on ESP8266 station + * - 0x02 - use the fixed rate on ESP8266 soft-AP + * - 0x03 - use the fixed rate on ESP8266 station and soft-AP + * @param uint8 rate : value of the fixed rate + * + * @return 0 : succeed + * @return otherwise : fail + */ +sint32 wifi_set_user_fixed_rate(uint8 enable_mask, uint8 rate); + +/** + * @brief Get the fixed rate and mask of ESP8266. + * + * @param uint8 *enable_mask : pointer of the enable_mask + * @param uint8 *rate : pointer of the fixed rate + * + * @return 0 : succeed + * @return otherwise : fail + */ +int wifi_get_user_fixed_rate(uint8 *enable_mask, uint8 *rate); + +enum support_rate { + RATE_11B5M = 0, + RATE_11B11M = 1, + RATE_11B1M = 2, + RATE_11B2M = 3, + RATE_11G6M = 4, + RATE_11G12M = 5, + RATE_11G24M = 6, + RATE_11G48M = 7, + RATE_11G54M = 8, + RATE_11G9M = 9, + RATE_11G18M = 10, + RATE_11G36M = 11 +}; + +/** + * @brief Set the support rate of ESP8266. + * + * Set the rate range in the IE of support rate in ESP8266's beacon, + * probe req/resp and other packets. + * Tell other devices about the rate range supported by ESP8266 to limit + * the rate of sending packets from other devices. + * Example : wifi_set_user_sup_rate(RATE_11G6M, RATE_11G24M); + * + * @attention This API can only support 802.11g now, but it will support 802.11b in next version. + * + * @param uint8 min : the minimum value of the support rate, according to enum support_rate. + * @param uint8 max : the maximum value of the support rate, according to enum support_rate. + * + * @return 0 : succeed + * @return otherwise : fail + */ +sint32 wifi_set_user_sup_rate(uint8 min, uint8 max); + +enum RATE_11B_ID { + RATE_11B_B11M = 0, + RATE_11B_B5M = 1, + RATE_11B_B2M = 2, + RATE_11B_B1M = 3 +}; + +enum RATE_11G_ID { + RATE_11G_G54M = 0, + RATE_11G_G48M = 1, + RATE_11G_G36M = 2, + RATE_11G_G24M = 3, + RATE_11G_G18M = 4, + RATE_11G_G12M = 5, + RATE_11G_G9M = 6, + RATE_11G_G6M = 7, + RATE_11G_B5M = 8, + RATE_11G_B2M = 9, + RATE_11G_B1M = 10 +}; + +enum RATE_11N_ID { + RATE_11N_MCS7S = 0, + RATE_11N_MCS7 = 1, + RATE_11N_MCS6 = 2, + RATE_11N_MCS5 = 3, + RATE_11N_MCS4 = 4, + RATE_11N_MCS3 = 5, + RATE_11N_MCS2 = 6, + RATE_11N_MCS1 = 7, + RATE_11N_MCS0 = 8, + RATE_11N_B5M = 9, + RATE_11N_B2M = 10, + RATE_11N_B1M = 11 +}; + +#define RC_LIMIT_11B 0 +#define RC_LIMIT_11G 1 +#define RC_LIMIT_11N 2 +#define RC_LIMIT_P2P_11G 3 +#define RC_LIMIT_P2P_11N 4 +#define RC_LIMIT_NUM 5 + +#define LIMIT_RATE_MASK_NONE 0x00 +#define LIMIT_RATE_MASK_STA 0x01 +#define LIMIT_RATE_MASK_AP 0x02 +#define LIMIT_RATE_MASK_ALL 0x03 + +/** + * @brief Limit the initial rate of sending data from ESP8266. + * + * Example: + * wifi_set_user_rate_limit(RC_LIMIT_11G, 0, RATE_11G_G18M, RATE_11G_G6M); + * + * @attention The rate of retransmission is not limited by this API. + * + * @param uint8 mode : WiFi mode + * - #define RC_LIMIT_11B 0 + * - #define RC_LIMIT_11G 1 + * - #define RC_LIMIT_11N 2 + * @param uint8 ifidx : interface of ESP8266 + * - 0x00 - ESP8266 station + * - 0x01 - ESP8266 soft-AP + * @param uint8 max : the maximum value of the rate, according to the enum rate + * corresponding to the first parameter mode. + * @param uint8 min : the minimum value of the rate, according to the enum rate + * corresponding to the first parameter mode. + * + * @return 0 : succeed + * @return otherwise : fail + */ +bool wifi_set_user_rate_limit(uint8 mode, uint8 ifidx, uint8 max, uint8 min); + +/** + * @brief Get the interfaces of ESP8266 whose rate of sending data is limited by + * wifi_set_user_rate_limit. + * + * @param null + * + * @return LIMIT_RATE_MASK_NONE - disable the limitation on both ESP8266 station and soft-AP + * @return LIMIT_RATE_MASK_STA - enable the limitation on ESP8266 station + * @return LIMIT_RATE_MASK_AP - enable the limitation on ESP8266 soft-AP + * @return LIMIT_RATE_MASK_ALL - enable the limitation on both ESP8266 station and soft-AP + */ +uint8 wifi_get_user_limit_rate_mask(void); + +/** + * @brief Set the interfaces of ESP8266 whose rate of sending packets is limited by + * wifi_set_user_rate_limit. + * + * @param uint8 enable_mask : + * - LIMIT_RATE_MASK_NONE - disable the limitation on both ESP8266 station and soft-AP + * - LIMIT_RATE_MASK_STA - enable the limitation on ESP8266 station + * - LIMIT_RATE_MASK_AP - enable the limitation on ESP8266 soft-AP + * - LIMIT_RATE_MASK_ALL - enable the limitation on both ESP8266 station and soft-AP + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_user_limit_rate_mask(uint8 enable_mask); + +/** + * @} + */ + + +/** \defgroup WiFi_User_IE_APIs User IE APIs + * @brief WiFi User IE APIs + */ + +/** @addtogroup WiFi_User_IE_APIs + * @{ + */ + +typedef enum { + USER_IE_BEACON = 0, + USER_IE_PROBE_REQ, + USER_IE_PROBE_RESP, + USER_IE_ASSOC_REQ, + USER_IE_ASSOC_RESP, + USER_IE_MAX +} user_ie_type; + +/** + * @brief User IE received callback. + * + * @param user_ie_type type : type of user IE. + * @param const uint8 sa[6] : source address of the packet. + * @param const uint8 m_oui[3] : factory tag. + * @param uint8 *user_ie : pointer of user IE. + * @param uint8 ie_len : length of user IE. + * @param sint32 rssi : signal strength. + * + * @return null + */ +typedef void (*user_ie_manufacturer_recv_cb_t)(user_ie_type type, const uint8 sa[6], const uint8 m_oui[3], uint8 *ie, uint8 ie_len, sint32 rssi); + +/** + * @brief Set user IE of ESP8266. + * + * The user IE will be added to the target packets of user_ie_type. + * + * @param bool enable : + * - true, enable the corresponding user IE function, all parameters below have to be set. + * - false, disable the corresponding user IE function and release the resource, + * only the parameter "type" below has to be set. + * @param uint8 *m_oui : factory tag, apply for it from Espressif System. + * @param user_ie_type type : IE type. If it is USER_IE_BEACON, please disable the + * IE function and enable again to take the configuration + * effect immediately . + * @param uint8 *user_ie : user-defined information elements, need not input the whole + * 802.11 IE, need only the user-define part. + * @param uint8 len : length of user IE, 247 bytes at most. + * + * @return true : succeed + * @return false : fail + */ + +bool wifi_set_user_ie(bool enable, uint8 *m_oui, user_ie_type type, uint8 *user_ie, uint8 len); + +/** + * @brief Register user IE received callback. + * + * @param user_ie_manufacturer_recv_cb_t cb : callback + * + * @return 0 : succeed + * @return -1 : fail + */ +sint32 wifi_register_user_ie_manufacturer_recv_cb(user_ie_manufacturer_recv_cb_t cb); + +/** + * @brief Unregister user IE received callback. + * + * @param null + * + * @return null + */ +void wifi_unregister_user_ie_manufacturer_recv_cb(void); + +/** + * @} + */ + +/** \defgroup WiFi_Sniffer_APIs Sniffer APIs + * @brief WiFi sniffer APIs + */ + +/** @addtogroup WiFi_Sniffer_APIs + * @{ + */ + +/** + * @brief The RX callback function in the promiscuous mode. + * + * Each time a packet is received, the callback function will be called. + * + * @param uint8 *buf : the data received + * @param uint16 len : data length + * + * @return null + */ +typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len); + +/** + * @brief Register the RX callback function in the promiscuous mode. + * + * Each time a packet is received, the registered callback function will be called. + * + * @param wifi_promiscuous_cb_t cb : callback + * + * @return null + */ +void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); + +/** + * @brief Get the channel number for sniffer functions. + * + * @param null + * + * @return channel number + */ +uint8 wifi_get_channel(void); + +/** + * @brief Set the channel number for sniffer functions. + * + * @param uint8 channel : channel number + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_channel(uint8 channel); + +/** + * @brief Set the MAC address filter for the sniffer mode. + * + * @attention This filter works only for the current sniffer mode. + * If users disable and then enable the sniffer mode, and then enable + * sniffer, they need to set the MAC address filter again. + * + * @param const uint8_t *address : MAC address + * + * @return true : succeed + * @return false : fail + */ +bool wifi_promiscuous_set_mac(const uint8_t *address); + +/** + * @brief Enable the promiscuous mode. + * + * @attention 1. The promiscuous mode can only be enabled in the ESP8266 station mode. + * @attention 2. When in the promiscuous mode, the ESP8266 station and soft-AP are disabled. + * @attention 3. Call wifi_station_disconnect to disconnect before enabling the promiscuous mode. + * @attention 4. Don't call any other APIs when in the promiscuous mode. Call + * wifi_promiscuous_enable(0) to quit sniffer before calling other APIs. + * + * @param uint8 promiscuous : + * - 0: to disable the promiscuous mode + * - 1: to enable the promiscuous mode + * + * @return null + */ +void wifi_promiscuous_enable(uint8 promiscuous); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif #endif diff --git a/include/espressif/esp_wps.h b/include/espressif/esp_wps.h new file mode 100644 index 00000000..ca6ee951 --- /dev/null +++ b/include/espressif/esp_wps.h @@ -0,0 +1,139 @@ +/* + * 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 __ESPWPS_H__ +#define __ESPWPS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WPS_APIs WPS APIs + * @brief ESP8266 WPS APIs + * + * WPS can only be used when ESP8266 station is enabled. + * + */ + +/** @addtogroup WPS_APIs + * @{ + */ + +typedef enum wps_type { + WPS_TYPE_DISABLE = 0, + WPS_TYPE_PBC, + WPS_TYPE_PIN, + WPS_TYPE_DISPLAY, + WPS_TYPE_MAX, +} WPS_TYPE_t; + +enum wps_cb_status { + WPS_CB_ST_SUCCESS = 0, /**< WPS succeed */ + WPS_CB_ST_FAILED, /**< WPS fail */ + WPS_CB_ST_TIMEOUT, /**< WPS timeout, fail */ + WPS_CB_ST_WEP, /**< WPS failed because that WEP is not supported */ + WPS_CB_ST_SCAN_ERR, /**< can not find the target WPS AP */ +}; + +/** + * @brief Enable Wi-Fi WPS function. + * + * @attention WPS can only be used when ESP8266 station is enabled. + * + * @param WPS_TYPE_t wps_type : WPS type, so far only WPS_TYPE_PBC is supported + * + * @return true : succeed + * @return false : fail + */ +bool wifi_wps_enable(WPS_TYPE_t wps_type); + +/** + * @brief Disable Wi-Fi WPS function and release resource it taken. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_wps_disable(void); + +/** + * @brief WPS starts to work. + * + * @attention WPS can only be used when ESP8266 station is enabled. + * + * @param null + * + * @return true : WPS starts to work successfully, but does not mean WPS succeed. + * @return false : fail + */ +bool wifi_wps_start(void); + +/** + * @brief WPS callback. + * + * @param int status : status of WPS, enum wps_cb_status. + * - If parameter status == WPS_CB_ST_SUCCESS in WPS callback, it means WPS got AP's + * information, user can call wifi_wps_disable to disable WPS and release resource, + * then call wifi_station_connect to connect to target AP. + * - Otherwise, it means that WPS fail, user can create a timer to retry WPS by + * wifi_wps_start after a while, or call wifi_wps_disable to disable WPS and release resource. + * + * @return null + */ +typedef void (*wps_st_cb_t)(int status); + +/** + * @brief Set WPS callback. + * + * @attention WPS can only be used when ESP8266 station is enabled. + * + * @param wps_st_cb_t cb : callback. + * + * @return true : WPS starts to work successfully, but does not mean WPS succeed. + * @return false : fail + */ +bool wifi_set_wps_cb(wps_st_cb_t cb); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/espconn.h b/include/espressif/espconn.h new file mode 100644 index 00000000..c646fa14 --- /dev/null +++ b/include/espressif/espconn.h @@ -0,0 +1,691 @@ +/* + * 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 __ESPCONN_H__ +#define __ESPCONN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef sint8 err_t; + +typedef void *espconn_handle; + +/** \defgroup Espconn_APIs Network Espconn APIs + * @brief Network espconn APIs + * + */ + +/** @addtogroup Espconn_APIs + * @{ + */ + +/** + * @brief Connect callback. + * + * Callback which will be called if successful listening (ESP8266 as TCP server) + * or connection (ESP8266 as TCP client) callback, register by espconn_regist_connectcb. + * + * @attention The pointer "void *arg" may be different in different callbacks, please don't + * use this pointer directly to distinguish one from another in multiple connections, + * use remote_ip and remote_port in espconn instead. + * + * @param void *arg : pointer corresponding structure espconn. + * + * @return null + */ +typedef void (* espconn_connect_callback)(void *arg); + +/** + * @brief Reconnect callback. + * + * Enter this callback when error occurred, TCP connection broke. This callback is + * registered by espconn_regist_reconcb. + * + * @attention The pointer "void *arg" may be different in different callbacks, please don't + * use this pointer directly to distinguish one from another in multiple connections, + * use remote_ip and remote_port in espconn instead. + * + * @param void *arg : pointer corresponding structure espconn. + * @param sint8 err : error code + * - ESCONN_TIMEOUT - Timeout + * - ESPCONN_ABRT - TCP connection aborted + * - ESPCONN_RST - TCP connection abort + * - ESPCONN_CLSD - TCP connection closed + * - ESPCONN_CONN - TCP connection + * - ESPCONN_HANDSHAKE - TCP SSL handshake fail + * - ESPCONN_PROTO_MSG - SSL application invalid + * + * @return null + */ +typedef void (* espconn_reconnect_callback)(void *arg, sint8 err); + +/* Definitions for error constants. */ + +#define ESPCONN_OK 0 /**< No error, everything OK. */ +#define ESPCONN_MEM -1 /**< Out of memory. */ +#define ESPCONN_TIMEOUT -3 /**< Timeout. */ +#define ESPCONN_RTE -4 /**< Routing problem. */ +#define ESPCONN_INPROGRESS -5 /**< Operation in progress. */ +#define ESPCONN_MAXNUM -7 /**< Total number exceeds the maximum limitation. */ + +#define ESPCONN_ABRT -8 /**< Connection aborted. */ +#define ESPCONN_RST -9 /**< Connection reset. */ +#define ESPCONN_CLSD -10 /**< Connection closed. */ +#define ESPCONN_CONN -11 /**< Not connected. */ + +#define ESPCONN_ARG -12 /**< Illegal argument. */ +#define ESPCONN_IF -14 /**< UDP send error. */ +#define ESPCONN_ISCONN -15 /**< Already connected. */ + +/** Protocol family and type of the espconn */ +enum espconn_type { + ESPCONN_INVALID = 0, /**< invalid type */ + ESPCONN_TCP = 0x10, /**< TCP */ + ESPCONN_UDP = 0x20, /**< UDP */ +}; + +/** Current state of the espconn. */ +enum espconn_state { + ESPCONN_NONE, /**< idle state, no connection */ + ESPCONN_WAIT, /**< ESP8266 is as TCP client, and waiting for connection */ + ESPCONN_LISTEN, /**< ESP8266 is as TCP server, and waiting for connection */ + ESPCONN_CONNECT, /**< connected */ + ESPCONN_WRITE, /**< sending data */ + ESPCONN_READ, /**< receiving data */ + ESPCONN_CLOSE /**< connection closed */ +}; + +typedef struct _esp_tcp { + int remote_port; /**< remote port of TCP connection */ + int local_port; /**< ESP8266's local port of TCP connection */ + uint8 local_ip[4]; /**< local IP of ESP8266 */ + uint8 remote_ip[4]; /**< remote IP of TCP connection */ + espconn_connect_callback connect_callback; /**< connected callback */ + espconn_reconnect_callback reconnect_callback; /**< as error handler, the TCP connection broke unexpectedly */ + espconn_connect_callback disconnect_callback; /**< disconnected callback */ + espconn_connect_callback write_finish_fn; /**< data send by espconn_send has wrote into buffer waiting for sending, or has sent successfully */ +} esp_tcp; + +typedef struct _esp_udp { + int remote_port; /**< remote port of UDP transmission */ + int local_port; /**< ESP8266's local port for UDP transmission */ + uint8 local_ip[4]; /**< local IP of ESP8266 */ + uint8 remote_ip[4]; /**< remote IP of UDP transmission */ +} esp_udp; + +typedef struct _remot_info { + enum espconn_state state; /**< state of espconn */ + int remote_port; /**< remote port */ + uint8 remote_ip[4]; /**< remote IP address */ +} remot_info; + +/** A callback prototype to inform about events for a espconn */ +typedef void (* espconn_recv_callback)(void *arg, char *pdata, unsigned short len); +typedef void (* espconn_sent_callback)(void *arg); + +/** A espconn descriptor */ +struct espconn { + enum espconn_type type; /**< type of the espconn (TCP or UDP) */ + enum espconn_state state; /**< current state of the espconn */ + union { + esp_tcp *tcp; + esp_udp *udp; + } proto; + espconn_recv_callback recv_callback; /**< data received callback */ + espconn_sent_callback sent_callback; /**< data sent callback */ + uint8 link_cnt; /**< link count */ + void *reserve; /**< reserved for user data */ +}; + +enum espconn_option { + ESPCONN_START = 0x00, /**< no option, start enum. */ + ESPCONN_REUSEADDR = 0x01, /**< free memory after TCP disconnection happen, need not wait 2 minutes. */ + ESPCONN_NODELAY = 0x02, /**< disable nagle algorithm during TCP data transmission, quicken the data transmission. */ + ESPCONN_COPY = 0x04, /**< enable espconn_regist_write_finish, enter write_finish_callback means that the data espconn_send sending was written into 2920 bytes write-buffer waiting for sending or already sent. */ + ESPCONN_KEEPALIVE = 0x08, /**< enable TCP keep alive. */ + ESPCONN_END /**< no option, end enum. */ +}; + +enum espconn_level { + ESPCONN_KEEPIDLE, /**< TCP keep-alive interval, unit : second. */ + ESPCONN_KEEPINTVL, /**< packet interval during TCP keep-alive, unit : second. */ + ESPCONN_KEEPCNT /**< maximum packet retry count of TCP keep-alive. */ +}; + +enum { + ESPCONN_IDLE = 0, + ESPCONN_CLIENT, + ESPCONN_SERVER, + ESPCONN_BOTH, + ESPCONN_MAX +}; + +/** + * @brief Connect to a TCP server (ESP8266 acting as TCP client). + * + * @attention If espconn_connect fail, returns non-0 value, there is no connection, so it + * won't enter any espconn callback. + * + * @param struct espconn *espconn : the network connection structure, the espconn to + * listen to the connection + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_RTE - Routing Problem + * - ESPCONN_MEM - Out of memory + * - ESPCONN_ISCONN - Already connected + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn + */ +sint8 espconn_connect(struct espconn *espconn); + +/** + * @brief Disconnect a TCP connection. + * + * @attention Don't call this API in any espconn callback. If needed, please use system + * task to trigger espconn_disconnect. + * + * @param struct espconn *espconn : the network connection structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn + */ +sint8 espconn_disconnect(struct espconn *espconn); + +/** + * @brief Delete a transmission. + * + * @attention Corresponding creation API : + * - TCP: espconn_accept, + * - UDP: espconn_create + * + * @param struct espconn *espconn : the network connection structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding network according + * to structure espconn + */ +sint8 espconn_delete(struct espconn *espconn); + +/** + * @brief Creates a TCP server (i.e. accepts connections). + * + * @param struct espconn *espconn : the network connection structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + * - ESPCONN_ISCONN - Already connected + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn + */ +sint8 espconn_accept(struct espconn *espconn); + +/** + * @brief Create UDP transmission. + * + * @attention Parameter remote_ip and remote_port need to be set, do not set to be 0. + * + * @param struct espconn *espconn : the UDP control block structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + * - ESPCONN_ISCONN - Already connected + * - ESPCONN_ARG - illegal argument, can't find the corresponding UDP transmission + * according to structure espconn + */ +sint8 espconn_create(struct espconn *espconn); + +/** + * @brief Get maximum number of how many TCP connections are allowed. + * + * @param null + * + * @return Maximum number of how many TCP connections are allowed. + */ +uint8 espconn_tcp_get_max_con(void); + +/** + * @brief Set the maximum number of how many TCP connection is allowed. + * + * @param uint8 num : Maximum number of how many TCP connection is allowed. + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn + */ +sint8 espconn_tcp_set_max_con(uint8 num); + +/** + * @brief Get the maximum number of TCP clients which are allowed to connect to ESP8266 TCP server. + * + * @param struct espconn *espconn : the TCP server structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_tcp_get_max_con_allow(struct espconn *espconn); + +/** + * @brief Set the maximum number of TCP clients allowed to connect to ESP8266 TCP server. + * + * @param struct espconn *espconn : the TCP server structure + * @param uint8 num : Maximum number of TCP clients which are allowed + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_tcp_set_max_con_allow(struct espconn *espconn, uint8 num); + +/** + * @brief Register timeout interval of ESP8266 TCP server. + * + * @attention 1. If timeout is set to 0, timeout will be disable and ESP8266 TCP server will + * not disconnect TCP clients has stopped communication. This usage of timeout=0, + * is deprecated. + * @attention 2. This timeout interval is not very precise, only as reference. + * + * @param struct espconn *espconn : the TCP connection structure + * @param uint32 interval : timeout interval, unit: second, maximum: 7200 seconds + * @param uint8 type_flag : 0, set for all connections; 1, set for a specific connection + * - If the type_flag set to be 0, please call this API after espconn_accept, before listened + * a TCP connection. + * - If the type_flag set to be 1, the first parameter *espconn is the specific connection. + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_regist_time(struct espconn *espconn, uint32 interval, uint8 type_flag); + +/** + * @brief Get the information about a TCP connection or UDP transmission. + * + * @param struct espconn *espconn : the network connection structure + * @param remot_info **pcon_info : connect to client info + * @param uint8 typeflags : 0, regular server; 1, ssl server + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding transmission according to + * structure espconn + */ +sint8 espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, uint8 typeflags); + +/** + * @brief Register data sent callback which will be called back when data are successfully sent. + * + * @param struct espconn *espconn : the network connection structure + * @param espconn_sent_callback sent_cb : registered callback function which will be called if + * the data is successfully sent + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding transmission according + * to structure espconn + */ +sint8 espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_cb); + +/** + * @brief Register a callback which will be called when all sending TCP data is completely + * write into write-buffer or sent. + * + * Need to call espconn_set_opt to enable write-buffer first. + * + * @attention 1. write-buffer is used to keep TCP data that waiting to be sent, queue number + * of the write-buffer is 8 which means that it can keep 8 packets at most. + * The size of write-buffer is 2920 bytes. + * @attention 2. Users can enable it by using espconn_set_opt. + * @attention 3. Users can call espconn_send to send the next packet in write_finish_callback + * instead of using espconn_sent_callback. + * + * @param struct espconn *espconn : the network connection structure + * @param espconn_connect_callback write_finish_fn : registered callback function which will + * be called if the data is completely write + * into write buffer or sent. + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback write_finish_fn); + +/** + * @brief Send data through network. + * + * @attention 1. Please call espconn_send after espconn_sent_callback of the pre-packet. + * @attention 2. If it is a UDP transmission, it is suggested to set espconn->proto.udp->remote_ip + * and remote_port before every calling of espconn_send. + * + * @param struct espconn *espconn : the network connection structure + * @param uint8 *psent : pointer of data + * @param uint16 length : data length + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + * - ESPCONN_ARG - illegal argument, can't find the corresponding network transmission + * according to structure espconn + * - ESPCONN_MAXNUM - buffer of sending data is full + * - ESPCONN_IF - send UDP data fail + */ +sint8 espconn_send(struct espconn *espconn, uint8 *psent, uint16 length); + +/** + * @brief Send data through network. + * + * This API is deprecated, please use espconn_send instead. + * + * @attention 1. Please call espconn_sent after espconn_sent_callback of the pre-packet. + * @attention 2. If it is a UDP transmission, it is suggested to set espconn->proto.udp->remote_ip + * and remote_port before every calling of espconn_sent. + * + * @param struct espconn *espconn : the network connection structure + * @param uint8 *psent : pointer of data + * @param uint16 length : data length + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + * - ESPCONN_ARG - illegal argument, can't find the corresponding network transmission + * according to structure espconn + * - ESPCONN_MAXNUM - buffer of sending data is full + * - ESPCONN_IF - send UDP data fail + */ +sint8 espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length); + +/** + * @brief Send UDP data. + * + * @param struct espconn *espconn : the UDP structure + * @param uint8 *psent : pointer of data + * @param uint16 length : data length + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + * - ESPCONN_MAXNUM - buffer of sending data is full + * - ESPCONN_IF - send UDP data fail + */ +sint16 espconn_sendto(struct espconn *espconn, uint8 *psent, uint16 length); + +/** + * @brief Register connection function which will be called back under successful TCP connection. + * + * @param struct espconn *espconn : the TCP connection structure + * @param espconn_connect_callback connect_cb : registered callback function + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_regist_connectcb(struct espconn *espconn, espconn_connect_callback connect_cb); + +/** + * @brief register data receive function which will be called back when data are received. + * + * @param struct espconn *espconn : the network transmission structure + * @param espconn_recv_callback recv_cb : registered callback function + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_regist_recvcb(struct espconn *espconn, espconn_recv_callback recv_cb); + +/** + * @brief Register reconnect callback. + * + * @attention espconn_reconnect_callback is more like a network-broken error handler; it handles + * errors that occurs in any phase of the connection. + * For instance, if espconn_send fails, espconn_reconnect_callback will be called + * because the network is broken. + * + * @param struct espconn *espconn : the TCP connection structure + * @param espconn_reconnect_callback recon_cb : registered callback function + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_regist_reconcb(struct espconn *espconn, espconn_reconnect_callback recon_cb); + +/** + * @brief Register disconnection function which will be called back under successful TCP + * disconnection. + * + * @param struct espconn *espconn : the TCP connection structure + * @param espconn_connect_callback discon_cb : registered callback function + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_regist_disconcb(struct espconn *espconn, espconn_connect_callback discon_cb); + +/** + * @brief Get an available port for network. + * + * @param null + * + * @return Port number. + */ +uint32 espconn_port(void); + +/** + * @brief Set option of TCP connection. + * + * @attention In general, we need not call this API. If call espconn_set_opt, please call + * it in espconn_connect_callback. + * + * @param struct espconn *espconn : the TCP connection structure + * @param uint8 opt : option of TCP connection, refer to enum espconn_option + * - bit 0: 1: free memory after TCP disconnection happen need not wait 2 minutes; + * - bit 1: 1: disable nagle algorithm during TCP data transmission, quiken the data transmission. + * - bit 2: 1: enable espconn_regist_write_finish, enter write finish callback means + * the data espconn_send sending was written into 2920 bytes write-buffer + * waiting for sending or already sent. + * - bit 3: 1: enable TCP keep alive + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_set_opt(struct espconn *espconn, uint8 opt); + +/** + * @brief Clear option of TCP connection. + * + * @param struct espconn *espconn : the TCP connection structure + * @param uint8 opt : enum espconn_option + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_clear_opt(struct espconn *espconn, uint8 opt); + +/** + * @brief Set configuration of TCP keep alive. + * + * @attention In general, we need not call this API. If needed, please call it in + * espconn_connect_callback and call espconn_set_opt to enable keep alive first. + * + * @param struct espconn *espconn : the TCP connection structure + * @param uint8 level : To do TCP keep-alive detection every ESPCONN_KEEPIDLE. If there + * is no response, retry ESPCONN_KEEPCNT times every ESPCONN_KEEPINTVL. + * If still no response, considers it as TCP connection broke, goes + * into espconn_reconnect_callback. Notice, keep alive interval is not + * precise, only for reference, it depends on priority. + * @param void* optarg : value of parameter + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_set_keepalive(struct espconn *espconn, uint8 level, void *optarg); + +/** + * @brief Get configuration of TCP keep alive. + * + * @param struct espconn *espconn : the TCP connection structure + * @param uint8 level : enum espconn_level + * @param void* optarg : value of parameter + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection according + * to structure espconn + */ +sint8 espconn_get_keepalive(struct espconn *espconn, uint8 level, void *optarg); + +/** + * @brief Callback which is invoked when a hostname is found. + * + * @param const char *name : hostname + * @param ip_addr_t *ipaddr : IP address of the hostname, or to be NULL if the name could + * not be found (or on any other error). + * @param void *callback_arg : callback argument. + * + * @return null + */ +typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); + +/** + * @brief DNS function. + * + * Parse a hostname (string) to an IP address. + * + * @param struct espconn *pespconn : espconn to parse a hostname. + * @param const char *hostname : the hostname. + * @param ip_addr_t *addr : IP address. + * @param dns_found_callback found : callback of DNS + * + * @return err_t : + * - ESPCONN_OK - succeed + * - ESPCONN_INPROGRESS - error code : already connected + * - ESPCONN_ARG - error code : illegal argument, can't find network transmission + * according to structure espconn + */ +err_t espconn_gethostbyname(struct espconn *pespconn, const char *hostname, ip_addr_t *addr, dns_found_callback found); + +/** + * @brief Join a multicast group. + * + * @attention This API can only be called after the ESP8266 station connects to a router. + * + * @param ip_addr_t *host_ip : IP of UDP host + * @param ip_addr_t *multicast_ip : IP of multicast group + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + */ +sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip); + +/** + * @brief Leave a multicast group. + * + * @attention This API can only be called after the ESP8266 station connects to a router. + * + * @param ip_addr_t *host_ip : IP of UDP host + * @param ip_addr_t *multicast_ip : IP of multicast group + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - Out of memory + */ +sint8 espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip); + +/** + * @brief Puts in a request to block the TCP receive function. + * + * @attention The function does not act immediately; we recommend calling it while + * reserving 5*1460 bytes of memory. This API can be called more than once. + * + * @param struct espconn *espconn : corresponding TCP connection structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn. + */ +sint8 espconn_recv_hold(struct espconn *pespconn); + +/** + * @brief Unblock TCP receiving data (i.e. undo espconn_recv_hold). + * + * @attention This API takes effect immediately. + * + * @param struct espconn *espconn : corresponding TCP connection structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn. + */ +sint8 espconn_recv_unhold(struct espconn *pespconn); + +/** + * @brief Set default DNS server. Two DNS server is allowed to be set. + * + * @attention Only if ESP8266 DHCP client is disabled (wifi_station_dhcpc_stop), + * this API can be used. + * + * @param char numdns : DNS server ID, 0 or 1 + * @param ip_addr_t *dnsserver : DNS server IP + * + * @return null + */ +void espconn_dns_setserver(char numdns, ip_addr_t *dnsserver); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/espnow.h b/include/espressif/espnow.h new file mode 100644 index 00000000..3519c76a --- /dev/null +++ b/include/espressif/espnow.h @@ -0,0 +1,351 @@ +/* + * 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 __ESPNOW_H__ +#define __ESPNOW_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup ESPNow_APIs ESP-NOW APIs + * @brief ESP-NOW APIs + * + * @attention 1. ESP-NOW do not support broadcast and multicast. + * @attention 2. ESP-NOW is targeted to Smart-Light project, so it is suggested + * that slave role corresponding to soft-AP or soft-AP+station mode, + * controller role corresponding to station mode. + * @attention 3. When ESP8266 is in soft-AP+station mode, it will communicate through + * station interface if it is in slave role, and communicate through + * soft-AP interface if it is in controller role. + * @attention 4. ESP-NOW can not wake ESP8266 up from sleep, so if the target ESP8266 + * station is in sleep, ESP-NOW communication will fail. + * @attention 5. In station mode, ESP8266 supports 10 encrypt ESP-NOW peers at most, + * with the unencrypted peers, it can be 20 peers in total at most. + * @attention 6. In the soft-AP mode or soft-AP + station mode, the ESP8266 supports + * 6 encrypt ESP-NOW peers at most, with the unencrypted peers, it can + * be 20 peers in total at most. + * + */ + +/** @addtogroup ESPNow_APIs + * @{ + */ + +enum esp_now_role { + ESP_NOW_ROLE_IDLE = 0, + ESP_NOW_ROLE_CONTROLLER, + ESP_NOW_ROLE_SLAVE, + ESP_NOW_ROLE_MAX, +}; + +/** + * @brief ESP-NOW send callback. + * + * @attention The status will be OK, if ESP-NOW send packet successfully. But users + * need to make sure by themselves that key of communication is correct. + * + * @param uint8 *mac_addr : MAC address of target device + * @param uint8 *data : data received + * @param uint8 len : data length + * + * @return null + */ +typedef void (*esp_now_recv_cb_t)(uint8 *mac_addr, uint8 *data, uint8 len); + +/** + * @brief ESP-NOW send callback. + * + * @attention The status will be OK, if ESP-NOW send packet successfully. But users + * need to make sure by themselves that key of communication is correct. + * + * @param uint8 *mac_addr : MAC address of target device + * @param uint8 status : status of ESP-NOW sending packet, 0, OK; 1, fail. + * + * @return null + */ +typedef void (*esp_now_send_cb_t)(uint8 *mac_addr, uint8 status); + +/** + * @brief ESP-NOW initialization. + * + * @param null + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_init(void); + +/** + * @brief Deinitialize ESP-NOW. + * + * @param null + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_deinit(void); + +/** + * @brief Register ESP-NOW send callback. + * + * @param esp_now_send_cb_t cb : send callback + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_register_send_cb(esp_now_send_cb_t cb); + +/** + * @brief Unregister ESP-NOW send callback. + * + * @param null + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_unregister_send_cb(void); + +/** + * @brief Register ESP-NOW receive callback. + * + * @param esp_now_recv_cb_t cb : receive callback + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_register_recv_cb(esp_now_recv_cb_t cb); + +/** + * @brief Unregister ESP-NOW receive callback. + * + * @param null + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_unregister_recv_cb(void); + +/** + * @brief Send ESP-NOW packet. + * + * @param uint8 *da : destination MAC address. + * If it's NULL, send packet to all MAC addresses recorded + * by ESP-NOW; otherwise, send packet to target MAC address. + * @param uint8 *data : data need to send + * @param uint8 len : data length + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_send(uint8 *da, uint8 *data, uint8 len); + +/** + * @brief Add an ESP-NOW peer, store MAC address of target device into ESP-NOW MAC list. + * + * @param uint8 *mac_addr : MAC address of device + * @param uint8 role : role type of device, enum esp_now_role + * @param uint8 channel : channel of device + * @param uint8 *key : 16 bytes key which is needed for ESP-NOW communication + * @param uint8 key_len : length of key, has to be 16 bytes now + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_add_peer(uint8 *mac_addr, uint8 role, uint8 channel, uint8 *key, uint8 key_len); + +/** + * @brief Delete an ESP-NOW peer, delete MAC address of the device from ESP-NOW MAC list. + * + * @param u8 *mac_addr : MAC address of device + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_del_peer(uint8 *mac_addr); + +/** + * @brief Set ESP-NOW role of device itself. + * + * @param uint8 role : role type of device, enum esp_now_role. + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_set_self_role(uint8 role); + +/** + * @brief Get ESP-NOW role of device itself. + * + * @param uint8 role : role type of device, enum esp_now_role. + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_get_self_role(void); + +/** + * @brief Set ESP-NOW role for a target device. If it is set multiple times, + * new role will cover the old one. + * + * @param uint8 *mac_addr : MAC address of device. + * @param uint8 role : role type, enum esp_now_role. + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_set_peer_role(uint8 *mac_addr, uint8 role); + +/** + * @brief Get ESP-NOW role of a target device. + * + * @param uint8 *mac_addr : MAC address of device. + * + * @return ESP_NOW_ROLE_CONTROLLER, role type : controller + * @return ESP_NOW_ROLE_SLAVE, role type : slave + * @return otherwise : fail + */ +sint32 esp_now_get_peer_role(uint8 *mac_addr); + +/** + * @brief Record channel information of a ESP-NOW device. + * + * When communicate with this device, + * - call esp_now_get_peer_channel to get its channel first, + * - then call wifi_set_channel to be in the same channel and do communication. + * + * @param uint8 *mac_addr : MAC address of target device. + * @param uint8 channel : channel, usually to be 1 ~ 13, some area may use channel 14. + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_set_peer_channel(uint8 *mac_addr, uint8 channel); + +/** + * @brief Get channel information of a ESP-NOW device. + * + * @attention ESP-NOW communication needs to be at the same channel. + * + * @param uint8 *mac_addr : MAC address of target device. + * + * @return 1 ~ 13 (some area may get 14) : channel number + * @return Non-0 : fail + */ +sint32 esp_now_get_peer_channel(uint8 *mac_addr); + +/** + * @brief Set ESP-NOW key for a target device. + * + * If it is set multiple times, new key will cover the old one. + * + * @param uint8 *mac_addr : MAC address of target device. + * @param uint8 *key : 16 bytes key which is needed for ESP-NOW communication, + * if it is NULL, current key will be reset to be none. + * @param uint8 key_len : key length, has to be 16 bytes now + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_set_peer_key(uint8 *mac_addr, uint8 *key, uint8 key_len); + +/** + * @brief Get ESP-NOW key of a target device. + * + * If it is set multiple times, new key will cover the old one. + * + * @param uint8 *mac_addr : MAC address of target device. + * @param uint8 *key : pointer of key, buffer size has to be 16 bytes at least + * @param uint8 key_len : key length + * + * @return 0 : succeed + * @return > 0 : find target device but can't get key + * @return < 0 : fail + */ +sint32 esp_now_get_peer_key(uint8 *mac_addr, uint8 *key, uint8 *key_len); + +/** + * @brief Get MAC address of ESP-NOW device. + * + * Get MAC address of ESP-NOW device which is pointed now, and move + * the pointer to next one in ESP-NOW MAC list or move the pointer to + * the first one in ESP-NOW MAC list. + * + * @attention 1. This API can not re-entry + * @attention 2. Parameter has to be true when you call it the first time. + * + * @param bool restart : true, move pointer to the first one in ESP-NOW MAC list; + * false, move pointer to the next one in ESP-NOW MAC list + * + * @return NULL, no ESP-NOW devices exist + * @return Otherwise, MAC address of ESP-NOW device which is pointed now + */ +uint8 *esp_now_fetch_peer(bool restart); + +/** + * @brief Check if target device exists or not. + * + * @param uint8 *mac_addr : MAC address of target device. + * + * @return 0 : device does not exist + * @return < 0 : error occur, check fail + * @return > 0 : device exists + */ +sint32 esp_now_is_peer_exist(uint8 *mac_addr); + +/** + * @brief Get the total number of ESP-NOW devices which are associated, and the + * number count of encrypted devices. + * + * @param uint8 *all_cnt : total number of ESP-NOW devices which are associated. + * @param uint8 *encryp_cnt : number count of encrypted devices + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_get_cnt_info(uint8 *all_cnt, uint8 *encrypt_cnt); + +/** + * @brief Set the encrypt key of communication key. + * + * All ESP-NOW devices share the same encrypt key. If users do not set + * the encrypt key, ESP-NOW communication key will be encrypted by a default key. + * + * @param uint8 *key : pointer of encrypt key. + * @param uint8 len : key length, has to be 16 bytes now. + * + * @return 0 : succeed + * @return Non-0 : fail + */ +sint32 esp_now_set_kok(uint8 *key, uint8 len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/mesh.h b/include/espressif/mesh.h new file mode 100644 index 00000000..496560f9 --- /dev/null +++ b/include/espressif/mesh.h @@ -0,0 +1,274 @@ +/* + * 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 __LWIP_API_MESH_H__ +#define __LWIP_API_MESH_H__ + +#include "lwip/ip_addr.h" +#include "espconn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (* espconn_mesh_callback)(); + +enum mesh_type { + MESH_CLOSE = 0, + MESH_LOCAL, + MESH_ONLINE, + MESH_NONE = 0xFF +}; + +/** \defgroup Mesh_APIs Mesh APIs + * @brief Mesh APIs + * + * + * + */ + +/** @addtogroup Mesh_APIs + * @{ + */ + +enum mesh_status { + MESH_DISABLE = 0, /**< mesh disabled */ + MESH_WIFI_CONN, /**< WiFi connected */ + MESH_NET_CONN, /**< TCP connection OK */ + MESH_LOCAL_AVAIL, /**< local mesh is avaliable */ + MESH_ONLINE_AVAIL /**< online mesh is avaliable */ +}; + +enum mesh_node_type { + MESH_NODE_PARENT = 0, /**< get information of parent node */ + MESH_NODE_CHILD, /**< get information of child node(s) */ + MESH_NODE_ALL /**< get information of all nodes */ +}; + +/** + * @brief Check whether the IP address is mesh local IP address or not. + * + * @attention 1. The range of mesh local IP address is 2.255.255.* ~ max_hop.255.255.*. + * @attention 2. IP pointer should not be NULL. If the IP pointer is NULL, it will return false. + * + * @param struct ip_addr *ip : IP address + * + * @return true : the IP address is mesh local IP address + * @return false : the IP address is not mesh local IP address + */ +bool espconn_mesh_local_addr(struct ip_addr *ip); + +/** + * @brief Get the information of mesh node. + * + * @param enum mesh_node_type typ : mesh node type. + * @param uint8_t **info : the information will be saved in *info. + * @param uint8_t *count : the node count in *info. + * + * @return true : succeed + * @return false : fail + */ +bool espconn_mesh_get_node_info(enum mesh_node_type type, + uint8_t **info, uint8_t *count); + +/** + * @brief Set WiFi cryption algrithm and password for mesh node. + * + * @attention The function must be called before espconn_mesh_enable. + * + * @param AUTH_MODE mode : cryption algrithm (WPA/WAP2/WPA_WPA2). + * @param uint8_t *passwd : password of WiFi. + * @param uint8_t passwd_len : length of password (8 <= passwd_len <= 64). + * + * @return true : succeed + * @return false : fail + */ +bool espconn_mesh_encrypt_init(AUTH_MODE mode, uint8_t *passwd, uint8_t passwd_len); + +/** + * @brief Set prefix of SSID for mesh node. + * + * @attention The function must be called before espconn_mesh_enable. + * + * @param uint8_t *prefix : prefix of SSID. + * @param uint8_t prefix_len : length of prefix (0 < passwd_len <= 22). + * + * @return true : succeed + * @return false : fail + */ +bool espconn_mesh_set_ssid_prefix(uint8_t *prefix, uint8_t prefix_len); + +/** + * @brief Set max hop for mesh network. + * + * @attention The function must be called before espconn_mesh_enable. + * + * @param uint8_t max_hops : max hop of mesh network (1 <= max_hops < 10, 4 is recommended). + * + * @return true : succeed + * @return false : fail + */ +bool espconn_mesh_set_max_hops(uint8_t max_hops); + +/** + * @brief Set group ID of mesh node. + * + * @attention The function must be called before espconn_mesh_enable. + * + * @param uint8_t *grp_id : group ID. + * @param uint16_t gid_len: length of group ID, now gid_len = 6. + * + * @return true : succeed + * @return false : fail + */ +bool espconn_mesh_group_id_init(uint8_t *grp_id, uint16_t gid_len); + +/** + * @brief Set the curent device type. + * + * @param uint8_t dev_type : device type of mesh node + * + * @return true : succeed + * @return false : fail + */ +bool espconn_mesh_set_dev_type(uint8_t dev_type); + +/** + * @brief Try to establish mesh connection to server. + * + * @attention If espconn_mesh_connect fail, returns non-0 value, there is no connection, so it + * won't enter any espconn callback. + * + * @param struct espconn *usr_esp : the network connection structure, the usr_esp to + * listen to the connection + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_RTE - Routing Problem + * - ESPCONN_MEM - Out of memory + * - ESPCONN_ISCONN - Already connected + * - ESPCONN_ARG - Illegal argument, can't find the corresponding connection + * according to structure espconn + */ +sint8 espconn_mesh_connect(struct espconn *usr_esp); + +/** + * @brief Disconnect a mesh connection. + * + * @attention Do not call this API in any espconn callback. If needed, please use system + * task to trigger espconn_mesh_disconnect. + * + * @param struct espconn *usr_esp : the network connection structure + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_ARG - illegal argument, can't find the corresponding TCP connection + * according to structure espconn + */ + +sint8 espconn_mesh_disconnect(struct espconn *usr_esp); + +/** + * @brief Get current mesh status. + * + * @param null + * + * @return the current mesh status, please refer to enum mesh_status. + */ +sint8 espconn_mesh_get_status(); + +/** + * @brief Send data through mesh network. + * + * @attention Please call espconn_mesh_sent after espconn_sent_callback of the pre-packet. + * + * @param struct espconn *usr_esp : the network connection structure + * @param uint8 *pdata : pointer of data + * @param uint16 len : data length + * + * @return 0 : succeed + * @return Non-0 : error code + * - ESPCONN_MEM - out of memory + * - ESPCONN_ARG - illegal argument, can't find the corresponding network transmission + * according to structure espconn + * - ESPCONN_MAXNUM - buffer of sending data is full + * - ESPCONN_IF - send UDP data fail + */ +sint8 espconn_mesh_sent(struct espconn *usr_esp, uint8 *pdata, uint16 len); + +/** + * @brief Get max hop of mesh network. + * + * @param null. + * + * @return the current max hop of mesh + */ +uint8 espconn_mesh_get_max_hops(); + +/** + * @brief To enable mesh network. + * + * @attention 1. the function should be called in user_init. + * @attention 2. if mesh node can not scan the mesh AP, it will be isolate node without trigger enable_cb. + * user can use espconn_mesh_get_status to get current status of node. + * @attention 3. if user try to enable online mesh, but node fails to establish mesh connection + * the node will work with local mesh. + * + * @param espconn_mesh_callback enable_cb : callback function of mesh-enable + * @param enum mesh_type type : type of mesh, local or online. + * + * @return null + */ +void espconn_mesh_enable(espconn_mesh_callback enable_cb, enum mesh_type type); + +/** + * @brief To disable mesh network. + * + * @attention When mesh network is disabed, the system will trigger disable_cb. + * + * @param espconn_mesh_callback disable_cb : callback function of mesh-disable + * @param enum mesh_type type : type of mesh, local or online. + * + * @return null + */ +void espconn_mesh_disable(espconn_mesh_callback disable_cb); + +/** + * @brief To print version of mesh. + * + * @param null + * + * @return null + */ +void espconn_mesh_init(); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/pwm.h b/include/espressif/pwm.h index 00ac6a45..9c2a2be9 100644 --- a/include/espressif/pwm.h +++ b/include/espressif/pwm.h @@ -1,19 +1,133 @@ +/* + * 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 __PWM_H__ #define __PWM_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup PWM_Driver_APIs PWM Driver APIs + * @brief PWM driver APIs + */ + +/** @addtogroup PWM_Driver_APIs + * @{ + */ + struct pwm_param { - uint32 period; - uint32 freq; - uint32 duty[8]; + uint32 period; /**< PWM period */ + uint32 freq; /**< PWM frequency */ + uint32 duty[8]; /**< PWM duty */ }; #define PWM_DEPTH 1023 -void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32 (*pin_info_list)[3]); +/** + * @brief PWM function initialization, including GPIO, frequency and duty cycle. + * + * @attention This API can be called only once. + * + * @param uint32 period : pwm frequency + * @param uint32 *duty : duty cycle + * @param uint32 pwm_channel_num : PWM channel number + * @param uint32 (*pin_info_list)[3] : GPIO parameter of PWM channel, it is a pointer + * of n x 3 array which defines GPIO register, IO + * reuse of corresponding pin and GPIO number. + * + * @return null + */ +void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32(*pin_info_list)[3]); +/** + * @brief Set the duty cycle of a PWM channel. + * + * Set the time that high level signal will last, duty depends on period, + * the maximum value can be period *1000 / 45. + * For example, 1KHz PWM, duty range is 0~22222 + * + * @attention After set configuration, pwm_start needs to be called to take effect. + * + * @param uint32 duty : duty cycle + * @param uint8 channel : PWM channel number + * + * @return null + */ void pwm_set_duty(uint32 duty, uint8 channel); + +/** + * @brief Get the duty cycle of a PWM channel. + * + * Duty cycle will be (duty * 45)/(period *1000). + * + * @param uint8 channel : PWM channel number + * + * @return Duty cycle of PWM output. + */ uint32 pwm_get_duty(uint8 channel); + +/** + * @brief Set PWM period, unit : us. + * + * For example, for 1KHz PWM, period is 1000 us. + * + * @attention After set configuration, pwm_start needs to be called to take effect. + * + * @param uint32 period : PWM period, unit : us. + * + * @return null + */ void pwm_set_period(uint32 period); + +/** + * @brief Get PWM period, unit : us. + * + * @param null + * + * @return PWM period, unit : us. + */ uint32 pwm_get_period(void); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/queue.h b/include/espressif/queue.h index a760c8db..6fab9ce5 100644 --- a/include/espressif/queue.h +++ b/include/espressif/queue.h @@ -1,197 +1,225 @@ -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ +/* + * 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. + * + */ -#define QMD_SAVELINK(name, link) -#define TRASHIT(x) +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define QMD_SAVELINK(name, link) +#define TRASHIT(x) /* * Singly-linked List declarations. */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} +#define SLIST_HEAD(name, type) \ + struct name { \ + struct type *slh_first; /* first element */ \ + } -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} +#define SLIST_ENTRY(type) \ + struct { \ + struct type *sle_next; /* next element */ \ + } /* * Singly-linked List functions. */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) -#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != NULL; \ - (varp) = &SLIST_NEXT((var), field)) +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ + } while (0) -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ + } while (0) -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ + } while (0) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) -#define SLIST_REMOVE(head, elm, type, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_REMOVE_AFTER(curelm, field); \ - } \ - TRASHIT(*oldnext); \ -} while (0) +#define SLIST_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_REMOVE_AFTER(curelm, field); \ + } \ + TRASHIT(*oldnext); \ + } while (0) -#define SLIST_REMOVE_AFTER(elm, field) do { \ - SLIST_NEXT(elm, field) = \ - SLIST_NEXT(SLIST_NEXT(elm, field), field); \ -} while (0) +#define SLIST_REMOVE_AFTER(elm, field) do { \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ + } while (0) -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ + } while (0) /* * Singly-linked Tail queue declarations. */ -#define STAILQ_HEAD(name, type) \ - struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ +#define STAILQ_HEAD(name, type) \ + struct name { \ + struct type *stqh_first; /* first element */ \ + struct type **stqh_last; /* addr of last next element */ \ } -#define STAILQ_HEAD_INITIALIZER(head) \ +#define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).stqh_first } -#define STAILQ_ENTRY(type) \ - struct { \ - struct type *stqe_next; /* next element */ \ +#define STAILQ_ENTRY(type) \ + struct { \ + struct type *stqe_next; /* next element */ \ } /* * Singly-linked Tail queue functions. */ -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ } while (0) -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) -#define STAILQ_FIRST(head) ((head)->stqh_first) +#define STAILQ_FIRST(head) ((head)->stqh_first) -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ (var) = STAILQ_NEXT((var), field)) -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ (var) = (tvar)) -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ } while (0) -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ } while (0) -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ } while (0) -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *)(void *) \ +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head))? \ + NULL : \ + ((struct type *)(void *)\ ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) -#define STAILQ_REMOVE(head, elm, type, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - STAILQ_REMOVE_AFTER(head, curelm, field); \ - } \ - TRASHIT(*oldnext); \ +#define STAILQ_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + STAILQ_REMOVE_AFTER(head, curelm, field); \ + } \ + TRASHIT(*oldnext); \ } while (0) -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ } while (0) -#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ - if ((STAILQ_NEXT(elm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ } while (0) -#define STAILQ_SWAP(head1, head2, type) do { \ - struct type *swap_first = STAILQ_FIRST(head1); \ - struct type **swap_last = (head1)->stqh_last; \ - STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_FIRST(head2) = swap_first; \ - (head2)->stqh_last = swap_last; \ - if (STAILQ_EMPTY(head1)) \ - (head1)->stqh_last = &STAILQ_FIRST(head1); \ - if (STAILQ_EMPTY(head2)) \ - (head2)->stqh_last = &STAILQ_FIRST(head2); \ +#define STAILQ_SWAP(head1, head2, type) do { \ + struct type *swap_first = STAILQ_FIRST(head1); \ + struct type **swap_last = (head1)->stqh_last; \ + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &STAILQ_FIRST(head1); \ + if (STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &STAILQ_FIRST(head2); \ } while (0) #define STAILQ_INSERT_CHAIN_HEAD(head, elm_chead, elm_ctail, field) do { \ @@ -201,4 +229,8 @@ struct { \ STAILQ_FIRST(head) = (elm_chead); \ } while (0) +#ifdef __cplusplus +} +#endif + #endif /* !_SYS_QUEUE_H_ */ diff --git a/include/espressif/smartconfig.h b/include/espressif/smartconfig.h index c17113f1..5403e19a 100644 --- a/include/espressif/smartconfig.h +++ b/include/espressif/smartconfig.h @@ -1,29 +1,165 @@ /* - * Copyright (C) 2015 -2018 Espressif System + * 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 __SMARTCONFIG_H__ #define __SMARTCONFIG_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup Smartconfig_APIs Smartconfig APIs + * @brief SmartConfig APIs + * + * SmartConfig can only be enabled in station only mode. + * Please make sure the target AP is enabled before enable SmartConfig. + * + */ + +/** @addtogroup Smartconfig_APIs + * @{ + */ + typedef enum { - SC_STATUS_WAIT = 0, - SC_STATUS_FIND_CHANNEL, - SC_STATUS_GETTING_SSID_PSWD, - SC_STATUS_LINK, - SC_STATUS_LINK_OVER, + SC_STATUS_WAIT = 0, /**< waiting, do not start connection in this phase */ + SC_STATUS_FIND_CHANNEL, /**< find target channel, start connection by APP in this phase */ + SC_STATUS_GETTING_SSID_PSWD, /**< getting SSID and password of target AP */ + SC_STATUS_LINK, /**< connecting to target AP */ + SC_STATUS_LINK_OVER, /**< got IP, connect to AP successfully */ } sc_status; typedef enum { - SC_TYPE_ESPTOUCH = 0, - SC_TYPE_AIRKISS, + SC_TYPE_ESPTOUCH = 0, /**< protocol: ESPTouch */ + SC_TYPE_AIRKISS, /**< protocol: AirKiss */ + SC_TYPE_ESPTOUCH_AIRKISS, /**< protocol: ESPTouch and AirKiss */ } sc_type; +/** + * @brief The callback of SmartConfig, executed when smart-config status changed. + * + * @param sc_status status : status of SmartConfig: + * - if status == SC_STATUS_GETTING_SSID_PSWD, parameter void *pdata is a pointer + of sc_type, means SmartConfig type: AirKiss or ESP-TOUCH. + * - if status == SC_STATUS_LINK, parameter void *pdata is a pointer of struct station_config; + * - if status == SC_STATUS_LINK_OVER, parameter void *pdata is a pointer of mobile + * phone's IP address, 4 bytes. This is only available in ESPTOUCH, otherwise, + * it is NULL. + * - otherwise, parameter void *pdata is NULL. + * @param void *pdata : data of SmartConfig + * + * @return null + */ typedef void (*sc_callback_t)(sc_status status, void *pdata); +/** + * @brief Get the version of SmartConfig. + * + * @param null + * + * @return SmartConfig version + */ const char *smartconfig_get_version(void); + +/** + * @brief Start SmartConfig mode. + * + * Start SmartConfig mode, to connect ESP8266 station to AP, by sniffing + * for special packets from the air, containing SSID and password of desired AP. + * You need to broadcast the SSID and password (e.g. from mobile device or computer) + * with the SSID and password encoded. + * + * @attention 1. This api can only be called in station mode. + * @attention 2. During SmartConfig, ESP8266 station and soft-AP are disabled. + * @attention 3. Can not call smartconfig_start twice before it finish, please call + * smartconfig_stop first. + * @attention 4. Don't call any other APIs during SmartConfig, please call smartconfig_stop first. + * + * @param sc_callback_t cb : SmartConfig callback; executed when SmartConfig status changed; + * @param uint8 log : 1, UART output logs; otherwise, UART only outputs the result. + * + * @return true : succeed + * @return false : fail + */ bool smartconfig_start(sc_callback_t cb, ...); + +/** + * @brief Stop SmartConfig, free the buffer taken by smartconfig_start. + * + * @attention Whether connect to AP succeed or not, this API should be called to free + * memory taken by smartconfig_start. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ bool smartconfig_stop(void); -bool esptouch_set_timeout(uint8 time_s);//15s~255s, offset:45s + +/** + * @brief Set timeout of SmartConfig. + * + * @attention SmartConfig timeout start at SC_STATUS_FIND_CHANNEL, SmartConfig will + * restart if timeout. + * + * @param uint8 time_s : range 15s~255s, offset:45s. + * + * @return true : succeed + * @return false : fail + */ +bool esptouch_set_timeout(uint8 time_s); + +/** + * @brief Set protocol type of SmartConfig. + * + * @attention If users need to set the SmartConfig type, please set it before calling + * smartconfig_start. + * + * @param sc_type type : AirKiss, ESP-TOUCH or both. + * + * @return true : succeed + * @return false : fail + */ +bool smartconfig_set_type(sc_type type); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif #endif diff --git a/include/espressif/spi_flash.h b/include/espressif/spi_flash.h index 0bb2edd7..c6c769d9 100644 --- a/include/espressif/spi_flash.h +++ b/include/espressif/spi_flash.h @@ -1,24 +1,126 @@ -/* - * copyright (c) Espressif System 2010 - * +/* + * 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 __SPI_FLASH_H__ #define __SPI_FLASH_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup SPI_Driver_APIs SPI Driver APIs + * @brief SPI Flash APIs + */ + +/** @addtogroup SPI_Driver_APIs + * @{ + */ + typedef enum { - SPI_FLASH_RESULT_OK, - SPI_FLASH_RESULT_ERR, - SPI_FLASH_RESULT_TIMEOUT + SPI_FLASH_RESULT_OK, /**< SPI Flash operating OK */ + SPI_FLASH_RESULT_ERR, /**< SPI Flash operating fail */ + SPI_FLASH_RESULT_TIMEOUT /**< SPI Flash operating time out */ } SpiFlashOpResult; -#define SPI_FLASH_SEC_SIZE 4096 +#define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */ +/** + * @brief Get ID info of SPI Flash. + * + * @param null + * + * @return SPI Flash ID + */ uint32 spi_flash_get_id(void); + +/** + * @brief Read state register of SPI Flash. + * + * @param uint32 *status : the read value (pointer) of state register. + * + * @return SpiFlashOpResult + */ SpiFlashOpResult spi_flash_read_status(uint32 *status); + +/** + * @brief Write state register of SPI Flash. + * + * @param uint32 status_value : Write state register value. + * + * @return SpiFlashOpResult + */ SpiFlashOpResult spi_flash_write_status(uint32 status_value); + +/** + * @brief Erase the Flash sector. + * + * @param uint16 sec : Sector number, the count starts at sector 0, 4KB per sector. + * + * @return SpiFlashOpResult + */ SpiFlashOpResult spi_flash_erase_sector(uint16 sec); + +/** + * @brief Write data to Flash. + * + * @param uint32 des_addr : destination address in Flash. + * @param uint32 *src_addr : source address of the data. + * @param uint32 size : length of data + * + * @return SpiFlashOpResult + */ SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size); + +/** + * @brief Read data from Flash. + * + * @param uint32 src_addr : source address of the data. + * @param uint32 *des_addr : destination address in Flash. + * @param uint32 size : length of data + * + * @return SpiFlashOpResult + */ SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/espressif/upgrade.h b/include/espressif/upgrade.h index ec6dba99..974f6551 100644 --- a/include/espressif/upgrade.h +++ b/include/espressif/upgrade.h @@ -1,48 +1,149 @@ +/* + * 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 __UPGRADE_H__ #define __UPGRADE_H__ #include "lwip/sockets.h" -#define SPI_FLASH_SEC_SIZE 4096 +#ifdef __cplusplus +extern "C" { +#endif -#define USER_BIN1 0x00 -#define USER_BIN2 0x01 +/** \defgroup System_APIs System APIs + * @brief System APIs + */ -#define UPGRADE_FLAG_IDLE 0x00 -#define UPGRADE_FLAG_START 0x01 -#define UPGRADE_FLAG_FINISH 0x02 +/** @addtogroup System_APIs + * @{ + */ -#define UPGRADE_FW_BIN1 0x00 -#define UPGRADE_FW_BIN2 0x01 +/** \defgroup Upgrade_APIs Upgrade APIs + * @brief Firmware upgrade (FOTA) APIs + */ -typedef void (*upgrade_states_check_callback)(void * arg); +/** @addtogroup Upgrade_APIs + * @{ + */ + +#define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */ + +#define USER_BIN1 0x00 /**< firmware, user1.bin */ +#define USER_BIN2 0x01 /**< firmware, user2.bin */ + +#define UPGRADE_FLAG_IDLE 0x00 /**< flag of upgrading firmware, idle */ +#define UPGRADE_FLAG_START 0x01 /**< flag of upgrading firmware, start upgrade */ +#define UPGRADE_FLAG_FINISH 0x02 /**< flag of upgrading firmware, finish upgrading */ + +#define UPGRADE_FW_BIN1 0x00 /**< firmware, user1.bin */ +#define UPGRADE_FW_BIN2 0x01 /**< firmware, user2.bin */ + +/** + * @brief Callback of upgrading firmware through WiFi. + * + * @param void * arg : information about upgrading server + * + * @return null + */ +typedef void (*upgrade_states_check_callback)(void *arg); //#define UPGRADE_SSL_ENABLE struct upgrade_server_info { - struct sockaddr_in sockaddrin; - upgrade_states_check_callback check_cb; - uint32 check_times; - uint8 pre_version[16]; - uint8 upgrade_version[16]; - uint8 *url; + struct sockaddr_in sockaddrin; /**< socket of upgrading */ + upgrade_states_check_callback check_cb; /**< callback of upgrading */ + uint32 check_times; /**< time out of upgrading, unit : ms */ + uint8 pre_version[16]; /**< previous version of firmware */ + uint8 upgrade_version[16]; /**< the new version of firmware */ + uint8 *url; /**< the url of upgrading server */ void *pclient_param; - uint8 upgrade_flag; + uint8 upgrade_flag; /**< true, upgrade succeed; false, upgrade fail */ }; -#define UPGRADE_FLAG_IDLE 0x00 -#define UPGRADE_FLAG_START 0x01 -#define UPGRADE_FLAG_FINISH 0x02 - -bool system_upgrade_start(struct upgrade_server_info *server); -bool system_upgrade_start_ssl(struct upgrade_server_info *server); +/** + * @brief Upgrade function initialization. + * + * @param null + * + * @return null + */ void system_upgrade_init(); + +/** + * @brief Upgrade function de-initialization. + * + * @param null + * + * @return null + */ void system_upgrade_deinit(); + +/** + * @brief Upgrade function de-initialization. + * + * @param uint8 *data : segment of the firmware bin data + * @param uint32 len : length of the segment bin data + * + * @return null + */ bool system_upgrade(uint8 *data, uint32 len); #ifdef UPGRADE_SSL_ENABLE + +/** + * @brief Start upgrade firmware through WiFi with SSL connection. + * + * @param struct upgrade_server_info *server : the firmware upgrade server info + * + * @return true : succeed + * @return false : fail + */ bool system_upgrade_start_ssl(struct upgrade_server_info *server); #else + +/** + * @brief Start upgrade firmware through WiFi with normal connection. + * + * @param struct upgrade_server_info *server : the firmware upgrade server info + * + * @return true : succeed + * @return false : fail + */ + bool system_upgrade_start(struct upgrade_server_info *server); #endif + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/freertos/FreeRTOSConfig.h b/include/freertos/FreeRTOSConfig.h index 293f2bb4..0f157144 100644 --- a/include/freertos/FreeRTOSConfig.h +++ b/include/freertos/FreeRTOSConfig.h @@ -78,8 +78,9 @@ *----------------------------------------------------------*/ #define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 0 +#define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 0 +#define configUSE_TICKLESS_IDLE 1 #define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 ) #define configTICK_RATE_HZ ( ( portTickType ) 100 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) @@ -97,12 +98,13 @@ #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_MUTEXES 1 #define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_TIMERS 1 #if configUSE_TIMERS #define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) #define configTIMER_QUEUE_LENGTH (10) -#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 ) +#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 256 ) #endif /* Co-routine definitions. */ diff --git a/include/freertos/StackMacros.h b/include/freertos/StackMacros.h index 467da7ea..7fa9503c 100644 --- a/include/freertos/StackMacros.h +++ b/include/freertos/StackMacros.h @@ -134,7 +134,7 @@ #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ { \ - static const unsigned char ucExpectedStackBytes[] ICACHE_RODATA_ATTR = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ diff --git a/include/freertos/portmacro.h b/include/freertos/portmacro.h index 3d3dd58d..e8c85ceb 100644 --- a/include/freertos/portmacro.h +++ b/include/freertos/portmacro.h @@ -70,7 +70,8 @@ extern "C" { #endif -#include "esp_common.h" +#include "c_types.h" +#include "espressif/esp_libc.h" #include #include "xtensa_rtos.h" diff --git a/include/freertos/task.h b/include/freertos/task.h index ec1ce0b8..51e78857 100644 --- a/include/freertos/task.h +++ b/include/freertos/task.h @@ -1495,6 +1495,8 @@ void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ); */ void vTaskStepTick( portTickType xTicksToJump ); +portTickType prvGetExpectedIdleTime( void ); + /* * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port * specific sleep function to determine if it is ok to proceed with the sleep, diff --git a/include/lwip/arch/cc.h b/include/lwip/arch/cc.h index e62fc171..5a1f9209 100644 --- a/include/lwip/arch/cc.h +++ b/include/lwip/arch/cc.h @@ -47,12 +47,6 @@ #define BYTE_ORDER BIG_ENDIAN #endif -typedef unsigned char u8_t; -typedef signed char s8_t; -typedef unsigned short u16_t; -typedef signed short s16_t; -typedef unsigned long u32_t; -typedef signed long s32_t; typedef unsigned long mem_ptr_t; typedef int sys_prot_t; @@ -72,14 +66,16 @@ typedef int sys_prot_t; //#define LWIP_DEBUG -#ifdef LWIP_DEBUG #include -#define os_printf(fmt, ...) do { \ - static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = fmt; \ - printf(flash_str, ##__VA_ARGS__); \ - } while(0) +#ifndef os_printf +#define os_printf(fmt, ...) do { \ + static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = fmt; \ + printf(flash_str, ##__VA_ARGS__); \ + } while(0) +#endif +#ifdef LWIP_DEBUG #define LWIP_PLATFORM_DIAG(x) do {os_printf x;} while(0) #define LWIP_PLATFORM_ASSERT(x) do {os_printf(x); sys_arch_assert(__FILE__, __LINE__);} while(0) #else diff --git a/include/lwip/lwip/dhcpserver.h b/include/lwip/lwip/dhcpserver.h index 8e68e3e0..f959abb4 100644 --- a/include/lwip/lwip/dhcpserver.h +++ b/include/lwip/lwip/dhcpserver.h @@ -4,26 +4,27 @@ #define USE_DNS typedef struct dhcps_state{ - sint16_t state; + s16_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]; + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; + u8_t sname[64]; + u8_t file[128]; + u8_t options[312]; }dhcps_msg; #ifndef LWIP_OPEN_SRC struct dhcps_lease { + bool enable; struct ip_addr start_ip; struct ip_addr end_ip; }; @@ -37,8 +38,8 @@ enum dhcps_offer_option{ struct dhcps_pool{ struct ip_addr ip; - uint8 mac[6]; - uint32 lease_timer; + u8_t mac[6]; + u32_t lease_timer; }; typedef struct _list_node{ @@ -46,7 +47,8 @@ typedef struct _list_node{ struct _list_node *pnext; }list_node; -#define DHCPS_LEASE_TIMER 0x05A0 +extern u32_t dhcps_lease_time; +#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 #define DHCPS_MAX_LEASE 0x64 #define BOOTP_BROADCAST 0x8000 @@ -89,6 +91,7 @@ typedef struct _list_node{ #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) diff --git a/include/lwip/lwip/mem.h b/include/lwip/lwip/mem.h index f93d29be..87a8962e 100644 --- a/include/lwip/lwip/mem.h +++ b/include/lwip/lwip/mem.h @@ -33,7 +33,6 @@ #define __LWIP_MEM_H__ #include "lwip/opt.h" -#include "freertos/FreeRTOS.h" #ifdef __cplusplus extern "C" { diff --git a/include/lwip/lwip/netif.h b/include/lwip/lwip/netif.h index d28d8bed..49084b35 100644 --- a/include/lwip/lwip/netif.h +++ b/include/lwip/lwip/netif.h @@ -150,6 +150,8 @@ typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, ip6_addr_t *group, u8_t action); #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +/*add DHCP event processing by LiuHan*/ +typedef void (*dhcp_event_fn)(void); /** Generic data structure used for all lwIP network interfaces. * The following fields should be filled in by the initialization @@ -163,6 +165,8 @@ struct netif { ip_addr_t netmask; ip_addr_t gw; + ipX_addr_t link_local_addr; + #if LWIP_IPV6 /** Array of IPv6 addresses for this netif. */ ip6_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; @@ -208,6 +212,7 @@ struct netif { /** the DHCP client state information for this netif */ struct dhcp *dhcp; struct udp_pcb *dhcps_pcb; //dhcps + dhcp_event_fn dhcp_event; #endif /* LWIP_DHCP */ #if LWIP_AUTOIP /** the AutoIP client state information for this netif */ diff --git a/include/lwip/lwip/sockets.h b/include/lwip/lwip/sockets.h index e69d7ff1..4c30e575 100644 --- a/include/lwip/lwip/sockets.h +++ b/include/lwip/lwip/sockets.h @@ -70,6 +70,9 @@ struct sockaddr_in { }; #if LWIP_IPV6 + +#define INET6_ADDRSTRLEN 46 + struct sockaddr_in6 { u8_t sin6_len; /* length of this structure */ sa_family_t sin6_family; /* AF_INET6 */ @@ -421,6 +424,20 @@ int lwip_fcntl(int s, int cmd, int val); #define fcntl(a,b,c) lwip_fcntl(a,b,c) #endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ +#if LWIP_IPV6 +#define inet_ntop(af,src,dst,size) \ + (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t *)(src),(dst),(size)) \ + : (((af) == AF_INET) ? ipaddr_ntoa_r((const ip_addr_t *)(src),(dst),(size)) : NULL)) +#define inet_pton(af,src,dst) \ + (((af) == AF_INET6) ? inet6_aton((src),(const ip6_addr_t *)(dst)) \ + : (((af) == AF_INET) ? inet_aton((src),(const ip_addr_t *)(dst)) : 0)) +#else /* LWIP_IPV6 */ +#define inet_ntop(af,src,dst,size) \ + (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL) +#define inet_pton(af,src,dst) \ + (((af) == AF_INET) ? inet_aton((src),(dst)) : 0) +#endif /* LWIP_IPV6 */ + #endif /* LWIP_COMPAT_SOCKETS */ #ifdef __cplusplus diff --git a/include/lwip/lwipopts.h b/include/lwip/lwipopts.h index a75ff799..88040b3d 100644 --- a/include/lwip/lwipopts.h +++ b/include/lwip/lwipopts.h @@ -49,14 +49,15 @@ * MEMCPY: override this if you have a faster implementation at hand than the * one included in your C library */ -#define MEMCPY(dst,src,len) ets_memcpy(dst,src,len) +#define MEMCPY(dst,src,len) memcpy(dst,src,len) /** * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a * call to memcpy() if the length is known at compile time and is small. */ -#define SMEMCPY(dst,src,len) ets_memcpy(dst,src,len) +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#define LWIP_RAND os_random /* ------------------------------------ ---------- Memory options ---------- @@ -92,17 +93,13 @@ * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. * (requires the LWIP_TCP option) */ -#ifndef MEMP_NUM_TCP_PCB -#define MEMP_NUM_TCP_PCB 11 -#endif +#define MEMP_NUM_TCP_PCB (*(volatile uint32*)0x600011FC) /** * MEMP_NUM_NETCONN: the number of struct netconns. * (only needed if you use the sequential API, like api_lib.c) */ -#ifndef MEMP_NUM_NETCONN #define MEMP_NUM_NETCONN 10 -#endif /* -------------------------------- @@ -176,6 +173,11 @@ #define LWIP_DHCP_BOOTP_FILE 0 +/** + * DHCP_MAXRTX: Maximum number of retries of current request. + */ +#define DHCP_MAXRTX (*(volatile uint32*)0x600011E0) + /* ------------------------------------ ---------- AUTOIP options ---------- @@ -200,9 +202,7 @@ * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS * transport. */ -#ifndef LWIP_DNS #define LWIP_DNS 1 -#endif /* --------------------------------- @@ -214,6 +214,12 @@ ---------- TCP options ---------- --------------------------------- */ +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#define TCP_WND (*(volatile uint32*)0x600011F0) + /** * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. * Define to 0 if your device is low on memory. @@ -231,13 +237,12 @@ /** * TCP_MAXRTX: Maximum number of retransmissions of data segments. */ -#define TCP_MAXRTX 6 - +#define TCP_MAXRTX (*(volatile uint32*)0x600011E8) /** * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. */ -#define TCP_SYNMAXRTX 3 +#define TCP_SYNMAXRTX (*(volatile uint32*)0x600011E4) /** * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. @@ -293,9 +298,7 @@ /** * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. */ -#ifndef TCPIP_THREAD_NAME #define TCPIP_THREAD_NAME "tiT" -#endif /** * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. @@ -392,9 +395,7 @@ /** * LWIP_STATS==1: Enable statistics collection in lwip_stats. */ -#ifndef LWIP_STATS #define LWIP_STATS 0 -#endif /* --------------------------------- @@ -413,6 +414,10 @@ ---------- IPv6 options --------------- --------------------------------------- */ +/** + * LWIP_IPV6==1: Enable IPv6 + */ +#define LWIP_IPV6 1 /* --------------------------------------- diff --git a/include/nopoll/nopoll.h b/include/nopoll/nopoll.h new file mode 100644 index 00000000..c483e4b8 --- /dev/null +++ b/include/nopoll/nopoll.h @@ -0,0 +1,135 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_H__ +#define __NOPOLL_H__ + +#include +#include + +BEGIN_C_DECLS + +#if defined(NOPOLL_OS_WIN32) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * \addtogroup nopoll_module + * @{ + */ + +nopoll_bool nopoll_cmp (const char * string1, const char * string2); + +nopoll_bool nopoll_ncmp (const char * string1, const char * string2, int bytes); + +char * nopoll_strdup_printf (const char * chunk, ...); + +char * nopoll_strdup_printfv (const char * chunk, va_list args); + +void nopoll_trim (char * chunk, int * trimmed); + +void nopoll_sleep (long microseconds); + +void nopoll_thread_handlers (noPollMutexCreate mutex_create, + noPollMutexDestroy mutex_destroy, + noPollMutexLock mutex_lock, + noPollMutexUnlock mutex_unlock); + +noPollPtr nopoll_mutex_create (void); + +void nopoll_mutex_lock (noPollPtr mutex); + +void nopoll_mutex_unlock (noPollPtr mutex); + +void nopoll_mutex_destroy (noPollPtr mutex); + +nopoll_bool nopoll_base64_encode (const char * content, + int length, + char * output, + int * output_size); + +nopoll_bool nopoll_base64_decode (const char * content, + int length, + char * output, + int * output_size); + +int nopoll_timeval_substract (struct timeval * a, + struct timeval * b, + struct timeval * result); + +char * nopoll_strdup (const char * buffer); + +nopoll_bool nopoll_nonce (char * buffer, int nonce_size); + +void nopoll_cleanup_library (void); + +int nopoll_get_bit (char byte, int position); + +void nopoll_set_bit (char * buffer, int position); + +void nopoll_show_byte (noPollCtx * ctx, char byte, const char * label); + +char * nopoll_int2bin (int a, char *buffer, int buf_size); + +void nopoll_int2bin_print (noPollCtx * ctx, int value); + +int nopoll_get_8bit (const char * buffer); + +int nopoll_get_16bit (const char * buffer); + +void nopoll_set_16bit (int value, char * buffer); + +void nopoll_set_32bit (int value, char * buffer); + +int nopoll_get_32bit (const char * buffer); + +/* @} */ + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_config.h b/include/nopoll/nopoll_config.h new file mode 100644 index 00000000..d8f2116a --- /dev/null +++ b/include/nopoll/nopoll_config.h @@ -0,0 +1,67 @@ +/* + * Nopoll Library nopoll_config.h + * Platform dependant definitions. + * + * This is a generated file. Please modify 'configure.in' + */ + +#ifndef __NOPOLL_CONFIG_H__ +#define __NOPOLL_CONFIG_H__ + +/** + * \addtogroup nopoll_decl_module + * @{ + */ + +/** + * @brief Allows to convert integer value (including constant values) + * into a pointer representation. + * + * Use the oposite function to restore the value from a pointer to a + * integer: \ref PTR_TO_INT. + * + * @param integer The integer value to cast to pointer. + * + * @return A \ref noPollPtr reference. + */ +#ifndef INT_TO_PTR +#define INT_TO_PTR(integer) ((noPollPtr) (long) ((int)integer)) +#endif + +/** + * @brief Allows to convert a pointer reference (\ref noPollPtr), + * which stores an integer that was stored using \ref INT_TO_PTR. + * + * Use the oposite function to restore the pointer value stored in the + * integer value. + * + * @param ptr The pointer to cast to a integer value. + * + * @return A int value. + */ +#ifndef PTR_TO_INT +#define PTR_TO_INT(ptr) ((int) (long) (ptr)) +#endif + +/** + * @brief Allows to get current platform configuration. This is used + * by Nopoll library but could be used by applications built on top of + * Nopoll to change its configuration based on the platform information. + */ +#define NOPOLL_OS_UNIX (0) + +/** + * @internal Allows to now if the platform support vasprintf + * function. Do not use this macro as it is supposed to be for + * internal use. + */ +//#define NOPOLL_HAVE_VASPRINTF (1) + +/** + * @brief Indicates that this platform have support for 64bits. + */ +//#define NOPOLL_64BIT_PLATFORM (0) + +/* @} */ + +#endif diff --git a/include/nopoll/nopoll_conn.h b/include/nopoll/nopoll_conn.h new file mode 100644 index 00000000..aff440f8 --- /dev/null +++ b/include/nopoll/nopoll_conn.h @@ -0,0 +1,198 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_CONN_H__ +#define __NOPOLL_CONN_H__ + +#include + +BEGIN_C_DECLS + +noPollConn * nopoll_conn_new (noPollCtx * ctx, + const char * host_ip, + const char * host_port, + const char * host_name, + const char * get_url, + const char * protocols, + const char * origin); + +noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, + noPollConnOpts * opts, + const char * host_ip, + const char * host_port, + const char * host_name, + const char * get_url, + const char * protocols, + const char * origin); + +noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, + noPollConnOpts * options, + const char * host_ip, + const char * host_port, + const char * host_name, + const char * get_url, + const char * protocols, + const char * origin); + +noPollConn * nopoll_conn_accept (noPollCtx * ctx, noPollConn * listener); + +noPollConn * nopoll_conn_accept_socket (noPollCtx * ctx, noPollConn * listener, NOPOLL_SOCKET session); + +nopoll_bool nopoll_conn_accept_complete (noPollCtx * ctx, + noPollConn * listener, + noPollConn * conn, + NOPOLL_SOCKET session, + nopoll_bool tls_on); + +nopoll_bool nopoll_conn_ref (noPollConn * conn); + +int nopoll_conn_ref_count (noPollConn * conn); + +void nopoll_conn_unref (noPollConn * conn); + +nopoll_bool nopoll_conn_is_ok (noPollConn * conn); + +nopoll_bool nopoll_conn_is_ready (noPollConn * conn); + +nopoll_bool nopoll_conn_is_tls_on (noPollConn * conn); + +NOPOLL_SOCKET nopoll_conn_socket (noPollConn * conn); + +void nopoll_conn_set_socket (noPollConn * conn, NOPOLL_SOCKET _socket); + +int nopoll_conn_get_id (noPollConn * conn); + +noPollCtx * nopoll_conn_ctx (noPollConn * conn); + +noPollRole nopoll_conn_role (noPollConn * conn); + +const char * nopoll_conn_host (noPollConn * conn); + +const char * nopoll_conn_port (noPollConn * conn); + +const char * nopoll_conn_get_origin (noPollConn * conn); + +const char * nopoll_conn_get_host_header (noPollConn * conn); + +const char * nopoll_conn_get_cookie (noPollConn * conn); + +const char * nopoll_conn_get_accepted_protocol (noPollConn * conn); + +const char * nopoll_conn_get_requested_protocol (noPollConn * conn); + +void nopoll_conn_set_accepted_protocol (noPollConn * conn, const char * protocol); + +int nopoll_conn_get_close_status (noPollConn * conn); + +const char * nopoll_conn_get_close_reason (noPollConn * conn); + +void nopoll_conn_shutdown (noPollConn * conn); + +void nopoll_conn_close (noPollConn * conn); + +void nopoll_conn_close_ext (noPollConn * conn, int status, const char * reason, int reason_size); + +void nopoll_conn_set_hook (noPollConn * conn, noPollPtr ptr); + +noPollPtr nopoll_conn_get_hook (noPollConn * conn); + +nopoll_bool nopoll_conn_set_sock_block (NOPOLL_SOCKET socket, + nopoll_bool enable); + +noPollMsg * nopoll_conn_get_msg (noPollConn * conn); + +int nopoll_conn_send_text (noPollConn * conn, const char * content, long length); + +int nopoll_conn_send_text_fragment (noPollConn * conn, const char * content, long length); + +int nopoll_conn_send_binary (noPollConn * conn, const char * content, long length); + +int nopoll_conn_send_binary_fragment (noPollConn * conn, const char * content, long length); + +int nopoll_conn_complete_pending_write (noPollConn * conn); + +int nopoll_conn_pending_write_bytes (noPollConn * conn); + +int nopoll_conn_flush_writes (noPollConn * conn, long timeout, int previous_result); + +int nopoll_conn_read (noPollConn * conn, char * buffer, int bytes, nopoll_bool block, long int timeout); + +noPollConn * nopoll_conn_get_listener (noPollConn * conn); + +nopoll_bool nopoll_conn_send_ping (noPollConn * conn); + +nopoll_bool nopoll_conn_send_pong (noPollConn * conn); + +void nopoll_conn_set_on_msg (noPollConn * conn, + noPollOnMessageHandler on_msg, + noPollPtr user_data); + +void nopoll_conn_set_on_ready (noPollConn * conn, + noPollActionHandler on_ready, + noPollPtr user_data); + +void nopoll_conn_set_on_close (noPollConn * conn, + noPollOnCloseHandler on_close, + noPollPtr user_data); + +int nopoll_conn_send_frame (noPollConn * conn, nopoll_bool fin, nopoll_bool masked, + noPollOpCode op_code, long length, noPollPtr content, + long sleep_in_header); + +int __nopoll_conn_send_common (noPollConn * conn, + const char * content, + long length, + nopoll_bool has_fin, + long sleep_in_header, + noPollOpCode frame_type); + +nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, + int timeout); + +/** internal api **/ +void nopoll_conn_complete_handshake (noPollConn * conn); + +int nopoll_conn_default_receive (noPollConn * conn, char * buffer, int buffer_size); + +int nopoll_conn_default_send (noPollConn * conn, char * buffer, int buffer_size); + +void nopoll_conn_mask_content (noPollCtx * ctx, char * payload, int payload_size, char * mask, int desp); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_conn_opts.h b/include/nopoll/nopoll_conn_opts.h new file mode 100644 index 00000000..5aeb571f --- /dev/null +++ b/include/nopoll/nopoll_conn_opts.h @@ -0,0 +1,73 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_CONN_OPTS_H__ +#define __NOPOLL_CONN_OPTS_H__ + +#include + +BEGIN_C_DECLS + +noPollConnOpts * nopoll_conn_opts_new (void); + +void nopoll_conn_opts_set_ssl_protocol (noPollConnOpts * opts, noPollSslProtocol ssl_protocol); + +nopoll_bool nopoll_conn_opts_set_ssl_certs (noPollConnOpts * opts, + const char * client_certificate, + const char * private_key, + const char * chain_certificate, + const char * ca_certificate); + +void nopoll_conn_opts_ssl_peer_verify (noPollConnOpts * opts, nopoll_bool verify); + +void nopoll_conn_opts_set_cookie (noPollConnOpts * opts, const char * cookie_content); + +nopoll_bool nopoll_conn_opts_ref (noPollConnOpts * opts); + +void nopoll_conn_opts_unref (noPollConnOpts * opts); + +void nopoll_conn_opts_set_reuse (noPollConnOpts * opts, nopoll_bool reuse); + +void nopoll_conn_opts_free (noPollConnOpts * opts); + +/** internal API **/ +void __nopoll_conn_opts_release_if_needed (noPollConnOpts * options); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_ctx.h b/include/nopoll/nopoll_ctx.h new file mode 100644 index 00000000..a9e41545 --- /dev/null +++ b/include/nopoll/nopoll_ctx.h @@ -0,0 +1,106 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_CTX_H__ +#define __NOPOLL_CTX_H__ + +#include + +BEGIN_C_DECLS + +noPollCtx * nopoll_ctx_new (void); + +nopoll_bool nopoll_ctx_ref (noPollCtx * ctx); + +void nopoll_ctx_unref (noPollCtx * ctx); + +int nopoll_ctx_ref_count (noPollCtx * ctx); + +nopoll_bool nopoll_ctx_register_conn (noPollCtx * ctx, + noPollConn * conn); + +void nopoll_ctx_unregister_conn (noPollCtx * ctx, + noPollConn * conn); + +int nopoll_ctx_conns (noPollCtx * ctx); + +nopoll_bool nopoll_ctx_set_certificate (noPollCtx * ctx, + const char * serverName, + const char * certificateFile, + const char * privateKey, + const char * optionalChainFile); + +nopoll_bool nopoll_ctx_find_certificate (noPollCtx * ctx, + const char * serverName, + const char ** certificateFile, + const char ** privateKey, + const char ** optionalChainFile); + +void nopoll_ctx_set_on_accept (noPollCtx * ctx, + noPollActionHandler on_accept, + noPollPtr user_data); + +void nopoll_ctx_set_on_open (noPollCtx * ctx, + noPollActionHandler on_open, + noPollPtr user_data); + +void nopoll_ctx_set_on_ready (noPollCtx * ctx, + noPollActionHandler on_ready, + noPollPtr user_data); + +void nopoll_ctx_set_on_msg (noPollCtx * ctx, + noPollOnMessageHandler on_msg, + noPollPtr user_data); + +void nopoll_ctx_set_ssl_context_creator (noPollCtx * ctx, + noPollSslContextCreator context_creator, + noPollPtr user_data); + +void nopoll_ctx_set_post_ssl_check (noPollCtx * ctx, + noPollSslPostCheck post_ssl_check, + noPollPtr user_data); + +noPollConn * nopoll_ctx_foreach_conn (noPollCtx * ctx, noPollForeachConn foreach, noPollPtr user_data); + +void nopoll_ctx_set_protocol_version (noPollCtx * ctx, int version); + +void nopoll_ctx_free (noPollCtx * ctx); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_decl.h b/include/nopoll/nopoll_decl.h new file mode 100644 index 00000000..04a1e585 --- /dev/null +++ b/include/nopoll/nopoll_decl.h @@ -0,0 +1,467 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_DECL_H__ +#define __NOPOLL_DECL_H__ + +/** + * \defgroup nopoll_decl_module Nopoll Declarations: Common Nopoll declarations, Types, macros, and support functions. + */ + +/** + * \addtogroup nopoll_decl_module + * @{ + */ + +/* include platform specific configuration */ +#include + +/* include this at this place to load GNU extensions */ +#if defined(__GNUC__) +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# define __NOPOLL_PRETTY_FUNCTION__ __PRETTY_FUNCTION__ +# define __NOPOLL_LINE__ __LINE__ +# define __NOPOLL_FILE__ __FILE__ +#elif defined(_MSC_VER) +# define __NOPOLL_PRETTY_FUNCTION__ __FUNCDNAME__ +# define __NOPOLL_LINE__ __LINE__ +# define __NOPOLL_FILE__ __FILE__ +#else +/* unknown compiler */ +#define __NOPOLL_PRETTY_FUNCTION__ "" +#define __NOPOLL_LINE__ 0 +#define __NOPOLL_FILE__ "" +#endif + +#include +#include +#include +#include + +/* only include unistd.h if unix platform is found or gnu gcc compiler + * is found */ +#if defined(__GNUC__) || defined(NOPOLL_OS_UNIX) +# include +#endif + +//#include +//#include +//#include +//#include +#include "lwip/netdb.h" +#include "lwip/sockets.h" + +/* Direct portable mapping definitions */ +#if defined(NOPOLL_OS_UNIX) + +/* Portable definitions while using noPoll Library */ +#define NOPOLL_EINTR EINTR +/** + * @brief Portable definition for EWOULDBLOCK errno code. + */ +#define NOPOLL_EWOULDBLOCK EWOULDBLOCK +#define NOPOLL_EINPROGRESS EINPROGRESS +#define NOPOLL_ENOTCONN ENOTCONN +#define NOPOLL_EAGAIN EAGAIN +#define NOPOLL_SOCKET int +#define NOPOLL_INVALID_SOCKET -1 +#define NOPOLL_SOCKET_ERROR -1 +#define nopoll_close_socket(s) do {if ( s >= 0) {close (s);}} while (0) +#define nopoll_is_disconnected (errno == EPIPE) + +#endif /* end defined(AXL_OS_UNIX) */ + +#if defined(NOPOLL_OS_WIN32) + +/* additional includes for the windows platform */ + +/* _WIN32_WINNT note: If the application including the header defines + * the _WIN32_WINNT, it must include the bit defined by the value + * 0x400. */ +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x400 +#endif +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_FULL_VER +#define strcasecmp(string1, string2) _stricmp(string1, string2) +#endif + +#define NOPOLL_EINTR WSAEINTR +#define NOPOLL_EWOULDBLOCK WSAEWOULDBLOCK +#define NOPOLL_EINPROGRESS WSAEINPROGRESS +#define NOPOLL_ENOTCONN WSAENOTCONN +#define NOPOLL_EAGAIN WSAEWOULDBLOCK +#define SHUT_RDWR SD_BOTH +#define SHUT_WR SD_SEND +#define NOPOLL_SOCKET SOCKET +#define NOPOLL_INVALID_SOCKET INVALID_SOCKET +#define NOPOLL_SOCKET_ERROR SOCKET_ERROR +#define nopoll_close_socket(s) do {if ( s >= 0) {closesocket (s);}} while (0) +#define uint16_t u_short +#define nopoll_is_disconnected ((errno == WSAESHUTDOWN) || (errno == WSAECONNABORTED) || (errno == WSAECONNRESET)) + +/* a definition to avoid warnings */ +#define strlen (int) strlen + +/* no link support windows */ +#define S_ISLNK(m) (0) + +#endif /* end defined(AXL_OS_WINDOWS) */ + +#if defined(NOPOLL_OS_UNIX) +//#include +//#include +//#include "c_types.h" +//#include +//#include +//#include "lwip/sockets.h" +//#include +//#include +//#include +//#include +//#include +//#include +#endif + +/* additional headers for poll support */ +#if defined(NOPOLL_HAVE_POLL) +#include +#endif + +/* additional headers for linux epoll support */ +#if defined(NOPOLL_HAVE_EPOLL) +#include +#endif + +//#include + +#if defined(NOPOLL_OS_WIN32) +/* errno redefinition for windows platform. this declaration must + * follow the previous include. */ +#ifdef errno +#undef errno +#endif +#define errno (WSAGetLastError()) +#endif + +/** + * @brief Common definition to have false (\ref nopoll_false) value (which is defined to 0 integer value). + */ +#define nopoll_false ((int)0) +/** + * @brief Common definition to have true (\ref nopoll_true) value (which is defined to 1 integer value). + */ +#define nopoll_true ((int)1) + +/** + * @brief Bool definition for the Nopoll toolkit. This type built on + * top of int is used along with \ref nopoll_false and \ref + * nopoll_true to model those API functions and attributes that + * returns or receive a boolean state. + */ +typedef int nopoll_bool; + +/** + * @brief Pointer to any structure definition. It should be required + * to use this definition, however, some platforms doesn't support the + * void * making it necessary to use the char * + * definition as a general way to represent references. + */ +typedef void * noPollPtr; + +/** + * @brief Execution context object used by the API to provide default + * settings. + */ +typedef struct _noPollCtx noPollCtx; + +/** + * @brief Abstraction that represents a connection that maybe be a listener created by \ref nopoll_listener_new or because the connection was received as a consequence of that call, or because it is a client connection created by \ref nopoll_conn_new + * + * See noPoll API because there are other methods to create connections (not only previous mentioned functions). + */ +typedef struct _noPollConn noPollConn; + +/** + * @brief Optional connection options to change default behaviour. + */ +typedef struct _noPollConnOpts noPollConnOpts; + +/** + * @brief Abstraction that represents a selected IO wait mechanism. + */ +typedef struct _noPollIoEngine noPollIoEngine; + +/** + * @brief Abstraction that represents a single websocket message + * received. + */ +typedef struct _noPollMsg noPollMsg; + +/** + * @brief Abstraction that represents the status and data exchanged + * during the handshake. + */ +typedef struct _noPollHandshake noPollHandShake; + +/** + * @brief Nopoll debug levels. + * + * While reporting log to the console, these levels are used to report + * the severity for such log. + */ +typedef enum { + /** + * @brief Debug level. Only used to report common + * circumstances that represent the proper functionality. + */ + NOPOLL_LEVEL_DEBUG, + /** + * @brief Warning level. Only used to report that an internal + * issue have happend that could be interesting while + * reporting error, but it could also mean common situations. + */ + NOPOLL_LEVEL_WARNING, + /** + * @brief Critical level. Only used to report critical + * situations where some that have happened shouldn't. + * + * This level should only be used while reporting critical + * situations. + */ + NOPOLL_LEVEL_CRITICAL} +noPollDebugLevel; + +/** + * @brief Describes the connection role (how it was initiated). + */ +typedef enum { + /** + * @brief Unknown role, returned/used when the connection isn't defined. + */ + NOPOLL_ROLE_UNKNOWN, + /** + * @brief When the connection was created connecting to a web + * socket server (see \ref nopoll_conn_new). + */ + NOPOLL_ROLE_CLIENT, + /** + * @brief When the connection was accepted being a listener + * process. + */ + NOPOLL_ROLE_LISTENER, + /** + * @brief When the connection was created by \ref + * nopoll_listener_new to accept incoming connections. + */ + NOPOLL_ROLE_MAIN_LISTENER +} noPollRole; + +/** + * @brief List of supported IO waiting mechanism available. + */ +typedef enum { + /** + * @brief Selects the default (best) IO mechanism found on the + * system. + */ + NOPOLL_IO_ENGINE_DEFAULT, + /** + * @brief Selects the select(2) based IO wait mechanism. + */ + NOPOLL_IO_ENGINE_SELECT, + /** + * @brief Selects the poll(2) based IO wait mechanism. + */ + NOPOLL_IO_ENGINE_POLL, + /** + * @brief Selects the epoll(2) based IO wait mechanism. + */ + NOPOLL_IO_ENGINE_EPOLL +} noPollIoEngineType; + +/** + * @brief Support macro to allocate memory using nopoll_calloc function, + * making a casting and using the sizeof keyword. + * + * @param type The type to allocate + * @param count How many items to allocate. + * + * @return A newly allocated pointer. + */ +#define nopoll_new(type, count) (type *) nopoll_calloc (count, sizeof (type)) + +/** + * @brief Allows to check a condition and return if it is not meet. + * + * @param ctx The context where the operation will take place. + * @param expr The expresion to check. + */ +#define nopoll_return_if_fail(ctx, expr) \ + if (!(expr)) {__nopoll_log (ctx, __function_name__, __file__, __line__, NOPOLL_LEVEL_CRITICAL, "Expresion '%s' have failed at %s (%s:%d)", #expr, __NOPOLL_PRETTY_FUNCTION__, __NOPOLL_FILE__, __NOPOLL_LINE__); return;} + +/** + * @brief Allows to check a condition and return the given value if it + * is not meet. + * + * @param ctx The context where the operation will take place. + * + * @param expr The expresion to check. + * + * @param val The value to return if the expression is not meet. + */ +#define nopoll_return_val_if_fail(ctx, expr, val) \ + if (!(expr)) { __nopoll_log (ctx, __function_name__, __file__, __line__, NOPOLL_LEVEL_CRITICAL, "Expresion '%s' have failed, returning: %s at %s (%s:%d)", #expr, #val, __NOPOLL_PRETTY_FUNCTION__, __NOPOLL_FILE__, __NOPOLL_LINE__); return val;} + + +/** + * @internal + * + * C++ support declarations borrowed from the libtool webpage. Thanks + * you guys for this information. + * + * BEGIN_C_DECLS should be used at the beginning of your declarations, + * so that C++ compilers don't mangle their names. Use END_C_DECLS at + * the end of C declarations. + */ +#undef BEGIN_C_DECLS +#undef END_C_DECLS +#ifdef __cplusplus +# define BEGIN_C_DECLS extern "C" { +# define END_C_DECLS } +#else +# define BEGIN_C_DECLS /* empty */ +# define END_C_DECLS /* empty */ +#endif + + +/** + * @brief Type of frames and opcodes supported by noPoll. + */ +typedef enum { + /** + * @brief Support to model unknown op code. + */ + NOPOLL_UNKNOWN_OP_CODE = -1, + /** + * @brief Denotes a continuation frame. + */ + NOPOLL_CONTINUATION_FRAME = 0, + /** + * @brief Denotes a text frame (utf-8 content) and the first + * frame of the message. + */ + NOPOLL_TEXT_FRAME = 1, + /** + * @brief Denotes a binary frame and the first frame of the + * message. + */ + NOPOLL_BINARY_FRAME = 2, + /** + * @brief Denotes a close frame request. + */ + NOPOLL_CLOSE_FRAME = 8, + /** + * @brief Denotes a ping frame (used to ring test the circuit + * and to keep alive the connection). + */ + NOPOLL_PING_FRAME = 9, + /** + * @brief Denotes a pong frame (reply to ping request). + */ + NOPOLL_PONG_FRAME = 10 +} noPollOpCode; + +/** + * @brief SSL/TLS protocol type to use for the client or listener + * connection. + */ +typedef enum { + /** + * @brief Allows to define SSLv23 as SSL protocol used by the + * client or server connection. A TLS/SSL connection + * established with these methods may understand SSLv3, TLSv1, + * TLSv1.1 and TLSv1.2 protocols (\ref NOPOLL_METHOD_SSLV3, \ref NOPOLL_METHOD_TLSV1, ...) + */ + NOPOLL_METHOD_SSLV23 = 2, + /** + * @brief Allows to define SSLv3 as SSL protocol used by the + * client or server connection. A connection/listener + * established with this method will only understand this + * method. + */ + NOPOLL_METHOD_SSLV3 = 3, + /** + * @brief Allows to define TLSv1 as SSL protocol used by the + * client or server connection. A connection/listener + * established with this method will only understand this + * method. + */ + NOPOLL_METHOD_TLSV1 = 4, +//#if defined(TLSv1_1_client_method) + /** + * @brief Allows to define TLSv1.1 as SSL protocol used by the + * client or server connection. A connection/listener + * established with this method will only understand this + * method. + */ + NOPOLL_METHOD_TLSV1_1 = 5 +//#endif +} noPollSslProtocol ; + +BEGIN_C_DECLS + +noPollPtr nopoll_calloc (size_t count, size_t size); + +noPollPtr nopoll_realloc (noPollPtr ref, size_t size); + +void nopoll_free (noPollPtr ref); + +END_C_DECLS + +#endif + +/* @} */ diff --git a/include/nopoll/nopoll_handlers.h b/include/nopoll/nopoll_handlers.h new file mode 100644 index 00000000..e3a385ce --- /dev/null +++ b/include/nopoll/nopoll_handlers.h @@ -0,0 +1,329 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_HANDLERS_H__ +#define __NOPOLL_HANDLERS_H__ + +/** + * \defgroup nopoll_handlers noPoll Handlers: Handler definitions used by the library to du async notifications + */ + +/** + * \addtogroup nopoll_handlers + * @{ + */ + +/** + * @brief General async handler definition used to notify generic + * events associated to a connection. + * + * Currently this handler is used by: + * - \ref nopoll_ctx_set_on_accept + * - \ref nopoll_ctx_set_on_open + * + * @param ctx The context where the wait is happening. + * + * @param conn The connection where the data or something meaningful + * was detected. + * + * @param user_data Optional user data pointer passed in into the handler. + * + * @return The function returns a boolean value which is interpreted + * in an especific form according to the event. + */ +typedef nopoll_bool (*noPollActionHandler) (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data); + +/** + * @brief Handler used to define the create function for an IO mechanism. + * + * @param ctx The context where the io mechanism will be created. + */ +typedef noPollPtr (*noPollIoMechCreate) (noPollCtx * ctx); + +/** + * @brief Handler used to define the IO wait set destroy function for + * an IO mechanism. + * + * @param ctx The context where the io mechanism will be destroyed. + * + * @param io_object The io object to be destroyed as created by \ref + * noPollIoMechCreate handler. + */ +typedef void (*noPollIoMechDestroy) (noPollCtx * ctx, noPollPtr io_object); + +/** + * @brief Handler used to define the IO wait set clear function for an + * IO mechanism. + * + * @param ctx The context where the io mechanism will be cleared. + * + * @param io_object The io object to be created as created by \ref + * noPollIoMechCreate handler. + */ +typedef void (*noPollIoMechClear) (noPollCtx * ctx, noPollPtr io_object); + + +/** + * @brief Handler used to define the IO wait function for an IO + * mechanism. + * + * @param ctx The context where the io mechanism was created. + * + * @param io_object The io object to be created as created by \ref + * noPollIoMechCreate handler where the wait will be implemented. + */ +typedef int (*noPollIoMechWait) (noPollCtx * ctx, noPollPtr io_object); + + +/** + * @brief Handler used to define the IO add to set function for an IO + * mechanism. + * + * @param ctx The context where the io mechanism was created. + * + * @param conn The noPollConn to be added to the working set. + * + * @param io_object The io object to be created as created by \ref + * noPollIoMechCreate handler where the wait will be implemented. + */ +typedef nopoll_bool (*noPollIoMechAddTo) (int fds, + noPollCtx * ctx, + noPollConn * conn, + noPollPtr io_object); + + +/** + * @brief Handler used to define the IO is set function for an IO + * mechanism. + * + * @param ctx The context where the io mechanism was created. + * + * @param conn The noPollConn to be added to the working set. + * + * @param io_object The io object to be created as created by \ref + * noPollIoMechCreate handler where the wait will be implemented. + */ +typedef nopoll_bool (*noPollIoMechIsSet) (noPollCtx * ctx, + int fds, + noPollPtr io_object); + +/** + * @brief Handler used to define the foreach function that is used by + * \ref nopoll_ctx_foreach_conn + * + * @param ctx The context where the foreach operation is taking place. + * + * @param conn The connection notified + * + * @param user_data Optional user defined pointer received at \ref + * nopoll_ctx_foreach_conn. + * + * @return nopoll_true to stop the foreach process, otherwise + * nopoll_false to keep checking the next connection until all + * connections are notified. + */ +typedef nopoll_bool (*noPollForeachConn) (noPollCtx * ctx, + noPollConn * conn, + noPollPtr user_data); + +/** + * @brief Handler definition used to describe read functions used by \ref noPollConn. + * + * @param conn The connection where the readOperation will take place. + * + * @param buffer The buffer where data read from socket will be placed. + * + * @param buffer_size The buffer size that is receiving the function. + */ +typedef int (*noPollRead) (noPollConn * conn, + char * buffer, + int buffer_size); + +/** + * @brief Handler definition used to notify websocket messages + * received. + * + * This handler will be called when a websocket message is + * received. Keep in mind the reference received on this handler will + * be finished when the handler ends. If you need to have a reference + * to the message after handler execution, acquire a reference via + * \ref nopoll_msg_ref. + * + * @param ctx The context where the messagewas received. + * + * @param conn The connection where the message was received. + * + * @param msg The websocket message was received. + * + * @param user_data An optional user defined pointer. + */ +typedef void (*noPollOnMessageHandler) (noPollCtx * ctx, + noPollConn * conn, + noPollMsg * msg, + noPollPtr user_data); + +/** + * @brief Handler definition used by \ref nopoll_conn_set_on_close. + * + * Handler definition for the function that is called when the + * connection is closed but just before shutting down the socket + * associated to the connection. + * + * @param ctx The context where the operation will take place. + * + * @param conn The connection where the operation will take place. + * + * @param user_data The reference that was configured to be passed in + * into the handler. + */ +typedef void (*noPollOnCloseHandler) (noPollCtx * ctx, + noPollConn * conn, + noPollPtr user_data); + +/** + * @brief Mutex creation handler used by the library. + * + * @return A reference to the mutex created (already initialized). + */ +typedef noPollPtr (*noPollMutexCreate) (void); + +/** + * @brief Mutex destroy handler used by the library. + * + * @param The mutex to destroy. + */ +typedef void (*noPollMutexDestroy) (noPollPtr mutex); + +/** + * @brief Mutex lock handler used by the library. + * + * @param The mutex where to implement the lock operation. + */ +typedef void (*noPollMutexLock) (noPollPtr mutex); + +/** + * @brief Mutex unlock handler used by the library. + * + * @param The mutex where to implement the unlock operation. + */ +typedef void (*noPollMutexUnlock) (noPollPtr mutex); + +/** + * @brief Handler used by nopoll_log_set_handler to receive all log + * notifications produced by the library on this function. + * + * @param ctx The context where the operation is happening. + * + * @param level The log level + * + * @param log_msg The actual log message reported. + * + * @param user_data A reference to user defined pointer passed in into the function. + */ +typedef void (*noPollLogHandler) (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data); + +/** + * @brief An optional handler that allows user land code to define how + * is SSL_CTX (SSL context) created and which are the settings it + * should have before taking place SSL/TLS handshake. + * + * NOTE: that the function should return one context for every + * connection created. Do not reuse unless you know what you are + * doing. + * + * A very bare implementation for this context creation will be: + * + * \code + * SSL_CTX * my_ssl_ctx_creator (noPollCtx * ctx, noPollConn * conn, noPollConnOpts * opts, nopoll_bool is_client, noPollPtr user_data) + * { + * // very basic context creation using default settings provided by OpenSSL + * return SSL_CTX_new (is_client ? TLSv1_client_method () : TLSv1_server_method ()); + * } + * \endcode + * + * @param ctx The context where the operation is taking place. + * + * @param conn The connection that is being requested for a new context (SSL_CTX). Use is_client to know if this is a connecting client or a listener connection. + * + * @param opts Optional reference to the connection object created for this connection. + * + * @param is_client nopoll_true to signal that this is a request for a context for a client connection. Otherwise, it is for a listener connection. + * + * @param user_data User defined pointer that received on this function as defined at \ref nopoll_ctx_set_ssl_context_creator. + * + * @return The function must return a valid SSL_CTX object (see OpenSSL documentation to know more about this) or NULL if it fails. + */ +typedef noPollPtr (*noPollSslContextCreator) (noPollCtx * ctx, + noPollConn * conn, + noPollConnOpts * opts, + nopoll_bool is_client, + noPollPtr user_data); + +/** + * @brief Optional user defined handler that allows to execute SSL + * post checks code before proceed. + * + * This handler is configured at \ref nopoll_ctx_set_post_ssl_check + * and allows to implement custom actions while additional + * verifications about certificate received, validation based on + * certain attributes, etc. + * + * Note that when this handler is called, the SSL handshake has + * finished without error. In case of SSL handshake failure, this + * handler is not executed. + * + * @param ctx The context where the operation happens. + * + * @param conn The connection where the operation takes place and for which the post SSL check is being done. + * + * @param SSL_CTX The OpenSSL SSL_CTX object created for this connection. + * + * @param SSL The OpenSSL SSL object created for this connection. + * + * @param user_data User defined data that is received on this handler as configured at \ref nopoll_ctx_set_post_ssl_check + */ +typedef nopoll_bool (*noPollSslPostCheck) (noPollCtx * ctx, + noPollConn * conn, + noPollPtr SSL_CTX, + noPollPtr SSL, + noPollPtr user_data); + + +#endif + +/* @} */ diff --git a/include/nopoll/nopoll_io.h b/include/nopoll/nopoll_io.h new file mode 100644 index 00000000..8e8f2a26 --- /dev/null +++ b/include/nopoll/nopoll_io.h @@ -0,0 +1,52 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_IO_H__ +#define __NOPOLL_IO_H__ + +#include + +BEGIN_C_DECLS + +noPollIoEngine * nopoll_io_get_engine (noPollCtx * ctx, noPollIoEngineType engine_type); + +void nopoll_io_release_engine (noPollIoEngine * engine); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_listener.h b/include/nopoll/nopoll_listener.h new file mode 100644 index 00000000..49002366 --- /dev/null +++ b/include/nopoll/nopoll_listener.h @@ -0,0 +1,80 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_LISTENER_H__ +#define __NOPOLL_LISTENER_H__ + +#include + +BEGIN_C_DECLS + +NOPOLL_SOCKET nopoll_listener_sock_listen (noPollCtx * ctx, + const char * host, + const char * port); + +noPollConn * nopoll_listener_new (noPollCtx * ctx, + const char * host, + const char * port); + +noPollConn * nopoll_listener_new_opts (noPollCtx * ctx, + noPollConnOpts * opts, + const char * host, + const char * port); + +noPollConn * nopoll_listener_tls_new (noPollCtx * ctx, + const char * host, + const char * port); + +noPollConn * nopoll_listener_tls_new_opts (noPollCtx * ctx, + noPollConnOpts * opts, + const char * host, + const char * port); + +nopoll_bool nopoll_listener_set_certificate (noPollConn * listener, + const char * certificate, + const char * private_key, + const char * chain_file); + +noPollConn * nopoll_listener_from_socket (noPollCtx * ctx, + NOPOLL_SOCKET session); + +NOPOLL_SOCKET nopoll_listener_accept (NOPOLL_SOCKET server_socket); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_log.h b/include/nopoll/nopoll_log.h new file mode 100644 index 00000000..c8f2c9a3 --- /dev/null +++ b/include/nopoll/nopoll_log.h @@ -0,0 +1,113 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_LOG_H__ +#define __NOPOLL_LOG_H__ + +#include +#include + +BEGIN_C_DECLS + +/** + * \addtogroup nopoll_log_module + * @{ + */ + +nopoll_bool nopoll_log_is_enabled (noPollCtx * ctx); + +nopoll_bool nopoll_log_color_is_enabled (noPollCtx * ctx); + +void nopoll_log_enable (noPollCtx * ctx, nopoll_bool value); + +void nopoll_log_color_enable (noPollCtx * ctx, nopoll_bool value); + +void nopoll_log_set_handler (noPollCtx * ctx, noPollLogHandler handler, noPollPtr user_data); + +/* include this at this place to load GNU extensions */ +#if defined(__GNUC__) +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +# define __function_name__ __PRETTY_FUNCTION__ +# define __line__ __LINE__ +# define __file__ __FILE__ +#elif defined(_MSC_VER) +# define __function_name__ __FUNCDNAME__ +# define __line__ __LINE__ +# define __file__ __FILE__ +#else +/* unknown compiler */ +#define __function_name__ "" +#define __line__ 0 +#define __file__ "" +#endif + + +#if defined(SHOW_DEBUG_LOG) +# define nopoll_log(ctx,level,message, ...) do{__nopoll_log(ctx, __function_name__, __file__, __line__, level, message, ##__VA_ARGS__);}while(0) +#else +# if defined(NOPOLL_OS_WIN32) && !( defined (__GNUC__) || _MSC_VER >= 1400) +/* default case where '...' is not supported but log is still + * disabled */ +# define nopoll_log __nopoll_log +# else +# define nopoll_log(ctx, level, message, ...) /* nothing */ +# endif +#endif + +/** + * @internal The following definition allows to find printf like wrong + * argument passing to nopoll_log function. To activate the depuration + * just add the following to local nopoll_config.h file: + * + * #define SHOW_FORMAT_BUGS (1) + */ +#if defined(SHOW_FORMAT_BUGS) +# undef nopoll_log +# define nopoll_log(ctx,level,message, ...) do{printf (message, ##__VA_ARGS__);}while(0) +#endif + +void __nopoll_log (noPollCtx * ctx, const char * function_name, const char * file, int line, noPollDebugLevel level, const char * message, ...); + +/* @} */ + +END_C_DECLS + +#endif + diff --git a/include/nopoll/nopoll_loop.h b/include/nopoll/nopoll_loop.h new file mode 100644 index 00000000..245d9738 --- /dev/null +++ b/include/nopoll/nopoll_loop.h @@ -0,0 +1,52 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_LOOP_H__ +#define __NOPOLL_LOOP_H__ + +#include + +BEGIN_C_DECLS + +int nopoll_loop_wait (noPollCtx * ctx, long timeout); + +void nopoll_loop_stop (noPollCtx * ctx); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_msg.h b/include/nopoll/nopoll_msg.h new file mode 100644 index 00000000..74242b5b --- /dev/null +++ b/include/nopoll/nopoll_msg.h @@ -0,0 +1,68 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_MSG_H__ +#define __NOPOLL_MSG_H__ + +#include + +BEGIN_C_DECLS + +const unsigned char * nopoll_msg_get_payload (noPollMsg * msg); + +int nopoll_msg_get_payload_size (noPollMsg * msg); + +noPollMsg * nopoll_msg_new (void); + +nopoll_bool nopoll_msg_ref (noPollMsg * msg); + +int nopoll_msg_ref_count (noPollMsg * msg); + +nopoll_bool nopoll_msg_is_final (noPollMsg * msg); + +nopoll_bool nopoll_msg_is_fragment (noPollMsg * msg); + +noPollOpCode nopoll_msg_opcode (noPollMsg * msg); + +noPollMsg * nopoll_msg_join (noPollMsg * msg, noPollMsg * msg2); + +void nopoll_msg_unref (noPollMsg * msg); + +END_C_DECLS + +#endif diff --git a/include/nopoll/nopoll_private.h b/include/nopoll/nopoll_private.h new file mode 100644 index 00000000..306fb16b --- /dev/null +++ b/include/nopoll/nopoll_private.h @@ -0,0 +1,386 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ +#ifndef __NOPOLL_PRIVATE_H__ +#define __NOPOLL_PRIVATE_H__ + +#include "ssl/ssl_compat-1.0.h" +#include + +typedef struct _noPollCertificate { + + char * serverName; + char * certificateFile; + char * privateKey; + char * optionalChainFile; + +} noPollCertificate; + +struct _noPollCtx { + /** + * @internal Controls logs output.. + */ + /* context reference counting */ + int refs; + + /* console log */ + nopoll_bool not_executed; + nopoll_bool debug_enabled; + + /* colored log */ + nopoll_bool not_executed_color; + nopoll_bool debug_color_enabled; + + nopoll_bool keep_looping; + + /** + * @internal noPollConn connection timeout. + */ + long conn_connect_std_timeout; + + /** + * @internal Default listener connection backlog + */ + int backlog; + + /** + * @internal Currently selected io engine on this context. + */ + noPollIoEngine * io_engine; + + /** + * @internal Connection array list and its length. + */ + int conn_id; + noPollConn ** conn_list; + int conn_length; + /** + * @internal Number of connections registered on this context. + */ + int conn_num; + + /** + * @internal Reference to defined on accept handling. + */ + noPollActionHandler on_accept; + noPollPtr on_accept_data; + + /** + * @internal Reference to defined on ready handling. + */ + noPollActionHandler on_ready; + noPollPtr on_ready_data; + + /** + * @internal Reference to defined on open handling. + */ + noPollActionHandler on_open; + noPollPtr on_open_data; + + /** + * @internal Reference to the defined on message handling. + */ + noPollOnMessageHandler on_msg; + noPollPtr on_msg_data; + + /** + * @internal Basic fake support for protocol version, by + * default: 13, due to RFC6455 standard + */ + int protocol_version; + + /** + * @internal Certificates added.. + */ + noPollCertificate * certificates; + int certificates_length; + + /* mutex */ + noPollPtr ref_mutex; + + /* log handling */ + noPollLogHandler log_handler; + noPollPtr log_user_data; + + /* context creator */ + noPollSslContextCreator context_creator; + noPollPtr context_creator_data; + + /* SSL postcheck */ + noPollSslPostCheck post_ssl_check; + noPollPtr post_ssl_check_data; +}; + +struct _noPollConn { + /** + * @internal Connection id. + */ + int id; + + /** + * @internal The context associated to this connection. + */ + noPollCtx * ctx; + + /** + * @internal This is the actual socket handler associated to + * the noPollConn object. + */ + NOPOLL_SOCKET session; + /** + * @internal Flag to signal this connection has finished its + * handshake. + */ + nopoll_bool handshake_ok; + + /** + * @internal Current connection receive function. + */ + noPollRead receive; + + /** + * @internal Current connection receive function. + */ + noPollRead sends; + + /** + * @internal The connection role. + */ + noPollRole role; + + /** + * @internal Conection host ip location (connecting or listening). + */ + char * host; + + /** + * @internal Connection port location (connecting or + * listening). + */ + char * port; + + /** + * @internal Host name requested on the connection. + */ + char * host_name; + /** + * @internal Origin requested on the connection. + */ + char * origin; + + /** + * @internal reference to the get url. + */ + char * get_url; + + /** + * @internal Reference to protocols requested to be opened on + * this connection. + */ + char * protocols; + /* @internal reference to the protocol that was replied by the server */ + char * accepted_protocol; + + /* close status and reason */ + int peer_close_status; + char * peer_close_reason; + + /** + * @internal Reference to the defined on message handling. + */ + noPollOnMessageHandler on_msg; + noPollPtr on_msg_data; + + /** + * @internal Reference to defined on ready handling. + */ + noPollActionHandler on_ready; + noPollPtr on_ready_data; + + /** + * @internal Reference to the defined on close handling. + */ + noPollOnCloseHandler on_close; + noPollPtr on_close_data; + + /* reference to the handshake */ + noPollHandShake * handshake; + + /* reference to a buffer with pending content */ + char * pending_line; + + /** + * @internal connection reference counting. + */ + int refs; + + /** + * @internal References to pending content to be read + */ + noPollMsg * pending_msg; + long int pending_diff; + long int pending_desp; + + /** + * @internal Flag to handle TLS support upon connection + * reception. + */ + nopoll_bool tls_on; + /** + * @internal Flag that indicates that the provided session + * must call to accept the TLS session before proceeding. + */ + nopoll_bool pending_ssl_accept; + + /* SSL support */ + SSL_CTX * ssl_ctx; + SSL * ssl; + + /* certificates */ + char * certificate; + char * private_key; + char * chain_certificate; + + /* pending buffer */ + char pending_buf[100]; + int pending_buf_bytes; + + /** + * @internal Support for an user defined pointer. + */ + noPollPtr hook; + + /** + * @internal Mutex + */ + noPollPtr ref_mutex; + + /** + * @internal Variable to track pending bytes from previous + * read that must be completed. + */ + noPollMsg * previous_msg; + /* allows to track if previous message was a fragment to flag + * next message, even having FIN enabled as a fragment. */ + nopoll_bool previous_was_fragment; + + char * pending_write; + int pending_write_bytes; + + /** + * @internal Internal reference to the connection options. + */ + noPollConnOpts * opts; + + /** + * @internal Reference to the listener in the case this is a + * connection that was created due to a listener running. + */ + noPollConn * listener; +}; + +struct _noPollIoEngine { + noPollPtr io_object; + noPollCtx * ctx; + noPollIoMechCreate create; + noPollIoMechDestroy destroy; + noPollIoMechClear clear; + noPollIoMechWait wait; + noPollIoMechAddTo addto; + noPollIoMechIsSet isset; +}; + +struct _noPollMsg { + nopoll_bool has_fin; + short op_code; + nopoll_bool is_masked; + + noPollPtr payload; + long int payload_size; + + int refs; + noPollPtr ref_mutex; + + char mask[4]; + int remain_bytes; + + nopoll_bool is_fragment; + int unmask_desp; +}; + +struct _noPollHandshake { + /** + * @internal Reference to the to the GET url HTTP/1.1 header + * part. + */ + nopoll_bool upgrade_websocket; + nopoll_bool connection_upgrade; + nopoll_bool received_101; + char * websocket_key; + char * websocket_version; + char * websocket_accept; + char * expected_accept; + + /* reference to cookie header */ + char * cookie; +}; + +struct _noPollConnOpts { + /* If the connection options object should be reused across calls */ + nopoll_bool reuse; + + /* mutex */ + noPollPtr mutex; + int refs; + + /* What ssl protocol should be used */ + noPollSslProtocol ssl_protocol; + + /* SSL options */ + char * certificate; + char * private_key; + char * chain_certificate; + char * ca_certificate; + + nopoll_bool disable_ssl_verify; + + /* cookie support */ + char * cookie; +}; + +#endif diff --git a/include/nopoll/nopoll_win32.h b/include/nopoll/nopoll_win32.h new file mode 100644 index 00000000..5b1d589d --- /dev/null +++ b/include/nopoll/nopoll_win32.h @@ -0,0 +1,66 @@ +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ + +#ifndef __NOPOLL_WIN32_H__ +#define __NOPOLL_WIN32_H__ + +#include + +BEGIN_C_DECLS + +int nopoll_win32_init (noPollCtx * ctx); + +int nopoll_win32_nonblocking_enable (NOPOLL_SOCKET socket); + +int nopoll_win32_blocking_enable (NOPOLL_SOCKET socket); + +/* gettimeofday support on windows */ +int nopoll_win32_gettimeofday (struct timeval *tv, noPollPtr notUsed); + +BOOL APIENTRY DllMain (HINSTANCE hInst, + DWORD reason, + LPVOID reserved); + +#if !defined(EINPROGRESS) +#define EINPROGRESS (WSAEINPROGRESS) +#endif + +END_C_DECLS + +#endif diff --git a/include/spiffs/spiffs.h b/include/spiffs/spiffs.h new file mode 100644 index 00000000..2bf0a6e9 --- /dev/null +++ b/include/spiffs/spiffs.h @@ -0,0 +1,560 @@ +/* + * spiffs.h + * + * Created on: May 26, 2013 + * Author: petera + */ + + + +#ifndef SPIFFS_H_ +#define SPIFFS_H_ +#if defined(__cplusplus) +extern "C" { +#endif + +#include "spiffs_config.h" + +#define SPIFFS_OK 0 +#define SPIFFS_ERR_NOT_MOUNTED -10000 +#define SPIFFS_ERR_FULL -10001 +#define SPIFFS_ERR_NOT_FOUND -10002 +#define SPIFFS_ERR_END_OF_OBJECT -10003 +#define SPIFFS_ERR_DELETED -10004 +#define SPIFFS_ERR_NOT_FINALIZED -10005 +#define SPIFFS_ERR_NOT_INDEX -10006 +#define SPIFFS_ERR_OUT_OF_FILE_DESCS -10007 +#define SPIFFS_ERR_FILE_CLOSED -10008 +#define SPIFFS_ERR_FILE_DELETED -10009 +#define SPIFFS_ERR_BAD_DESCRIPTOR -10010 +#define SPIFFS_ERR_IS_INDEX -10011 +#define SPIFFS_ERR_IS_FREE -10012 +#define SPIFFS_ERR_INDEX_SPAN_MISMATCH -10013 +#define SPIFFS_ERR_DATA_SPAN_MISMATCH -10014 +#define SPIFFS_ERR_INDEX_REF_FREE -10015 +#define SPIFFS_ERR_INDEX_REF_LU -10016 +#define SPIFFS_ERR_INDEX_REF_INVALID -10017 +#define SPIFFS_ERR_INDEX_FREE -10018 +#define SPIFFS_ERR_INDEX_LU -10019 +#define SPIFFS_ERR_INDEX_INVALID -10020 +#define SPIFFS_ERR_NOT_WRITABLE -10021 +#define SPIFFS_ERR_NOT_READABLE -10022 +#define SPIFFS_ERR_CONFLICTING_NAME -10023 +#define SPIFFS_ERR_NOT_CONFIGURED -10024 + +#define SPIFFS_ERR_NOT_A_FS -10025 +#define SPIFFS_ERR_MOUNTED -10026 +#define SPIFFS_ERR_ERASE_FAIL -10027 +#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028 + +#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029 + +#define SPIFFS_ERR_INTERNAL -10050 + +#define SPIFFS_ERR_TEST -10100 + + +// spiffs file descriptor index type. must be signed +typedef s16_t spiffs_file; +// spiffs file descriptor flags +typedef u16_t spiffs_flags; +// spiffs file mode +typedef u16_t spiffs_mode; +// object type +typedef u8_t spiffs_obj_type; + +/* spi read call function type */ +typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst); +/* spi write call function type */ +typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src); +/* spi erase call function type */ +typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size); + +/* file system check callback report operation */ +typedef enum { + SPIFFS_CHECK_LOOKUP = 0, + SPIFFS_CHECK_INDEX, + SPIFFS_CHECK_PAGE +} spiffs_check_type; + +/* file system check callback report type */ +typedef enum { + SPIFFS_CHECK_PROGRESS = 0, + SPIFFS_CHECK_ERROR, + SPIFFS_CHECK_FIX_INDEX, + SPIFFS_CHECK_FIX_LOOKUP, + SPIFFS_CHECK_DELETE_ORPHANED_INDEX, + SPIFFS_CHECK_DELETE_PAGE, + SPIFFS_CHECK_DELETE_BAD_FILE, +} spiffs_check_report; + +/* file system check callback function */ +typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, + u32_t arg1, u32_t arg2); + +#ifndef SPIFFS_DBG +#define SPIFFS_DBG(...) \ + print(__VA_ARGS__) +#endif +#ifndef SPIFFS_GC_DBG +#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__) +#endif +#ifndef SPIFFS_CACHE_DBG +#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__) +#endif +#ifndef SPIFFS_CHECK_DBG +#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__) +#endif + +/* Any write to the filehandle is appended to end of the file */ +#define SPIFFS_APPEND (1<<0) +/* If the opened file exists, it will be truncated to zero length before opened */ +#define SPIFFS_TRUNC (1<<1) +/* If the opened file does not exist, it will be created before opened */ +#define SPIFFS_CREAT (1<<2) +/* The opened file may only be read */ +#define SPIFFS_RDONLY (1<<3) +/* The opened file may only be writted */ +#define SPIFFS_WRONLY (1<<4) +/* The opened file may be both read and writted */ +#define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY) +/* Any writes to the filehandle will never be cached */ +#define SPIFFS_DIRECT (1<<5) + +#define SPIFFS_SEEK_SET (0) +#define SPIFFS_SEEK_CUR (1) +#define SPIFFS_SEEK_END (2) + +#define SPIFFS_TYPE_FILE (1) +#define SPIFFS_TYPE_DIR (2) +#define SPIFFS_TYPE_HARD_LINK (3) +#define SPIFFS_TYPE_SOFT_LINK (4) + +#ifndef SPIFFS_LOCK +#define SPIFFS_LOCK(fs) +#endif + +#ifndef SPIFFS_UNLOCK +#define SPIFFS_UNLOCK(fs) +#endif + +// phys structs + +// spiffs spi configuration struct +typedef struct { + // physical read function + spiffs_read hal_read_f; + // physical write function + spiffs_write hal_write_f; + // physical erase function + spiffs_erase hal_erase_f; +#if SPIFFS_SINGLETON == 0 + // physical size of the spi flash + u32_t phys_size; + // physical offset in spi flash used for spiffs, + // must be on block boundary + u32_t phys_addr; + // physical size when erasing a block + u32_t phys_erase_block; + + // logical size of a block, must be on physical + // block size boundary and must never be less than + // a physical block + u32_t log_block_size; + // logical size of a page, must be at least + // log_block_size / 8 + u32_t log_page_size; +#endif +} spiffs_config; + +typedef struct { + // file system configuration + spiffs_config cfg; + // number of logical blocks + u32_t block_count; + + // cursor for free blocks, block index + spiffs_block_ix free_cursor_block_ix; + // cursor for free blocks, entry index + int free_cursor_obj_lu_entry; + // cursor when searching, block index + spiffs_block_ix cursor_block_ix; + // cursor when searching, entry index + int cursor_obj_lu_entry; + + // primary work buffer, size of a logical page + u8_t *lu_work; + // secondary work buffer, size of a logical page + u8_t *work; + // file descriptor memory area + u8_t *fd_space; + // available file descriptors + u32_t fd_count; + + // last error + s32_t err_code; + + // current number of free blocks + u32_t free_blocks; + // current number of busy pages + u32_t stats_p_allocated; + // current number of deleted pages + u32_t stats_p_deleted; + // flag indicating that garbage collector is cleaning + u8_t cleaning; + // max erase count amongst all blocks + spiffs_obj_id max_erase_count; + +#if SPIFFS_GC_STATS + u32_t stats_gc_runs; +#endif + +#if SPIFFS_CACHE + // cache memory + void *cache; + // cache size + u32_t cache_size; +#if SPIFFS_CACHE_STATS + u32_t cache_hits; + u32_t cache_misses; +#endif +#endif + + // check callback function + spiffs_check_callback check_cb_f; + + // mounted flag + u8_t mounted; + // config magic + u32_t config_magic; +} spiffs; + +/* spiffs file status struct */ +typedef struct { + spiffs_obj_id obj_id; + u32_t size; + spiffs_obj_type type; + u8_t name[SPIFFS_OBJ_NAME_LEN]; +} spiffs_stat; + +struct spiffs_dirent { + spiffs_obj_id obj_id; + u8_t name[SPIFFS_OBJ_NAME_LEN]; + spiffs_obj_type type; + u32_t size; + spiffs_page_ix pix; +}; + +typedef struct { + spiffs *fs; + spiffs_block_ix block; + int entry; +} spiffs_DIR; + +// functions + +/** + * Initializes the file system dynamic parameters and mounts the filesystem. + * If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS + * if the flash does not contain a recognizable file system. + * In this case, SPIFFS_format must be called prior to remounting. + * @param fs the file system struct + * @param config the physical and logical configuration of the file system + * @param work a memory work buffer comprising 2*config->log_page_size + * bytes used throughout all file system operations + * @param fd_space memory for file descriptors + * @param fd_space_size memory size of file descriptors + * @param cache memory for cache, may be null + * @param cache_size memory size of cache + * @param check_cb_f callback function for reporting during consistency checks + */ +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); + +/** + * Unmounts the file system. All file handles will be flushed of any + * cached writes and closed. + * @param fs the file system struct + */ +void SPIFFS_unmount(spiffs *fs); + +/** + * Creates a new file. + * @param fs the file system struct + * @param path the path of the new file + * @param mode ignored, for posix compliance + */ +s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode); + +/** + * Opens/creates a file. + * @param fs the file system struct + * @param path the path of the new file + * @param flags the flags for the open command, can be combinations of + * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, + * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT + * @param mode ignored, for posix compliance + */ +spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode mode); + + +/** + * Opens a file by given dir entry. + * Optimization purposes, when traversing a file system with SPIFFS_readdir + * a normal SPIFFS_open would need to traverse the filesystem again to find + * the file, whilst SPIFFS_open_by_dirent already knows where the file resides. + * @param fs the file system struct + * @param path the dir entry to the file + * @param flags the flags for the open command, can be combinations of + * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, + * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT. + * SPIFFS_CREAT will have no effect in this case. + * @param mode ignored, for posix compliance + */ +spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode); + +/** + * Reads from given filehandle. + * @param fs the file system struct + * @param fh the filehandle + * @param buf where to put read data + * @param len how much to read + * @returns number of bytes read, or -1 if error + */ +s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len); + +/** + * Writes to given filehandle. + * @param fs the file system struct + * @param fh the filehandle + * @param buf the data to write + * @param len how much to write + * @returns number of bytes written, or -1 if error + */ +s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len); + +/** + * Moves the read/write file offset + * @param fs the file system struct + * @param fh the filehandle + * @param offs how much/where to move the offset + * @param whence if SPIFFS_SEEK_SET, the file offset shall be set to offset bytes + * if SPIFFS_SEEK_CUR, the file offset shall be set to its current location plus offset + * if SPIFFS_SEEK_END, the file offset shall be set to the size of the file plus offset + */ +s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence); + +/** + * Removes a file by path + * @param fs the file system struct + * @param path the path of the file to remove + */ +s32_t SPIFFS_remove(spiffs *fs, char *path); + +/** + * Removes a file by filehandle + * @param fs the file system struct + * @param fh the filehandle of the file to remove + */ +s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh); + +/** + * Gets file status by path + * @param fs the file system struct + * @param path the path of the file to stat + * @param s the stat struct to populate + */ +s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s); + +/** + * Gets file status by filehandle + * @param fs the file system struct + * @param fh the filehandle of the file to stat + * @param s the stat struct to populate + */ +s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s); + +/** + * Flushes all pending write operations from cache for given file + * @param fs the file system struct + * @param fh the filehandle of the file to flush + */ +s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh); + +/** + * Closes a filehandle. If there are pending write operations, these are finalized before closing. + * @param fs the file system struct + * @param fh the filehandle of the file to close + */ +void SPIFFS_close(spiffs *fs, spiffs_file fh); + +/** + * Renames a file + * @param fs the file system struct + * @param old path of file to rename + * @param newPath new path of file + */ +s32_t SPIFFS_rename(spiffs *fs, char *old, char *newPath); + +/** + * Returns last error of last file operation. + * @param fs the file system struct + */ +s32_t SPIFFS_errno(spiffs *fs); + +/** + * Clears last error. + * @param fs the file system struct + */ +void SPIFFS_clearerr(spiffs *fs); + +/** + * Opens a directory stream corresponding to the given name. + * The stream is positioned at the first entry in the directory. + * On hydrogen builds the name argument is ignored as hydrogen builds always correspond + * to a flat file structure - no directories. + * @param fs the file system struct + * @param name the name of the directory + * @param d pointer the directory stream to be populated + */ +spiffs_DIR *SPIFFS_opendir(spiffs *fs, char *name, spiffs_DIR *d); + +/** + * Closes a directory stream + * @param d the directory stream to close + */ +s32_t SPIFFS_closedir(spiffs_DIR *d); + +/** + * Reads a directory into given spifs_dirent struct. + * @param d pointer to the directory stream + * @param e the dirent struct to be populated + * @returns null if error or end of stream, else given dirent is returned + */ +struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e); + +/** + * Runs a consistency check on given filesystem. + * @param fs the file system struct + */ +s32_t SPIFFS_check(spiffs *fs); + +/** + * Searches for a block with only deleted entries. If found, it is erased. + * @param fs the file system struct + */ +s32_t SPIFFS_erase_deleted_block(spiffs *fs); + + +/** + * Returns number of total bytes available and number of used bytes. + * This is an estimation, and depends on if there a many files with little + * data or few files with much data. + * NB: If used number of bytes exceeds total bytes, a SPIFFS_check should + * run. This indicates a power loss in midst of things. In worst case + * (repeated powerlosses in mending or gc) you might have to delete some files. + * + * @param fs the file system struct + * @param total total number of bytes in filesystem + * @param used used number of bytes in filesystem + */ +s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used); + +/** + * Formats the entire file system. All data will be lost. + * The filesystem must not be mounted when calling this. + * + * NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount + * MUST be called prior to formatting in order to configure the filesystem. + * If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling + * SPIFFS_format. + * If SPIFFS_mount fails, SPIFFS_format can be called directly without calling + * SPIFFS_unmount first. + * + * @param fs the file system struct + */ +s32_t SPIFFS_format(spiffs *fs); + +/** + * Returns nonzero if spiffs is mounted, or zero if unmounted. + * @param fs the file system struct + */ +u8_t SPIFFS_mounted(spiffs *fs); + +/** + * Tries to find a block where most or all pages are deleted, and erase that + * block if found. Does not care for wear levelling. Will not move pages + * around. + * If parameter max_free_pages are set to 0, only blocks with only deleted + * pages will be selected. + * + * NB: the garbage collector is automatically called when spiffs needs free + * pages. The reason for this function is to give possibility to do background + * tidying when user knows the system is idle. + * + * Use with care. + * + * Setting max_free_pages to anything larger than zero will eventually wear + * flash more as a block containing free pages can be erased. + * + * Will set err_no to SPIFFS_OK if a block was found and erased, + * SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found, + * or other error. + * + * @param fs the file system struct + * @param max_free_pages maximum number allowed free pages in block + */ +s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages); + +/** + * Will try to make room for given amount of bytes in the filesystem by moving + * pages and erasing blocks. + * If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If + * there already is this amount (or more) of free space, SPIFFS_gc will + * silently return. It is recommended to call SPIFFS_info before invoking + * this method in order to determine what amount of bytes to give. + * + * NB: the garbage collector is automatically called when spiffs needs free + * pages. The reason for this function is to give possibility to do background + * tidying when user knows the system is idle. + * + * Use with care. + * + * @param fs the file system struct + * @param size amount of bytes that should be freed + */ +s32_t SPIFFS_gc(spiffs *fs, u32_t size); + +#if SPIFFS_TEST_VISUALISATION +/** + * Prints out a visualization of the filesystem. + * @param fs the file system struct + */ +s32_t SPIFFS_vis(spiffs *fs); +#endif + +#if SPIFFS_BUFFER_HELP +/** + * Returns number of bytes needed for the filedescriptor buffer given + * amount of file descriptors. + */ +u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs); + +#if SPIFFS_CACHE +/** + * Returns number of bytes needed for the cache buffer given + * amount of cache pages. + */ +u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); +#endif +#endif + +#if SPIFFS_CACHE +#endif +#if defined(__cplusplus) +} +#endif + +#endif /* SPIFFS_H_ */ diff --git a/include/spiffs/spiffs_config.h b/include/spiffs/spiffs_config.h new file mode 100644 index 00000000..ac19c17f --- /dev/null +++ b/include/spiffs/spiffs_config.h @@ -0,0 +1,218 @@ +/* + * spiffs_config.h + * + * Created on: Jul 3, 2013 + * Author: petera + */ + +#ifndef SPIFFS_CONFIG_H_ +#define SPIFFS_CONFIG_H_ + +// ----------- 8< ------------ +// Following includes are for the linux test build of spiffs +// These may/should/must be removed/altered/replaced in your target +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +// ----------- >8 ------------ + +// compile time switches + +// Set generic spiffs debug output call. +#ifndef SPIFFS_DBG +#define SPIFFS_DBG(...) //printf(__VA_ARGS__) +#endif +// Set spiffs debug output call for garbage collecting. +#ifndef SPIFFS_GC_DBG +#define SPIFFS_GC_DBG(...) //printf(__VA_ARGS__) +#endif +// Set spiffs debug output call for caching. +#ifndef SPIFFS_CACHE_DBG +#define SPIFFS_CACHE_DBG(...) //printf(__VA_ARGS__) +#endif +// Set spiffs debug output call for system consistency checks. +#ifndef SPIFFS_CHECK_DBG +#define SPIFFS_CHECK_DBG(...) //printf(__VA_ARGS__) +#endif + +// Enable/disable API functions to determine exact number of bytes +// for filedescriptor and cache buffers. Once decided for a configuration, +// this can be disabled to reduce flash. +#ifndef SPIFFS_BUFFER_HELP +#define SPIFFS_BUFFER_HELP 0 +#endif + +// Enables/disable memory read caching of nucleus file system operations. +// If enabled, memory area must be provided for cache in SPIFFS_mount. +#ifndef SPIFFS_CACHE +#define SPIFFS_CACHE 1 +#endif + +#if SPIFFS_CACHE +// Enables memory write caching for file descriptors in hydrogen +#ifndef SPIFFS_CACHE_WR +#define SPIFFS_CACHE_WR 1 +#endif + +// Enable/disable statistics on caching. Debug/test purpose only. +#ifndef SPIFFS_CACHE_STATS +#define SPIFFS_CACHE_STATS 1 +#endif +#endif + +// Always check header of each accessed page to ensure consistent state. +// If enabled it will increase number of reads, will increase flash. +#ifndef SPIFFS_PAGE_CHECK +#define SPIFFS_PAGE_CHECK 1 +#endif + +// Define maximum number of gc runs to perform to reach desired free pages. +#ifndef SPIFFS_GC_MAX_RUNS +#define SPIFFS_GC_MAX_RUNS 5 +#endif + +// Enable/disable statistics on gc. Debug/test purpose only. +#ifndef SPIFFS_GC_STATS +#define SPIFFS_GC_STATS 1 +#endif + +// Garbage collecting examines all pages in a block which and sums up +// to a block score. Deleted pages normally gives positive score and +// used pages normally gives a negative score (as these must be moved). +// To have a fair wear-leveling, the erase age is also included in score, +// whose factor normally is the most positive. +// The larger the score, the more likely it is that the block will +// picked for garbage collection. + +// Garbage collecting heuristics - weight used for deleted pages. +#ifndef SPIFFS_GC_HEUR_W_DELET +#define SPIFFS_GC_HEUR_W_DELET (5) +#endif +// Garbage collecting heuristics - weight used for used pages. +#ifndef SPIFFS_GC_HEUR_W_USED +#define SPIFFS_GC_HEUR_W_USED (-1) +#endif +// Garbage collecting heuristics - weight used for time between +// last erased and erase of this block. +#ifndef SPIFFS_GC_HEUR_W_ERASE_AGE +#define SPIFFS_GC_HEUR_W_ERASE_AGE (50) +#endif + +// Object name maximum length. +#ifndef SPIFFS_OBJ_NAME_LEN +#define SPIFFS_OBJ_NAME_LEN (32) +#endif + +// Size of buffer allocated on stack used when copying data. +// Lower value generates more read/writes. No meaning having it bigger +// than logical page size. +#ifndef SPIFFS_COPY_BUFFER_STACK +#define SPIFFS_COPY_BUFFER_STACK (64) +#endif + +// Enable this to have an identifiable spiffs filesystem. This will look for +// a magic in all sectors to determine if this is a valid spiffs system or +// not on mount point. If not, SPIFFS_format must be called prior to mounting +// again. +#ifndef SPIFFS_USE_MAGIC +#define SPIFFS_USE_MAGIC (0) +#endif + +// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level +// These should be defined on a multithreaded system + +// define this to enter a mutex if you're running on a multithreaded system +#ifndef SPIFFS_LOCK +#define SPIFFS_LOCK(fs) +#endif +// define this to exit a mutex if you're running on a multithreaded system +#ifndef SPIFFS_UNLOCK +#define SPIFFS_UNLOCK(fs) +#endif + + +// Enable if only one spiffs instance with constant configuration will exist +// on the target. This will reduce calculations, flash and memory accesses. +// Parts of configuration must be defined below instead of at time of mount. +#ifndef SPIFFS_SINGLETON +#define SPIFFS_SINGLETON 0 +#endif + +#if SPIFFS_SINGLETON +// Instead of giving parameters in config struct, singleton build must +// give parameters in defines below. +#ifndef SPIFFS_CFG_PHYS_SZ +#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*2) +#endif +#ifndef SPIFFS_CFG_PHYS_ERASE_SZ +#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536) +#endif +#ifndef SPIFFS_CFG_PHYS_ADDR +#define SPIFFS_CFG_PHYS_ADDR(ignore) (0) +#endif +#ifndef SPIFFS_CFG_LOG_PAGE_SZ +#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) +#endif +#ifndef SPIFFS_CFG_LOG_BLOCK_SZ +#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536) +#endif +#endif + +// Enable this if your target needs aligned data for index tables +#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES +#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 +#endif + +// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function +// in the api. This function will visualize all filesystem using given printf +// function. +#ifndef SPIFFS_TEST_VISUALISATION +#define SPIFFS_TEST_VISUALISATION 0 +#endif +#if SPIFFS_TEST_VISUALISATION +#ifndef spiffs_printf +#define spiffs_printf(...) printf(__VA_ARGS__) +#endif +// spiffs_printf argument for a free page +#ifndef SPIFFS_TEST_VIS_FREE_STR +#define SPIFFS_TEST_VIS_FREE_STR "_" +#endif +// spiffs_printf argument for a deleted page +#ifndef SPIFFS_TEST_VIS_DELE_STR +#define SPIFFS_TEST_VIS_DELE_STR "/" +#endif +// spiffs_printf argument for an index page for given object id +#ifndef SPIFFS_TEST_VIS_INDX_STR +#define SPIFFS_TEST_VIS_INDX_STR(id) "i" +#endif +// spiffs_printf argument for a data page for given object id +#ifndef SPIFFS_TEST_VIS_DATA_STR +#define SPIFFS_TEST_VIS_DATA_STR(id) "d" +#endif +#endif + +// Types depending on configuration such as the amount of flash bytes +// given to spiffs file system in total (spiffs_file_system_size), +// the logical block size (log_block_size), and the logical page size +// (log_page_size) + +// Block index type. Make sure the size of this type can hold +// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size +typedef u16_t spiffs_block_ix; +// Page index type. Make sure the size of this type can hold +// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size +typedef u16_t spiffs_page_ix; +// Object id type - most significant bit is reserved for index flag. Make sure the +// size of this type can hold the highest object id on a full system, +// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2 +typedef u16_t spiffs_obj_id; +// Object span index type. Make sure the size of this type can +// hold the largest possible span index on the system - +// i.e. (spiffs_file_system_size / log_page_size) - 1 +typedef u16_t spiffs_span_ix; + +#endif /* SPIFFS_CONFIG_H_ */ diff --git a/include/spiffs/spiffs_nucleus.h b/include/spiffs/spiffs_nucleus.h new file mode 100644 index 00000000..80cc1cff --- /dev/null +++ b/include/spiffs/spiffs_nucleus.h @@ -0,0 +1,718 @@ +/* + * spiffs_nucleus.h + * + * Created on: Jun 15, 2013 + * Author: petera + */ + +/* SPIFFS layout + * + * spiffs is designed for following spi flash characteristics: + * - only big areas of data (blocks) can be erased + * - erasing resets all bits in a block to ones + * - writing pulls ones to zeroes + * - zeroes cannot be pulled to ones, without erase + * - wear leveling + * + * spiffs is also meant to be run on embedded, memory constraint devices. + * + * Entire area is divided in blocks. Entire area is also divided in pages. + * Each block contains same number of pages. A page cannot be erased, but a + * block can be erased. + * + * Entire area must be block_size * x + * page_size must be block_size / (2^y) where y > 2 + * + * ex: area = 1024*1024 bytes, block size = 65536 bytes, page size = 256 bytes + * + * BLOCK 0 PAGE 0 object lookup 1 + * PAGE 1 object lookup 2 + * ... + * PAGE n-1 object lookup n + * PAGE n object data 1 + * PAGE n+1 object data 2 + * ... + * PAGE n+m-1 object data m + * + * BLOCK 1 PAGE n+m object lookup 1 + * PAGE n+m+1 object lookup 2 + * ... + * PAGE 2n+m-1 object lookup n + * PAGE 2n+m object data 1 + * PAGE 2n+m object data 2 + * ... + * PAGE 2n+2m-1 object data m + * ... + * + * n is number of object lookup pages, which is number of pages needed to index all pages + * in a block by object id + * : block_size / page_size * sizeof(obj_id) / page_size + * m is number data pages, which is number of pages in block minus number of lookup pages + * : block_size / page_size - block_size / page_size * sizeof(obj_id) / page_size + * thus, n+m is total number of pages in a block + * : block_size / page_size + * + * ex: n = 65536/256*2/256 = 2, m = 65536/256 - 2 = 254 => n+m = 65536/256 = 256 + * + * Object lookup pages contain object id entries. Each entry represent the corresponding + * data page. + * Assuming a 16 bit object id, an object id being 0xffff represents a free page. + * An object id being 0x0000 represents a deleted page. + * + * ex: page 0 : lookup : 0008 0001 0aaa ffff ffff ffff ffff ffff .. + * page 1 : lookup : ffff ffff ffff ffff ffff ffff ffff ffff .. + * page 2 : data : data for object id 0008 + * page 3 : data : data for object id 0001 + * page 4 : data : data for object id 0aaa + * ... + * + * + * Object data pages can be either object index pages or object content. + * All object data pages contains a data page header, containing object id and span index. + * The span index denotes the object page ordering amongst data pages with same object id. + * This applies to both object index pages (when index spans more than one page of entries), + * and object data pages. + * An object index page contains page entries pointing to object content page. The entry index + * in a object index page correlates to the span index in the actual object data page. + * The first object index page (span index 0) is called object index header page, and also + * contains object flags (directory/file), size, object name etc. + * + * ex: + * BLOCK 1 + * PAGE 256: objectl lookup page 1 + * [*123] [ 123] [ 123] [ 123] + * [ 123] [*123] [ 123] [ 123] + * [free] [free] [free] [free] ... + * PAGE 257: objectl lookup page 2 + * [free] [free] [free] [free] ... + * PAGE 258: object index page (header) + * obj.id:0123 span.ix:0000 flags:INDEX + * size:1600 name:ex.txt type:file + * [259] [260] [261] [262] + * PAGE 259: object data page + * obj.id:0123 span.ix:0000 flags:DATA + * PAGE 260: object data page + * obj.id:0123 span.ix:0001 flags:DATA + * PAGE 261: object data page + * obj.id:0123 span.ix:0002 flags:DATA + * PAGE 262: object data page + * obj.id:0123 span.ix:0003 flags:DATA + * PAGE 263: object index page + * obj.id:0123 span.ix:0001 flags:INDEX + * [264] [265] [fre] [fre] + * [fre] [fre] [fre] [fre] + * PAGE 264: object data page + * obj.id:0123 span.ix:0004 flags:DATA + * PAGE 265: object data page + * obj.id:0123 span.ix:0005 flags:DATA + * + */ +#ifndef SPIFFS_NUCLEUS_H_ +#define SPIFFS_NUCLEUS_H_ + +#define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1) +#define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1) +#define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2) +#define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3) +#define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4) + +#define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20) +#define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21) +#define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22) + +#define SPIFFS_EV_IX_UPD 0 +#define SPIFFS_EV_IX_NEW 1 +#define SPIFFS_EV_IX_DEL 2 + +#define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1))) + +#define SPIFFS_UNDEFINED_LEN (u32_t)(-1) + +#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0) +#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1) + +#define SPIFFS_MAGIC(fs) ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs))) + +#define SPIFFS_CONFIG_MAGIC (0x20090315) + +#if SPIFFS_SINGLETON == 0 +#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \ + ((fs)->cfg.log_page_size) +#define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \ + ((fs)->cfg.log_block_size) +#define SPIFFS_CFG_PHYS_SZ(fs) \ + ((fs)->cfg.phys_size) +#define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \ + ((fs)->cfg.phys_erase_block) +#define SPIFFS_CFG_PHYS_ADDR(fs) \ + ((fs)->cfg.phys_addr) +#endif + +// total number of pages +#define SPIFFS_MAX_PAGES(fs) \ + ( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// total number of pages per block, including object lookup pages +#define SPIFFS_PAGES_PER_BLOCK(fs) \ + ( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// number of object lookup pages per block +#define SPIFFS_OBJ_LOOKUP_PAGES(fs) \ + (MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) ) +// checks if page index belongs to object lookup +#define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \ + (((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) +// number of object lookup entries in all object lookup pages +#define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \ + (SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) +// converts a block to physical address +#define SPIFFS_BLOCK_TO_PADDR(fs, block) \ + ( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) ) +// converts a object lookup entry to page index +#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \ + ((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry)) +// converts a object lookup entry to physical address of corresponding page +#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \ + (SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// converts a page to physical address +#define SPIFFS_PAGE_TO_PADDR(fs, page) \ + ( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// converts a physical address to page +#define SPIFFS_PADDR_TO_PAGE(fs, addr) \ + ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// gives index in page for a physical address +#define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \ + ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) ) +// returns containing block for given page +#define SPIFFS_BLOCK_FOR_PAGE(fs, page) \ + ( (page) / SPIFFS_PAGES_PER_BLOCK(fs) ) +// returns starting page for block +#define SPIFFS_PAGE_FOR_BLOCK(fs, block) \ + ( (block) * SPIFFS_PAGES_PER_BLOCK(fs) ) +// converts page to entry in object lookup page +#define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \ + ( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) ) +// returns data size in a data page +#define SPIFFS_DATA_PAGE_SIZE(fs) \ + ( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) ) +// returns physical address for block's erase count, +// always in the physical last entry of the last object lookup page +#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \ + ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) ) +// returns physical address for block's magic, +// always in the physical second last entry of the last object lookup page +#define SPIFFS_MAGIC_PADDR(fs, bix) \ + ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 ) +// checks if there is any room for magic in the object luts +#define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \ + ( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \ + <= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) ) + +// define helpers object + +// entries in an object header page index +#define SPIFFS_OBJ_HDR_IX_LEN(fs) \ + ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix)) +// entries in an object page index +#define SPIFFS_OBJ_IX_LEN(fs) \ + ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix)) +// object index entry for given data span index +#define SPIFFS_OBJ_IX_ENTRY(fs, spix) \ + ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs))) +// object index span index number for given data span index or entry +#define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \ + ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs))) + + +#define SPIFFS_OP_T_OBJ_LU (0<<0) +#define SPIFFS_OP_T_OBJ_LU2 (1<<0) +#define SPIFFS_OP_T_OBJ_IX (2<<0) +#define SPIFFS_OP_T_OBJ_DA (3<<0) +#define SPIFFS_OP_C_DELE (0<<2) +#define SPIFFS_OP_C_UPDT (1<<2) +#define SPIFFS_OP_C_MOVS (2<<2) +#define SPIFFS_OP_C_MOVD (3<<2) +#define SPIFFS_OP_C_FLSH (4<<2) +#define SPIFFS_OP_C_READ (5<<2) +#define SPIFFS_OP_C_WRTHRU (6<<2) + +#define SPIFFS_OP_TYPE_MASK (3<<0) +#define SPIFFS_OP_COM_MASK (7<<2) + + +// if 0, this page is written to, else clean +#define SPIFFS_PH_FLAG_USED (1<<0) +// if 0, writing is finalized, else under modification +#define SPIFFS_PH_FLAG_FINAL (1<<1) +// if 0, this is an index page, else a data page +#define SPIFFS_PH_FLAG_INDEX (1<<2) +// if 0, page is deleted, else valid +#define SPIFFS_PH_FLAG_DELET (1<<7) +// if 0, this index header is being deleted +#define SPIFFS_PH_FLAG_IXDELE (1<<6) + + +#define SPIFFS_CHECK_MOUNT(fs) \ + ((fs)->mounted != 0) + +#define SPIFFS_CHECK_CFG(fs) \ + ((fs)->config_magic == SPIFFS_CONFIG_MAGIC) + +#define SPIFFS_CHECK_RES(res) \ + do { \ + if ((res) < SPIFFS_OK) return (res); \ + } while (0); + +#define SPIFFS_API_CHECK_MOUNT(fs) \ + if (!SPIFFS_CHECK_MOUNT((fs))) { \ + (fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \ + return -1; \ + } + +#define SPIFFS_API_CHECK_CFG(fs) \ + if (!SPIFFS_CHECK_CFG((fs))) { \ + (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \ + return -1; \ + } + +#define SPIFFS_API_CHECK_RES(fs, res) \ + if ((res) < SPIFFS_OK) { \ + (fs)->err_code = (res); \ + return -1; \ + } + +#define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \ + if ((res) < SPIFFS_OK) { \ + (fs)->err_code = (res); \ + SPIFFS_UNLOCK(fs); \ + return -1; \ + } + +#define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \ + if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ + if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ + if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ + if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \ + if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \ + if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH; + //if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED; + +#define SPIFFS_VALIDATE_DATA(ph, objid, spix) \ + if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ + if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ + if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ + if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \ + if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \ + if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH; + + +// check id +#define SPIFFS_VIS_CHECK_ID (1<<0) +// report argument object id to visitor - else object lookup id is reported +#define SPIFFS_VIS_CHECK_PH (1<<1) +// stop searching at end of all look up pages +#define SPIFFS_VIS_NO_WRAP (1<<2) + +#if SPIFFS_CACHE + +#define SPIFFS_CACHE_FLAG_DIRTY (1<<0) +#define SPIFFS_CACHE_FLAG_WRTHRU (1<<1) +#define SPIFFS_CACHE_FLAG_OBJLU (1<<2) +#define SPIFFS_CACHE_FLAG_OBJIX (1<<3) +#define SPIFFS_CACHE_FLAG_DATA (1<<4) +#define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7) + +#define SPIFFS_CACHE_PAGE_SIZE(fs) \ + (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)) + +#define spiffs_get_cache(fs) \ + ((spiffs_cache *)((fs)->cache)) + +#define spiffs_get_cache_page_hdr(fs, c, ix) \ + ((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)]))) + +#define spiffs_get_cache_page(fs, c, ix) \ + ((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page)) + +// cache page struct +typedef struct { + // cache flags + u8_t flags; + // cache page index + u8_t ix; + // last access of this cache page + u32_t last_access; + union { + // type read cache + struct { + // read cache page index + spiffs_page_ix pix; + }; +#if SPIFFS_CACHE_WR + // type write cache + struct { + // write cache + spiffs_obj_id obj_id; + // offset in cache page + u32_t offset; + // size of cache page + u16_t size; + }; +#endif + }; +} spiffs_cache_page; + +// cache struct +typedef struct { + u8_t cpage_count; + u32_t last_access; + u32_t cpage_use_map; + u32_t cpage_use_mask; + u8_t *cpages; +} spiffs_cache; + +#endif + + +// spiffs nucleus file descriptor +typedef struct { + // the filesystem of this descriptor + spiffs *fs; + // number of file descriptor - if 0, the file descriptor is closed + spiffs_file file_nbr; + // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted + spiffs_obj_id obj_id; + // size of the file + u32_t size; + // cached object index header page index + spiffs_page_ix objix_hdr_pix; + // cached offset object index page index + spiffs_page_ix cursor_objix_pix; + // cached offset object index span index + spiffs_span_ix cursor_objix_spix; + // current absolute offset + u32_t offset; + // current file descriptor offset + u32_t fdoffset; + // fd flags + spiffs_flags flags; +#if SPIFFS_CACHE_WR + spiffs_cache_page *cache_page; +#endif +} spiffs_fd; + + +// object structs + +// page header, part of each page except object lookup pages +// NB: this is always aligned when the data page is an object index, +// as in this case struct spiffs_page_object_ix is used +typedef struct __attribute(( packed )) { + // object id + spiffs_obj_id obj_id; + // object span index + spiffs_span_ix span_ix; + // flags + u8_t flags; +} spiffs_page_header; + +// object index header page header +typedef struct __attribute(( packed )) +#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES + __attribute(( aligned(sizeof(spiffs_page_ix)) )) +#endif +{ + // common page header + spiffs_page_header p_hdr; + // alignment + u8_t _align[4 - (sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3)]; + // size of object + u32_t size; + // type of object + spiffs_obj_type type; + // name of object + u8_t name[SPIFFS_OBJ_NAME_LEN]; +} spiffs_page_object_ix_header; + +// object index page header +typedef struct __attribute(( packed )) { + spiffs_page_header p_hdr; + u8_t _align[4 - (sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3)]; +} spiffs_page_object_ix; + +// callback func for object lookup visitor +typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, + u32_t user_data, void *user_p); + + +#if SPIFFS_CACHE +#define _spiffs_rd(fs, op, fh, addr, len, dst) \ + spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst)) +#define _spiffs_wr(fs, op, fh, addr, len, src) \ + spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src)) +#else +#define _spiffs_rd(fs, op, fh, addr, len, dst) \ + spiffs_phys_rd((fs), (addr), (len), (dst)) +#define _spiffs_wr(fs, op, fh, addr, len, src) \ + spiffs_phys_wr((fs), (addr), (len), (src)) +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +// --------------- + +s32_t spiffs_phys_rd( + spiffs *fs, +#if SPIFFS_CACHE + u8_t op, + spiffs_file fh, +#endif + u32_t addr, + u32_t len, + u8_t *dst); + +s32_t spiffs_phys_wr( + spiffs *fs, +#if SPIFFS_CACHE + u8_t op, + spiffs_file fh, +#endif + u32_t addr, + u32_t len, + u8_t *src); + +s32_t spiffs_phys_cpy( + spiffs *fs, + spiffs_file fh, + u32_t dst, + u32_t src, + u32_t len); + +s32_t spiffs_phys_count_free_blocks( + spiffs *fs); + +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, + u32_t user_data, + void *user_p, + spiffs_block_ix *block_ix, + int *lu_entry); + +s32_t spiffs_erase_block( + spiffs *fs, + spiffs_block_ix bix); + +// --------------- + +s32_t spiffs_obj_lu_scan( + spiffs *fs); + +s32_t spiffs_obj_lu_find_free_obj_id( + spiffs *fs, + spiffs_obj_id *obj_id, + u8_t *conflicting_name); + +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 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 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 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 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 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 spiffs_page_delete( + spiffs *fs, + spiffs_page_ix pix); + +// --------------- + +s32_t spiffs_object_create( + spiffs *fs, + spiffs_obj_id obj_id, + u8_t name[SPIFFS_OBJ_NAME_LEN], + spiffs_obj_type type, + spiffs_page_ix *objix_hdr_pix); + +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, + u8_t name[SPIFFS_OBJ_NAME_LEN], + u32_t size, + spiffs_page_ix *new_pix); + +void spiffs_cb_object_event( + spiffs *fs, + spiffs_fd *fd, + int ev, + spiffs_obj_id obj_id, + spiffs_span_ix spix, + spiffs_page_ix new_pix, + u32_t new_size); + +s32_t spiffs_object_open_by_id( + spiffs *fs, + spiffs_obj_id obj_id, + spiffs_fd *f, + spiffs_flags flags, + spiffs_mode mode); + +s32_t spiffs_object_open_by_page( + spiffs *fs, + spiffs_page_ix pix, + spiffs_fd *f, + spiffs_flags flags, + spiffs_mode mode); + +s32_t spiffs_object_append( + spiffs_fd *fd, + u32_t offset, + u8_t *data, + u32_t len); + +s32_t spiffs_object_modify( + spiffs_fd *fd, + u32_t offset, + u8_t *data, + u32_t len); + +s32_t spiffs_object_read( + spiffs_fd *fd, + u32_t offset, + u32_t len, + u8_t *dst); + +s32_t spiffs_object_truncate( + spiffs_fd *fd, + u32_t new_len, + u8_t remove_object); + +s32_t spiffs_object_find_object_index_header_by_name( + spiffs *fs, + u8_t name[SPIFFS_OBJ_NAME_LEN], + spiffs_page_ix *pix); + +// --------------- + +s32_t spiffs_gc_check( + spiffs *fs, + u32_t len); + +s32_t spiffs_gc_erase_page_stats( + spiffs *fs, + spiffs_block_ix bix); + +s32_t spiffs_gc_find_candidate( + spiffs *fs, + spiffs_block_ix **block_candidate, + int *candidate_count, + char fs_crammed); + +s32_t spiffs_gc_clean( + spiffs *fs, + spiffs_block_ix bix); + +s32_t spiffs_gc_quick( + spiffs *fs, u16_t max_free_pages); + +// --------------- + +s32_t spiffs_fd_find_new( + spiffs *fs, + spiffs_fd **fd); + +s32_t spiffs_fd_return( + spiffs *fs, + spiffs_file f); + +s32_t spiffs_fd_get( + spiffs *fs, + spiffs_file f, + spiffs_fd **fd); + +#if SPIFFS_CACHE +void spiffs_cache_init( + spiffs *fs); + +void spiffs_cache_drop_page( + spiffs *fs, + spiffs_page_ix pix); + +#if SPIFFS_CACHE_WR +spiffs_cache_page *spiffs_cache_page_allocate_by_fd( + spiffs *fs, + spiffs_fd *fd); + +void spiffs_cache_fd_release( + spiffs *fs, + spiffs_cache_page *cp); + +spiffs_cache_page *spiffs_cache_page_get_by_fd( + spiffs *fs, + spiffs_fd *fd); +#endif +#endif + +s32_t spiffs_lookup_consistency_check( + spiffs *fs, + u8_t check_all_objects); + +s32_t spiffs_page_consistency_check( + spiffs *fs); + +s32_t spiffs_object_index_consistency_check( + spiffs *fs); + +#endif /* SPIFFS_NUCLEUS_H_ */ diff --git a/include/ssl/ssl_bigint_impl.h b/include/ssl/ssl_bigint_impl.h index c82fefb6..fef6e037 100644 --- a/include/ssl/ssl_bigint_impl.h +++ b/include/ssl/ssl_bigint_impl.h @@ -73,7 +73,7 @@ typedef int32_t slong_comp; /**< A signed double precision component. */ #define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */ typedef uint32_t comp; /**< A single precision component. */ typedef uint64_t long_comp; /**< A double precision component. */ -typedef sint64_t slong_comp; /**< A signed double precision component. */ +typedef int64_t slong_comp; /**< A signed double precision component. */ #endif /** diff --git a/include/ssl/ssl_compat-1.0.h b/include/ssl/ssl_compat-1.0.h new file mode 100644 index 00000000..d0438a22 --- /dev/null +++ b/include/ssl/ssl_compat-1.0.h @@ -0,0 +1,100 @@ +/* + * ssl_compat-1.0.h + * + * Created on: Sep 7, 2015 + * Author: liuhan + */ + +#ifndef SSL_COMPAT_1_0_H_ +#define SSL_COMPAT_1_0_H_ + +#include "ssl/ssl_platform.h" + +/*encapsulation the function based on the espressif platform*/ + +#define SSL_library_init(a) esp_ssl_library_init(a) +#define SSL_new(a) esp_ssl_new(a) +#define SSL_set_fd(a,b) esp_ssl_set_fd(a,b) +#define SSL_free(a) esp_ssl_free(a) +#define SSL_connect(a) esp_ssl_connect(a) +#define SSL_accept(a) esp_ssl_accept(a) +#define SSL_read(a,b,c) esp_ssl_read(a,b,c) +#define SSL_write(a,b,c) esp_ssl_write(a,b,c) +#define SSL_get_peer_certificate(a) esp_ssl_get_peer_certificate(a) +#define SSL_get_verify_result(a) esp_ssl_get_verify_result(a) +#define SSL_get_error(a,b) esp_ssl_get_error(a,b) +#define SSL_pending(a) esp_ssl_pending(a) +#define SSL_fragment_length_negotiation(a,b) esp_ssl_fragment_length_negotiation(a,b) + +#define SSL_CTX_new(a) esp_ssl_CTX_new(a) +#define SSL_CTX_set_option(a,b) esp_ssl_CTX_set_option(a,b) +#define SSL_CTX_free(a) esp_ssl_CTX_free(a) +#define SSL_CTX_load_verify_locations(a,b,c) esp_ssl_CTX_load_verify_locations(a,b,c) +#define SSL_CTX_set_default_verify_paths(a) esp_ssl_CTX_set_default_verify_paths(a) +#define SSL_CTX_use_certificate_chain_file(a,b) esp_ssl_CTX_use_certificate_chain_file(a,b) +#define SSL_CTX_use_PrivateKey_file(a,b,c) esp_ssl_CTX_use_PrivateKey_file(a,b,c) +#define SSL_CTX_check_private_key(a) esp_ssl_CTX_check_private_key(a) +#define SSL_CTX_set_verify(a,b,c) esp_ssl_CTX_set_verify(a) +#define SSL_CTX_set_verify_depth(a,b) esp_ssl_CTX_set_verify_depth(a) +#define SSL_CTX_set_client_cert_cb esp_ssl_CTX_set_client_cert_cb +#define SSL_CTX_set_mode(a) esp_ssl_CTX_set_mode(a) + +#define X509_free(a) esp_X509_free(a) +#define X509_STORE_CTX_get_current_cert(a) esp_X509_store_ctx_get_current_cert(a) +#define X509_NAME_oneline(a,b,c) esp_X509_NAME_oneline(a,b,c) +#define X509_get_issuer_name(a) esp_X509_get_issuer_name(a) +#define X509_get_subject_name(a) esp_X509_get_subject_name(a) +#define X509_STORE_CTX_get_error_depth(a) esp_X509_STORE_CTX_get_error_depth(a) +#define X509_STORE_CTX_get_error(a) esp_X509_STORE_CTX_get_error(a) +#define X509_verify_cert_error_string(a) esp_X509_verify_cert_error_string(a) + +#define EVP_sha1(a) esp_EVP_sha1(a) +#define EVP_DigestInit(a,b) esp_EVP_DigestInit(a,b) +#define EVP_DigestUpdate(a,b,c) esp_EVP_DigestUpdate(a,b,c) +#define EVP_DigestFinal(a,b,c) esp_EVP_DigestFinal(a,b,c) +#define EVP_cleanup(a) esp_EVP_cleanup(a) + +#define ERR_get_error(a) esp_ERR_get_error(a) +#define ERR_error_string_n(a,b,c) esp_ERR_error_string_n(a,b,c) +#define ERR_error_string(a,b) esp_ERR_error_string(a,b) +#define ERR_free_strings(a) esp_ERR_free_strings(a) +#define strerror(a) esp_ERR_strerror(a) + +#define CRYPTO_cleanup_all_ex_data(a) esp_CRYPTO_cleanup_all_ex_data(a) + +#define base64_encode(a,b,c,d,e) esp_base64_encode(a,b,c,d,e) + +#define TLSv1_client_method(a) esp_TLSv1_client_method(a) +//#if TLSv1_1__method +#define TLSv1_1_client_method(a) esp_TLSv1_1_client_method(a) +//#endif +#define SSLv3_client_method(a) esp_SSLv3_client_method(a) +#define SSLv23_client_method(a) esp_SSLv23_client_method(a) + +#define TLSv1_server_method(a) esp_TLSv1_server_method(a) +//#if TLSv1_1__method +#define TLSv1_1_server_method(a) esp_TLSv1_1_server_method(a) +//#endif +#define SSLv3_server_method(a) esp_SSLv3_server_method(a) +#define SSLv23_server_method(a) esp_SSLv23_server_method(a) + +/*encapsulation the protocol based on the espressif platform*/ +#define SSL_ERROR_NONE ESP_SSL_ERROR_NONE +#define SSL_ERROR_WANT_WRITE ESP_SSL_ERROR_WANT_WRITE +#define SSL_ERROR_WANT_READ ESP_SSL_ERROR_WANT_READ +#define SSL_ERROR_WANT_X509_LOOKUP ESP_SSL_ERROR_WANT_X509_LOOKUP +#define SSL_ERROR_SYSCALL ESP_SSL_ERROR_SYSCALL +#define SSL_ERROR_ZERO_RETURN ESP_SSL_ERROR_ZERO_RETURN +#define SSL_ERROR_SSL ESP_SSL_ERROR_SSL +#define SSL_FILETYPE_PEM ESP_SSL_FILETYPE_PEM +#define SSL_VERIFY_PEER ESP_SSL_VERIFY_PEER +#define EVP_MAX_MD_SIZE ESP_EVP_MAX_MD_SIZE +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT ESP_SSL_VERIFY_FAIL_IF_NO_PEER_CERT +#define SSL_MODE_ENABLE_PARTIAL_WRITE ESP_SSL_MODE_ENABLE_PARTIAL_WRITE +#define SSL_VERIFY_NONE ESP_SSL_VERIFY_NONE +#define SSL_ERROR_WANT_CONNECT ESP_SSL_ERROR_WANT_CONNECT +#define SSL_ERROR_WANT_ACCEPT ESP_SSL_ERROR_WANT_ACCEPT + +/*encapsulation the protocol based on the different platform*/ + +#endif /* SSL_COMPAT_1_0_H_ */ diff --git a/include/ssl/ssl_config.h b/include/ssl/ssl_config.h index 88ad6706..e2048305 100644 --- a/include/ssl/ssl_config.h +++ b/include/ssl/ssl_config.h @@ -45,7 +45,7 @@ #define CONFIG_SSL_HAS_PEM 1 #undef CONFIG_SSL_USE_PKCS12 #define CONFIG_SSL_EXPIRY_TIME 24 -#define CONFIG_X509_MAX_CA_CERTS 150 +#define CONFIG_X509_MAX_CA_CERTS 3 #define CONFIG_SSL_MAX_CERTS 3 #undef CONFIG_SSL_CTX_MUTEXING #define CONFIG_USE_DEV_URANDOM 1 @@ -56,6 +56,9 @@ #undef CONFIG_AXTLSWRAP #define CONFIG_AXHTTPD 1 +/*add by LiuH for debug at 2015.06.11*/ +#define CONFIG_SSL_DISPLAY_MODE 0 + /* * Axhttpd Configuration */ diff --git a/include/ssl/ssl_crypto.h b/include/ssl/ssl_crypto.h index 1ea461a5..5d902275 100644 --- a/include/ssl/ssl_crypto.h +++ b/include/ssl/ssl_crypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich * * All rights reserved. * @@ -124,22 +124,58 @@ void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len); void SHA1_Final(uint8_t *digest, SHA1_CTX *); /************************************************************************** - * MD2 declarations + * SHA256 declarations **************************************************************************/ -#define MD2_SIZE 16 +#define SHA256_SIZE 32 typedef struct { - unsigned char cksum[16]; /* checksum of the data block */ - unsigned char state[48]; /* intermediate digest state */ - unsigned char buffer[16]; /* data block being processed */ - int left; /* amount of data in buffer */ -} MD2_CTX; + uint32_t total[2]; + uint32_t state[8]; + uint8_t buffer[64]; +} SHA256_CTX; -EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx); -EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen); -EXP_FUNC void STDCALL MD2_Final(uint8_t *digest, MD2_CTX *ctx); +void SHA256_Init(SHA256_CTX *c); +void SHA256_Update(SHA256_CTX *, const uint8_t *input, int len); +void SHA256_Final(uint8_t *digest, SHA256_CTX *); + +/************************************************************************** + * SHA512 declarations + **************************************************************************/ + +#define SHA512_SIZE 64 + +typedef struct +{ + union + { + uint64_t h[8]; + uint8_t digest[64]; + } h_dig; + union + { + uint64_t w[80]; + uint8_t buffer[128]; + } w_buf; + size_t size; + uint64_t totalSize; +} SHA512_CTX; + +void SHA512_Init(SHA512_CTX *c); +void SHA512_Update(SHA512_CTX *, const uint8_t *input, int len); +void SHA512_Final(uint8_t *digest, SHA512_CTX *); + +/************************************************************************** + * SHA384 declarations + **************************************************************************/ + +#define SHA384_SIZE 48 + +typedef SHA512_CTX SHA384_CTX; +void SHA384_Init(SHA384_CTX *c); +void SHA384_Update(SHA384_CTX *, const uint8_t *input, int len); +void SHA384_Final(uint8_t *digest, SHA384_CTX *); /************************************************************************** * MD5 declarations @@ -203,7 +239,7 @@ void RSA_pub_key_new(RSA_CTX **rsa_ctx, const uint8_t *pub_exp, int pub_len); void RSA_free(RSA_CTX *ctx); int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data, - int is_decryption); + int out_len, int is_decryption); bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg); #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT) bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len, @@ -220,8 +256,8 @@ void RSA_print(const RSA_CTX *ctx); EXP_FUNC void STDCALL RNG_initialize(void); EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size); EXP_FUNC void STDCALL RNG_terminate(void); -EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data); -void get_random_NZ(int num_rand_bytes, uint8_t *rand_data); +EXP_FUNC int STDCALL get_random(int num_rand_bytes, uint8_t *rand_data); +int get_random_NZ(int num_rand_bytes, uint8_t *rand_data); #ifdef __cplusplus } diff --git a/include/ssl/ssl_crypto_misc.h b/include/ssl/ssl_crypto_misc.h index 8e1ba539..1c45db18 100644 --- a/include/ssl/ssl_crypto_misc.h +++ b/include/ssl/ssl_crypto_misc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich * * All rights reserved. * @@ -55,6 +55,7 @@ extern "C" { #define X509_VFY_ERROR_INVALID_CHAIN -7 #define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8 #define X509_INVALID_PRIV_KEY -9 +#define X509_MAX_CERTS -10 /* * The Distinguished Name @@ -112,6 +113,7 @@ const char * x509_display_error(int error); #define ASN1_TELETEX_STR 0x14 #define ASN1_IA5_STR 0x16 #define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 #define ASN1_UNICODE_STR 0x1e #define ASN1_SEQUENCE 0x30 #define ASN1_CONTEXT_DNSNAME 0x82 @@ -125,8 +127,11 @@ const char * x509_display_error(int error); #define SIG_TYPE_MD2 0x02 #define SIG_TYPE_MD5 0x04 #define SIG_TYPE_SHA1 0x05 +#define SIG_TYPE_SHA256 0x0b +#define SIG_TYPE_SHA384 0x0c +#define SIG_TYPE_SHA512 0x0d -int get_asn1_length(const uint8_t *buf, int *offset); +uint32_t get_asn1_length(const uint8_t *buf, int *offset); int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx); int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type); int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type); @@ -148,7 +153,7 @@ int asn1_signature_type(const uint8_t *cert, **************************************************************************/ #define SALT_SIZE 8 -extern const char * const unsupported_str; +extern const char unsupported_str[]; typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int); typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key, diff --git a/include/ssl/ssl_os_port.h b/include/ssl/ssl_os_port.h index a68b9e1a..5181496d 100644 --- a/include/ssl/ssl_os_port.h +++ b/include/ssl/ssl_os_port.h @@ -52,6 +52,44 @@ extern "C" { #define STDCALL #define EXP_FUNC +//struct timeval { +// long tv_sec; /* seconds */ +// long tv_usec; /* and microseconds */ +//}; + +#define tls_htons(x) ((uint16)((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))) +#define tls_ntohs(x) tls_htons(x) +#define tls_htonl(_n) ((uint32)( (((_n) & 0xff) << 24) | (((_n) & 0xff00) << 8) | (((_n) >> 8) & 0xff00) | (((_n) >> 24) & 0xff) )) +#define tls_ntohl(x) tls_htonl(x) + +#ifndef be16toh +#define be16toh(x) ((uint16)tls_ntohs((uint16)(x))) +#endif + +#ifndef htobe16 +#define htobe16(x) ((uint16)tls_htons((uint16)(x))) +#endif + +#ifndef be32toh +#define be32toh(x) ((uint32)tls_ntohl((uint32)(x))) +#endif + +#ifndef htobe32 +#define htobe32(x) ((uint32)tls_htonl((uint32)(x))) +#endif + +#ifndef be64toh +static __inline__ uint64 be64toh(uint64 __x); +static __inline__ uint64 be64toh(uint64 __x) {return (((uint64)be32toh(__x & (uint64)0xFFFFFFFFULL)) << 32) | ((uint64)be32toh((__x & (uint64)0xFFFFFFFF00000000ULL) >> 32));} +#define be64toh(x) be64toh(x) +#endif + +#ifndef htobe64 +#define htobe64(x) be64toh(x) +#endif + +/* Mutexing definitions */ + #define SSL_CTX_MUTEX_INIT(A) #define SSL_CTX_MUTEX_DESTROY(A) #define SSL_CTX_LOCK(A) diff --git a/include/ssl/ssl_platform.h b/include/ssl/ssl_platform.h new file mode 100644 index 00000000..57353227 --- /dev/null +++ b/include/ssl/ssl_platform.h @@ -0,0 +1,53 @@ +/* + * ssl_platom.h + * + * Created on: Sep 7, 2015 + * Author: liuhan + */ + +#ifndef SSL_PLATOM_H_ +#define SSL_PLATOM_H_ + +#include "ssl/ssl_os_port.h" +#include "ssl/ssl_ssl.h" +#include "ssl/ssl_tls1.h" + +typedef void * (*ssl_func_type_t)(void); +typedef void * (*bio_func_type_t)(void); + +typedef struct +{ + ssl_func_type_t ssl_func_type; +} PLATOM_CTX; + +#define PLATOM_CTX_ATTR ((PLATOM_CTX *)ssl_ctx->bonus_attr) + +/*encapsulation the structure based on the espressif platform*/ +struct _MD_CTX +{ + unsigned char cksum[16]; /* checksum of the data block */ + unsigned char state[48]; /* intermediate digest state */ + unsigned char buffer[16]; /* data block being processed */ + int left; /* amount of data in buffer */ +}; + +typedef struct _MD_CTX EVP_MD_CTX; +typedef unsigned char EVP_MD; +typedef struct _x509_ctx X509; +typedef struct _x509_ctx X509_STORE_CTX; +//typedef struct _SSL SSL; +//typedef struct _SSL_CTX SSL_CTX; + +#define ESP_SSL_ERROR_NONE 0 +#define ESP_SSL_ERROR_WANT_WRITE 1 +#define ESP_SSL_ERROR_WANT_READ 2 +#define ESP_SSL_ERROR_WANT_X509_LOOKUP 3 +#define ESP_SSL_ERROR_SYSCALL 4 +#define ESP_SSL_ERROR_ZERO_RETURN 5 +#define ESP_SSL_ERROR_SSL 6 +#define ESP_SSL_FILETYPE_PEM 10 +#define ESP_SSL_VERIFY_PEER 11 +#define ESP_EVP_MAX_MD_SIZE 6 +#define ESP_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 4 + +#endif /* SSL_PLATOM_H_ */ diff --git a/include/ssl/ssl_tls1.h b/include/ssl/ssl_tls1.h index 5597856b..48e90b8c 100644 --- a/include/ssl/ssl_tls1.h +++ b/include/ssl/ssl_tls1.h @@ -76,7 +76,7 @@ extern "C" { #define IS_SET_SSL_FLAG(A) (ssl->flag & A) #define MAX_KEY_BYTE_SIZE 512 /* for a 4096 bit key */ -#define RT_MAX_PLAIN_LENGTH 1024 +#define RT_MAX_PLAIN_LENGTH 1460 #define RT_EXTRA 1024 #define BM_RECORD_OFFSET 5 @@ -89,6 +89,17 @@ extern "C" { #define PARANOIA_CHECK(A, B) if (A < B) { \ ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; } +/*Max Fragment Length Negotiation*/ +enum { + SSL_MAX_FRAG_LEN_NONE, + SSL_MAX_FRAG_LEN_512, + SSL_MAX_FRAG_LEN_1024, + SSL_MAX_FRAG_LEN_2048, + SSL_MAX_FRAG_LEN_4096, + SSL_MAX_FRAG_LEN_8192, + SSL_MAX_FRAG_LEN_INVALID +}; + /* protocol types */ enum { @@ -169,14 +180,15 @@ struct _SSL uint8_t sess_id_size; uint8_t version; uint8_t client_version; - sint16_t next_state; - sint16_t hs_status; + int16_t next_state; + int16_t hs_status; DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */ int client_fd; const cipher_info_t *cipher_info; void *encrypt_ctx; void *decrypt_ctx; - uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA]; + uint8_t *bm_all_data; + uint32_t max_fragme_length; uint8_t *bm_data; uint16_t bm_index; uint16_t bm_read_index; @@ -219,9 +231,9 @@ struct _SSL_CTX #ifdef CONFIG_SSL_CTX_MUTEXING SSL_CTX_MUTEX_TYPE mutex; #endif -#ifdef CONFIG_OPENSSL_COMPATIBLE +//#ifdef CONFIG_OPENSSL_COMPATIBLE void *bonus_attr; -#endif +//#endif }; typedef struct _SSL_CTX SSL_CTX; @@ -291,6 +303,9 @@ SSL_SESSION *ssl_session_update(int max_sessions, const uint8_t *session_id); void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl); +/*Max Fragment Length Negotiation*/ +bool ssl_fragment_length_negotiation(SSL* ssl, int fragmet_level); + #ifdef __cplusplus } #endif diff --git a/include/ssl/ssl_version.h b/include/ssl/ssl_version.h index e8158cc0..85c1640b 100644 --- a/include/ssl/ssl_version.h +++ b/include/ssl/ssl_version.h @@ -1 +1 @@ -#define AXTLS_VERSION "1.4.9" +#define AXTLS_VERSION "1.5.3" diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index 3e7ec1b4..b1a03d4f 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -24,7 +24,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 - dram0_0_seg : org = 0x3FFE8000, len = 0x14000 + dram0_0_seg : org = 0x3FFE8000, len = 0x18000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40240000, len = 0x3C000 } diff --git a/ld/eagle.app.v6.new.1024.app1.ld b/ld/eagle.app.v6.new.1024.app1.ld index e3dc9c3c..040e5fb2 100644 --- a/ld/eagle.app.v6.new.1024.app1.ld +++ b/ld/eagle.app.v6.new.1024.app1.ld @@ -15,7 +15,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 - dram0_0_seg : org = 0x3FFE8000, len = 0x14000 + dram0_0_seg : org = 0x3FFE8000, len = 0x18000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40201010, len = 0x6B000 } diff --git a/ld/eagle.app.v6.new.1024.app2.ld b/ld/eagle.app.v6.new.1024.app2.ld index 3827d084..5e571610 100644 --- a/ld/eagle.app.v6.new.1024.app2.ld +++ b/ld/eagle.app.v6.new.1024.app2.ld @@ -15,7 +15,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 - dram0_0_seg : org = 0x3FFE8000, len = 0x14000 + dram0_0_seg : org = 0x3FFE8000, len = 0x18000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40281010, len = 0x6B000 } diff --git a/ld/eagle.app.v6.new.2048.ld b/ld/eagle.app.v6.new.2048.ld index 2584ac6f..41e3c565 100644 --- a/ld/eagle.app.v6.new.2048.ld +++ b/ld/eagle.app.v6.new.2048.ld @@ -17,7 +17,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 - dram0_0_seg : org = 0x3FFE8000, len = 0x14000 + dram0_0_seg : org = 0x3FFE8000, len = 0x18000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40201010, len = 0xE0000 } diff --git a/ld/eagle.app.v6.new.512.app1.ld b/ld/eagle.app.v6.new.512.app1.ld index 83a29428..771c03d8 100644 --- a/ld/eagle.app.v6.new.512.app1.ld +++ b/ld/eagle.app.v6.new.512.app1.ld @@ -15,7 +15,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 - dram0_0_seg : org = 0x3FFE8000, len = 0x14000 + dram0_0_seg : org = 0x3FFE8000, len = 0x18000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40201010, len = 0x2B000 } diff --git a/ld/eagle.app.v6.new.512.app2.ld b/ld/eagle.app.v6.new.512.app2.ld index cb997e91..eec8ca52 100644 --- a/ld/eagle.app.v6.new.512.app2.ld +++ b/ld/eagle.app.v6.new.512.app2.ld @@ -15,7 +15,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 - dram0_0_seg : org = 0x3FFE8000, len = 0x14000 + dram0_0_seg : org = 0x3FFE8000, len = 0x18000 iram1_0_seg : org = 0x40100000, len = 0x8000 irom0_0_seg : org = 0x40241010, len = 0x2B000 } diff --git a/lib/libcirom.a b/lib/libcirom.a index 7696ecc51b9dec0ceb944eee4ae40522b74ad17e..2c4a99a5199bff74ef9ef06417fd8db7ac5d0311 100644 GIT binary patch delta 360030 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�r%Kw&Gz$A2Au%P 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

9%{C3Mq{OP&_Ef039^ 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 ULy9Bb(kVhi#UsmLJ_wT%(TKsELdI=1 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