From 642e1ef7bc263aa09b0d42f2b46b3c5a85790394 Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Fri, 20 Mar 2015 17:22:59 +0200 Subject: [PATCH 1/3] Typo fix --- examples/atmelavr-and-arduino/adafruit-blink/README.rst | 4 ++-- .../atmelavr-and-arduino/arduino-external-libs/README.rst | 4 ++-- .../atmelavr-and-arduino/arduino-internal-libs/README.rst | 4 ++-- examples/atmelavr-and-arduino/arduino-own-src_dir/README.rst | 4 ++-- .../atmelavr-and-arduino/atmelavr-native-blink/README.rst | 4 ++-- examples/atmelavr-and-arduino/digitstump-mouse/README.rst | 4 ++-- .../atmelavr-and-arduino/engduino-magnetometer/README.rst | 4 ++-- examples/atmelavr-and-arduino/panstamp-blink/README.rst | 4 ++-- examples/mbed/mbed-serial/README.rst | 4 ++-- examples/stm32/stm32-cmsis-blink/README.rst | 4 ++-- examples/stm32/stm32-opencm3-blink/README.rst | 4 ++-- examples/stm32/stm32-spl-blink/README.rst | 4 ++-- examples/teensy/teensy-internal-libs/README.rst | 4 ++-- examples/timsp430/panstamp-blink/README.rst | 4 ++-- examples/timsp430/timsp430-energia-blink/README.rst | 4 ++-- examples/timsp430/timsp430-native-blink/README.rst | 4 ++-- examples/titiva/titiva-energia-blink/README.rst | 4 ++-- examples/titiva/titiva-native-blink/README.rst | 4 ++-- examples/titiva/titiva-opencm3-blink/README.rst | 4 ++-- examples/wiring-blink/README.rst | 4 ++-- 20 files changed, 40 insertions(+), 40 deletions(-) diff --git a/examples/atmelavr-and-arduino/adafruit-blink/README.rst b/examples/atmelavr-and-arduino/adafruit-blink/README.rst index 290761d5..ffccc76e 100644 --- a/examples/atmelavr-and-arduino/adafruit-blink/README.rst +++ b/examples/atmelavr-and-arduino/adafruit-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/arduino-external-libs/README.rst b/examples/atmelavr-and-arduino/arduino-external-libs/README.rst index 675b2129..634386f8 100644 --- a/examples/atmelavr-and-arduino/arduino-external-libs/README.rst +++ b/examples/atmelavr-and-arduino/arduino-external-libs/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/arduino-internal-libs/README.rst b/examples/atmelavr-and-arduino/arduino-internal-libs/README.rst index cb17077d..f510bf29 100644 --- a/examples/atmelavr-and-arduino/arduino-internal-libs/README.rst +++ b/examples/atmelavr-and-arduino/arduino-internal-libs/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/arduino-own-src_dir/README.rst b/examples/atmelavr-and-arduino/arduino-own-src_dir/README.rst index 02a88a40..8c5469cf 100644 --- a/examples/atmelavr-and-arduino/arduino-own-src_dir/README.rst +++ b/examples/atmelavr-and-arduino/arduino-own-src_dir/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/atmelavr-native-blink/README.rst b/examples/atmelavr-and-arduino/atmelavr-native-blink/README.rst index 14bfc2de..4edae991 100644 --- a/examples/atmelavr-and-arduino/atmelavr-native-blink/README.rst +++ b/examples/atmelavr-and-arduino/atmelavr-native-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/digitstump-mouse/README.rst b/examples/atmelavr-and-arduino/digitstump-mouse/README.rst index f01bea45..0a7076bc 100644 --- a/examples/atmelavr-and-arduino/digitstump-mouse/README.rst +++ b/examples/atmelavr-and-arduino/digitstump-mouse/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/engduino-magnetometer/README.rst b/examples/atmelavr-and-arduino/engduino-magnetometer/README.rst index 4aed8102..71ef0514 100644 --- a/examples/atmelavr-and-arduino/engduino-magnetometer/README.rst +++ b/examples/atmelavr-and-arduino/engduino-magnetometer/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/atmelavr-and-arduino/panstamp-blink/README.rst b/examples/atmelavr-and-arduino/panstamp-blink/README.rst index e0a3e32a..eb66f295 100644 --- a/examples/atmelavr-and-arduino/panstamp-blink/README.rst +++ b/examples/atmelavr-and-arduino/panstamp-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/mbed/mbed-serial/README.rst b/examples/mbed/mbed-serial/README.rst index 5ea1282a..7f1feb4a 100644 --- a/examples/mbed/mbed-serial/README.rst +++ b/examples/mbed/mbed-serial/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/stm32/stm32-cmsis-blink/README.rst b/examples/stm32/stm32-cmsis-blink/README.rst index e6cac2a7..0c1b987b 100644 --- a/examples/stm32/stm32-cmsis-blink/README.rst +++ b/examples/stm32/stm32-cmsis-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/stm32/stm32-opencm3-blink/README.rst b/examples/stm32/stm32-opencm3-blink/README.rst index 579fdcab..b2df8478 100644 --- a/examples/stm32/stm32-opencm3-blink/README.rst +++ b/examples/stm32/stm32-opencm3-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/stm32/stm32-spl-blink/README.rst b/examples/stm32/stm32-spl-blink/README.rst index 72a568be..8ed58571 100644 --- a/examples/stm32/stm32-spl-blink/README.rst +++ b/examples/stm32/stm32-spl-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/teensy/teensy-internal-libs/README.rst b/examples/teensy/teensy-internal-libs/README.rst index 5cea44c9..e1a1cc9a 100644 --- a/examples/teensy/teensy-internal-libs/README.rst +++ b/examples/teensy/teensy-internal-libs/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/timsp430/panstamp-blink/README.rst b/examples/timsp430/panstamp-blink/README.rst index f812cba1..6e7c06b7 100644 --- a/examples/timsp430/panstamp-blink/README.rst +++ b/examples/timsp430/panstamp-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/timsp430/timsp430-energia-blink/README.rst b/examples/timsp430/timsp430-energia-blink/README.rst index 67c8f443..7ad63a62 100644 --- a/examples/timsp430/timsp430-energia-blink/README.rst +++ b/examples/timsp430/timsp430-energia-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/timsp430/timsp430-native-blink/README.rst b/examples/timsp430/timsp430-native-blink/README.rst index 341ecf7e..5014d0ce 100644 --- a/examples/timsp430/timsp430-native-blink/README.rst +++ b/examples/timsp430/timsp430-native-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/titiva/titiva-energia-blink/README.rst b/examples/titiva/titiva-energia-blink/README.rst index e8b4caaf..3f182624 100644 --- a/examples/titiva/titiva-energia-blink/README.rst +++ b/examples/titiva/titiva-energia-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/titiva/titiva-native-blink/README.rst b/examples/titiva/titiva-native-blink/README.rst index 52e59f63..109f2ebb 100644 --- a/examples/titiva/titiva-native-blink/README.rst +++ b/examples/titiva/titiva-native-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/titiva/titiva-opencm3-blink/README.rst b/examples/titiva/titiva-opencm3-blink/README.rst index d98ff383..d3a83202 100644 --- a/examples/titiva/titiva-opencm3-blink/README.rst +++ b/examples/titiva/titiva-opencm3-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ diff --git a/examples/wiring-blink/README.rst b/examples/wiring-blink/README.rst index 551f4d73..8dbda11e 100644 --- a/examples/wiring-blink/README.rst +++ b/examples/wiring-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ From 7cfb9db046215911221cd0292c91f3d681f26f7b Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Fri, 20 Mar 2015 17:23:46 +0200 Subject: [PATCH 2/3] Typo fix --- examples/mbed/mbed-blink/README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/mbed/mbed-blink/README.rst b/examples/mbed/mbed-blink/README.rst index b36ea0e3..cc6c6377 100644 --- a/examples/mbed/mbed-blink/README.rst +++ b/examples/mbed/mbed-blink/README.rst @@ -1,5 +1,5 @@ -How to buid PlatformIO based project -==================================== +How to build PlatformIO based project +===================================== 1. `Install PlatformIO `_ 2. Download `source code with examples `_ From 726887732f6c651ace6308745f0e7cde04c30fde Mon Sep 17 00:00:00 2001 From: Valeriy Koval Date: Fri, 20 Mar 2015 19:46:13 +0200 Subject: [PATCH 3/3] Add full support for MBED libraries: rtos, eth, dsp, fat, usb --- examples/mbed/mbed-dsp/README.rst | 21 + examples/mbed/mbed-dsp/platformio.ini | 43 + examples/mbed/mbed-dsp/src/data.cpp | 94 +++ examples/mbed/mbed-dsp/src/main.cpp | 65 ++ examples/mbed/mbed-http-client/README.rst | 21 + .../lib/HTTPClient/HTTPClient.cpp | 739 ++++++++++++++++++ .../lib/HTTPClient/HTTPClient.h | 159 ++++ .../lib/HTTPClient/IHTTPData.h | 105 +++ .../lib/HTTPClient/data/HTTPMap.cpp | 200 +++++ .../lib/HTTPClient/data/HTTPMap.h | 71 ++ .../lib/HTTPClient/data/HTTPText.cpp | 104 +++ .../lib/HTTPClient/data/HTTPText.h | 72 ++ examples/mbed/mbed-http-client/platformio.ini | 25 + examples/mbed/mbed-http-client/src/main.cpp | 79 ++ examples/mbed/mbed-rtos/README.rst | 21 + examples/mbed/mbed-rtos/platformio.ini | 37 + examples/mbed/mbed-rtos/src/main.cpp | 38 + platformio/boards/freescalekinetis.json | 19 +- platformio/boards/nordicnrf51.json | 20 +- platformio/boards/ststm32.json | 16 + platformio/builder/scripts/frameworks/mbed.py | 104 ++- scripts/mbed_to_package.py | 58 +- 22 files changed, 2092 insertions(+), 19 deletions(-) create mode 100644 examples/mbed/mbed-dsp/README.rst create mode 100644 examples/mbed/mbed-dsp/platformio.ini create mode 100644 examples/mbed/mbed-dsp/src/data.cpp create mode 100644 examples/mbed/mbed-dsp/src/main.cpp create mode 100644 examples/mbed/mbed-http-client/README.rst create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.cpp create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.h create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/IHTTPData.h create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.cpp create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.h create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.cpp create mode 100644 examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.h create mode 100644 examples/mbed/mbed-http-client/platformio.ini create mode 100644 examples/mbed/mbed-http-client/src/main.cpp create mode 100644 examples/mbed/mbed-rtos/README.rst create mode 100644 examples/mbed/mbed-rtos/platformio.ini create mode 100644 examples/mbed/mbed-rtos/src/main.cpp diff --git a/examples/mbed/mbed-dsp/README.rst b/examples/mbed/mbed-dsp/README.rst new file mode 100644 index 00000000..557272de --- /dev/null +++ b/examples/mbed/mbed-dsp/README.rst @@ -0,0 +1,21 @@ +How to build PlatformIO based project +===================================== + +1. `Install PlatformIO `_ +2. Download `source code with examples `_ +3. Extract ZIP archive +4. Run these commands: + +.. code-block:: bash + + # Change directory to example + > cd platformio-develop/examples/mbed/mbed-dsp + + # Process example project + > platformio run + + # Upload firmware + > platformio run --target upload + + # Clean build files + > platformio run --target clean diff --git a/examples/mbed/mbed-dsp/platformio.ini b/examples/mbed/mbed-dsp/platformio.ini new file mode 100644 index 00000000..f1f25ccb --- /dev/null +++ b/examples/mbed/mbed-dsp/platformio.ini @@ -0,0 +1,43 @@ +# +# Project Configuration File +# +# A detailed documentation with the EXAMPLES is located here: +# http://docs.platformio.org/en/latest/projectconf.html +# + +# A sign `#` at the beginning of the line indicates a comment +# Comment lines are ignored. + +# Simple and base environment +# [env:mybaseenv] +# platform = %INSTALLED_PLATFORM_NAME_HERE% +# framework = +# board = +# +# Automatic targets - enable auto-uploading +# targets = upload + + +# NXP LPC Platform +[env:lpc1768] +platform = nxplpc +framework = mbed +board = lpc1768 + +# Nordic nRF51 Platform +[env:nrf51_mkit] +platform = nordicnrf51 +framework = mbed +board = nrf51_mkit + +# Freescale FRDM Platform +[env:frdm_kl25z] +platform = freescalekinetis +framework = mbed +board = frdm_kl25z + +# ST STM32 Platform +[env:nucleo_f401re] +platform = ststm32 +framework = mbed +board = nucleo_f401re diff --git a/examples/mbed/mbed-dsp/src/data.cpp b/examples/mbed/mbed-dsp/src/data.cpp new file mode 100644 index 00000000..d946b36b --- /dev/null +++ b/examples/mbed/mbed-dsp/src/data.cpp @@ -0,0 +1,94 @@ +#include "arm_math.h" + +/* ---------------------------------------------------------------------- +** Test input signal contains 1000Hz + 15000 Hz +** ------------------------------------------------------------------- */ + +float32_t testInput_f32_1kHz_15kHz[320] = +{ ++0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, +-0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f, +-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f, ++0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, ++0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f, +-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f, ++0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, ++0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f, +-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f, +-0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, +-0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f, +-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f, ++0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, ++0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f, +-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f, +-0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, ++0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +-0.8660254038f, -0.4619397663f, -1.3194792169f, -1.1827865776f, -0.5000000000f, -1.1827865776f, -1.3194792169f, -0.4619397663f, +-0.8660254038f, -1.2552931065f, -0.3535533906f, -0.4174197128f, -1.0000000000f, -0.1913417162f, +0.0947343455f, -0.5924659585f, +-0.0000000000f, +0.5924659585f, -0.0947343455f, +0.1913417162f, +1.0000000000f, +0.4174197128f, +0.3535533906f, +1.2552931065f, ++0.8660254038f, +0.4619397663f, +1.3194792169f, +1.1827865776f, +0.5000000000f, +1.1827865776f, +1.3194792169f, +0.4619397663f, ++0.8660254038f, +1.2552931065f, +0.3535533906f, +0.4174197128f, +1.0000000000f, +0.1913417162f, -0.0947343455f, +0.5924659585f, ++0.0000000000f, -0.5924659585f, +0.0947343455f, -0.1913417162f, -1.0000000000f, -0.4174197128f, -0.3535533906f, -1.2552931065f, +}; + +float32_t refOutput[320] = +{ ++0.0000000000f, -0.0010797829f, -0.0007681386f, -0.0001982932f, +0.0000644313f, +0.0020854271f, +0.0036891871f, +0.0015855941f, +-0.0026280805f, -0.0075907658f, -0.0119390538f, -0.0086665968f, +0.0088981202f, +0.0430539279f, +0.0974468742f, +0.1740405600f, ++0.2681416601f, +0.3747720089f, +0.4893362230f, +0.6024154672f, +0.7058740791f, +0.7968348987f, +0.8715901940f, +0.9277881093f, ++0.9682182661f, +0.9934674267f, +1.0012052245f, +0.9925859371f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f, ++0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, -0.0000000000f, -0.1309866321f, +-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f, +-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f, +-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f, ++0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f, ++0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f, ++0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, -0.0000000000f, -0.1309866321f, +-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f, +-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f, +-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f, ++0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f, ++0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f, ++0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, -0.0000000000f, -0.1309866321f, +-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f, +-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f, +-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f, ++0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f, ++0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f, ++0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, +0.0000000000f, -0.1309866321f, +-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f, +-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f, +-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f, ++0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f, ++0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f, ++0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, +0.0000000000f, -0.1309866321f, +-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f, +-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f, +-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, -0.0000000000f, +0.1309866321f, ++0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f, ++0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f, ++0.7085021596f, +0.6100062330f, +0.5012752767f, +0.3834386057f, +0.2592435399f, +0.1309866321f, +0.0000000000f, -0.1309866321f, +-0.2592435399f, -0.3834386057f, -0.5012752767f, -0.6100062330f, -0.7085021596f, -0.7952493046f, -0.8679010068f, -0.9257026822f, +-0.9681538347f, -0.9936657199f, -1.0019733630f, -0.9936657199f, -0.9681538347f, -0.9257026822f, -0.8679010068f, -0.7952493046f, +-0.7085021596f, -0.6100062330f, -0.5012752767f, -0.3834386057f, -0.2592435399f, -0.1309866321f, +0.0000000000f, +0.1309866321f, ++0.2592435399f, +0.3834386057f, +0.5012752767f, +0.6100062330f, +0.7085021596f, +0.7952493046f, +0.8679010068f, +0.9257026822f, ++0.9681538347f, +0.9936657199f, +1.0019733630f, +0.9936657199f, +0.9681538347f, +0.9257026822f, +0.8679010068f, +0.7952493046f +}; + diff --git a/examples/mbed/mbed-dsp/src/main.cpp b/examples/mbed/mbed-dsp/src/main.cpp new file mode 100644 index 00000000..f6bdb4b7 --- /dev/null +++ b/examples/mbed/mbed-dsp/src/main.cpp @@ -0,0 +1,65 @@ +#include "arm_math.h" +#include "math_helper.h" +#include + +#define BLOCK_SIZE 32 +#define NUM_BLOCKS 10 + +#define TEST_LENGTH_SAMPLES (BLOCK_SIZE * NUM_BLOCKS) + +#define SNR_THRESHOLD_F32 140.0f +#define NUM_TAPS 29 + +/* ------------------------------------------------------------------- + * The input signal and reference output (computed with MATLAB) + * are defined externally in arm_fir_lpf_data.c. + * ------------------------------------------------------------------- */ +extern float32_t testInput_f32_1kHz_15kHz[TEST_LENGTH_SAMPLES]; +extern float32_t refOutput[TEST_LENGTH_SAMPLES]; + +/* ------------------------------------------------------------------- + * Declare State buffer of size (numTaps + blockSize - 1) + * ------------------------------------------------------------------- */ +static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1]; + +/* ---------------------------------------------------------------------- + * FIR Coefficients buffer generated using fir1() MATLAB function. + * fir1(28, 6/24) + * ------------------------------------------------------------------- */ +const float32_t firCoeffs32[NUM_TAPS] = { + -0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f, + +0.0085302217f, -0.0000000000f, -0.0173976984f, -0.0341458607f, -0.0333591565f, + +0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f, + +0.2229246956f, +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f, + -0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f, +0.0080754303f, + +0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f +}; + +/* ---------------------------------------------------------------------- + * FIR LPF Example + * ------------------------------------------------------------------- */ +int main(void) { + /* Call FIR init function to initialize the instance structure. */ + arm_fir_instance_f32 S; + arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs32[0], &firStateF32[0], BLOCK_SIZE); + + /* ---------------------------------------------------------------------- + * Call the FIR process function for every blockSize samples + * ------------------------------------------------------------------- */ + for (uint32_t i=0; i < NUM_BLOCKS; i++) { + float32_t* signal = testInput_f32_1kHz_15kHz + (i * BLOCK_SIZE); + arm_fir_f32(&S, signal, signal, BLOCK_SIZE); + } + + /* ---------------------------------------------------------------------- + * Compare the generated output against the reference output computed + * in MATLAB. + * ------------------------------------------------------------------- */ + float32_t snr = arm_snr_f32(refOutput, testInput_f32_1kHz_15kHz, TEST_LENGTH_SAMPLES); + printf("snr: %f\n\r", snr); + if (snr < SNR_THRESHOLD_F32) { + printf("Failed\n\r"); + } else { + printf("Success\n\r"); + } +} diff --git a/examples/mbed/mbed-http-client/README.rst b/examples/mbed/mbed-http-client/README.rst new file mode 100644 index 00000000..c7f23685 --- /dev/null +++ b/examples/mbed/mbed-http-client/README.rst @@ -0,0 +1,21 @@ +How to build PlatformIO based project +===================================== + +1. `Install PlatformIO `_ +2. Download `source code with examples `_ +3. Extract ZIP archive +4. Run these commands: + +.. code-block:: bash + + # Change directory to example + > cd platformio-develop/examples/mbed/mbed-http-client + + # Process example project + > platformio run + + # Upload firmware + > platformio run --target upload + + # Clean build files + > platformio run --target clean diff --git a/examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.cpp b/examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.cpp new file mode 100644 index 00000000..0a6abd31 --- /dev/null +++ b/examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.cpp @@ -0,0 +1,739 @@ +/* HTTPClient.cpp */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +//Debug is disabled by default +#if 0 +//Enable debug +#include +#define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__); +#define WARN(x, ...) std::printf("[HTTPClient : WARN]"x"\r\n", ##__VA_ARGS__); +#define ERR(x, ...) std::printf("[HTTPClient : ERR]"x"\r\n", ##__VA_ARGS__); + +#else +//Disable debug +#define DBG(x, ...) +#define WARN(x, ...) +#define ERR(x, ...) + +#endif + +#define HTTP_PORT 80 + +#define OK 0 + +#define MIN(x,y) (((x)<(y))?(x):(y)) +#define MAX(x,y) (((x)>(y))?(x):(y)) + +#define CHUNK_SIZE 256 + +#include + +#include "HTTPClient.h" + +HTTPClient::HTTPClient() : +m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) +{ + +} + +HTTPClient::~HTTPClient() +{ + +} + +#if 0 +void HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification +{ + m_basicAuthUser = user; + m_basicAuthPassword = password; +} +#endif + +HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking +{ + return connect(url, HTTP_GET, NULL, pDataIn, timeout); +} + +HTTPResult HTTPClient::get(const char* url, char* result, size_t maxResultLen, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking +{ + HTTPText str(result, maxResultLen); + return get(url, &str, timeout); +} + +HTTPResult HTTPClient::post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking +{ + return connect(url, HTTP_POST, (IHTTPDataOut*)&dataOut, pDataIn, timeout); +} + +HTTPResult HTTPClient::put(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking +{ + return connect(url, HTTP_PUT, (IHTTPDataOut*)&dataOut, pDataIn, timeout); +} + +HTTPResult HTTPClient::del(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking +{ + return connect(url, HTTP_DELETE, NULL, pDataIn, timeout); +} + + +int HTTPClient::getHTTPResponseCode() +{ + return m_httpResponseCode; +} + +#define CHECK_CONN_ERR(ret) \ + do{ \ + if(ret) { \ + m_sock.close(); \ + ERR("Connection error (%d)", ret); \ + return HTTP_CONN; \ + } \ + } while(0) + +#define PRTCL_ERR() \ + do{ \ + m_sock.close(); \ + ERR("Protocol error"); \ + return HTTP_PRTCL; \ + } while(0) + +HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout) //Execute request +{ + m_httpResponseCode = 0; //Invalidate code + m_timeout = timeout; + + pDataIn->writeReset(); + if( pDataOut ) + { + pDataOut->readReset(); + } + + char scheme[8]; + uint16_t port; + char host[32]; + char path[64]; + //First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?) + HTTPResult res = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path)); + if(res != HTTP_OK) + { + ERR("parseURL returned %d", res); + return res; + } + + if(port == 0) //TODO do handle HTTPS->443 + { + port = 80; + } + + DBG("Scheme: %s", scheme); + DBG("Host: %s", host); + DBG("Port: %d", port); + DBG("Path: %s", path); + + //Connect + DBG("Connecting socket to server"); + int ret = m_sock.connect(host, port); + if (ret < 0) + { + m_sock.close(); + ERR("Could not connect"); + return HTTP_CONN; + } + + //Send request + DBG("Sending request"); + char buf[CHUNK_SIZE]; + const char* meth = (method==HTTP_GET)?"GET":(method==HTTP_POST)?"POST":(method==HTTP_PUT)?"PUT":(method==HTTP_DELETE)?"DELETE":""; + snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s\r\n", meth, path, host); //Write request + ret = send(buf); + if(ret) + { + m_sock.close(); + ERR("Could not write request"); + return HTTP_CONN; + } + + //Send all headers + + //Send default headers + DBG("Sending headers"); + if( pDataOut != NULL ) + { + if( pDataOut->getIsChunked() ) + { + ret = send("Transfer-Encoding: chunked\r\n"); + CHECK_CONN_ERR(ret); + } + else + { + snprintf(buf, sizeof(buf), "Content-Length: %d\r\n", pDataOut->getDataLen()); + ret = send(buf); + CHECK_CONN_ERR(ret); + } + char type[48]; + if( pDataOut->getDataType(type, 48) == HTTP_OK ) + { + snprintf(buf, sizeof(buf), "Content-Type: %s\r\n", type); + ret = send(buf); + CHECK_CONN_ERR(ret); + } + + //Send specific headers + while( pDataOut->getHeader(buf, sizeof(buf) - 3) ) //must have space left for CRLF + 0 terminating char + { + size_t headerlen = strlen(buf); + snprintf(buf + headerlen, sizeof(buf) - headerlen, "\r\n"); + ret = send(buf); + CHECK_CONN_ERR(ret); + } + } + + //Send specific headers + while( pDataIn->getHeader(buf, sizeof(buf) - 3) ) + { + size_t headerlen = strlen(buf); + snprintf(buf + headerlen, sizeof(buf) - headerlen, "\r\n"); + ret = send(buf); + CHECK_CONN_ERR(ret); + } + + //Close headers + DBG("Headers sent"); + ret = send("\r\n"); + CHECK_CONN_ERR(ret); + + size_t trfLen; + + //Send data (if available) + if( pDataOut != NULL ) + { + DBG("Sending data"); + while(true) + { + size_t writtenLen = 0; + pDataOut->read(buf, CHUNK_SIZE, &trfLen); + if( pDataOut->getIsChunked() ) + { + //Write chunk header + char chunkHeader[16]; + snprintf(chunkHeader, sizeof(chunkHeader), "%X\r\n", trfLen); //In hex encoding + ret = send(chunkHeader); + CHECK_CONN_ERR(ret); + } + else if( trfLen == 0 ) + { + break; + } + if( trfLen != 0 ) + { + ret = send(buf, trfLen); + CHECK_CONN_ERR(ret); + } + + if( pDataOut->getIsChunked() ) + { + ret = send("\r\n"); //Chunk-terminating CRLF + CHECK_CONN_ERR(ret); + } + else + { + writtenLen += trfLen; + if( writtenLen >= pDataOut->getDataLen() ) + { + break; + } + } + + if( trfLen == 0 ) + { + break; + } + } + } + + //Receive response + DBG("Receiving response"); + ret = recv(buf, 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes + CHECK_CONN_ERR(ret); + + buf[trfLen] = '\0'; + + //Make sure we got the first response line + char* crlfPtr = NULL; + while( true ) + { + crlfPtr = strstr(buf, "\r\n"); + if(crlfPtr == NULL) + { + if( trfLen < CHUNK_SIZE - 1 ) + { + size_t newTrfLen; + ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen); + trfLen += newTrfLen; + buf[trfLen] = '\0'; + DBG("Read %d chars; In buf: [%s]", newTrfLen, buf); + CHECK_CONN_ERR(ret); + continue; + } + else + { + PRTCL_ERR(); + } + } + break; + } + + int crlfPos = crlfPtr - buf; + buf[crlfPos] = '\0'; + + //Parse HTTP response + //if( sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &m_httpResponseCode) != 1 ) + if(crlfPos > 13) + { + buf[13] = '\0'; + } + if( sscanf(buf, "HTTP/%*d.%*d %d", &m_httpResponseCode) != 1 ) //Kludge for newlib nano + { + //Cannot match string, error + ERR("Not a correct HTTP answer : %s\n", buf); + PRTCL_ERR(); + } + + if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) + { + //Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers + WARN("Response code %d", m_httpResponseCode); + PRTCL_ERR(); + } + + DBG("Reading headers"); + + memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well + trfLen -= (crlfPos + 2); + + size_t recvContentLength = 0; + bool recvChunked = false; + bool recvLengthUnknown = true; + //Now get headers + while( true ) + { + crlfPtr = strstr(buf, "\r\n"); + if(crlfPtr == NULL) + { + if( trfLen < CHUNK_SIZE - 1 ) + { + size_t newTrfLen; + ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen); + trfLen += newTrfLen; + buf[trfLen] = '\0'; + DBG("Read %d chars; In buf: [%s]", newTrfLen, buf); + CHECK_CONN_ERR(ret); + continue; + } + else + { + PRTCL_ERR(); + } + } + + crlfPos = crlfPtr - buf; + + if(crlfPos == 0) //End of headers + { + DBG("Headers read"); + memmove(buf, &buf[2], trfLen - 2 + 1); //Be sure to move NULL-terminating char as well + trfLen -= 2; + break; + } + + buf[crlfPos] = '\0'; + + char key[32]; + char value[32]; + + //key[31] = '\0'; + //value[31] = '\0'; + + memset(key, 0, 32); + memset(value, 0, 32); + + //int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value); + + int n = 0; + + char* keyEnd = strchr(buf, ':'); + if(keyEnd != NULL) + { + *keyEnd = '\0'; + if(strlen(buf) < 32) + { + strcpy(key, buf); + n++; + char* valueStart = keyEnd + 2; + if( (valueStart - buf) < crlfPos ) + { + if(strlen(valueStart) < 32) + { + strcpy(value, valueStart); + n++; + } + } + } + } + if ( n == 2 ) + { + DBG("Read header : %s: %s\n", key, value); + if( !strcmp(key, "Content-Length") ) + { + sscanf(value, "%d", &recvContentLength); + recvLengthUnknown = false; + pDataIn->setDataLen(recvContentLength); + } + else if( !strcmp(key, "Transfer-Encoding") ) + { + if( !strcmp(value, "Chunked") || !strcmp(value, "chunked") ) + { + recvChunked = true; + recvLengthUnknown = false; + pDataIn->setIsChunked(true); + } + } + else if( !strcmp(key, "Content-Type") ) + { + pDataIn->setDataType(value); + } + + memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well + trfLen -= (crlfPos + 2); + + } + else + { + ERR("Could not parse header"); + PRTCL_ERR(); + } + + } + + //Receive data + DBG("Receiving data"); + while(true) + { + size_t readLen = 0; + + if( recvChunked ) + { + //Read chunk header + bool foundCrlf; + do + { + foundCrlf = false; + crlfPos=0; + buf[trfLen]=0; + if(trfLen >= 2) + { + for(; crlfPos < trfLen - 2; crlfPos++) + { + if( buf[crlfPos] == '\r' && buf[crlfPos + 1] == '\n' ) + { + foundCrlf = true; + break; + } + } + } + if(!foundCrlf) //Try to read more + { + if( trfLen < CHUNK_SIZE ) + { + size_t newTrfLen; + ret = recv(buf + trfLen, 0, CHUNK_SIZE - trfLen - 1, &newTrfLen); + trfLen += newTrfLen; + CHECK_CONN_ERR(ret); + continue; + } + else + { + PRTCL_ERR(); + } + } + } while(!foundCrlf); + buf[crlfPos] = '\0'; + int n = sscanf(buf, "%x", &readLen); + if(n!=1) + { + ERR("Could not read chunk length"); + PRTCL_ERR(); + } + + memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2)); //Not need to move NULL-terminating char any more + trfLen -= (crlfPos + 2); + + if( readLen == 0 ) + { + //Last chunk + break; + } + } + else + { + readLen = recvContentLength; + } + + DBG("Retrieving %d bytes (%d bytes in buffer)", readLen, trfLen); + + do + { + if(recvLengthUnknown ) + { + readLen = trfLen; + } + pDataIn->write(buf, MIN(trfLen, readLen)); + if(!recvLengthUnknown) + { + if( trfLen > readLen ) + { + memmove(buf, &buf[readLen], trfLen - readLen); + trfLen -= readLen; + readLen = 0; + } + else + { + readLen -= trfLen; + } + } + else + { + trfLen = 0; + } + + if(readLen || recvLengthUnknown) + { + ret = recv(buf, 1, CHUNK_SIZE - trfLen - 1, &trfLen); + if(recvLengthUnknown && (ret == HTTP_CLOSED)) + { + //Write and exit + pDataIn->write(buf, trfLen); + break; + } + CHECK_CONN_ERR(ret); + if(recvLengthUnknown && (trfLen == 0)) + { + break; + } + } + } while(readLen || recvLengthUnknown); + + if( recvChunked ) + { + if(trfLen < 2) + { + size_t newTrfLen; + //Read missing chars to find end of chunk + ret = recv(buf + trfLen, 2 - trfLen, CHUNK_SIZE - trfLen - 1, &newTrfLen); + CHECK_CONN_ERR(ret); + trfLen += newTrfLen; + } + if( (buf[0] != '\r') || (buf[1] != '\n') ) + { + ERR("Format error"); + PRTCL_ERR(); + } + memmove(buf, &buf[2], trfLen - 2); + trfLen -= 2; + } + else + { + break; + } + + } + + m_sock.close(); + DBG("Completed HTTP transaction"); + + return HTTP_OK; +} + +HTTPResult HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure +{ + DBG("Trying to read between %d and %d bytes", minLen, maxLen); + size_t readLen = 0; + + if(!m_sock.is_connected()) + { + WARN("Connection was closed by server"); + return HTTP_CLOSED; //Connection was closed by server + } + + int ret; + while(readLen < maxLen) + { + if(readLen < minLen) + { + DBG("Trying to read at most %d bytes [Blocking]", minLen - readLen); + m_sock.set_blocking(false, m_timeout); + ret = m_sock.receive_all(buf + readLen, minLen - readLen); + } + else + { + DBG("Trying to read at most %d bytes [Not blocking]", maxLen - readLen); + m_sock.set_blocking(false, 0); + ret = m_sock.receive(buf + readLen, maxLen - readLen); + } + + if( ret > 0) + { + readLen += ret; + } + else if( ret == 0 ) + { + break; + } + else + { + if(!m_sock.is_connected()) + { + ERR("Connection error (recv returned %d)", ret); + *pReadLen = readLen; + return HTTP_CONN; + } + else + { + break; + } + } + + if(!m_sock.is_connected()) + { + break; + } + } + DBG("Read %d bytes", readLen); + *pReadLen = readLen; + return HTTP_OK; +} + +HTTPResult HTTPClient::send(char* buf, size_t len) //0 on success, err code on failure +{ + if(len == 0) + { + len = strlen(buf); + } + DBG("Trying to write %d bytes", len); + size_t writtenLen = 0; + + if(!m_sock.is_connected()) + { + WARN("Connection was closed by server"); + return HTTP_CLOSED; //Connection was closed by server + } + + m_sock.set_blocking(false, m_timeout); + int ret = m_sock.send_all(buf, len); + if(ret > 0) + { + writtenLen += ret; + } + else if( ret == 0 ) + { + WARN("Connection was closed by server"); + return HTTP_CLOSED; //Connection was closed by server + } + else + { + ERR("Connection error (send returned %d)", ret); + return HTTP_CONN; + } + + DBG("Written %d bytes", writtenLen); + return HTTP_OK; +} + +HTTPResult HTTPClient::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL +{ + char* schemePtr = (char*) url; + char* hostPtr = (char*) strstr(url, "://"); + if(hostPtr == NULL) + { + WARN("Could not find host"); + return HTTP_PARSE; //URL is invalid + } + + if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char + { + WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1); + return HTTP_PARSE; + } + memcpy(scheme, schemePtr, hostPtr - schemePtr); + scheme[hostPtr - schemePtr] = '\0'; + + hostPtr+=3; + + size_t hostLen = 0; + + char* portPtr = strchr(hostPtr, ':'); + if( portPtr != NULL ) + { + hostLen = portPtr - hostPtr; + portPtr++; + if( sscanf(portPtr, "%hu", port) != 1) + { + WARN("Could not find port"); + return HTTP_PARSE; + } + } + else + { + *port=0; + } + char* pathPtr = strchr(hostPtr, '/'); + if( hostLen == 0 ) + { + hostLen = pathPtr - hostPtr; + } + + if( maxHostLen < hostLen + 1 ) //including NULL-terminating char + { + WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1); + return HTTP_PARSE; + } + memcpy(host, hostPtr, hostLen); + host[hostLen] = '\0'; + + size_t pathLen; + char* fragmentPtr = strchr(hostPtr, '#'); + if(fragmentPtr != NULL) + { + pathLen = fragmentPtr - pathPtr; + } + else + { + pathLen = strlen(pathPtr); + } + + if( maxPathLen < pathLen + 1 ) //including NULL-terminating char + { + WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1); + return HTTP_PARSE; + } + memcpy(path, pathPtr, pathLen); + path[pathLen] = '\0'; + + return HTTP_OK; +} diff --git a/examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.h b/examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.h new file mode 100644 index 00000000..25301c36 --- /dev/null +++ b/examples/mbed/mbed-http-client/lib/HTTPClient/HTTPClient.h @@ -0,0 +1,159 @@ +/* HTTPClient.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** \file +HTTP Client header file +*/ + +#ifndef HTTP_CLIENT_H +#define HTTP_CLIENT_H + +#include "TCPSocketConnection.h" + +#define HTTP_CLIENT_DEFAULT_TIMEOUT 15000 + +class HTTPData; + +#include "IHTTPData.h" +#include "mbed.h" + +///HTTP client results +enum HTTPResult +{ + HTTP_PROCESSING, /// + +using std::size_t; + +class IHTTPData +{ + protected: + /** Get a specific header + * + */ + virtual bool getHeader(char* header, size_t maxHeaderLen) { return false; } +}; + +///This is a simple interface for HTTP data storage (impl examples are Key/Value Pairs, File, etc...) +class IHTTPDataOut : public IHTTPData +{ +protected: + friend class HTTPClient; + + /** Reset stream to its beginning + * Called by the HTTPClient on each new request + */ + virtual void readReset() = 0; + + /** Read a piece of data to be transmitted + * @param buf Pointer to the buffer on which to copy the data + * @param len Length of the buffer + * @param pReadLen Pointer to the variable on which the actual copied data length will be stored + */ + virtual int read(char* buf, size_t len, size_t* pReadLen) = 0; + + /** Get MIME type + * @param type Internet media type from Content-Type header + */ + virtual int getDataType(char* type, size_t maxTypeLen) = 0; //Internet media type for Content-Type header + + /** Determine whether the HTTP client should chunk the data + * Used for Transfer-Encoding header + */ + virtual bool getIsChunked() = 0; + + /** If the data is not chunked, get its size + * Used for Content-Length header + */ + virtual size_t getDataLen() = 0; + +}; + +///This is a simple interface for HTTP data storage (impl examples are Key/Value Pairs, File, etc...) +class IHTTPDataIn : public IHTTPData +{ +protected: + friend class HTTPClient; + + /** Reset stream to its beginning + * Called by the HTTPClient on each new request + */ + virtual void writeReset() = 0; + + /** Write a piece of data transmitted by the server + * @param buf Pointer to the buffer from which to copy the data + * @param len Length of the buffer + */ + virtual int write(const char* buf, size_t len) = 0; + + /** Set MIME type + * @param type Internet media type from Content-Type header + */ + virtual void setDataType(const char* type) = 0; + + /** Determine whether the data is chunked + * Recovered from Transfer-Encoding header + */ + virtual void setIsChunked(bool chunked) = 0; + + /** If the data is not chunked, set its size + * From Content-Length header + */ + virtual void setDataLen(size_t len) = 0; + +}; + +#endif diff --git a/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.cpp b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.cpp new file mode 100644 index 00000000..5eb4c52e --- /dev/null +++ b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.cpp @@ -0,0 +1,200 @@ +/* HTTPMap.cpp */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "HTTPMap.h" + +#include + +#include + +#define OK 0 + +using std::strncpy; + +HTTPMap::HTTPMap() : m_pos(0), m_count(0) +{ + +} + +void HTTPMap::put(const char* key, const char* value) +{ + if(m_count >= HTTPMAP_TABLE_SIZE) + { + return; + } + m_keys[m_count] = key; + m_values[m_count] = value; + m_count++; +} + +void HTTPMap::clear() +{ + m_count = 0; + m_pos = 0; +} + +/*virtual*/ void HTTPMap::readReset() +{ + m_pos = 0; +} + +/*virtual*/ int HTTPMap::read(char* buf, size_t len, size_t* pReadLen) +{ + if(m_pos >= m_count) + { + *pReadLen = 0; + m_pos = 0; + return OK; + } + + //URL encode + char* out = buf; + const char* in = m_keys[m_pos]; + if( (m_pos != 0) && (out - buf < len - 1) ) + { + *out='&'; + out++; + } + + while( (*in != '\0') && (out - buf < len - 3) ) + { + if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~') + { + *out = *in; + out++; + } + else if( *in == ' ' ) + { + *out='+'; + out++; + } + else + { + char hex[] = "0123456789abcdef"; + *out='%'; + out++; + *out=hex[(*in>>4)&0xf]; + out++; + *out=hex[(*in)&0xf]; + out++; + } + in++; + } + + if( out - buf < len - 1 ) + { + *out='='; + out++; + } + + in = m_values[m_pos]; + while( (*in != '\0') && (out - buf < len - 3) ) + { + if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~') + { + *out = *in; + out++; + } + else if( *in == ' ' ) + { + *out='+'; + out++; + } + else + { + char hex[] = "0123456789abcdef"; + *out='%'; + out++; + *out=hex[(*in>>4)&0xf]; + out++; + *out=hex[(*in)&0xf]; + out++; + } + in++; + } + + *pReadLen = out - buf; + + m_pos++; + return OK; +} + +/*virtual*/ int HTTPMap::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header +{ + strncpy(type, "application/x-www-form-urlencoded", maxTypeLen-1); + type[maxTypeLen-1] = '\0'; + return OK; +} + +/*virtual*/ bool HTTPMap::getIsChunked() //For Transfer-Encoding header +{ + return false; ////Data is computed one key/value pair at a time +} + +/*virtual*/ size_t HTTPMap::getDataLen() //For Content-Length header +{ + size_t count = 0; + for(size_t i = 0; i< m_count; i++) + { + //URL encode + const char* in = m_keys[i]; + if( i != 0 ) + { + count++; + } + + while( (*in != '\0') ) + { + if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~') + { + count++; + } + else if( *in == ' ' ) + { + count++; + } + else + { + count+=3; + } + in++; + } + + count ++; + + in = m_values[i]; + while( (*in != '\0') ) + { + if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~') + { + count++; + } + else if( *in == ' ' ) + { + count++; + } + else + { + count+=3; + } + in++; + } + } + return count; +} diff --git a/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.h b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.h new file mode 100644 index 00000000..c8433778 --- /dev/null +++ b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPMap.h @@ -0,0 +1,71 @@ +/* HTTPMap.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef HTTPMAP_H_ +#define HTTPMAP_H_ + +#include "../IHTTPData.h" + +#define HTTPMAP_TABLE_SIZE 32 + +/** Map of key/value pairs + * Used to transmit POST data using the application/x-www-form-urlencoded encoding + */ +class HTTPMap: public IHTTPDataOut +{ +public: + /** + Instantiates HTTPMap + It supports at most 32 key/values pairs + */ + HTTPMap(); + + /** Put Key/Value pair + The references to the parameters must remain valid as long as the clear() function is not called + @param key The key to use + @param value The corresponding value + */ + void put(const char* key, const char* value); + + /** Clear table + */ + void clear(); + +protected: + //IHTTPDataIn + virtual void readReset(); + + virtual int read(char* buf, size_t len, size_t* pReadLen); + + virtual int getDataType(char* type, size_t maxTypeLen); //Internet media type for Content-Type header + + virtual bool getIsChunked(); //For Transfer-Encoding header + + virtual size_t getDataLen(); //For Content-Length header + +private: + const char* m_keys[HTTPMAP_TABLE_SIZE]; + const char* m_values[HTTPMAP_TABLE_SIZE]; + + size_t m_pos; + size_t m_count; +}; + +#endif /* HTTPMAP_H_ */ diff --git a/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.cpp b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.cpp new file mode 100644 index 00000000..18cd4207 --- /dev/null +++ b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.cpp @@ -0,0 +1,104 @@ +/* HTTPText.cpp */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "HTTPText.h" + +#include + +#define OK 0 + +using std::memcpy; +using std::strncpy; +using std::strlen; + +#define MIN(x,y) (((x)<(y))?(x):(y)) + +HTTPText::HTTPText(char* str) : m_str(str), m_pos(0) +{ + m_size = strlen(str) + 1; +} + +HTTPText::HTTPText(char* str, size_t size) : m_str(str), m_size(size), m_pos(0) +{ + +} + +//IHTTPDataIn +/*virtual*/ void HTTPText::readReset() +{ + m_pos = 0; +} + +/*virtual*/ int HTTPText::read(char* buf, size_t len, size_t* pReadLen) +{ + *pReadLen = MIN(len, m_size - 1 - m_pos); + memcpy(buf, m_str + m_pos, *pReadLen); + m_pos += *pReadLen; + return OK; +} + +/*virtual*/ int HTTPText::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header +{ + strncpy(type, "text/plain", maxTypeLen-1); + type[maxTypeLen-1] = '\0'; + return OK; +} + +/*virtual*/ bool HTTPText::getIsChunked() //For Transfer-Encoding header +{ + return false; +} + +/*virtual*/ size_t HTTPText::getDataLen() //For Content-Length header +{ + return m_size - 1; +} + +//IHTTPDataOut +/*virtual*/ void HTTPText::writeReset() +{ + m_pos = 0; +} + +/*virtual*/ int HTTPText::write(const char* buf, size_t len) +{ + size_t writeLen = MIN(len, m_size - 1 - m_pos); + memcpy(m_str + m_pos, buf, writeLen); + m_pos += writeLen; + m_str[m_pos] = '\0'; + return OK; +} + +/*virtual*/ void HTTPText::setDataType(const char* type) //Internet media type from Content-Type header +{ + +} + +/*virtual*/ void HTTPText::setIsChunked(bool chunked) //From Transfer-Encoding header +{ + +} + +/*virtual*/ void HTTPText::setDataLen(size_t len) //From Content-Length header, or if the transfer is chunked, next chunk length +{ + +} + + + diff --git a/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.h b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.h new file mode 100644 index 00000000..f55ff762 --- /dev/null +++ b/examples/mbed/mbed-http-client/lib/HTTPClient/data/HTTPText.h @@ -0,0 +1,72 @@ +/* HTTPText.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef HTTPTEXT_H_ +#define HTTPTEXT_H_ + +#include "../IHTTPData.h" + +/** A data endpoint to store text +*/ +class HTTPText : public IHTTPDataIn, public IHTTPDataOut +{ +public: + /** Create an HTTPText instance for output + * @param str String to be transmitted + */ + HTTPText(char* str); + + /** Create an HTTPText instance for input + * @param str Buffer to store the incoming string + * @param size Size of the buffer + */ + HTTPText(char* str, size_t size); + +protected: + //IHTTPDataIn + virtual void readReset(); + + virtual int read(char* buf, size_t len, size_t* pReadLen); + + virtual int getDataType(char* type, size_t maxTypeLen); //Internet media type for Content-Type header + + virtual bool getIsChunked(); //For Transfer-Encoding header + + virtual size_t getDataLen(); //For Content-Length header + + //IHTTPDataOut + virtual void writeReset(); + + virtual int write(const char* buf, size_t len); + + virtual void setDataType(const char* type); //Internet media type from Content-Type header + + virtual void setIsChunked(bool chunked); //From Transfer-Encoding header + + virtual void setDataLen(size_t len); //From Content-Length header, or if the transfer is chunked, next chunk length + +private: + char* m_str; + size_t m_size; + + size_t m_pos; +}; + +#endif /* HTTPTEXT_H_ */ diff --git a/examples/mbed/mbed-http-client/platformio.ini b/examples/mbed/mbed-http-client/platformio.ini new file mode 100644 index 00000000..65c87729 --- /dev/null +++ b/examples/mbed/mbed-http-client/platformio.ini @@ -0,0 +1,25 @@ +# +# Project Configuration File +# +# A detailed documentation with the EXAMPLES is located here: +# http://docs.platformio.org/en/latest/projectconf.html +# + +# A sign `#` at the beginning of the line indicates a comment +# Comment lines are ignored. + +# Simple and base environment +# [env:mybaseenv] +# platform = %INSTALLED_PLATFORM_NAME_HERE% +# framework = +# board = +# +# Automatic targets - enable auto-uploading +# targets = upload + + +# NXP LPC Platform +[env:lpc1768] +platform = nxplpc +framework = mbed +board = lpc1768 diff --git a/examples/mbed/mbed-http-client/src/main.cpp b/examples/mbed/mbed-http-client/src/main.cpp new file mode 100644 index 00000000..2e69c69a --- /dev/null +++ b/examples/mbed/mbed-http-client/src/main.cpp @@ -0,0 +1,79 @@ +#include "mbed.h" +#include "EthernetInterface.h" +#include "HTTPClient.h" + +EthernetInterface eth; +HTTPClient http; +char str[512]; + +int main() +{ + eth.init(); //Use DHCP + + eth.connect(); + + //GET data + printf("\nTrying to fetch page...\n"); + int ret = http.get("http://mbed.org/media/uploads/donatien/hello.txt", str, 128); + if (!ret) + { + printf("Page fetched successfully - read %d characters\n", strlen(str)); + printf("Result: %s\n", str); + } + else + { + printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode()); + } + + //POST data + HTTPMap map; + HTTPText inText(str, 512); + map.put("Hello", "World"); + map.put("test", "1234"); + printf("\nTrying to post data...\n"); + ret = http.post("http://httpbin.org/post", map, &inText); + if (!ret) + { + printf("Executed POST successfully - read %d characters\n", strlen(str)); + printf("Result: %s\n", str); + } + else + { + printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode()); + } + + //PUT data + strcpy(str, "This is a PUT test!"); + HTTPText outText(str); + //HTTPText inText(str, 512); + printf("\nTrying to put resource...\n"); + ret = http.put("http://httpbin.org/put", outText, &inText); + if (!ret) + { + printf("Executed PUT successfully - read %d characters\n", strlen(str)); + printf("Result: %s\n", str); + } + else + { + printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode()); + } + + //DELETE data + //HTTPText inText(str, 512); + printf("\nTrying to delete resource...\n"); + ret = http.del("http://httpbin.org/delete", &inText); + if (!ret) + { + printf("Executed DELETE successfully - read %d characters\n", strlen(str)); + printf("Result: %s\n", str); + } + else + { + printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode()); + } + + eth.disconnect(); + + while(1) { + } +} diff --git a/examples/mbed/mbed-rtos/README.rst b/examples/mbed/mbed-rtos/README.rst new file mode 100644 index 00000000..6411da4b --- /dev/null +++ b/examples/mbed/mbed-rtos/README.rst @@ -0,0 +1,21 @@ +How to build PlatformIO based project +==================================== + +1. `Install PlatformIO `_ +2. Download `source code with examples `_ +3. Extract ZIP archive +4. Run these commands: + +.. code-block:: bash + + # Change directory to example + > cd platformio-develop/examples/mbed/mbed-rtos + + # Process example project + > platformio run + + # Upload firmware + > platformio run --target upload + + # Clean build files + > platformio run --target clean diff --git a/examples/mbed/mbed-rtos/platformio.ini b/examples/mbed/mbed-rtos/platformio.ini new file mode 100644 index 00000000..cb93e0e6 --- /dev/null +++ b/examples/mbed/mbed-rtos/platformio.ini @@ -0,0 +1,37 @@ +# +# Project Configuration File +# +# A detailed documentation with the EXAMPLES is located here: +# http://docs.platformio.org/en/latest/projectconf.html +# + +# A sign `#` at the beginning of the line indicates a comment +# Comment lines are ignored. + +# Simple and base environment +# [env:mybaseenv] +# platform = %INSTALLED_PLATFORM_NAME_HERE% +# framework = +# board = +# +# Automatic targets - enable auto-uploading +# targets = upload + + +# NXP LPC Platform +[env:lpc1768] +platform = nxplpc +framework = mbed +board = lpc1768 + +# Freescale FRDM Platform +[env:frdm_kl25z] +platform = freescalekinetis +framework = mbed +board = frdm_kl25z + +# ST STM32 Platform +[env:nucleo_f401re] +platform = ststm32 +framework = mbed +board = nucleo_f401re diff --git a/examples/mbed/mbed-rtos/src/main.cpp b/examples/mbed/mbed-rtos/src/main.cpp new file mode 100644 index 00000000..a1aa46d1 --- /dev/null +++ b/examples/mbed/mbed-rtos/src/main.cpp @@ -0,0 +1,38 @@ +#include "mbed.h" +#include "rtos.h" + +/* + * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and + * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes + * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize. + */ +#if defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) +#define STACK_SIZE DEFAULT_STACK_SIZE/4 +#else +#define STACK_SIZE DEFAULT_STACK_SIZE +#endif + +void print_char(char c = '*') { + printf("%c", c); + fflush(stdout); +} + +DigitalOut led1(LED1); +DigitalOut led2(LED2); + +void led2_thread(void const *argument) { + while (true) { + led2 = !led2; + Thread::wait(1000); + print_char(); + } +} + +int main() { + Thread thread(led2_thread, NULL, osPriorityNormal, STACK_SIZE); + + while (true) { + led1 = !led1; + Thread::wait(500); + } +} diff --git a/platformio/boards/freescalekinetis.json b/platformio/boards/freescalekinetis.json index 88be3603..869a977a 100644 --- a/platformio/boards/freescalekinetis.json +++ b/platformio/boards/freescalekinetis.json @@ -78,8 +78,7 @@ }, "url": "https://developer.mbed.org/platforms/FRDM-K20D50M/", "vendor": "Freescale" - } - , + }, "frdm_k22f": { "build": { "f_cpu": "120000000L", @@ -95,5 +94,21 @@ }, "url": "https://developer.mbed.org/platforms/FRDM-K22F/", "vendor": "Freescale" + }, + "IBMEthernetKit": { + "build": { + "f_cpu": "120000000L", + "cpu": "cortex-m4", + "mcu": "mk64fn1m0vll12" + }, + "frameworks": ["mbed"], + "name": "Ethernet IoT Starter Kit", + "platform": "freescalekinetis", + "upload": { + "maximum_ram_size": 262144, + "maximum_size": 1048576 + }, + "url": "http://developer.mbed.org/platforms/IBMEthernetKit/", + "vendor": "Freescale" } } \ No newline at end of file diff --git a/platformio/boards/nordicnrf51.json b/platformio/boards/nordicnrf51.json index acdabaee..abe44026 100644 --- a/platformio/boards/nordicnrf51.json +++ b/platformio/boards/nordicnrf51.json @@ -94,8 +94,7 @@ }, "url": "https://developer.mbed.org/platforms/Nordic-nRF51-Dongle/", "vendor": "Nordic" - } - , + }, "wallBotBLE": { "build": { "f_cpu": "16000000L", @@ -111,6 +110,21 @@ }, "url": "https://developer.mbed.org/platforms/JKSoft-Wallbot-BLE/", "vendor": "JKSoft" + }, + "seeedTinyBLE": { + "build": { + "f_cpu": "16000000L", + "cpu": "cortex-m0", + "mcu": "nrf51822" + }, + "frameworks": ["mbed"], + "name": "Seeed Tiny BLE", + "platform": "nordicnrf51", + "upload": { + "maximum_ram_size": 16384, + "maximum_size": 262144 + }, + "url": "http://developer.mbed.org/platforms/Seeed-Tiny-BLE/", + "vendor": "SeeedStudio" } - } \ No newline at end of file diff --git a/platformio/boards/ststm32.json b/platformio/boards/ststm32.json index 20b77108..8b45b992 100644 --- a/platformio/boards/ststm32.json +++ b/platformio/boards/ststm32.json @@ -235,6 +235,22 @@ "url": "https://developer.mbed.org/platforms/ST-Nucleo-F302R8/", "vendor": "ST" }, + "nucleo_f303re": { + "build": { + "f_cpu": "72000000L", + "cpu": "cortex-m4", + "mcu": "stm32f303ret6" + }, + "frameworks": ["mbed"], + "name": "ST Nucleo F303RE", + "platform": "ststm32", + "upload": { + "maximum_ram_size": 65536, + "maximum_size": 524288 + }, + "url": "http://developer.mbed.org/platforms/ST-Nucleo-F303RE/", + "vendor": "ST" + }, "nucleo_f334r8": { "build": { "f_cpu": "72000000L", diff --git a/platformio/builder/scripts/frameworks/mbed.py b/platformio/builder/scripts/frameworks/mbed.py index a53eeb0e..191e04d1 100644 --- a/platformio/builder/scripts/frameworks/mbed.py +++ b/platformio/builder/scripts/frameworks/mbed.py @@ -15,11 +15,13 @@ the mbed Developer Community. http://mbed.org/ """ +import re import xml.etree.ElementTree as ElementTree from binascii import crc32 -from os.path import join, normpath +from os import walk +from os.path import basename, isfile, join, normpath -from SCons.Script import DefaultEnvironment +from SCons.Script import DefaultEnvironment, Exit env = DefaultEnvironment() @@ -41,9 +43,10 @@ MBED_VARIANTS = { "lpc11u35": "LPC11U35_401", "mbuino": "LPC11U24", "nrf51_mkit": "NRF51822", - "redBearLab": "NRF51822", + "seeedTinyBLE": "SEEED_TINY_BLE", + "redBearLab": "RBLAB_NRF51822", "nrf51-dt": "NRF51_DK", - "redBearLabBLENano": "NRF51822", + "redBearLabBLENano": "RBLAB_NRF51822", "wallBotBLE": "NRF51822", "frdm_kl25z": "KL25Z", "frdm_kl46z": "KL46Z", @@ -53,6 +56,86 @@ MBED_VARIANTS = { "frdm_k22f": "K22F" } +MBED_LIBS_MAP = { + "dsp": {"ar": ["dsp", "cmsis_dsp"]}, + "eth": {"ar": ["eth"], "deps": ["rtos"]}, + "fat": {"ar": ["fat"]}, + "rtos": {"ar": ["rtos", "rtx"]}, + "usb": {"ar": ["USBDevice"]}, + "usb_host": {"ar": ["USBHost"]} +} + + +def get_mbedlib_includes(): + result = [] + for lib in MBED_LIBS_MAP.keys(): + includes = [] + lib_dir = join(env.subst("$PLATFORMFW_DIR"), "libs", lib) + for _, _, files in walk(lib_dir): + for libfile in files: + if libfile.endswith(".h"): + includes.append(libfile) + result.append((lib, set(includes))) + return result + + +def get_used_mbedlibs(): + re_includes = re.compile(r"^(#include\s+(?:\<|\")([^\r\n\"]+))", + re.M | re.I) + srcincs = [] + for root, _, files in walk(env.get("PROJECTSRC_DIR")): + for pfile in files: + if not any([pfile.endswith(ext) for ext in (".h", ".c", ".cpp")]): + continue + with open(join(root, pfile)) as fp: + srcincs.extend([i[1] for i in re_includes.findall(fp.read())]) + srcincs = set(srcincs) + + result = {} + for libname, libincs in get_mbedlib_includes(): + if libincs & srcincs and libname not in result: + result[libname] = MBED_LIBS_MAP[libname] + + return result + + +def add_mbedlib(libname, libar): + if libar in env.get("LIBS"): + return + + lib_dir = join(env.subst("$PLATFORMFW_DIR"), "libs", libname) + if not isfile(join(lib_dir, "TARGET_%s" % variant, + "TOOLCHAIN_GCC_ARM", "lib%s.a" % libar)): + Exit("Error: %s board doesn't support %s library!" % + (env.get("BOARD"), libname)) + + env.Append( + LIBPATH=[ + join(env.subst("$PLATFORMFW_DIR"), "libs", libname, + "TARGET_%s" % variant, "TOOLCHAIN_GCC_ARM") + ], + LIBS=[libar] + ) + + sysincdirs = ( + "eth", + "include", + "ipv4", + "lwip-eth", + "lwip-sys" + ) + + for root, _, files in walk(lib_dir): + if (not any(f.endswith(".h") for f in files) and + basename(root) not in sysincdirs): + continue + var_dir = join("$BUILD_DIR", "FrameworkMbed%sInc%d" % + (libname.upper(), crc32(root))) + if var_dir in env.get("CPPPATH"): + continue + env.VariantDir(var_dir, root) + env.Append(CPPPATH=[var_dir]) + def parse_eix_file(filename): result = {} @@ -93,6 +176,7 @@ def get_build_flags(data): flags['CFLAGS'] = list(cflags - cppflags) return flags + board_type = env.subst("$BOARD") variant = MBED_VARIANTS[ board_type] if board_type in MBED_VARIANTS else board_type.upper() @@ -123,7 +207,6 @@ for lib_path in eixdata.get("CPPPATH"): env.VariantDir(_vdir, join(variant_dir, lib_path)) env.Append(CPPPATH=[_vdir]) - env.Append( LIBPATH=[join(variant_dir, lib_path) for lib_path in eixdata.get("LIBPATH", []) @@ -135,7 +218,7 @@ env.Append( # libs = [l for l in eixdata.get("STDLIBS", []) if l not in env.get("LIBS")] -libs.append("mbed") +libs.extend(["mbed", "c", "gcc"]) libs.append(env.Library( join("$BUILD_DIR", "FrameworkMbed"), @@ -144,3 +227,12 @@ libs.append(env.Library( )) env.Append(LIBS=libs) + +for _libname, _libdata in get_used_mbedlibs().iteritems(): + for _libar in _libdata['ar']: + add_mbedlib(_libname, _libar) + if "deps" not in _libdata: + continue + for libdep in _libdata['deps']: + for _libar in MBED_LIBS_MAP[libdep]['ar']: + add_mbedlib(libdep, _libar) diff --git a/scripts/mbed_to_package.py b/scripts/mbed_to_package.py index 877c3473..3e13e460 100644 --- a/scripts/mbed_to_package.py +++ b/scripts/mbed_to_package.py @@ -11,7 +11,7 @@ from sys import path path.append("..") -from platformio.util import exec_command +from platformio.util import exec_command, get_home_dir def _unzip_generated_file(mbed_dir, output_dir, mcu): @@ -19,7 +19,6 @@ def _unzip_generated_file(mbed_dir, output_dir, mcu): mbed_dir, "build", "export", "MBED_A1_emblocks_%s.zip" % mcu) variant_dir = join(output_dir, "variant", mcu) if isfile(filename): - print "Processing board: %s" % mcu with zipfile.ZipFile(filename) as zfile: mkdir(variant_dir) zfile.extractall(variant_dir) @@ -34,6 +33,33 @@ def _unzip_generated_file(mbed_dir, output_dir, mcu): print "Warning! Skipped board: %s" % mcu +def buildlib(mbed_dir, mcu, lib="mbed"): + build_command = [ + "python", + join(mbed_dir, "workspace_tools", "build.py"), + "--mcu", mcu, + "-t", "GCC_ARM" + ] + if lib is not "mbed": + build_command.append(lib) + build_result = exec_command(build_command, cwd=getcwd()) + if build_result['returncode'] != 0: + print "* %s doesn't support %s library!" % (mcu, lib) + + +def copylibs(mbed_dir, output_dir): + libs = ["dsp", "fat", "net", "rtos", "usb", "usb_host"] + libs_dir = join(output_dir, "libs") + makedirs(libs_dir) + + print "Moving generated libraries to framework dir..." + for lib in libs: + if lib == "net": + move(join(mbed_dir, "build", lib, "eth"), libs_dir) + continue + move(join(mbed_dir, "build", lib), libs_dir) + + def main(mbed_dir, output_dir): print "Starting..." @@ -44,18 +70,34 @@ def main(mbed_dir, output_dir): print "Deleting previous framework dir..." rmtree(output_dir) + settings_file = join(mbed_dir, "workspace_tools", "private_settings.py") + if not isfile(settings_file): + with open(settings_file, "w") as f: + f.write("GCC_ARM_PATH = '%s'" % + join(get_home_dir(), "packages", "toolchain-gccarmnoneeabi", + "bin")) + makedirs(join(output_dir, "variant")) - # make .eix files + mbed_libs = ["--rtos", "--dsp", "--fat", "--eth", "--usb", "--usb_host"] + for mcu in set(gccarm.GccArm.TARGETS): - exec_command( - ["python", join(mbed_dir, "workspace_tools", "build.py"), - "--mcu", mcu, "-t", "GCC_ARM"], cwd=getcwd() - ) - exec_command( + print "Processing board: %s" % mcu + buildlib(mbed_dir, mcu) + for lib in mbed_libs: + buildlib(mbed_dir, mcu, lib) + result = exec_command( ["python", join(mbed_dir, "workspace_tools", "project.py"), "--mcu", mcu, "-i", "emblocks", "-p", "0", "-b"], cwd=getcwd() ) + if result['returncode'] != 0: + print "Unable to build the project for %s" % mcu + continue _unzip_generated_file(mbed_dir, output_dir, mcu) + copylibs(mbed_dir, output_dir) + + with open(join(output_dir, "boards.txt"), "w") as fp: + fp.write("\n".join(sorted(listdir(join(output_dir, "variant"))))) + print "Complete!"