Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5831c36a1 | ||
|
|
2d31dc247c | ||
|
|
b289d89f01 | ||
|
|
1198d5a1b9 | ||
|
|
7635f3df69 |
+11
-11
@@ -1,21 +1,21 @@
|
||||
## Contributing to ESP_WiFiManager
|
||||
## Contributing to AsyncHTTPRequest_Generic
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
Please report bugs in ESP_WiFiManager if you find them.
|
||||
Please report bugs in [AsyncHTTPRequest_Generic](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/new) if you find them.
|
||||
|
||||
However, before reporting a bug please check through the following:
|
||||
|
||||
* [Existing Open Issues](https://github.com/khoih-prog/ESP_WiFiManager/issues) - someone might have already encountered this.
|
||||
* [Existing Open Issues](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues) - someone might have already encountered this.
|
||||
|
||||
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/ESP_WiFiManager/issues/new).
|
||||
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues/new).
|
||||
|
||||
### How to submit a bug report
|
||||
|
||||
Please ensure to specify the following:
|
||||
|
||||
* Arduino IDE version (e.g. 1.8.11) or Platform.io version
|
||||
* `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v2.6.3 or ESP32 v1.0.4)
|
||||
* Arduino IDE version (e.g. 1.8.13) or Platform.io version
|
||||
* `ESP8266`,`ESP32` or `STM32` Core Version (e.g. ESP8266 core v2.7.4, ESP32 v1.0.4 or STM32 v1.9.0)
|
||||
* Contextual information (e.g. what you were trying to achieve)
|
||||
* Simplest possible steps to reproduce
|
||||
* Anything that might be relevant in your opinion, such as:
|
||||
@@ -26,10 +26,10 @@ Please ensure to specify the following:
|
||||
### Example
|
||||
|
||||
```
|
||||
Arduino IDE version: 1.8.11
|
||||
ESP8266 Core Version 2.6.3
|
||||
OS: Ubuntu 16.04 LTS
|
||||
Linux Inspiron 4.4.0-170-generic #199-Ubuntu SMP Thu Nov 14 01:45:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
|
||||
Arduino IDE version: 1.8.13
|
||||
ESP32 Core Version 1.0.4
|
||||
OS: Ubuntu 20.04 LTS
|
||||
Linux xy-Inspiron-3593 5.4.0-51-generic #56-Ubuntu SMP Mon Oct 5 14:28:49 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
|
||||
|
||||
Context:
|
||||
I encountered an endless loop while trying to connect to Local WiFi.
|
||||
@@ -44,7 +44,7 @@ Steps to reproduce:
|
||||
|
||||
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
|
||||
|
||||
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_WiFiManager/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
|
||||
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
|
||||
|
||||
### Sending Pull Requests
|
||||
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
#
|
||||
# This library 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 library 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 library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Arduino SAMD Core and platform.
|
||||
#
|
||||
# For more info:
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=Seeed SAMD (32-bits ARM Cortex-M0+ and Cortex-M4) Boards
|
||||
version=1.8.1
|
||||
|
||||
# Compile variables
|
||||
# -----------------
|
||||
|
||||
compiler.warning_flags=-w
|
||||
compiler.warning_flags.none=-w
|
||||
compiler.warning_flags.default=
|
||||
compiler.warning_flags.more=-Wall -Wno-expansion-to-defined
|
||||
compiler.warning_flags.all=-Wall -Wextra -Wno-expansion-to-defined
|
||||
|
||||
compiler.path={runtime.tools.arm-none-eabi-gcc-7-2017q4.path}/bin/
|
||||
compiler.c.cmd=arm-none-eabi-gcc
|
||||
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD -D__SKETCH_NAME__="""{build.project_name}"""
|
||||
compiler.c.elf.cmd=arm-none-eabi-g++
|
||||
compiler.c.elf.flags=-Os -Wl,--gc-sections -save-temps
|
||||
compiler.S.cmd=arm-none-eabi-gcc
|
||||
compiler.S.flags=-c -g -x assembler-with-cpp -MMD
|
||||
compiler.cpp.cmd=arm-none-eabi-g++
|
||||
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu++14 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD -D__SKETCH_NAME__="""{build.project_name}"""
|
||||
compiler.ar.cmd=arm-none-eabi-ar
|
||||
compiler.ar.flags=rcs
|
||||
compiler.objcopy.cmd=arm-none-eabi-objcopy
|
||||
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
|
||||
compiler.elf2hex.bin.flags=-O binary
|
||||
compiler.elf2hex.hex.flags=-O ihex -R .eeprom
|
||||
compiler.elf2hex.cmd=arm-none-eabi-objcopy
|
||||
compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -u _printf_float -u _scanf_float -Wl,--wrap,_write -u __wrap__write
|
||||
compiler.size.cmd=arm-none-eabi-size
|
||||
compiler.define=-DARDUINO=
|
||||
compiler.readelf.cmd=arm-none-eabi-readelf
|
||||
|
||||
# this can be overriden in boards.txt
|
||||
build.extra_flags=
|
||||
build.project_flags=
|
||||
build.cache_flags=
|
||||
build.flags.optimize=
|
||||
build.flags.maxspi=
|
||||
build.flags.maxqspi=
|
||||
build.flags.usbstack=
|
||||
build.flags.debug=
|
||||
build.flags.txrxled=
|
||||
build.flags.role=
|
||||
|
||||
# These can be overridden in platform.local.txt
|
||||
compiler.c.extra_flags=
|
||||
compiler.c.elf.extra_flags=
|
||||
#compiler.c.elf.extra_flags=-v
|
||||
compiler.cpp.extra_flags=
|
||||
compiler.S.extra_flags=
|
||||
compiler.ar.extra_flags=
|
||||
compiler.elf2hex.extra_flags=
|
||||
|
||||
compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/DSP/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.1.path}/CMSIS-Atmel/CMSIS/Device/ATMEL/"
|
||||
compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math
|
||||
|
||||
compiler.libraries.ldflags=
|
||||
|
||||
# USB Flags
|
||||
# ---------
|
||||
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON -DUSB_CONFIG_POWER={build.usb_power} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {build.flags.usbstack} {build.flags.debug} {build.flags.role} "-I{build.core.path}/TinyUSB" "-I{build.core.path}/TinyUSB/Adafruit_TinyUSB_ArduinoCore" "-I{build.core.path}/TinyUSB/Adafruit_TinyUSB_ArduinoCore/tinyusb/src"
|
||||
|
||||
# Default advertised device power setting in mA
|
||||
build.usb_power=100
|
||||
|
||||
# Default usb manufacturer will be replaced at compile time using
|
||||
# numeric vendor ID if available or by board's specific value.
|
||||
build.usb_manufacturer="Unknown"
|
||||
|
||||
|
||||
# Compile patterns
|
||||
# ----------------
|
||||
|
||||
## Compile c files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.project_flags} {build.cache_flags} {build.flags.debug} {build.flags.txrxled} {build.flags.role} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile c++ files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.project_flags} {build.cache_flags} {build.flags.debug} {build.flags.txrxled} {build.flags.role} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {build.extra_flags} {build.project_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile S files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.project_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Create archives
|
||||
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
|
||||
archive_file_path={build.path}/{archive_file}
|
||||
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
|
||||
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} {compiler.libraries.ldflags} -Wl,--start-group {compiler.arm.cmsis.ldflags} "-L{build.variant.path}" -lm "{build.path}/{archive_file}" -Wl,--end-group
|
||||
|
||||
## Create output (bin file)
|
||||
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
|
||||
|
||||
## Create output (hex file)
|
||||
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
|
||||
|
||||
build.preferred_out_format=bin
|
||||
|
||||
## Save hex
|
||||
recipe.output.tmp_file={build.project_name}.{build.preferred_out_format}
|
||||
recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_out_format}
|
||||
|
||||
## Compute size
|
||||
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
|
||||
recipe.size.regex=\.text\s+([0-9]+).*
|
||||
|
||||
#
|
||||
# BOSSA
|
||||
#
|
||||
tools.bossac.path={runtime.tools.bossac-1.7.0-arduino3.path}
|
||||
tools.bossac.cmd=bossac
|
||||
tools.bossac.cmd.windows=bossac.exe
|
||||
tools.bossac.upload.params.verbose=-i -d
|
||||
tools.bossac.upload.params.quiet=
|
||||
tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -i -e -w -v "{build.path}/{build.project_name}.bin" -R
|
||||
tools.bossac_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R
|
||||
tools.bossac.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossac.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
# v1.8.0
|
||||
tools.bossac18.path={runtime.tools.bossac-1.8.0-48-gb176eee.path}
|
||||
tools.bossac18.cmd=bossac
|
||||
tools.bossac18.upload.params.verbose=-i -d
|
||||
tools.bossac18.upload.params.quiet=
|
||||
tools.bossac18.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U -i --offset={upload.offset} -w -v "{build.path}/{build.project_name}.bin" -R
|
||||
tools.bossac18.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossac18.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
#
|
||||
# BOSSA (ignore binary size)
|
||||
#
|
||||
tools.bossacI.path={runtime.tools.bossac-1.7.0-arduino3.path}
|
||||
tools.bossacI.cmd=bossac
|
||||
tools.bossacI.cmd.windows=bossac.exe
|
||||
tools.bossacI.upload.params.verbose=-i -d
|
||||
tools.bossacI.upload.params.quiet=
|
||||
tools.bossacI.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -I -U {upload.native_usb} -i -e -w "{build.path}/{build.project_name}.bin" -R
|
||||
tools.bossacI_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R
|
||||
tools.bossacI.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossacI.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
#
|
||||
# OpenOCD sketch upload
|
||||
#
|
||||
tools.openocd.path={runtime.tools.openocd-0.10.0-arduino7.path}
|
||||
tools.openocd.cmd=bin/openocd
|
||||
tools.openocd.cmd.windows=bin/openocd.exe
|
||||
tools.openocd.upload.params.verbose=-d2
|
||||
tools.openocd.upload.params.quiet=-d0
|
||||
tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown"
|
||||
tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
# Program flashes the binary at 0x0000, so use the linker script without_bootloader
|
||||
tools.openocd.program.params.verbose=-d2
|
||||
tools.openocd.program.params.quiet=-d0
|
||||
tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
|
||||
tools.openocd.erase.params.verbose=-d3
|
||||
tools.openocd.erase.params.quiet=-d0
|
||||
tools.openocd.erase.pattern=
|
||||
tools.openocd.bootloader.params.verbose=-d2
|
||||
tools.openocd.bootloader.params.quiet=-d0
|
||||
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
|
||||
#
|
||||
# OpenOCD sketch upload - version with configurable bootloader size
|
||||
# FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences
|
||||
#
|
||||
tools.openocd-withbootsize.path={runtime.tools.openocd-0.10.0-arduino7.path}
|
||||
tools.openocd-withbootsize.cmd=bin/openocd
|
||||
tools.openocd-withbootsize.cmd.windows=bin/openocd.exe
|
||||
tools.openocd-withbootsize.upload.params.verbose=-d2
|
||||
tools.openocd-withbootsize.upload.params.quiet=-d0
|
||||
tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown"
|
||||
# Program flashes the binary at 0x0000, so use the linker script without_bootloader
|
||||
tools.openocd-withbootsize.program.params.verbose=-d2
|
||||
tools.openocd-withbootsize.program.params.quiet=-d0
|
||||
tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
|
||||
tools.openocd-withbootsize.erase.params.verbose=-d3
|
||||
tools.openocd-withbootsize.erase.params.quiet=-d0
|
||||
tools.openocd-withbootsize.erase.pattern=
|
||||
tools.openocd-withbootsize.bootloader.params.verbose=-d2
|
||||
tools.openocd-withbootsize.bootloader.params.quiet=-d0
|
||||
tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
|
||||
@@ -0,0 +1,226 @@
|
||||
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
#
|
||||
# This library 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 library 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 library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Arduino SAMD Core and platform.
|
||||
#
|
||||
# For more info:
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=Adafruit SAMD (32-bits ARM Cortex-M0+ and Cortex-M4) Boards
|
||||
version=1.6.4
|
||||
|
||||
# Compile variables
|
||||
# -----------------
|
||||
|
||||
compiler.warning_flags=-w
|
||||
compiler.warning_flags.none=-w
|
||||
compiler.warning_flags.default=
|
||||
compiler.warning_flags.more=-Wall -Wno-expansion-to-defined
|
||||
compiler.warning_flags.all=-Wall -Wextra -Wno-expansion-to-defined
|
||||
|
||||
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
|
||||
compiler.c.cmd=arm-none-eabi-gcc
|
||||
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD -D__SKETCH_NAME__="""{build.project_name}"""
|
||||
compiler.c.elf.cmd=arm-none-eabi-g++
|
||||
compiler.c.elf.flags=-Os -Wl,--gc-sections -save-temps
|
||||
compiler.S.cmd=arm-none-eabi-gcc
|
||||
compiler.S.flags=-c -g -x assembler-with-cpp -MMD
|
||||
compiler.cpp.cmd=arm-none-eabi-g++
|
||||
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD -D__SKETCH_NAME__="""{build.project_name}"""
|
||||
compiler.ar.cmd=arm-none-eabi-ar
|
||||
compiler.ar.flags=rcs
|
||||
compiler.objcopy.cmd=arm-none-eabi-objcopy
|
||||
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
|
||||
compiler.elf2hex.bin.flags=-O binary
|
||||
compiler.elf2hex.hex.flags=-O ihex -R .eeprom
|
||||
compiler.elf2hex.cmd=arm-none-eabi-objcopy
|
||||
compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align
|
||||
compiler.size.cmd=arm-none-eabi-size
|
||||
compiler.define=-DARDUINO=
|
||||
compiler.readelf.cmd=arm-none-eabi-readelf
|
||||
|
||||
# this can be overriden in boards.txt
|
||||
build.extra_flags=
|
||||
build.cache_flags=
|
||||
build.flags.optimize=
|
||||
build.flags.maxspi=
|
||||
build.flags.maxqspi=
|
||||
build.flags.usbstack=
|
||||
build.flags.debug=
|
||||
|
||||
# These can be overridden in platform.local.txt
|
||||
compiler.c.extra_flags=
|
||||
compiler.c.elf.extra_flags=
|
||||
#compiler.c.elf.extra_flags=-v
|
||||
compiler.cpp.extra_flags=
|
||||
compiler.S.extra_flags=
|
||||
compiler.ar.extra_flags=
|
||||
compiler.elf2hex.extra_flags=
|
||||
|
||||
compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/DSP/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.0.path}/CMSIS/Device/ATMEL/"
|
||||
compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math
|
||||
|
||||
compiler.libraries.ldflags=
|
||||
|
||||
# USB Flags
|
||||
# ---------
|
||||
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON -DUSB_CONFIG_POWER={build.usb_power} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {build.flags.usbstack} {build.flags.debug} "-I{build.core.path}/TinyUSB" "-I{build.core.path}/TinyUSB/Adafruit_TinyUSB_ArduinoCore" "-I{build.core.path}/TinyUSB/Adafruit_TinyUSB_ArduinoCore/tinyusb/src"
|
||||
|
||||
# Default advertised device power setting in mA
|
||||
build.usb_power=100
|
||||
|
||||
# Default usb manufacturer will be replaced at compile time using
|
||||
# numeric vendor ID if available or by board's specific value.
|
||||
build.usb_manufacturer="Unknown"
|
||||
|
||||
|
||||
# Compile patterns
|
||||
# ----------------
|
||||
|
||||
## Compile c files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile c++ files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile S files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Create archives
|
||||
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
|
||||
archive_file_path={build.path}/{archive_file}
|
||||
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
|
||||
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} {compiler.libraries.ldflags} -Wl,--start-group {compiler.arm.cmsis.ldflags} "-L{build.variant.path}" -lm "{build.path}/{archive_file}" -Wl,--end-group
|
||||
|
||||
## Create output (bin file)
|
||||
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
|
||||
|
||||
## Create output (hex file)
|
||||
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
|
||||
|
||||
build.preferred_out_format=bin
|
||||
|
||||
## Save hex
|
||||
recipe.output.tmp_file={build.project_name}.{build.preferred_out_format}
|
||||
recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_out_format}
|
||||
|
||||
## Compute size
|
||||
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
|
||||
recipe.size.regex=\.text\s+([0-9]+).*
|
||||
|
||||
#
|
||||
# BOSSA
|
||||
#
|
||||
tools.bossac.path={runtime.tools.bossac-1.7.0-arduino3.path}
|
||||
tools.bossac.cmd=bossac
|
||||
tools.bossac.cmd.windows=bossac.exe
|
||||
|
||||
tools.bossac.upload.params.verbose=-i -d
|
||||
tools.bossac.upload.params.quiet=
|
||||
tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -i -e -w -v "{build.path}/{build.project_name}.bin" -R
|
||||
|
||||
tools.bossac_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R
|
||||
|
||||
tools.bossac.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossac.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
# v1.8.0
|
||||
|
||||
tools.bossac18.path={runtime.tools.bossac-1.8.0-48-gb176eee.path}
|
||||
tools.bossac18.cmd=bossac
|
||||
|
||||
tools.bossac18.upload.params.verbose=-i -d
|
||||
tools.bossac18.upload.params.quiet=
|
||||
tools.bossac18.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U -i --offset={upload.offset} -w -v "{build.path}/{build.project_name}.bin" -R
|
||||
|
||||
tools.bossac18.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossac18.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
#
|
||||
# BOSSA (ignore binary size)
|
||||
#
|
||||
tools.bossacI.path={runtime.tools.bossac-1.7.0-arduino3.path}
|
||||
tools.bossacI.cmd=bossac
|
||||
tools.bossacI.cmd.windows=bossac.exe
|
||||
|
||||
tools.bossacI.upload.params.verbose=-i -d
|
||||
tools.bossacI.upload.params.quiet=
|
||||
tools.bossacI.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -I -U {upload.native_usb} -i -e -w "{build.path}/{build.project_name}.bin" -R
|
||||
|
||||
tools.bossacI_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R
|
||||
|
||||
tools.bossacI.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossacI.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
|
||||
#
|
||||
# OpenOCD sketch upload
|
||||
#
|
||||
|
||||
tools.openocd.path={runtime.tools.openocd-0.10.0-arduino7.path}
|
||||
tools.openocd.cmd=bin/openocd
|
||||
tools.openocd.cmd.windows=bin/openocd.exe
|
||||
|
||||
tools.openocd.upload.params.verbose=-d2
|
||||
tools.openocd.upload.params.quiet=-d0
|
||||
tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown"
|
||||
|
||||
tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
# Program flashes the binary at 0x0000, so use the linker script without_bootloader
|
||||
tools.openocd.program.params.verbose=-d2
|
||||
tools.openocd.program.params.quiet=-d0
|
||||
tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
|
||||
|
||||
tools.openocd.erase.params.verbose=-d3
|
||||
tools.openocd.erase.params.quiet=-d0
|
||||
tools.openocd.erase.pattern=
|
||||
|
||||
tools.openocd.bootloader.params.verbose=-d2
|
||||
tools.openocd.bootloader.params.quiet=-d0
|
||||
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
|
||||
|
||||
#
|
||||
# OpenOCD sketch upload - version with configurable bootloader size
|
||||
# FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences
|
||||
#
|
||||
|
||||
tools.openocd-withbootsize.path={runtime.tools.openocd-0.10.0-arduino7.path}
|
||||
tools.openocd-withbootsize.cmd=bin/openocd
|
||||
tools.openocd-withbootsize.cmd.windows=bin/openocd.exe
|
||||
|
||||
tools.openocd-withbootsize.upload.params.verbose=-d2
|
||||
tools.openocd-withbootsize.upload.params.quiet=-d0
|
||||
tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown"
|
||||
|
||||
# Program flashes the binary at 0x0000, so use the linker script without_bootloader
|
||||
tools.openocd-withbootsize.program.params.verbose=-d2
|
||||
tools.openocd-withbootsize.program.params.quiet=-d0
|
||||
tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
|
||||
|
||||
tools.openocd-withbootsize.erase.params.verbose=-d3
|
||||
tools.openocd-withbootsize.erase.params.quiet=-d0
|
||||
tools.openocd-withbootsize.erase.pattern=
|
||||
|
||||
tools.openocd-withbootsize.bootloader.params.verbose=-d2
|
||||
tools.openocd-withbootsize.bootloader.params.quiet=-d0
|
||||
tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
Arduino.h - Main include file for the Arduino SDK
|
||||
Copyright (c) 2014 Arduino LLC. All right reserved.
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// KH, This is the fix according to https://github.com/arduino/ArduinoCore-samd/pull/399
|
||||
// to avoid notorious compiler error while uing STL (min and max macro error)
|
||||
// It's terrible Arduino has just released new core and still don't merge the PR
|
||||
|
||||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef bool boolean;
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t word;
|
||||
|
||||
// some libraries and sketches depend on this AVR stuff,
|
||||
// assuming Arduino.h or WProgram.h automatically includes it...
|
||||
//
|
||||
#include "avr/pgmspace.h"
|
||||
#include "avr/interrupt.h"
|
||||
#include "avr/io.h"
|
||||
|
||||
#include "binary.h"
|
||||
#include "itoa.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif // __cplusplus
|
||||
|
||||
// Include Atmel headers
|
||||
#include "sam.h"
|
||||
|
||||
#include "wiring_constants.h"
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (SystemCoreClock / 1000L) )
|
||||
#define microsecondsToClockCycles(a) ( (a) * (SystemCoreClock / 1000000L) )
|
||||
|
||||
void yield( void ) ;
|
||||
|
||||
/* system functions */
|
||||
int main( void );
|
||||
void init( void );
|
||||
|
||||
/* sketch */
|
||||
void setup( void ) ;
|
||||
void loop( void ) ;
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// The following headers are for C++ only compilation
|
||||
#ifdef __cplusplus
|
||||
#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "Tone.h"
|
||||
#include "WMath.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "pulse.h"
|
||||
#include <bits/stl_algobase.h>
|
||||
#endif
|
||||
|
||||
#include "delay.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Uart.h"
|
||||
#endif
|
||||
|
||||
// Include board variant
|
||||
#include "variant.h"
|
||||
#include "wiring.h"
|
||||
#include "wiring_digital.h"
|
||||
#include "wiring_analog.h"
|
||||
#include "wiring_shift.h"
|
||||
#include "WInterrupts.h"
|
||||
|
||||
#ifndef __cplusplus
|
||||
// undefine stdlib's abs if encountered
|
||||
#ifdef abs
|
||||
#undef abs
|
||||
#endif // abs
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define abs(x) ((x)>0?(x):-(x))
|
||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
|
||||
#else
|
||||
//using std::min;
|
||||
//using std::max;
|
||||
template<class T, class L>
|
||||
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
|
||||
{
|
||||
return (b < a) ? b : a;
|
||||
}
|
||||
|
||||
template<class T, class L>
|
||||
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
|
||||
{
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||
#define sq(x) ((x)*(x))
|
||||
|
||||
#define interrupts() __enable_irq()
|
||||
#define noInterrupts() __disable_irq()
|
||||
|
||||
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
||||
#define highByte(w) ((uint8_t) ((w) >> 8))
|
||||
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||
#define bit(b) (1UL << (b))
|
||||
|
||||
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
|
||||
// Interrupts
|
||||
#define digitalPinToInterrupt(P) ( P )
|
||||
#endif
|
||||
|
||||
// Allows publishing the Beta core under samd-beta / arduino organization
|
||||
#ifndef ARDUINO_ARCH_SAMD
|
||||
#define ARDUINO_ARCH_SAMD
|
||||
#endif
|
||||
|
||||
// USB Device
|
||||
#include "USB/USBDesc.h"
|
||||
#include "USB/USBCore.h"
|
||||
#include "USB/USBAPI.h"
|
||||
#include "USB/USB_host.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "USB/CDC.h"
|
||||
#endif
|
||||
|
||||
#endif // Arduino_h
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
Arduino.h - Main include file for the Arduino SDK
|
||||
Copyright (c) 2014 Arduino LLC. All right reserved.
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// KH, This is the fix according to https://github.com/arduino/ArduinoCore-samd/pull/399
|
||||
// to avoid notorious compiler error while uing STL (min and max macro error)
|
||||
// It's terrible Arduino has just released new core and still don't merge the PR
|
||||
|
||||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef bool boolean;
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t word;
|
||||
|
||||
// some libraries and sketches depend on this AVR stuff,
|
||||
// assuming Arduino.h or WProgram.h automatically includes it...
|
||||
//
|
||||
#include "avr/pgmspace.h"
|
||||
#include "avr/interrupt.h"
|
||||
#include "avr/io.h"
|
||||
|
||||
#include "binary.h"
|
||||
#include "itoa.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif // __cplusplus
|
||||
|
||||
// Include Atmel headers
|
||||
#include "sam.h"
|
||||
|
||||
#include "wiring_constants.h"
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (SystemCoreClock / 1000L) )
|
||||
#define microsecondsToClockCycles(a) ( (a) * (SystemCoreClock / 1000000L) )
|
||||
|
||||
void yield( void ) ;
|
||||
|
||||
/* system functions */
|
||||
int main( void );
|
||||
void init( void );
|
||||
|
||||
/* sketch */
|
||||
void setup( void ) ;
|
||||
void loop( void ) ;
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
// The following headers are for C++ only compilation
|
||||
#ifdef __cplusplus
|
||||
#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "Tone.h"
|
||||
#include "WMath.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "pulse.h"
|
||||
#include <bits/stl_algobase.h>
|
||||
#endif
|
||||
|
||||
#include "delay.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Uart.h"
|
||||
#endif
|
||||
|
||||
// Include board variant
|
||||
#include "variant.h"
|
||||
#include "wiring.h"
|
||||
#include "wiring_digital.h"
|
||||
#include "wiring_analog.h"
|
||||
#include "wiring_shift.h"
|
||||
#include "WInterrupts.h"
|
||||
|
||||
#ifndef __cplusplus
|
||||
// undefine stdlib's abs if encountered
|
||||
#ifdef abs
|
||||
#undef abs
|
||||
#endif // abs
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define abs(x) ((x)>0?(x):-(x))
|
||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
|
||||
#else
|
||||
//using std::min;
|
||||
//using std::max;
|
||||
template<class T, class L>
|
||||
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
|
||||
{
|
||||
return (b < a) ? b : a;
|
||||
}
|
||||
|
||||
template<class T, class L>
|
||||
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
|
||||
{
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||
#define sq(x) ((x)*(x))
|
||||
|
||||
#define interrupts() __enable_irq()
|
||||
#define noInterrupts() __disable_irq()
|
||||
|
||||
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
||||
#define highByte(w) ((uint8_t) ((w) >> 8))
|
||||
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||
#define bit(b) (1UL << (b))
|
||||
|
||||
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
|
||||
// Interrupts
|
||||
#define digitalPinToInterrupt(P) ( P )
|
||||
#endif
|
||||
|
||||
// Allows publishing the Beta core under samd-beta / arduino organization
|
||||
#ifndef ARDUINO_ARCH_SAMD
|
||||
#define ARDUINO_ARCH_SAMD
|
||||
#endif
|
||||
|
||||
// USB Device
|
||||
#include "USB/USBDesc.h"
|
||||
#include "USB/USBCore.h"
|
||||
#include "USB/USBAPI.h"
|
||||
#include "USB/USB_host.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "USB/CDC.h"
|
||||
#endif
|
||||
|
||||
#endif // Arduino_h
|
||||
@@ -0,0 +1,242 @@
|
||||
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
#
|
||||
# This library 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 library 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 library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Arduino SAMD Core and platform.
|
||||
#
|
||||
# For more info:
|
||||
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification
|
||||
|
||||
name=Arduino SAMD (32-bits ARM Cortex-M0+) Boards
|
||||
version=1.8.9
|
||||
|
||||
# Compile variables
|
||||
# -----------------
|
||||
|
||||
compiler.warning_flags=-w
|
||||
compiler.warning_flags.none=-w
|
||||
compiler.warning_flags.default=
|
||||
compiler.warning_flags.more=-Wall -Wno-expansion-to-defined
|
||||
compiler.warning_flags.all=-Wall -Wextra -Wno-expansion-to-defined
|
||||
|
||||
# EXPERIMENTAL feature: optimization flags
|
||||
# - this is alpha and may be subject to change without notice
|
||||
compiler.optimization_flags=-Os
|
||||
compiler.optimization_flags.release=-Os
|
||||
compiler.optimization_flags.debug=-Og -g3
|
||||
|
||||
compiler.path={runtime.tools.arm-none-eabi-gcc-7-2017q4.path}/bin/
|
||||
compiler.c.cmd=arm-none-eabi-gcc
|
||||
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g {compiler.optimization_flags} {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD
|
||||
compiler.c.elf.cmd=arm-none-eabi-g++
|
||||
compiler.c.elf.flags={compiler.optimization_flags} -Wl,--gc-sections -save-temps
|
||||
compiler.S.cmd=arm-none-eabi-gcc
|
||||
compiler.S.flags=-c -g -x assembler-with-cpp -MMD
|
||||
compiler.cpp.cmd=arm-none-eabi-g++
|
||||
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g {compiler.optimization_flags} {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD
|
||||
compiler.ar.cmd=arm-none-eabi-ar
|
||||
compiler.ar.flags=rcs
|
||||
compiler.objcopy.cmd=arm-none-eabi-objcopy
|
||||
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
|
||||
compiler.elf2hex.bin.flags=-O binary
|
||||
compiler.elf2hex.hex.flags=-O ihex -R .eeprom
|
||||
compiler.elf2hex.cmd=arm-none-eabi-objcopy
|
||||
compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align
|
||||
compiler.size.cmd=arm-none-eabi-size
|
||||
compiler.define=-DARDUINO=
|
||||
compiler.readelf.cmd=arm-none-eabi-readelf
|
||||
|
||||
# this can be overriden in boards.txt
|
||||
build.extra_flags=
|
||||
|
||||
# These can be overridden in platform.local.txt
|
||||
compiler.c.extra_flags=
|
||||
compiler.c.elf.extra_flags=
|
||||
#compiler.c.elf.extra_flags=-v
|
||||
compiler.cpp.extra_flags=
|
||||
compiler.S.extra_flags=
|
||||
compiler.ar.extra_flags=
|
||||
compiler.elf2hex.extra_flags=
|
||||
|
||||
compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.0.path}/CMSIS/Device/ATMEL/"
|
||||
compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math
|
||||
|
||||
compiler.libraries.ldflags=
|
||||
|
||||
# USB Flags
|
||||
# ---------
|
||||
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
|
||||
|
||||
# Default usb manufacturer will be replaced at compile time using
|
||||
# numeric vendor ID if available or by board's specific value.
|
||||
build.usb_manufacturer="Unknown"
|
||||
|
||||
# Compile patterns
|
||||
# ----------------
|
||||
|
||||
## Compile c files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile c++ files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DBOARD_NAME="{build.board}" -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Compile S files
|
||||
## KH Add -DBOARD_NAME="{build.board}"
|
||||
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
|
||||
|
||||
## Create archives
|
||||
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
|
||||
archive_file_path={build.path}/{archive_file}
|
||||
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
|
||||
|
||||
## Combine gc-sections, archives, and objects
|
||||
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} {compiler.libraries.ldflags} -Wl,--start-group {compiler.arm.cmsis.ldflags} -lm "{build.path}/{archive_file}" -Wl,--end-group
|
||||
|
||||
## Create output (bin file)
|
||||
recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
|
||||
|
||||
## Create output (hex file)
|
||||
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
|
||||
|
||||
build.preferred_out_format=bin
|
||||
|
||||
## Save hex
|
||||
recipe.output.tmp_file={build.project_name}.{build.preferred_out_format}
|
||||
recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_out_format}
|
||||
|
||||
## Compute size
|
||||
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
|
||||
recipe.size.regex=^(?:\.text|\.data|)\s+([0-9]+).*
|
||||
recipe.size.regex.data=^(?:\.data|\.bss)\s+([0-9]+).*
|
||||
|
||||
# Upload/Debug tools
|
||||
# ------------------
|
||||
|
||||
#
|
||||
# AVRDUDE
|
||||
#
|
||||
tools.avrdude.path={runtime.tools.avrdude.path}
|
||||
tools.avrdude.cmd={path}/bin/avrdude
|
||||
tools.avrdude.config.path={path}/etc/avrdude.conf
|
||||
|
||||
tools.avrdude.upload.params.verbose=-v -v
|
||||
tools.avrdude.upload.params.quiet=-q -q
|
||||
tools.avrdude.upload.params.noverify=-V
|
||||
tools.avrdude.upload.pattern="{cmd}" "-C{config.path}" {upload.verbose} -p{build.emu.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} "-Uflash:w:{build.path}/{build.project_name}.hex:i"
|
||||
|
||||
tools.avrdude_remote.upload.pattern="openocd --version 2>&1 | grep 2016 && if opkg update; then opkg upgrade openocd; exit 1; else echo 'Please connect your board to the Internet in order to upgrade tools' >&2; exit 1; fi || /usr/bin/run-avrdude /tmp/sketch.hex"
|
||||
|
||||
tools.avrdude.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.avrdude.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
#
|
||||
# BOSSA
|
||||
#
|
||||
tools.bossac.path={runtime.tools.bossac-1.7.0-arduino3.path}
|
||||
tools.bossac.cmd=bossac
|
||||
tools.bossac.cmd.windows=bossac.exe
|
||||
|
||||
tools.bossac.upload.params.verbose=-i -d
|
||||
tools.bossac.upload.params.quiet=
|
||||
tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -i -e -w -v "{build.path}/{build.project_name}.bin" -R
|
||||
|
||||
tools.bossac_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R
|
||||
|
||||
arduinoota.extraflags=
|
||||
tools.bossac.network_cmd={runtime.tools.arduinoOTA-1.3.0.path}/bin/arduinoOTA
|
||||
tools.bossac.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b {arduinoota.extraflags}
|
||||
|
||||
#
|
||||
# BOSSA (ignore binary size)
|
||||
#
|
||||
tools.bossacI.path={runtime.tools.bossac-1.7.0-arduino3.path}
|
||||
tools.bossacI.cmd=bossac
|
||||
tools.bossacI.cmd.windows=bossac.exe
|
||||
|
||||
tools.bossacI.upload.params.verbose=-i -d
|
||||
tools.bossacI.upload.params.quiet=
|
||||
tools.bossacI.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -I -U {upload.native_usb} -i -e -w "{build.path}/{build.project_name}.bin" -R
|
||||
|
||||
tools.bossacI_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R
|
||||
|
||||
tools.bossacI.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.bossacI.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
|
||||
#
|
||||
# OpenOCD sketch upload
|
||||
#
|
||||
|
||||
tools.openocd.path={runtime.tools.openocd-0.10.0-arduino7.path}
|
||||
tools.openocd.cmd=bin/openocd
|
||||
tools.openocd.cmd.windows=bin/openocd.exe
|
||||
|
||||
tools.openocd.upload.params.verbose=-d2
|
||||
tools.openocd.upload.params.quiet=-d0
|
||||
tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown"
|
||||
|
||||
tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
|
||||
tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
|
||||
|
||||
tools.openocd.program.params.verbose=-d2
|
||||
tools.openocd.program.params.quiet=-d0
|
||||
tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.hex} verify reset; shutdown"
|
||||
|
||||
tools.openocd.erase.params.verbose=-d3
|
||||
tools.openocd.erase.params.quiet=-d0
|
||||
tools.openocd.erase.pattern=
|
||||
|
||||
tools.openocd.bootloader.params.verbose=-d2
|
||||
tools.openocd.bootloader.params.quiet=-d0
|
||||
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
|
||||
|
||||
#
|
||||
# OpenOCD sketch upload - version with configurable bootloader size
|
||||
# FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences
|
||||
#
|
||||
|
||||
tools.openocd-withbootsize.path={runtime.tools.openocd-0.10.0-arduino7.path}
|
||||
tools.openocd-withbootsize.cmd=bin/openocd
|
||||
tools.openocd-withbootsize.cmd.windows=bin/openocd.exe
|
||||
|
||||
tools.openocd-withbootsize.upload.params.verbose=-d2
|
||||
tools.openocd-withbootsize.upload.params.quiet=-d0
|
||||
tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown"
|
||||
|
||||
# Program flashes the binary at 0x0000, so use the linker script without_bootloader
|
||||
tools.openocd-withbootsize.program.params.verbose=-d2
|
||||
tools.openocd-withbootsize.program.params.quiet=-d0
|
||||
tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
|
||||
|
||||
tools.openocd-withbootsize.erase.params.verbose=-d3
|
||||
tools.openocd-withbootsize.erase.params.quiet=-d0
|
||||
tools.openocd-withbootsize.erase.pattern=
|
||||
|
||||
tools.openocd-withbootsize.bootloader.params.verbose=-d2
|
||||
tools.openocd-withbootsize.bootloader.params.quiet=-d0
|
||||
tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
|
||||
|
||||
#
|
||||
# GDB (Debugger)
|
||||
#
|
||||
# EXPERIMENTAL feature: debug.pattern
|
||||
# - this is alpha and may be subject to change without notice
|
||||
tools.gdb-openocd.path={runtime.tools.arm-none-eabi-gcc-7-2017q4.path}/bin/
|
||||
tools.gdb-openocd.cmd=arm-none-eabi-gdb
|
||||
tools.gdb-openocd.cmd.windows=arm-none-eabi-gdb.exe
|
||||
tools.gdb-openocd.interpreter=console
|
||||
tools.gdb-openocd.debug.pattern="{path}/{cmd}" --interpreter={interpreter} -ex "set remotetimeout 5" -ex "set pagination off" -ex 'target extended-remote | "{tools.openocd.path}/{tools.openocd.cmd}" -s "{tools.openocd.path}/share/openocd/scripts/" --file "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "gdb_port pipe" -c "telnet_port 0"' "{build.path}/{build.project_name}.elf"
|
||||
@@ -45,6 +45,15 @@ Chunked responses are recognized and handled transparently.
|
||||
---
|
||||
---
|
||||
|
||||
### Releases v1.0.2
|
||||
|
||||
1. Make Mutex Lock and delete more reliable and error-proof to prevent random crash.
|
||||
|
||||
### Releases v1.0.1
|
||||
|
||||
1. Restore cpp code besides Impl.h code to use in case of `multiple definition` linker error. Thanks to [Daniel Brunner](https://github.com/0xFEEDC0DE64) to report and make PR in [**Fixed linker errors when included in multiple .cpp files**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/pull/1). See [**HOWTO Fix `Multiple Definitions` Linker Error**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic#HOWTO-Fix-Multiple-Definitions-Linker-Error)
|
||||
|
||||
|
||||
### Releases v1.0.0
|
||||
|
||||
1. Initial coding to add support to **STM32F/L/H/G/WB/MP1** using built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
@@ -97,7 +106,8 @@ The best and easiest way is to use `Arduino Library Manager`. Search for `AsyncH
|
||||
3. Extract the zip file to `AsyncHTTPRequest_Generic-master` directory
|
||||
4. Copy the whole `AsyncHTTPRequest_Generic-master` folder to Arduino libraries' directory such as `~/Arduino/libraries/`.
|
||||
|
||||
### VS Code & PlatformIO:
|
||||
### VS Code & PlatformIO
|
||||
|
||||
1. Install [VS Code](https://code.visualstudio.com/)
|
||||
2. Install [PlatformIO](https://platformio.org/platformio-ide)
|
||||
3. Install **AsyncHTTPRequest_Generic** library by using [Library Manager](https://docs.platformio.org/en/latest/librarymanager/). Search for ***AsyncHTTPRequest_Generic*** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22)
|
||||
@@ -152,11 +162,11 @@ This file must be copied into the directory:
|
||||
|
||||
- `~/.arduino15/packages/arduino/hardware/sam/x.yy.zz/platform.txt`
|
||||
|
||||
4. ***To be able to compile without error and automatically detect and display BOARD_NAME on Arduino SAMD (Nano-33-IoT, etc) boards***, you have to copy the whole [Arduino SAMD cores 1.8.8](Packages_Patches/arduino/hardware/samd/1.8.8) directory into Arduino SAMD directory (~/.arduino15/packages/arduino/hardware/samd/1.8.8).
|
||||
4. ***To be able to compile without error and automatically detect and display BOARD_NAME on Arduino SAMD (Nano-33-IoT, etc) boards***, you have to copy the whole [Arduino SAMD cores 1.8.9](Packages_Patches/arduino/hardware/samd/1.8.9) directory into Arduino SAMD directory (~/.arduino15/packages/arduino/hardware/samd/1.8.9).
|
||||
|
||||
Supposing the Arduino SAMD version is 1.8.8. These files must be copied into the directory:
|
||||
- `~/.arduino15/packages/arduino/hardware/samd/1.8.8/platform.txt`
|
||||
- ***`~/.arduino15/packages/arduino/hardware/samd/1.8.8/cores/arduino/Arduino.h`***
|
||||
Supposing the Arduino SAMD version is 1.8.9. These files must be copied into the directory:
|
||||
- `~/.arduino15/packages/arduino/hardware/samd/1.8.9/platform.txt`
|
||||
- ***`~/.arduino15/packages/arduino/hardware/samd/1.8.9/cores/arduino/Arduino.h`***
|
||||
|
||||
Whenever a new version is installed, remember to copy these files into the new version directory. For example, new version is x.yy.z
|
||||
|
||||
@@ -174,22 +184,22 @@ These files must be copied into the directory:
|
||||
|
||||
Whenever the above-mentioned compiler error issue is fixed with the new Arduino SAMD release, you don't need to copy the `Arduino.h` file anymore.
|
||||
|
||||
5. ***To be able to automatically detect and display BOARD_NAME on Adafruit SAMD (Itsy-Bitsy M4, etc) boards***, you have to copy the file [Adafruit SAMD platform.txt](Packages_Patches/adafruit/hardware/samd/1.6.3) into Adafruit samd directory (~/.arduino15/packages/adafruit/hardware/samd/1.6.3).
|
||||
5. ***To be able to automatically detect and display BOARD_NAME on Adafruit SAMD (Itsy-Bitsy M4, etc) boards***, you have to copy the file [Adafruit SAMD platform.txt](Packages_Patches/adafruit/hardware/samd/1.6.4) into Adafruit samd directory (~/.arduino15/packages/adafruit/hardware/samd/1.6.4).
|
||||
|
||||
Supposing the Adafruit SAMD core version is 1.6.3. This file must be copied into the directory:
|
||||
Supposing the Adafruit SAMD core version is 1.6.4. This file must be copied into the directory:
|
||||
|
||||
- `~/.arduino15/packages/adafruit/hardware/samd/1.6.3/platform.txt`
|
||||
- `~/.arduino15/packages/adafruit/hardware/samd/1.6.4/platform.txt`
|
||||
|
||||
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz
|
||||
This file must be copied into the directory:
|
||||
|
||||
- `~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/platform.txt`
|
||||
|
||||
6. ***To be able to automatically detect and display BOARD_NAME on Seeeduino SAMD (XIAO M0, Wio Terminal, etc) boards***, you have to copy the file [Seeeduino SAMD platform.txt](Packages_Patches/Seeeduino/hardware/samd/1.7.9) into Adafruit samd directory (~/.arduino15/packages/Seeeduino/hardware/samd/1.7.9).
|
||||
6. ***To be able to automatically detect and display BOARD_NAME on Seeeduino SAMD (XIAO M0, Wio Terminal, etc) boards***, you have to copy the file [Seeeduino SAMD platform.txt](Packages_Patches/Seeeduino/hardware/samd/1.8.1) into Adafruit samd directory (~/.arduino15/packages/Seeeduino/hardware/samd/1.8.1).
|
||||
|
||||
Supposing the Seeeduino SAMD core version is 1.7.9. This file must be copied into the directory:
|
||||
Supposing the Seeeduino SAMD core version is 1.8.1. This file must be copied into the directory:
|
||||
|
||||
- `~/.arduino15/packages/Seeeduino/hardware/samd/1.7.9/platform.txt`
|
||||
- `~/.arduino15/packages/Seeeduino/hardware/samd/1.8.1/platform.txt`
|
||||
|
||||
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz
|
||||
This file must be copied into the directory:
|
||||
@@ -212,6 +222,58 @@ theses files must be copied into the corresponding directory:
|
||||
---
|
||||
---
|
||||
|
||||
### HOWTO Fix `Multiple Definitions` Linker Error
|
||||
|
||||
The current library implementation, using xyz-Impl.h instead of standard xyz.cpp, possibly creates certain `Multiple Definitions` Linker error in certain use cases. Although it's simple to just modify several lines of code, either in the library or in the application, the library is adding a separate source directory, named src_cpp, besides the standard src directory.
|
||||
|
||||
To use the old standard cpp way, just
|
||||
|
||||
1. **Rename the h-only src directory into src_h.**
|
||||
2. **Then rename the cpp src_cpp directory into src.**
|
||||
3. Close then reopen the application code in Arduino IDE, etc. to recompile from scratch.
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
### HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)
|
||||
|
||||
Please have a look at [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to have more detailed description and solution of the issue.
|
||||
|
||||
#### 1. ESP32 has 2 ADCs, named ADC1 and ADC2
|
||||
|
||||
#### 2. ESP32 ADCs functions
|
||||
|
||||
- ADC1 controls ADC function for pins **GPIO32-GPIO39**
|
||||
- ADC2 controls ADC function for pins **GPIO0, 2, 4, 12-15, 25-27**
|
||||
|
||||
#### 3.. ESP32 WiFi uses ADC2 for WiFi functions
|
||||
|
||||
Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master/components/driver/adc_common.c#L61)
|
||||
|
||||
> In ADC2, there're two locks used for different cases:
|
||||
> 1. lock shared with app and Wi-Fi:
|
||||
> ESP32:
|
||||
> When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed.
|
||||
> ESP32S2:
|
||||
> The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.
|
||||
>
|
||||
> 2. lock shared between tasks:
|
||||
> when several tasks sharing the ADC2, we want to guarantee
|
||||
> all the requests will be handled.
|
||||
> Since conversions are short (about 31us), app returns the lock very soon,
|
||||
> we use a spinlock to stand there waiting to do conversions one by one.
|
||||
>
|
||||
> adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
|
||||
|
||||
|
||||
- In order to use ADC2 for other functions, we have to **acquire complicated firmware locks and very difficult to do**
|
||||
- So, it's not advisable to use ADC2 with WiFi/BlueTooth (BT/BLE).
|
||||
- Use ADC1, and pins GPIO32-GPIO39
|
||||
- If somehow it's a must to use those pins serviced by ADC2 (**GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27**), use the **fix mentioned at the end** of [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to work with ESP32 WiFi/BlueTooth (BT/BLE).
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
### Examples
|
||||
|
||||
Also see examples:
|
||||
@@ -235,12 +297,12 @@ Please take a look at other examples, as well.
|
||||
```cpp
|
||||
#include "defines.h"
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 // 600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
#include <Ticker.h> // https://github.com/sstaub/Ticker
|
||||
#include <Ticker.h> // https://github.com/sstaub/Ticker
|
||||
|
||||
AsyncHTTPRequest request;
|
||||
|
||||
@@ -442,7 +504,7 @@ AsyncHTTPRequest @ IP : 192.168.2.72
|
||||
|
||||
**************************************
|
||||
abbreviation: EDT
|
||||
client_ip: 216.154.52.212
|
||||
client_ip: aaa.bbb.ccc.ddd
|
||||
datetime: 2020-09-13T18:22:59.555816-04:00
|
||||
day_of_week: 0
|
||||
day_of_year: 257
|
||||
@@ -459,7 +521,7 @@ week_number: 37
|
||||
|
||||
**************************************
|
||||
abbreviation: EDT
|
||||
client_ip: 216.154.52.212
|
||||
client_ip: aaa.bbb.ccc.ddd
|
||||
datetime: 2020-09-13T18:27:57.586325-04:00
|
||||
day_of_week: 0
|
||||
day_of_year: 257
|
||||
@@ -489,7 +551,7 @@ After waiting 3.43 secs more in setup(), connection result is connected. Local I
|
||||
H
|
||||
**************************************
|
||||
abbreviation: EDT
|
||||
client_ip: 216.154.52.212
|
||||
client_ip: aaa.bbb.ccc.ddd
|
||||
datetime: 2020-09-13T19:35:37.951609-04:00
|
||||
day_of_week: 0
|
||||
day_of_year: 257
|
||||
@@ -521,7 +583,7 @@ After waiting 2.35 secs more in setup(), connection result is connected. Local I
|
||||
H
|
||||
**************************************
|
||||
abbreviation: EDT
|
||||
client_ip: 216.154.52.212
|
||||
client_ip: aaa.bbb.ccc.ddd
|
||||
datetime: 2020-09-13T19:37:02.118166-04:00
|
||||
day_of_week: 0
|
||||
day_of_year: 257
|
||||
@@ -539,7 +601,7 @@ week_number: 37
|
||||
HHHHHHHHH HHHHHHHHHH HHHHHHHHHH H
|
||||
**************************************
|
||||
abbreviation: EDT
|
||||
client_ip: 216.154.52.212
|
||||
client_ip: aaa.bbb.ccc.ddd
|
||||
datetime: 2020-09-13T19:42:01.507586-04:00
|
||||
day_of_week: 0
|
||||
day_of_year: 257
|
||||
@@ -570,7 +632,7 @@ HTTP WebServer is @ IP : 192.168.2.81
|
||||
|
||||
**************************************
|
||||
abbreviation: EDT
|
||||
client_ip: 216.154.52.212
|
||||
client_ip: aaa.bbb.ccc.ddd
|
||||
datetime: 2020-09-13T19:56:28.295033-04:00
|
||||
day_of_week: 0
|
||||
day_of_year: 257
|
||||
@@ -690,6 +752,14 @@ Submit issues to: [AsyncHTTPRequest_Generic issues](https://github.com/khoih-pro
|
||||
---
|
||||
---
|
||||
|
||||
### Releases v1.0.2
|
||||
|
||||
1. Make Mutex Lock and delete more reliable and error-proof to prevent random crash.
|
||||
|
||||
### Releases v1.0.1
|
||||
|
||||
1. Restore cpp code besides Impl.h code to use in case of `multiple definition` linker error. Thanks to [Daniel Brunner](https://github.com/0xFEEDC0DE64) to report and make PR in [**Fixed linker errors when included in multiple .cpp files**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/pull/1). See [**HOWTO Fix `Multiple Definitions` Linker Error**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic#HOWTO-Fix-Multiple-Definitions-Linker-Error)
|
||||
|
||||
### Releases v1.0.0
|
||||
|
||||
1. Initial coding to add support to **STM32F/L/H/G/WB/MP1** using built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
@@ -702,16 +772,19 @@ Submit issues to: [AsyncHTTPRequest_Generic issues](https://github.com/khoih-pro
|
||||
|
||||
This library is based on, modified, bug-fixed and improved from:
|
||||
|
||||
1. [Bob Lemaire's asyncHTTPrequest Library](https://github.com/boblemaire/asyncHTTPrequest)
|
||||
1. [Bob Lemaire's **asyncHTTPrequest Library**](https://github.com/boblemaire/asyncHTTPrequest) to use the better **asynchronous** features of these following Async TCP Libraries : ( [`ESPAsyncTCP`](https://github.com/me-no-dev/ESPAsyncTCP), [`AsyncTCP`](https://github.com/me-no-dev/AsyncTCP), and [`STM32AsyncTCP`](https://github.com/philbowles/STM32AsyncTCP) ).
|
||||
|
||||
to use the better **asynchronous** features of these following Async TCP Libraries : ( [`ESPAsyncTCP`](https://github.com/me-no-dev/ESPAsyncTCP), [`AsyncTCP`](https://github.com/me-no-dev/AsyncTCP), and [`STM32AsyncTCP`](https://github.com/philbowles/STM32AsyncTCP) ).
|
||||
2. Thanks to [Daniel Brunner](https://github.com/0xFEEDC0DE64) to report and make PR in [Fixed linker errors when included in multiple .cpp files](https://github.com/khoih-prog/AsyncHTTPRequest_Generic/pull/1) leading to v1.0.1. See [**HOWTO Fix `Multiple Definitions` Linker Error**](https://github.com/khoih-prog/AsyncHTTPRequest_Generic#HOWTO-Fix-Multiple-Definitions-Linker-Error)
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/boblemaire"><img src="https://github.com/boblemaire.png" width="100px;" alt="boblemaire"/><br /><sub><b>⭐️ Bob Lemaire</b></sub></a><br /></td>
|
||||
<td align="center"><a href="https://github.com/0xFEEDC0DE64"><img src="https://github.com/0xFEEDC0DE64.png" width="100px;" alt="0xFEEDC0DE64"/><br /><sub><b>Daniel Brunner</b></sub></a><br /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
### Contributing
|
||||
|
||||
If you want to contribute to this project:
|
||||
|
||||
@@ -17,21 +17,23 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
// Select a test server address
|
||||
char GET_ServerAddress[] = "192.168.2.110/";
|
||||
//char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt";
|
||||
//char GET_ServerAddress[] = "192.168.2.110/";
|
||||
char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt";
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 //600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
@@ -51,7 +53,7 @@ void sendRequest(void)
|
||||
Serial.println("\nSending GET Request to " + String(GET_ServerAddress));
|
||||
|
||||
request.open("GET", GET_ServerAddress);
|
||||
request.setReqHeader("X-CUSTOM-HEADER", "custom_value");
|
||||
//request.setReqHeader("X-CUSTOM-HEADER", "custom_value");
|
||||
request.send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
// Dweet.io POST client. Connects to dweet.io once every ten seconds, sends a POST request and a request body.
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
//************************************************************************************************************
|
||||
//
|
||||
@@ -55,7 +57,7 @@
|
||||
#define _ASYNC_HTTP_LOGLEVEL_ 1
|
||||
|
||||
// 300s = 5 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL 300
|
||||
#define HTTP_REQUEST_INTERVAL 30 //300
|
||||
|
||||
// 10s
|
||||
#define HEARTBEAT_INTERVAL 10
|
||||
@@ -76,6 +78,7 @@ const char* password = "your_pass";
|
||||
|
||||
AsyncHTTPRequest request;
|
||||
Ticker ticker;
|
||||
Ticker ticker1;
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
@@ -105,6 +108,10 @@ void sendRequest()
|
||||
request.open("GET", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
|
||||
request.send();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Can't send request");
|
||||
}
|
||||
}
|
||||
|
||||
void requestCB(void* optParm, AsyncHTTPRequest* request, int readyState)
|
||||
@@ -129,13 +136,6 @@ void setup()
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
if (WiFi.status() == WL_NO_SHIELD)
|
||||
{
|
||||
Serial.println(F("WiFi shield not present"));
|
||||
// don't continue
|
||||
while (true);
|
||||
}
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
Serial.println("Connecting to WiFi SSID: " + String(ssid));
|
||||
@@ -154,7 +154,7 @@ void setup()
|
||||
request.onReadyStateChange(requestCB);
|
||||
ticker.attach(HTTP_REQUEST_INTERVAL, sendRequest);
|
||||
|
||||
ticker.attach(HEARTBEAT_INTERVAL, heartBeatPrint);
|
||||
ticker1.attach(HEARTBEAT_INTERVAL, heartBeatPrint);
|
||||
|
||||
// Send first request now
|
||||
sendRequest();
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
//************************************************************************************************************
|
||||
//
|
||||
@@ -54,8 +56,8 @@
|
||||
#define ASYNC_HTTP_DEBUG_PORT Serial
|
||||
#define _ASYNC_HTTP_LOGLEVEL_ 1
|
||||
|
||||
// 300s = 5 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL 300
|
||||
// 300s = 5 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL 10 //300
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
//************************************************************************************************************
|
||||
//
|
||||
@@ -48,8 +50,8 @@
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 //600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "defines.h"
|
||||
@@ -30,8 +32,8 @@
|
||||
//char GET_ServerAddress[] = "ipv4bot.whatismyipaddress.com/";
|
||||
char GET_ServerAddress[] = "http://worldtimeapi.org/api/timezone/America/Toronto.txt";
|
||||
|
||||
// 600s = 10 minutes to not flooding
|
||||
#define HTTP_REQUEST_INTERVAL_MS 600000
|
||||
// 600s = 10 minutes to not flooding, 10s in testing
|
||||
#define HTTP_REQUEST_INTERVAL_MS 10000 //600000
|
||||
|
||||
#include <AsyncHTTPRequest_Generic.h> // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
/*
|
||||
Currently support
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name":"AsyncHTTPRequest_Generic",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"description":"Simple Async HTTP Request library, supporting GET and POST, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32, ESP8266 and currently STM32 with built-in LAN8742A Ethernet.",
|
||||
"keywords":"async,tcp,http,ESP8266,ESP32,ESPAsyncTCP,AsyncTCP,stm32,ethernet,wifi,lan8742a",
|
||||
"authors": [
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
name=AsyncHTTPRequest_Generic
|
||||
version=1.0.0
|
||||
author=Bob Lemaire,Khoi Hoang
|
||||
version=1.0.2
|
||||
author=Bob Lemaire,Khoi Hoang <khoih.prog@gmail.com>
|
||||
maintainer=Khoi Hoang <khoih.prog@gmail.com>
|
||||
license=MIT
|
||||
sentence=Simple Async HTTP Request library, supporting GET and POST, on top of AsyncTCP libraries, such as AsyncTCP, ESPAsyncTCP, AsyncTCP_STM32, etc.. for ESP32, ESP8266 and currently STM32 with built-in LAN8742A Ethernet.
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef AsyncHTTPRequest_Debug_STM32_H
|
||||
#define AsyncHTTPRequest_Debug_STM32_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ASYNC_HTTP_DEBUG_PORT
|
||||
#define A_DBG_PORT ASYNC_HTTP_DEBUG_PORT
|
||||
@@ -68,4 +69,3 @@
|
||||
#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#endif // AsyncHTTPRequest_Debug_STM32_H
|
||||
|
||||
@@ -17,17 +17,18 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef AsyncHTTPRequest_Generic_h
|
||||
#define AsyncHTTPRequest_Generic_h
|
||||
|
||||
#define AsyncHTTPRequest_Generic_version "1.0.0"
|
||||
#pragma once
|
||||
|
||||
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "1.0.2"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
@@ -43,15 +44,29 @@
|
||||
#define DEBUG_IOTA_HTTP_SET false
|
||||
#endif
|
||||
|
||||
|
||||
// KH add
|
||||
#define SAFE_DELETE(object) if (object) { delete object;}
|
||||
#define SAFE_DELETE_ARRAY(object) if (object) { delete[] object;}
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
// KH mod
|
||||
#define MUTEX_LOCK_NR if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return;}
|
||||
#define MUTEX_LOCK(returnVal) if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return returnVal;}
|
||||
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
@@ -60,6 +75,9 @@
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
|
||||
#include "STM32AsyncTCP.h"
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
@@ -108,9 +126,12 @@ class AsyncHTTPRequest
|
||||
|
||||
~header()
|
||||
{
|
||||
delete[] name;
|
||||
delete[] value;
|
||||
delete next;
|
||||
SAFE_DELETE_ARRAY(name)
|
||||
SAFE_DELETE_ARRAY(value)
|
||||
SAFE_DELETE(next)
|
||||
//delete[] name;
|
||||
//delete[] value;
|
||||
//delete next;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -131,13 +152,13 @@ class AsyncHTTPRequest
|
||||
|
||||
~URL()
|
||||
{
|
||||
delete[] scheme;
|
||||
delete[] user;
|
||||
delete[] pwd;
|
||||
delete[] host;
|
||||
delete[] path;
|
||||
delete[] query;
|
||||
delete[] fragment;
|
||||
SAFE_DELETE_ARRAY(scheme)
|
||||
SAFE_DELETE_ARRAY(user)
|
||||
SAFE_DELETE_ARRAY(pwd)
|
||||
SAFE_DELETE_ARRAY(host)
|
||||
SAFE_DELETE_ARRAY(path)
|
||||
SAFE_DELETE_ARRAY(query)
|
||||
SAFE_DELETE_ARRAY(fragment)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -265,5 +286,3 @@ class AsyncHTTPRequest
|
||||
};
|
||||
|
||||
#include "AsyncHTTPRequest_Impl_Generic.h"
|
||||
|
||||
#endif // AsyncHTTPRequest_Generic_h
|
||||
|
||||
@@ -17,18 +17,17 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef AsyncHTTPRequest_Impl_Generic_h
|
||||
#define AsyncHTTPRequest_Impl_Generic_h
|
||||
|
||||
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::AsyncHTTPRequest(): _readyState(readyStateUnsent), _HTTPcode(0), _chunked(false), _debug(DEBUG_IOTA_HTTP_SET)
|
||||
@@ -48,15 +47,20 @@ AsyncHTTPRequest::~AsyncHTTPRequest()
|
||||
if (_client)
|
||||
_client->close(true);
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
delete[] _connectedHost;
|
||||
|
||||
SAFE_DELETE(_URL)
|
||||
SAFE_DELETE(_headers)
|
||||
SAFE_DELETE(_request)
|
||||
SAFE_DELETE(_response)
|
||||
SAFE_DELETE(_chunks)
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
#ifdef ESP32
|
||||
vSemaphoreDelete(threadLock);
|
||||
// KH add
|
||||
if (threadLock)
|
||||
{
|
||||
vSemaphoreDelete(threadLock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -67,8 +71,9 @@ void AsyncHTTPRequest::setDebug(bool debug)
|
||||
{
|
||||
_debug = true;
|
||||
|
||||
AHTTP_LOGDEBUG3("setDebug(", debug ? "on" : "off", ") version", AsyncHTTPRequest_Generic_version);
|
||||
AHTTP_LOGDEBUG3("setDebug(", debug ? "on" : "off", ") version", ASYNC_HTTP_REQUEST_GENERIC_VERSION);
|
||||
}
|
||||
|
||||
_debug = debug;
|
||||
}
|
||||
|
||||
@@ -90,13 +95,13 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
|
||||
_requestStartTime = millis();
|
||||
|
||||
delete _URL;
|
||||
delete _headers;
|
||||
delete _request;
|
||||
delete _response;
|
||||
delete _chunks;
|
||||
SAFE_DELETE(_URL)
|
||||
SAFE_DELETE(_headers)
|
||||
SAFE_DELETE(_request)
|
||||
SAFE_DELETE(_response)
|
||||
SAFE_DELETE(_chunks)
|
||||
|
||||
_URL = nullptr;
|
||||
_URL = nullptr;
|
||||
_headers = nullptr;
|
||||
_response = nullptr;
|
||||
_request = nullptr;
|
||||
@@ -126,12 +131,20 @@ bool AsyncHTTPRequest::open(const char* method, const char* URL)
|
||||
}
|
||||
|
||||
char* hostName = new char[strlen(_URL->host) + 10];
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
delete[] hostName;
|
||||
_lastActivity = millis();
|
||||
|
||||
if (hostName)
|
||||
{
|
||||
sprintf(hostName, "%s:%d", _URL->host, _URL->port);
|
||||
_addHeader("host", hostName);
|
||||
|
||||
SAFE_DELETE_ARRAY(hostName)
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
return _connect();
|
||||
return _connect();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::onReadyStateChange(readyStateChangeCB cb, void* arg)
|
||||
@@ -153,12 +166,13 @@ bool AsyncHTTPRequest::send()
|
||||
{
|
||||
AHTTP_LOGDEBUG("send()");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
if ( ! _buildRequest())
|
||||
return false;
|
||||
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@@ -169,17 +183,20 @@ bool AsyncHTTPRequest::send(String body)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(String)", body.substring(0, 16).c_str(), ", length =", body.length());
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(body.length()).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_request->write(body);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@@ -190,7 +207,8 @@ bool AsyncHTTPRequest::send(const char* body)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", body, ", length =", strlen(body));
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(strlen(body)).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@@ -202,6 +220,7 @@ bool AsyncHTTPRequest::send(const char* body)
|
||||
|
||||
_request->write(body);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@@ -212,7 +231,8 @@ bool AsyncHTTPRequest::send(const uint8_t* body, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", (char*) body, ", length =", len);
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(len).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@@ -224,6 +244,7 @@ bool AsyncHTTPRequest::send(const uint8_t* body, size_t len)
|
||||
|
||||
_request->write(body, len);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@@ -234,7 +255,8 @@ bool AsyncHTTPRequest::send(xbuf* body, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("send(char)", body->peekString(16).c_str(), ", length =", len);
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(false)
|
||||
|
||||
_addHeader("Content-Length", String(len).c_str());
|
||||
|
||||
if ( ! _buildRequest())
|
||||
@@ -246,6 +268,7 @@ bool AsyncHTTPRequest::send(xbuf* body, size_t len)
|
||||
|
||||
_request->write(body, len);
|
||||
_send();
|
||||
|
||||
_unlock;
|
||||
|
||||
return true;
|
||||
@@ -256,12 +279,15 @@ void AsyncHTTPRequest::abort()
|
||||
{
|
||||
AHTTP_LOGDEBUG("abort()");
|
||||
|
||||
_lock;
|
||||
|
||||
if (! _client)
|
||||
if (! _client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_client->abort();
|
||||
|
||||
_unlock;
|
||||
}
|
||||
//**************************************************************************************************************
|
||||
@@ -281,7 +307,7 @@ String AsyncHTTPRequest::responseText()
|
||||
{
|
||||
AHTTP_LOGDEBUG("responseText()");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(String())
|
||||
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
{
|
||||
@@ -301,12 +327,13 @@ String AsyncHTTPRequest::responseText()
|
||||
|
||||
_HTTPcode = HTTPCODE_TOO_LESS_RAM;
|
||||
_client->abort();
|
||||
|
||||
_unlock;
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
localString = _response->readString(avail);
|
||||
localString = _response->readString(avail);
|
||||
_contentRead += localString.length();
|
||||
|
||||
AHTTP_LOGDEBUG3("responseText(char)", localString.substring(0, 16).c_str(), ", avail =", avail);
|
||||
@@ -321,19 +348,20 @@ size_t AsyncHTTPRequest::responseRead(uint8_t* buf, size_t len)
|
||||
{
|
||||
if ( ! _response || _readyState < readyStateLoading || ! available())
|
||||
{
|
||||
//DEBUG_HTTP("responseRead() no data\r\n");
|
||||
AHTTP_LOGDEBUG("responseRead() no data");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK(0)
|
||||
|
||||
size_t avail = available() > len ? len : available();
|
||||
_response->read(buf, avail);
|
||||
|
||||
AHTTP_LOGDEBUG3("responseRead(char)", (char*) buf, ", avail =", avail);
|
||||
|
||||
_contentRead += avail;
|
||||
|
||||
_unlock;
|
||||
|
||||
return avail;
|
||||
@@ -388,7 +416,7 @@ uint32_t AsyncHTTPRequest::elapsedTime()
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::version()
|
||||
{
|
||||
return String(AsyncHTTPRequest_Generic_version);
|
||||
return String(ASYNC_HTTP_REQUEST_GENERIC_VERSION);
|
||||
}
|
||||
|
||||
/*______________________________________________________________________________________________________________
|
||||
@@ -409,11 +437,22 @@ bool AsyncHTTPRequest::_parseURL(const char* url)
|
||||
//**************************************************************************************************************
|
||||
bool AsyncHTTPRequest::_parseURL(String url)
|
||||
{
|
||||
delete _URL;
|
||||
SAFE_DELETE(_URL)
|
||||
|
||||
int hostBeg = 0;
|
||||
|
||||
_URL = new URL;
|
||||
_URL->scheme = new char[8];
|
||||
|
||||
if (_URL)
|
||||
{
|
||||
_URL->scheme = new char[8];
|
||||
|
||||
if (! (_URL->scheme) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
strcpy(_URL->scheme, "HTTP://");
|
||||
|
||||
if (url.substring(0, 7).equalsIgnoreCase("HTTP://"))
|
||||
@@ -440,6 +479,10 @@ bool AsyncHTTPRequest::_parseURL(String url)
|
||||
}
|
||||
|
||||
_URL->host = new char[hostEnd - hostBeg + 1];
|
||||
|
||||
if (_URL->host == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->host, url.substring(hostBeg, hostEnd).c_str());
|
||||
|
||||
int queryBeg = url.indexOf('?');
|
||||
@@ -448,8 +491,17 @@ bool AsyncHTTPRequest::_parseURL(String url)
|
||||
queryBeg = url.length();
|
||||
|
||||
_URL->path = new char[queryBeg - pathBeg + 1];
|
||||
|
||||
if (_URL->path == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->path, url.substring(pathBeg, queryBeg).c_str());
|
||||
|
||||
_URL->query = new char[url.length() - queryBeg + 1];
|
||||
|
||||
if (_URL->query == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_URL->query, url.substring(queryBeg).c_str());
|
||||
|
||||
AHTTP_LOGDEBUG2("_parseURL(): scheme+host", _URL->scheme, _URL->host);
|
||||
@@ -466,11 +518,18 @@ bool AsyncHTTPRequest::_connect()
|
||||
if ( ! _client)
|
||||
{
|
||||
_client = new AsyncClient();
|
||||
|
||||
if (! _client)
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] _connectedHost;
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
_connectedHost = new char[strlen(_URL->host) + 1];
|
||||
|
||||
if (_connectedHost == nullptr)
|
||||
return false;
|
||||
|
||||
strcpy(_connectedHost, _URL->host);
|
||||
_connectedPort = _URL->port;
|
||||
|
||||
@@ -523,14 +582,21 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
|
||||
// Build the header.
|
||||
if ( ! _request)
|
||||
{
|
||||
_request = new xbuf;
|
||||
|
||||
if ( ! _request)
|
||||
return false;
|
||||
}
|
||||
|
||||
_request->write(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ");
|
||||
_request->write(_URL->path);
|
||||
_request->write(_URL->query);
|
||||
_request->write(" HTTP/1.1\r\n");
|
||||
|
||||
AHTTP_LOGDEBUG3(_HTTPmethod == HTTPmethodGET ? "GET " : "POST ", _URL->path, _URL->query, " HTTP/1.1\r\n" );
|
||||
|
||||
delete _URL;
|
||||
SAFE_DELETE(_URL)
|
||||
|
||||
_URL = nullptr;
|
||||
header* hdr = _headers;
|
||||
@@ -541,10 +607,14 @@ bool AsyncHTTPRequest::_buildRequest()
|
||||
_request->write(':');
|
||||
_request->write(hdr->value);
|
||||
_request->write("\r\n");
|
||||
|
||||
AHTTP_LOGDEBUG3(hdr->name, ":", hdr->value, "\r\n" );
|
||||
|
||||
hdr = hdr->next;
|
||||
}
|
||||
|
||||
delete _headers;
|
||||
SAFE_DELETE(_headers)
|
||||
|
||||
_headers = nullptr;
|
||||
_request->write("\r\n");
|
||||
|
||||
@@ -574,19 +644,26 @@ size_t AsyncHTTPRequest::_send()
|
||||
|
||||
size_t sent = 0;
|
||||
uint8_t* temp = new uint8_t[100];
|
||||
|
||||
if (!temp)
|
||||
return 0;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
size_t chunk = supply < 100 ? supply : 100;
|
||||
supply -= _request->read(temp, chunk);
|
||||
sent += _client->add((char*)temp, chunk);
|
||||
|
||||
supply -= _request->read(temp, chunk);
|
||||
sent += _client->add((char*)temp, chunk);
|
||||
}
|
||||
|
||||
delete temp;
|
||||
// KH, Must be delete [] temp;
|
||||
SAFE_DELETE_ARRAY(temp)
|
||||
|
||||
if (_request->available() == 0)
|
||||
{
|
||||
delete _request;
|
||||
//delete _request;
|
||||
SAFE_DELETE(_request)
|
||||
|
||||
_request = nullptr;
|
||||
}
|
||||
|
||||
@@ -676,10 +753,20 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
{
|
||||
AHTTP_LOGDEBUG("_onConnect handler");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_client = client;
|
||||
_setReadyState(readyStateOpened);
|
||||
|
||||
_response = new xbuf;
|
||||
|
||||
if (!_response)
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_contentLength = 0;
|
||||
_contentRead = 0;
|
||||
_chunked = false;
|
||||
@@ -700,13 +787,14 @@ void AsyncHTTPRequest::_onConnect(AsyncClient* client)
|
||||
}
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
_unlock;
|
||||
}
|
||||
|
||||
//**************************************************************************************************************
|
||||
void AsyncHTTPRequest::_onPoll(AsyncClient* client)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
if (_timeout && (millis() - _lastActivity) > (_timeout * 1000))
|
||||
{
|
||||
@@ -737,7 +825,7 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
{
|
||||
AHTTP_LOGDEBUG("\n_onDisconnect handler");
|
||||
|
||||
_lock;
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
if (_readyState < readyStateOpened)
|
||||
{
|
||||
@@ -749,16 +837,19 @@ void AsyncHTTPRequest::_onDisconnect(AsyncClient* client)
|
||||
_HTTPcode = HTTPCODE_CONNECTION_LOST;
|
||||
}
|
||||
|
||||
delete _client;
|
||||
SAFE_DELETE(_client)
|
||||
|
||||
_client = nullptr;
|
||||
|
||||
delete[] _connectedHost;
|
||||
SAFE_DELETE_ARRAY(_connectedHost)
|
||||
|
||||
_connectedHost = nullptr;
|
||||
|
||||
_connectedPort = -1;
|
||||
_connectedPort = -1;
|
||||
_requestEndTime = millis();
|
||||
_lastActivity = 0;
|
||||
_lastActivity = 0;
|
||||
_setReadyState(readyStateDone);
|
||||
|
||||
_unlock;
|
||||
}
|
||||
|
||||
@@ -767,6 +858,8 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
{
|
||||
AHTTP_LOGDEBUG3("_onData handler", (char*) Vbuf, ", len =", len);
|
||||
|
||||
MUTEX_LOCK_NR
|
||||
|
||||
_lastActivity = millis();
|
||||
|
||||
// Transfer data to xbuf
|
||||
@@ -783,8 +876,12 @@ void AsyncHTTPRequest::_onData(void* Vbuf, size_t len)
|
||||
// if headers not complete, collect them. If still not complete, just return.
|
||||
if (_readyState == readyStateOpened)
|
||||
{
|
||||
if ( ! _collectHeaders())
|
||||
if ( ! _collectHeaders())
|
||||
{
|
||||
_unlock;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's data in the buffer and not Done, advance readyState to Loading.
|
||||
@@ -929,7 +1026,8 @@ void AsyncHTTPRequest::setReqHeader(const char* name, const __FlashStringHelper*
|
||||
{
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(name, _value);
|
||||
delete[] _value;
|
||||
|
||||
SAFE_DELETE_ARRAY(_value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,7 +1038,8 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const char*
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
_addHeader(_name, value);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,8 +1051,9 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, const __Fla
|
||||
char* _name = _charstar(name);
|
||||
char* _value = _charstar(value);
|
||||
_addHeader(_name, _value);
|
||||
delete[] _name;
|
||||
delete[] _value;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
SAFE_DELETE_ARRAY(_value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,7 +1064,8 @@ void AsyncHTTPRequest::setReqHeader(const __FlashStringHelper *name, int32_t val
|
||||
{
|
||||
char* _name = _charstar(name);
|
||||
setReqHeader(_name, String(value).c_str());
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1055,7 +1156,8 @@ char* AsyncHTTPRequest::respHeaderValue(const __FlashStringHelper *name)
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
|
||||
if ( ! hdr)
|
||||
return nullptr;
|
||||
@@ -1071,7 +1173,8 @@ bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
|
||||
char* _name = _charstar(name);
|
||||
header* hdr = _getHeader(_name);
|
||||
delete[] _name;
|
||||
|
||||
SAFE_DELETE_ARRAY(_name)
|
||||
|
||||
if ( ! hdr)
|
||||
return false;
|
||||
@@ -1084,7 +1187,8 @@ bool AsyncHTTPRequest::respHeaderExists(const __FlashStringHelper *name)
|
||||
//**************************************************************************************************************
|
||||
String AsyncHTTPRequest::headers()
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(String())
|
||||
|
||||
String _response = "";
|
||||
header* hdr = _headers;
|
||||
|
||||
@@ -1098,6 +1202,7 @@ String AsyncHTTPRequest::headers()
|
||||
}
|
||||
|
||||
_response += "\r\n";
|
||||
|
||||
_unlock;
|
||||
|
||||
return _response;
|
||||
@@ -1106,17 +1211,19 @@ String AsyncHTTPRequest::headers()
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const char* value)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = (header*) &_headers;
|
||||
|
||||
while (hdr->next)
|
||||
{
|
||||
if (strcasecmp(name, hdr->next->name) == 0)
|
||||
{
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
oldHdr->next = nullptr;
|
||||
delete oldHdr;
|
||||
header* oldHdr = hdr->next;
|
||||
hdr->next = hdr->next->next;
|
||||
oldHdr->next = nullptr;
|
||||
|
||||
SAFE_DELETE(oldHdr)
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1125,10 +1232,37 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const
|
||||
}
|
||||
|
||||
hdr->next = new header;
|
||||
hdr->next->name = new char[strlen(name) + 1];
|
||||
strcpy(hdr->next->name, name);
|
||||
hdr->next->value = new char[strlen(value) + 1];
|
||||
strcpy(hdr->next->value, value);
|
||||
|
||||
if (hdr->next)
|
||||
{
|
||||
hdr->next->name = new char[strlen(name) + 1];
|
||||
|
||||
if (hdr->next->name)
|
||||
strcpy(hdr->next->name, name);
|
||||
else
|
||||
{
|
||||
SAFE_DELETE(hdr->next)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
hdr->next->value = new char[strlen(value) + 1];
|
||||
|
||||
if (hdr->next->value)
|
||||
strcpy(hdr->next->value, value);
|
||||
else
|
||||
{
|
||||
SAFE_DELETE_ARRAY(hdr->next->name)
|
||||
SAFE_DELETE(hdr->next)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_unlock;
|
||||
|
||||
return hdr->next;
|
||||
@@ -1137,7 +1271,8 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_addHeader(const char* name, const
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@@ -1156,7 +1291,8 @@ AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(const char* name)
|
||||
//**************************************************************************************************************
|
||||
AsyncHTTPRequest::header* AsyncHTTPRequest::_getHeader(int ndx)
|
||||
{
|
||||
_lock;
|
||||
MUTEX_LOCK(nullptr)
|
||||
|
||||
header* hdr = _headers;
|
||||
|
||||
while (hdr)
|
||||
@@ -1181,11 +1317,14 @@ char* AsyncHTTPRequest::_charstar(const __FlashStringHelper * str)
|
||||
return nullptr;
|
||||
|
||||
char* ptr = new char[strlen_P((PGM_P)str) + 1];
|
||||
strcpy_P(ptr, (PGM_P)str);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
strcpy_P(ptr, (PGM_P)str);
|
||||
}
|
||||
|
||||
// Rturn good ptr or nullptr
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // AsyncHTTPRequest_Impl_Generic_h
|
||||
|
||||
+3
-5
@@ -17,11 +17,13 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
@@ -44,9 +46,6 @@
|
||||
********************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#ifndef xbuf_h
|
||||
#define xbuf_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
struct xseg
|
||||
@@ -150,4 +149,3 @@ class xbuf: public Print
|
||||
|
||||
#include "utility/xbuf_Impl.h"
|
||||
|
||||
#endif // xbuf_h
|
||||
|
||||
+11
-7
@@ -17,17 +17,16 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.0
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#ifndef xbuf_Impl_h
|
||||
#define xbuf_Impl_h
|
||||
|
||||
//#include "utility/xbuf.h"
|
||||
#pragma once
|
||||
|
||||
xbuf::xbuf(const uint16_t segSize) : _head(nullptr), _tail(nullptr), _used(0), _free(0), _offset(0)
|
||||
{
|
||||
@@ -363,14 +362,20 @@ void xbuf::addSeg()
|
||||
if (_tail)
|
||||
{
|
||||
_tail->next = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
|
||||
// KH, Must check NULL here
|
||||
_tail = _tail->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// KH, Must check NULL here
|
||||
_tail = _head = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
}
|
||||
|
||||
_tail->next = nullptr;
|
||||
// KH, Must check NULL here
|
||||
if (_tail)
|
||||
_tail->next = nullptr;
|
||||
|
||||
_free += _segSize;
|
||||
}
|
||||
|
||||
@@ -392,4 +397,3 @@ void xbuf::remSeg()
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
#endif // xbuf_Impl_h
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Debug_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ASYNC_HTTP_DEBUG_PORT
|
||||
#define A_DBG_PORT ASYNC_HTTP_DEBUG_PORT
|
||||
#else
|
||||
#define A_DBG_PORT Serial
|
||||
#endif
|
||||
|
||||
// Change _ASYNC_HTTP_LOGLEVEL_ to set tracing and logging verbosity
|
||||
// 0: DISABLED: no logging
|
||||
// 1: ERROR: errors
|
||||
// 2: WARN: errors and warnings
|
||||
// 3: INFO: errors, warnings and informational (default)
|
||||
// 4: DEBUG: errors, warnings, informational and debug
|
||||
|
||||
#ifndef _ASYNC_HTTP_LOGLEVEL_
|
||||
#define _ASYNC_HTTP_LOGLEVEL_ 0
|
||||
#endif
|
||||
|
||||
#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,287 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "1.0.2"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "AsyncHTTPRequest_Debug_Generic.h"
|
||||
|
||||
#ifndef DEBUG_IOTA_PORT
|
||||
#define DEBUG_IOTA_PORT Serial
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_IOTA_HTTP
|
||||
#define DEBUG_IOTA_HTTP_SET true
|
||||
#else
|
||||
#define DEBUG_IOTA_HTTP_SET false
|
||||
#endif
|
||||
|
||||
|
||||
// KH add
|
||||
#define SAFE_DELETE(object) if (object) { delete object;}
|
||||
#define SAFE_DELETE_ARRAY(object) if (object) { delete[] object;}
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
// KH mod
|
||||
#define MUTEX_LOCK_NR if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return;}
|
||||
#define MUTEX_LOCK(returnVal) if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return returnVal;}
|
||||
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
#elif ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
|
||||
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
|
||||
#include "STM32AsyncTCP.h"
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
#endif
|
||||
|
||||
#include <pgmspace.h>
|
||||
#include <utility/xbuf.h>
|
||||
|
||||
#define DEBUG_HTTP(format,...) if(_debug){\
|
||||
DEBUG_IOTA_PORT.printf("Debug(%3ld): ", millis()-_requestStartTime);\
|
||||
DEBUG_IOTA_PORT.printf_P(PSTR(format),##__VA_ARGS__);}
|
||||
|
||||
#define DEFAULT_RX_TIMEOUT 3 // Seconds for timeout
|
||||
|
||||
#define HTTPCODE_CONNECTION_REFUSED (-1)
|
||||
#define HTTPCODE_SEND_HEADER_FAILED (-2)
|
||||
#define HTTPCODE_SEND_PAYLOAD_FAILED (-3)
|
||||
#define HTTPCODE_NOT_CONNECTED (-4)
|
||||
#define HTTPCODE_CONNECTION_LOST (-5)
|
||||
#define HTTPCODE_NO_STREAM (-6)
|
||||
#define HTTPCODE_NO_HTTP_SERVER (-7)
|
||||
#define HTTPCODE_TOO_LESS_RAM (-8)
|
||||
#define HTTPCODE_ENCODING (-9)
|
||||
#define HTTPCODE_STREAM_WRITE (-10)
|
||||
#define HTTPCODE_TIMEOUT (-11)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
readyStateUnsent = 0, // Client created, open not yet called
|
||||
readyStateOpened = 1, // open() has been called, connected
|
||||
readyStateHdrsRecvd = 2, // send() called, response headers available
|
||||
readyStateLoading = 3, // receiving, partial data available
|
||||
readyStateDone = 4 // Request complete, all data available.
|
||||
} reqStates;
|
||||
|
||||
class AsyncHTTPRequest
|
||||
{
|
||||
struct header
|
||||
{
|
||||
header* next;
|
||||
char* name;
|
||||
char* value;
|
||||
|
||||
header(): next(nullptr), name(nullptr), value(nullptr)
|
||||
{};
|
||||
|
||||
~header()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(name)
|
||||
SAFE_DELETE_ARRAY(value)
|
||||
SAFE_DELETE(next)
|
||||
//delete[] name;
|
||||
//delete[] value;
|
||||
//delete next;
|
||||
}
|
||||
};
|
||||
|
||||
struct URL
|
||||
{
|
||||
char* scheme;
|
||||
char* user;
|
||||
char* pwd;
|
||||
char* host;
|
||||
int port;
|
||||
char* path;
|
||||
char* query;
|
||||
char* fragment;
|
||||
|
||||
URL(): scheme(nullptr), user(nullptr), pwd(nullptr), host(nullptr),
|
||||
port(80), path(nullptr), query(nullptr), fragment(nullptr)
|
||||
{};
|
||||
|
||||
~URL()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(scheme)
|
||||
SAFE_DELETE_ARRAY(user)
|
||||
SAFE_DELETE_ARRAY(pwd)
|
||||
SAFE_DELETE_ARRAY(host)
|
||||
SAFE_DELETE_ARRAY(path)
|
||||
SAFE_DELETE_ARRAY(query)
|
||||
SAFE_DELETE_ARRAY(fragment)
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(void*, AsyncHTTPRequest*, int readyState)> readyStateChangeCB;
|
||||
typedef std::function<void(void*, AsyncHTTPRequest*, size_t available)> onDataCB;
|
||||
|
||||
public:
|
||||
AsyncHTTPRequest();
|
||||
~AsyncHTTPRequest();
|
||||
|
||||
|
||||
//External functions in typical order of use:
|
||||
//__________________________________________________________________________________________________________*/
|
||||
void setDebug(bool); // Turn debug message on/off
|
||||
bool debug(); // is debug on or off?
|
||||
|
||||
bool open(const char* /*GET/POST*/, const char* URL); // Initiate a request
|
||||
void onReadyStateChange(readyStateChangeCB, void* arg = 0); // Optional event handler for ready state change
|
||||
// or you can simply poll readyState()
|
||||
void setTimeout(int); // overide default timeout (seconds)
|
||||
|
||||
void setReqHeader(const char* name, const char* value); // add a request header
|
||||
void setReqHeader(const char* name, int32_t value); // overload to use integer value
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
void setReqHeader(const char* name, const __FlashStringHelper* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, const char* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, const __FlashStringHelper* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, int32_t value);
|
||||
#endif
|
||||
|
||||
bool send(); // Send the request (GET)
|
||||
bool send(String body); // Send the request (POST)
|
||||
bool send(const char* body); // Send the request (POST)
|
||||
bool send(const uint8_t* buffer, size_t len); // Send the request (POST) (binary data?)
|
||||
bool send(xbuf* body, size_t len); // Send the request (POST) data in an xbuf
|
||||
void abort(); // Abort the current operation
|
||||
|
||||
reqStates readyState(); // Return the ready state
|
||||
|
||||
int respHeaderCount(); // Retrieve count of response headers
|
||||
char* respHeaderName(int index); // Return header name by index
|
||||
char* respHeaderValue(int index); // Return header value by index
|
||||
char* respHeaderValue(const char* name); // Return header value by name
|
||||
|
||||
bool respHeaderExists(const char* name); // Does header exist by name?
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
char* respHeaderValue(const __FlashStringHelper *name);
|
||||
bool respHeaderExists(const __FlashStringHelper *name);
|
||||
#endif
|
||||
|
||||
String headers(); // Return all headers as String
|
||||
|
||||
void onData(onDataCB, void* arg = 0); // Notify when min data is available
|
||||
size_t available(); // response available
|
||||
size_t responseLength(); // indicated response length or sum of chunks to date
|
||||
int responseHTTPcode(); // HTTP response code or (negative) error code
|
||||
String responseText(); // response (whole* or partial* as string)
|
||||
size_t responseRead(uint8_t* buffer, size_t len); // Read response into buffer
|
||||
uint32_t elapsedTime(); // Elapsed time of in progress transaction or last completed (ms)
|
||||
String version(); // Version of AsyncHTTPRequest
|
||||
//___________________________________________________________________________________________________________________________________
|
||||
|
||||
private:
|
||||
|
||||
enum {HTTPmethodGET, HTTPmethodPOST} _HTTPmethod;
|
||||
|
||||
reqStates _readyState;
|
||||
|
||||
int16_t _HTTPcode; // HTTP response code or (negative) exception code
|
||||
bool _chunked; // Processing chunked response
|
||||
bool _debug; // Debug state
|
||||
uint32_t _timeout; // Default or user overide RxTimeout in seconds
|
||||
uint32_t _lastActivity; // Time of last activity
|
||||
uint32_t _requestStartTime; // Time last open() issued
|
||||
uint32_t _requestEndTime; // Time of last disconnect
|
||||
URL* _URL; // -> URL data structure
|
||||
char* _connectedHost; // Host when connected
|
||||
int _connectedPort; // Port when connected
|
||||
AsyncClient* _client; // ESPAsyncTCP AsyncClient instance
|
||||
size_t _contentLength; // content-length header value or sum of chunk headers
|
||||
size_t _contentRead; // number of bytes retrieved by user since last open()
|
||||
readyStateChangeCB _readyStateChangeCB; // optional callback for readyState change
|
||||
void* _readyStateChangeCBarg; // associated user argument
|
||||
onDataCB _onDataCB; // optional callback when data received
|
||||
void* _onDataCBarg; // associated user argument
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t threadLock;
|
||||
#endif
|
||||
|
||||
// request and response String buffers and header list (same queue for request and response).
|
||||
|
||||
xbuf* _request; // Tx data buffer
|
||||
xbuf* _response; // Rx data buffer for headers
|
||||
xbuf* _chunks; // First stage for chunked response
|
||||
header* _headers; // request or (readyState > readyStateHdrsRcvd) response headers
|
||||
|
||||
// Protected functions
|
||||
|
||||
header* _addHeader(const char*, const char*);
|
||||
header* _getHeader(const char*);
|
||||
header* _getHeader(int);
|
||||
bool _buildRequest();
|
||||
bool _parseURL(const char*);
|
||||
bool _parseURL(String);
|
||||
void _processChunks();
|
||||
bool _connect();
|
||||
size_t _send();
|
||||
void _setReadyState(reqStates);
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
char* _charstar(const __FlashStringHelper *str);
|
||||
#endif
|
||||
|
||||
// callbacks
|
||||
|
||||
void _onConnect(AsyncClient*);
|
||||
void _onDisconnect(AsyncClient*);
|
||||
void _onData(void*, size_t);
|
||||
void _onError(AsyncClient*, int8_t);
|
||||
void _onPoll(AsyncClient*);
|
||||
bool _collectHeaders();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
/****************************************************************************************************************************
|
||||
xbuf_Impl.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#include "utility/xbuf.h"
|
||||
|
||||
xbuf::xbuf(const uint16_t segSize) : _head(nullptr), _tail(nullptr), _used(0), _free(0), _offset(0)
|
||||
{
|
||||
_segSize = (segSize + 3) & -4;//((segSize + 3) >> 2) << 2;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
xbuf::~xbuf()
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const uint8_t byte)
|
||||
{
|
||||
return write((uint8_t*) &byte, 1);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const char* buf)
|
||||
{
|
||||
return write((uint8_t*)buf, strlen(buf));
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(String string)
|
||||
{
|
||||
return write((uint8_t*)string.c_str(), string.length());
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t supply = len;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
if (!_free)
|
||||
{
|
||||
addSeg();
|
||||
}
|
||||
|
||||
size_t demand = _free < supply ? _free : supply;
|
||||
memcpy(_tail->data + ((_offset + _used) % _segSize), buf + (len - supply), demand);
|
||||
_free -= demand;
|
||||
_used += demand;
|
||||
supply -= demand;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(xbuf* buf, const size_t len)
|
||||
{
|
||||
size_t supply = len;
|
||||
|
||||
if (supply > buf->available())
|
||||
{
|
||||
supply = buf->available();
|
||||
}
|
||||
|
||||
size_t read = 0;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
if (!_free)
|
||||
{
|
||||
addSeg();
|
||||
}
|
||||
|
||||
size_t demand = _free < supply ? _free : supply;
|
||||
read += buf->read(_tail->data + ((_offset + _used) % _segSize), demand);
|
||||
_free -= demand;
|
||||
_used += demand;
|
||||
supply -= demand;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
uint8_t xbuf::read()
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
read((uint8_t*) &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
uint8_t xbuf::peek()
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
peek((uint8_t*) &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::read(uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t read = 0;
|
||||
|
||||
while (read < len && _used)
|
||||
{
|
||||
size_t supply = (_offset + _used) > _segSize ? _segSize - _offset : _used;
|
||||
size_t demand = len - read;
|
||||
size_t chunk = supply < demand ? supply : demand;
|
||||
memcpy(buf + read, _head->data + _offset, chunk);
|
||||
_offset += chunk;
|
||||
_used -= chunk;
|
||||
read += chunk;
|
||||
|
||||
if (_offset == _segSize)
|
||||
{
|
||||
remSeg();
|
||||
_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! _used)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::peek(uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t read = 0;
|
||||
xseg* seg = _head;
|
||||
size_t offset = _offset;
|
||||
size_t used = _used;
|
||||
|
||||
while (read < len && used)
|
||||
{
|
||||
size_t supply = (offset + used) > _segSize ? _segSize - offset : used;
|
||||
size_t demand = len - read;
|
||||
size_t chunk = supply < demand ? supply : demand;
|
||||
|
||||
memcpy(buf + read, seg->data + offset, chunk);
|
||||
|
||||
offset += chunk;
|
||||
used -= chunk;
|
||||
read += chunk;
|
||||
|
||||
if (offset == _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::available()
|
||||
{
|
||||
return _used;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
int xbuf::indexOf(const char target, const size_t begin)
|
||||
{
|
||||
char targetstr[2] = " ";
|
||||
targetstr[0] = target;
|
||||
|
||||
return indexOf(targetstr, begin);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
int xbuf::indexOf(const char* target, const size_t begin)
|
||||
{
|
||||
size_t targetLen = strlen(target);
|
||||
|
||||
if (targetLen > _segSize || targetLen > _used)
|
||||
return -1;
|
||||
|
||||
size_t searchPos = _offset + begin;
|
||||
size_t searchEnd = _offset + _used - targetLen;
|
||||
|
||||
if (searchPos > searchEnd)
|
||||
return -1;
|
||||
|
||||
size_t searchSeg = searchPos / _segSize;
|
||||
xseg* seg = _head;
|
||||
|
||||
while (searchSeg)
|
||||
{
|
||||
seg = seg->next;
|
||||
searchSeg --;
|
||||
}
|
||||
|
||||
size_t segPos = searchPos % _segSize;
|
||||
|
||||
while (searchPos <= searchEnd)
|
||||
{
|
||||
size_t compLen = targetLen;
|
||||
|
||||
if (compLen <= (_segSize - segPos))
|
||||
{
|
||||
if (memcmp(target, seg->data + segPos, compLen) == 0)
|
||||
{
|
||||
return searchPos - _offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t compLen = _segSize - segPos;
|
||||
|
||||
if (memcmp(target, seg->data + segPos, compLen) == 0)
|
||||
{
|
||||
compLen = targetLen - compLen;
|
||||
|
||||
if (memcmp(target + targetLen - compLen, seg->next->data, compLen) == 0)
|
||||
{
|
||||
return searchPos - _offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchPos++;
|
||||
segPos++;
|
||||
|
||||
if (segPos == _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
segPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readStringUntil(const char target)
|
||||
{
|
||||
return readString(indexOf(target) + 1);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readStringUntil(const char* target)
|
||||
{
|
||||
int index = indexOf(target);
|
||||
|
||||
if (index < 0)
|
||||
return String();
|
||||
|
||||
return readString(index + strlen(target));
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readString(int endPos)
|
||||
{
|
||||
String result;
|
||||
|
||||
if ( ! result.reserve(endPos + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (endPos > _used)
|
||||
{
|
||||
endPos = _used;
|
||||
}
|
||||
|
||||
if (endPos > 0 && result.reserve(endPos + 1))
|
||||
{
|
||||
while (endPos--)
|
||||
{
|
||||
result += (char)_head->data[_offset++];
|
||||
_used--;
|
||||
|
||||
if (_offset >= _segSize)
|
||||
{
|
||||
remSeg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::peekString(int endPos)
|
||||
{
|
||||
String result;
|
||||
|
||||
xseg* seg = _head;
|
||||
size_t offset = _offset;
|
||||
|
||||
if (endPos > _used)
|
||||
{
|
||||
endPos = _used;
|
||||
}
|
||||
|
||||
if (endPos > 0 && result.reserve(endPos + 1))
|
||||
{
|
||||
while (endPos--)
|
||||
{
|
||||
result += (char)seg->data[offset++];
|
||||
|
||||
if ( offset >= _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::flush()
|
||||
{
|
||||
while (_head)
|
||||
remSeg();
|
||||
|
||||
_tail = nullptr;
|
||||
_offset = 0;
|
||||
_used = 0;
|
||||
_free = 0;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::addSeg()
|
||||
{
|
||||
if (_tail)
|
||||
{
|
||||
_tail->next = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
|
||||
// KH, Must check NULL here
|
||||
_tail = _tail->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// KH, Must check NULL here
|
||||
_tail = _head = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
}
|
||||
|
||||
// KH, Must check NULL here
|
||||
if (_tail)
|
||||
_tail->next = nullptr;
|
||||
|
||||
_free += _segSize;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::remSeg()
|
||||
{
|
||||
if (_head)
|
||||
{
|
||||
xseg *next = _head->next;
|
||||
delete[] (uint32_t*) _head;
|
||||
_head = next;
|
||||
|
||||
if ( ! _head)
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/****************************************************************************************************************************
|
||||
xbuf.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
xbuf is a dynamic buffering system that supports reading and writing much like cbuf.
|
||||
The class has it's own provision for writing from buffers, Strings and other xbufs
|
||||
as well as the inherited Print functions.
|
||||
Rather than use a large contiguous heap allocation, xbuf uses a linked chain of segments
|
||||
to dynamically grow and shrink with the contents.
|
||||
There are other benefits as well to using smaller heap allocation units:
|
||||
1) A buffer can work fine in a fragmented heap environment (admittedly contributing to it)
|
||||
2) xbuf contents can be copied from one buffer to another without the need for
|
||||
2x heap during the copy.
|
||||
The segment size defaults to 64 but can be dynamically set in the constructor at creation.
|
||||
The inclusion of indexOf and read/peek until functions make it useful for handling
|
||||
data streams like HTTP, and in fact is why it was created.
|
||||
|
||||
NOTE: The size of the indexOf() search string is limited to the segment size.
|
||||
It could be extended but didn't seem to be a practical consideration.
|
||||
|
||||
********************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
struct xseg
|
||||
{
|
||||
xseg *next;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
class xbuf: public Print
|
||||
{
|
||||
public:
|
||||
|
||||
xbuf(const uint16_t segSize = 64);
|
||||
virtual ~xbuf();
|
||||
|
||||
size_t write(const uint8_t);
|
||||
size_t write(const char*);
|
||||
size_t write(const uint8_t*, const size_t);
|
||||
size_t write(xbuf*, const size_t);
|
||||
size_t write(String);
|
||||
size_t available();
|
||||
int indexOf(const char, const size_t begin = 0);
|
||||
int indexOf(const char*, const size_t begin = 0);
|
||||
uint8_t read();
|
||||
size_t read(uint8_t*, size_t);
|
||||
String readStringUntil(const char);
|
||||
String readStringUntil(const char*);
|
||||
String readString(int);
|
||||
|
||||
String readString()
|
||||
{
|
||||
return readString(available());
|
||||
}
|
||||
|
||||
void flush();
|
||||
|
||||
uint8_t peek();
|
||||
size_t peek(uint8_t*, const size_t);
|
||||
|
||||
String peekStringUntil(const char target)
|
||||
{
|
||||
return peekString(indexOf(target, 0));
|
||||
}
|
||||
|
||||
String peekStringUntil(const char* target)
|
||||
{
|
||||
return peekString(indexOf(target, 0));
|
||||
}
|
||||
|
||||
String peekString()
|
||||
{
|
||||
return peekString(_used);
|
||||
}
|
||||
|
||||
String peekString(int);
|
||||
|
||||
/* In addition to the above functions,
|
||||
the following inherited functions from the Print class are available.
|
||||
|
||||
size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
size_t printf_P(PGM_P format, ...) __attribute__((format(printf, 2, 3)));
|
||||
size_t print(const __FlashStringHelper *);
|
||||
size_t print(const String &);
|
||||
size_t print(const char[]);
|
||||
size_t print(char);
|
||||
size_t print(unsigned char, int = DEC);
|
||||
size_t print(int, int = DEC);
|
||||
size_t print(unsigned int, int = DEC);
|
||||
size_t print(long, int = DEC);
|
||||
size_t print(unsigned long, int = DEC);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(const Printable&);
|
||||
|
||||
size_t println(const __FlashStringHelper *);
|
||||
size_t println(const String &s);
|
||||
size_t println(const char[]);
|
||||
size_t println(char);
|
||||
size_t println(unsigned char, int = DEC);
|
||||
size_t println(int, int = DEC);
|
||||
size_t println(unsigned int, int = DEC);
|
||||
size_t println(long, int = DEC);
|
||||
size_t println(unsigned long, int = DEC);
|
||||
size_t println(double, int = 2);
|
||||
size_t println(const Printable&);
|
||||
size_t println(void);
|
||||
*/
|
||||
|
||||
protected:
|
||||
|
||||
xseg *_head;
|
||||
xseg *_tail;
|
||||
uint16_t _used;
|
||||
uint16_t _free;
|
||||
uint16_t _offset;
|
||||
uint16_t _segSize;
|
||||
|
||||
void addSeg();
|
||||
void remSeg();
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Debug_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ASYNC_HTTP_DEBUG_PORT
|
||||
#define A_DBG_PORT ASYNC_HTTP_DEBUG_PORT
|
||||
#else
|
||||
#define A_DBG_PORT Serial
|
||||
#endif
|
||||
|
||||
// Change _ASYNC_HTTP_LOGLEVEL_ to set tracing and logging verbosity
|
||||
// 0: DISABLED: no logging
|
||||
// 1: ERROR: errors
|
||||
// 2: WARN: errors and warnings
|
||||
// 3: INFO: errors, warnings and informational (default)
|
||||
// 4: DEBUG: errors, warnings, informational and debug
|
||||
|
||||
#ifndef _ASYNC_HTTP_LOGLEVEL_
|
||||
#define _ASYNC_HTTP_LOGLEVEL_ 0
|
||||
#endif
|
||||
|
||||
#define AHTTP_LOGERROR(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGERROR0(x) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGERROR1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGERROR2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGERROR3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>0) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#define AHTTP_LOGWARN(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGWARN0(x) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGWARN1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGWARN2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGWARN3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>1) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#define AHTTP_LOGINFO(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGINFO0(x) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGINFO1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGINFO2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGINFO3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>2) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
#define AHTTP_LOGDEBUG(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.println(x); }
|
||||
#define AHTTP_LOGDEBUG0(x) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print(x); }
|
||||
#define AHTTP_LOGDEBUG1(x,y) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.println(y); }
|
||||
#define AHTTP_LOGDEBUG2(x,y,z) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.println(z); }
|
||||
#define AHTTP_LOGDEBUG3(x,y,z,w) if(_ASYNC_HTTP_LOGLEVEL_>3) { A_DBG_PORT.print("[AHTTP] "); A_DBG_PORT.print(x); A_DBG_PORT.print(" "); A_DBG_PORT.print(y); A_DBG_PORT.print(" "); A_DBG_PORT.print(z); A_DBG_PORT.print(" "); A_DBG_PORT.println(w); }
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/****************************************************************************************************************************
|
||||
AsyncHTTPRequest_Generic.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ASYNC_HTTP_REQUEST_GENERIC_VERSION "1.0.2"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "AsyncHTTPRequest_Debug_Generic.h"
|
||||
|
||||
#ifndef DEBUG_IOTA_PORT
|
||||
#define DEBUG_IOTA_PORT Serial
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_IOTA_HTTP
|
||||
#define DEBUG_IOTA_HTTP_SET true
|
||||
#else
|
||||
#define DEBUG_IOTA_HTTP_SET false
|
||||
#endif
|
||||
|
||||
|
||||
// KH add
|
||||
#define SAFE_DELETE(object) if (object) { delete object;}
|
||||
#define SAFE_DELETE_ARRAY(object) if (object) { delete[] object;}
|
||||
|
||||
#if ESP32
|
||||
|
||||
#include <AsyncTCP.h>
|
||||
|
||||
// KH mod
|
||||
#define MUTEX_LOCK_NR if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return;}
|
||||
#define MUTEX_LOCK(returnVal) if (xSemaphoreTakeRecursive(threadLock,portMAX_DELAY) != pdTRUE) { return returnVal;}
|
||||
|
||||
#define _lock xSemaphoreTakeRecursive(threadLock,portMAX_DELAY)
|
||||
#define _unlock xSemaphoreGiveRecursive(threadLock)
|
||||
|
||||
#elif ESP8266
|
||||
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
#elif ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
|
||||
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
|
||||
defined(STM32WB) || defined(STM32MP1) )
|
||||
|
||||
#include "STM32AsyncTCP.h"
|
||||
|
||||
#define MUTEX_LOCK_NR
|
||||
#define MUTEX_LOCK(returnVal)
|
||||
#define _lock
|
||||
#define _unlock
|
||||
|
||||
#endif
|
||||
|
||||
#include <pgmspace.h>
|
||||
#include <utility/xbuf.h>
|
||||
|
||||
#define DEBUG_HTTP(format,...) if(_debug){\
|
||||
DEBUG_IOTA_PORT.printf("Debug(%3ld): ", millis()-_requestStartTime);\
|
||||
DEBUG_IOTA_PORT.printf_P(PSTR(format),##__VA_ARGS__);}
|
||||
|
||||
#define DEFAULT_RX_TIMEOUT 3 // Seconds for timeout
|
||||
|
||||
#define HTTPCODE_CONNECTION_REFUSED (-1)
|
||||
#define HTTPCODE_SEND_HEADER_FAILED (-2)
|
||||
#define HTTPCODE_SEND_PAYLOAD_FAILED (-3)
|
||||
#define HTTPCODE_NOT_CONNECTED (-4)
|
||||
#define HTTPCODE_CONNECTION_LOST (-5)
|
||||
#define HTTPCODE_NO_STREAM (-6)
|
||||
#define HTTPCODE_NO_HTTP_SERVER (-7)
|
||||
#define HTTPCODE_TOO_LESS_RAM (-8)
|
||||
#define HTTPCODE_ENCODING (-9)
|
||||
#define HTTPCODE_STREAM_WRITE (-10)
|
||||
#define HTTPCODE_TIMEOUT (-11)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
readyStateUnsent = 0, // Client created, open not yet called
|
||||
readyStateOpened = 1, // open() has been called, connected
|
||||
readyStateHdrsRecvd = 2, // send() called, response headers available
|
||||
readyStateLoading = 3, // receiving, partial data available
|
||||
readyStateDone = 4 // Request complete, all data available.
|
||||
} reqStates;
|
||||
|
||||
class AsyncHTTPRequest
|
||||
{
|
||||
struct header
|
||||
{
|
||||
header* next;
|
||||
char* name;
|
||||
char* value;
|
||||
|
||||
header(): next(nullptr), name(nullptr), value(nullptr)
|
||||
{};
|
||||
|
||||
~header()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(name)
|
||||
SAFE_DELETE_ARRAY(value)
|
||||
SAFE_DELETE(next)
|
||||
//delete[] name;
|
||||
//delete[] value;
|
||||
//delete next;
|
||||
}
|
||||
};
|
||||
|
||||
struct URL
|
||||
{
|
||||
char* scheme;
|
||||
char* user;
|
||||
char* pwd;
|
||||
char* host;
|
||||
int port;
|
||||
char* path;
|
||||
char* query;
|
||||
char* fragment;
|
||||
|
||||
URL(): scheme(nullptr), user(nullptr), pwd(nullptr), host(nullptr),
|
||||
port(80), path(nullptr), query(nullptr), fragment(nullptr)
|
||||
{};
|
||||
|
||||
~URL()
|
||||
{
|
||||
SAFE_DELETE_ARRAY(scheme)
|
||||
SAFE_DELETE_ARRAY(user)
|
||||
SAFE_DELETE_ARRAY(pwd)
|
||||
SAFE_DELETE_ARRAY(host)
|
||||
SAFE_DELETE_ARRAY(path)
|
||||
SAFE_DELETE_ARRAY(query)
|
||||
SAFE_DELETE_ARRAY(fragment)
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(void*, AsyncHTTPRequest*, int readyState)> readyStateChangeCB;
|
||||
typedef std::function<void(void*, AsyncHTTPRequest*, size_t available)> onDataCB;
|
||||
|
||||
public:
|
||||
AsyncHTTPRequest();
|
||||
~AsyncHTTPRequest();
|
||||
|
||||
|
||||
//External functions in typical order of use:
|
||||
//__________________________________________________________________________________________________________*/
|
||||
void setDebug(bool); // Turn debug message on/off
|
||||
bool debug(); // is debug on or off?
|
||||
|
||||
bool open(const char* /*GET/POST*/, const char* URL); // Initiate a request
|
||||
void onReadyStateChange(readyStateChangeCB, void* arg = 0); // Optional event handler for ready state change
|
||||
// or you can simply poll readyState()
|
||||
void setTimeout(int); // overide default timeout (seconds)
|
||||
|
||||
void setReqHeader(const char* name, const char* value); // add a request header
|
||||
void setReqHeader(const char* name, int32_t value); // overload to use integer value
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
void setReqHeader(const char* name, const __FlashStringHelper* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, const char* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, const __FlashStringHelper* value);
|
||||
void setReqHeader(const __FlashStringHelper *name, int32_t value);
|
||||
#endif
|
||||
|
||||
bool send(); // Send the request (GET)
|
||||
bool send(String body); // Send the request (POST)
|
||||
bool send(const char* body); // Send the request (POST)
|
||||
bool send(const uint8_t* buffer, size_t len); // Send the request (POST) (binary data?)
|
||||
bool send(xbuf* body, size_t len); // Send the request (POST) data in an xbuf
|
||||
void abort(); // Abort the current operation
|
||||
|
||||
reqStates readyState(); // Return the ready state
|
||||
|
||||
int respHeaderCount(); // Retrieve count of response headers
|
||||
char* respHeaderName(int index); // Return header name by index
|
||||
char* respHeaderValue(int index); // Return header value by index
|
||||
char* respHeaderValue(const char* name); // Return header value by name
|
||||
|
||||
bool respHeaderExists(const char* name); // Does header exist by name?
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
char* respHeaderValue(const __FlashStringHelper *name);
|
||||
bool respHeaderExists(const __FlashStringHelper *name);
|
||||
#endif
|
||||
|
||||
String headers(); // Return all headers as String
|
||||
|
||||
void onData(onDataCB, void* arg = 0); // Notify when min data is available
|
||||
size_t available(); // response available
|
||||
size_t responseLength(); // indicated response length or sum of chunks to date
|
||||
int responseHTTPcode(); // HTTP response code or (negative) error code
|
||||
String responseText(); // response (whole* or partial* as string)
|
||||
size_t responseRead(uint8_t* buffer, size_t len); // Read response into buffer
|
||||
uint32_t elapsedTime(); // Elapsed time of in progress transaction or last completed (ms)
|
||||
String version(); // Version of AsyncHTTPRequest
|
||||
//___________________________________________________________________________________________________________________________________
|
||||
|
||||
private:
|
||||
|
||||
enum {HTTPmethodGET, HTTPmethodPOST} _HTTPmethod;
|
||||
|
||||
reqStates _readyState;
|
||||
|
||||
int16_t _HTTPcode; // HTTP response code or (negative) exception code
|
||||
bool _chunked; // Processing chunked response
|
||||
bool _debug; // Debug state
|
||||
uint32_t _timeout; // Default or user overide RxTimeout in seconds
|
||||
uint32_t _lastActivity; // Time of last activity
|
||||
uint32_t _requestStartTime; // Time last open() issued
|
||||
uint32_t _requestEndTime; // Time of last disconnect
|
||||
URL* _URL; // -> URL data structure
|
||||
char* _connectedHost; // Host when connected
|
||||
int _connectedPort; // Port when connected
|
||||
AsyncClient* _client; // ESPAsyncTCP AsyncClient instance
|
||||
size_t _contentLength; // content-length header value or sum of chunk headers
|
||||
size_t _contentRead; // number of bytes retrieved by user since last open()
|
||||
readyStateChangeCB _readyStateChangeCB; // optional callback for readyState change
|
||||
void* _readyStateChangeCBarg; // associated user argument
|
||||
onDataCB _onDataCB; // optional callback when data received
|
||||
void* _onDataCBarg; // associated user argument
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t threadLock;
|
||||
#endif
|
||||
|
||||
// request and response String buffers and header list (same queue for request and response).
|
||||
|
||||
xbuf* _request; // Tx data buffer
|
||||
xbuf* _response; // Rx data buffer for headers
|
||||
xbuf* _chunks; // First stage for chunked response
|
||||
header* _headers; // request or (readyState > readyStateHdrsRcvd) response headers
|
||||
|
||||
// Protected functions
|
||||
|
||||
header* _addHeader(const char*, const char*);
|
||||
header* _getHeader(const char*);
|
||||
header* _getHeader(int);
|
||||
bool _buildRequest();
|
||||
bool _parseURL(const char*);
|
||||
bool _parseURL(String);
|
||||
void _processChunks();
|
||||
bool _connect();
|
||||
size_t _send();
|
||||
void _setReadyState(reqStates);
|
||||
|
||||
#if (ESP32 || ESP8266)
|
||||
char* _charstar(const __FlashStringHelper *str);
|
||||
#endif
|
||||
|
||||
// callbacks
|
||||
|
||||
void _onConnect(AsyncClient*);
|
||||
void _onDisconnect(AsyncClient*);
|
||||
void _onData(void*, size_t);
|
||||
void _onError(AsyncClient*, int8_t);
|
||||
void _onPoll(AsyncClient*);
|
||||
bool _collectHeaders();
|
||||
};
|
||||
|
||||
#include "AsyncHTTPRequest_Impl_Generic.h"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,151 @@
|
||||
/****************************************************************************************************************************
|
||||
xbuf.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
/********************************************************************************************
|
||||
xbuf is a dynamic buffering system that supports reading and writing much like cbuf.
|
||||
The class has it's own provision for writing from buffers, Strings and other xbufs
|
||||
as well as the inherited Print functions.
|
||||
Rather than use a large contiguous heap allocation, xbuf uses a linked chain of segments
|
||||
to dynamically grow and shrink with the contents.
|
||||
There are other benefits as well to using smaller heap allocation units:
|
||||
1) A buffer can work fine in a fragmented heap environment (admittedly contributing to it)
|
||||
2) xbuf contents can be copied from one buffer to another without the need for
|
||||
2x heap during the copy.
|
||||
The segment size defaults to 64 but can be dynamically set in the constructor at creation.
|
||||
The inclusion of indexOf and read/peek until functions make it useful for handling
|
||||
data streams like HTTP, and in fact is why it was created.
|
||||
|
||||
NOTE: The size of the indexOf() search string is limited to the segment size.
|
||||
It could be extended but didn't seem to be a practical consideration.
|
||||
|
||||
********************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
struct xseg
|
||||
{
|
||||
xseg *next;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
class xbuf: public Print
|
||||
{
|
||||
public:
|
||||
|
||||
xbuf(const uint16_t segSize = 64);
|
||||
virtual ~xbuf();
|
||||
|
||||
size_t write(const uint8_t);
|
||||
size_t write(const char*);
|
||||
size_t write(const uint8_t*, const size_t);
|
||||
size_t write(xbuf*, const size_t);
|
||||
size_t write(String);
|
||||
size_t available();
|
||||
int indexOf(const char, const size_t begin = 0);
|
||||
int indexOf(const char*, const size_t begin = 0);
|
||||
uint8_t read();
|
||||
size_t read(uint8_t*, size_t);
|
||||
String readStringUntil(const char);
|
||||
String readStringUntil(const char*);
|
||||
String readString(int);
|
||||
|
||||
String readString()
|
||||
{
|
||||
return readString(available());
|
||||
}
|
||||
|
||||
void flush();
|
||||
|
||||
uint8_t peek();
|
||||
size_t peek(uint8_t*, const size_t);
|
||||
|
||||
String peekStringUntil(const char target)
|
||||
{
|
||||
return peekString(indexOf(target, 0));
|
||||
}
|
||||
|
||||
String peekStringUntil(const char* target)
|
||||
{
|
||||
return peekString(indexOf(target, 0));
|
||||
}
|
||||
|
||||
String peekString()
|
||||
{
|
||||
return peekString(_used);
|
||||
}
|
||||
|
||||
String peekString(int);
|
||||
|
||||
/* In addition to the above functions,
|
||||
the following inherited functions from the Print class are available.
|
||||
|
||||
size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
size_t printf_P(PGM_P format, ...) __attribute__((format(printf, 2, 3)));
|
||||
size_t print(const __FlashStringHelper *);
|
||||
size_t print(const String &);
|
||||
size_t print(const char[]);
|
||||
size_t print(char);
|
||||
size_t print(unsigned char, int = DEC);
|
||||
size_t print(int, int = DEC);
|
||||
size_t print(unsigned int, int = DEC);
|
||||
size_t print(long, int = DEC);
|
||||
size_t print(unsigned long, int = DEC);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(const Printable&);
|
||||
|
||||
size_t println(const __FlashStringHelper *);
|
||||
size_t println(const String &s);
|
||||
size_t println(const char[]);
|
||||
size_t println(char);
|
||||
size_t println(unsigned char, int = DEC);
|
||||
size_t println(int, int = DEC);
|
||||
size_t println(unsigned int, int = DEC);
|
||||
size_t println(long, int = DEC);
|
||||
size_t println(unsigned long, int = DEC);
|
||||
size_t println(double, int = 2);
|
||||
size_t println(const Printable&);
|
||||
size_t println(void);
|
||||
*/
|
||||
|
||||
protected:
|
||||
|
||||
xseg *_head;
|
||||
xseg *_tail;
|
||||
uint16_t _used;
|
||||
uint16_t _free;
|
||||
uint16_t _offset;
|
||||
uint16_t _segSize;
|
||||
|
||||
void addSeg();
|
||||
void remSeg();
|
||||
|
||||
};
|
||||
|
||||
#include "utility/xbuf_Impl.h"
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
/****************************************************************************************************************************
|
||||
xbuf_Impl.h - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
|
||||
|
||||
For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
|
||||
|
||||
AsyncHTTPRequest_STM32 is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
|
||||
|
||||
Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
|
||||
Licensed under MIT license
|
||||
|
||||
Copyright (C) <2018> <Bob Lemaire, IoTaWatt, Inc.>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
as published bythe Free Software Foundation, either version 3 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 General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Version: 1.0.2
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
|
||||
1.0.1 K Hoang 09/10/2020 Restore cpp code besides Impl.h code.
|
||||
1.0.2 K Hoang 09/11/2020 Make Mutex Lock and delete more reliable and error-proof
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
xbuf::xbuf(const uint16_t segSize) : _head(nullptr), _tail(nullptr), _used(0), _free(0), _offset(0)
|
||||
{
|
||||
_segSize = (segSize + 3) & -4;//((segSize + 3) >> 2) << 2;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
xbuf::~xbuf()
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const uint8_t byte)
|
||||
{
|
||||
return write((uint8_t*) &byte, 1);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const char* buf)
|
||||
{
|
||||
return write((uint8_t*)buf, strlen(buf));
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(String string)
|
||||
{
|
||||
return write((uint8_t*)string.c_str(), string.length());
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(const uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t supply = len;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
if (!_free)
|
||||
{
|
||||
addSeg();
|
||||
}
|
||||
|
||||
size_t demand = _free < supply ? _free : supply;
|
||||
memcpy(_tail->data + ((_offset + _used) % _segSize), buf + (len - supply), demand);
|
||||
_free -= demand;
|
||||
_used += demand;
|
||||
supply -= demand;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::write(xbuf* buf, const size_t len)
|
||||
{
|
||||
size_t supply = len;
|
||||
|
||||
if (supply > buf->available())
|
||||
{
|
||||
supply = buf->available();
|
||||
}
|
||||
|
||||
size_t read = 0;
|
||||
|
||||
while (supply)
|
||||
{
|
||||
if (!_free)
|
||||
{
|
||||
addSeg();
|
||||
}
|
||||
|
||||
size_t demand = _free < supply ? _free : supply;
|
||||
read += buf->read(_tail->data + ((_offset + _used) % _segSize), demand);
|
||||
_free -= demand;
|
||||
_used += demand;
|
||||
supply -= demand;
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
uint8_t xbuf::read()
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
read((uint8_t*) &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
uint8_t xbuf::peek()
|
||||
{
|
||||
uint8_t byte = 0;
|
||||
peek((uint8_t*) &byte, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::read(uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t read = 0;
|
||||
|
||||
while (read < len && _used)
|
||||
{
|
||||
size_t supply = (_offset + _used) > _segSize ? _segSize - _offset : _used;
|
||||
size_t demand = len - read;
|
||||
size_t chunk = supply < demand ? supply : demand;
|
||||
memcpy(buf + read, _head->data + _offset, chunk);
|
||||
_offset += chunk;
|
||||
_used -= chunk;
|
||||
read += chunk;
|
||||
|
||||
if (_offset == _segSize)
|
||||
{
|
||||
remSeg();
|
||||
_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! _used)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::peek(uint8_t* buf, const size_t len)
|
||||
{
|
||||
size_t read = 0;
|
||||
xseg* seg = _head;
|
||||
size_t offset = _offset;
|
||||
size_t used = _used;
|
||||
|
||||
while (read < len && used)
|
||||
{
|
||||
size_t supply = (offset + used) > _segSize ? _segSize - offset : used;
|
||||
size_t demand = len - read;
|
||||
size_t chunk = supply < demand ? supply : demand;
|
||||
|
||||
memcpy(buf + read, seg->data + offset, chunk);
|
||||
|
||||
offset += chunk;
|
||||
used -= chunk;
|
||||
read += chunk;
|
||||
|
||||
if (offset == _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
size_t xbuf::available()
|
||||
{
|
||||
return _used;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
int xbuf::indexOf(const char target, const size_t begin)
|
||||
{
|
||||
char targetstr[2] = " ";
|
||||
targetstr[0] = target;
|
||||
|
||||
return indexOf(targetstr, begin);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
int xbuf::indexOf(const char* target, const size_t begin)
|
||||
{
|
||||
size_t targetLen = strlen(target);
|
||||
|
||||
if (targetLen > _segSize || targetLen > _used)
|
||||
return -1;
|
||||
|
||||
size_t searchPos = _offset + begin;
|
||||
size_t searchEnd = _offset + _used - targetLen;
|
||||
|
||||
if (searchPos > searchEnd)
|
||||
return -1;
|
||||
|
||||
size_t searchSeg = searchPos / _segSize;
|
||||
xseg* seg = _head;
|
||||
|
||||
while (searchSeg)
|
||||
{
|
||||
seg = seg->next;
|
||||
searchSeg --;
|
||||
}
|
||||
|
||||
size_t segPos = searchPos % _segSize;
|
||||
|
||||
while (searchPos <= searchEnd)
|
||||
{
|
||||
size_t compLen = targetLen;
|
||||
|
||||
if (compLen <= (_segSize - segPos))
|
||||
{
|
||||
if (memcmp(target, seg->data + segPos, compLen) == 0)
|
||||
{
|
||||
return searchPos - _offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t compLen = _segSize - segPos;
|
||||
|
||||
if (memcmp(target, seg->data + segPos, compLen) == 0)
|
||||
{
|
||||
compLen = targetLen - compLen;
|
||||
|
||||
if (memcmp(target + targetLen - compLen, seg->next->data, compLen) == 0)
|
||||
{
|
||||
return searchPos - _offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchPos++;
|
||||
segPos++;
|
||||
|
||||
if (segPos == _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
segPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readStringUntil(const char target)
|
||||
{
|
||||
return readString(indexOf(target) + 1);
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readStringUntil(const char* target)
|
||||
{
|
||||
int index = indexOf(target);
|
||||
|
||||
if (index < 0)
|
||||
return String();
|
||||
|
||||
return readString(index + strlen(target));
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::readString(int endPos)
|
||||
{
|
||||
String result;
|
||||
|
||||
if ( ! result.reserve(endPos + 1))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (endPos > _used)
|
||||
{
|
||||
endPos = _used;
|
||||
}
|
||||
|
||||
if (endPos > 0 && result.reserve(endPos + 1))
|
||||
{
|
||||
while (endPos--)
|
||||
{
|
||||
result += (char)_head->data[_offset++];
|
||||
_used--;
|
||||
|
||||
if (_offset >= _segSize)
|
||||
{
|
||||
remSeg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
String xbuf::peekString(int endPos)
|
||||
{
|
||||
String result;
|
||||
|
||||
xseg* seg = _head;
|
||||
size_t offset = _offset;
|
||||
|
||||
if (endPos > _used)
|
||||
{
|
||||
endPos = _used;
|
||||
}
|
||||
|
||||
if (endPos > 0 && result.reserve(endPos + 1))
|
||||
{
|
||||
while (endPos--)
|
||||
{
|
||||
result += (char)seg->data[offset++];
|
||||
|
||||
if ( offset >= _segSize)
|
||||
{
|
||||
seg = seg->next;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::flush()
|
||||
{
|
||||
while (_head)
|
||||
remSeg();
|
||||
|
||||
_tail = nullptr;
|
||||
_offset = 0;
|
||||
_used = 0;
|
||||
_free = 0;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::addSeg()
|
||||
{
|
||||
if (_tail)
|
||||
{
|
||||
_tail->next = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
|
||||
// KH, Must check NULL here
|
||||
_tail = _tail->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// KH, Must check NULL here
|
||||
_tail = _head = (xseg*) new uint32_t[_segSize / 4 + 1];
|
||||
}
|
||||
|
||||
// KH, Must check NULL here
|
||||
if (_tail)
|
||||
_tail->next = nullptr;
|
||||
|
||||
_free += _segSize;
|
||||
}
|
||||
|
||||
//*******************************************************************************************************************
|
||||
void xbuf::remSeg()
|
||||
{
|
||||
if (_head)
|
||||
{
|
||||
xseg *next = _head->next;
|
||||
delete[] (uint32_t*) _head;
|
||||
_head = next;
|
||||
|
||||
if ( ! _head)
|
||||
{
|
||||
_tail = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user