Compare commits

...

144 Commits

Author SHA1 Message Date
71e3d515f3 Fix BLEUUID toString (#3289)
uuid16 is Missing first 4 characters.
uuid is Missing last 2 characters.
2019-10-01 11:54:21 +03:00
64cfb33deb Add Added unimplemented getCharacteristicsByHandle function (#3277)
* Add Added unimplemented getCharacteristicsByHandle function

Defined in BLERemoteService.h
But, Not included in BLERemoteService.cpp

* Delete log output
2019-10-01 11:43:59 +03:00
5f1dff7dad IDF release/v3.2 d3e562907 (#3292) 2019-10-01 11:21:44 +03:00
40ebee1cb1 Update BluetoothSerial.cpp (#3308) 2019-10-01 11:10:31 +03:00
ed96d2a1b7 Use Github Actions for release (#3309)
* move scripts and tone down travis

* Update and rename main.yml to push.yml

* Create release.yml
2019-10-01 10:44:04 +03:00
caa391ab34 More efficient CI builds (#3303)
* More efficient CI builds

* Update main.yml
2019-09-30 12:10:48 +03:00
3b71e136e1 Builder scripts update (#3300) 2019-09-30 02:01:29 +03:00
1c77790a5b allow the examples to build in a more strict env (#3299) 2019-09-29 23:47:02 +03:00
5bff89f0be Fixed issue-3153 - Allocating enough memory to construct the entire UUID as a String. (#3297) 2019-09-29 23:03:48 +03:00
9bbd720d4c Update BLEDevice.cpp (#3267)
Pretty sure this was a typo as the deinit doesn't actually allow for reinit if that is an ifndef.  Changed in my local copy and can now deinit and reinit just fine.  Also, not sure why we are checking for the architecture here.  Just curious.
2019-09-26 21:50:16 +03:00
589bb7032d Update WiFiScan.h (#3266)
Add an accessor function for the useful wifi data
2019-09-26 21:03:08 +03:00
f8c06894c5 Better cleanup on mount failures, as the idf api now seems to assign handle and mountpoint before failing. Fixes #3265 (#3282) 2019-09-26 19:12:52 +03:00
a5c873b786 Update README.md 2019-09-24 23:32:13 +03:00
895a150840 Update README.md 2019-09-24 23:23:42 +03:00
ca88fdc273 Fixed FFat::end. Fixes #3244 (#3245)
* Fixed FFat::end. Fixes #3244

* Missed the handle check in format
2019-09-24 23:23:03 +03:00
f32083a6d0 Fix timerRestart
Closes: https://github.com/espressif/arduino-esp32/issues/2944

Thanks @atanisoft
2019-09-24 19:25:27 +03:00
b30e55efff Added partition size option for Pico Kit (#3258)
The original boards.txt was missing a menu option to select the FLASH partitioning options.
2019-09-24 19:21:35 +03:00
0ac2de7aab Add partition schemes to adafruit featheresp32 (#3255)
* Add partition schemes to adafruit featheresp32

* Removed minimal partition scheme
2019-09-24 19:21:08 +03:00
0eec630314 Add missing env to PIO CI build 2019-09-24 18:49:17 +03:00
731fd19bdf Update get.py
Enable insecure download for CI
2019-09-24 17:20:58 +03:00
298c6104a2 Added board defintion for VintLabs boards (#3252) 2019-09-24 12:26:15 +03:00
8ea12f89f3 Update pins (#3249) 2019-09-23 10:14:33 +03:00
b3ba80d570 nvs_handle is an int, was assigning NULL. Also cleaned up end to ensure no memory leak. (#3246) 2019-09-22 23:31:38 +03:00
Luc
a5935ce1cc Add sample for Time date for FatFS like SPIFFS (#3234) 2019-09-22 09:38:24 +03:00
96d6975bd5 Changed WeMosBat.name (#3240)
The old version would crash the Stino plugin, which appears not to support quotes in board names
2019-09-22 09:37:45 +03:00
9eaeeb660c Change the first argument of SPI::wrteBytes to be const (#3242)
fixes: https://github.com/espressif/arduino-esp32/issues/3241
2019-09-22 09:36:32 +03:00
e22d8b6787 Update stale messages for easier filtering 2019-09-21 16:12:22 +03:00
Luc
56fe2dbaff Fix F_Fat::format return false when succeed (#3220)
this is due to ussage of esp_err_t result; instead of boolean, ESP_OK =0 so it is false
2019-09-21 02:34:25 +03:00
06a399b84a Extend logging of ArduinoOTA (#3217) 2019-09-16 19:54:21 +03:00
4ce2cc3c1d Fix HTTP Client with SSL (#3216) 2019-09-16 19:14:32 +03:00
07390157df Fix Camera Example (#3202)
* Update app_httpd.cpp

* Stop LWIP from using PSRAM and enable OV7725
2019-09-13 01:19:53 +03:00
bab3a70f54 Added timeout to WiFiScan.cpp to prevent getting stuck at WIFI_SCAN_RUNNING (#3197)
* Added timeout to WiFiScan class to prevent haning at stucking at WIFI_SCAN_RUNNING when scan fails internally

* fixed tabs and returns, connected scanTimeout to max_scan_per_channel timeout

* Corrected tabs two

* Added static vars scanTimeout und scanStarted to WiFiScan.h protected section

* Fixed missing ; in line 64
2019-09-11 15:58:34 +03:00
cd4f9038ee Fix WiFi disconnect event not being propageted. (#3085)
Relative to #3006
2019-09-11 15:12:15 +03:00
7fe2812f7f Inline ESP::getCycleCount() to make it safe to call from ISRs (#3165)
* Inline ESP::getCycleCount() to make it safe to call from ISRs

* Attribute IRAM_ATTR ISR-safe function in addition to inlining.
2019-09-11 14:29:53 +03:00
Luc
9710fedaf0 Fix wrong values in .cvs files (#3196)
* Fix wrong values in .cvs files

Add missing upload size for partitions bigger than default one

* Add new partion to generic

Fix hardcoded partition for 16M flash
2019-09-10 22:52:51 +03:00
f5cacfee1a Remove extra connects from Client.h (#3191) 2019-09-09 09:36:22 +03:00
f71a4bd406 Bugfix/detect baudrate (#3188)
* Expose uartStartDetectBaudrate(uart_t *) in esp32-hal-uart.h and call it from HardwareSerial::begin() if baudrate detection is requested (by passing a baudrate of 0) to solve baudrate detection problems

* Avoid a division by zero error in uartGetBaudRate()
2019-09-09 00:59:32 +03:00
5f77b0108b Fix return of Print::print(timeinfo, format) (#3189) 2019-09-09 00:36:30 +03:00
717ca79ecb #3181 printf double vsnprintf() fix, malloc, va_end (#3184)
* Use loc_buf for small strings, check for error return from vsnprintf

* cleanup arg when bailing out of new

* Use malloc/free instead of new/delete in printf

* Return actual bytes written in printf

* FIX: write before free
2019-09-08 23:49:32 +03:00
07613b3158 Update URL to point to upstream repository (#3187)
Pointing to an old fork is misleading.
2019-09-08 23:15:46 +03:00
80ea521940 Add support for 160MHz rated CPUs (#3135)
Some ESP32 chips are rated only to 160MHz. This change adds support for them and does not allow frequency to be switched to 240MHz
2019-09-05 12:30:43 +03:00
5c04de6f39 Fix packager 2019-09-05 11:22:40 +03:00
0d163a1ce2 Update IDF 3.2 to 7dd492319 + WiFi fix (#3177) 2019-09-05 11:08:45 +03:00
2a7e509978 Fix long Ticker period conversion: cast ms to uint64_t when calculating us (#3175)
* Fix long Ticker period conversion

* Simplify long Ticker period conversion fix by using 1000ULL
2019-09-05 10:34:47 +03:00
1b8c7e34f9 Try bash only examples build (#3164) 2019-09-01 18:45:55 +03:00
7a574399b1 Rework the sketch builder to match the IDE (#3146)
* Rework the sketch builder to match the IDE

* Link the board to the home folder

* Rename files for clarity

* move ci files to own subfolder

* Update Github CI to use the new script locations
2019-08-28 01:28:11 +03:00
fd089d8fd3 Pull in ESP8266 String::replace() fixes, others (#3143)
Pull in bugfixes from the ESP8266 repo for problems in the SSO
implementation of replace().  See the following patches for full
details:

54240d2cc5 (diff-8d9e71e16d437343017df828f0528f63)
78a1a66e6d (diff-8d9e71e16d437343017df828f0528f63)
4e9358445a (diff-8d9e71e16d437343017df828f0528f63)

Fixes #3140
2019-08-27 20:05:36 +03:00
f356ccd54a Added the pragma line to the top (#3139)
* Removed pragme in BLERemoteService.cpp

* Added the line at the top and changed to warning
2019-08-27 10:21:27 +03:00
6daf773464 Fix travis deploy generating bad json 2019-08-21 03:29:23 +03:00
70a896481d Update Both CIs to run parallel jobs (#3120) 2019-08-21 01:56:05 +03:00
390da0d090 bump CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM to improve RX performance (#3119) 2019-08-20 22:07:56 +03:00
d5e2bb12ca Update IDF to 90747cc8b (#3118) 2019-08-20 21:11:00 +03:00
f4acac4c2b Bugfix/http client (#2867)
* Fix persistance issue found, see ESP8266 issue #6152

* Correcting the parsing of the header for HTTP1.0

* Send 'Connection: Close' header in case of HTTP1.0

* Let reuse connection depend on protocol used: HTTP1.0 or HTTP1.1

* Fixed reuse, added null ptr checks, added check for _trainsportTraits in connect() in case _client was set null

* Fix reuse connection issues, similar to ESP8266 PR #6176
2019-08-20 17:18:09 +03:00
5137fc5c80 Ble notification/indication status and timeout (#2998)
* add timed wait

* Added Notification/Indication data and status callbacks

* imply null-object pattern for BLE callback
2019-08-20 17:15:30 +03:00
03066e42ef Flush UART RX queue too (#3009) 2019-08-20 16:48:52 +03:00
cd5257ad78 ESP.getCpuFreqMHz fix (#3007)
* ESP.getCpuFreqMHz was returning the CONFIG_ variable.  Now calls the getCpuFrequencyMhz function.

* Changed the Esp function to uint32_t to match
2019-08-20 16:48:26 +03:00
ee6336a312 links http -> https (#3010)
more secure
2019-08-20 16:47:43 +03:00
61f71930e9 The progress callback is now correctly invoked with Update.write (#3024)
The progress callback was only invoked with Update.writeStream before
2019-08-20 16:45:57 +03:00
ec40c4c96f Cast TimerWakeup conversion factor as ULL (#3027) 2019-08-20 16:45:18 +03:00
2bda4a9617 Fix BLE stop advertising not working (#3034)
BLEAdvertising::handleGAPEvent -> ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT should NOT call start()!
2019-08-20 16:44:50 +03:00
91b9fae111 Add generic IP utilities (#3038)
* Add generic IP calculations

Add:
calculateNetworkID(IPAddress ip, IPAddress subnet) => Calculate the network id using the ip and subnet (e.g. 192.168.0.0)
calculateBroadcast(IPAddress ip, IPAddress subnet) => Calculate the broadcast ip using the ip and subnet (e.g. 192.168.0.255)
calculateSubnetCIDR(IPAddress subnetMask) => Calculate the subnet CIDR using the subnet (e.g. 24)

Add:
broadcastIP() => Retrieve the network id (e.g. 192.168.0.0)
networkID() => Retrieve the broadcast IP (e.g. 192.168.0.255)
subnetCIDR() => Retrieve the subnet CIDR (e.g. 24)

Add:
broadcastIP() => Retrieve the network id (e.g. 192.168.0.0)
networkID() => Retrieve the broadcast IP (e.g. 192.168.0.255)
subnetCIDR() => Retrieve the subnet CIDR (e.g. 24)

Add:
softAPBroadcastIP() => Retrieve the network id (e.g. 192.168.0.0)
softAPNetwrokID() => Retrieve the broadcast IP (e.g. 192.168.0.255)
softAPSubnetCIDR() => Retrieve the subnet CIDR (e.g. 24)
2019-08-20 16:42:55 +03:00
2a1fde7736 Include stdint for uint16_t (#3069) 2019-08-20 16:39:31 +03:00
a12d609b22 Corrected count of characteristics to get (#3082)
Only space for 1 characteristic is allocated, requesting 10 leads to stack corruption.
2019-08-20 16:38:59 +03:00
73576674b8 add core installation 1.0.2 (#3064)
* add core installation 1.0.2

* added 1.0.3
2019-08-20 16:38:34 +03:00
007a93ec7e Update Print.cpp (#3060)
#2891
2019-08-20 16:36:04 +03:00
a5f3fc6fad Magicbit Variant (#3107)
* Updated magicbit variant

* Added LED_BUILTIN
2019-08-20 15:44:12 +03:00
65e256c40a Try github CI (#3115) 2019-08-20 15:32:47 +03:00
fa55a2c91d Update stale.yml 2019-08-01 18:55:47 +03:00
a070884441 Update stale.yml 2019-08-01 11:05:05 +03:00
a9c8b46b1a Update stale.yml 2019-07-31 16:43:58 +03:00
6954150176 Create stale.yml 2019-07-31 10:04:08 +03:00
548f712df2 Fix empty libs being included with the builder (#2997) 2019-07-17 16:48:51 +03:00
56ce580b0e Fix incorrect definition of FPSTR() and move from pgmspace.h to WString.h (#1371) (#2961) 2019-07-17 10:16:47 +03:00
509d31ba51 create variant for magicbit board (#2987)
* create varient for magicbit board

* update boards.txt
2019-07-17 10:10:45 +03:00
9e32cec9a2 Update IDF to a8916daeb (#2992) 2019-07-17 10:09:43 +03:00
3376ea1bd5 Added more menu settings for TinyPICO - Fash mode and Flash speed. Set Flash mode default to QIO (#2976) 2019-07-16 17:15:13 +03:00
1c7e329140 RMT: Fix in bitshift of NeoPixel example project (#2986)
Fixed bit shift in demo application of using RMT peripheral. Init data array to be transmitted was off by one, as for the first iteration (i==0) the mask was 1<<8, which results in shifted RGB value in color variable
Closes https://github.com/espressif/arduino-esp32/issues/2921
2019-07-16 17:14:28 +03:00
c17b212cd0 WPA2 connection fix (significant improvement to connection time) (#2989)
* Config fix test

* Also force config even if equal
2019-07-16 17:12:20 +03:00
7dbda4988b Update boards.txt (#2933)
* Update boards.txt

Adding ESP32-WROOM-32 8MB flash option

* Update boards.txt

Fixing partition size and typo

* Update boards.txt
2019-07-10 09:13:09 +03:00
d1134fd45e Fix issue with semaphores (#2974) 2019-07-10 09:11:35 +03:00
d5fdd715ef WiFiClient.cpp - Fix connect() behavior (#2784)
* WiFiClient.cpp - Fix connect() behavior

* lwip_connect_r() : check return code
2019-07-09 19:48:05 +03:00
ca7106e97e Added convert method to EEPROM to transfer data from partition to nvs (#2841)
* Added convert method to transfer data from partition to nvs

* Could have sworn I changed the return when I made the label

* Empty state should be 0xFF.  Fixed some logging levels

* Set result on success
2019-07-09 19:47:06 +03:00
87e5787cf7 Added support for TinyPICO in the boards list (#2901) 2019-07-09 19:40:34 +03:00
c13d11e7d1 fix empty reply from server error (#2903)
The flush causes an empty response a client side.

see https://github.com/espressif/arduino-esp32/issues/2902
2019-07-09 19:39:12 +03:00
b0d8d4dd44 Change some WiFi buffer settings to match esp-idf. See #2899 (#2912) 2019-07-09 19:36:45 +03:00
05de017bd5 BLE Library onRead Callback fix and Client disconnect feature (#2913)
* BLEServer::disconnect()

* Invoke Read callback first, to make data update possible before read
2019-07-09 19:35:07 +03:00
e1548e9b7e Fix hang on client disconnect during upload (#2914) 2019-07-09 19:34:24 +03:00
c29ec9da3d Removed partitioning comments from EEPROM class example (#2920)
* Remove partitioning comments

* Revert "Remove partitioning comments"

This reverts commit b3b03a81572d352816819cff772231ba037dc338.

* Removed partitioning comments from EEPROM example
2019-07-09 19:34:04 +03:00
b3783fba95 fixed typo (#2927) 2019-07-09 19:31:38 +03:00
a22ec4a978 Reduce flash usage up to 214k in one click (#2929)
* std::stringstream -> std::string

* Fix small issues

* Small fix 2
2019-07-09 19:31:17 +03:00
20498cf8b1 Expand gitignore to cover files created by Visual Micro (#2934)
* Expand gitignore to cover files created by Visual Micro's Arduino IDE for Visual Studio

(cherry picked from commit d6209c79ea16a26564fe27e74e5f277160129847)

* Also ignore VS project files

(cherry picked from commit e0ec212bd41e75a3570a6098a66ee66787db58db)
2019-07-09 19:28:04 +03:00
02e51728c4 Fix Timeout Bug in WebServer (#2938) 2019-07-09 19:27:24 +03:00
d2816b2f32 Fix Unused Variable Warning (#2940)
Some Debugging variables were enabled at ERROR level instead of DEBUG.  Specifically `tAfter` and `tBefore`
2019-07-09 19:24:35 +03:00
2e32022611 ESP8266 => ESP32 tidyup, set correct default port (#2948)
Tidied up references to the ESP8266, and set the correct default port for the ESP32.
2019-07-09 19:24:10 +03:00
74ffdac74a fix for BLE Library Compile Error #2866 (#2876) 2019-07-09 19:23:01 +03:00
4ee17ec3ee Fix warning -Wempty-body by adding braces to 'if' stmt body (#2951) 2019-07-09 19:21:57 +03:00
476660f763 Cleanup WiFiMulti (#2955)
* Use macros for switch case labels

* Fixed spelling error in "too"

* Fix spacing

* Inline private functions that are only called once
2019-07-09 19:21:01 +03:00
Luc
f558e69181 Fix warnings in platformio (#2960)
Fix : warning: converting to non-pointer type 'int' from NULL [-Wconversion-null]
Fix : warning: unused variable 'res' [-Wunused-variable]
2019-07-09 19:19:16 +03:00
5bf3aab527 Make a selective menuconfig option for FFat (#2966) 2019-07-09 19:14:53 +03:00
1aced120ba docs: fix typo (#2973) 2019-07-09 19:14:27 +03:00
7d7824701f Fix persistance issue found, see ESP8266 issue #6152 (#2851) 2019-06-05 14:00:00 +02:00
89feacb813 Fix map() division by zero (#2848) 2019-06-05 13:48:13 +02:00
aae6f24a37 Update (#2838)
Added PoE-ISO and DevKit-Lipo.
For the other boards added alternative Serial (Serial1/Serial2) pins.
2019-06-05 13:44:52 +02:00
43b781a158 Update AsyncUDP library.json (#2837)
* Fix https://github.com/platformio/platform-espressif32/issues/186

* Drop library.json
2019-06-05 13:43:15 +02:00
e055b28d1a Ignore Werror-maybe-uninitialized from Azure IoT Library (#2824)
Ignore the error about a potentially uninitialized variable
in the Azure library that will occur when compiling as a component
in ESP-IDF.
2019-06-05 13:42:08 +02:00
714ba948e6 Update BLERemoteCharacteristic.cpp (#2800)
Prevents the error that is generated on free on row 186
When calling the function readValue() sometimes it gave an error on this free.
2019-06-05 13:38:49 +02:00
e57de64a3c Fixed multi_heap_free failed during setting the value of the characteristic in BLE Library. (#2789) 2019-06-05 13:37:06 +02:00
fd5a2f08f9 Fix #2750 (#2763)
* Fix #2750

* Fixes for pull comments

* latest modifications following comments from me-no-dev

* Move SPIFFSFSImpl to .cpp file
2019-05-14 00:15:35 +03:00
e9389e3122 Fix AsyncUDP buffer error
fixes: https://github.com/espressif/arduino-esp32/issues/2685
2019-05-13 23:18:38 +03:00
0acf19af8f Update IDF to v3.2 977854975 (#2771)
* Update IDF to v3.2 977854975

* Update app_httpd.cpp
2019-05-12 18:52:23 +03:00
aff2e42ac6 Add Pycom GPy board (#2754) 2019-05-11 11:24:11 +03:00
2743e7b739 Update mac.md (#2745) 2019-05-11 11:21:25 +03:00
c453a0037b Adding TTGO T1 board definition (#2744)
Fixes https://github.com/espressif/arduino-esp32/issues/2740
2019-05-11 11:20:57 +03:00
2f249edb8e Use std::abs for a float-compatible abs() function (#2738)
* Other Arduino cores uses a macro to redefine libc abs() to take any
  type, meaning abs(-3.3) == 3.3 not the normal libc result of 3.

* 1e4bf14a3 (#1783) replaced similar min, max macros with c++ stdlib. However
  this change includes <algorithm> after the line which defines the abs() macro.
  <algorithm> includes <cstdlib> which undefines abs() and re-defines it.

* This means abs() becomes the plain libc version again which only takes
  integers, so abs(-3.3) == 3. As reported here:
  https://github.com/espressif/esp-idf/issues/3405

This fix tries to keep in the spirit of #1783 by using libstdc++. The other
option would be to include <cstdlib> before defining the abs() macro, so it
doesn't get undef-ed again later on.
2019-05-11 11:18:39 +03:00
bd57ff4ab4 StreamString SSO fix (#2736)
As found by @mongozmaki in https://github.com/esp8266/Arduino/pull/6035

With SSO implementation in String, StreamString::write generates wrong
strings under some circumstances.  Reason is that String::len() returns
strlen(sso_buf) if SSO=true but with newly written data
(in StreamString::write) the null-termination missing at the time len()
is called.

Furthermore, len() is called twice which is inefficient if SSO=true.
2019-05-11 11:16:05 +03:00
43bf393dbf Fix semaphores in IDF & std::string assert (#2728)
* Fix semaphores in IDF & std::string assert 

Fixes the problem of giving a mutex from a callback with the latest IDF. Also addresses an occasional assert that happens when the btc_task callback gives the semaphore and causes an assert due to both cores potentially writing m_owner concurrently.

* Restored m_owner position in wait() as requested

* Reapply assert fix and move setting m_owner in ::give() 

Revert previous revert commit and move setting of m_owner in ::give to before giving the semaphore to prevent race condition possibility.
2019-05-11 11:03:09 +03:00
bea7bd1852 Implemented ability to change BLE address (#2690)
Implemented the ability to change the ESP32s BLE device address as
according the the BLE specification. This address is used when
advertising the ESP32 over BLE.
2019-05-11 11:02:26 +03:00
7dd537f8d3 Fix libgcc not being in rom
fixes: https://github.com/espressif/arduino-esp32/issues/2758
2019-05-09 13:07:49 +03:00
50d142950d Update esp32-hal-rmt.c 2019-05-01 20:10:41 +03:00
d13de284b8 Undo the redefinition of FPSTR from 8266 merge (#2726)
Fixes Arduino.h redefinition errors.
2019-04-30 16:52:14 +03:00
697d4ff7c4 Add board "WEMOS D1 MINI ESP32". (#2710) 2019-04-27 14:10:21 +03:00
ab309e40d5 Copy ESP8266 String w/SSO to ESP32 repo (#2715)
I redid the ESP8266 WString library to enable small string optimization
(SSO) a while back, and think it would be helpful even on the ESP32 with
its higher memory complement.

SSO avoids lots of tiny mallocs() on the heap which cause fragmentation
by using the memory in the class object itself to store the actual
string and only mallocing() for buffers that are larger than what can
fit in thie class object.  Modern C++ std::string implementations have
this optimization as well, but since we're using Arduino strings we had
to roll our own.
2019-04-26 19:41:42 +03:00
932666a03f Ensure that _size is properly set in begin (#2706)
* Ensure that _size is properly set in begin

* NULL check on _data assignment

* Changed _data to malloc in order to catch alloc fails
2019-04-26 19:39:22 +03:00
a0ad987029 Add TTGO T-Watch board definition (#2681) 2019-04-25 12:16:26 +03:00
271e5cd206 Fix Werror=reorder for idf.py build (#2707) 2019-04-25 12:02:21 +03:00
619568db5b Converted EEPROM library to use nvs instead of partition. (#2678)
* Converted EEPROM library to use nvs instead of partition.  Removed eeprom partition from all partition table CSV files.
* Changed variable names, added some comments, formatting as per me-no-dev's requests
* Checks for memory on malloc
* Moved include nvs.h from header to code
* Reworked the extra example to make it more clear how to actually use the library and persist data
2019-04-23 23:55:12 +03:00
0202ba7c21 Fix reorder error in WebServer (#2700) 2019-04-23 17:57:33 +03:00
119ece2b0f Portability from ESP8266, virtual Stream member functions. (#2701) 2019-04-23 17:56:49 +03:00
606446a830 Update ALKS board (#2694) 2019-04-23 10:52:24 +03:00
a28cf00295 add lolin32 CPU freq choice (#2682) 2019-04-22 22:00:23 +03:00
672e4faa92 Add optional support for CORS headers (#2688)
* add support for CORS headers

* remove accidental function impl

* rename setCORS to enableCORS, and add aliased function enableCrossOrigin
2019-04-22 21:52:39 +03:00
f8eebb5c39 Fix indentation 2019-04-17 23:27:32 +03:00
6bf104874a Add LGPL 2.1 License 2019-04-16 03:08:50 +02:00
9a9ff62216 Add connect with timeout to Client class 2019-04-15 18:01:43 +02:00
3d6e4e1b94 Use milliseconds for timeout 2019-04-15 17:27:54 +02:00
01d7ea7b80 Refactored use of LOG_X(LOG_TAG, ...) to log_x(...) (#2672)
* Replaced ARDUINO_VARIANT with const char

* Fixed missing return value

* Added quotes around defined value in macro (Issue #2193)

* Change logging from Error to Verbose when not found and default available

* Move Enter and Exit logging to Verbose Level

* Refactored LOG_X() into log_x()
2019-04-15 17:26:35 +02:00
Bob
af23d0bb10 Return empty string instead of "0" (#2673) 2019-04-15 17:23:42 +02:00
582e6433e9 Add proper timeout handling to WiFiClientSecure 2019-04-15 17:19:49 +02:00
ef07a84ade Update esp32-camera driver 2019-04-13 22:52:21 +02:00
ea043cdb14 Fix WiFi Multi not clearing password 2019-04-13 17:19:06 +02:00
c60092951f Add missing definitions 2019-04-13 17:18:25 +02:00
fa74767b2e Allow selecting in IDF the running core for Arduino's core tasks 2019-04-13 17:13:13 +02:00
d922557e01 Set default Serial1 pins for Adafruit Feather 32 2019-04-13 13:28:16 +02:00
33d4186b35 Add board "SparkFun LoRa Gateway 1-Channel". (#2664)
* Add board "SparkFun LoRa Gateway 1-Channel".

* Extend boards.txt.

Source: https://learn.sparkfun.com/tutorials/sparkfun-lora-gateway-1-channel-hookup-guide/all
2019-04-13 12:26:35 +02:00
309 changed files with 8176 additions and 4635 deletions

View File

@ -24,7 +24,7 @@ https://github.com/me-no-dev/EspExceptionDecoder
### Hardware:
Board: ?ESP32 Dev Module? ?node32? ?ttgo_lora?
Core Installation version: ?1.0.0? ?1.0.1-rc4? ?1.0.1? ?1.0.1-git?
Core Installation version: ?1.0.0? ?1.0.1-rc4? ?1.0.1? ?1.0.1-git? ?1.0.2? ?1.0.3?
IDE name: ?Arduino IDE? ?Platform.io? ?IDF component?
Flash Frequency: ?40Mhz?
PSRAM enabled: ?no? ?yes?

View File

@ -8,10 +8,10 @@
set -e
cd "`dirname $0`/.." # cd to arduino-esp32 root
# pull all submodules
git submodule update --init --recursive
# find all source files in repo
#REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name 'main.cpp' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort`
REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort`
# find all source files named in CMakeLists.txt COMPONENT_SRCS

View File

@ -0,0 +1,42 @@
#!/bin/bash
export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32"
if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
echo "Installing ESP32 Arduino Core in '$ARDUINO_ESP32_PATH'..."
script_init_path="$PWD"
mkdir -p "$ARDUINO_USR_PATH/hardware/espressif" && \
cd "$ARDUINO_USR_PATH/hardware/espressif"
if [ $? -ne 0 ]; then exit 1; fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..." && \
ln -s $GITHUB_WORKSPACE esp32
else
echo "Cloning Core Repository..." && \
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: GIT clone failed"; exit 1; fi
fi
cd esp32 && \
echo "Updating submodules..." && \
git submodule update --init --recursive > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Submodule update failed"; exit 1; fi
echo "Installing Python Serial..." && \
pip install pyserial > /dev/null
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
if [ "$OS_IS_WINDOWS" == "1" ]; then
echo "Installing Python Requests..."
pip install requests > /dev/null
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
fi
echo "Downloading the tools and the toolchain..."
cd tools && python get.py > /dev/null
if [ $? -ne 0 ]; then echo "ERROR: Download failed"; exit 1; fi
cd $script_init_path
echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'"
echo ""
fi

217
.github/scripts/install-arduino-ide.sh vendored Normal file
View File

@ -0,0 +1,217 @@
#!/bin/bash
#OSTYPE: 'linux-gnu', ARCH: 'x86_64' => linux64
#OSTYPE: 'msys', ARCH: 'x86_64' => win32
#OSTYPE: 'darwin18', ARCH: 'i386' => macos
OSBITS=`arch`
if [[ "$OSTYPE" == "linux"* ]]; then
export OS_IS_LINUX="1"
ARCHIVE_FORMAT="tar.xz"
if [[ "$OSBITS" == "i686" ]]; then
OS_NAME="linux32"
elif [[ "$OSBITS" == "x86_64" ]]; then
OS_NAME="linux64"
elif [[ "$OSBITS" == "armv7l" ]]; then
OS_NAME="linuxarm"
else
OS_NAME="$OSTYPE-$OSBITS"
echo "Unknown OS '$OS_NAME'"
exit 1
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
export OS_IS_MACOS="1"
ARCHIVE_FORMAT="zip"
OS_NAME="macosx"
elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
export OS_IS_WINDOWS="1"
ARCHIVE_FORMAT="zip"
OS_NAME="windows"
else
OS_NAME="$OSTYPE-$OSBITS"
echo "Unknown OS '$OS_NAME'"
exit 1
fi
export OS_NAME
ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp"
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
if [ "$OS_IS_MACOS" == "1" ]; then
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
else
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Arduino"
fi
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Installing Arduino IDE on $OS_NAME..."
echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT'..."
if [ "$OS_IS_LINUX" == "1" ]; then
wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Download failed"; exit 1; fi
echo "Extracting 'arduino.$ARCHIVE_FORMAT'..."
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ $? -ne 0 ]; then exit 1; fi
mv arduino-nightly "$ARDUINO_IDE_PATH"
else
curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Download failed"; exit 1; fi
echo "Extracting 'arduino.$ARCHIVE_FORMAT'..."
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ $? -ne 0 ]; then exit 1; fi
if [ "$OS_IS_MACOS" == "1" ]; then
mv "Arduino.app" "/Applications/Arduino.app"
else
mv arduino-nightly "$ARDUINO_IDE_PATH"
fi
fi
if [ $? -ne 0 ]; then exit 1; fi
rm -rf "arduino.$ARCHIVE_FORMAT"
mkdir -p "$ARDUINO_USR_PATH/libraries"
mkdir -p "$ARDUINO_USR_PATH/hardware"
echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'"
echo ""
fi
function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketch <fqbn> <path-to-ino> [extra-options]"
return 1
fi
local fqbn="$1"
local sketch="$2"
local xtra_opts="$3"
local win_opts=""
if [ "$OS_IS_WINDOWS" == "1" ]; then
local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
fi
echo ""
echo "Compiling '"$(basename "$sketch")"'..."
mkdir -p "$ARDUINO_BUILD_DIR"
mkdir -p "$ARDUINO_CACHE_DIR"
$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \
-fqbn=$fqbn \
-warnings="all" \
-tools "$ARDUINO_IDE_PATH/tools-builder" \
-tools "$ARDUINO_IDE_PATH/tools" \
-built-in-libraries "$ARDUINO_IDE_PATH/libraries" \
-hardware "$ARDUINO_IDE_PATH/hardware" \
-hardware "$ARDUINO_USR_PATH/hardware" \
-libraries "$ARDUINO_USR_PATH/libraries" \
-build-cache "$ARDUINO_CACHE_DIR" \
-build-path "$ARDUINO_BUILD_DIR" \
$win_opts $xtra_opts "$sketch"
}
function count_sketches() # count_sketches <examples-path>
{
local examples="$1"
local sketches=$(find $examples -name *.ino)
local sketchnum=0
rm -rf sketches.txt
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
continue
fi
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
done
return $sketchnum
}
function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total-chunks> [extra-options]
{
local fqbn=$1
local examples=$2
local chunk_idex=$3
local chunks_num=$4
local xtra_opts=$5
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketches <fqbn> <examples-path> [<chunk> <total-chunks>] [extra-options]"
return 1
fi
if [ "$#" -lt 4 ]; then
chunk_idex="0"
chunks_num="1"
xtra_opts=$3
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
count_sketches "$examples"
local sketchcount=$?
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches";
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [ "${sketchdirname}.ino" != "$sketchname" ] \
|| [ -f "$sketchdir/.test.skip" ]; then
continue
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_sketch "$fqbn" "$sketch" "$xtra_opts"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}

View File

@ -0,0 +1,153 @@
#!/bin/bash
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
echo "Installing Python Wheel..."
pip install wheel > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
echo "Installing PlatformIO..."
pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
echo "Installing Platform ESP32..."
python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: Install failed"; exit 1; fi
echo "Replacing the framework version..."
if [[ "$OSTYPE" == "darwin"* ]]; then
sed 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" > "platform.json" && \
mv -f "platform.json" "$HOME/.platformio/platforms/espressif32/platform.json"
else
sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json"
fi
if [ $? -ne 0 ]; then echo "ERROR: Replace failed"; exit 1; fi
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
echo "Linking Core..." && \
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
else
echo "Cloning Core Repository..." && \
git clone https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
if [ $? -ne 0 ]; then echo "ERROR: GIT clone failed"; exit 1; fi
fi
echo "PlatformIO for ESP32 has been installed"
echo ""
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino>
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketch <board> <path-to-ino>"
return 1
fi
local board="$1"
local sketch="$2"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"'..."
python -m platformio ci --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv"
}
function count_sketches() # count_sketches <examples-path>
{
local examples="$1"
local sketches=$(find $examples -name *.ino)
local sketchnum=0
rm -rf sketches.txt
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
continue
fi
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
done
return $sketchnum
}
function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chunk> <total-chunks>
{
if [ "$#" -lt 2 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketches <board> <examples-path> [<chunk> <total-chunks>]"
return 1
fi
local board=$1
local examples=$2
local chunk_idex=$3
local chunks_num=$4
if [ "$#" -lt 4 ]; then
chunk_idex="0"
chunks_num="1"
fi
if [ "$chunks_num" -le 0 ]; then
echo "ERROR: Chunks count must be positive number"
return 1
fi
if [ "$chunk_idex" -ge "$chunks_num" ]; then
echo "ERROR: Chunk index must be less than chunks count"
return 1
fi
count_sketches "$examples"
local sketchcount=$?
local sketches=$(cat sketches.txt)
rm -rf sketches.txt
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
echo "Found $sketchcount Sketches";
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [ "${sketchdirname}.ino" != "$sketchname" ] \
|| [ -f "$sketchdir/.test.skip" ]; then
continue
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ] \
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_pio_sketch "$board" "$sketch"
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
done
return 0
}

6
package/merge_packages.py → .github/scripts/merge_packages.py vendored Normal file → Executable file
View File

@ -36,7 +36,11 @@ def pkgVersionNormalized(versionString):
verParts = re.split('\.|-rc', verStr, flags=re.IGNORECASE)
if len(verParts) == 3:
verStr = str(versionString) + '-rc' + str(sys.maxint)
if (sys.version_info > (3, 0)): # Python 3
verStr = str(versionString) + '-rc' + str(sys.maxsize)
else: # Python 2
verStr = str(versionString) + '-rc' + str(sys.maxint)
elif len(verParts) != 4:
print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr)

71
.github/scripts/on-push.sh vendored Executable file
View File

@ -0,0 +1,71 @@
#!/bin/bash
if [ ! -z "$TRAVIS_TAG" ]; then
echo "Skipping Test: Tagged build"
exit 0
fi
if [ ! -z "$GITHUB_WORKSPACE" ]; then
export TRAVIS_BUILD_DIR="$GITHUB_WORKSPACE"
export TRAVIS_REPO_SLUG="$GITHUB_REPOSITORY"
elif [ ! -z "$TRAVIS_BUILD_DIR" ]; then
export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR"
export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG"
else
export GITHUB_WORKSPACE="$PWD"
export GITHUB_REPOSITORY="espressif/arduino-esp32"
fi
CHUNK_INDEX=$1
CHUNKS_CNT=$2
BUILD_PIO=0
if [ "$#" -lt 2 ] || [ "$CHUNKS_CNT" -le 0 ]; then
CHUNK_INDEX=0
CHUNKS_CNT=1
elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ]; then
CHUNK_INDEX=$CHUNKS_CNT
elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
BUILD_PIO=1
fi
echo "Updating submodules ..."
git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
if [ "$BUILD_PIO" -eq 0 ]; then
# ArduinoIDE Test
FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
source ./.github/scripts/install-arduino-ide.sh
source ./.github/scripts/install-arduino-core-esp32.sh
if [ "$OS_IS_WINDOWS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
elif [ "$OS_IS_MACOS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
else
# CMake Test
if [ "$CHUNK_INDEX" -eq 0 ]; then
bash "$ARDUINO_ESP32_PATH/.github/scripts/check-cmakelists.sh"
if [ $? -ne 0 ]; then exit 1; fi
fi
build_sketches "$FQBN" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi
else
# PlatformIO Test
source ./.github/scripts/install-platformio-esp32.sh
BOARD="esp32dev"
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
#build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries"
fi
if [ $? -ne 0 ]; then exit 1; fi

380
.github/scripts/on-release.sh vendored Executable file
View File

@ -0,0 +1,380 @@
#!/bin/bash
if [ ! $GITHUB_EVENT_NAME == "release" ]; then
echo "Wrong event '$GITHUB_EVENT_NAME'!"
exit 1
fi
EVENT_JSON=`cat $GITHUB_EVENT_PATH`
action=`echo $EVENT_JSON | jq -r '.action'`
if [ ! $action == "published" ]; then
echo "Wrong action '$action'. Exiting now..."
exit 0
fi
draft=`echo $EVENT_JSON | jq -r '.release.draft'`
if [ $draft == "true" ]; then
echo "It's a draft release. Exiting now..."
exit 0
fi
RELEASE_PRE=`echo $EVENT_JSON | jq -r '.release.prerelease'`
RELEASE_TAG=`echo $EVENT_JSON | jq -r '.release.tag_name'`
RELEASE_BRANCH=`echo $EVENT_JSON | jq -r '.release.target_commitish'`
RELEASE_ID=`echo $EVENT_JSON | jq -r '.release.id'`
RELEASE_BODY=`echo $EVENT_JSON | jq -r '.release.body'`
OUTPUT_DIR="$GITHUB_WORKSPACE/build"
PACKAGE_NAME="esp32-$RELEASE_TAG"
PACKAGE_JSON_MERGE="$GITHUB_WORKSPACE/.github/scripts/merge_packages.py"
PACKAGE_JSON_TEMPLATE="$GITHUB_WORKSPACE/package/package_esp32_index.template.json"
PACKAGE_JSON_DEV="package_esp32_dev_index.json"
PACKAGE_JSON_REL="package_esp32_index.json"
echo "Event: $GITHUB_EVENT_NAME, Repo: $GITHUB_REPOSITORY, Path: $GITHUB_WORKSPACE, Ref: $GITHUB_REF"
echo "Action: $action, Branch: $RELEASE_BRANCH, ID: $RELEASE_ID"
echo "Tag: $RELEASE_TAG, Draft: $draft, Pre-Release: $RELEASE_PRE"
function get_file_size(){
local file="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then
eval `stat -s "$file"`
local res="$?"
echo "$st_size"
return $res
else
stat --printf="%s" "$file"
return $?
fi
}
function git_upload_asset(){
local name=$(basename "$1")
# local mime=$(file -b --mime-type "$1")
curl -k -X POST -sH "Authorization: token $GITHUB_TOKEN" -H "Content-Type: application/octet-stream" --data-binary @"$1" "https://uploads.github.com/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets?name=$name"
}
function git_safe_upload_asset(){
local file="$1"
local name=$(basename "$file")
local size=`get_file_size "$file"`
local upload_res=`git_upload_asset "$file"`
if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1
fi
up_size=`echo "$upload_res" | jq -r '.size'`
if [ $up_size -ne $size ]; then
>&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset
return 1
fi
echo "$upload_res" | jq -r '.browser_download_url'
return $?
}
function git_upload_to_pages(){
local path=$1
local src=$2
if [ ! -f "$src" ]; then
>&2 echo "Input is not a file! Aborting..."
return 1
fi
local info=`curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.object+json" -X GET "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path?ref=gh-pages"`
local type=`echo "$info" | jq -r '.type'`
local message=$(basename $path)
local sha=""
local content=""
if [ $type == "file" ]; then
sha=`echo "$info" | jq -r '.sha'`
sha=",\"sha\":\"$sha\""
message="Updating $message"
elif [ ! $type == "null" ]; then
>&2 echo "Wrong type '$type'"
return 1
else
message="Creating $message"
fi
content=`base64 -i "$src"`
data="{\"branch\":\"gh-pages\",\"message\":\"$message\",\"content\":\"$content\"$sha}"
echo "$data" | curl -s -k -H "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw+json" -X PUT --data @- "https://api.github.com/repos/$GITHUB_REPOSITORY/contents/$path"
}
function git_safe_upload_to_pages(){
local path=$1
local file="$2"
local name=$(basename "$file")
local size=`get_file_size "$file"`
local upload_res=`git_upload_to_pages "$path" "$file"`
if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to upload '$name' ($?)"
return 1
fi
up_size=`echo "$upload_res" | jq -r '.content.size'`
if [ $up_size -ne $size ]; then
>&2 echo "ERROR: Uploaded size does not match! $up_size != $size"
#git_delete_asset
return 1
fi
echo "$upload_res" | jq -r '.content.download_url'
return $?
}
function merge_package_json(){
local jsonLink=$1
local jsonOut=$2
local old_json=$OUTPUT_DIR/oldJson.json
local merged_json=$OUTPUT_DIR/mergedJson.json
echo "Downloading previous JSON $jsonLink ..."
curl -L -o "$old_json" "https://github.com/$GITHUB_REPOSITORY/releases/download/$jsonLink?access_token=$GITHUB_TOKEN" 2>/dev/null
if [ $? -ne 0 ]; then echo "ERROR: Download Failed! $?"; exit 1; fi
echo "Creating new JSON ..."
set +e
stdbuf -oL python "$PACKAGE_JSON_MERGE" "$jsonOut" "$old_json" > "$merged_json"
set -e
set -v
if [ ! -s $merged_json ]; then
rm -f "$merged_json"
echo "Nothing to merge"
else
rm -f "$jsonOut"
mv "$merged_json" "$jsonOut"
echo "JSON data successfully merged"
fi
rm -f "$old_json"
set +v
}
set -e
##
## PACKAGE ZIP
##
mkdir -p "$OUTPUT_DIR"
PKG_DIR="$OUTPUT_DIR/$PACKAGE_NAME"
PACKAGE_ZIP="$PACKAGE_NAME.zip"
echo "Updating submodules ..."
git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
mkdir -p "$PKG_DIR/tools"
# Copy all core files to the package folder
echo "Copying files for packaging ..."
cp -f "$GITHUB_WORKSPACE/boards.txt" "$PKG_DIR/"
cp -f "$GITHUB_WORKSPACE/programmers.txt" "$PKG_DIR/"
cp -Rf "$GITHUB_WORKSPACE/cores" "$PKG_DIR/"
cp -Rf "$GITHUB_WORKSPACE/libraries" "$PKG_DIR/"
cp -Rf "$GITHUB_WORKSPACE/variants" "$PKG_DIR/"
cp -f "$GITHUB_WORKSPACE/tools/espota.exe" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/espota.py" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/esptool.py" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/gen_esp32part.py" "$PKG_DIR/tools/"
cp -f "$GITHUB_WORKSPACE/tools/gen_esp32part.exe" "$PKG_DIR/tools/"
cp -Rf "$GITHUB_WORKSPACE/tools/partitions" "$PKG_DIR/tools/"
cp -Rf "$GITHUB_WORKSPACE/tools/sdk" "$PKG_DIR/tools/"
# Remove unnecessary files in the package folder
echo "Cleaning up folders ..."
find "$PKG_DIR" -name '*.DS_Store' -exec rm -f {} \;
find "$PKG_DIR" -name '*.git*' -type f -delete
# Replace tools locations in platform.txt
echo "Generating platform.txt..."
cat "$GITHUB_WORKSPACE/platform.txt" | \
sed "s/version=.*/version=$ver$extent/g" | \
sed 's/runtime.tools.xtensa-esp32-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32-elf//g' | \
sed 's/tools.esptool_py.path={runtime.platform.path}\/tools\/esptool/tools.esptool_py.path=\{runtime.tools.esptool_py.path\}/g' \
> "$PKG_DIR/platform.txt"
# Add header with version information
echo "Generating core_version.h ..."
ver_define=`echo $RELEASE_TAG | tr "[:lower:].\055" "[:upper:]_"`
ver_hex=`git -C "$GITHUB_WORKSPACE" rev-parse --short=8 HEAD 2>/dev/null`
echo \#define ARDUINO_ESP32_GIT_VER 0x$ver_hex > "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_GIT_DESC `git -C "$GITHUB_WORKSPACE" describe --tags 2>/dev/null` >> "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_RELEASE_$ver_define >> "$PKG_DIR/cores/esp32/core_version.h"
echo \#define ARDUINO_ESP32_RELEASE \"$ver_define\" >> "$PKG_DIR/cores/esp32/core_version.h"
# Compress package folder
echo "Creating ZIP ..."
pushd "$OUTPUT_DIR" >/dev/null
zip -qr "$PACKAGE_ZIP" "$PACKAGE_NAME"
if [ $? -ne 0 ]; then echo "ERROR: Failed to create $PACKAGE_ZIP ($?)"; exit 1; fi
# Calculate SHA-256
echo "Calculating SHA sum ..."
PACKAGE_PATH="$OUTPUT_DIR/$PACKAGE_ZIP"
PACKAGE_SHA=`shasum -a 256 "$PACKAGE_ZIP" | cut -f 1 -d ' '`
PACKAGE_SIZE=`get_file_size "$PACKAGE_ZIP"`
popd >/dev/null
rm -rf "$PKG_DIR"
echo "'$PACKAGE_ZIP' Created! Size: $PACKAGE_SIZE, SHA-256: $PACKAGE_SHA"
echo
# Upload package to release page
echo "Uploading package to release page ..."
PACKAGE_URL=`git_safe_upload_asset "$PACKAGE_PATH"`
echo "Package Uploaded"
echo "Download URL: $PACKAGE_URL"
echo
##
## PACKAGE JSON
##
# Construct JQ argument with package data
jq_arg=".packages[0].platforms[0].version = \"$RELEASE_TAG\" | \
.packages[0].platforms[0].url = \"$PACKAGE_URL\" |\
.packages[0].platforms[0].archiveFileName = \"$PACKAGE_ZIP\" |\
.packages[0].platforms[0].size = \"$PACKAGE_SIZE\" |\
.packages[0].platforms[0].checksum = \"SHA-256:$PACKAGE_SHA\""
# Generate package JSONs
echo "Genarating $PACKAGE_JSON_DEV ..."
cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
if [ "$RELEASE_PRE" == "false" ]; then
echo "Genarating $PACKAGE_JSON_REL ..."
cat "$PACKAGE_JSON_TEMPLATE" | jq "$jq_arg" > "$OUTPUT_DIR/$PACKAGE_JSON_REL"
fi
# Figure out the last release or pre-release
echo "Getting previous releases ..."
releasesJson=`curl -sH "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$GITHUB_REPOSITORY/releases" 2>/dev/null`
if [ $? -ne 0 ]; then echo "ERROR: Get Releases Failed! ($?)"; exit 1; fi
set +e
prev_release=$(echo "$releasesJson" | jq -e -r '. | map(select(.draft == false and .prerelease == false)) | sort_by(.created_at | - fromdateiso8601) | .[0].tag_name')
prev_any_release=$(echo "$releasesJson" | jq -e -r '. | map(select(.draft == false)) | sort_by(.created_at | - fromdateiso8601) | .[0].tag_name')
shopt -s nocasematch
if [ "$prev_any_release" == "$RELEASE_TAG" ]; then
prev_release=$(echo "$releasesJson" | jq -e -r '. | map(select(.draft == false and .prerelease == false)) | sort_by(.created_at | - fromdateiso8601) | .[1].tag_name')
prev_any_release=$(echo "$releasesJson" | jq -e -r '. | map(select(.draft == false)) | sort_by(.created_at | - fromdateiso8601) | .[1].tag_name')
fi
COMMITS_SINCE_RELEASE="$prev_any_release"
shopt -u nocasematch
set -e
# Merge package JSONs with previous releases
if [ ! -z "$prev_any_release" ] && [ "$prev_any_release" != "null" ]; then
echo "Merging with JSON from $prev_any_release ..."
merge_package_json "$prev_any_release/$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV"
fi
if [ "$RELEASE_PRE" == "false" ]; then
COMMITS_SINCE_RELEASE="$prev_release"
if [ ! -z "$prev_release" ] && [ "$prev_release" != "null" ]; then
echo "Merging with JSON from $prev_release ..."
merge_package_json "$prev_release/$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL"
fi
fi
echo "Previous Release: $prev_release"
echo "Previous (any)release: $prev_any_release"
echo
# Upload package JSONs
echo "Uploading $PACKAGE_JSON_DEV ..."
echo "Download URL: "`git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_DEV"`
echo "Pages URL: "`git_safe_upload_to_pages "$PACKAGE_JSON_DEV" "$OUTPUT_DIR/$PACKAGE_JSON_DEV"`
echo
if [ "$RELEASE_PRE" == "false" ]; then
echo "Uploading $PACKAGE_JSON_REL ..."
echo "Download URL: "`git_safe_upload_asset "$OUTPUT_DIR/$PACKAGE_JSON_REL"`
echo "Pages URL: "`git_safe_upload_to_pages "$PACKAGE_JSON_REL" "$OUTPUT_DIR/$PACKAGE_JSON_REL"`
echo
fi
##
## RELEASE NOTES
##
# Create release notes
echo "Preparing release notes ..."
releaseNotes=""
# Process annotated tags
relNotesRaw=`git -C "$GITHUB_WORKSPACE" show -s --format=%b $RELEASE_TAG`
readarray -t msgArray <<<"$relNotesRaw"
arrLen=${#msgArray[@]}
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
ind=3
while [ $ind -lt $arrLen ]; do
if [ $ind -eq 3 ]; then
releaseNotes="#### ${msgArray[ind]}"
releaseNotes+=$'\r\n'
else
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
if [ ${#oneLine} -gt 0 ]; then
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
releaseNotes+="$oneLine"
releaseNotes+=$'\r\n'
fi
fi
let ind=$ind+1
done
fi
# Append Commit Messages
if [ ! -z "$COMMITS_SINCE_RELEASE" ] && [ "$COMMITS_SINCE_RELEASE" != "null" ]; then
echo "Getting commits since $COMMITS_SINCE_RELEASE ..."
commitFile=$OUTPUT_DIR/commits.txt
git -C "$GITHUB_WORKSPACE" log --oneline $COMMITS_SINCE_RELEASE.. > "$OUTPUT_DIR/commits.txt"
releaseNotes+=$'\r\n##### Commits\r\n'
IFS=$'\n'
for next in `cat $commitFile`
do
IFS=' ' read -r commitId commitMsg <<< "$next"
commitLine="- [$commitId](https://github.com/$GITHUB_REPOSITORY/commit/$commitId) $commitMsg"
releaseNotes+="$commitLine"
releaseNotes+=$'\r\n'
done
rm -f $commitFile
fi
# Prepend the original release body
if [ "${RELEASE_BODY: -1}" == $'\r' ]; then
RELEASE_BODY="${RELEASE_BODY:0:-1}"
else
RELEASE_BODY="$RELEASE_BODY"
fi
RELEASE_BODY+=$'\r\n'
releaseNotes="$RELEASE_BODY$releaseNotes"
# Update release page
echo "Updating release notes ..."
releaseNotes=$(printf '%s' "$releaseNotes" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))')
releaseNotes=${releaseNotes:1:-1}
curlData="{\"body\": \"$releaseNotes\"}"
releaseData=`curl --data "$curlData" "https://api.github.com/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID?access_token=$GITHUB_TOKEN" 2>/dev/null`
if [ $? -ne 0 ]; then echo "ERROR: Updating Release Failed: $?"; exit 1; fi
echo "Release notes successfully updated"
echo
##
## SUBMODULE VERSIONS
##
# Upload submodules versions
echo "Generating submodules.txt ..."
git -C "$GITHUB_WORKSPACE" submodule status > "$OUTPUT_DIR/submodules.txt"
echo "Uploading submodules.txt ..."
echo "Download URL: "`git_safe_upload_asset "$OUTPUT_DIR/submodules.txt"`
echo ""
set +e
##
## DONE
##
echo "DONE!"

64
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,64 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 14
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- pinned
- security
- "to be implemented"
- "for reference"
- "move to PR"
- "enhancement"
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
[STALE_SET] This issue has been automatically marked as stale because it has not had
recent activity. It will be closed in 14 days if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
unmarkComment: >
[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

49
.github/workflows/push.yml vendored Normal file
View File

@ -0,0 +1,49 @@
name: ESP32 Arduino CI
on:
push:
branches:
- master
- release/*
pull_request:
jobs:
# Ubuntu
build-arduino-linux:
name: Arduino ${{ matrix.chunk }} on ubuntu-latest
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
steps:
- uses: actions/checkout@v1
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
# Windows and MacOS
build-arduino-win-mac:
name: Arduino on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh
# PlatformIO on Windows, Ubuntu and Mac
build-platformio:
name: PlatformIO on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO

17
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: ESP32 Arduino Release
on:
release:
types: published
jobs:
build:
name: Publish Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Build Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash ./.github/scripts/on-release.sh

7
.gitignore vendored
View File

@ -5,3 +5,10 @@ tools/esptool.exe
tools/mkspiffs/mkspiffs
tools/mkspiffs/mkspiffs.exe
.DS_Store
#Ignore files built by Visual Studio/Visual Micro
[Dd]ebug*/
[Rr]elease*/
.vs/
__vm/
*.vcxproj*

View File

@ -1,8 +1,6 @@
sudo: false
language: python
python:
- "2.7"
os:
- linux
@ -10,22 +8,40 @@ os:
git:
depth: false
env:
global:
- secure: "l/4Dt+KQ/mACtGAHDUsPr66fUte840PZoQ4xpPikqWZI0uARu4l+Ym7+sHinnT6fBqrj8AJeBYGz4nFa8NK4LutZn9mSD40w+sxl0wSV4oHV8rzKe3Cd8+sMG3+o33yWoikMNjSvqa73Q0rm+SgrlInNdZbuAyixL+a2alaWSnGPm4F2xwUGj+S33TOy5P/Xp77CYtCV5S8vzyk/eEdNhoF0GYePJVdfuzCOUjXMyT5OWxORkzzQ7Hnn/Ka/RDfV8Si4HgujLQBrK5q6iPnNBFqBSqilYBepSMn4opnOBpIm0SCgePz7XQEFC83buA7GUcnCnfg38bf+dCwHaODf1d1PmqVRYt2QmfinexXtM4afAtL0iBUDtvrfnXHzwW9w82VeZhpbJSVh9DUQvB0IlsZeCz9J9PUBAi3N+SMX+9l+BomYwRUlPuKY+Ef2JKk9q6mxtUkky5R0daAlVxEhpVdQks1rT+T+NMoDMemxQ3SKEiqAHh6EgHecruszffmZ71uLX9MpERpew0qN+UFiafws+jkTjx+3yF9yut0Hf9sMbeAYzzkGzRqJTUEBJ6B29Cql8M0yRXCNN/8wuuTHhG8esstozga4ZQoIVrq7mEAgup376PTcNfr1+imbbWVQ7lJdYIuDe6OS5V3OX6np11vgK/DbhfyzvQv9Z1zAGnM="
- REMOTE_URL=https://github.com/$TRAVIS_REPO_SLUG/releases/download/$TRAVIS_TAG
script:
- bash $TRAVIS_BUILD_DIR/tools/build.sh
before_install:
- git submodule update --init --recursive
deploy:
provider: script
skip_cleanup: true
script: bash $TRAVIS_BUILD_DIR/tools/deploy.sh -t$TRAVIS_TAG -a$ESP32_GITHUB_TOKEN -s$TRAVIS_REPO_SLUG -drelease
stages:
- build
- deploy
on:
tags: true
jobs:
include:
- name: "Build Arduino 0"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 0 10
- name: "Build Arduino 1"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 10
- name: "Build Arduino 2"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 2 10
- name: "Build Arduino 3"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 3 10
- name: "Build PlatformIO"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh 1 1
notifications:
email:

View File

@ -209,3 +209,8 @@ set(COMPONENT_REQUIRES spi_flash mbedtls mdns ethernet)
set(COMPONENT_PRIV_REQUIRES fatfs nvs_flash app_update spiffs bootloader_support openssl bt)
register_component()
set_source_files_properties(libraries/AzureIoT/src/az_iot/iothub_client/src/iothubtransport_mqtt_common.c
PROPERTIES COMPILE_FLAGS
-Wno-maybe-uninitialized
)

View File

@ -19,6 +19,70 @@ config AUTOSTART_ARDUINO
If disabled, you can call initArduino() to run any preparations
required by the framework
choice ARDUINO_RUNNING_CORE
bool "Core on which Arduino's setup() and loop() are running"
default ARDUINO_RUN_CORE1
help
Select on which core Arduino's setup() and loop() functions run
config ARDUINO_RUN_CORE0
bool "CORE 0"
config ARDUINO_RUN_CORE1
bool "CORE 1"
config ARDUINO_RUN_NO_AFFINITY
bool "BOTH"
endchoice
config ARDUINO_RUNNING_CORE
int
default 0 if ARDUINO_RUN_CORE0
default 1 if ARDUINO_RUN_CORE1
default -1 if ARDUINO_RUN_NO_AFFINITY
choice ARDUINO_EVENT_RUNNING_CORE
bool "Core on which Arduino's event handler is running"
default ARDUINO_EVENT_RUN_CORE1
help
Select on which core Arduino's WiFi.onEvent() run
config ARDUINO_EVENT_RUN_CORE0
bool "CORE 0"
config ARDUINO_EVENT_RUN_CORE1
bool "CORE 1"
config ARDUINO_EVENT_RUN_NO_AFFINITY
bool "BOTH"
endchoice
config ARDUINO_EVENT_RUNNING_CORE
int
default 0 if ARDUINO_EVENT_RUN_CORE0
default 1 if ARDUINO_EVENT_RUN_CORE1
default -1 if ARDUINO_EVENT_RUN_NO_AFFINITY
choice ARDUINO_UDP_RUNNING_CORE
bool "Core on which Arduino's UDP is running"
default ARDUINO_UDP_RUN_CORE1
help
Select on which core Arduino's UDP run
config ARDUINO_UDP_RUN_CORE0
bool "CORE 0"
config ARDUINO_UDP_RUN_CORE1
bool "CORE 1"
config ARDUINO_UDP_RUN_NO_AFFINITY
bool "BOTH"
endchoice
config ARDUINO_UDP_RUNNING_CORE
int
default 0 if ARDUINO_UDP_RUN_CORE0
default 1 if ARDUINO_UDP_RUN_CORE1
default -1 if ARDUINO_UDP_RUN_NO_AFFINITY
config DISABLE_HAL_LOCKS
bool "Disable mutex locks for HAL"
default "n"
@ -168,6 +232,12 @@ config ARDUINO_SELECTIVE_ESPmDNS
select ARDUINO_SELECTIVE_WiFi
default y
config ARDUINO_SELECTIVE_FFat
bool "Enable FFat"
depends on ARDUINO_SELECTIVE_COMPILATION
select ARDUINO_SELECTIVE_FS
default y
config ARDUINO_SELECTIVE_FS
bool "Enable FS"
depends on ARDUINO_SELECTIVE_COMPILATION

503
LICENSE.md Normal file
View File

@ -0,0 +1,503 @@
### GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
### Preamble
The licenses for most software are designed to take away your freedom
to share and change it. By contrast, the GNU General Public Licenses
are intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there
is no warranty for the free library. Also, if the library is modified
by someone else and passed on, the recipients should know that what
they have is not the original version, so that the original author's
reputation will not be affected by problems that might be introduced
by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using a
shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
**0.** This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License"). Each
licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does and
what the program that uses the Library does.
**1.** You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a
fee.
**2.** You may modify your copy or copies of the Library or any
portion of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
- **a)** The modified work must itself be a software library.
- **b)** You must cause the files modified to carry prominent
notices stating that you changed the files and the date of
any change.
- **c)** You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
- **d)** If a facility in the modified Library refers to a function
or a table of data to be supplied by an application program that
uses the facility, other than as an argument passed when the
facility is invoked, then you must make a good faith effort to
ensure that, in the event an application does not supply such
function or table, the facility still operates, and performs
whatever part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of
the application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
**3.** You may opt to apply the terms of the ordinary GNU General
Public License instead of this License to a given copy of the Library.
To do this, you must alter all the notices that refer to this License,
so that they refer to the ordinary GNU General Public License, version
2, instead of to this License. (If a newer version than version 2 of
the ordinary GNU General Public License has appeared, then you can
specify that version instead if you wish.) Do not make any other
change in these notices.
Once this change is made in a given copy, it is irreversible for that
copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the
Library into a program that is not a library.
**4.** You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy from
a designated place, then offering equivalent access to copy the source
code from the same place satisfies the requirement to distribute the
source code, even though third parties are not compelled to copy the
source along with the object code.
**5.** A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a work,
in isolation, is not a derivative work of the Library, and therefore
falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License. Section
6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data structure
layouts and accessors, and small macros and small inline functions
(ten lines or less in length), then the use of the object file is
unrestricted, regardless of whether it is legally a derivative work.
(Executables containing this object code plus portions of the Library
will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
**6.** As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a work
containing portions of the Library, and distribute that work under
terms of your choice, provided that the terms permit modification of
the work for the customer's own use and reverse engineering for
debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
- **a)** Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood that
the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
- **b)** Use a suitable shared library mechanism for linking with
the Library. A suitable mechanism is one that (1) uses at run time
a copy of the library already present on the user's computer
system, rather than copying library functions into the executable,
and (2) will operate properly with a modified version of the
library, if the user installs one, as long as the modified version
is interface-compatible with the version that the work was
made with.
- **c)** Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
- **d)** If distribution of the work is made by offering access to
copy from a designated place, offer equivalent access to copy the
above specified materials from the same place.
- **e)** Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
**7.** You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
- **a)** Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other
library facilities. This must be distributed under the terms of
the Sections above.
- **b)** Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
**8.** You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
**9.** You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
**10.** Each time you redistribute the Library (or any work based on
the Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
**11.** If, as a consequence of a court judgment or allegation of
patent infringement or for any other reason (not limited to patent
issues), conditions are imposed on you (whether by court order,
agreement or otherwise) that contradict the conditions of this
License, they do not excuse you from the conditions of this License.
If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations,
then as a consequence you may not distribute the Library at all. For
example, if a patent license would not permit royalty-free
redistribution of the Library by all those who receive copies directly
or indirectly through you, then the only way you could satisfy both it
and this License would be to refrain entirely from distribution of the
Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
**12.** If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
**13.** The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time. Such
new versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
**14.** If you wish to incorporate parts of the Library into other
free programs whose distribution conditions are incompatible with
these, write to the author to ask for permission. For software which
is copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
**NO WARRANTY**
**15.** BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
**16.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
### END OF TERMS AND CONDITIONS
### How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library. It
is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
one line to give the library's name and an idea of what it does.
Copyright (C) year name of author
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper
mail.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.
signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -1,4 +1,5 @@
# Arduino core for ESP32 WiFi chip [![Build Status](https://travis-ci.org/espressif/arduino-esp32.svg?branch=master)](https://travis-ci.org/espressif/arduino-esp32)
# Arduino core for the ESP32
[![Build Status](https://travis-ci.org/espressif/arduino-esp32.svg?branch=master)](https://travis-ci.org/espressif/arduino-esp32) ![](https://github.com/espressif/arduino-esp32/workflows/ESP32%20Arduino%20CI/badge.svg)
### Need help or have a question? Join the chat at [![https://gitter.im/espressif/arduino-esp32](https://badges.gitter.im/espressif/arduino-esp32.svg)](https://gitter.im/espressif/arduino-esp32?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@ -9,17 +10,12 @@
- [Issue/Bug report template](#issuebug-report-template)
- [ESP32Dev Board PINMAP](#esp32dev-board-pinmap)
## Development Status
### Development Status
[Latest stable release ![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg?style=plastic) ![Release Date](https://img.shields.io/github/release-date/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) ![Downloads](https://img.shields.io/github/downloads/espressif/arduino-esp32/latest/total.svg?style=plastic)
[Latest development release ![Development Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic) ![Development Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) ![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)
Most of the framework is implemented. Most noticable is the missing analogWrite. While analogWrite is on it's way, there are a few other options that you can use:
- 16 channels [LEDC](cores/esp32/esp32-hal-ledc.h) which is PWM
- 8 channels [SigmaDelta](cores/esp32/esp32-hal-sigmadelta.h) which uses SigmaDelta modulation
- 2 channels [DAC](cores/esp32/esp32-hal-dac.h) which gives real analog output
## Installation Instructions
### Installation Instructions
- Using Arduino IDE Boards Manager (preferred)
+ [Instructions for Boards Manager](docs/arduino-ide/boards_manager.md)
- Using Arduino IDE with the development repository
@ -33,20 +29,19 @@ Most of the framework is implemented. Most noticable is the missing analogWrite.
- [Using as ESP-IDF component](docs/esp-idf_component.md)
- [Using OTAWebUpdater](docs/OTAWebUpdate/OTAWebUpdate.md)
#### Decoding exceptions
### Decoding exceptions
You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder) to get meaningful call trace.
#### Issue/Bug report template
### Issue/Bug report template
Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labelled as [for reference](https://github.com/espressif/arduino-esp32/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3A%22for%20reference%22%20).
Finally, if you're sure no one else had the issue, follow the [ISSUE_TEMPLATE](docs/ISSUE_TEMPLATE.md) while reporting any issue.
## ESP32Dev Board PINMAP
### ESP32Dev Board PINMAP
![Pin Functions](docs/esp32_pinmap.png)
## Hint
### Hint
Sometimes to program ESP32 via serial you must keep GPIO0 LOW during the programming process

View File

@ -1,19 +0,0 @@
build: off
environment:
matrix:
- PLATFORMIO_CI_SRC: "libraries/WiFi/examples/WiFiClient"
- PLATFORMIO_CI_SRC: "libraries/WiFi/examples/WiFiClientBasic"
- PLATFORMIO_CI_SRC: "libraries/WiFi/examples/WiFiClientEvents"
- PLATFORMIO_CI_SRC: "libraries/WiFi/examples/WiFiIPv6"
- PLATFORMIO_CI_SRC: "libraries/WiFi/examples/WiFiScan"
- PLATFORMIO_CI_SRC: "libraries/WiFi/examples/WiFiSmartConfig"
install:
- cmd: git submodule update --init --recursive
- cmd: SET PATH=%PATH%;C:\Python27\Scripts
- cmd: pip install -U https://github.com/platformio/platformio/archive/develop.zip
- cmd: platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage
test_script:
- cmd: platformio ci -b esp32dev -b nano32 -b node32s

View File

@ -44,6 +44,9 @@ esp32.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIF
esp32.menu.PartitionScheme.default.build.partitions=default
esp32.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
esp32.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
esp32.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT)
esp32.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
esp32.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336
esp32.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
esp32.menu.PartitionScheme.minimal.build.partitions=minimal
esp32.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
@ -66,6 +69,10 @@ esp32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT)
esp32.menu.PartitionScheme.fatflash.build.partitions=ffat
esp32.menu.PartitionScheme.fatflash.upload.maximum_size=2097152
esp32.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS)
esp32.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB
esp32.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728
esp32.menu.CPUFreq.240=240MHz (WiFi/BT)
esp32.menu.CPUFreq.240.build.f_cpu=240000000L
@ -104,12 +111,14 @@ esp32.menu.FlashFreq.40.build.flash_freq=40m
esp32.menu.FlashSize.4M=4MB (32Mb)
esp32.menu.FlashSize.4M.build.flash_size=4MB
esp32.menu.FlashSize.8M=8MB (64Mb)
esp32.menu.FlashSize.8M.build.flash_size=8MB
esp32.menu.FlashSize.8M.build.partitions=default_8MB
esp32.menu.FlashSize.2M=2MB (16Mb)
esp32.menu.FlashSize.2M.build.flash_size=2MB
esp32.menu.FlashSize.2M.build.partitions=minimal
esp32.menu.FlashSize.16M=16MB (128Mb)
esp32.menu.FlashSize.16M.build.flash_size=16MB
esp32.menu.FlashSize.16M.build.partitions=ffat
esp32.menu.UploadSpeed.921600=921600
esp32.menu.UploadSpeed.921600.upload.speed=921600
@ -225,7 +234,6 @@ esp32wrover.menu.DebugLevel.verbose=Verbose
esp32wrover.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
pico32.name=ESP32 Pico Kit
pico32.upload.tool=esptool_py
@ -249,6 +257,15 @@ pico32.build.boot=dio
pico32.build.partitions=default
pico32.build.defines=
pico32.menu.PartitionScheme.default=Default
pico32.menu.PartitionScheme.default.build.partitions=default
pico32.menu.PartitionScheme.no_ota=No OTA (Large APP)
pico32.menu.PartitionScheme.no_ota.build.partitions=no_ota
pico32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
pico32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
pico32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
pico32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
pico32.menu.UploadSpeed.921600=921600
pico32.menu.UploadSpeed.921600.upload.speed=921600
pico32.menu.UploadSpeed.115200=115200
@ -279,6 +296,110 @@ pico32.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
tinypico.name=TinyPICO
tinypico.upload.tool=esptool_py
tinypico.upload.maximum_size=1310720
tinypico.upload.maximum_data_size=327680
tinypico.upload.wait_for_upload_port=true
tinypico.serial.disableDTR=true
tinypico.serial.disableRTS=true
tinypico.build.mcu=esp32
tinypico.build.core=esp32
tinypico.build.variant=pico32
tinypico.build.board=ESP32_PICO
tinypico.build.f_cpu=240000000L
tinypico.build.flash_size=4MB
tinypico.build.flash_freq=80m
tinypico.build.flash_mode=dio
tinypico.build.boot=dio
tinypico.build.partitions=default
tinypico.build.defines=
tinypico.menu.UploadSpeed.921600=921600
tinypico.menu.UploadSpeed.921600.upload.speed=921600
tinypico.menu.UploadSpeed.115200=115200
tinypico.menu.UploadSpeed.115200.upload.speed=115200
tinypico.menu.UploadSpeed.256000.windows=256000
tinypico.menu.UploadSpeed.256000.upload.speed=256000
tinypico.menu.UploadSpeed.230400.windows.upload.speed=256000
tinypico.menu.UploadSpeed.230400=230400
tinypico.menu.UploadSpeed.230400.upload.speed=230400
tinypico.menu.UploadSpeed.460800.linux=460800
tinypico.menu.UploadSpeed.460800.macosx=460800
tinypico.menu.UploadSpeed.460800.upload.speed=460800
tinypico.menu.UploadSpeed.512000.windows=512000
tinypico.menu.UploadSpeed.512000.upload.speed=512000
tinypico.menu.FlashMode.qio=QIO
tinypico.menu.FlashMode.qio.build.flash_mode=dio
tinypico.menu.FlashMode.qio.build.boot=qio
tinypico.menu.FlashMode.dio=DIO
tinypico.menu.FlashMode.dio.build.flash_mode=dio
tinypico.menu.FlashMode.dio.build.boot=dio
tinypico.menu.FlashFreq.80=80MHz
tinypico.menu.FlashFreq.80.build.flash_freq=80m
tinypico.menu.FlashFreq.40=40MHz
tinypico.menu.FlashFreq.40.build.flash_freq=40m
tinypico.menu.PSRAM.enabled=Enabled
tinypico.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
tinypico.menu.PSRAM.disabled=Disabled
tinypico.menu.PSRAM.disabled.build.defines=
tinypico.menu.DebugLevel.none=None
tinypico.menu.DebugLevel.none.build.code_debug=0
tinypico.menu.DebugLevel.error=Error
tinypico.menu.DebugLevel.error.build.code_debug=1
tinypico.menu.DebugLevel.warn=Warn
tinypico.menu.DebugLevel.warn.build.code_debug=2
tinypico.menu.DebugLevel.info=Info
tinypico.menu.DebugLevel.info.build.code_debug=3
tinypico.menu.DebugLevel.debug=Debug
tinypico.menu.DebugLevel.debug.build.code_debug=4
tinypico.menu.DebugLevel.verbose=Verbose
tinypico.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
magicbit.name=MagicBit
magicbit.upload.tool=esptool_py
magicbit.upload.maximum_size=1310720
magicbit.upload.maximum_data_size=327680
magicbit.upload.wait_for_upload_port=true
magicbit.serial.disableDTR=true
magicbit.serial.disableRTS=true
magicbit.build.mcu=esp32
magicbit.build.core=esp32
magicbit.build.variant=magicbit
magicbit.build.board=ESP32_DEV
magicbit.build.f_cpu=240000000L
magicbit.build.flash_size=4MB
magicbit.build.flash_freq=40m
magicbit.build.flash_mode=dio
magicbit.build.boot=dio
magicbit.build.partitions=default
magicbit.menu.CPUFreq.240=240MHz (WiFi/BT)
magicbit.menu.CPUFreq.240.build.f_cpu=240000000L
magicbit.menu.CPUFreq.160=160MHz (WiFi/BT)
magicbit.menu.CPUFreq.160.build.f_cpu=160000000L
magicbit.menu.CPUFreq.80=80MHz (WiFi/BT)
magicbit.menu.CPUFreq.80.build.f_cpu=80000000L
magicbit.menu.CPUFreq.40=40MHz (40MHz XTAL)
magicbit.menu.UploadSpeed.921600=921600
magicbit.menu.UploadSpeed.921600.upload.speed=921600
magicbit.menu.UploadSpeed.115200=115200
magicbit.menu.UploadSpeed.115200.upload.speed=115200
##############################################################
turta_iot_node.name=Turta IoT Node
turta_iot_node.upload.tool=esptool_py
@ -378,6 +499,128 @@ ttgo-lora32-v1.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
ttgo-t1.name=TTGO T1
ttgo-t1.upload.tool=esptool_py
ttgo-t1.upload.maximum_size=1310720
ttgo-t1.upload.maximum_data_size=327680
ttgo-t1.upload.wait_for_upload_port=true
ttgo-t1.serial.disableDTR=true
ttgo-t1.serial.disableRTS=true
ttgo-t1.build.mcu=esp32
ttgo-t1.build.core=esp32
ttgo-t1.build.variant=ttgo-t1
ttgo-t1.build.board=TTGO_T1
ttgo-t1.build.f_cpu=240000000L
ttgo-t1.build.flash_size=4MB
ttgo-t1.build.flash_freq=40m
ttgo-t1.build.flash_mode=dio
ttgo-t1.build.boot=dio
ttgo-t1.build.partitions=default
ttgo-t1.build.defines=
ttgo-t1.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
ttgo-t1.menu.PartitionScheme.default.build.partitions=default
ttgo-t1.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
ttgo-t1.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
ttgo-t1.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
ttgo-t1.menu.PartitionScheme.minimal.build.partitions=minimal
ttgo-t1.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
ttgo-t1.menu.PartitionScheme.no_ota.build.partitions=no_ota
ttgo-t1.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
ttgo-t1.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
ttgo-t1.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
ttgo-t1.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
ttgo-t1.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
ttgo-t1.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
ttgo-t1.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
ttgo-t1.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
ttgo-t1.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
ttgo-t1.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
ttgo-t1.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
ttgo-t1.menu.PartitionScheme.huge_app.build.partitions=huge_app
ttgo-t1.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
ttgo-t1.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
ttgo-t1.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
ttgo-t1.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
ttgo-t1.menu.CPUFreq.240=240MHz (WiFi/BT)
ttgo-t1.menu.CPUFreq.240.build.f_cpu=240000000L
ttgo-t1.menu.CPUFreq.160=160MHz (WiFi/BT)
ttgo-t1.menu.CPUFreq.160.build.f_cpu=160000000L
ttgo-t1.menu.CPUFreq.80=80MHz (WiFi/BT)
ttgo-t1.menu.CPUFreq.80.build.f_cpu=80000000L
ttgo-t1.menu.CPUFreq.40=40MHz (40MHz XTAL)
ttgo-t1.menu.CPUFreq.40.build.f_cpu=40000000L
ttgo-t1.menu.CPUFreq.26=26MHz (26MHz XTAL)
ttgo-t1.menu.CPUFreq.26.build.f_cpu=26000000L
ttgo-t1.menu.CPUFreq.20=20MHz (40MHz XTAL)
ttgo-t1.menu.CPUFreq.20.build.f_cpu=20000000L
ttgo-t1.menu.CPUFreq.13=13MHz (26MHz XTAL)
ttgo-t1.menu.CPUFreq.13.build.f_cpu=13000000L
ttgo-t1.menu.CPUFreq.10=10MHz (40MHz XTAL)
ttgo-t1.menu.CPUFreq.10.build.f_cpu=10000000L
ttgo-t1.menu.FlashMode.qio=QIO
ttgo-t1.menu.FlashMode.qio.build.flash_mode=dio
ttgo-t1.menu.FlashMode.qio.build.boot=qio
ttgo-t1.menu.FlashMode.dio=DIO
ttgo-t1.menu.FlashMode.dio.build.flash_mode=dio
ttgo-t1.menu.FlashMode.dio.build.boot=dio
ttgo-t1.menu.FlashMode.qout=QOUT
ttgo-t1.menu.FlashMode.qout.build.flash_mode=dout
ttgo-t1.menu.FlashMode.qout.build.boot=qout
ttgo-t1.menu.FlashMode.dout=DOUT
ttgo-t1.menu.FlashMode.dout.build.flash_mode=dout
ttgo-t1.menu.FlashMode.dout.build.boot=dout
ttgo-t1.menu.FlashFreq.80=80MHz
ttgo-t1.menu.FlashFreq.80.build.flash_freq=80m
ttgo-t1.menu.FlashFreq.40=40MHz
ttgo-t1.menu.FlashFreq.40.build.flash_freq=40m
ttgo-t1.menu.FlashSize.4M=4MB (32Mb)
ttgo-t1.menu.FlashSize.4M.build.flash_size=4MB
ttgo-t1.menu.FlashSize.2M=2MB (16Mb)
ttgo-t1.menu.FlashSize.2M.build.flash_size=2MB
ttgo-t1.menu.FlashSize.2M.build.partitions=minimal
ttgo-t1.menu.FlashSize.16M=16MB (128Mb)
ttgo-t1.menu.FlashSize.16M.build.flash_size=16MB
ttgo-t1.menu.FlashSize.16M.build.partitions=ffat
ttgo-t1.menu.UploadSpeed.921600=921600
ttgo-t1.menu.UploadSpeed.921600.upload.speed=921600
ttgo-t1.menu.UploadSpeed.115200=115200
ttgo-t1.menu.UploadSpeed.115200.upload.speed=115200
ttgo-t1.menu.UploadSpeed.256000.windows=256000
ttgo-t1.menu.UploadSpeed.256000.upload.speed=256000
ttgo-t1.menu.UploadSpeed.230400.windows.upload.speed=256000
ttgo-t1.menu.UploadSpeed.230400=230400
ttgo-t1.menu.UploadSpeed.230400.upload.speed=230400
ttgo-t1.menu.UploadSpeed.460800.linux=460800
ttgo-t1.menu.UploadSpeed.460800.macosx=460800
ttgo-t1.menu.UploadSpeed.460800.upload.speed=460800
ttgo-t1.menu.UploadSpeed.512000.windows=512000
ttgo-t1.menu.UploadSpeed.512000.upload.speed=512000
ttgo-t1.menu.DebugLevel.none=None
ttgo-t1.menu.DebugLevel.none.build.code_debug=0
ttgo-t1.menu.DebugLevel.error=Error
ttgo-t1.menu.DebugLevel.error.build.code_debug=1
ttgo-t1.menu.DebugLevel.warn=Warn
ttgo-t1.menu.DebugLevel.warn.build.code_debug=2
ttgo-t1.menu.DebugLevel.info=Info
ttgo-t1.menu.DebugLevel.info.build.code_debug=3
ttgo-t1.menu.DebugLevel.debug=Debug
ttgo-t1.menu.DebugLevel.debug.build.code_debug=4
ttgo-t1.menu.DebugLevel.verbose=Verbose
ttgo-t1.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
cw02.name=XinaBox CW02
cw02.upload.tool=esptool_py
@ -879,6 +1122,23 @@ lolin32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
lolin32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
lolin32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
lolin32.menu.CPUFreq.240=240MHz (WiFi/BT)
lolin32.menu.CPUFreq.240.build.f_cpu=240000000L
lolin32.menu.CPUFreq.160=160MHz (WiFi/BT)
lolin32.menu.CPUFreq.160.build.f_cpu=160000000L
lolin32.menu.CPUFreq.80=80MHz (WiFi/BT)
lolin32.menu.CPUFreq.80.build.f_cpu=80000000L
lolin32.menu.CPUFreq.40=40MHz (40MHz XTAL)
lolin32.menu.CPUFreq.40.build.f_cpu=40000000L
lolin32.menu.CPUFreq.26=26MHz (26MHz XTAL)
lolin32.menu.CPUFreq.26.build.f_cpu=26000000L
lolin32.menu.CPUFreq.20=20MHz (40MHz XTAL)
lolin32.menu.CPUFreq.20.build.f_cpu=20000000L
lolin32.menu.CPUFreq.13=13MHz (26MHz XTAL)
lolin32.menu.CPUFreq.13.build.f_cpu=13000000L
lolin32.menu.CPUFreq.10=10MHz (40MHz XTAL)
lolin32.menu.CPUFreq.10.build.f_cpu=10000000L
lolin32.menu.UploadSpeed.921600=921600
lolin32.menu.UploadSpeed.921600.upload.speed=921600
lolin32.menu.UploadSpeed.115200=115200
@ -940,7 +1200,7 @@ pocket_32.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
WeMosBat.name="WeMos" WiFi&Bluetooth Battery
WeMosBat.name=WeMos WiFi&Bluetooth Battery
WeMosBat.upload.tool=esptool_py
WeMosBat.upload.maximum_size=1310720
@ -1403,6 +1663,15 @@ featheresp32.menu.DebugLevel.debug.build.code_debug=4
featheresp32.menu.DebugLevel.verbose=Verbose
featheresp32.menu.DebugLevel.verbose.build.code_debug=5
featheresp32.menu.PartitionScheme.default=Default
featheresp32.menu.PartitionScheme.default.build.partitions=default
featheresp32.menu.PartitionScheme.no_ota=No OTA (Large APP)
featheresp32.menu.PartitionScheme.no_ota.build.partitions=no_ota
featheresp32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
featheresp32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
featheresp32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
featheresp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
##############################################################
nodemcu-32s.name=NodeMCU-32S
@ -1814,6 +2083,121 @@ esp32-poe.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
##############################################################
esp32-poe-iso.name=OLIMEX ESP32-PoE-ISO
esp32-poe-iso.upload.tool=esptool_py
esp32-poe-iso.upload.maximum_size=1310720
esp32-poe-iso.upload.maximum_data_size=327680
esp32-poe-iso.upload.wait_for_upload_port=true
esp32-poe-iso.serial.disableDTR=true
esp32-poe-iso.serial.disableRTS=true
esp32-poe-iso.build.mcu=esp32
esp32-poe-iso.build.core=esp32
esp32-poe-iso.build.variant=esp32-poe-iso
esp32-poe-iso.build.board=ESP32_POE_ISO
esp32-poe-iso.build.f_cpu=240000000L
esp32-poe-iso.build.flash_mode=dio
esp32-poe-iso.build.flash_size=4MB
esp32-poe-iso.build.boot=dio
esp32-poe-iso.build.partitions=default
esp32-poe-iso.build.defines=
esp32-poe-iso.menu.FlashFreq.80=80MHz
esp32-poe-iso.menu.FlashFreq.80.build.flash_freq=80m
esp32-poe-iso.menu.FlashFreq.40=40MHz
esp32-poe-iso.menu.FlashFreq.40.build.flash_freq=40m
esp32-poe-iso.menu.UploadSpeed.115200=115200
esp32-poe-iso.menu.UploadSpeed.115200.upload.speed=115200
esp32-poe-iso.menu.PartitionScheme.default=Default
esp32-poe-iso.menu.PartitionScheme.default.build.partitions=default
esp32-poe-iso.menu.PartitionScheme.no_ota=No OTA (Large APP)
esp32-poe-iso.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32-poe-iso.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32-poe-iso.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32-poe-iso.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32-poe-iso.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
##############################################################
esp32-DevKitLipo.name=OLIMEX ESP32-DevKit-LiPo
esp32-DevKitLipo.upload.tool=esptool_py
esp32-DevKitLipo.upload.maximum_size=1310720
esp32-DevKitLipo.upload.maximum_data_size=327680
esp32-DevKitLipo.upload.wait_for_upload_port=true
esp32-DevKitLipo.serial.disableDTR=true
esp32-DevKitLipo.serial.disableRTS=true
esp32-DevKitLipo.build.mcu=esp32
esp32-DevKitLipo.build.core=esp32
esp32-DevKitLipo.build.variant=esp32-devkit-lipo
esp32-DevKitLipo.build.board=ESP32_DEVKIT_LIPO
esp32-DevKitLipo.build.f_cpu=240000000L
esp32-DevKitLipo.build.flash_size=4MB
esp32-DevKitLipo.build.flash_freq=40m
esp32-DevKitLipo.build.flash_mode=dio
esp32-DevKitLipo.build.boot=dio
esp32-DevKitLipo.build.partitions=default
esp32-DevKitLipo.build.defines=
esp32-DevKitLipo.menu.PartitionScheme.default=Default
esp32-DevKitLipo.menu.PartitionScheme.default.build.partitions=default
esp32-DevKitLipo.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
esp32-DevKitLipo.menu.PartitionScheme.minimal.build.partitions=minimal
esp32-DevKitLipo.menu.PartitionScheme.no_ota=No OTA (Large APP)
esp32-DevKitLipo.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32-DevKitLipo.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32-DevKitLipo.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA)
esp32-DevKitLipo.menu.PartitionScheme.huge_app.build.partitions=huge_app
esp32-DevKitLipo.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
esp32-DevKitLipo.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32-DevKitLipo.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32-DevKitLipo.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32-DevKitLipo.menu.PartitionScheme.fatflash=16M Fat
esp32-DevKitLipo.menu.PartitionScheme.fatflash.build.partitions=ffat
esp32-DevKitLipo.menu.FlashMode.qio=QIO
esp32-DevKitLipo.menu.FlashMode.qio.build.flash_mode=dio
esp32-DevKitLipo.menu.FlashMode.qio.build.boot=qio
esp32-DevKitLipo.menu.FlashMode.dio=DIO
esp32-DevKitLipo.menu.FlashMode.dio.build.flash_mode=dio
esp32-DevKitLipo.menu.FlashMode.dio.build.boot=dio
esp32-DevKitLipo.menu.FlashMode.qout=QOUT
esp32-DevKitLipo.menu.FlashMode.qout.build.flash_mode=dout
esp32-DevKitLipo.menu.FlashMode.qout.build.boot=qout
esp32-DevKitLipo.menu.FlashMode.dout=DOUT
esp32-DevKitLipo.menu.FlashMode.dout.build.flash_mode=dout
esp32-DevKitLipo.menu.FlashMode.dout.build.boot=dout
esp32-DevKitLipo.menu.FlashFreq.80=80MHz
esp32-DevKitLipo.menu.FlashFreq.80.build.flash_freq=80m
esp32-DevKitLipo.menu.FlashFreq.40=40MHz
esp32-DevKitLipo.menu.FlashFreq.40.build.flash_freq=40m
esp32-DevKitLipo.menu.UploadSpeed.921600=921600
esp32-DevKitLipo.menu.UploadSpeed.921600.upload.speed=921600
esp32-DevKitLipo.menu.UploadSpeed.115200=115200
esp32-DevKitLipo.menu.UploadSpeed.115200.upload.speed=115200
esp32-DevKitLipo.menu.UploadSpeed.256000.windows=256000
esp32-DevKitLipo.menu.UploadSpeed.256000.upload.speed=256000
esp32-DevKitLipo.menu.UploadSpeed.230400.windows.upload.speed=256000
esp32-DevKitLipo.menu.UploadSpeed.230400=230400
esp32-DevKitLipo.menu.UploadSpeed.230400.upload.speed=230400
esp32-DevKitLipo.menu.UploadSpeed.460800.linux=460800
esp32-DevKitLipo.menu.UploadSpeed.460800.macosx=460800
esp32-DevKitLipo.menu.UploadSpeed.460800.upload.speed=460800
esp32-DevKitLipo.menu.UploadSpeed.512000.windows=512000
esp32-DevKitLipo.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
espino32.name=ThaiEasyElec's ESPino32
espino32.upload.tool=esptool_py
@ -1967,6 +2351,7 @@ m5stack-fire.menu.PSRAM.disabled.build.defines=
m5stack-fire.menu.PartitionScheme.default=Default (2 x 6.5 MB app, 3.6 MB SPIFFS)
m5stack-fire.menu.PartitionScheme.default.build.partitions=default_16MB
m5stack-fire.menu.PartitionScheme.default.upload.maximum_size=6553600
m5stack-fire.menu.PartitionScheme.large_spiffs=Large SPIFFS (7 MB)
m5stack-fire.menu.PartitionScheme.large_spiffs.build.partitions=large_spiffs_16MB
m5stack-fire.menu.PartitionScheme.large_spiffs.upload.maximum_size=4685824
@ -2396,6 +2781,7 @@ heltec_wifi_lora_32_V2.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-
heltec_wifi_lora_32_V2.menu.PartitionScheme.default=default_8MB
heltec_wifi_lora_32_V2.menu.PartitionScheme.default.build.partitions=default_8MB
heltec_wifi_lora_32_V2.menu.PartitionScheme.default.upload.maximum_size=3342336
heltec_wifi_lora_32_V2.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
heltec_wifi_lora_32_V2.menu.PartitionScheme.minimal.build.partitions=minimal
heltec_wifi_lora_32_V2.menu.PartitionScheme.no_ota=No OTA (Large APP)
@ -2443,7 +2829,7 @@ heltec_wifi_lora_32_V2.menu.FlashFreq.40.build.flash_freq=40m
heltec_wifi_lora_32_V2.menu.FlashSize.8M=8MB (64Mb)
heltec_wifi_lora_32_V2.menu.FlashSize.8M.build.flash_size=8MB
heltec_wifi_lora_32_V2.menu.FlashSize.2M.build.partitions=default_8MB
heltec_wifi_lora_32_V2.menu.FlashSize.8M.build.partitions=default_8MB
heltec_wifi_lora_32_V2.menu.FlashSize.4M=4MB (32Mb)
heltec_wifi_lora_32_V2.menu.FlashSize.4M.build.flash_size=4MB
heltec_wifi_lora_32_V2.menu.FlashSize.2M=2MB (16Mb)
@ -2513,6 +2899,7 @@ heltec_wireless_stick.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-e
heltec_wireless_stick.menu.PartitionScheme.default=default_8MB
heltec_wireless_stick.menu.PartitionScheme.default.build.partitions=default_8MB
heltec_wireless_stick.menu.PartitionScheme.default.upload.maximum_size=3342336
heltec_wireless_stick.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
heltec_wireless_stick.menu.PartitionScheme.minimal.build.partitions=minimal
heltec_wireless_stick.menu.PartitionScheme.no_ota=No OTA (Large APP)
@ -2744,16 +3131,54 @@ alksesp32.build.boot=dio
alksesp32.build.partitions=default
alksesp32.build.defines=
alksesp32.menu.PartitionScheme.default=Default
alksesp32.menu.PSRAM.disabled=Disabled
alksesp32.menu.PSRAM.disabled.build.defines=
alksesp32.menu.PSRAM.enabled=Enabled
alksesp32.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
alksesp32.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
alksesp32.menu.PartitionScheme.default.build.partitions=default
alksesp32.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
alksesp32.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
alksesp32.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
alksesp32.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
alksesp32.menu.PartitionScheme.minimal.build.partitions=minimal
alksesp32.menu.PartitionScheme.no_ota=No OTA (Large APP)
alksesp32.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
alksesp32.menu.PartitionScheme.no_ota.build.partitions=no_ota
alksesp32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
alksesp32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
alksesp32.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
alksesp32.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
alksesp32.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
alksesp32.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
alksesp32.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
alksesp32.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
alksesp32.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
alksesp32.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
alksesp32.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
alksesp32.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
alksesp32.menu.PartitionScheme.huge_app.build.partitions=huge_app
alksesp32.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
alksesp32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
alksesp32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
alksesp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
alksesp32.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT)
alksesp32.menu.PartitionScheme.fatflash.build.partitions=ffat
alksesp32.menu.CPUFreq.240=240MHz (WiFi/BT)
alksesp32.menu.CPUFreq.240.build.f_cpu=240000000L
alksesp32.menu.CPUFreq.160=160MHz (WiFi/BT)
alksesp32.menu.CPUFreq.160.build.f_cpu=160000000L
alksesp32.menu.CPUFreq.80=80MHz (WiFi/BT)
alksesp32.menu.CPUFreq.80.build.f_cpu=80000000L
alksesp32.menu.CPUFreq.40=40MHz (40MHz XTAL)
alksesp32.menu.CPUFreq.40.build.f_cpu=40000000L
alksesp32.menu.CPUFreq.26=26MHz (26MHz XTAL)
alksesp32.menu.CPUFreq.26.build.f_cpu=26000000L
alksesp32.menu.CPUFreq.20=20MHz (40MHz XTAL)
alksesp32.menu.CPUFreq.20.build.f_cpu=20000000L
alksesp32.menu.CPUFreq.13=13MHz (26MHz XTAL)
alksesp32.menu.CPUFreq.13.build.f_cpu=13000000L
alksesp32.menu.CPUFreq.10=10MHz (40MHz XTAL)
alksesp32.menu.CPUFreq.10.build.f_cpu=10000000L
alksesp32.menu.FlashMode.qio=QIO
alksesp32.menu.FlashMode.qio.build.flash_mode=dio
@ -2778,6 +3203,9 @@ alksesp32.menu.FlashSize.4M.build.flash_size=4MB
alksesp32.menu.FlashSize.2M=2MB (16Mb)
alksesp32.menu.FlashSize.2M.build.flash_size=2MB
alksesp32.menu.FlashSize.2M.build.partitions=minimal
alksesp32.menu.FlashSize.16M=16MB (128Mb)
alksesp32.menu.FlashSize.16M.build.flash_size=16MB
alksesp32.menu.FlashSize.16M.build.partitions=ffat
alksesp32.menu.UploadSpeed.921600=921600
alksesp32.menu.UploadSpeed.921600.upload.speed=921600
@ -3451,4 +3879,326 @@ esp32cam.build.code_debug=0
##############################################################
sparkfun_lora_gateway_1-channel.name=SparkFun LoRa Gateway 1-Channel
sparkfun_lora_gateway_1-channel.upload.tool=esptool_py
sparkfun_lora_gateway_1-channel.upload.maximum_size=1310720
sparkfun_lora_gateway_1-channel.upload.maximum_data_size=294912
sparkfun_lora_gateway_1-channel.upload.wait_for_upload_port=true
sparkfun_lora_gateway_1-channel.serial.disableDTR=true
sparkfun_lora_gateway_1-channel.serial.disableRTS=true
sparkfun_lora_gateway_1-channel.build.mcu=esp32
sparkfun_lora_gateway_1-channel.build.core=esp32
sparkfun_lora_gateway_1-channel.build.variant=sparkfun_lora_gateway_1-channel
sparkfun_lora_gateway_1-channel.build.board=ESP32_DEV
sparkfun_lora_gateway_1-channel.build.f_cpu=240000000L
sparkfun_lora_gateway_1-channel.build.flash_size=4MB
sparkfun_lora_gateway_1-channel.build.flash_freq=40m
sparkfun_lora_gateway_1-channel.build.flash_mode=dio
sparkfun_lora_gateway_1-channel.build.boot=dio
sparkfun_lora_gateway_1-channel.build.partitions=default
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.default=Default
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.default.build.partitions=default
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.minimal.build.partitions=minimal
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.no_ota=No OTA (Large APP)
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.no_ota.build.partitions=no_ota
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
sparkfun_lora_gateway_1-channel.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
sparkfun_lora_gateway_1-channel.menu.FlashMode.qio=QIO
sparkfun_lora_gateway_1-channel.menu.FlashMode.qio.build.flash_mode=dio
sparkfun_lora_gateway_1-channel.menu.FlashMode.qio.build.boot=qio
sparkfun_lora_gateway_1-channel.menu.FlashMode.dio=DIO
sparkfun_lora_gateway_1-channel.menu.FlashMode.dio.build.flash_mode=dio
sparkfun_lora_gateway_1-channel.menu.FlashMode.dio.build.boot=dio
sparkfun_lora_gateway_1-channel.menu.FlashMode.qout=QOUT
sparkfun_lora_gateway_1-channel.menu.FlashMode.qout.build.flash_mode=dout
sparkfun_lora_gateway_1-channel.menu.FlashMode.qout.build.boot=qout
sparkfun_lora_gateway_1-channel.menu.FlashMode.dout=DOUT
sparkfun_lora_gateway_1-channel.menu.FlashMode.dout.build.flash_mode=dout
sparkfun_lora_gateway_1-channel.menu.FlashMode.dout.build.boot=dout
sparkfun_lora_gateway_1-channel.menu.FlashFreq.80=80MHz
sparkfun_lora_gateway_1-channel.menu.FlashFreq.80.build.flash_freq=80m
sparkfun_lora_gateway_1-channel.menu.FlashFreq.40=40MHz
sparkfun_lora_gateway_1-channel.menu.FlashFreq.40.build.flash_freq=40m
sparkfun_lora_gateway_1-channel.menu.FlashSize.4M=4MB (32Mb)
sparkfun_lora_gateway_1-channel.menu.FlashSize.4M.build.flash_size=4MB
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.921600=921600
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.921600.upload.speed=921600
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.115200=115200
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.115200.upload.speed=115200
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.256000.windows=256000
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.256000.upload.speed=256000
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.230400.windows.upload.speed=256000
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.230400=230400
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.230400.upload.speed=230400
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.460800.linux=460800
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.460800.macosx=460800
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.460800.upload.speed=460800
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.512000.windows=512000
sparkfun_lora_gateway_1-channel.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
ttgo-t-watch.name=TTGO T-Watch
ttgo-t-watch.upload.tool=esptool_py
ttgo-t-watch.upload.maximum_size=6553600
ttgo-t-watch.upload.maximum_data_size=4521984
ttgo-t-watch.upload.wait_for_upload_port=true
ttgo-t-watch.serial.disableDTR=true
ttgo-t-watch.serial.disableRTS=true
ttgo-t-watch.build.mcu=esp32
ttgo-t-watch.build.core=esp32
ttgo-t-watch.build.variant=twatch
ttgo-t-watch.build.board=T-Watch
ttgo-t-watch.build.f_cpu=240000000L
ttgo-t-watch.build.flash_size=16MB
ttgo-t-watch.build.flash_freq=80m
ttgo-t-watch.build.flash_mode=dio
ttgo-t-watch.build.boot=dio
ttgo-t-watch.build.partitions=default_16MB
ttgo-t-watch.build.defines=
ttgo-t-watch.menu.PSRAM.enabled=Enabled
ttgo-t-watch.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
ttgo-t-watch.menu.PSRAM.disabled=Disabled
ttgo-t-watch.menu.PSRAM.disabled.build.defines=
ttgo-t-watch.menu.PartitionScheme.default=Default (2 x 6.5 MB app, 3.6 MB SPIFFS)
ttgo-t-watch.menu.PartitionScheme.default.build.partitions=default_16MB
ttgo-t-watch.menu.PartitionScheme.default.upload.maximum_size=6553600
ttgo-t-watch.menu.PartitionScheme.large_spiffs=Large SPIFFS (7 MB)
ttgo-t-watch.menu.PartitionScheme.large_spiffs.build.partitions=large_spiffs_16MB
ttgo-t-watch.menu.PartitionScheme.large_spiffs.upload.maximum_size=4685824
ttgo-t-watch.menu.UploadSpeed.2000000=2000000
ttgo-t-watch.menu.UploadSpeed.2000000.upload.speed=2000000
ttgo-t-watch.menu.UploadSpeed.1152000=1152000
ttgo-t-watch.menu.UploadSpeed.1152000.upload.speed=1152000
ttgo-t-watch.menu.UploadSpeed.921600=921600
ttgo-t-watch.menu.UploadSpeed.921600.upload.speed=921600
ttgo-t-watch.menu.UploadSpeed.115200=115200
ttgo-t-watch.menu.UploadSpeed.115200.upload.speed=115200
ttgo-t-watch.menu.UploadSpeed.256000.windows=256000
ttgo-t-watch.menu.UploadSpeed.256000.upload.speed=256000
ttgo-t-watch.menu.UploadSpeed.230400.windows.upload.speed=256000
ttgo-t-watch.menu.UploadSpeed.230400=230400
ttgo-t-watch.menu.UploadSpeed.230400.upload.speed=230400
ttgo-t-watch.menu.UploadSpeed.460800.linux=460800
ttgo-t-watch.menu.UploadSpeed.460800.macosx=460800
ttgo-t-watch.menu.UploadSpeed.460800.upload.speed=460800
ttgo-t-watch.menu.UploadSpeed.512000.windows=512000
ttgo-t-watch.menu.UploadSpeed.512000.upload.speed=512000
ttgo-t-watch.menu.DebugLevel.none=None
ttgo-t-watch.menu.DebugLevel.none.build.code_debug=0
ttgo-t-watch.menu.DebugLevel.error=Error
ttgo-t-watch.menu.DebugLevel.error.build.code_debug=1
ttgo-t-watch.menu.DebugLevel.warn=Warn
ttgo-t-watch.menu.DebugLevel.warn.build.code_debug=2
ttgo-t-watch.menu.DebugLevel.info=Info
ttgo-t-watch.menu.DebugLevel.info.build.code_debug=3
ttgo-t-watch.menu.DebugLevel.debug=Debug
ttgo-t-watch.menu.DebugLevel.debug.build.code_debug=4
ttgo-t-watch.menu.DebugLevel.verbose=Verbose
ttgo-t-watch.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
d1_mini32.name=WEMOS D1 MINI ESP32
d1_mini32.upload.tool=esptool_py
d1_mini32.upload.maximum_size=1310720
d1_mini32.upload.maximum_data_size=327680
d1_mini32.upload.wait_for_upload_port=true
d1_mini32.serial.disableDTR=true
d1_mini32.serial.disableRTS=true
d1_mini32.build.mcu=esp32
d1_mini32.build.core=esp32
d1_mini32.build.variant=d1_mini32
d1_mini32.build.board=D1_MINI32
d1_mini32.build.f_cpu=240000000L
d1_mini32.build.flash_mode=dio
d1_mini32.build.flash_size=4MB
d1_mini32.build.boot=dio
d1_mini32.build.partitions=default
d1_mini32.build.defines=
d1_mini32.menu.FlashFreq.80=80MHz
d1_mini32.menu.FlashFreq.80.build.flash_freq=80m
d1_mini32.menu.FlashFreq.40=40MHz
d1_mini32.menu.FlashFreq.40.build.flash_freq=40m
d1_mini32.menu.PartitionScheme.default=Default
d1_mini32.menu.PartitionScheme.default.build.partitions=default
d1_mini32.menu.PartitionScheme.no_ota=No OTA (Large APP)
d1_mini32.menu.PartitionScheme.no_ota.build.partitions=no_ota
d1_mini32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
d1_mini32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
d1_mini32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
d1_mini32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
d1_mini32.menu.CPUFreq.240=240MHz (WiFi/BT)
d1_mini32.menu.CPUFreq.240.build.f_cpu=240000000L
d1_mini32.menu.CPUFreq.160=160MHz (WiFi/BT)
d1_mini32.menu.CPUFreq.160.build.f_cpu=160000000L
d1_mini32.menu.CPUFreq.80=80MHz (WiFi/BT)
d1_mini32.menu.CPUFreq.80.build.f_cpu=80000000L
d1_mini32.menu.CPUFreq.40=40MHz (40MHz XTAL)
d1_mini32.menu.CPUFreq.40.build.f_cpu=40000000L
d1_mini32.menu.CPUFreq.26=26MHz (26MHz XTAL)
d1_mini32.menu.CPUFreq.26.build.f_cpu=26000000L
d1_mini32.menu.CPUFreq.20=20MHz (40MHz XTAL)
d1_mini32.menu.CPUFreq.20.build.f_cpu=20000000L
d1_mini32.menu.CPUFreq.13=13MHz (26MHz XTAL)
d1_mini32.menu.CPUFreq.13.build.f_cpu=13000000L
d1_mini32.menu.CPUFreq.10=10MHz (40MHz XTAL)
d1_mini32.menu.CPUFreq.10.build.f_cpu=10000000L
d1_mini32.menu.UploadSpeed.921600=921600
d1_mini32.menu.UploadSpeed.921600.upload.speed=921600
d1_mini32.menu.UploadSpeed.115200=115200
d1_mini32.menu.UploadSpeed.115200.upload.speed=115200
d1_mini32.menu.UploadSpeed.256000.windows=256000
d1_mini32.menu.UploadSpeed.256000.upload.speed=256000
d1_mini32.menu.UploadSpeed.230400.windows.upload.speed=256000
d1_mini32.menu.UploadSpeed.230400=230400
d1_mini32.menu.UploadSpeed.230400.upload.speed=230400
d1_mini32.menu.UploadSpeed.460800.linux=460800
d1_mini32.menu.UploadSpeed.460800.macosx=460800
d1_mini32.menu.UploadSpeed.460800.upload.speed=460800
d1_mini32.menu.UploadSpeed.512000.windows=512000
d1_mini32.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
gpy.name=Pycom GPy
gpy.upload.tool=esptool_py
gpy.upload.maximum_size=1310720
gpy.upload.maximum_data_size=327680
gpy.upload.wait_for_upload_port=true
gpy.serial.disableDTR=true
gpy.serial.disableRTS=true
gpy.build.mcu=esp32
gpy.build.core=esp32
gpy.build.variant=gpy
gpy.build.board=PYCOM_GPY
gpy.build.f_cpu=240000000L
gpy.build.flash_mode=dio
gpy.build.flash_size=8MB
gpy.build.boot=dio
gpy.build.partitions=default
gpy.menu.FlashFreq.80=80MHz
gpy.menu.FlashFreq.80.build.flash_freq=80m
gpy.menu.FlashFreq.40=40MHz
gpy.menu.FlashFreq.40.build.flash_freq=40m
gpy.menu.UploadSpeed.921600=921600
gpy.menu.UploadSpeed.921600.upload.speed=921600
gpy.menu.UploadSpeed.115200=115200
gpy.menu.UploadSpeed.115200.upload.speed=115200
gpy.menu.UploadSpeed.256000.windows=256000
gpy.menu.UploadSpeed.256000.upload.speed=256000
gpy.menu.UploadSpeed.230400.windows.upload.speed=256000
gpy.menu.UploadSpeed.230400=230400
gpy.menu.UploadSpeed.230400.upload.speed=230400
gpy.menu.UploadSpeed.460800.linux=460800
gpy.menu.UploadSpeed.460800.macosx=460800
gpy.menu.UploadSpeed.460800.upload.speed=460800
gpy.menu.UploadSpeed.512000.windows=512000
gpy.menu.UploadSpeed.512000.upload.speed=512000
gpy.menu.DebugLevel.none=None
gpy.menu.DebugLevel.none.build.code_debug=0
gpy.menu.DebugLevel.error=Error
gpy.menu.DebugLevel.error.build.code_debug=1
gpy.menu.DebugLevel.warn=Warn
gpy.menu.DebugLevel.warn.build.code_debug=2
gpy.menu.DebugLevel.info=Info
gpy.menu.DebugLevel.info.build.code_debug=3
gpy.menu.DebugLevel.debug=Debug
gpy.menu.DebugLevel.debug.build.code_debug=4
gpy.menu.DebugLevel.verbose=Verbose
gpy.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
vintlabs-devkit-v1.name=VintLabs ESP32 Devkit
vintlabs-devkit-v1.upload.tool=esptool_py
vintlabs-devkit-v1.upload.maximum_size=1310720
vintlabs-devkit-v1.upload.maximum_data_size=327680
vintlabs-devkit-v1.upload.wait_for_upload_port=true
vintlabs-devkit-v1.serial.disableDTR=true
vintlabs-devkit-v1.serial.disableRTS=true
vintlabs-devkit-v1.build.mcu=esp32
vintlabs-devkit-v1.build.core=esp32
vintlabs-devkit-v1.build.variant=vintlabsdevkitv1
vintlabs-devkit-v1.build.board=ESP32_DEV
vintlabs-devkit-v1.build.f_cpu=240000000L
vintlabs-devkit-v1.build.flash_mode=dio
vintlabs-devkit-v1.build.flash_size=4MB
vintlabs-devkit-v1.build.boot=dio
vintlabs-devkit-v1.build.partitions=default
vintlabs-devkit-v1.build.defines=
vintlabs-devkit-v1.menu.FlashFreq.80=80MHz
vintlabs-devkit-v1.menu.FlashFreq.80.build.flash_freq=80m
vintlabs-devkit-v1.menu.FlashFreq.40=40MHz
vintlabs-devkit-v1.menu.FlashFreq.40.build.flash_freq=40m
vintlabs-devkit-v1.menu.UploadSpeed.2000000=2000000
vintlabs-devkit-v1.menu.UploadSpeed.2000000.upload.speed=2000000
vintlabs-devkit-v1.menu.UploadSpeed.921600=921600
vintlabs-devkit-v1.menu.UploadSpeed.921600.upload.speed=921600
vintlabs-devkit-v1.menu.UploadSpeed.115200=115200
vintlabs-devkit-v1.menu.UploadSpeed.115200.upload.speed=115200
vintlabs-devkit-v1.menu.UploadSpeed.256000.windows=256000
vintlabs-devkit-v1.menu.UploadSpeed.256000.upload.speed=256000
vintlabs-devkit-v1.menu.UploadSpeed.230400.windows.upload.speed=256000
vintlabs-devkit-v1.menu.UploadSpeed.230400=230400
vintlabs-devkit-v1.menu.UploadSpeed.230400.upload.speed=230400
vintlabs-devkit-v1.menu.UploadSpeed.460800.linux=460800
vintlabs-devkit-v1.menu.UploadSpeed.460800.macosx=460800
vintlabs-devkit-v1.menu.UploadSpeed.460800.upload.speed=460800
vintlabs-devkit-v1.menu.UploadSpeed.512000.windows=512000
vintlabs-devkit-v1.menu.UploadSpeed.512000.upload.speed=512000
vintlabs-devkit-v1.menu.DebugLevel.none=None
vintlabs-devkit-v1.menu.DebugLevel.none.build.code_debug=0
vintlabs-devkit-v1.menu.DebugLevel.error=Error
vintlabs-devkit-v1.menu.DebugLevel.error.build.code_debug=1
vintlabs-devkit-v1.menu.DebugLevel.warn=Warn
vintlabs-devkit-v1.menu.DebugLevel.warn.build.code_debug=2
vintlabs-devkit-v1.menu.DebugLevel.info=Info
vintlabs-devkit-v1.menu.DebugLevel.info.build.code_debug=3
vintlabs-devkit-v1.menu.DebugLevel.debug=Debug
vintlabs-devkit-v1.menu.DebugLevel.debug.build.code_debug=4
##############################################################

View File

@ -68,12 +68,6 @@
#define __STRINGIFY(a) #a
#endif
// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif
#define abs(x) ((x)>0?(x):-(x))
#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)
@ -160,6 +154,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
#include "HardwareSerial.h"
#include "Esp.h"
using std::abs;
using std::isinf;
using std::isnan;
using std::max;

View File

@ -92,13 +92,6 @@ void EspClass::deepSleep(uint32_t time_us)
esp_deep_sleep(time_us);
}
uint32_t EspClass::getCycleCount()
{
uint32_t ccount;
__asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount));
return ccount;
}
void EspClass::restart(void)
{
esp_restart();

View File

@ -75,8 +75,8 @@ public:
uint32_t getMaxAllocPsram();
uint8_t getChipRevision();
uint8_t getCpuFreqMHz(){ return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; }
uint32_t getCycleCount();
uint32_t getCpuFreqMHz(){ return getCpuFrequencyMhz(); }
inline uint32_t getCycleCount() __attribute__((always_inline));
const char * getSdkVersion();
void deepSleep(uint32_t time_us);
@ -101,6 +101,13 @@ public:
};
uint32_t IRAM_ATTR EspClass::getCycleCount()
{
uint32_t ccount;
__asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount));
return ccount;
}
extern EspClass ESP;
#endif //ESP_H

View File

@ -55,6 +55,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert);
if(!baud) {
uartStartDetectBaudrate(_uart);
time_t startMillis = millis();
unsigned long detectedBaudRate = 0;
while(millis() - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) {

View File

@ -52,19 +52,24 @@ size_t Print::printf(const char *format, ...)
va_list copy;
va_start(arg, format);
va_copy(copy, arg);
size_t len = vsnprintf(NULL, 0, format, arg);
int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
va_end(copy);
if(len < 0) {
va_end(arg);
return 0;
};
if(len >= sizeof(loc_buf)){
temp = new char[len+1];
temp = (char*) malloc(len+1);
if(temp == NULL) {
va_end(arg);
return 0;
}
len = vsnprintf(temp, len+1, format, arg);
}
len = vsnprintf(temp, len+1, format, arg);
write((uint8_t*)temp, len);
va_end(arg);
if(len >= sizeof(loc_buf)){
delete[] temp;
len = write((uint8_t*)temp, len);
if(temp != loc_buf){
free(temp);
}
return len;
}
@ -154,8 +159,10 @@ size_t Print::print(struct tm * timeinfo, const char * format)
}
char buf[64];
size_t written = strftime(buf, 64, f, timeinfo);
print(buf);
return written;
if(written == 0){
return written;
}
return print(buf);
}
size_t Print::println(void)

View File

@ -97,8 +97,8 @@ public:
float parseFloat(); // float version of parseInt
size_t readBytes(char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes(uint8_t *buffer, size_t length)
virtual size_t readBytes(char *buffer, size_t length); // read chars from stream into buffer
virtual size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *) buffer, length);
}
@ -114,7 +114,7 @@ public:
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
String readString();
virtual String readString();
String readStringUntil(char terminator);
protected:

View File

@ -2,6 +2,7 @@
StreamString.cpp
Copyright (c) 2015 Markus Sattler. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -22,31 +23,28 @@
#include <Arduino.h>
#include "StreamString.h"
size_t StreamString::write(const uint8_t *data, size_t size)
{
size_t StreamString::write(const uint8_t *data, size_t size) {
if(size && data) {
if(reserve(length() + size + 1)) {
memcpy((void *) (buffer + len), (const void *) data, size);
len += size;
*(buffer + len) = 0x00; // add null for string end
const unsigned int newlen = length() + size;
if(reserve(newlen + 1)) {
memcpy((void *) (wbuffer() + len()), (const void *) data, size);
setLen(newlen);
*(wbuffer() + newlen) = 0x00; // add null for string end
return size;
}
}
return 0;
}
size_t StreamString::write(uint8_t data)
{
size_t StreamString::write(uint8_t data) {
return concat((char) data);
}
int StreamString::available()
{
int StreamString::available() {
return length();
}
int StreamString::read()
{
int StreamString::read() {
if(length()) {
char c = charAt(0);
remove(0, 1);
@ -56,8 +54,7 @@ int StreamString::read()
return -1;
}
int StreamString::peek()
{
int StreamString::peek() {
if(length()) {
char c = charAt(0);
return c;
@ -65,7 +62,6 @@ int StreamString::peek()
return -1;
}
void StreamString::flush()
{
void StreamString::flush() {
}

View File

@ -65,9 +65,12 @@ long random(long howsmall, long howbig)
return random(diff) + howsmall;
}
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
long map(long x, long in_min, long in_max, long out_min, long out_max) {
long divisor = (in_max - in_min);
if(divisor == 0){
return -1; //AVR returns -1, SAM returns 0
}
return (x - in_min) * (out_max - out_min) / divisor + out_min;
}
unsigned int makeWord(unsigned int w)

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
#include <string.h>
#include <ctype.h>
#include <pgmspace.h>
#include <stdint.h>
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
@ -35,295 +36,300 @@ class StringSumHelper;
// an abstract class used as a means to proide a unique pointer type
// but really has no body
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))
// The string class
class String
{
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const
{
}
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str) : String(reinterpret_cast<const char *>(str)) {};
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base = 10);
explicit String(int, unsigned char base = 10);
explicit String(unsigned int, unsigned char base = 10);
explicit String(long, unsigned char base = 10);
explicit String(unsigned long, unsigned char base = 10);
explicit String(float, unsigned char decimalPlaces = 2);
explicit String(double, unsigned char decimalPlaces = 2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const
{
if(buffer) {
return len;
} else {
return 0;
class String {
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {
}
}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator =(const String &rhs);
String & operator =(const char *cstr);
String & operator = (const __FlashStringHelper *str);
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const String &str);
String(const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator =(String &&rval);
String & operator =(StringSumHelper &&rval);
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base = 10);
explicit String(int, unsigned char base = 10);
explicit String(unsigned int, unsigned char base = 10);
explicit String(long, unsigned char base = 10);
explicit String(unsigned long, unsigned char base = 10);
explicit String(float, unsigned char decimalPlaces = 2);
explicit String(double, unsigned char decimalPlaces = 2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {
if(buffer()) {
return len();
} else {
return 0;
}
}
inline void clear(void) {
setLen(0);
}
inline bool isEmpty(void) const {
return length() == 0;
}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator =(const String &rhs);
String & operator =(const char *cstr);
String & operator = (const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator =(String &&rval);
String & operator =(StringSumHelper &&rval);
#endif
// concatenate (works w/ built-in types)
// concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsucessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsuccessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator +=(const String &rhs)
{
concat(rhs);
return (*this);
}
String & operator +=(const char *cstr)
{
concat(cstr);
return (*this);
}
String & operator +=(char c)
{
concat(c);
return (*this);
}
String & operator +=(unsigned char num)
{
concat(num);
return (*this);
}
String & operator +=(int num)
{
concat(num);
return (*this);
}
String & operator +=(unsigned int num)
{
concat(num);
return (*this);
}
String & operator +=(long num)
{
concat(num);
return (*this);
}
String & operator +=(unsigned long num)
{
concat(num);
return (*this);
}
String & operator +=(float num)
{
concat(num);
return (*this);
}
String & operator +=(double num)
{
concat(num);
return (*this);
}
String & operator += (const __FlashStringHelper *str)
{
concat(str);
return (*this);
}
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator +=(const String &rhs) {
concat(rhs);
return (*this);
}
String & operator +=(const char *cstr) {
concat(cstr);
return (*this);
}
String & operator +=(char c) {
concat(c);
return (*this);
}
String & operator +=(unsigned char num) {
concat(num);
return (*this);
}
String & operator +=(int num) {
concat(num);
return (*this);
}
String & operator +=(unsigned int num) {
concat(num);
return (*this);
}
String & operator +=(long num) {
concat(num);
return (*this);
}
String & operator +=(unsigned long num) {
concat(num);
return (*this);
}
String & operator +=(float num) {
concat(num);
return (*this);
}
String & operator +=(double num) {
concat(num);
return (*this);
}
String & operator += (const __FlashStringHelper *str){
concat(str);
return (*this);
}
friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator +(const StringSumHelper &lhs, char c);
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, int num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, long num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator +(const StringSumHelper &lhs, char c);
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, int num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, long num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const
{
return buffer ? &String::StringIfHelper : 0;
}
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator ==(const String &rhs) const
{
return equals(rhs);
}
unsigned char operator ==(const char *cstr) const
{
return equals(cstr);
}
unsigned char operator !=(const String &rhs) const
{
return !equals(rhs);
}
unsigned char operator !=(const char *cstr) const
{
return !equals(cstr);
}
unsigned char operator <(const String &rhs) const;
unsigned char operator >(const String &rhs) const;
unsigned char operator <=(const String &rhs) const;
unsigned char operator >=(const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char equalsConstantTime(const String &s) const;
unsigned char startsWith(const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const {
return buffer() ? &String::StringIfHelper : 0;
}
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char operator ==(const String &rhs) const {
return equals(rhs);
}
unsigned char operator ==(const char *cstr) const {
return equals(cstr);
}
unsigned char operator !=(const String &rhs) const {
return !equals(rhs);
}
unsigned char operator !=(const char *cstr) const {
return !equals(cstr);
}
unsigned char operator <(const String &rhs) const;
unsigned char operator >(const String &rhs) const;
unsigned char operator <=(const String &rhs) const;
unsigned char operator >=(const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char equalsConstantTime(const String &s) const;
unsigned char startsWith(const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [](unsigned int index) const;
char& operator [](unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const
{
getBytes((unsigned char *) buf, bufsize, index);
}
const char * c_str() const
{
return buffer;
}
// character access
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [](unsigned int index) const;
char& operator [](unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
getBytes((unsigned char *) buf, bufsize, index);
}
const char* c_str() const { return buffer(); }
char* begin() { return wbuffer(); }
char* end() { return wbuffer() + length(); }
const char* begin() const { return c_str(); }
const char* end() const { return c_str() + length(); }
// search
int indexOf(char ch) const;
int indexOf(char ch, unsigned int fromIndex) const;
int indexOf(const String &str) const;
int indexOf(const String &str, unsigned int fromIndex) const;
int lastIndexOf(char ch) const;
int lastIndexOf(char ch, unsigned int fromIndex) const;
int lastIndexOf(const String &str) const;
int lastIndexOf(const String &str, unsigned int fromIndex) const;
String substring(unsigned int beginIndex) const
{
return substring(beginIndex, len);
}
;
String substring(unsigned int beginIndex, unsigned int endIndex) const;
// search
int indexOf(char ch) const;
int indexOf(char ch, unsigned int fromIndex) const;
int indexOf(const String &str) const;
int indexOf(const String &str, unsigned int fromIndex) const;
int lastIndexOf(char ch) const;
int lastIndexOf(char ch, unsigned int fromIndex) const;
int lastIndexOf(const String &str) const;
int lastIndexOf(const String &str, unsigned int fromIndex) const;
String substring(unsigned int beginIndex) const {
return substring(beginIndex, len());
}
;
String substring(unsigned int beginIndex, unsigned int endIndex) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
double toDouble(void) const;
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
double toDouble(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
protected:
// Contains the string info when we're not in SSO mode
struct _ptr {
char * buff;
uint16_t cap;
uint16_t len;
};
// This allows strings up up to 11 (10 + \0 termination) without any extra space.
enum { SSOSIZE = sizeof(struct _ptr) + 4 - 1 }; // Characters to allocate space for SSO, must be 12 or more
struct _sso {
char buff[SSOSIZE];
unsigned char len : 7; // Ensure only one byte is allocated by GCC for the bitfields
unsigned char isSSO : 1;
} __attribute__((packed)); // Ensure that GCC doesn't expand the flag byte to a 32-bit word for alignment issues
enum { CAPACITY_MAX = 65535 }; // If typeof(cap) changed from uint16_t, be sure to update this enum to the max value storable in the type
union {
struct _ptr ptr;
struct _sso sso;
};
// Accessor functions
inline bool isSSO() const { return sso.isSSO; }
inline unsigned int len() const { return isSSO() ? sso.len : ptr.len; }
inline unsigned int capacity() const { return isSSO() ? (unsigned int)SSOSIZE - 1 : ptr.cap; } // Size of max string not including terminal NUL
inline void setSSO(bool set) { sso.isSSO = set; }
inline void setLen(int len) { if (isSSO()) sso.len = len; else ptr.len = len; }
inline void setCapacity(int cap) { if (!isSSO()) ptr.cap = cap; }
inline void setBuffer(char *buff) { if (!isSSO()) ptr.buff = buff; }
// Buffer accessor functions
inline const char *buffer() const { return (const char *)(isSSO() ? sso.buff : ptr.buff); }
inline char *wbuffer() const { return isSSO() ? const_cast<char *>(sso.buff) : ptr.buff; } // Writable version of buffer
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void move(String &rhs);
void move(String &rhs);
#endif
};
class StringSumHelper: public String
{
public:
StringSumHelper(const String &s) :
String(s)
{
}
StringSumHelper(const char *p) :
String(p)
{
}
StringSumHelper(char c) :
String(c)
{
}
StringSumHelper(unsigned char num) :
String(num)
{
}
StringSumHelper(int num) :
String(num)
{
}
StringSumHelper(unsigned int num) :
String(num)
{
}
StringSumHelper(long num) :
String(num)
{
}
StringSumHelper(unsigned long num) :
String(num)
{
}
StringSumHelper(float num) :
String(num)
{
}
StringSumHelper(double num) :
String(num)
{
}
class StringSumHelper: public String {
public:
StringSumHelper(const String &s) :
String(s) {
}
StringSumHelper(const char *p) :
String(p) {
}
StringSumHelper(char c) :
String(c) {
}
StringSumHelper(unsigned char num) :
String(num) {
}
StringSumHelper(int num) :
String(num) {
}
StringSumHelper(unsigned int num) :
String(num) {
}
StringSumHelper(long num) :
String(num) {
}
StringSumHelper(unsigned long num) :
String(num) {
}
StringSumHelper(float num) :
String(num) {
}
StringSumHelper(double num) :
String(num) {
}
};
extern const String emptyString;
#endif // __cplusplus
#endif // String_class_h

View File

@ -23,6 +23,7 @@
#include "soc/rtc_cntl_reg.h"
#include "rom/rtc.h"
#include "soc/apb_ctrl_reg.h"
#include "soc/efuse_reg.h"
#include "esp32-hal.h"
#include "esp32-hal-cpu.h"
@ -150,6 +151,15 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
}
return false;
}
//check if cpu supports the frequency
if(cpu_freq_mhz == 240){
//Check if ESP32 is rated for a CPU frequency of 160MHz only
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
log_e("Can not switch to 240 MHz! Chip CPU frequency rated for 160MHz.");
cpu_freq_mhz = 160;
}
}
//Get current CPU clock configuration
rtc_clk_cpu_freq_get_config(&cconf);
//return if frequency has not changed

View File

@ -1270,7 +1270,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
i2c->dev->ctr.trans_start=1; // go for it
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
portTickType tBefore=xTaskGetTickCount();
#endif
@ -1278,7 +1278,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut);
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
portTickType tAfter=xTaskGetTickCount();
#endif

View File

@ -111,6 +111,24 @@ void disableCore1WDT(){
}
#endif
BaseType_t xTaskCreateUniversal( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask,
const BaseType_t xCoreID ){
#ifndef CONFIG_FREERTOS_UNICORE
if(xCoreID >= 0 && xCoreID < 2) {
return xTaskCreatePinnedToCore(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID);
} else {
#endif
return xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask);
#ifndef CONFIG_FREERTOS_UNICORE
}
#endif
}
unsigned long IRAM_ATTR micros()
{
return (unsigned long) (esp_timer_get_time());

View File

@ -665,7 +665,6 @@ static void IRAM_ATTR _rmt_isr(void* arg)
}
if (intr_val & _INT_ERROR(ch)) {
digitalWrite(2, 1);
// clear the flag
RMT.int_clr.val = _INT_ERROR(ch);
RMT.int_ena.val &= ~_INT_ERROR(ch);

View File

@ -165,6 +165,7 @@ void timerStop(hw_timer_t *timer){
void timerRestart(hw_timer_t *timer){
timer->dev->config.enable = 0;
timer->dev->reload = 1;
timer->dev->config.enable = 1;
}

View File

@ -343,6 +343,8 @@ void uartFlush(uart_t* uart)
READ_PERI_REG(UART_FIFO_REG(uart->num));
}
xQueueReset(uart->queue);
UART_MUTEX_UNLOCK();
}
@ -399,7 +401,12 @@ uint32_t uartGetBaudRate(uart_t* uart)
if(uart == NULL) {
return 0;
}
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
if(!clk_div) {
return 0;
}
return ((getApbFrequency()<<4)/clk_div);
}
@ -520,6 +527,14 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
* detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is
* rounded to the closed real baudrate.
*/
void uartStartDetectBaudrate(uart_t *uart) {
if(!uart) return;
uart->dev->auto_baud.glitch_filt = 0x08;
uart->dev->auto_baud.en = 0;
uart->dev->auto_baud.en = 1;
}
unsigned long
uartDetectBaudrate(uart_t *uart)
{

View File

@ -72,6 +72,7 @@ size_t uartResizeRxBuffer(uart_t* uart, size_t new_size);
void uartSetDebug(uart_t* uart);
int uartGetDebug();
void uartStartDetectBaudrate(uart_t *uart);
unsigned long uartDetectBaudrate(uart_t *uart);
bool uartRxActive(uart_t* uart);

View File

@ -90,6 +90,16 @@ void enableCore1WDT();
void disableCore1WDT();
#endif
//if xCoreID < 0 or CPU is unicore, it will use xTaskCreate, else xTaskCreatePinnedToCore
//allows to easily handle all possible situations without repetitive code
BaseType_t xTaskCreateUniversal( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask,
const BaseType_t xCoreID );
unsigned long micros();
unsigned long millis();
void delay(uint32_t);

View File

@ -7,12 +7,6 @@ TaskHandle_t loopTaskHandle = NULL;
#if CONFIG_AUTOSTART_ARDUINO
#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif
bool loopTaskWDTEnabled;
void loopTask(void *pvParameters)
@ -30,7 +24,7 @@ extern "C" void app_main()
{
loopTaskWDTEnabled = false;
initArduino();
xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
}
#endif

View File

@ -32,7 +32,6 @@ typedef unsigned long prog_uint32_t;
#define PROGMEM
#define PGM_P const char *
#define PGM_VOID_P const void *
#define FPSTR(p) ((const char *)(p))
#define PSTR(s) (s)
#define _SFR_BYTE(n) (n)

View File

@ -23,5 +23,7 @@ Installation instructions for Mac OS
- Try `python3` instead of `python` if you get the error: `IOError: [Errno socket error] [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590)` when running `python get.py`
- If you get the following error when running `python get.py` urllib.error.URLError: <urlopen error SSL: CERTIFICATE_VERIFY_FAILED, go to Macintosh HD > Applications > Python3.6 folder (or any other python version), and run the following scripts: Install Certificates.command and Update Shell Profile.command
- Restart Arduino IDE

View File

@ -1,11 +1,11 @@
Installation instructions for using PlatformIO
=================================================
- [What is PlatformIO?](http://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp32)
- [PlatformIO IDE](http://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp32)
- [PlatformIO Core](http://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp32) (command line tool)
- [Advanced usage](http://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32) -
- [What is PlatformIO?](https://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp32)
- [PlatformIO IDE](https://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp32)
- [PlatformIO Core](https://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp32) (command line tool)
- [Advanced usage](https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32) -
custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version
- [Integration with Cloud and Standalone IDEs](http://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp32) -
- [Integration with Cloud and Standalone IDEs](https://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp32) -
Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode
- [Project Examples](http://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32#examples)
- [Project Examples](https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32#examples)

View File

@ -127,9 +127,7 @@ void ArduinoOTAClass::begin() {
}
_initialized = true;
_state = OTA_IDLE;
#ifdef OTA_DEBUG
OTA_DEBUG.printf("OTA server at: %s.local:%u\n", _hostname.c_str(), _port);
#endif
log_i("OTA server at: %s.local:%u", _hostname.c_str(), _port);
}
int ArduinoOTAClass::parseInt(){
@ -173,6 +171,7 @@ void ArduinoOTAClass::_onRx(){
_md5 = readStringUntil('\n');
_md5.trim();
if(_md5.length() != 32){
log_e("bad md5 length");
return;
}
@ -198,6 +197,7 @@ void ArduinoOTAClass::_onRx(){
} else if (_state == OTA_WAITAUTH) {
int cmd = parseInt();
if (cmd != U_AUTH) {
log_e("%d was expected. got %d instead", U_AUTH, cmd);
_state = OTA_IDLE;
return;
}
@ -205,6 +205,7 @@ void ArduinoOTAClass::_onRx(){
String cnonce = readStringUntil(' ');
String response = readStringUntil('\n');
if (cnonce.length() != 32 || response.length() != 32) {
log_e("auth param fail");
_state = OTA_IDLE;
return;
}
@ -225,6 +226,7 @@ void ArduinoOTAClass::_onRx(){
} else {
_udp_ota.beginPacket(_udp_ota.remoteIP(), _udp_ota.remotePort());
_udp_ota.print("Authentication Failed");
log_w("Authentication Failed");
_udp_ota.endPacket();
if (_error_callback) _error_callback(OTA_AUTH_ERROR);
_state = OTA_IDLE;
@ -234,9 +236,9 @@ void ArduinoOTAClass::_onRx(){
void ArduinoOTAClass::_runUpdate() {
if (!Update.begin(_size, _cmd)) {
#ifdef OTA_DEBUG
Update.printError(OTA_DEBUG);
#endif
log_e("Begin ERROR: %s", Update.errorString());
if (_error_callback) {
_error_callback(OTA_BEGIN_ERROR);
}
@ -272,21 +274,15 @@ void ArduinoOTAClass::_runUpdate() {
}
if (!waited){
if(written && tried++ < 3){
#ifdef OTA_DEBUG
OTA_DEBUG.printf("Try[%u]: %u\n", tried, written);
#endif
log_i("Try[%u]: %u", tried, written);
if(!client.printf("%u", written)){
#ifdef OTA_DEBUG
OTA_DEBUG.printf("failed to respond\n");
#endif
log_e("failed to respond");
_state = OTA_IDLE;
break;
}
continue;
}
#ifdef OTA_DEBUG
OTA_DEBUG.printf("Receive Failed\n");
#endif
log_e("Receive Failed");
if (_error_callback) {
_error_callback(OTA_RECEIVE_ERROR);
}
@ -295,9 +291,7 @@ void ArduinoOTAClass::_runUpdate() {
return;
}
if(!available){
#ifdef OTA_DEBUG
OTA_DEBUG.printf("No Data: %u\n", waited);
#endif
log_e("No Data: %u", waited);
_state = OTA_IDLE;
break;
}
@ -317,18 +311,14 @@ void ArduinoOTAClass::_runUpdate() {
log_w("didn't write enough! %u != %u", written, r);
}
if(!client.printf("%u", written)){
#ifdef OTA_DEBUG
OTA_DEBUG.printf("failed to respond\n");
#endif
log_w("failed to respond");
}
total += written;
if(_progress_callback) {
_progress_callback(total, _size);
}
} else {
#ifdef OTA_DEBUG
Update.printError(OTA_DEBUG);
#endif
log_e("Write ERROR: %s", Update.errorString());
}
}
@ -351,10 +341,7 @@ void ArduinoOTAClass::_runUpdate() {
Update.printError(client);
client.stop();
delay(10);
#ifdef OTA_DEBUG
OTA_DEBUG.print("Update ERROR: ");
Update.printError(OTA_DEBUG);
#endif
log_e("Update ERROR: %s", Update.errorString());
_state = OTA_IDLE;
}
}
@ -366,9 +353,7 @@ void ArduinoOTAClass::end() {
MDNS.end();
}
_state = OTA_IDLE;
#ifdef OTA_DEBUG
OTA_DEBUG.println("OTA server stopped.");
#endif
log_i("OTA server stopped.");
}
void ArduinoOTAClass::handle() {
@ -395,4 +380,4 @@ void ArduinoOTAClass::setTimeout(int timeoutInMillis) {
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA)
ArduinoOTAClass ArduinoOTA;
#endif
#endif

View File

@ -1,17 +0,0 @@
{
"name":"AsyncUDP",
"description":"Asynchronous UDP Library for ESP32",
"keywords":"async,udp,server,client,multicast,broadcast",
"authors":
{
"name": "Hristo Gochkov",
"maintainer": true
},
"repository":
{
"type": "git",
"url": "https://github.com/me-no-dev/ESPAsyncUDP.git"
},
"frameworks": "arduino",
"platforms":"espressif"
}

View File

@ -150,7 +150,7 @@ static bool _udp_task_start(){
}
}
if(!_udp_task_handle){
xTaskCreate(_udp_task, "async_udp", 4096, NULL, 3, (TaskHandle_t*)&_udp_task_handle);
xTaskCreateUniversal(_udp_task, "async_udp", 4096, NULL, 3, (TaskHandle_t*)&_udp_task_handle, CONFIG_ARDUINO_UDP_RUNNING_CORE);
if(!_udp_task_handle){
return false;
}
@ -682,8 +682,9 @@ void AsyncUDP::_recv(udp_pcb *upcb, pbuf *pb, const ip_addr_t *addr, uint16_t po
if(_handler) {
AsyncUDPPacket packet(this, this_pb, addr, port, netif);
_handler(packet);
} else {
pbuf_free(this_pb);
}
pbuf_free(this_pb);
}
}

View File

@ -87,6 +87,7 @@ bool connectToServer() {
pRemoteCharacteristic->registerForNotify(notifyCallback);
connected = true;
return true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.

View File

@ -13,6 +13,7 @@
#include <iomanip>
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#ifdef ARDUINO_ARCH_ESP32
#include "esp32-hal-log.h"
#endif
@ -83,13 +84,11 @@ esp_bd_addr_t *BLEAddress::getNative() {
* @return The string representation of the address.
*/
std::string BLEAddress::toString() {
std::stringstream stream;
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[0] << ':';
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[1] << ':';
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[2] << ':';
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[3] << ':';
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[4] << ':';
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[5];
return stream.str();
auto size = 18;
char *res = (char*)malloc(size);
snprintf(res, size, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[0], m_address[1], m_address[2], m_address[3], m_address[4], m_address[5]);
std::string ret(res);
free(res);
return ret;
} // toString
#endif

View File

@ -16,13 +16,7 @@
#include <sstream>
#include "BLEAdvertisedDevice.h"
#include "BLEUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG="BLEAdvertisedDevice";
#endif
BLEAdvertisedDevice::BLEAdvertisedDevice() {
m_adFlag = 0;
@ -249,7 +243,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
length--;
char* pHex = BLEUtils::buildHexData(nullptr, payload, length);
ESP_LOGD(LOG_TAG, "Type: 0x%.2x (%s), length: %d, data: %s",
log_d("Type: 0x%.2x (%s), length: %d, data: %s",
ad_type, BLEUtils::advTypeToString(ad_type), length, pHex);
free(pHex);
@ -308,7 +302,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
case ESP_BLE_AD_TYPE_SERVICE_DATA: { // Adv Data Type: 0x16 (Service Data) - 2 byte UUID
if (length < 2) {
ESP_LOGE(LOG_TAG, "Length too small for ESP_BLE_AD_TYPE_SERVICE_DATA");
log_e("Length too small for ESP_BLE_AD_TYPE_SERVICE_DATA");
break;
}
uint16_t uuid = *(uint16_t*)payload;
@ -321,7 +315,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
case ESP_BLE_AD_TYPE_32SERVICE_DATA: { // Adv Data Type: 0x20 (Service Data) - 4 byte UUID
if (length < 4) {
ESP_LOGE(LOG_TAG, "Length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA");
log_e("Length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA");
break;
}
uint32_t uuid = *(uint32_t*) payload;
@ -334,7 +328,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
case ESP_BLE_AD_TYPE_128SERVICE_DATA: { // Adv Data Type: 0x21 (Service Data) - 16 byte UUID
if (length < 16) {
ESP_LOGE(LOG_TAG, "Length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA");
log_e("Length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA");
break;
}
@ -346,7 +340,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
} //ESP_BLE_AD_TYPE_32SERVICE_DATA
default: {
ESP_LOGD(LOG_TAG, "Unhandled type: adType: %d - 0x%.2x", ad_type, ad_type);
log_d("Unhandled type: adType: %d - 0x%.2x", ad_type, ad_type);
break;
}
} // switch
@ -386,7 +380,7 @@ void BLEAdvertisedDevice::setAdFlag(uint8_t adFlag) {
void BLEAdvertisedDevice::setAppearance(uint16_t appearance) {
m_appearance = appearance;
m_haveAppearance = true;
ESP_LOGD(LOG_TAG, "- appearance: %d", m_appearance);
log_d("- appearance: %d", m_appearance);
} // setAppearance
@ -398,7 +392,7 @@ void BLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) {
m_manufacturerData = manufacturerData;
m_haveManufacturerData = true;
char* pHex = BLEUtils::buildHexData(nullptr, (uint8_t*) m_manufacturerData.data(), (uint8_t) m_manufacturerData.length());
ESP_LOGD(LOG_TAG, "- manufacturer data: %s", pHex);
log_d("- manufacturer data: %s", pHex);
free(pHex);
} // setManufacturerData
@ -410,7 +404,7 @@ void BLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) {
void BLEAdvertisedDevice::setName(std::string name) {
m_name = name;
m_haveName = true;
ESP_LOGD(LOG_TAG, "- setName(): name: %s", m_name.c_str());
log_d("- setName(): name: %s", m_name.c_str());
} // setName
@ -421,7 +415,7 @@ void BLEAdvertisedDevice::setName(std::string name) {
void BLEAdvertisedDevice::setRSSI(int rssi) {
m_rssi = rssi;
m_haveRSSI = true;
ESP_LOGD(LOG_TAG, "- setRSSI(): rssi: %d", m_rssi);
log_d("- setRSSI(): rssi: %d", m_rssi);
} // setRSSI
@ -450,7 +444,7 @@ void BLEAdvertisedDevice::setServiceUUID(const char* serviceUUID) {
void BLEAdvertisedDevice::setServiceUUID(BLEUUID serviceUUID) {
m_serviceUUIDs.push_back(serviceUUID);
m_haveServiceUUID = true;
ESP_LOGD(LOG_TAG, "- addServiceUUID(): serviceUUID: %s", serviceUUID.toString().c_str());
log_d("- addServiceUUID(): serviceUUID: %s", serviceUUID.toString().c_str());
} // setServiceUUID
@ -481,7 +475,7 @@ void BLEAdvertisedDevice::setServiceDataUUID(BLEUUID uuid) {
void BLEAdvertisedDevice::setTXPower(int8_t txPower) {
m_txPower = txPower;
m_haveTXPower = true;
ESP_LOGD(LOG_TAG, "- txPower: %d", m_txPower);
log_d("- txPower: %d", m_txPower);
} // setTXPower
@ -490,23 +484,29 @@ void BLEAdvertisedDevice::setTXPower(int8_t txPower) {
* @return A string representation of this device.
*/
std::string BLEAdvertisedDevice::toString() {
std::stringstream ss;
ss << "Name: " << getName() << ", Address: " << getAddress().toString();
std::string res = "Name: " + getName() + ", Address: " + getAddress().toString();
if (haveAppearance()) {
ss << ", appearance: " << getAppearance();
char val[6];
snprintf(val, sizeof(val), "%d", getAppearance());
res += ", appearance: ";
res += val;
}
if (haveManufacturerData()) {
char *pHex = BLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().data(), getManufacturerData().length());
ss << ", manufacturer data: " << pHex;
res += ", manufacturer data: ";
res += pHex;
free(pHex);
}
if (haveServiceUUID()) {
ss << ", serviceUUID: " << getServiceUUID().toString();
res += ", serviceUUID: " + getServiceUUID().toString();
}
if (haveTXPower()) {
ss << ", txPower: " << (int)getTXPower();
char val[4];
snprintf(val, sizeof(val), "%d", getTXPower());
res += ", txPower: ";
res += val;
}
return ss.str();
return res;
} // toString
uint8_t* BLEAdvertisedDevice::getPayload() {

View File

@ -22,16 +22,7 @@
#include <esp_err.h>
#include "BLEUtils.h"
#include "GeneralUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEAdvertising";
#endif
/**
* @brief Construct a default advertising object.
@ -120,25 +111,25 @@ void BLEAdvertising::setScanResponse(bool set) {
* @param [in] connectWhitelistOnly If true, only allow connections from those on the white list.
*/
void BLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connectWhitelistOnly) {
ESP_LOGD(LOG_TAG, ">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly);
log_v(">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly);
if (!scanRequestWhitelistOnly && !connectWhitelistOnly) {
m_advParams.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY;
ESP_LOGD(LOG_TAG, "<< setScanFilter");
log_v("<< setScanFilter");
return;
}
if (scanRequestWhitelistOnly && !connectWhitelistOnly) {
m_advParams.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY;
ESP_LOGD(LOG_TAG, "<< setScanFilter");
log_v("<< setScanFilter");
return;
}
if (!scanRequestWhitelistOnly && connectWhitelistOnly) {
m_advParams.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST;
ESP_LOGD(LOG_TAG, "<< setScanFilter");
log_v("<< setScanFilter");
return;
}
if (scanRequestWhitelistOnly && connectWhitelistOnly) {
m_advParams.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST;
ESP_LOGD(LOG_TAG, "<< setScanFilter");
log_v("<< setScanFilter");
return;
}
} // setScanFilter
@ -149,15 +140,15 @@ void BLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connectWh
* @param [in] advertisementData The data to be advertised.
*/
void BLEAdvertising::setAdvertisementData(BLEAdvertisementData& advertisementData) {
ESP_LOGD(LOG_TAG, ">> setAdvertisementData");
log_v(">> setAdvertisementData");
esp_err_t errRc = ::esp_ble_gap_config_adv_data_raw(
(uint8_t*)advertisementData.getPayload().data(),
advertisementData.getPayload().length());
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_config_adv_data_raw: %d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_config_adv_data_raw: %d %s", errRc, GeneralUtils::errorToString(errRc));
}
m_customAdvData = true; // Set the flag that indicates we are using custom advertising data.
ESP_LOGD(LOG_TAG, "<< setAdvertisementData");
log_v("<< setAdvertisementData");
} // setAdvertisementData
@ -166,15 +157,15 @@ void BLEAdvertising::setAdvertisementData(BLEAdvertisementData& advertisementDat
* @param [in] advertisementData The data to be advertised.
*/
void BLEAdvertising::setScanResponseData(BLEAdvertisementData& advertisementData) {
ESP_LOGD(LOG_TAG, ">> setScanResponseData");
log_v(">> setScanResponseData");
esp_err_t errRc = ::esp_ble_gap_config_scan_rsp_data_raw(
(uint8_t*)advertisementData.getPayload().data(),
advertisementData.getPayload().length());
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_config_scan_rsp_data_raw: %d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_config_scan_rsp_data_raw: %d %s", errRc, GeneralUtils::errorToString(errRc));
}
m_customScanResponseData = true; // Set the flag that indicates we are using custom scan response data.
ESP_LOGD(LOG_TAG, "<< setScanResponseData");
log_v("<< setScanResponseData");
} // setScanResponseData
/**
@ -183,7 +174,7 @@ void BLEAdvertising::setScanResponseData(BLEAdvertisementData& advertisementData
* @return N/A.
*/
void BLEAdvertising::start() {
ESP_LOGD(LOG_TAG, ">> start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData);
log_v(">> start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData);
// We have a vector of service UUIDs that we wish to advertise. In order to use the
// ESP-IDF framework, these must be supplied in a contiguous array of their 128bit (16 byte)
@ -195,14 +186,14 @@ void BLEAdvertising::start() {
m_advData.p_service_uuid = new uint8_t[m_advData.service_uuid_len];
uint8_t* p = m_advData.p_service_uuid;
for (int i = 0; i < numServices; i++) {
ESP_LOGD(LOG_TAG, "- advertising service: %s", m_serviceUUIDs[i].toString().c_str());
log_d("- advertising service: %s", m_serviceUUIDs[i].toString().c_str());
BLEUUID serviceUUID128 = m_serviceUUIDs[i].to128();
memcpy(p, serviceUUID128.getNative()->uuid.uuid128, 16);
p += 16;
}
} else {
m_advData.service_uuid_len = 0;
ESP_LOGD(LOG_TAG, "- no services advertised");
log_d("- no services advertised");
}
esp_err_t errRc;
@ -214,7 +205,7 @@ void BLEAdvertising::start() {
m_advData.include_txpower = !m_scanResp;
errRc = ::esp_ble_gap_config_adv_data(&m_advData);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gap_config_adv_data: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gap_config_adv_data: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
}
@ -225,7 +216,7 @@ void BLEAdvertising::start() {
m_advData.include_txpower = m_scanResp;
errRc = ::esp_ble_gap_config_adv_data(&m_advData);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gap_config_adv_data (Scan response): rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gap_config_adv_data (Scan response): rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
}
@ -240,10 +231,10 @@ void BLEAdvertising::start() {
// Start advertising.
errRc = ::esp_ble_gap_start_advertising(&m_advParams);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gap_start_advertising: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gap_start_advertising: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
ESP_LOGD(LOG_TAG, "<< start");
log_v("<< start");
} // start
@ -253,15 +244,36 @@ void BLEAdvertising::start() {
* @return N/A.
*/
void BLEAdvertising::stop() {
ESP_LOGD(LOG_TAG, ">> stop");
log_v(">> stop");
esp_err_t errRc = ::esp_ble_gap_stop_advertising();
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_stop_advertising: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_stop_advertising: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
ESP_LOGD(LOG_TAG, "<< stop");
log_v("<< stop");
} // stop
/**
* @brief Set BLE address.
* @param [in] Bluetooth address.
* @param [in] Bluetooth address type.
* Set BLE address.
*/
void BLEAdvertising::setDeviceAddress(esp_bd_addr_t addr, esp_ble_addr_type_t type)
{
log_v(">> setPrivateAddress");
m_advParams.own_addr_type = type;
esp_err_t errRc = esp_ble_gap_set_rand_addr((uint8_t*)addr);
if (errRc != ESP_OK)
{
log_e("esp_ble_gap_set_rand_addr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
log_v("<< setPrivateAddress");
} // setPrivateAddress
/**
* @brief Add data to the payload to be advertised.
* @param [in] data The data to be added to the payload.
@ -352,12 +364,12 @@ void BLEAdvertisementData::setFlags(uint8_t flag) {
* @param [in] data Manufacturer data.
*/
void BLEAdvertisementData::setManufacturerData(std::string data) {
ESP_LOGD("BLEAdvertisementData", ">> setManufacturerData");
log_d("BLEAdvertisementData", ">> setManufacturerData");
char cdata[2];
cdata[0] = data.length() + 1;
cdata[1] = ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE; // 0xff
addData(std::string(cdata, 2) + data);
ESP_LOGD("BLEAdvertisementData", "<< setManufacturerData");
log_d("BLEAdvertisementData", "<< setManufacturerData");
} // setManufacturerData
@ -366,12 +378,12 @@ void BLEAdvertisementData::setManufacturerData(std::string data) {
* @param [in] The complete name of the device.
*/
void BLEAdvertisementData::setName(std::string name) {
ESP_LOGD("BLEAdvertisementData", ">> setName: %s", name.c_str());
log_d("BLEAdvertisementData", ">> setName: %s", name.c_str());
char cdata[2];
cdata[0] = name.length() + 1;
cdata[1] = ESP_BLE_AD_TYPE_NAME_CMPL; // 0x09
addData(std::string(cdata, 2) + name);
ESP_LOGD("BLEAdvertisementData", "<< setName");
log_d("BLEAdvertisementData", "<< setName");
} // setName
@ -455,12 +467,12 @@ void BLEAdvertisementData::setServiceData(BLEUUID uuid, std::string data) {
* @param [in] The short name of the device.
*/
void BLEAdvertisementData::setShortName(std::string name) {
ESP_LOGD("BLEAdvertisementData", ">> setShortName: %s", name.c_str());
log_d("BLEAdvertisementData", ">> setShortName: %s", name.c_str());
char cdata[2];
cdata[0] = name.length() + 1;
cdata[1] = ESP_BLE_AD_TYPE_NAME_SHORT; // 0x08
addData(std::string(cdata, 2) + name);
ESP_LOGD("BLEAdvertisementData", "<< setShortName");
log_d("BLEAdvertisementData", "<< setShortName");
} // setShortName
@ -476,7 +488,7 @@ void BLEAdvertising::handleGAPEvent(
esp_gap_ble_cb_event_t event,
esp_ble_gap_cb_param_t* param) {
ESP_LOGD(LOG_TAG, "handleGAPEvent [event no: %d]", (int)event);
log_d("handleGAPEvent [event no: %d]", (int)event);
switch(event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: {
@ -492,8 +504,8 @@ void BLEAdvertising::handleGAPEvent(
break;
}
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: {
ESP_LOGI(LOG_TAG, "STOP advertising");
start();
log_i("STOP advertising");
//start();
break;
}
default:

View File

@ -58,6 +58,7 @@ public:
void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly);
void setScanResponseData(BLEAdvertisementData& advertisementData);
void setPrivateAddress(esp_ble_addr_type_t type = BLE_ADDR_TYPE_RANDOM);
void setDeviceAddress(esp_bd_addr_t addr, esp_ble_addr_type_t type = BLE_ADDR_TYPE_RANDOM);
void handleGAPEvent(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param);
void setMinPreferred(uint16_t);

View File

@ -8,13 +8,7 @@
#if defined(CONFIG_BT_ENABLED)
#include <string.h>
#include "BLEBeacon.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEBeacon";
#endif
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8))
@ -58,7 +52,7 @@ int8_t BLEBeacon::getSignalPower() {
*/
void BLEBeacon::setData(std::string data) {
if (data.length() != sizeof(m_beaconData)) {
ESP_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", data.length(), sizeof(m_beaconData));
log_e("Unable to set the data ... length passed in was %d and expected %d", data.length(), sizeof(m_beaconData));
return;
}
memcpy(&m_beaconData, data.data(), sizeof(m_beaconData));

View File

@ -18,16 +18,11 @@
#include "BLEUtils.h"
#include "BLE2902.h"
#include "GeneralUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLECharacteristic";
#endif
#define NULL_HANDLE (0xffff)
static BLECharacteristicCallbacks defaultCallback; //null-object-pattern
/**
* @brief Construct a characteristic
@ -46,7 +41,7 @@ BLECharacteristic::BLECharacteristic(BLEUUID uuid, uint32_t properties) {
m_bleUUID = uuid;
m_handle = NULL_HANDLE;
m_properties = (esp_gatt_char_prop_t)0;
m_pCallbacks = nullptr;
m_pCallbacks = &defaultCallback;
setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0);
setReadProperty((properties & PROPERTY_READ) != 0);
@ -70,9 +65,9 @@ BLECharacteristic::~BLECharacteristic() {
* @return N/A.
*/
void BLECharacteristic::addDescriptor(BLEDescriptor* pDescriptor) {
ESP_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str());
log_v(">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str());
m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor);
ESP_LOGD(LOG_TAG, "<< addDescriptor()");
log_v("<< addDescriptor()");
} // addDescriptor
@ -81,16 +76,16 @@ void BLECharacteristic::addDescriptor(BLEDescriptor* pDescriptor) {
* @param [in] pService The service with which to associate this characteristic.
*/
void BLECharacteristic::executeCreate(BLEService* pService) {
ESP_LOGD(LOG_TAG, ">> executeCreate()");
log_v(">> executeCreate()");
if (m_handle != NULL_HANDLE) {
ESP_LOGE(LOG_TAG, "Characteristic already has a handle.");
log_e("Characteristic already has a handle.");
return;
}
m_pService = pService; // Save the service to which this characteristic belongs.
ESP_LOGD(LOG_TAG, "Registering characteristic (esp_ble_gatts_add_char): uuid: %s, service: %s",
log_d("Registering characteristic (esp_ble_gatts_add_char): uuid: %s, service: %s",
getUUID().toString().c_str(),
m_pService->toString().c_str());
@ -107,7 +102,7 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
&control); // Whether to auto respond or not.
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_add_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gatts_add_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreCreateEvt.wait("executeCreate");
@ -118,7 +113,7 @@ void BLECharacteristic::executeCreate(BLEService* pService) {
pDescriptor = m_descriptorMap.getNext();
} // End while
ESP_LOGD(LOG_TAG, "<< executeCreate");
log_v("<< executeCreate");
} // executeCreate
@ -200,7 +195,7 @@ void BLECharacteristic::handleGATTServerEvent(
esp_gatts_cb_event_t event,
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t* param) {
ESP_LOGD(LOG_TAG, ">> handleGATTServerEvent: %s", BLEUtils::gattServerEventTypeToString(event).c_str());
log_v(">> handleGATTServerEvent: %s", BLEUtils::gattServerEventTypeToString(event).c_str());
switch(event) {
// Events handled:
@ -226,9 +221,7 @@ void BLECharacteristic::handleGATTServerEvent(
case ESP_GATTS_EXEC_WRITE_EVT: {
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
m_value.commit();
if (m_pCallbacks != nullptr) {
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
}
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
} else {
m_value.cancel();
}
@ -238,7 +231,7 @@ void BLECharacteristic::handleGATTServerEvent(
param->write.conn_id,
param->write.trans_id, ESP_GATT_OK, nullptr);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
break;
} // ESP_GATTS_EXEC_WRITE_EVT
@ -288,11 +281,11 @@ void BLECharacteristic::handleGATTServerEvent(
setValue(param->write.value, param->write.len);
}
ESP_LOGD(LOG_TAG, " - Response to write event: New value: handle: %.2x, uuid: %s",
log_d(" - Response to write event: New value: handle: %.2x, uuid: %s",
getHandle(), getUUID().toString().c_str());
char* pHexData = BLEUtils::buildHexData(nullptr, param->write.value, param->write.len);
ESP_LOGD(LOG_TAG, " - Data: length: %d, data: %s", param->write.len, pHexData);
log_d(" - Data: length: %d, data: %s", param->write.len, pHexData);
free(pHexData);
if (param->write.need_rsp) {
@ -309,11 +302,11 @@ void BLECharacteristic::handleGATTServerEvent(
param->write.conn_id,
param->write.trans_id, ESP_GATT_OK, &rsp);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
} // Response needed
if (m_pCallbacks != nullptr && param->write.is_prep != true) {
if (param->write.is_prep != true) {
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
}
} // Match on handles.
@ -361,9 +354,9 @@ void BLECharacteristic::handleGATTServerEvent(
// get mtu for peer device that we are sending read request to
uint16_t maxOffset = getService()->getServer()->getPeerMTU(param->read.conn_id) - 1;
ESP_LOGD(LOG_TAG, "mtu value: %d", maxOffset);
log_d("mtu value: %d", maxOffset);
if (param->read.need_rsp) {
ESP_LOGD(LOG_TAG, "Sending a response (esp_ble_gatts_send_response)");
log_d("Sending a response (esp_ble_gatts_send_response)");
esp_gatt_rsp_t rsp;
if (param->read.is_long) {
@ -384,6 +377,10 @@ void BLECharacteristic::handleGATTServerEvent(
}
} else { // read.is_long == false
// If is.long is false then this is the first (or only) request to read data, so invoke the callback
// Invoke the read callback.
m_pCallbacks->onRead(this);
std::string value = m_value.getValue();
if (value.length() + 1 > maxOffset) {
@ -398,16 +395,12 @@ void BLECharacteristic::handleGATTServerEvent(
rsp.attr_value.offset = 0;
memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len);
}
if (m_pCallbacks != nullptr) { // If is.long is false then this is the first (or only) request to read data, so invoke the callback
m_pCallbacks->onRead(this); // Invoke the read callback.
}
}
rsp.attr_value.handle = param->read.handle;
rsp.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
char *pHexData = BLEUtils::buildHexData(nullptr, rsp.attr_value.value, rsp.attr_value.len);
ESP_LOGD(LOG_TAG, " - Data: length=%d, data=%s, offset=%d", rsp.attr_value.len, pHexData, rsp.attr_value.offset);
log_d(" - Data: length=%d, data=%s, offset=%d", rsp.attr_value.len, pHexData, rsp.attr_value.offset);
free(pHexData);
esp_err_t errRc = ::esp_ble_gatts_send_response(
@ -416,7 +409,7 @@ void BLECharacteristic::handleGATTServerEvent(
ESP_GATT_OK,
&rsp);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gatts_send_response: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
} // Response needed
} // Handle matches this characteristic.
@ -431,7 +424,7 @@ void BLECharacteristic::handleGATTServerEvent(
// - uint16_t conn_id The connection used.
//
case ESP_GATTS_CONF_EVT: {
// ESP_LOGD(LOG_TAG, "m_handle = %d, conf->handle = %d", m_handle, param->conf.handle);
// log_d("m_handle = %d, conf->handle = %d", m_handle, param->conf.handle);
if(param->conf.conn_id == getService()->getServer()->getConnId()) // && param->conf.handle == m_handle) // bug in esp-idf and not implemented in arduino yet
m_semaphoreConfEvt.give(param->conf.status);
break;
@ -456,7 +449,7 @@ void BLECharacteristic::handleGATTServerEvent(
// event.
m_descriptorMap.handleGATTServerEvent(event, gatts_if, param);
ESP_LOGD(LOG_TAG, "<< handleGATTServerEvent");
log_v("<< handleGATTServerEvent");
} // handleGATTServerEvent
@ -468,9 +461,9 @@ void BLECharacteristic::handleGATTServerEvent(
*/
void BLECharacteristic::indicate() {
ESP_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length());
log_v(">> indicate: length: %d", m_value.getValue().length());
notify(false);
ESP_LOGD(LOG_TAG, "<< indicate");
log_v("<< indicate");
} // indicate
@ -481,15 +474,18 @@ void BLECharacteristic::indicate() {
* @return N/A.
*/
void BLECharacteristic::notify(bool is_notification) {
ESP_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length());
log_v(">> notify: length: %d", m_value.getValue().length());
assert(getService() != nullptr);
assert(getService()->getServer() != nullptr);
m_pCallbacks->onNotify(this); // Invoke the notify callback.
GeneralUtils::hexDump((uint8_t*)m_value.getValue().data(), m_value.getValue().length());
if (getService()->getServer()->getConnectedCount() == 0) {
ESP_LOGD(LOG_TAG, "<< notify: No connected clients.");
log_v("<< notify: No connected clients.");
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_NO_CLIENT, 0);
return;
}
@ -499,38 +495,53 @@ void BLECharacteristic::notify(bool is_notification) {
BLE2902 *p2902 = (BLE2902*)getDescriptorByUUID((uint16_t)0x2902);
if(is_notification) {
if (p2902 != nullptr && !p2902->getNotifications()) {
ESP_LOGD(LOG_TAG, "<< notifications disabled; ignoring");
log_v("<< notifications disabled; ignoring");
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_NOTIFY_DISABLED, 0); // Invoke the notify callback.
return;
}
}
else{
if (p2902 != nullptr && !p2902->getIndications()) {
ESP_LOGD(LOG_TAG, "<< indications disabled; ignoring");
log_v("<< indications disabled; ignoring");
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED, 0); // Invoke the notify callback.
return;
}
}
for (auto &myPair : getService()->getServer()->getPeerDevices(false)) {
uint16_t _mtu = (myPair.second.mtu);
if (m_value.getValue().length() > _mtu - 3) {
ESP_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3);
log_w("- Truncating to %d bytes (maximum notify size)", _mtu - 3);
}
size_t length = m_value.getValue().length();
if(!is_notification)
if(!is_notification) // is indication
m_semaphoreConfEvt.take("indicate");
esp_err_t errRc = ::esp_ble_gatts_send_indicate(
getService()->getServer()->getGattsIf(),
myPair.first,
getHandle(), length, (uint8_t*)m_value.getValue().data(), !is_notification); // The need_confirm = false makes this a notify.
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc));
m_semaphoreConfEvt.give();
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_GATT, errRc); // Invoke the notify callback.
return;
}
if(!is_notification)
m_semaphoreConfEvt.wait("indicate");
if(!is_notification){ // is indication
if(!m_semaphoreConfEvt.timedWait("indicate", indicationTimeout)){
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT, 0); // Invoke the notify callback.
} else {
auto code = (esp_gatt_status_t) m_semaphoreConfEvt.value();
if(code == ESP_GATT_OK) {
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::SUCCESS_INDICATE, code); // Invoke the notify callback.
} else {
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE, code);
}
}
} else {
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::SUCCESS_NOTIFY, 0); // Invoke the notify callback.
}
}
ESP_LOGD(LOG_TAG, "<< notify");
log_v("<< notify");
} // Notify
@ -542,7 +553,7 @@ void BLECharacteristic::notify(bool is_notification) {
* @return N/A
*/
void BLECharacteristic::setBroadcastProperty(bool value) {
//ESP_LOGD(LOG_TAG, "setBroadcastProperty(%d)", value);
//log_d("setBroadcastProperty(%d)", value);
if (value) {
m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_BROADCAST);
} else {
@ -556,9 +567,13 @@ void BLECharacteristic::setBroadcastProperty(bool value) {
* @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic.
*/
void BLECharacteristic::setCallbacks(BLECharacteristicCallbacks* pCallbacks) {
ESP_LOGD(LOG_TAG, ">> setCallbacks: 0x%x", (uint32_t)pCallbacks);
m_pCallbacks = pCallbacks;
ESP_LOGD(LOG_TAG, "<< setCallbacks");
log_v(">> setCallbacks: 0x%x", (uint32_t)pCallbacks);
if (pCallbacks != nullptr){
m_pCallbacks = pCallbacks;
} else {
m_pCallbacks = &defaultCallback;
}
log_v("<< setCallbacks");
} // setCallbacks
@ -573,9 +588,9 @@ void BLECharacteristic::setCallbacks(BLECharacteristicCallbacks* pCallbacks) {
* @param [in] handle The handle associated with this characteristic.
*/
void BLECharacteristic::setHandle(uint16_t handle) {
ESP_LOGD(LOG_TAG, ">> setHandle: handle=0x%.2x, characteristic uuid=%s", handle, getUUID().toString().c_str());
log_v(">> setHandle: handle=0x%.2x, characteristic uuid=%s", handle, getUUID().toString().c_str());
m_handle = handle;
ESP_LOGD(LOG_TAG, "<< setHandle");
log_v("<< setHandle");
} // setHandle
@ -584,7 +599,7 @@ void BLECharacteristic::setHandle(uint16_t handle) {
* @param [in] value Set to true if we are to allow indicate messages.
*/
void BLECharacteristic::setIndicateProperty(bool value) {
//ESP_LOGD(LOG_TAG, "setIndicateProperty(%d)", value);
//log_d("setIndicateProperty(%d)", value);
if (value) {
m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_INDICATE);
} else {
@ -598,7 +613,7 @@ void BLECharacteristic::setIndicateProperty(bool value) {
* @param [in] value Set to true if we are to allow notification messages.
*/
void BLECharacteristic::setNotifyProperty(bool value) {
//ESP_LOGD(LOG_TAG, "setNotifyProperty(%d)", value);
//log_d("setNotifyProperty(%d)", value);
if (value) {
m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_NOTIFY);
} else {
@ -612,7 +627,7 @@ void BLECharacteristic::setNotifyProperty(bool value) {
* @param [in] value Set to true if we are to allow reads.
*/
void BLECharacteristic::setReadProperty(bool value) {
//ESP_LOGD(LOG_TAG, "setReadProperty(%d)", value);
//log_d("setReadProperty(%d)", value);
if (value) {
m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_READ);
} else {
@ -628,14 +643,16 @@ void BLECharacteristic::setReadProperty(bool value) {
*/
void BLECharacteristic::setValue(uint8_t* data, size_t length) {
char* pHex = BLEUtils::buildHexData(nullptr, data, length);
ESP_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str());
log_v(">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str());
free(pHex);
if (length > ESP_GATT_MAX_ATTR_LEN) {
ESP_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN);
log_e("Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN);
return;
}
m_semaphoreSetValue.take();
m_value.setValue(data, length);
ESP_LOGD(LOG_TAG, "<< setValue");
m_semaphoreSetValue.give();
log_v("<< setValue");
} // setValue
@ -676,15 +693,13 @@ void BLECharacteristic::setValue(int& data32) {
} // setValue
void BLECharacteristic::setValue(float& data32) {
uint8_t temp[4];
*((float*)temp) = data32;
setValue(temp, 4);
float temp = data32;
setValue((uint8_t*)&temp, 4);
} // setValue
void BLECharacteristic::setValue(double& data64) {
uint8_t temp[8];
*((double*)temp) = data64;
setValue(temp, 8);
double temp = data64;
setValue((uint8_t*)&temp, 8);
} // setValue
@ -693,7 +708,7 @@ void BLECharacteristic::setValue(double& data64) {
* @param [in] value Set to true if we are to allow writes with no response.
*/
void BLECharacteristic::setWriteNoResponseProperty(bool value) {
//ESP_LOGD(LOG_TAG, "setWriteNoResponseProperty(%d)", value);
//log_d("setWriteNoResponseProperty(%d)", value);
if (value) {
m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE_NR);
} else {
@ -707,7 +722,7 @@ void BLECharacteristic::setWriteNoResponseProperty(bool value) {
* @param [in] value Set to true if we are to allow writes.
*/
void BLECharacteristic::setWriteProperty(bool value) {
//ESP_LOGD(LOG_TAG, "setWriteProperty(%d)", value);
//log_d("setWriteProperty(%d)", value);
if (value) {
m_properties = (esp_gatt_char_prop_t)(m_properties | ESP_GATT_CHAR_PROP_BIT_WRITE);
} else {
@ -721,17 +736,18 @@ void BLECharacteristic::setWriteProperty(bool value) {
* @return A string representation of the characteristic.
*/
std::string BLECharacteristic::toString() {
std::stringstream stringstream;
stringstream << std::hex << std::setfill('0');
stringstream << "UUID: " << m_bleUUID.toString() + ", handle: 0x" << std::setw(2) << m_handle;
stringstream << " " <<
((m_properties & ESP_GATT_CHAR_PROP_BIT_READ) ? "Read " : "") <<
((m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE) ? "Write " : "") <<
((m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE_NR) ? "WriteNoResponse " : "") <<
((m_properties & ESP_GATT_CHAR_PROP_BIT_BROADCAST) ? "Broadcast " : "") <<
((m_properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY) ? "Notify " : "") <<
((m_properties & ESP_GATT_CHAR_PROP_BIT_INDICATE) ? "Indicate " : "");
return stringstream.str();
std::string res = "UUID: " + m_bleUUID.toString() + ", handle : 0x";
char hex[5];
snprintf(hex, sizeof(hex), "%04x", m_handle);
res += hex;
res += " ";
if (m_properties & ESP_GATT_CHAR_PROP_BIT_READ) res += "Read ";
if (m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE) res += "Write ";
if (m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE_NR) res += "WriteNoResponse ";
if (m_properties & ESP_GATT_CHAR_PROP_BIT_BROADCAST) res += "Broadcast ";
if (m_properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY) res += "Notify ";
if (m_properties & ESP_GATT_CHAR_PROP_BIT_INDICATE) res += "Indicate ";
return res;
} // toString
@ -743,8 +759,8 @@ BLECharacteristicCallbacks::~BLECharacteristicCallbacks() {}
* @param [in] pCharacteristic The characteristic that is the source of the event.
*/
void BLECharacteristicCallbacks::onRead(BLECharacteristic* pCharacteristic) {
ESP_LOGD("BLECharacteristicCallbacks", ">> onRead: default");
ESP_LOGD("BLECharacteristicCallbacks", "<< onRead");
log_d("BLECharacteristicCallbacks", ">> onRead: default");
log_d("BLECharacteristicCallbacks", "<< onRead");
} // onRead
@ -753,8 +769,31 @@ void BLECharacteristicCallbacks::onRead(BLECharacteristic* pCharacteristic) {
* @param [in] pCharacteristic The characteristic that is the source of the event.
*/
void BLECharacteristicCallbacks::onWrite(BLECharacteristic* pCharacteristic) {
ESP_LOGD("BLECharacteristicCallbacks", ">> onWrite: default");
ESP_LOGD("BLECharacteristicCallbacks", "<< onWrite");
log_d("BLECharacteristicCallbacks", ">> onWrite: default");
log_d("BLECharacteristicCallbacks", "<< onWrite");
} // onWrite
/**
* @brief Callback function to support a Notify request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
*/
void BLECharacteristicCallbacks::onNotify(BLECharacteristic* pCharacteristic) {
log_d("BLECharacteristicCallbacks", ">> onNotify: default");
log_d("BLECharacteristicCallbacks", "<< onNotify");
} // onNotify
/**
* @brief Callback function to support a Notify/Indicate Status report.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] s Status of the notification/indication
* @param [in] code Additional code of underlying errors
*/
void BLECharacteristicCallbacks::onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code) {
log_d("BLECharacteristicCallbacks", ">> onStatus: default");
log_d("BLECharacteristicCallbacks", "<< onStatus");
} // onStatus
#endif /* CONFIG_BT_ENABLED */

View File

@ -90,6 +90,8 @@ public:
static const uint32_t PROPERTY_INDICATE = 1<<4;
static const uint32_t PROPERTY_WRITE_NR = 1<<5;
static const uint32_t indicationTimeout = 1000;
private:
friend class BLEServer;
@ -117,6 +119,7 @@ private:
void setHandle(uint16_t handle);
FreeRTOS::Semaphore m_semaphoreCreateEvt = FreeRTOS::Semaphore("CreateEvt");
FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt");
FreeRTOS::Semaphore m_semaphoreSetValue = FreeRTOS::Semaphore("SetValue");
}; // BLECharacteristic
@ -129,9 +132,22 @@ private:
*/
class BLECharacteristicCallbacks {
public:
typedef enum {
SUCCESS_INDICATE,
SUCCESS_NOTIFY,
ERROR_INDICATE_DISABLED,
ERROR_NOTIFY_DISABLED,
ERROR_GATT,
ERROR_NO_CLIENT,
ERROR_INDICATE_TIMEOUT,
ERROR_INDICATE_FAILURE
}Status;
virtual ~BLECharacteristicCallbacks();
virtual void onRead(BLECharacteristic* pCharacteristic);
virtual void onWrite(BLECharacteristic* pCharacteristic);
virtual void onNotify(BLECharacteristic* pCharacteristic);
virtual void onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code);
};
#endif /* CONFIG_BT_ENABLED */
#endif /* COMPONENTS_CPP_UTILS_BLECHARACTERISTIC_H_ */

View File

@ -116,17 +116,18 @@ void BLECharacteristicMap::setByUUID(BLECharacteristic* pCharacteristic, BLEUUID
* @return A string representation of the characteristic map.
*/
std::string BLECharacteristicMap::toString() {
std::stringstream stringStream;
stringStream << std::hex << std::setfill('0');
std::string res;
int count = 0;
char hex[5];
for (auto &myPair: m_uuidMap) {
if (count > 0) {
stringStream << "\n";
}
if (count > 0) {res += "\n";}
snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
count++;
stringStream << "handle: 0x" << std::setw(2) << myPair.first->getHandle() << ", uuid: " + myPair.first->getUUID().toString();
res += "handle: 0x";
res += hex;
res += ", uuid: " + myPair.first->getUUID().toString();
}
return stringStream.str();
return res;
} // toString

View File

@ -18,14 +18,7 @@
#include <sstream>
#include <unordered_set>
#include "BLEDevice.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEClient";
#endif
/*
* Design
@ -75,14 +68,14 @@ BLEClient::~BLEClient() {
*
*/
void BLEClient::clearServices() {
ESP_LOGD(LOG_TAG, ">> clearServices");
log_v(">> clearServices");
// Delete all the services.
for (auto &myPair : m_servicesMap) {
delete myPair.second;
}
m_servicesMap.clear();
m_haveServices = false;
ESP_LOGD(LOG_TAG, "<< clearServices");
log_v("<< clearServices");
} // clearServices
/**
@ -100,7 +93,7 @@ bool BLEClient::connect(BLEAdvertisedDevice* device) {
* @return True on success.
*/
bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) {
ESP_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str());
log_v(">> connect(%s)", address.toString().c_str());
// We need the connection handle that we get from registering the application. We register the app
// and then block on its completion. When the event has arrived, we will have the handle.
@ -111,7 +104,7 @@ bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) {
// clearServices(); // we dont need to delete services since every client is unique?
esp_err_t errRc = ::esp_ble_gattc_app_register(m_appId);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_app_register: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_app_register: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return false;
}
@ -128,12 +121,12 @@ bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) {
1 // direct connection <-- maybe needs to be changed in case of direct indirect connection???
);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return false;
}
uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete.
ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK);
log_v("<< connect(), rc=%d", rc==ESP_GATT_OK);
return rc == ESP_GATT_OK;
} // connect
@ -143,13 +136,13 @@ bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) {
* @return N/A.
*/
void BLEClient::disconnect() {
ESP_LOGD(LOG_TAG, ">> disconnect()");
log_v(">> disconnect()");
esp_err_t errRc = ::esp_ble_gattc_close(getGattcIf(), getConnId());
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_close: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_close: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
ESP_LOGD(LOG_TAG, "<< disconnect()");
log_v("<< disconnect()");
} // disconnect
@ -161,14 +154,14 @@ void BLEClient::gattClientEventHandler(
esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t* evtParam) {
ESP_LOGD(LOG_TAG, "gattClientEventHandler [esp_gatt_if: %d] ... %s",
log_d("gattClientEventHandler [esp_gatt_if: %d] ... %s",
gattc_if, BLEUtils::gattClientEventTypeToString(event).c_str());
// Execute handler code based on the type of event received.
switch(event) {
case ESP_GATTC_SRVC_CHG_EVT:
ESP_LOGI(LOG_TAG, "SERVICE CHANGED");
log_i("SERVICE CHANGED");
break;
case ESP_GATTC_CLOSE_EVT: {
@ -191,10 +184,11 @@ void BLEClient::gattClientEventHandler(
if (m_pClientCallbacks != nullptr) {
m_pClientCallbacks->onDisconnect(this);
}
BLEDevice::removePeerDevice(m_appId, true);
esp_ble_gattc_app_unregister(m_gattc_if);
m_semaphoreOpenEvt.give(ESP_GATT_IF_NONE);
m_semaphoreRssiCmplEvt.give();
m_semaphoreSearchCmplEvt.give(1);
BLEDevice::removePeerDevice(m_appId, true);
break;
} // ESP_GATTC_DISCONNECT_EVT
@ -234,7 +228,7 @@ void BLEClient::gattClientEventHandler(
case ESP_GATTC_CFG_MTU_EVT:
if(evtParam->cfg_mtu.status != ESP_GATT_OK) {
ESP_LOGE(LOG_TAG,"Config mtu failed");
log_e("Config mtu failed");
}
m_mtu = evtParam->cfg_mtu.mtu;
break;
@ -243,7 +237,7 @@ void BLEClient::gattClientEventHandler(
BLEDevice::updatePeerDevice(this, true, m_gattc_if);
esp_err_t errRc = esp_ble_gattc_send_mtu_req(gattc_if, evtParam->connect.conn_id);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_send_mtu_req: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_send_mtu_req: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
if(BLEDevice::m_securityLevel){
@ -263,17 +257,17 @@ void BLEClient::gattClientEventHandler(
case ESP_GATTC_SEARCH_CMPL_EVT: {
esp_ble_gattc_cb_param_t* p_data = (esp_ble_gattc_cb_param_t*)evtParam;
if (p_data->search_cmpl.status != ESP_GATT_OK){
ESP_LOGE(LOG_TAG, "search service failed, error status = %x", p_data->search_cmpl.status);
log_e("search service failed, error status = %x", p_data->search_cmpl.status);
break;
}
#ifndef ARDUINO_ARCH_ESP32
// commented out just for now to keep backward compatibility
// if(p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_REMOTE_DEVICE) {
// ESP_LOGI(LOG_TAG, "Get service information from remote device");
// log_i("Get service information from remote device");
// } else if (p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_NVS_FLASH) {
// ESP_LOGI(LOG_TAG, "Get service information from flash");
// log_i("Get service information from flash");
// } else {
// ESP_LOGI(LOG_TAG, "unknown service source");
// log_i("unknown service source");
// }
#endif
m_semaphoreSearchCmplEvt.give(0);
@ -343,9 +337,9 @@ BLEAddress BLEClient::getPeerAddress() {
* @return The RSSI value.
*/
int BLEClient::getRssi() {
ESP_LOGD(LOG_TAG, ">> getRssi()");
log_v(">> getRssi()");
if (!isConnected()) {
ESP_LOGD(LOG_TAG, "<< getRssi(): Not connected");
log_v("<< getRssi(): Not connected");
return 0;
}
// We make the API call to read the RSSI value which is an asynchronous operation. We expect to receive
@ -354,11 +348,11 @@ int BLEClient::getRssi() {
m_semaphoreRssiCmplEvt.take("getRssi");
esp_err_t rc = ::esp_ble_gap_read_rssi(*getPeerAddress().getNative());
if (rc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< getRssi: esp_ble_gap_read_rssi: rc=%d %s", rc, GeneralUtils::errorToString(rc));
log_e("<< getRssi: esp_ble_gap_read_rssi: rc=%d %s", rc, GeneralUtils::errorToString(rc));
return 0;
}
int rssiValue = m_semaphoreRssiCmplEvt.wait("getRssi");
ESP_LOGD(LOG_TAG, "<< getRssi(): %d", rssiValue);
log_v("<< getRssi(): %d", rssiValue);
return rssiValue;
} // getRssi
@ -380,7 +374,7 @@ BLERemoteService* BLEClient::getService(const char* uuid) {
* @throws BLEUuidNotFound
*/
BLERemoteService* BLEClient::getService(BLEUUID uuid) {
ESP_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str());
log_v(">> getService: uuid: %s", uuid.toString().c_str());
// Design
// ------
// We wish to retrieve the service given its UUID. It is possible that we have not yet asked the
@ -393,11 +387,11 @@ BLERemoteService* BLEClient::getService(BLEUUID uuid) {
std::string uuidStr = uuid.toString();
for (auto &myPair : m_servicesMap) {
if (myPair.first == uuidStr) {
ESP_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str());
log_v("<< getService: found the service with uuid: %s", uuid.toString().c_str());
return myPair.second;
}
} // End of each of the services.
ESP_LOGD(LOG_TAG, "<< getService: not found");
log_v("<< getService: not found");
return nullptr;
} // getService
@ -416,7 +410,7 @@ std::map<std::string, BLERemoteService*>* BLEClient::getServices() {
* peer BLE partner to be returned as events. Each event will be an an instance of ESP_GATTC_SEARCH_RES_EVT
* and will culminate with an ESP_GATTC_SEARCH_CMPL_EVT when all have been received.
*/
ESP_LOGD(LOG_TAG, ">> getServices");
log_v(">> getServices");
// TODO implement retrieving services from cache
clearServices(); // Clear any services that may exist.
@ -428,12 +422,12 @@ std::map<std::string, BLERemoteService*>* BLEClient::getServices() {
m_semaphoreSearchCmplEvt.take("getServices");
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_search_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_search_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return &m_servicesMap;
}
// If sucessfull, remember that we now have services.
m_haveServices = (m_semaphoreSearchCmplEvt.wait("getServices") == 0);
ESP_LOGD(LOG_TAG, "<< getServices");
log_v("<< getServices");
return &m_servicesMap;
} // getServices
@ -445,9 +439,9 @@ std::map<std::string, BLERemoteService*>* BLEClient::getServices() {
* @throws BLEUuidNotFound
*/
std::string BLEClient::getValue(BLEUUID serviceUUID, BLEUUID characteristicUUID) {
ESP_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
log_v(">> getValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
std::string ret = getService(serviceUUID)->getCharacteristic(characteristicUUID)->readValue();
ESP_LOGD(LOG_TAG, "<<getValue");
log_v("<<getValue");
return ret;
} // getValue
@ -461,7 +455,7 @@ std::string BLEClient::getValue(BLEUUID serviceUUID, BLEUUID characteristicUUID)
void BLEClient::handleGAPEvent(
esp_gap_ble_cb_event_t event,
esp_ble_gap_cb_param_t* param) {
ESP_LOGD(LOG_TAG, "BLEClient ... handling GAP event!");
log_d("BLEClient ... handling GAP event!");
switch (event) {
//
// ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT
@ -508,9 +502,9 @@ void BLEClient::setClientCallbacks(BLEClientCallbacks* pClientCallbacks) {
* @throws BLEUuidNotFound
*/
void BLEClient::setValue(BLEUUID serviceUUID, BLEUUID characteristicUUID, std::string value) {
ESP_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
log_v(">> setValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
getService(serviceUUID)->getCharacteristic(characteristicUUID)->writeValue(value);
ESP_LOGD(LOG_TAG, "<< setValue");
log_v("<< setValue");
} // setValue
uint16_t BLEClient::getMTU() {
@ -522,14 +516,13 @@ uint16_t BLEClient::getMTU() {
* @return A string representation of this client.
*/
std::string BLEClient::toString() {
std::ostringstream ss;
ss << "peer address: " << m_peerAddress.toString();
ss << "\nServices:\n";
std::string res = "peer address: " + m_peerAddress.toString();
res += "\nServices:\n";
for (auto &myPair : m_servicesMap) {
ss << myPair.second->toString() << "\n";
res += myPair.second->toString() + "\n";
// myPair.second is the value
}
return ss.str();
return res;
} // toString

View File

@ -15,7 +15,7 @@
#include <string.h>
#include <map>
#include <string>
#include "BLEExceptions.h"
//#include "BLEExceptions.h"
#include "BLERemoteService.h"
#include "BLEService.h"
#include "BLEAddress.h"

View File

@ -15,16 +15,7 @@
#include "BLEService.h"
#include "BLEDescriptor.h"
#include "GeneralUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEDescriptor";
#endif
#define NULL_HANDLE (0xffff)
@ -63,10 +54,10 @@ BLEDescriptor::~BLEDescriptor() {
* @param [in] pCharacteristic The characteristic to which to register this descriptor.
*/
void BLEDescriptor::executeCreate(BLECharacteristic* pCharacteristic) {
ESP_LOGD(LOG_TAG, ">> executeCreate(): %s", toString().c_str());
log_v(">> executeCreate(): %s", toString().c_str());
if (m_handle != NULL_HANDLE) {
ESP_LOGE(LOG_TAG, "Descriptor already has a handle.");
log_e("Descriptor already has a handle.");
return;
}
@ -82,12 +73,12 @@ void BLEDescriptor::executeCreate(BLECharacteristic* pCharacteristic) {
&m_value,
&control);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_add_char_descr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gatts_add_char_descr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreCreateEvt.wait("executeCreate");
ESP_LOGD(LOG_TAG, "<< executeCreate");
log_v("<< executeCreate");
} // executeCreate
@ -213,9 +204,9 @@ void BLEDescriptor::handleGATTServerEvent(
* @param [in] pCallbacks An instance of a callback structure used to define any callbacks for the descriptor.
*/
void BLEDescriptor::setCallbacks(BLEDescriptorCallbacks* pCallback) {
ESP_LOGD(LOG_TAG, ">> setCallbacks: 0x%x", (uint32_t) pCallback);
log_v(">> setCallbacks: 0x%x", (uint32_t) pCallback);
m_pCallback = pCallback;
ESP_LOGD(LOG_TAG, "<< setCallbacks");
log_v("<< setCallbacks");
} // setCallbacks
@ -226,9 +217,9 @@ void BLEDescriptor::setCallbacks(BLEDescriptorCallbacks* pCallback) {
* @return N/A.
*/
void BLEDescriptor::setHandle(uint16_t handle) {
ESP_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle);
log_v(">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle);
m_handle = handle;
ESP_LOGD(LOG_TAG, "<< setHandle()");
log_v("<< setHandle()");
} // setHandle
@ -239,7 +230,7 @@ void BLEDescriptor::setHandle(uint16_t handle) {
*/
void BLEDescriptor::setValue(uint8_t* data, size_t length) {
if (length > ESP_GATT_MAX_ATTR_LEN) {
ESP_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN);
log_e("Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN);
return;
}
m_value.attr_len = length;
@ -264,10 +255,10 @@ void BLEDescriptor::setAccessPermissions(esp_gatt_perm_t perm) {
* @return A string representation of the descriptor.
*/
std::string BLEDescriptor::toString() {
std::stringstream stringstream;
stringstream << std::hex << std::setfill('0');
stringstream << "UUID: " << m_bleUUID.toString() + ", handle: 0x" << std::setw(2) << m_handle;
return stringstream.str();
char hex[5];
snprintf(hex, sizeof(hex), "%04x", m_handle);
std::string res = "UUID: " + m_bleUUID.toString() + ", handle: 0x" + hex;
return res;
} // toString
@ -278,8 +269,8 @@ BLEDescriptorCallbacks::~BLEDescriptorCallbacks() {}
* @param [in] pDescriptor The descriptor that is the source of the event.
*/
void BLEDescriptorCallbacks::onRead(BLEDescriptor* pDescriptor) {
ESP_LOGD("BLEDescriptorCallbacks", ">> onRead: default");
ESP_LOGD("BLEDescriptorCallbacks", "<< onRead");
log_d("BLEDescriptorCallbacks", ">> onRead: default");
log_d("BLEDescriptorCallbacks", "<< onRead");
} // onRead
@ -288,8 +279,8 @@ void BLEDescriptorCallbacks::onRead(BLEDescriptor* pDescriptor) {
* @param [in] pDescriptor The descriptor that is the source of the event.
*/
void BLEDescriptorCallbacks::onWrite(BLEDescriptor* pDescriptor) {
ESP_LOGD("BLEDescriptorCallbacks", ">> onWrite: default");
ESP_LOGD("BLEDescriptorCallbacks", "<< onWrite");
log_d("BLEDescriptorCallbacks", ">> onWrite: default");
log_d("BLEDescriptorCallbacks", "<< onWrite");
} // onWrite

View File

@ -90,17 +90,18 @@ void BLEDescriptorMap::setByHandle(uint16_t handle, BLEDescriptor* pDescriptor)
* @return A string representation of the descriptor map.
*/
std::string BLEDescriptorMap::toString() {
std::stringstream stringStream;
stringStream << std::hex << std::setfill('0');
std::string res;
char hex[5];
int count = 0;
for (auto &myPair : m_uuidMap) {
if (count > 0) {
stringStream << "\n";
}
if (count > 0) {res += "\n";}
snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
count++;
stringStream << "handle: 0x" << std::setw(2) << myPair.first->getHandle() << ", uuid: " + myPair.first->getUUID().toString();
res += "handle: 0x";
res += hex;
res += ", uuid: " + myPair.first->getUUID().toString();
}
return stringStream.str();
return res;
} // toString

View File

@ -34,7 +34,7 @@
#if defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEDevice";
@ -63,13 +63,13 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @return A new instance of the client.
*/
/* STATIC */ BLEClient* BLEDevice::createClient() {
ESP_LOGD(LOG_TAG, ">> createClient");
log_v(">> createClient");
#ifndef CONFIG_GATTC_ENABLE // Check that BLE GATTC is enabled in make menuconfig
ESP_LOGE(LOG_TAG, "BLE GATTC is not enabled - CONFIG_GATTC_ENABLE not defined");
log_e("BLE GATTC is not enabled - CONFIG_GATTC_ENABLE not defined");
abort();
#endif // CONFIG_GATTC_ENABLE
m_pClient = new BLEClient();
ESP_LOGD(LOG_TAG, "<< createClient");
log_v("<< createClient");
return m_pClient;
} // createClient
@ -79,14 +79,14 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @return A new instance of the server.
*/
/* STATIC */ BLEServer* BLEDevice::createServer() {
ESP_LOGD(LOG_TAG, ">> createServer");
log_v(">> createServer");
#ifndef CONFIG_GATTS_ENABLE // Check that BLE GATTS is enabled in make menuconfig
ESP_LOGE(LOG_TAG, "BLE GATTS is not enabled - CONFIG_GATTS_ENABLE not defined");
log_e("BLE GATTS is not enabled - CONFIG_GATTS_ENABLE not defined");
abort();
#endif // CONFIG_GATTS_ENABLE
m_pServer = new BLEServer();
m_pServer->createApp(m_appId++);
ESP_LOGD(LOG_TAG, "<< createServer");
log_v("<< createServer");
return m_pServer;
} // createServer
@ -103,7 +103,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t* param
) {
ESP_LOGD(LOG_TAG, "gattServerEventHandler [esp_gatt_if: %d] ... %s",
log_d("gattServerEventHandler [esp_gatt_if: %d] ... %s",
gatts_if,
BLEUtils::gattServerEventTypeToString(event).c_str());
@ -150,7 +150,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t* param) {
ESP_LOGD(LOG_TAG, "gattClientEventHandler [esp_gatt_if: %d] ... %s",
log_d("gattClientEventHandler [esp_gatt_if: %d] ... %s",
gattc_if, BLEUtils::gattClientEventTypeToString(event).c_str());
BLEUtils::dumpGattClientEvent(event, gattc_if, param);
@ -194,16 +194,16 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
switch(event) {
case ESP_GAP_BLE_OOB_REQ_EVT: /* OOB request event */
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_OOB_REQ_EVT");
log_i("ESP_GAP_BLE_OOB_REQ_EVT");
break;
case ESP_GAP_BLE_LOCAL_IR_EVT: /* BLE local IR event */
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_LOCAL_IR_EVT");
log_i("ESP_GAP_BLE_LOCAL_IR_EVT");
break;
case ESP_GAP_BLE_LOCAL_ER_EVT: /* BLE local ER event */
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_LOCAL_ER_EVT");
log_i("ESP_GAP_BLE_LOCAL_ER_EVT");
break;
case ESP_GAP_BLE_NC_REQ_EVT: /* NUMERIC CONFIRMATION */
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_NC_REQ_EVT");
log_i("ESP_GAP_BLE_NC_REQ_EVT");
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
if(BLEDevice::m_securityCallbacks != nullptr){
esp_ble_confirm_reply(param->ble_security.ble_req.bd_addr, BLEDevice::m_securityCallbacks->onConfirmPIN(param->ble_security.key_notif.passkey));
@ -211,8 +211,8 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
#endif // CONFIG_BLE_SMP_ENABLE
break;
case ESP_GAP_BLE_PASSKEY_REQ_EVT: /* passkey request event */
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PASSKEY_REQ_EVT: ");
// esp_log_buffer_hex(LOG_TAG, m_remote_bda, sizeof(m_remote_bda));
log_i("ESP_GAP_BLE_PASSKEY_REQ_EVT: ");
// esp_log_buffer_hex(m_remote_bda, sizeof(m_remote_bda));
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
if(BLEDevice::m_securityCallbacks != nullptr){
esp_ble_passkey_reply(param->ble_security.ble_req.bd_addr, true, BLEDevice::m_securityCallbacks->onPassKeyRequest());
@ -225,7 +225,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
case ESP_GAP_BLE_SEC_REQ_EVT:
/* send the positive(true) security response to the peer device to accept the security request.
If not accept the security request, should sent the security response with negative(false) accept value*/
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_SEC_REQ_EVT");
log_i("ESP_GAP_BLE_SEC_REQ_EVT");
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
if(BLEDevice::m_securityCallbacks!=nullptr){
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, BLEDevice::m_securityCallbacks->onSecurityRequest());
@ -240,9 +240,9 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
*/
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: //the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
//display the passkey number to the user to input it in the peer deivce within 30 seconds
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_PASSKEY_NOTIF_EVT");
log_i("ESP_GAP_BLE_PASSKEY_NOTIF_EVT");
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
ESP_LOGI(LOG_TAG, "passKey = %d", param->ble_security.key_notif.passkey);
log_i("passKey = %d", param->ble_security.key_notif.passkey);
if(BLEDevice::m_securityCallbacks!=nullptr){
BLEDevice::m_securityCallbacks->onPassKeyNotify(param->ble_security.key_notif.passkey);
}
@ -250,13 +250,13 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key type info share with peer device to the user.
ESP_LOGD(LOG_TAG, "ESP_GAP_BLE_KEY_EVT");
log_d("ESP_GAP_BLE_KEY_EVT");
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
ESP_LOGI(LOG_TAG, "key type = %s", BLESecurity::esp_key_type_to_str(param->ble_security.ble_key.key_type));
log_i("key type = %s", BLESecurity::esp_key_type_to_str(param->ble_security.ble_key.key_type));
#endif // CONFIG_BLE_SMP_ENABLE
break;
case ESP_GAP_BLE_AUTH_CMPL_EVT:
ESP_LOGI(LOG_TAG, "ESP_GAP_BLE_AUTH_CMPL_EVT");
log_i("ESP_GAP_BLE_AUTH_CMPL_EVT");
#ifdef CONFIG_BLE_SMP_ENABLE // Check that BLE SMP (security) is configured in make menuconfig
if(BLEDevice::m_securityCallbacks != nullptr){
BLEDevice::m_securityCallbacks->onAuthenticationComplete(param->ble_security.auth_cmpl);
@ -305,12 +305,12 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* try and release/delete it.
*/
/* STATIC */ BLEScan* BLEDevice::getScan() {
//ESP_LOGD(LOG_TAG, ">> getScan");
//log_v(">> getScan");
if (m_pScan == nullptr) {
m_pScan = new BLEScan();
//ESP_LOGD(LOG_TAG, " - creating a new scan object");
//log_d(" - creating a new scan object");
}
//ESP_LOGD(LOG_TAG, "<< getScan: Returning object at 0x%x", (uint32_t)m_pScan);
//log_v("<< getScan: Returning object at 0x%x", (uint32_t)m_pScan);
return m_pScan;
} // getScan
@ -322,12 +322,12 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @param [in] characteristicUUID
*/
/* STATIC */ std::string BLEDevice::getValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID) {
ESP_LOGD(LOG_TAG, ">> getValue: bdAddress: %s, serviceUUID: %s, characteristicUUID: %s", bdAddress.toString().c_str(), serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
log_v(">> getValue: bdAddress: %s, serviceUUID: %s, characteristicUUID: %s", bdAddress.toString().c_str(), serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
BLEClient* pClient = createClient();
pClient->connect(bdAddress);
std::string ret = pClient->getValue(serviceUUID, characteristicUUID);
pClient->disconnect();
ESP_LOGD(LOG_TAG, "<< getValue");
log_v("<< getValue");
return ret;
} // getValue
@ -349,7 +349,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
#else
errRc = ::nvs_flash_init();
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "nvs_flash_init: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("nvs_flash_init: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
@ -359,20 +359,20 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
errRc = esp_bt_controller_init(&bt_cfg);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_bt_controller_init: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_bt_controller_init: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
#ifndef CLASSIC_BT_ENABLED
errRc = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_bt_controller_enable: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_bt_controller_enable: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
#else
errRc = esp_bt_controller_enable(ESP_BT_MODE_BTDM);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_bt_controller_enable: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_bt_controller_enable: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
#endif
@ -382,7 +382,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
if (bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
errRc = esp_bluedroid_init();
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_bluedroid_init: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_bluedroid_init: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
}
@ -390,21 +390,21 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
if (bt_state != ESP_BLUEDROID_STATUS_ENABLED) {
errRc = esp_bluedroid_enable();
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_bluedroid_enable: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_bluedroid_enable: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
}
errRc = esp_ble_gap_register_callback(BLEDevice::gapEventHandler);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_register_callback: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_register_callback: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
#ifdef CONFIG_GATTC_ENABLE // Check that BLE client is configured in make menuconfig
errRc = esp_ble_gattc_register_callback(BLEDevice::gattClientEventHandler);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_register_callback: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_register_callback: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
#endif // CONFIG_GATTC_ENABLE
@ -412,14 +412,14 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
#ifdef CONFIG_GATTS_ENABLE // Check that BLE server is configured in make menuconfig
errRc = esp_ble_gatts_register_callback(BLEDevice::gattServerEventHandler);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gatts_register_callback: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gatts_register_callback: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
#endif // CONFIG_GATTS_ENABLE
errRc = ::esp_ble_gap_set_device_name(deviceName.c_str());
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_set_device_name: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_set_device_name: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
};
@ -427,7 +427,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE;
errRc = ::esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_set_security_param: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_set_security_param: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
};
#endif // CONFIG_BLE_SMP_ENABLE
@ -450,12 +450,12 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @param [in] powerLevel.
*/
/* STATIC */ void BLEDevice::setPower(esp_power_level_t powerLevel) {
ESP_LOGD(LOG_TAG, ">> setPower: %d", powerLevel);
log_v(">> setPower: %d", powerLevel);
esp_err_t errRc = ::esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, powerLevel);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_tx_power_set: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
};
ESP_LOGD(LOG_TAG, "<< setPower");
log_v("<< setPower");
} // setPower
@ -466,7 +466,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @param [in] characteristicUUID
*/
/* STATIC */ void BLEDevice::setValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID, std::string value) {
ESP_LOGD(LOG_TAG, ">> setValue: bdAddress: %s, serviceUUID: %s, characteristicUUID: %s", bdAddress.toString().c_str(), serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
log_v(">> setValue: bdAddress: %s, serviceUUID: %s, characteristicUUID: %s", bdAddress.toString().c_str(), serviceUUID.toString().c_str(), characteristicUUID.toString().c_str());
BLEClient* pClient = createClient();
pClient->connect(bdAddress);
pClient->setValue(serviceUUID, characteristicUUID, value);
@ -479,9 +479,8 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @return A string representation of the nature of this device.
*/
/* STATIC */ std::string BLEDevice::toString() {
std::ostringstream oss;
oss << "BD Address: " << getAddress().toString();
return oss.str();
std::string res = "BD Address: " + getAddress().toString();
return res;
} // toString
@ -490,12 +489,12 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @param [in] address The address to add to the white list.
*/
void BLEDevice::whiteListAdd(BLEAddress address) {
ESP_LOGD(LOG_TAG, ">> whiteListAdd: %s", address.toString().c_str());
log_v(">> whiteListAdd: %s", address.toString().c_str());
esp_err_t errRc = esp_ble_gap_update_whitelist(true, *address.getNative()); // True to add an entry.
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_update_whitelist: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_update_whitelist: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
ESP_LOGD(LOG_TAG, "<< whiteListAdd");
log_v("<< whiteListAdd");
} // whiteListAdd
@ -504,12 +503,12 @@ void BLEDevice::whiteListAdd(BLEAddress address) {
* @param [in] address The address to remove from the white list.
*/
void BLEDevice::whiteListRemove(BLEAddress address) {
ESP_LOGD(LOG_TAG, ">> whiteListRemove: %s", address.toString().c_str());
log_v(">> whiteListRemove: %s", address.toString().c_str());
esp_err_t errRc = esp_ble_gap_update_whitelist(false, *address.getNative()); // False to remove an entry.
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_update_whitelist: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_update_whitelist: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
ESP_LOGD(LOG_TAG, "<< whiteListRemove");
log_v("<< whiteListRemove");
} // whiteListRemove
/*
@ -533,14 +532,14 @@ void BLEDevice::setSecurityCallbacks(BLESecurityCallbacks* callbacks) {
* @param [in] mtu Value to set local mtu, should be larger than 23 and lower or equal to 517
*/
esp_err_t BLEDevice::setMTU(uint16_t mtu) {
ESP_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu);
log_v(">> setLocalMTU: %d", mtu);
esp_err_t err = esp_ble_gatt_set_local_mtu(mtu);
if (err == ESP_OK) {
m_localMTU = mtu;
} else {
ESP_LOGE(LOG_TAG, "can't set local mtu value: %d", mtu);
log_e("can't set local mtu value: %d", mtu);
}
ESP_LOGD(LOG_TAG, "<< setLocalMTU");
log_v("<< setLocalMTU");
return err;
}
@ -558,16 +557,16 @@ bool BLEDevice::getInitialized() {
BLEAdvertising* BLEDevice::getAdvertising() {
if(m_bleAdvertising == nullptr) {
m_bleAdvertising = new BLEAdvertising();
ESP_LOGI(LOG_TAG, "create advertising");
log_i("create advertising");
}
ESP_LOGD(LOG_TAG, "get advertising");
log_d("get advertising");
return m_bleAdvertising;
}
void BLEDevice::startAdvertising() {
ESP_LOGD(LOG_TAG, ">> startAdvertising");
log_v(">> startAdvertising");
getAdvertising()->start();
ESP_LOGD(LOG_TAG, "<< startAdvertising");
log_v("<< startAdvertising");
} // startAdvertising
/* multi connect support */
@ -581,7 +580,7 @@ BLEClient* BLEDevice::getClientByGattIf(uint16_t conn_id) {
}
void BLEDevice::updatePeerDevice(void* peer, bool _client, uint16_t conn_id) {
ESP_LOGD(LOG_TAG, "update conn_id: %d, GATT role: %s", conn_id, _client? "client":"server");
log_d("update conn_id: %d, GATT role: %s", conn_id, _client? "client":"server");
std::map<uint16_t, conn_status_t>::iterator it = m_connectedClientsMap.find(ESP_GATT_IF_NONE);
if (it != m_connectedClientsMap.end()) {
std::swap(m_connectedClientsMap[conn_id], it->second);
@ -597,7 +596,7 @@ void BLEDevice::updatePeerDevice(void* peer, bool _client, uint16_t conn_id) {
}
void BLEDevice::addPeerDevice(void* peer, bool _client, uint16_t conn_id) {
ESP_LOGI(LOG_TAG, "add conn_id: %d, GATT role: %s", conn_id, _client? "client":"server");
log_i("add conn_id: %d, GATT role: %s", conn_id, _client? "client":"server");
conn_status_t status = {
.peer_device = peer,
.connected = true,
@ -608,7 +607,7 @@ void BLEDevice::addPeerDevice(void* peer, bool _client, uint16_t conn_id) {
}
void BLEDevice::removePeerDevice(uint16_t conn_id, bool _client) {
ESP_LOGI(LOG_TAG, "remove: %d, GATT role %s", conn_id, _client?"client":"server");
log_i("remove: %d, GATT role %s", conn_id, _client?"client":"server");
if(m_connectedClientsMap.find(conn_id) != m_connectedClientsMap.end())
m_connectedClientsMap.erase(conn_id);
}
@ -626,7 +625,7 @@ void BLEDevice::removePeerDevice(uint16_t conn_id, bool _client) {
esp_bluedroid_deinit();
esp_bt_controller_disable();
esp_bt_controller_deinit();
#ifndef ARDUINO_ARCH_ESP32
#ifdef ARDUINO_ARCH_ESP32
if (release_memory) {
esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); // <-- require tests because we released classic BT memory and this can cause crash (most likely not, esp-idf takes care of it)
} else {

View File

@ -7,8 +7,8 @@
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <string.h>
#include <sstream>
#include <esp_log.h>
#include <stdio.h>
#include "esp32-hal-log.h"
#include "BLEEddystoneTLM.h"
static const char LOG_TAG[] = "BLEEddystoneTLM";
@ -54,62 +54,44 @@ uint32_t BLEEddystoneTLM::getTime() {
} // getTime
std::string BLEEddystoneTLM::toString() {
std::stringstream ss;
std::string out = "";
uint32_t rawsec;
ss << "Version ";
ss << std::dec << m_eddystoneData.version;
ss << "\n";
std::string out = "";
uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
char val[6];
ss << "Battery Voltage ";
ss << std::dec << ENDIAN_CHANGE_U16(m_eddystoneData.volt);
ss << " mV\n";
out += "Version " + m_eddystoneData.version;
out += "\n";
out += "Battery Voltage " + ENDIAN_CHANGE_U16(m_eddystoneData.volt);
out += " mV\n";
ss << "Temperature ";
ss << (float) m_eddystoneData.temp;
ss << " °C\n";
out += "Temperature ";
snprintf(val, sizeof(val), "%d", m_eddystoneData.temp);
out += val;
out += ".0 °C\n";
ss << "Adv. Count ";
ss << std::dec << ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
out += "Adv. Count ";
snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U32(m_eddystoneData.advCount));
out += val;
out += "\n";
ss << "\n";
out += "Time ";
ss << "Time ";
snprintf(val, sizeof(val), "%04d", rawsec / 864000);
out += val;
out += ".";
rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
std::stringstream buffstream;
buffstream << "0000";
buffstream << std::dec << rawsec / 864000;
std::string buff = buffstream.str();
snprintf(val, sizeof(val), "%02d", (rawsec / 36000) % 24);
out += val;
out += ":";
ss << buff.substr(buff.length() - 4, buff.length());
ss << ".";
snprintf(val, sizeof(val), "%02d", (rawsec / 600) % 60);
out += val;
out += ":";
buffstream.str("");
buffstream.clear();
buffstream << "00";
buffstream << std::dec << (rawsec / 36000) % 24;
buff = buffstream.str();
ss << buff.substr(buff.length()-2, buff.length());
ss << ":";
snprintf(val, sizeof(val), "%02d", (rawsec / 10) % 60);
out += val;
out += "\n";
buffstream.str("");
buffstream.clear();
buffstream << "00";
buffstream << std::dec << (rawsec / 600) % 60;
buff = buffstream.str();
ss << buff.substr(buff.length() - 2, buff.length());
ss << ":";
buffstream.str("");
buffstream.clear();
buffstream << "00";
buffstream << std::dec << (rawsec / 10) % 60;
buff = buffstream.str();
ss << buff.substr(buff.length() - 2, buff.length());
ss << "\n";
return ss.str();
return out;
} // toString
/**
@ -117,7 +99,7 @@ std::string BLEEddystoneTLM::toString() {
*/
void BLEEddystoneTLM::setData(std::string data) {
if (data.length() != sizeof(m_eddystoneData)) {
ESP_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", data.length(), sizeof(m_eddystoneData));
log_e("Unable to set the data ... length passed in was %d and expected %d", data.length(), sizeof(m_eddystoneData));
return;
}
memcpy(&m_eddystoneData, data.data(), data.length());

View File

@ -7,7 +7,7 @@
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <string.h>
#include <esp_log.h>
#include "esp32-hal-log.h"
#include "BLEEddystoneURL.h"
static const char LOG_TAG[] = "BLEEddystoneURL";
@ -118,7 +118,7 @@ std::string BLEEddystoneURL::getDecodedURL() {
*/
void BLEEddystoneURL::setData(std::string data) {
if (data.length() > sizeof(m_eddystoneData)) {
ESP_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d", data.length(), sizeof(m_eddystoneData));
log_e("Unable to set the data ... length passed in was %d and max expected %d", data.length(), sizeof(m_eddystoneData));
return;
}
memset(&m_eddystoneData, 0, sizeof(m_eddystoneData));
@ -136,7 +136,7 @@ void BLEEddystoneURL::setPower(int8_t advertisedTxPower) {
void BLEEddystoneURL::setURL(std::string url) {
if (url.length() > sizeof(m_eddystoneData.url)) {
ESP_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d", url.length(), sizeof(m_eddystoneData.url));
log_e("Unable to set the url ... length passed in was %d and max expected %d", url.length(), sizeof(m_eddystoneData.url));
return;
}
memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url));

View File

@ -5,5 +5,5 @@
* Author: kolban
*/
#include "BLEExceptions.h"
//#include "BLEExceptions.h"

View File

@ -14,18 +14,11 @@
#include <esp_err.h>
#include <sstream>
#include "BLEExceptions.h"
//#include "BLEExceptions.h"
#include "BLEUtils.h"
#include "GeneralUtils.h"
#include "BLERemoteDescriptor.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLERemoteCharacteristic"; // The logging tag for this class.
#endif
/**
@ -40,15 +33,16 @@ BLERemoteCharacteristic::BLERemoteCharacteristic(
BLEUUID uuid,
esp_gatt_char_prop_t charProp,
BLERemoteService* pRemoteService) {
ESP_LOGD(LOG_TAG, ">> BLERemoteCharacteristic: handle: %d 0x%d, uuid: %s", handle, handle, uuid.toString().c_str());
log_v(">> BLERemoteCharacteristic: handle: %d 0x%d, uuid: %s", handle, handle, uuid.toString().c_str());
m_handle = handle;
m_uuid = uuid;
m_charProp = charProp;
m_pRemoteService = pRemoteService;
m_notifyCallback = nullptr;
m_rawData = nullptr;
retrieveDescriptors(); // Get the descriptors for this characteristic
ESP_LOGD(LOG_TAG, "<< BLERemoteCharacteristic");
log_v("<< BLERemoteCharacteristic");
} // BLERemoteCharacteristic
@ -166,7 +160,7 @@ void BLERemoteCharacteristic::gattClientEventHandler(esp_gattc_cb_event_t event,
case ESP_GATTC_NOTIFY_EVT: {
if (evtParam->notify.handle != getHandle()) break;
if (m_notifyCallback != nullptr) {
ESP_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", toString().c_str());
log_d("Invoking callback for notification on characteristic %s", toString().c_str());
m_notifyCallback(this, evtParam->notify.value, evtParam->notify.value_len, evtParam->notify.is_notify);
} // End we have a callback function ...
break;
@ -253,7 +247,7 @@ void BLERemoteCharacteristic::gattClientEventHandler(esp_gattc_cb_event_t event,
* @brief Populate the descriptors (if any) for this characteristic.
*/
void BLERemoteCharacteristic::retrieveDescriptors() {
ESP_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
log_v(">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
removeDescriptors(); // Remove any existing descriptors.
@ -277,13 +271,13 @@ void BLERemoteCharacteristic::retrieveDescriptors() {
}
if (status != ESP_GATT_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_get_all_descr: %s", BLEUtils::gattStatusToString(status).c_str());
log_e("esp_ble_gattc_get_all_descr: %s", BLEUtils::gattStatusToString(status).c_str());
break;
}
if (count == 0) break;
ESP_LOGD(LOG_TAG, "Found a descriptor: Handle: %d, UUID: %s", result.handle, BLEUUID(result.uuid).toString().c_str());
log_d("Found a descriptor: Handle: %d, UUID: %s", result.handle, BLEUUID(result.uuid).toString().c_str());
// We now have a new characteristic ... let us add that to our set of known characteristics
BLERemoteDescriptor* pNewRemoteDescriptor = new BLERemoteDescriptor(
@ -297,7 +291,7 @@ void BLERemoteCharacteristic::retrieveDescriptors() {
offset++;
} // while true
//m_haveCharacteristics = true; // Remember that we have received the characteristics.
ESP_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", offset);
log_v("<< retrieveDescriptors(): Found %d descriptors.", offset);
} // getDescriptors
@ -314,8 +308,8 @@ std::map<std::string, BLERemoteDescriptor*>* BLERemoteCharacteristic::getDescrip
* @return The handle for this characteristic.
*/
uint16_t BLERemoteCharacteristic::getHandle() {
//ESP_LOGD(LOG_TAG, ">> getHandle: Characteristic: %s", getUUID().toString().c_str());
//ESP_LOGD(LOG_TAG, "<< getHandle: %d 0x%.2x", m_handle, m_handle);
//log_v(">> getHandle: Characteristic: %s", getUUID().toString().c_str());
//log_v("<< getHandle: %d 0x%.2x", m_handle, m_handle);
return m_handle;
} // getHandle
@ -326,15 +320,15 @@ uint16_t BLERemoteCharacteristic::getHandle() {
* @return The Remote descriptor (if present) or null if not present.
*/
BLERemoteDescriptor* BLERemoteCharacteristic::getDescriptor(BLEUUID uuid) {
ESP_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
log_v(">> getDescriptor: uuid: %s", uuid.toString().c_str());
std::string v = uuid.toString();
for (auto &myPair : m_descriptorMap) {
if (myPair.first == v) {
ESP_LOGD(LOG_TAG, "<< getDescriptor: found");
log_v("<< getDescriptor: found");
return myPair.second;
}
}
ESP_LOGD(LOG_TAG, "<< getDescriptor: Not found");
log_v("<< getDescriptor: Not found");
return nullptr;
} // getDescriptor
@ -401,12 +395,12 @@ uint8_t BLERemoteCharacteristic::readUInt8() {
* @return The value of the remote characteristic.
*/
std::string BLERemoteCharacteristic::readValue() {
ESP_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x", getUUID().toString().c_str(), getHandle(), getHandle());
log_v(">> readValue(): uuid: %s, handle: %d 0x%.2x", getUUID().toString().c_str(), getHandle(), getHandle());
// Check to see that we are connected.
if (!getRemoteService()->getClient()->isConnected()) {
ESP_LOGE(LOG_TAG, "Disconnected");
throw BLEDisconnectedException();
log_e("Disconnected");
return std::string();
}
m_semaphoreReadCharEvt.take("readValue");
@ -421,7 +415,7 @@ std::string BLERemoteCharacteristic::readValue() {
ESP_GATT_AUTH_REQ_NONE); // Security
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_read_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_read_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return "";
}
@ -429,7 +423,7 @@ std::string BLERemoteCharacteristic::readValue() {
// in m_value will contain our data.
m_semaphoreReadCharEvt.wait("readValue");
ESP_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length());
log_v("<< readValue(): length: %d", m_value.length());
return m_value;
} // readValue
@ -441,7 +435,7 @@ std::string BLERemoteCharacteristic::readValue() {
* @return N/A.
*/
void BLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback, bool notifications) {
ESP_LOGD(LOG_TAG, ">> registerForNotify(): %s", toString().c_str());
log_v(">> registerForNotify(): %s", toString().c_str());
m_notifyCallback = notifyCallback; // Save the notification callback.
@ -455,7 +449,7 @@ void BLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback,
);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_register_for_notify: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_register_for_notify: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
uint8_t val[] = {0x01, 0x00};
@ -471,7 +465,7 @@ void BLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback,
);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_unregister_for_notify: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_unregister_for_notify: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
}
uint8_t val[] = {0x00, 0x00};
@ -481,7 +475,7 @@ void BLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback,
m_semaphoreRegForNotifyEvt.wait("registerForNotify");
ESP_LOGD(LOG_TAG, "<< registerForNotify()");
log_v("<< registerForNotify()");
} // registerForNotify
@ -507,11 +501,16 @@ void BLERemoteCharacteristic::removeDescriptors() {
* @return a String representation.
*/
std::string BLERemoteCharacteristic::toString() {
std::ostringstream ss;
ss << "Characteristic: uuid: " << m_uuid.toString() <<
", handle: " << getHandle() << " 0x" << std::hex << getHandle() <<
", props: " << BLEUtils::characteristicPropertiesToString(m_charProp);
return ss.str();
std::string res = "Characteristic: uuid: " + m_uuid.toString();
char val[6];
res += ", handle: ";
snprintf(val, sizeof(val), "%d", getHandle());
res += val;
res += " 0x";
snprintf(val, sizeof(val), "%04x", getHandle());
res += val;
res += ", props: " + BLEUtils::characteristicPropertiesToString(m_charProp);
return res;
} // toString
@ -547,12 +546,12 @@ void BLERemoteCharacteristic::writeValue(uint8_t newValue, bool response) {
*/
void BLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool response) {
// writeValue(std::string((char*)data, length), response);
ESP_LOGD(LOG_TAG, ">> writeValue(), length: %d", length);
log_v(">> writeValue(), length: %d", length);
// Check to see that we are connected.
if (!getRemoteService()->getClient()->isConnected()) {
ESP_LOGE(LOG_TAG, "Disconnected");
throw BLEDisconnectedException();
log_e("Disconnected");
return;
}
m_semaphoreWriteCharEvt.take("writeValue");
@ -568,13 +567,13 @@ void BLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool resp
);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_write_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_write_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreWriteCharEvt.wait("writeValue");
ESP_LOGD(LOG_TAG, "<< writeValue");
log_v("<< writeValue");
} // writeValue
/**

View File

@ -9,16 +9,7 @@
#include <sstream>
#include "BLERemoteDescriptor.h"
#include "GeneralUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLERemoteDescriptor";
#endif
BLERemoteDescriptor::BLERemoteDescriptor(
uint16_t handle,
@ -59,12 +50,12 @@ BLEUUID BLERemoteDescriptor::getUUID() {
std::string BLERemoteDescriptor::readValue() {
ESP_LOGD(LOG_TAG, ">> readValue: %s", toString().c_str());
log_v(">> readValue: %s", toString().c_str());
// Check to see that we are connected.
if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) {
ESP_LOGE(LOG_TAG, "Disconnected");
throw BLEDisconnectedException();
log_e("Disconnected");
return std::string();
}
m_semaphoreReadDescrEvt.take("readValue");
@ -77,7 +68,7 @@ std::string BLERemoteDescriptor::readValue() {
ESP_GATT_AUTH_REQ_NONE); // Security
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_read_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_read_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return "";
}
@ -85,7 +76,7 @@ std::string BLERemoteDescriptor::readValue() {
// in m_value will contain our data.
m_semaphoreReadDescrEvt.wait("readValue");
ESP_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length());
log_v("<< readValue(): length: %d", m_value.length());
return m_value;
} // readValue
@ -122,9 +113,12 @@ uint32_t BLERemoteDescriptor::readUInt32() {
* @retun A string representation of this BLE Remote Descriptor.
*/
std::string BLERemoteDescriptor::toString() {
std::stringstream ss;
ss << "handle: " << getHandle() << ", uuid: " << getUUID().toString();
return ss.str();
char val[6];
snprintf(val, sizeof(val), "%d", getHandle());
std::string res = "handle: ";
res += val;
res += ", uuid: " + getUUID().toString();
return res;
} // toString
@ -135,11 +129,11 @@ std::string BLERemoteDescriptor::toString() {
* @param [in] response True if we expect a response.
*/
void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response) {
ESP_LOGD(LOG_TAG, ">> writeValue: %s", toString().c_str());
log_v(">> writeValue: %s", toString().c_str());
// Check to see that we are connected.
if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) {
ESP_LOGE(LOG_TAG, "Disconnected");
throw BLEDisconnectedException();
log_e("Disconnected");
return;
}
esp_err_t errRc = ::esp_ble_gattc_write_char_descr(
@ -152,9 +146,9 @@ void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response
ESP_GATT_AUTH_REQ_NONE
);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_write_char_descr: %d", errRc);
log_e("esp_ble_gattc_write_char_descr: %d", errRc);
}
ESP_LOGD(LOG_TAG, "<< writeValue");
log_v("<< writeValue");
} // writeValue

View File

@ -12,15 +12,9 @@
#include "BLEUtils.h"
#include "GeneralUtils.h"
#include <esp_err.h>
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLERemoteService";
#endif
#pragma GCC diagnostic warning "-Wunused-but-set-parameter"
BLERemoteService::BLERemoteService(
esp_gatt_id_t srvcId,
@ -29,7 +23,7 @@ BLERemoteService::BLERemoteService(
uint16_t endHandle
) {
ESP_LOGD(LOG_TAG, ">> BLERemoteService()");
log_v(">> BLERemoteService()");
m_srvcId = srvcId;
m_pClient = pClient;
m_uuid = BLEUUID(m_srvcId);
@ -37,7 +31,7 @@ BLERemoteService::BLERemoteService(
m_startHandle = startHandle;
m_endHandle = endHandle;
ESP_LOGD(LOG_TAG, "<< BLERemoteService()");
log_v("<< BLERemoteService()");
}
@ -103,7 +97,7 @@ void BLERemoteService::gattClientEventHandler(
&m_srvcId,
&evtParam->get_char.char_id);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_get_characteristic: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_get_characteristic: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
break;
}
@ -165,14 +159,14 @@ BLERemoteCharacteristic* BLERemoteService::getCharacteristic(BLEUUID uuid) {
* @return N/A
*/
void BLERemoteService::retrieveCharacteristics() {
ESP_LOGD(LOG_TAG, ">> getCharacteristics() for service: %s", getUUID().toString().c_str());
log_v(">> getCharacteristics() for service: %s", getUUID().toString().c_str());
removeCharacteristics(); // Forget any previous characteristics.
uint16_t offset = 0;
esp_gattc_char_elem_t result;
while (true) {
uint16_t count = 10; // this value is used as in parameter that allows to search max 10 chars with the same uuid
uint16_t count = 1; // only room for 1 result allocated, so go one by one
esp_gatt_status_t status = ::esp_ble_gattc_get_all_char(
getClient()->getGattcIf(),
getClient()->getConnId(),
@ -188,7 +182,7 @@ void BLERemoteService::retrieveCharacteristics() {
}
if (status != ESP_GATT_OK) { // If we got an error, end.
ESP_LOGE(LOG_TAG, "esp_ble_gattc_get_all_char: %s", BLEUtils::gattStatusToString(status).c_str());
log_e("esp_ble_gattc_get_all_char: %s", BLEUtils::gattStatusToString(status).c_str());
break;
}
@ -196,7 +190,7 @@ void BLERemoteService::retrieveCharacteristics() {
break;
}
ESP_LOGD(LOG_TAG, "Found a characteristic: Handle: %d, UUID: %s", result.char_handle, BLEUUID(result.uuid).toString().c_str());
log_d("Found a characteristic: Handle: %d, UUID: %s", result.char_handle, BLEUUID(result.uuid).toString().c_str());
// We now have a new characteristic ... let us add that to our set of known characteristics
BLERemoteCharacteristic *pNewRemoteCharacteristic = new BLERemoteCharacteristic(
@ -212,7 +206,7 @@ void BLERemoteService::retrieveCharacteristics() {
} // Loop forever (until we break inside the loop).
m_haveCharacteristics = true; // Remember that we have received the characteristics.
ESP_LOGD(LOG_TAG, "<< getCharacteristics()");
log_v("<< getCharacteristics()");
} // getCharacteristics
@ -221,22 +215,35 @@ void BLERemoteService::retrieveCharacteristics() {
* @return A map of all the characteristics of this service.
*/
std::map<std::string, BLERemoteCharacteristic*>* BLERemoteService::getCharacteristics() {
ESP_LOGD(LOG_TAG, ">> getCharacteristics() for service: %s", getUUID().toString().c_str());
log_v(">> getCharacteristics() for service: %s", getUUID().toString().c_str());
// If is possible that we have not read the characteristics associated with the service so do that
// now. The request to retrieve the characteristics by calling "retrieveCharacteristics" is a blocking
// call and does not return until all the characteristics are available.
if (!m_haveCharacteristics) {
retrieveCharacteristics();
}
ESP_LOGD(LOG_TAG, "<< getCharacteristics() for service: %s", getUUID().toString().c_str());
log_v("<< getCharacteristics() for service: %s", getUUID().toString().c_str());
return &m_characteristicMap;
} // getCharacteristics
/**
* @brief Retrieve a map of all the characteristics of this service.
* @return A map of all the characteristics of this service.
*/
std::map<uint16_t, BLERemoteCharacteristic*>* BLERemoteService::getCharacteristicsByHandle() {
// If is possible that we have not read the characteristics associated with the service so do that
// now. The request to retrieve the characteristics by calling "retrieveCharacteristics" is a blocking
// call and does not return until all the characteristics are available.
if (!m_haveCharacteristics) {
retrieveCharacteristics();
}
return &m_characteristicMapByHandle;
} // getCharacteristicsByHandle
/**
* @brief This function is designed to get characteristics map when we have multiple characteristics with the same UUID
*/
void BLERemoteService::getCharacteristics(std::map<uint16_t, BLERemoteCharacteristic*>* pCharacteristicMap) {
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
pCharacteristicMap = &m_characteristicMapByHandle;
} // Get the characteristics map.
@ -265,8 +272,8 @@ uint16_t BLERemoteService::getStartHandle() {
uint16_t BLERemoteService::getHandle() {
ESP_LOGD(LOG_TAG, ">> getHandle: service: %s", getUUID().toString().c_str());
ESP_LOGD(LOG_TAG, "<< getHandle: %d 0x%.2x", getStartHandle(), getStartHandle());
log_v(">> getHandle: service: %s", getUUID().toString().c_str());
log_v("<< getHandle: %d 0x%.2x", getStartHandle(), getStartHandle());
return getStartHandle();
} // getHandle
@ -279,9 +286,9 @@ BLEUUID BLERemoteService::getUUID() {
* @brief Read the value of a characteristic associated with this service.
*/
std::string BLERemoteService::getValue(BLEUUID characteristicUuid) {
ESP_LOGD(LOG_TAG, ">> readValue: uuid: %s", characteristicUuid.toString().c_str());
log_v(">> readValue: uuid: %s", characteristicUuid.toString().c_str());
std::string ret = getCharacteristic(characteristicUuid)->readValue();
ESP_LOGD(LOG_TAG, "<< readValue");
log_v("<< readValue");
return ret;
} // readValue
@ -314,9 +321,9 @@ void BLERemoteService::removeCharacteristics() {
* @throws BLEUuidNotFound
*/
void BLERemoteService::setValue(BLEUUID characteristicUuid, std::string value) {
ESP_LOGD(LOG_TAG, ">> setValue: uuid: %s", characteristicUuid.toString().c_str());
log_v(">> setValue: uuid: %s", characteristicUuid.toString().c_str());
getCharacteristic(characteristicUuid)->writeValue(value);
ESP_LOGD(LOG_TAG, "<< setValue");
log_v("<< setValue");
} // setValue
@ -325,15 +332,25 @@ void BLERemoteService::setValue(BLEUUID characteristicUuid, std::string value) {
* @return A string representation of this remote service.
*/
std::string BLERemoteService::toString() {
std::ostringstream ss;
ss << "Service: uuid: " + m_uuid.toString();
ss << ", start_handle: " << std::dec << m_startHandle << " 0x" << std::hex << m_startHandle <<
", end_handle: " << std::dec << m_endHandle << " 0x" << std::hex << m_endHandle;
std::string res = "Service: uuid: " + m_uuid.toString();
char val[6];
res += ", start_handle: ";
snprintf(val, sizeof(val), "%d", m_startHandle);
res += val;
snprintf(val, sizeof(val), "%04x", m_startHandle);
res += " 0x";
res += val;
res += ", end_handle: ";
snprintf(val, sizeof(val), "%d", m_endHandle);
res += val;
snprintf(val, sizeof(val), "%04x", m_endHandle);
res += " 0x";
res += val;
for (auto &myPair : m_characteristicMap) {
ss << "\n" << myPair.second->toString();
res += "\n" + myPair.second->toString();
// myPair.second is the value
}
return ss.str();
return res;
} // toString

View File

@ -16,16 +16,7 @@
#include "BLEScan.h"
#include "BLEUtils.h"
#include "GeneralUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEScan";
#endif
/**
* Constructor
@ -75,7 +66,7 @@ void BLEScan::handleGAPEvent(
// Event that indicates that the duration allowed for the search has completed or that we have been
// asked to stop.
case ESP_GAP_SEARCH_INQ_CMPL_EVT: {
ESP_LOGW(LOG_TAG, "ESP_GAP_SEARCH_INQ_CMPL_EVT");
log_w("ESP_GAP_SEARCH_INQ_CMPL_EVT");
m_stopped = true;
m_semaphoreScanEnd.give();
if (m_scanCompleteCB != nullptr) {
@ -103,15 +94,15 @@ void BLEScan::handleGAPEvent(
}
if (found && !m_wantDuplicates) { // If we found a previous entry AND we don't want duplicates, then we are done.
ESP_LOGD(LOG_TAG, "Ignoring %s, already seen it.", advertisedAddress.toString().c_str());
log_d("Ignoring %s, already seen it.", advertisedAddress.toString().c_str());
vTaskDelay(1); // <--- allow to switch task in case we scan infinity and dont have new devices to report, or we are blocked here
break;
}
// We now construct a model of the advertised device that we have just found for the first
// time.
// ESP_LOG_BUFFER_HEXDUMP(LOG_TAG, (uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len, ESP_LOG_DEBUG);
// ESP_LOGW(LOG_TAG, "bytes length: %d + %d, addr type: %d", param->scan_rst.adv_data_len, param->scan_rst.scan_rsp_len, param->scan_rst.ble_addr_type);
// ESP_LOG_BUFFER_HEXDUMP((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len, ESP_LOG_DEBUG);
// log_w("bytes length: %d + %d, addr type: %d", param->scan_rst.adv_data_len, param->scan_rst.scan_rsp_len, param->scan_rst.ble_addr_type);
BLEAdvertisedDevice *advertisedDevice = new BLEAdvertisedDevice();
advertisedDevice->setAddress(advertisedAddress);
advertisedDevice->setRSSI(param->scan_rst.rssi);
@ -201,7 +192,7 @@ void BLEScan::setWindow(uint16_t windowMSecs) {
* @return True if scan started or false if there was an error.
*/
bool BLEScan::start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue) {
ESP_LOGD(LOG_TAG, ">> start(duration=%d)", duration);
log_v(">> start(duration=%d)", duration);
m_semaphoreScanEnd.take(std::string("start"));
m_scanCompleteCB = scanCompleteCB; // Save the callback to be invoked when the scan completes.
@ -218,7 +209,7 @@ bool BLEScan::start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), b
esp_err_t errRc = ::esp_ble_gap_set_scan_params(&m_scan_params);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_set_scan_params: err: %d, text: %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_set_scan_params: err: %d, text: %s", errRc, GeneralUtils::errorToString(errRc));
m_semaphoreScanEnd.give();
return false;
}
@ -226,14 +217,14 @@ bool BLEScan::start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), b
errRc = ::esp_ble_gap_start_scanning(duration);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_start_scanning: err: %d, text: %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_start_scanning: err: %d, text: %s", errRc, GeneralUtils::errorToString(errRc));
m_semaphoreScanEnd.give();
return false;
}
m_stopped = false;
ESP_LOGD(LOG_TAG, "<< start()");
log_v("<< start()");
return true;
} // start
@ -256,7 +247,7 @@ BLEScanResults BLEScan::start(uint32_t duration, bool is_continue) {
* @return N/A.
*/
void BLEScan::stop() {
ESP_LOGD(LOG_TAG, ">> stop()");
log_v(">> stop()");
esp_err_t errRc = ::esp_ble_gap_stop_scanning();
@ -264,16 +255,16 @@ void BLEScan::stop() {
m_semaphoreScanEnd.give();
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gap_stop_scanning: err: %d, text: %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gap_stop_scanning: err: %d, text: %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
ESP_LOGD(LOG_TAG, "<< stop()");
log_v("<< stop()");
} // stop
// delete peer device from cache after disconnecting, it is required in case we are connecting to devices with not public address
void BLEScan::erase(BLEAddress address) {
ESP_LOGI(LOG_TAG, "erase device: %s", address.toString().c_str());
log_i("erase device: %s", address.toString().c_str());
BLEAdvertisedDevice *advertisedDevice = m_scanResults.m_vectorAdvertisedDevices.find(address.toString())->second;
m_scanResults.m_vectorAdvertisedDevices.erase(address.toString());
delete advertisedDevice;
@ -284,9 +275,9 @@ void BLEScan::erase(BLEAddress address) {
* @brief Dump the scan results to the log.
*/
void BLEScanResults::dump() {
ESP_LOGD(LOG_TAG, ">> Dump scan results:");
log_v(">> Dump scan results:");
for (int i=0; i<getCount(); i++) {
ESP_LOGD(LOG_TAG, "- %s", getDevice(i).toString().c_str());
log_d("- %s", getDevice(i).toString().c_str());
}
} // dump

View File

@ -17,16 +17,7 @@
#include <string.h>
#include <string>
#include <unordered_set>
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEServer";
#endif
/**
* @brief Construct a %BLE Server
@ -73,12 +64,12 @@ BLEService* BLEServer::createService(const char* uuid) {
* @return A reference to the new service object.
*/
BLEService* BLEServer::createService(BLEUUID uuid, uint32_t numHandles, uint8_t inst_id) {
ESP_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str());
log_v(">> createService - %s", uuid.toString().c_str());
m_semaphoreCreateEvt.take("createService");
// Check that a service with the supplied UUID does not already exist.
if (m_serviceMap.getByUUID(uuid) != nullptr) {
ESP_LOGW(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.",
log_w("<< Attempt to create a new service with uuid %s but a service with that UUID already exists.",
uuid.toString().c_str());
}
@ -89,7 +80,7 @@ BLEService* BLEServer::createService(BLEUUID uuid, uint32_t numHandles, uint8_t
m_semaphoreCreateEvt.wait("createService");
ESP_LOGD(LOG_TAG, "<< createService");
log_v("<< createService");
return pService;
} // createService
@ -149,7 +140,7 @@ uint16_t BLEServer::getGattsIf() {
*
*/
void BLEServer::handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param) {
ESP_LOGD(LOG_TAG, ">> handleGATTServerEvent: %s",
log_v(">> handleGATTServerEvent: %s",
BLEUtils::gattServerEventTypeToString(event).c_str());
switch(event) {
@ -277,7 +268,7 @@ void BLEServer::handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t
// Invoke the handler for every Service we have.
m_serviceMap.handleGATTServerEvent(event, gatts_if, param);
ESP_LOGD(LOG_TAG, "<< handleGATTServerEvent");
log_v("<< handleGATTServerEvent");
} // handleGATTServerEvent
@ -287,11 +278,11 @@ void BLEServer::handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t
* @return N/A
*/
void BLEServer::registerApp(uint16_t m_appId) {
ESP_LOGD(LOG_TAG, ">> registerApp - %d", m_appId);
log_v(">> registerApp - %d", m_appId);
m_semaphoreRegisterAppEvt.take("registerApp"); // Take the mutex, will be released by ESP_GATTS_REG_EVT event.
::esp_ble_gatts_app_register(m_appId);
m_semaphoreRegisterAppEvt.wait("registerApp");
ESP_LOGD(LOG_TAG, "<< registerApp");
log_v("<< registerApp");
} // registerApp
@ -324,9 +315,9 @@ void BLEServer::removeService(BLEService* service) {
* retrieving the advertising object and invoking start upon it.
*/
void BLEServer::startAdvertising() {
ESP_LOGD(LOG_TAG, ">> startAdvertising");
log_v(">> startAdvertising");
BLEDevice::startAdvertising();
ESP_LOGD(LOG_TAG, "<< startAdvertising");
log_v("<< startAdvertising");
} // startAdvertising
/**
@ -344,34 +335,34 @@ bool BLEServer::connect(BLEAddress address) {
1 // direct connection
);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return false;
}
uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete.
ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK);
log_v("<< connect(), rc=%d", rc==ESP_GATT_OK);
return rc == ESP_GATT_OK;
} // connect
void BLEServerCallbacks::onConnect(BLEServer* pServer) {
ESP_LOGD("BLEServerCallbacks", ">> onConnect(): Default");
ESP_LOGD("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
ESP_LOGD("BLEServerCallbacks", "<< onConnect()");
log_d("BLEServerCallbacks", ">> onConnect(): Default");
log_d("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
log_d("BLEServerCallbacks", "<< onConnect()");
} // onConnect
void BLEServerCallbacks::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) {
ESP_LOGD("BLEServerCallbacks", ">> onConnect(): Default");
ESP_LOGD("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
ESP_LOGD("BLEServerCallbacks", "<< onConnect()");
log_d("BLEServerCallbacks", ">> onConnect(): Default");
log_d("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
log_d("BLEServerCallbacks", "<< onConnect()");
} // onConnect
void BLEServerCallbacks::onDisconnect(BLEServer* pServer) {
ESP_LOGD("BLEServerCallbacks", ">> onDisconnect(): Default");
ESP_LOGD("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
ESP_LOGD("BLEServerCallbacks", "<< onDisconnect()");
log_d("BLEServerCallbacks", ">> onDisconnect(): Default");
log_d("BLEServerCallbacks", "Device: %s", BLEDevice::toString().c_str());
log_d("BLEServerCallbacks", "<< onDisconnect()");
} // onDisconnect
/* multi connect support */
@ -421,4 +412,9 @@ void BLEServer::updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval,
conn_params.timeout = timeout; // timeout = 400*10ms = 4000ms
esp_ble_gap_update_conn_params(&conn_params);
}
void BLEServer::disconnect(uint16_t connId) {
esp_ble_gatts_close(m_gatts_if, connId);
}
#endif // CONFIG_BT_ENABLED

View File

@ -72,6 +72,7 @@ public:
BLEService* getServiceByUUID(const char* uuid);
BLEService* getServiceByUUID(BLEUUID uuid);
bool connect(BLEAddress address);
void disconnect(uint16_t connId);
uint16_t m_appId;
void updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout);

View File

@ -20,14 +20,7 @@
#include "BLEService.h"
#include "BLEUtils.h"
#include "GeneralUtils.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEService"; // Tag for logging.
#endif
#define NULL_HANDLE (0xffff)
@ -64,7 +57,7 @@ BLEService::BLEService(BLEUUID uuid, uint16_t numHandles) {
*/
void BLEService::executeCreate(BLEServer* pServer) {
ESP_LOGD(LOG_TAG, ">> executeCreate() - Creating service (esp_ble_gatts_create_service) service uuid: %s", getUUID().toString().c_str());
log_v(">> executeCreate() - Creating service (esp_ble_gatts_create_service) service uuid: %s", getUUID().toString().c_str());
m_pServer = pServer;
m_semaphoreCreateEvt.take("executeCreate"); // Take the mutex and release at event ESP_GATTS_CREATE_EVT
@ -75,12 +68,12 @@ void BLEService::executeCreate(BLEServer* pServer) {
esp_err_t errRc = ::esp_ble_gatts_create_service(getServer()->getGattsIf(), &srvc_id, m_numHandles); // The maximum number of handles associated with the service.
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gatts_create_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gatts_create_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreCreateEvt.wait("executeCreate");
ESP_LOGD(LOG_TAG, "<< executeCreate");
log_v("<< executeCreate");
} // executeCreate
@ -91,18 +84,18 @@ void BLEService::executeCreate(BLEServer* pServer) {
*/
void BLEService::executeDelete() {
ESP_LOGD(LOG_TAG, ">> executeDelete()");
log_v(">> executeDelete()");
m_semaphoreDeleteEvt.take("executeDelete"); // Take the mutex and release at event ESP_GATTS_DELETE_EVT
esp_err_t errRc = ::esp_ble_gatts_delete_service(getHandle());
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "esp_ble_gatts_delete_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("esp_ble_gatts_delete_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreDeleteEvt.wait("executeDelete");
ESP_LOGD(LOG_TAG, "<< executeDelete");
log_v("<< executeDelete");
} // executeDelete
@ -111,10 +104,10 @@ void BLEService::executeDelete() {
* @return N/A.
*/
void BLEService::dump() {
ESP_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%.2x",
log_d("Service: uuid:%s, handle: 0x%.2x",
m_uuid.toString().c_str(),
m_handle);
ESP_LOGD(LOG_TAG, "Characteristics:\n%s", m_characteristicMap.toString().c_str());
log_d("Characteristics:\n%s", m_characteristicMap.toString().c_str());
} // dump
@ -138,9 +131,9 @@ void BLEService::start() {
// We start the service through its local handle which was returned in the ESP_GATTS_CREATE_EVT event
// obtained as a result of calling esp_ble_gatts_create_service().
//
ESP_LOGD(LOG_TAG, ">> start(): Starting service (esp_ble_gatts_start_service): %s", toString().c_str());
log_v(">> start(): Starting service (esp_ble_gatts_start_service): %s", toString().c_str());
if (m_handle == NULL_HANDLE) {
ESP_LOGE(LOG_TAG, "<< !!! We attempted to start a service but don't know its handle!");
log_e("<< !!! We attempted to start a service but don't know its handle!");
return;
}
@ -158,12 +151,12 @@ void BLEService::start() {
esp_err_t errRc = ::esp_ble_gatts_start_service(m_handle);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_start_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gatts_start_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreStartEvt.wait("start");
ESP_LOGD(LOG_TAG, "<< start()");
log_v("<< start()");
} // start
@ -174,9 +167,9 @@ void BLEService::stop() {
// We ask the BLE runtime to start the service and then create each of the characteristics.
// We start the service through its local handle which was returned in the ESP_GATTS_CREATE_EVT event
// obtained as a result of calling esp_ble_gatts_create_service().
ESP_LOGD(LOG_TAG, ">> stop(): Stopping service (esp_ble_gatts_stop_service): %s", toString().c_str());
log_v(">> stop(): Stopping service (esp_ble_gatts_stop_service): %s", toString().c_str());
if (m_handle == NULL_HANDLE) {
ESP_LOGE(LOG_TAG, "<< !!! We attempted to stop a service but don't know its handle!");
log_e("<< !!! We attempted to stop a service but don't know its handle!");
return;
}
@ -184,12 +177,12 @@ void BLEService::stop() {
esp_err_t errRc = ::esp_ble_gatts_stop_service(m_handle);
if (errRc != ESP_OK) {
ESP_LOGE(LOG_TAG, "<< esp_ble_gatts_stop_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
log_e("<< esp_ble_gatts_stop_service: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return;
}
m_semaphoreStopEvt.wait("stop");
ESP_LOGD(LOG_TAG, "<< stop()");
log_v("<< stop()");
} // start
@ -198,13 +191,13 @@ void BLEService::stop() {
* @param [in] handle The handle associated with the service.
*/
void BLEService::setHandle(uint16_t handle) {
ESP_LOGD(LOG_TAG, ">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str());
log_v(">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str());
if (m_handle != NULL_HANDLE) {
ESP_LOGE(LOG_TAG, "!!! Handle is already set %.2x", m_handle);
log_e("!!! Handle is already set %.2x", m_handle);
return;
}
m_handle = handle;
ESP_LOGD(LOG_TAG, "<< setHandle");
log_v("<< setHandle");
} // setHandle
@ -226,14 +219,14 @@ void BLEService::addCharacteristic(BLECharacteristic* pCharacteristic) {
// BLECharacteristicMap class instance found in m_characteristicMap. We add the characteristic
// to the map and then ask the service to add the characteristic at the BLE level (ESP-IDF).
ESP_LOGD(LOG_TAG, ">> addCharacteristic()");
ESP_LOGD(LOG_TAG, "Adding characteristic: uuid=%s to service: %s",
log_v(">> addCharacteristic()");
log_d("Adding characteristic: uuid=%s to service: %s",
pCharacteristic->getUUID().toString().c_str(),
toString().c_str());
// Check that we don't add the same characteristic twice.
if (m_characteristicMap.getByUUID(pCharacteristic->getUUID()) != nullptr) {
ESP_LOGW(LOG_TAG, "<< Adding a new characteristic with the same UUID as a previous one");
log_w("<< Adding a new characteristic with the same UUID as a previous one");
//return;
}
@ -241,7 +234,7 @@ void BLEService::addCharacteristic(BLECharacteristic* pCharacteristic) {
// but not by handle. The handle is allocated to us on the ESP_GATTS_ADD_CHAR_EVT.
m_characteristicMap.setByUUID(pCharacteristic, pCharacteristic->getUUID());
ESP_LOGD(LOG_TAG, "<< addCharacteristic()");
log_v("<< addCharacteristic()");
} // addCharacteristic
@ -287,7 +280,7 @@ void BLEService::handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t
if (m_handle == param->add_char.service_handle) {
BLECharacteristic *pCharacteristic = getLastCreatedCharacteristic();
if (pCharacteristic == nullptr) {
ESP_LOGE(LOG_TAG, "Expected to find characteristic with UUID: %s, but didnt!",
log_e("Expected to find characteristic with UUID: %s, but didnt!",
BLEUUID(param->add_char.char_uuid).toString().c_str());
dump();
break;
@ -388,10 +381,12 @@ BLECharacteristic* BLEService::getCharacteristic(BLEUUID uuid) {
* @return A string representation of this service.
*/
std::string BLEService::toString() {
std::stringstream stringStream;
stringStream << "UUID: " << getUUID().toString() <<
", handle: 0x" << std::hex << std::setfill('0') << std::setw(2) << getHandle();
return stringStream.str();
std::string res = "UUID: " + getUUID().toString();
char hex[5];
snprintf(hex, sizeof(hex), "%04x", getHandle());
res += ", handle: 0x";
res += hex;
return res;
} // toString

View File

@ -6,7 +6,7 @@
*/
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <sstream>
#include <stdio.h>
#include <iomanip>
#include "BLEService.h"
@ -73,12 +73,15 @@ void BLEServiceMap::setByHandle(uint16_t handle, BLEService* service) {
* @return A string representation of the service map.
*/
std::string BLEServiceMap::toString() {
std::stringstream stringStream;
stringStream << std::hex << std::setfill('0');
std::string res;
char hex[5];
for (auto &myPair: m_handleMap) {
stringStream << "handle: 0x" << std::setw(2) << myPair.first << ", uuid: " + myPair.second->getUUID().toString() << "\n";
res += "handle: 0x";
snprintf(hex, sizeof(hex), "%04x", myPair.first);
res += hex;
res += ", uuid: " + myPair.second->getUUID().toString() + "\n";
}
return stringStream.str();
return res;
} // toString
void BLEServiceMap::handleGATTServerEvent(

View File

@ -13,15 +13,7 @@
#include <assert.h>
#include <stdlib.h>
#include "BLEUUID.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEUUID";
#endif
/**
* @brief Copy memory from source to target but in reverse order.
@ -121,7 +113,7 @@ BLEUUID::BLEUUID(std::string value) {
}
}
else {
ESP_LOGE(LOG_TAG, "ERROR: UUID value not 2, 4, 16 or 36 bytes");
log_e("ERROR: UUID value not 2, 4, 16 or 36 bytes");
m_valueSet = false;
}
} //BLEUUID(std::string)
@ -136,7 +128,7 @@ BLEUUID::BLEUUID(std::string value) {
*/
BLEUUID::BLEUUID(uint8_t* pData, size_t size, bool msbFirst) {
if (size != 16) {
ESP_LOGE(LOG_TAG, "ERROR: UUID length not 16 bytes");
log_e("ERROR: UUID length not 16 bytes");
return;
}
m_uuid.len = ESP_UUID_LEN_128;
@ -212,7 +204,7 @@ uint8_t BLEUUID::bitSize() {
case ESP_UUID_LEN_128:
return 128;
default:
ESP_LOGE(LOG_TAG, "Unknown UUID length: %d", m_uuid.len);
log_e("Unknown UUID length: %d", m_uuid.len);
return 0;
} // End of switch
} // bitSize
@ -225,7 +217,7 @@ uint8_t BLEUUID::bitSize() {
* @return True if the UUIDs are equal and false otherwise.
*/
bool BLEUUID::equals(BLEUUID uuid) {
//ESP_LOGD(TAG, "Comparing: %s to %s", toString().c_str(), uuid.toString().c_str());
//log_d("Comparing: %s to %s", toString().c_str(), uuid.toString().c_str());
if (!m_valueSet || !uuid.m_valueSet) return false;
if (uuid.m_uuid.len != m_uuid.len) {
@ -279,12 +271,12 @@ BLEUUID BLEUUID::fromString(std::string _uuid) {
* @return The native UUID value or NULL if not set.
*/
esp_bt_uuid_t* BLEUUID::getNative() {
//ESP_LOGD(TAG, ">> getNative()")
//log_d(">> getNative()")
if (m_valueSet == false) {
ESP_LOGD(LOG_TAG, "<< Return of un-initialized UUID!");
log_v("<< Return of un-initialized UUID!");
return nullptr;
}
//ESP_LOGD(TAG, "<< getNative()");
//log_d("<< getNative()");
return &m_uuid;
} // getNative
@ -296,7 +288,7 @@ esp_bt_uuid_t* BLEUUID::getNative() {
* will convert 16 or 32 bit representations to the full 128bit.
*/
BLEUUID BLEUUID::to128() {
//ESP_LOGD(LOG_TAG, ">> toFull() - %s", toString().c_str());
//log_v(">> toFull() - %s", toString().c_str());
// If we either don't have a value or are already a 128 bit UUID, nothing further to do.
if (!m_valueSet || m_uuid.len == ESP_UUID_LEN_128) {
@ -338,7 +330,7 @@ BLEUUID BLEUUID::to128() {
m_uuid.uuid.uuid128[0] = 0xfb;
m_uuid.len = ESP_UUID_LEN_128;
//ESP_LOGD(TAG, "<< toFull <- %s", toString().c_str());
//log_d("<< toFull <- %s", toString().c_str());
return *this;
} // to128
@ -357,51 +349,38 @@ BLEUUID BLEUUID::to128() {
*/
std::string BLEUUID::toString() {
if (!m_valueSet) return "<NULL>"; // If we have no value, nothing to format.
// If the UUIDs are 16 or 32 bit, pad correctly.
std::stringstream ss;
if (m_uuid.len == ESP_UUID_LEN_16) { // If the UUID is 16bit, pad correctly.
ss << "0000" <<
std::hex <<
std::setfill('0') <<
std::setw(4) <<
m_uuid.uuid.uuid16 <<
"-0000-1000-8000-00805f9b34fb";
return ss.str(); // Return the string
char hex[9];
snprintf(hex, sizeof(hex), "%08x", m_uuid.uuid.uuid16);
return std::string(hex) + "-0000-1000-8000-00805f9b34fb";
} // End 16bit UUID
if (m_uuid.len == ESP_UUID_LEN_32) { // If the UUID is 32bit, pad correctly.
ss << std::hex <<
std::setfill('0') <<
std::setw(8) <<
m_uuid.uuid.uuid32 <<
"-0000-1000-8000-00805f9b34fb";
return ss.str(); // return the string
char hex[9];
snprintf(hex, sizeof(hex), "%08x", m_uuid.uuid.uuid32);
return std::string(hex) + "-0000-1000-8000-00805f9b34fb";
} // End 32bit UUID
// The UUID is not 16bit or 32bit which means that it is 128bit.
//
// UUID string format:
// AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP
ss << std::hex << std::setfill('0') <<
std::setw(2) << (int) m_uuid.uuid.uuid128[15] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[14] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[13] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[12] << "-" <<
std::setw(2) << (int) m_uuid.uuid.uuid128[11] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[10] << "-" <<
std::setw(2) << (int) m_uuid.uuid.uuid128[9] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[8] << "-" <<
std::setw(2) << (int) m_uuid.uuid.uuid128[7] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[6] << "-" <<
std::setw(2) << (int) m_uuid.uuid.uuid128[5] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[4] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[3] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[2] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[1] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[0];
return ss.str();
auto size = 37; // 32 for UUID data, 4 for '-' delimiters and one for a terminator == 37 chars
char *hex = (char *)malloc(size);
snprintf(hex, size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
m_uuid.uuid.uuid128[15], m_uuid.uuid.uuid128[14],
m_uuid.uuid.uuid128[13], m_uuid.uuid.uuid128[12],
m_uuid.uuid.uuid128[11], m_uuid.uuid.uuid128[10],
m_uuid.uuid.uuid128[9], m_uuid.uuid.uuid128[8],
m_uuid.uuid.uuid128[7], m_uuid.uuid.uuid128[6],
m_uuid.uuid.uuid128[5], m_uuid.uuid.uuid128[4],
m_uuid.uuid.uuid128[3], m_uuid.uuid.uuid128[2],
m_uuid.uuid.uuid128[1], m_uuid.uuid.uuid128[0]);
std::string res(hex);
free(hex);
return res;
} // toString
#endif /* CONFIG_BT_ENABLED */

View File

@ -23,14 +23,7 @@
#include <sstream>
#include <iomanip>
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEUtils"; // Tag for logging.
#endif
/*
static std::map<std::string, BLEClient*> g_addressMap;
@ -611,26 +604,32 @@ static const gattService_t g_gattServices[] = {
* @return A string representation of characteristic properties.
*/
std::string BLEUtils::characteristicPropertiesToString(esp_gatt_char_prop_t prop) {
std::stringstream stream;
stream <<
"broadcast: " << ((prop & ESP_GATT_CHAR_PROP_BIT_BROADCAST)?"1":"0") <<
", read: " << ((prop & ESP_GATT_CHAR_PROP_BIT_READ)?"1":"0") <<
", write_nr: " << ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE_NR)?"1":"0") <<
", write: " << ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE)?"1":"0") <<
", notify: " << ((prop & ESP_GATT_CHAR_PROP_BIT_NOTIFY)?"1":"0") <<
", indicate: " << ((prop & ESP_GATT_CHAR_PROP_BIT_INDICATE)?"1":"0") <<
", auth: " << ((prop & ESP_GATT_CHAR_PROP_BIT_AUTH)?"1":"0");
return stream.str();
std::string res = "broadcast: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_BROADCAST)?"1":"0");
res += ", read: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_READ)?"1":"0");
res += ", write_nr: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE_NR)?"1":"0");
res += ", write: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE)?"1":"0");
res += ", notify: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_NOTIFY)?"1":"0");
res += ", indicate: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_INDICATE)?"1":"0");
res += ", auth: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_AUTH)?"1":"0");
return res;
} // characteristicPropertiesToString
/**
* @brief Convert an esp_gatt_id_t to a string.
*/
static std::string gattIdToString(esp_gatt_id_t gattId) {
std::stringstream stream;
stream << "uuid: " << BLEUUID(gattId.uuid).toString() << ", inst_id: " << (int)gattId.inst_id;
//sprintf(buffer, "uuid: %s, inst_id: %d", uuidToString(gattId.uuid).c_str(), gattId.inst_id);
return stream.str();
std::string res = "uuid: " + BLEUUID(gattId.uuid).toString() + ", inst_id: ";
char val[8];
snprintf(val, sizeof(val), "%d", (int)gattId.inst_id);
res += val;
return res;
} // gattIdToString
@ -661,23 +660,23 @@ const char* BLEUtils::addressTypeToString(esp_ble_addr_type_t type) {
* @return std::string A string representation of the advertising flags.
*/
std::string BLEUtils::adFlagsToString(uint8_t adFlags) {
std::stringstream ss;
std::string res;
if (adFlags & (1 << 0)) {
ss << "[LE Limited Discoverable Mode] ";
res += "[LE Limited Discoverable Mode] ";
}
if (adFlags & (1 << 1)) {
ss << "[LE General Discoverable Mode] ";
res += "[LE General Discoverable Mode] ";
}
if (adFlags & (1 << 2)) {
ss << "[BR/EDR Not Supported] ";
res += "[BR/EDR Not Supported] ";
}
if (adFlags & (1 << 3)) {
ss << "[Simultaneous LE and BR/EDR to Same Device Capable (Controller)] ";
res += "[Simultaneous LE and BR/EDR to Same Device Capable (Controller)] ";
}
if (adFlags & (1 << 4)) {
ss << "[Simultaneous LE and BR/EDR to Same Device Capable (Host)] ";
res += "[Simultaneous LE and BR/EDR to Same Device Capable (Host)] ";
}
return ss.str();
return res;
} // adFlagsToString
@ -744,7 +743,7 @@ const char* BLEUtils::advTypeToString(uint8_t advType) {
return "ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE";
#endif
default:
ESP_LOGV(LOG_TAG, " adv data type: 0x%x", advType);
log_v(" adv data type: 0x%x", advType);
return "";
} // End switch
} // advTypeToString
@ -779,7 +778,7 @@ char* BLEUtils::buildHexData(uint8_t* target, uint8_t* source, uint8_t length) {
if (target == nullptr) {
target = (uint8_t*) malloc(length * 2 + 1);
if (target == nullptr) {
ESP_LOGE(LOG_TAG, "buildHexData: malloc failed");
log_e("buildHexData: malloc failed");
return nullptr;
}
}
@ -809,13 +808,13 @@ char* BLEUtils::buildHexData(uint8_t* target, uint8_t* source, uint8_t length) {
* @return A string representation of a piece of memory.
*/
std::string BLEUtils::buildPrintData(uint8_t* source, size_t length) {
std::ostringstream ss;
std::string res;
for (int i = 0; i < length; i++) {
char c = *source;
ss << (isprint(c) ? c : '.');
res += (isprint(c) ? c : '.');
source++;
}
return ss.str();
return res;
} // buildPrintData
@ -949,7 +948,7 @@ std::string BLEUtils::gattClientEventTypeToString(esp_gattc_cb_event_t eventType
return "ESP_GATTC_WRITE_DESCR_EVT";
#endif
default:
ESP_LOGV(LOG_TAG, "Unknown GATT Client event type: %d", eventType);
log_v("Unknown GATT Client event type: %d", eventType);
return "Unknown";
}
} // gattClientEventTypeToString
@ -1047,14 +1046,14 @@ const char* BLEUtils::devTypeToString(esp_bt_dev_type_t type) {
void BLEUtils::dumpGapEvent(
esp_gap_ble_cb_event_t event,
esp_ble_gap_cb_param_t* param) {
ESP_LOGV(LOG_TAG, "Received a GAP event: %s", gapEventToString(event));
log_v("Received a GAP event: %s", gapEventToString(event));
switch (event) {
#if CONFIG_LOG_DEFAULT_LEVEL > 4
// ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
// adv_data_cmpl
// - esp_bt_status_t
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->adv_data_cmpl.status);
log_v("[status: %d]", param->adv_data_cmpl.status);
break;
} // ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
@ -1063,7 +1062,7 @@ void BLEUtils::dumpGapEvent(
// adv_data_raw_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->adv_data_raw_cmpl.status);
log_v("[status: %d]", param->adv_data_raw_cmpl.status);
break;
} // ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT
@ -1072,7 +1071,7 @@ void BLEUtils::dumpGapEvent(
// adv_start_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->adv_start_cmpl.status);
log_v("[status: %d]", param->adv_start_cmpl.status);
break;
} // ESP_GAP_BLE_ADV_START_COMPLETE_EVT
@ -1081,7 +1080,7 @@ void BLEUtils::dumpGapEvent(
// adv_stop_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->adv_stop_cmpl.status);
log_v("[status: %d]", param->adv_stop_cmpl.status);
break;
} // ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT
@ -1096,7 +1095,7 @@ void BLEUtils::dumpGapEvent(
// - esp_bd_addr_type_t addr_type
// - esp_bt_dev_type_t dev_type
case ESP_GAP_BLE_AUTH_CMPL_EVT: {
ESP_LOGV(LOG_TAG, "[bd_addr: %s, key_present: %d, key: ***, key_type: %d, success: %d, fail_reason: %d, addr_type: ***, dev_type: %s]",
log_v("[bd_addr: %s, key_present: %d, key: ***, key_type: %d, success: %d, fail_reason: %d, addr_type: ***, dev_type: %s]",
BLEAddress(param->ble_security.auth_cmpl.bd_addr).toString().c_str(),
param->ble_security.auth_cmpl.key_present,
param->ble_security.auth_cmpl.key_type,
@ -1112,7 +1111,7 @@ void BLEUtils::dumpGapEvent(
// clear_bond_dev_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->clear_bond_dev_cmpl.status);
log_v("[status: %d]", param->clear_bond_dev_cmpl.status);
break;
} // ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT
@ -1128,7 +1127,7 @@ void BLEUtils::dumpGapEvent(
// ESP_GAP_BLE_NC_REQ_EVT
case ESP_GAP_BLE_NC_REQ_EVT: {
ESP_LOGV(LOG_TAG, "[bd_addr: %s, passkey: %d]",
log_v("[bd_addr: %s, passkey: %d]",
BLEAddress(param->ble_security.key_notif.bd_addr).toString().c_str(),
param->ble_security.key_notif.passkey);
break;
@ -1141,7 +1140,7 @@ void BLEUtils::dumpGapEvent(
// - int8_t rssi
// - esp_bd_addr_t remote_addr
case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d, rssi: %d, remote_addr: %s]",
log_v("[status: %d, rssi: %d, remote_addr: %s]",
param->read_rssi_cmpl.status,
param->read_rssi_cmpl.rssi,
BLEAddress(param->read_rssi_cmpl.remote_addr).toString().c_str()
@ -1154,7 +1153,7 @@ void BLEUtils::dumpGapEvent(
// scan_param_cmpl.
// - esp_bt_status_t status
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->scan_param_cmpl.status);
log_v("[status: %d]", param->scan_param_cmpl.status);
break;
} // ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT
@ -1175,7 +1174,7 @@ void BLEUtils::dumpGapEvent(
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
switch (param->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT: {
ESP_LOGV(LOG_TAG, "search_evt: %s, bda: %s, dev_type: %s, ble_addr_type: %s, ble_evt_type: %s, rssi: %d, ble_adv: ??, flag: %d (%s), num_resps: %d, adv_data_len: %d, scan_rsp_len: %d",
log_v("search_evt: %s, bda: %s, dev_type: %s, ble_addr_type: %s, ble_evt_type: %s, rssi: %d, ble_adv: ??, flag: %d (%s), num_resps: %d, adv_data_len: %d, scan_rsp_len: %d",
searchEventTypeToString(param->scan_rst.search_evt),
BLEAddress(param->scan_rst.bda).toString().c_str(),
devTypeToString(param->scan_rst.dev_type),
@ -1192,7 +1191,7 @@ void BLEUtils::dumpGapEvent(
} // ESP_GAP_SEARCH_INQ_RES_EVT
default: {
ESP_LOGV(LOG_TAG, "search_evt: %s",searchEventTypeToString(param->scan_rst.search_evt));
log_v("search_evt: %s",searchEventTypeToString(param->scan_rst.search_evt));
break;
}
}
@ -1204,13 +1203,13 @@ void BLEUtils::dumpGapEvent(
// scan_rsp_data_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->scan_rsp_data_cmpl.status);
log_v("[status: %d]", param->scan_rsp_data_cmpl.status);
break;
} // ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
// ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->scan_rsp_data_raw_cmpl.status);
log_v("[status: %d]", param->scan_rsp_data_raw_cmpl.status);
break;
} // ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT
@ -1219,7 +1218,7 @@ void BLEUtils::dumpGapEvent(
// scan_start_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->scan_start_cmpl.status);
log_v("[status: %d]", param->scan_start_cmpl.status);
break;
} // ESP_GAP_BLE_SCAN_START_COMPLETE_EVT
@ -1228,7 +1227,7 @@ void BLEUtils::dumpGapEvent(
// scan_stop_cmpl
// - esp_bt_status_t status
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d]", param->scan_stop_cmpl.status);
log_v("[status: %d]", param->scan_stop_cmpl.status);
break;
} // ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT
@ -1243,7 +1242,7 @@ void BLEUtils::dumpGapEvent(
// - uint16_t conn_int
// - uint16_t timeout
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: {
ESP_LOGV(LOG_TAG, "[status: %d, bd_addr: %s, min_int: %d, max_int: %d, latency: %d, conn_int: %d, timeout: %d]",
log_v("[status: %d, bd_addr: %s, min_int: %d, max_int: %d, latency: %d, conn_int: %d, timeout: %d]",
param->update_conn_params.status,
BLEAddress(param->update_conn_params.bda).toString().c_str(),
param->update_conn_params.min_int,
@ -1257,12 +1256,12 @@ void BLEUtils::dumpGapEvent(
// ESP_GAP_BLE_SEC_REQ_EVT
case ESP_GAP_BLE_SEC_REQ_EVT: {
ESP_LOGV(LOG_TAG, "[bd_addr: %s]", BLEAddress(param->ble_security.ble_req.bd_addr).toString().c_str());
log_v("[bd_addr: %s]", BLEAddress(param->ble_security.ble_req.bd_addr).toString().c_str());
break;
} // ESP_GAP_BLE_SEC_REQ_EVT
#endif
default: {
ESP_LOGV(LOG_TAG, "*** dumpGapEvent: Logger not coded ***");
log_v("*** dumpGapEvent: Logger not coded ***");
break;
} // default
} // switch
@ -1281,7 +1280,7 @@ void BLEUtils::dumpGattClientEvent(
esp_ble_gattc_cb_param_t* evtParam) {
//esp_ble_gattc_cb_param_t* evtParam = (esp_ble_gattc_cb_param_t*) param;
ESP_LOGV(LOG_TAG, "GATT Event: %s", BLEUtils::gattClientEventTypeToString(event).c_str());
log_v("GATT Event: %s", BLEUtils::gattClientEventTypeToString(event).c_str());
switch (event) {
#if CONFIG_LOG_DEFAULT_LEVEL > 4
// ESP_GATTC_CLOSE_EVT
@ -1292,7 +1291,7 @@ void BLEUtils::dumpGattClientEvent(
// - esp_bd_addr_t remote_bda
// - esp_gatt_conn_reason_t reason
case ESP_GATTC_CLOSE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, reason:%s, conn_id: %d]",
log_v("[status: %s, reason:%s, conn_id: %d]",
BLEUtils::gattStatusToString(evtParam->close.status).c_str(),
BLEUtils::gattCloseReasonToString(evtParam->close.reason).c_str(),
evtParam->close.conn_id);
@ -1306,7 +1305,7 @@ void BLEUtils::dumpGattClientEvent(
// - uint16_t conn_id
// - esp_bd_addr_t remote_bda
case ESP_GATTC_CONNECT_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, remote_bda: %s]",
log_v("[conn_id: %d, remote_bda: %s]",
evtParam->connect.conn_id,
BLEAddress(evtParam->connect.remote_bda).toString().c_str()
);
@ -1320,7 +1319,7 @@ void BLEUtils::dumpGattClientEvent(
// - uint16_t conn_id
// - esp_bd_addr_t remote_bda
case ESP_GATTC_DISCONNECT_EVT: {
ESP_LOGV(LOG_TAG, "[reason: %s, conn_id: %d, remote_bda: %s]",
log_v("[reason: %s, conn_id: %d, remote_bda: %s]",
BLEUtils::gattCloseReasonToString(evtParam->disconnect.reason).c_str(),
evtParam->disconnect.conn_id,
BLEAddress(evtParam->disconnect.remote_bda).toString().c_str()
@ -1346,7 +1345,7 @@ void BLEUtils::dumpGattClientEvent(
if (evtParam->get_char.char_id.uuid.len == ESP_UUID_LEN_16) {
description = BLEUtils::gattCharacteristicUUIDToString(evtParam->get_char.char_id.uuid.uuid.uuid16);
}
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: %d, srvc_id: %s, char_id: %s [description: %s]\nchar_prop: %s]",
log_v("[status: %s, conn_id: %d, srvc_id: %s, char_id: %s [description: %s]\nchar_prop: %s]",
BLEUtils::gattStatusToString(evtParam->get_char.status).c_str(),
evtParam->get_char.conn_id,
BLEUtils::gattServiceIdToString(evtParam->get_char.srvc_id).c_str(),
@ -1355,7 +1354,7 @@ void BLEUtils::dumpGattClientEvent(
BLEUtils::characteristicPropertiesToString(evtParam->get_char.char_prop).c_str()
);
} else {
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: %d, srvc_id: %s]",
log_v("[status: %s, conn_id: %d, srvc_id: %s]",
BLEUtils::gattStatusToString(evtParam->get_char.status).c_str(),
evtParam->get_char.conn_id,
BLEUtils::gattServiceIdToString(evtParam->get_char.srvc_id).c_str()
@ -1376,7 +1375,7 @@ void BLEUtils::dumpGattClientEvent(
// bool is_notify
//
case ESP_GATTC_NOTIFY_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, remote_bda: %s, handle: %d 0x%.2x, value_len: %d, is_notify: %d]",
log_v("[conn_id: %d, remote_bda: %s, handle: %d 0x%.2x, value_len: %d, is_notify: %d]",
evtParam->notify.conn_id,
BLEAddress(evtParam->notify.remote_bda).toString().c_str(),
evtParam->notify.handle,
@ -1396,7 +1395,7 @@ void BLEUtils::dumpGattClientEvent(
// - uint16_t mtu
//
case ESP_GATTC_OPEN_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: %d, remote_bda: %s, mtu: %d]",
log_v("[status: %s, conn_id: %d, remote_bda: %s, mtu: %d]",
BLEUtils::gattStatusToString(evtParam->open.status).c_str(),
evtParam->open.conn_id,
BLEAddress(evtParam->open.remote_bda).toString().c_str(),
@ -1416,7 +1415,7 @@ void BLEUtils::dumpGattClientEvent(
// uint16_t value_type
// uint16_t value_len
case ESP_GATTC_READ_CHAR_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: %d, handle: %d 0x%.2x, value_len: %d]",
log_v("[status: %s, conn_id: %d, handle: %d 0x%.2x, value_len: %d]",
BLEUtils::gattStatusToString(evtParam->read.status).c_str(),
evtParam->read.conn_id,
evtParam->read.handle,
@ -1427,7 +1426,7 @@ void BLEUtils::dumpGattClientEvent(
GeneralUtils::hexDump(evtParam->read.value, evtParam->read.value_len);
/*
char* pHexData = BLEUtils::buildHexData(nullptr, evtParam->read.value, evtParam->read.value_len);
ESP_LOGV(LOG_TAG, "value: %s \"%s\"", pHexData, BLEUtils::buildPrintData(evtParam->read.value, evtParam->read.value_len).c_str());
log_v("value: %s \"%s\"", pHexData, BLEUtils::buildPrintData(evtParam->read.value, evtParam->read.value_len).c_str());
free(pHexData);
*/
}
@ -1440,7 +1439,7 @@ void BLEUtils::dumpGattClientEvent(
// - esp_gatt_status_t status
// - uint16_t app_id
case ESP_GATTC_REG_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, app_id: 0x%x]",
log_v("[status: %s, app_id: 0x%x]",
BLEUtils::gattStatusToString(evtParam->reg.status).c_str(),
evtParam->reg.app_id);
break;
@ -1452,7 +1451,7 @@ void BLEUtils::dumpGattClientEvent(
// - esp_gatt_status_t status
// - uint16_t handle
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, handle: %d 0x%.2x]",
log_v("[status: %s, handle: %d 0x%.2x]",
BLEUtils::gattStatusToString(evtParam->reg_for_notify.status).c_str(),
evtParam->reg_for_notify.handle,
evtParam->reg_for_notify.handle
@ -1466,7 +1465,7 @@ void BLEUtils::dumpGattClientEvent(
// - esp_gatt_status_t status
// - uint16_t conn_id
case ESP_GATTC_SEARCH_CMPL_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: %d]",
log_v("[status: %s, conn_id: %d]",
BLEUtils::gattStatusToString(evtParam->search_cmpl.status).c_str(),
evtParam->search_cmpl.conn_id);
break;
@ -1480,7 +1479,7 @@ void BLEUtils::dumpGattClientEvent(
// - uint16_t end_handle
// - esp_gatt_id_t srvc_id
case ESP_GATTC_SEARCH_RES_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, start_handle: %d 0x%.2x, end_handle: %d 0x%.2x, srvc_id: %s",
log_v("[conn_id: %d, start_handle: %d 0x%.2x, end_handle: %d 0x%.2x, srvc_id: %s",
evtParam->search_res.conn_id,
evtParam->search_res.start_handle,
evtParam->search_res.start_handle,
@ -1498,7 +1497,7 @@ void BLEUtils::dumpGattClientEvent(
// - uint16_t handle
// - uint16_t offset
case ESP_GATTC_WRITE_CHAR_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: %d, handle: %d 0x%.2x, offset: %d]",
log_v("[status: %s, conn_id: %d, handle: %d 0x%.2x, offset: %d]",
BLEUtils::gattStatusToString(evtParam->write.status).c_str(),
evtParam->write.conn_id,
evtParam->write.handle,
@ -1528,12 +1527,12 @@ void BLEUtils::dumpGattServerEvent(
esp_gatts_cb_event_t event,
esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t* evtParam) {
ESP_LOGV(LOG_TAG, "GATT ServerEvent: %s", BLEUtils::gattServerEventTypeToString(event).c_str());
log_v("GATT ServerEvent: %s", BLEUtils::gattServerEventTypeToString(event).c_str());
switch (event) {
#if CONFIG_LOG_DEFAULT_LEVEL > 4
case ESP_GATTS_ADD_CHAR_DESCR_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, attr_handle: %d 0x%.2x, service_handle: %d 0x%.2x, char_uuid: %s]",
log_v("[status: %s, attr_handle: %d 0x%.2x, service_handle: %d 0x%.2x, char_uuid: %s]",
gattStatusToString(evtParam->add_char_descr.status).c_str(),
evtParam->add_char_descr.attr_handle,
evtParam->add_char_descr.attr_handle,
@ -1545,7 +1544,7 @@ void BLEUtils::dumpGattServerEvent(
case ESP_GATTS_ADD_CHAR_EVT: {
if (evtParam->add_char.status == ESP_GATT_OK) {
ESP_LOGV(LOG_TAG, "[status: %s, attr_handle: %d 0x%.2x, service_handle: %d 0x%.2x, char_uuid: %s]",
log_v("[status: %s, attr_handle: %d 0x%.2x, service_handle: %d 0x%.2x, char_uuid: %s]",
gattStatusToString(evtParam->add_char.status).c_str(),
evtParam->add_char.attr_handle,
evtParam->add_char.attr_handle,
@ -1553,7 +1552,7 @@ void BLEUtils::dumpGattServerEvent(
evtParam->add_char.service_handle,
BLEUUID(evtParam->add_char.char_uuid).toString().c_str());
} else {
ESP_LOGE(LOG_TAG, "[status: %s, attr_handle: %d 0x%.2x, service_handle: %d 0x%.2x, char_uuid: %s]",
log_e("[status: %s, attr_handle: %d 0x%.2x, service_handle: %d 0x%.2x, char_uuid: %s]",
gattStatusToString(evtParam->add_char.status).c_str(),
evtParam->add_char.attr_handle,
evtParam->add_char.attr_handle,
@ -1571,7 +1570,7 @@ void BLEUtils::dumpGattServerEvent(
// - esp_gatt_status_t status The status code.
// - uint16_t conn_id The connection used.
case ESP_GATTS_CONF_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, conn_id: 0x%.2x]",
log_v("[status: %s, conn_id: 0x%.2x]",
gattStatusToString(evtParam->conf.status).c_str(),
evtParam->conf.conn_id);
break;
@ -1579,21 +1578,21 @@ void BLEUtils::dumpGattServerEvent(
case ESP_GATTS_CONGEST_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, congested: %d]",
log_v("[conn_id: %d, congested: %d]",
evtParam->congest.conn_id,
evtParam->congest.congested);
break;
} // ESP_GATTS_CONGEST_EVT
case ESP_GATTS_CONNECT_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, remote_bda: %s]",
log_v("[conn_id: %d, remote_bda: %s]",
evtParam->connect.conn_id,
BLEAddress(evtParam->connect.remote_bda).toString().c_str());
break;
} // ESP_GATTS_CONNECT_EVT
case ESP_GATTS_CREATE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, service_handle: %d 0x%.2x, service_id: [%s]]",
log_v("[status: %s, service_handle: %d 0x%.2x, service_id: [%s]]",
gattStatusToString(evtParam->create.status).c_str(),
evtParam->create.service_handle,
evtParam->create.service_handle,
@ -1602,7 +1601,7 @@ void BLEUtils::dumpGattServerEvent(
} // ESP_GATTS_CREATE_EVT
case ESP_GATTS_DISCONNECT_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, remote_bda: %s]",
log_v("[conn_id: %d, remote_bda: %s]",
evtParam->connect.conn_id,
BLEAddress(evtParam->connect.remote_bda).toString().c_str());
break;
@ -1633,7 +1632,7 @@ void BLEUtils::dumpGattServerEvent(
break;
}
ESP_LOGV(LOG_TAG, "[conn_id: %d, trans_id: %d, bda: %s, exec_write_flag: 0x%.2x=%s]",
log_v("[conn_id: %d, trans_id: %d, bda: %s, exec_write_flag: 0x%.2x=%s]",
evtParam->exec_write.conn_id,
evtParam->exec_write.trans_id,
BLEAddress(evtParam->exec_write.bda).toString().c_str(),
@ -1644,14 +1643,14 @@ void BLEUtils::dumpGattServerEvent(
case ESP_GATTS_MTU_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, mtu: %d]",
log_v("[conn_id: %d, mtu: %d]",
evtParam->mtu.conn_id,
evtParam->mtu.mtu);
break;
} // ESP_GATTS_MTU_EVT
case ESP_GATTS_READ_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, trans_id: %d, bda: %s, handle: 0x%.2x, is_long: %d, need_rsp:%d]",
log_v("[conn_id: %d, trans_id: %d, bda: %s, handle: 0x%.2x, is_long: %d, need_rsp:%d]",
evtParam->read.conn_id,
evtParam->read.trans_id,
BLEAddress(evtParam->read.bda).toString().c_str(),
@ -1662,14 +1661,14 @@ void BLEUtils::dumpGattServerEvent(
} // ESP_GATTS_READ_EVT
case ESP_GATTS_RESPONSE_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, handle: 0x%.2x]",
log_v("[status: %s, handle: 0x%.2x]",
gattStatusToString(evtParam->rsp.status).c_str(),
evtParam->rsp.handle);
break;
} // ESP_GATTS_RESPONSE_EVT
case ESP_GATTS_REG_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, app_id: %d]",
log_v("[status: %s, app_id: %d]",
gattStatusToString(evtParam->reg.status).c_str(),
evtParam->reg.app_id);
break;
@ -1682,7 +1681,7 @@ void BLEUtils::dumpGattServerEvent(
// - esp_gatt_status_t status
// - uint16_t service_handle
case ESP_GATTS_START_EVT: {
ESP_LOGV(LOG_TAG, "[status: %s, service_handle: 0x%.2x]",
log_v("[status: %s, service_handle: 0x%.2x]",
gattStatusToString(evtParam->start.status).c_str(),
evtParam->start.service_handle);
break;
@ -1702,7 +1701,7 @@ void BLEUtils::dumpGattServerEvent(
// - uint16_t len The length of the incoming value part.
// - uint8_t* value The data for this value part.
case ESP_GATTS_WRITE_EVT: {
ESP_LOGV(LOG_TAG, "[conn_id: %d, trans_id: %d, bda: %s, handle: 0x%.2x, offset: %d, need_rsp: %d, is_prep: %d, len: %d]",
log_v("[conn_id: %d, trans_id: %d, bda: %s, handle: 0x%.2x, offset: %d, need_rsp: %d, is_prep: %d, len: %d]",
evtParam->write.conn_id,
evtParam->write.trans_id,
BLEAddress(evtParam->write.bda).toString().c_str(),
@ -1712,13 +1711,13 @@ void BLEUtils::dumpGattServerEvent(
evtParam->write.is_prep,
evtParam->write.len);
char* pHex = buildHexData(nullptr, evtParam->write.value, evtParam->write.len);
ESP_LOGV(LOG_TAG, "[Data: %s]", pHex);
log_v("[Data: %s]", pHex);
free(pHex);
break;
} // ESP_GATTS_WRITE_EVT
#endif
default:
ESP_LOGV(LOG_TAG, "dumpGattServerEvent: *** NOT CODED ***");
log_v("dumpGattServerEvent: *** NOT CODED ***");
break;
}
} // dumpGattServerEvent
@ -1744,7 +1743,7 @@ const char* BLEUtils::eventTypeToString(esp_ble_evt_type_t eventType) {
return "ESP_BLE_EVT_SCAN_RSP";
#endif
default:
ESP_LOGV(LOG_TAG, "Unknown esp_ble_evt_type_t: %d (0x%.2x)", eventType, eventType);
log_v("Unknown esp_ble_evt_type_t: %d (0x%.2x)", eventType, eventType);
return "*** Unknown ***";
}
} // eventTypeToString
@ -1815,7 +1814,7 @@ const char* BLEUtils::gapEventToString(uint32_t eventType) {
return "ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT";
#endif
default:
ESP_LOGV(LOG_TAG, "gapEventToString: Unknown event type %d 0x%.2x", eventType, eventType);
log_v("gapEventToString: Unknown event type %d 0x%.2x", eventType, eventType);
return "Unknown event type";
}
} // gapEventToString
@ -1855,14 +1854,22 @@ std::string BLEUtils::gattDescriptorUUIDToString(uint32_t descriptorUUID) {
* @return A string representation of an esp_gattc_service_elem_t.
*/
std::string BLEUtils::gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement) {
std::stringstream ss;
ss << "[uuid: " << BLEUUID(pGATTCServiceElement->uuid).toString() <<
", start_handle: " << pGATTCServiceElement->start_handle <<
" 0x" << std::hex << pGATTCServiceElement->start_handle <<
", end_handle: " << std::dec << pGATTCServiceElement->end_handle <<
" 0x" << std::hex << pGATTCServiceElement->end_handle << "]";
return ss.str();
std::string res;
char val[6];
res += "[uuid: " + BLEUUID(pGATTCServiceElement->uuid).toString() + ", start_handle: ";
snprintf(val, sizeof(val), "%d", pGATTCServiceElement->start_handle);
res += val;
res += " 0x";
snprintf(val, sizeof(val), "%04x", pGATTCServiceElement->start_handle);
res += val;
res += ", end_handle: ";
snprintf(val, sizeof(val), "%d", pGATTCServiceElement->end_handle);
res += val;
res += " 0x";
snprintf(val, sizeof(val), "%04x", pGATTCServiceElement->end_handle);
res += val;
res += "]";
return res;
} // gattcServiceElementToString
@ -2025,7 +2032,7 @@ const char* BLEUtils::searchEventTypeToString(esp_gap_search_evt_t searchEvt) {
return "ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT";
#endif
default:
ESP_LOGV(LOG_TAG, "Unknown event type: 0x%x", searchEvt);
log_v("Unknown event type: 0x%x", searchEvt);
return "Unknown event type";
}
} // searchEventTypeToString

View File

@ -7,16 +7,7 @@
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include "BLEValue.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG="BLEValue";
#endif
BLEValue::BLEValue() {
m_accumulation = "";
@ -31,7 +22,7 @@ BLEValue::BLEValue() {
* @param [in] part A message part being added.
*/
void BLEValue::addPart(std::string part) {
ESP_LOGD(LOG_TAG, ">> addPart: length=%d", part.length());
log_v(">> addPart: length=%d", part.length());
m_accumulation += part;
} // addPart
@ -43,7 +34,7 @@ void BLEValue::addPart(std::string part) {
* @param [in] length The number of bytes being added.
*/
void BLEValue::addPart(uint8_t* pData, size_t length) {
ESP_LOGD(LOG_TAG, ">> addPart: length=%d", length);
log_v(">> addPart: length=%d", length);
m_accumulation += std::string((char*) pData, length);
} // addPart
@ -52,7 +43,7 @@ void BLEValue::addPart(uint8_t* pData, size_t length) {
* @brief Cancel the current accumulation.
*/
void BLEValue::cancel() {
ESP_LOGD(LOG_TAG, ">> cancel");
log_v(">> cancel");
m_accumulation = "";
m_readOffset = 0;
} // cancel
@ -65,7 +56,7 @@ void BLEValue::cancel() {
* we now have the complete message and commit the change as a unit.
*/
void BLEValue::commit() {
ESP_LOGD(LOG_TAG, ">> commit");
log_v(">> commit");
// If there is nothing to commit, do nothing.
if (m_accumulation.length() == 0) return;
setValue(m_accumulation);

View File

@ -12,14 +12,7 @@
#include <iomanip>
#include "FreeRTOS.h"
#include "sdkconfig.h"
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "FreeRTOS";
#endif
/**
* Sleep for the specified number of milliseconds.
@ -67,34 +60,64 @@ uint32_t FreeRTOS::getTimeSinceStart() {
* @return The value associated with the semaphore.
*/
uint32_t FreeRTOS::Semaphore::wait(std::string owner) {
ESP_LOGV(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
log_v(">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
if (m_usePthreads) {
pthread_mutex_lock(&m_pthread_mutex);
} else {
xSemaphoreTake(m_semaphore, portMAX_DELAY);
}
m_owner = owner;
if (m_usePthreads) {
pthread_mutex_unlock(&m_pthread_mutex);
} else {
xSemaphoreGive(m_semaphore);
}
ESP_LOGV(LOG_TAG, "<< wait: Semaphore released: %s", toString().c_str());
m_owner = std::string("<N/A>");
log_v("<< wait: Semaphore released: %s", toString().c_str());
return m_value;
} // wait
/**
* @brief Wait for a semaphore to be released in a given period of time by trying to take it and
* then releasing it again. The value associated with the semaphore can be taken by value() call after return
* @param [in] owner A debug tag.
* @param [in] timeoutMs timeout to wait in ms.
* @return True if we took the semaphore within timeframe.
*/
bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) {
log_v(">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
if (m_usePthreads && timeoutMs != portMAX_DELAY) {
assert(false); // We apparently don't have a timed wait for pthreads.
}
auto ret = pdTRUE;
if (m_usePthreads) {
pthread_mutex_lock(&m_pthread_mutex);
} else {
ret = xSemaphoreTake(m_semaphore, timeoutMs);
}
if (m_usePthreads) {
pthread_mutex_unlock(&m_pthread_mutex);
} else {
xSemaphoreGive(m_semaphore);
}
log_v("<< wait: Semaphore %s released: %d", toString().c_str(), ret);
return ret;
} // wait
FreeRTOS::Semaphore::Semaphore(std::string name) {
m_usePthreads = false; // Are we using pThreads or FreeRTOS?
if (m_usePthreads) {
pthread_mutex_init(&m_pthread_mutex, nullptr);
} else {
m_semaphore = xSemaphoreCreateMutex();
m_semaphore = xSemaphoreCreateBinary();
xSemaphoreGive(m_semaphore);
}
m_name = name;
@ -117,7 +140,9 @@ FreeRTOS::Semaphore::~Semaphore() {
* The Semaphore is given.
*/
void FreeRTOS::Semaphore::give() {
ESP_LOGV(LOG_TAG, "Semaphore giving: %s", toString().c_str());
log_v("Semaphore giving: %s", toString().c_str());
m_owner = std::string("<N/A>");
if (m_usePthreads) {
pthread_mutex_unlock(&m_pthread_mutex);
} else {
@ -127,7 +152,6 @@ void FreeRTOS::Semaphore::give() {
// FreeRTOS::sleep(10);
// #endif
m_owner = std::string("<N/A>");
} // Semaphore::give
@ -162,7 +186,7 @@ void FreeRTOS::Semaphore::giveFromISR() {
* @return True if we took the semaphore.
*/
bool FreeRTOS::Semaphore::take(std::string owner) {
ESP_LOGD(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str());
log_d("Semaphore taking: %s for %s", toString().c_str(), owner.c_str());
bool rc = false;
if (m_usePthreads) {
pthread_mutex_lock(&m_pthread_mutex);
@ -171,9 +195,9 @@ bool FreeRTOS::Semaphore::take(std::string owner) {
}
m_owner = owner;
if (rc) {
ESP_LOGD(LOG_TAG, "Semaphore taken: %s", toString().c_str());
log_d("Semaphore taken: %s", toString().c_str());
} else {
ESP_LOGE(LOG_TAG, "Semaphore NOT taken: %s", toString().c_str());
log_e("Semaphore NOT taken: %s", toString().c_str());
}
return rc;
} // Semaphore::take
@ -187,7 +211,7 @@ bool FreeRTOS::Semaphore::take(std::string owner) {
* @return True if we took the semaphore.
*/
bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) {
ESP_LOGV(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str());
log_v("Semaphore taking: %s for %s", toString().c_str(), owner.c_str());
bool rc = false;
if (m_usePthreads) {
assert(false); // We apparently don't have a timed wait for pthreads.
@ -196,9 +220,9 @@ bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) {
}
m_owner = owner;
if (rc) {
ESP_LOGV(LOG_TAG, "Semaphore taken: %s", toString().c_str());
log_v("Semaphore taken: %s", toString().c_str());
} else {
ESP_LOGE(LOG_TAG, "Semaphore NOT taken: %s", toString().c_str());
log_e("Semaphore NOT taken: %s", toString().c_str());
}
return rc;
} // Semaphore::take
@ -210,9 +234,12 @@ bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) {
* @return A string representation of the semaphore.
*/
std::string FreeRTOS::Semaphore::toString() {
std::stringstream stringStream;
stringStream << "name: "<< m_name << " (0x" << std::hex << std::setfill('0') << (uint32_t)m_semaphore << "), owner: " << m_owner;
return stringStream.str();
char hex[9];
std::string res = "name: " + m_name + " (0x";
snprintf(hex, sizeof(hex), "%08x", (uint32_t)m_semaphore);
res += hex;
res += "), owner: " + m_owner;
return res;
} // toString

View File

@ -40,6 +40,8 @@ public:
bool take(uint32_t timeoutMs, std::string owner = "<Unknown>");
std::string toString();
uint32_t wait(std::string owner = "<Unknown>");
bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY);
uint32_t value(){ return m_value; };
private:
SemaphoreHandle_t m_semaphore;

View File

@ -18,15 +18,7 @@
#include <esp_wifi.h>
#include <esp_heap_caps.h>
#include <esp_system.h>
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "GeneralUtils";
#endif
static const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
@ -112,14 +104,13 @@ bool GeneralUtils::base64Encode(const std::string& in, std::string* out) {
* * Amount of free RAM
*/
void GeneralUtils::dumpInfo() {
size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_8BIT);
esp_chip_info_t chipInfo;
esp_chip_info(&chipInfo);
ESP_LOGV(LOG_TAG, "--- dumpInfo ---");
ESP_LOGV(LOG_TAG, "Free heap: %d", freeHeap);
ESP_LOGV(LOG_TAG, "Chip Info: Model: %d, cores: %d, revision: %d", chipInfo.model, chipInfo.cores, chipInfo.revision);
ESP_LOGV(LOG_TAG, "ESP-IDF version: %s", esp_get_idf_version());
ESP_LOGV(LOG_TAG, "---");
log_v("--- dumpInfo ---");
log_v("Free heap: %d", heap_caps_get_free_size(MALLOC_CAP_8BIT));
log_v("Chip Info: Model: %d, cores: %d, revision: %d", chipInfo.model, chipInfo.cores, chipInfo.revision);
log_v("ESP-IDF version: %s", esp_get_idf_version());
log_v("---");
} // dumpInfo
@ -237,7 +228,7 @@ void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) {
if (index % 16 == 0) {
strcpy(hexBuf, hex.str().c_str());
strcpy(asciiBuf, ascii.str().c_str());
ESP_LOGV(tag, "%s %s", hexBuf, asciiBuf);
log_v("%s %s", hexBuf, asciiBuf);
hex.str("");
ascii.str("");
}
@ -249,8 +240,8 @@ void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) {
}
strcpy(hexBuf, hex.str().c_str());
strcpy(asciiBuf, ascii.str().c_str());
ESP_LOGV(tag, "%s %s", hexBuf, asciiBuf);
//ESP_LOGV(tag, "%s %s", hex.str().c_str(), ascii.str().c_str());
log_v("%s %s", hexBuf, asciiBuf);
//log_v("%s %s", hex.str().c_str(), ascii.str().c_str());
}
FreeRTOS::sleep(1000);
}
@ -272,7 +263,7 @@ void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) {
}
index++;
if (index % 16 == 0) {
ESP_LOGV(tag, "%s %s", hex.str().c_str(), ascii.str().c_str());
log_v("%s %s", hex.str().c_str(), ascii.str().c_str());
hex.str("");
ascii.str("");
}
@ -282,7 +273,7 @@ void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) {
hex << " ";
index++;
}
ESP_LOGV(tag, "%s %s", hex.str().c_str(), ascii.str().c_str());
log_v("%s %s", hex.str().c_str(), ascii.str().c_str());
}
FreeRTOS::sleep(1000);
}
@ -302,8 +293,8 @@ void GeneralUtils::hexDump(const uint8_t* pData, uint32_t length) {
char tempBuf[80];
uint32_t lineNumber = 0;
ESP_LOGV(LOG_TAG, " 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f");
ESP_LOGV(LOG_TAG, " -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
log_v(" 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f");
log_v(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
strcpy(ascii, "");
strcpy(hex, "");
uint32_t index = 0;
@ -318,7 +309,7 @@ void GeneralUtils::hexDump(const uint8_t* pData, uint32_t length) {
strcat(ascii, tempBuf);
index++;
if (index % 16 == 0) {
ESP_LOGV(LOG_TAG, "%.4x %s %s", lineNumber * 16, hex, ascii);
log_v("%.4x %s %s", lineNumber * 16, hex, ascii);
strcpy(ascii, "");
strcpy(hex, "");
lineNumber++;
@ -329,7 +320,7 @@ void GeneralUtils::hexDump(const uint8_t* pData, uint32_t length) {
strcat(hex, " ");
index++;
}
ESP_LOGV(LOG_TAG, "%.4x %s %s", lineNumber * 16, hex, ascii);
log_v("%.4x %s %s", lineNumber * 16, hex, ascii);
}
} // hexDump
@ -340,9 +331,12 @@ void GeneralUtils::hexDump(const uint8_t* pData, uint32_t length) {
* @return A string representation of the IP address.
*/
std::string GeneralUtils::ipToString(uint8_t *ip) {
std::stringstream s;
s << (int) ip[0] << '.' << (int) ip[1] << '.' << (int) ip[2] << '.' << (int) ip[3];
return s.str();
auto size = 16;
char *val = (char*)malloc(size);
snprintf(val, size, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
std::string res(val);
free(val);
return res;
} // ipToString
@ -355,11 +349,14 @@ std::string GeneralUtils::ipToString(uint8_t *ip) {
std::vector<std::string> GeneralUtils::split(std::string source, char delimiter) {
// See also: https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g
std::vector<std::string> strings;
std::istringstream iss(source);
std::string s;
while (std::getline(iss, s, delimiter)) {
strings.push_back(trim(s));
std::size_t current, previous = 0;
current = source.find(delimiter);
while (current != std::string::npos) {
strings.push_back(trim(source.substr(previous, current - previous)));
previous = current + 1;
current = source.find(delimiter, previous);
}
strings.push_back(trim(source.substr(previous, current - previous)));
return strings;
} // split

View File

@ -136,12 +136,12 @@ static void _spp_tx_task(void * arg){
if(len){
memcpy(_spp_tx_buffer, data, len);
_spp_tx_buffer_len += len;
free(packet);
packet = NULL;
if(uxQueueMessagesWaiting(_spp_tx_queue) == 0){
_spp_send_buffer();
}
}
free(packet);
packet = NULL;
}
} else {
log_e("Something went horribly wrong");

View File

@ -0,0 +1,4 @@
## EEPROM
EEPROM is deprecated. For new applications on ESP32, use Preferences. EEPROM is provided for backwards compatibility with existing Arduino applications.
EEPROM is implemented using a single blob within NVS, so it is a container within a container. As such, it is not going to be a high performance storage method. Preferences will directly use nvs, and store each entry as a single object therein.

View File

@ -1,37 +1,21 @@
/*
ESP32 eeprom_class example with EEPROM library
This simple example demonstrates using EEPROM library to store different data in
ESP32 Flash memory in a multiple user-defined EEPROM partition (0x1000 or 4KB max size or less).
ESP32 Flash memory in a multiple user-defined EEPROM class objects.
Install 'ESP32 Partiton Manager' ONCE from https://github.com/francis94c/ESP32Partitions
And generate different partitions with 'partition_name'
Usage: EEPROMClass ANY_OBJECT_NAME("partition_name", size);
Generated partition that would work perfectly with this example
#Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000, 0x140000,
eeprom0, data, 0x99, 0x290000, 0x1000,
eeprom1, data, 0x9a, 0x291000, 0x500,
eeprom2, data, 0x9b, 0x292000, 0x100,
spiffs, data, spiffs, 0x293000, 0x16d000,
Created for arduino-esp32 on 25 Dec, 2017
by Elochukwu Ifediora (fedy0)
converted to nvs by lbernstone - 06/22/2019
*/
#include "EEPROM.h"
// Instantiate eeprom objects with parameter/argument names and size same as in the partition table
EEPROMClass NAMES("eeprom0", 0x1000);
EEPROMClass HEIGHT("eeprom1", 0x500);
// Instantiate eeprom objects with parameter/argument names and sizes
EEPROMClass NAMES("eeprom0", 0x500);
EEPROMClass HEIGHT("eeprom1", 0x200);
EEPROMClass AGE("eeprom2", 0x100);
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Testing EEPROMClass\n");
if (!NAMES.begin(NAMES.length())) {
@ -53,11 +37,12 @@ void setup() {
ESP.restart();
}
char* name = "Teo Swee Ann";
const char* name = "Teo Swee Ann";
char rname[32];
double height = 5.8;
uint32_t age = 47;
// Write: Variables ---> EEPROM partitions
// Write: Variables ---> EEPROM stores
NAMES.put(0, name);
HEIGHT.put(0, height);
AGE.put(0, age);
@ -75,11 +60,11 @@ void setup() {
Serial.print("age: "); Serial.println(age);
Serial.println("------------------------------------\n");
// Read: Variables <--- EEPROM partitions
NAMES.get(0, name);
// Read: Variables <--- EEPROM stores
NAMES.get(0, rname);
HEIGHT.get(0, height);
AGE.get(0, age);
Serial.print("name: "); Serial.println(name);
Serial.print("name: "); Serial.println(rname);
Serial.print("height: "); Serial.println(height);
Serial.print("age: "); Serial.println(age);
@ -87,6 +72,5 @@ void setup() {
}
void loop() {
// put your main code here, to run repeatedly:
delay(0xFFFFFFFF);
}

View File

@ -13,78 +13,127 @@ void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("\nTesting EEPROM Library\n");
if (!EEPROM.begin(EEPROM.length())) {
if (!EEPROM.begin(1000)) {
Serial.println("Failed to initialise EEPROM");
Serial.println("Restarting...");
delay(1000);
ESP.restart();
}
int address = 0; // Same address is used through the example
int address = 0;
EEPROM.writeByte(address, -128); // -2^7
Serial.println(EEPROM.readByte(address));
address += sizeof(byte);
EEPROM.writeChar(address, 'A'); // Same as writyByte and readByte
Serial.println(char(EEPROM.readChar(address)));
address += sizeof(char);
EEPROM.writeUChar(address, 255); // 2^8 - 1
Serial.println(EEPROM.readUChar(address));
address += sizeof(unsigned char);
EEPROM.writeShort(address, -32768); // -2^15
Serial.println(EEPROM.readShort(address));
address += sizeof(short);
EEPROM.writeUShort(address, 65535); // 2^16 - 1
Serial.println(EEPROM.readUShort(address));
address += sizeof(unsigned short);
EEPROM.writeInt(address, -2147483648); // -2^31
Serial.println(EEPROM.readInt(address));
address += sizeof(int);
EEPROM.writeUInt(address, 4294967295); // 2^32 - 1
Serial.println(EEPROM.readUInt(address));
address += sizeof(unsigned int);
EEPROM.writeLong(address, -2147483648); // Same as writeInt and readInt
Serial.println(EEPROM.readLong(address));
address += sizeof(long);
EEPROM.writeULong(address, 4294967295); // Same as writeUInt and readUInt
Serial.println(EEPROM.readULong(address));
address += sizeof(unsigned long);
int64_t value = -9223372036854775808; // -2^63
int64_t value = -1223372036854775808LL; // -2^63
EEPROM.writeLong64(address, value);
value = 0; // Clear value
address += sizeof(int64_t);
uint64_t Value = 18446744073709551615ULL; // 2^64 - 1
EEPROM.writeULong64(address, Value);
address += sizeof(uint64_t);
EEPROM.writeFloat(address, 1234.1234);
address += sizeof(float);
EEPROM.writeDouble(address, 123456789.123456789);
address += sizeof(double);
EEPROM.writeBool(address, true);
address += sizeof(bool);
String sentence = "I love ESP32.";
EEPROM.writeString(address, sentence);
address += sentence.length() + 1;
char gratitude[21] = "Thank You Espressif!";
EEPROM.writeString(address, gratitude);
address += 21;
// See also the general purpose writeBytes() and readBytes() for BLOB in EEPROM library
EEPROM.commit();
address = 0;
Serial.println(EEPROM.readByte(address));
address += sizeof(byte);
Serial.println((char)EEPROM.readChar(address));
address += sizeof(char);
Serial.println(EEPROM.readUChar(address));
address += sizeof(unsigned char);
Serial.println(EEPROM.readShort(address));
address += sizeof(short);
Serial.println(EEPROM.readUShort(address));
address += sizeof(unsigned short);
Serial.println(EEPROM.readInt(address));
address += sizeof(int);
Serial.println(EEPROM.readUInt(address));
address += sizeof(unsigned int);
Serial.println(EEPROM.readLong(address));
address += sizeof(long);
Serial.println(EEPROM.readULong(address));
address += sizeof(unsigned long);
value = 0;
value = EEPROM.readLong64(value);
Serial.printf("0x%08X", (uint32_t)(value >> 32)); // Print High 4 bytes in HEX
Serial.printf("%08X\n", (uint32_t)value); // Print Low 4 bytes in HEX
address += sizeof(int64_t);
uint64_t Value = 18446744073709551615; // 2^64 - 1
EEPROM.writeULong64(address, Value);
Value = 0; // Clear Value
Value = EEPROM.readULong64(Value);
Serial.printf("0x%08X", (uint32_t)(Value >> 32)); // Print High 4 bytes in HEX
Serial.printf("%08X\n", (uint32_t)Value); // Print Low 4 bytes in HEX
address += sizeof(uint64_t);
EEPROM.writeFloat(address, 1234.1234);
Serial.println(EEPROM.readFloat(address), 4);
address += sizeof(float);
EEPROM.writeDouble(address, 123456789.123456789);
Serial.println(EEPROM.readDouble(address), 8);
address += sizeof(double);
EEPROM.writeBool(address, true);
Serial.println(EEPROM.readBool(address));
address += sizeof(bool);
String sentence = "I love ESP32.";
EEPROM.writeString(address, sentence);
Serial.println(EEPROM.readString(address));
address += sentence.length() + 1;
char gratitude[] = "Thank You Espressif!";
EEPROM.writeString(address, gratitude);
Serial.println(EEPROM.readString(address));
// See also the general purpose writeBytes() and readBytes() for BLOB in EEPROM library
// To avoid data overwrite, next address should be chosen/offset by using "address =+ sizeof(previousData)"
address += 21;
}
void loop() {
// put your main code here, to run repeatedly:
}
}

View File

@ -1,9 +1,9 @@
name=EEPROM
version=1.0
version=1.0.3
author=Ivan Grokhotkov
maintainer=Paolo Becchi <pbecchi@aerobusiness.it>
sentence=Enables reading and writing data to the permanent FLASH storage, up to 4kb.
sentence=Enables reading and writing data a sequential, addressable FLASH storage
paragraph=
category=Data Storage
url=http://arduino.cc/en/Reference/EEPROM
architectures=esp32
architectures=esp32

View File

@ -1,10 +1,9 @@
/*
EEPROM.h -ported by Paolo Becchi to Esp32 from esp8266 EEPROM
-Modified by Elochukwu Ifediora <ifedioraelochukwuc@gmail.com>
-Converted to nvs lbernstone@gmail.com
Uses a one sector flash partition defined in partition table
OR
Multiple sector flash partitions defined by the name column in the partition table
Uses a nvs byte array to emulate EEPROM
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
@ -25,72 +24,121 @@
*/
#include "EEPROM.h"
#include <nvs.h>
#include <esp_partition.h>
#include <esp_log.h>
EEPROMClass::EEPROMClass(uint32_t sector)
: _sector(sector)
EEPROMClass::EEPROMClass(void)
: _handle(0)
, _data(0)
, _size(0)
, _dirty(false)
, _name("eeprom")
, _user_defined_size(0)
{
}
EEPROMClass::EEPROMClass(uint32_t sector)
// Only for compatiility, no sectors in nvs!
: _handle(0)
, _data(0)
, _size(0)
, _dirty(false)
, _mypart(NULL)
, _name("eeprom")
, _user_defined_size(0)
{
}
EEPROMClass::EEPROMClass(const char* name, uint32_t user_defined_size)
: _sector(0)
: _handle(0)
, _data(0)
, _size(0)
, _dirty(false)
, _mypart(NULL)
, _name(name)
, _user_defined_size(user_defined_size)
{
}
EEPROMClass::EEPROMClass(void)
: _sector(0)// (((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE))
, _data(0)
, _size(0)
, _dirty(false)
, _mypart(NULL)
, _name("eeprom")
, _user_defined_size(0)
{
}
EEPROMClass::~EEPROMClass() {
// end();
end();
}
bool EEPROMClass::begin(size_t size) {
if (size <= 0) {
return false;
if (!size) {
return false;
}
if (size > SPI_FLASH_SEC_SIZE) {
size = SPI_FLASH_SEC_SIZE;
esp_err_t res = nvs_open(_name, NVS_READWRITE, &_handle);
if (res != ESP_OK) {
log_e("Unable to open NVS namespace: %d", res);
return false;
}
// _mypart = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_ANY, EEPROM_FLASH_PARTITION_NAME);
_mypart = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, _name);
if (_mypart == NULL) {
return false;
size_t key_size = 0;
res = nvs_get_blob(_handle, _name, NULL, &key_size);
if(res != ESP_OK && res != ESP_ERR_NVS_NOT_FOUND) {
log_e("Unable to read NVS key: %d", res);
return false;
}
if (size < key_size) { // truncate
log_w("truncating EEPROM from %d to %d", key_size, size);
uint8_t* key_data = (uint8_t*) malloc(key_size);
if(!key_data) {
log_e("Not enough memory to truncate EEPROM!");
return false;
}
nvs_get_blob(_handle, _name, key_data, &key_size);
nvs_set_blob(_handle, _name, key_data, size);
nvs_commit(_handle);
free(key_data);
}
else if (size > key_size) { // expand or new
size_t expand_size = size - key_size;
uint8_t* expand_key = (uint8_t*) malloc(expand_size);
if(!expand_key) {
log_e("Not enough memory to expand EEPROM!");
return false;
}
// check for adequate free space
if(nvs_set_blob(_handle, "expand", expand_key, expand_size)) {
log_e("Not enough space to expand EEPROM from %d to %d", key_size, size);
free(expand_key);
return false;
}
free(expand_key);
nvs_erase_key(_handle, "expand");
uint8_t* key_data = (uint8_t*) malloc(size);
if(!key_data) {
log_e("Not enough memory to expand EEPROM!");
return false;
}
memset(key_data, 0xFF, size);
if(key_size) {
log_i("Expanding EEPROM from %d to %d", key_size, size);
// hold data while key is deleted
nvs_get_blob(_handle, _name, key_data, &key_size);
nvs_erase_key(_handle, _name);
} else {
log_i("New EEPROM of %d bytes", size);
}
nvs_commit(_handle);
nvs_set_blob(_handle, _name, key_data, size);
free(key_data);
nvs_commit(_handle);
}
size = (size + 3) & (~3);
if (_data) {
delete[] _data;
}
_data = new uint8_t[size];
_size = size;
bool ret = false;
if (esp_partition_read (_mypart, 0, (void *) _data, _size) == ESP_OK) {
ret = true;
_data = (uint8_t*) malloc(size);
if(!_data) {
log_e("Not enough memory for %d bytes in EEPROM");
return false;
}
return ret;
_size = size;
nvs_get_blob(_handle, _name, _data, &_size);
return true;
}
void EEPROMClass::end() {
@ -104,6 +152,9 @@ void EEPROMClass::end() {
}
_data = 0;
_size = 0;
nvs_close(_handle);
_handle = 0;
}
uint8_t EEPROMClass::read(int address) {
@ -134,29 +185,21 @@ void EEPROMClass::write(int address, uint8_t value) {
bool EEPROMClass::commit() {
bool ret = false;
if (!_size)
return false;
if (!_dirty)
return true;
if (!_data)
return false;
if (esp_partition_erase_range(_mypart, 0, SPI_FLASH_SEC_SIZE) != ESP_OK)
{
log_e( "partition erase err.");
if (!_size) {
return false;
}
else
{
if (esp_partition_write(_mypart, 0, (void *)_data, _size) == ESP_ERR_INVALID_SIZE)
{
log_e( "error in Write");
}
else
{
if (!_data) {
return false;
}
if (!_dirty) {
return true;
}
if (ESP_OK != nvs_set_blob(_handle, _name, _data, _size)) {
log_e( "error in write");
} else {
_dirty = false;
ret = true;
}
}
return ret;
@ -175,6 +218,67 @@ uint16_t EEPROMClass::length ()
return _user_defined_size;
}
/*
Convert EEPROM partition into nvs blob
Call convert before you call begin
*/
uint16_t EEPROMClass::convert (bool clear, const char* EEPROMname, const char* nvsname)
{
uint16_t result = 0;
const esp_partition_t* mypart = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, EEPROMname);
if (mypart == NULL) {
log_i("EEPROM partition not found for conversion");
return result;
}
size_t size = mypart->size;
uint8_t* data = (uint8_t*) malloc(size);
if (!data) {
log_e("Not enough memory to convert EEPROM!");
goto exit;
}
if (esp_partition_read (mypart, 0, (void *) data, size) != ESP_OK) {
log_e("Unable to read EEPROM partition");
goto exit;
}
bool empty;
empty = true;
for (int x=0; x<size; x++) {
if (data[x] != 0xFF) {
empty = false;
break;
}
}
if (empty) {
log_i("EEPROM partition is empty, will not convert");
goto exit;
}
nvs_handle handle;
if (nvs_open(nvsname, NVS_READWRITE, &handle) != ESP_OK) {
log_e("Unable to open NVS");
goto exit;
}
esp_err_t err;
err = nvs_set_blob(handle, nvsname, data, size);
if (err != ESP_OK) {
log_e("Unable to add EEPROM data to NVS: %s", esp_err_to_name(err));
goto exit;
}
result = size;
if (clear) {
if (esp_partition_erase_range (mypart, 0, size) != ESP_OK) {
log_w("Unable to clear EEPROM partition");
}
}
exit:
free(data);
return result;
}
/*
Read 'value' from 'address'
*/
@ -286,7 +390,7 @@ size_t EEPROMClass::readString (int address, char* value, size_t maxLen)
String EEPROMClass::readString (int address)
{
if (address < 0 || address > _size)
return String(0);
return String();
uint16_t len;
for (len = 0; len <= _size; len++)
@ -294,7 +398,7 @@ String EEPROMClass::readString (int address)
break;
if (address + len > _size)
return String(0);
return String();
char value[len];
memcpy((uint8_t*) value, _data + address, len);

View File

@ -1,10 +1,9 @@
/*
EEPROM.h -ported by Paolo Becchi to Esp32 from esp8266 EEPROM
-Modified by Elochukwu Ifediora <ifedioraelochukwuc@gmail.com>
-Converted to nvs lbernstone@gmail.com
Uses a one sector flash partition defined in partition table
OR
Multiple sector flash partitions defined by the name column in the partition table
Uses a nvs byte array to emulate EEPROM
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
@ -30,19 +29,9 @@
#define EEPROM_FLASH_PARTITION_NAME "eeprom"
#endif
#include <Arduino.h>
extern "C" {
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <esp_partition.h>
}
typedef uint32_t nvs_handle;
//
// need to define AT LEAST a flash partition for EEPROM with above name
//
// eeprom , data , 0x99, start address, 0x1000
//
class EEPROMClass {
public:
EEPROMClass(uint32_t sector);
@ -58,6 +47,7 @@ class EEPROMClass {
void end();
uint8_t * getDataPtr();
uint16_t convert(bool clear, const char* EEPROMname = "eeprom", const char* nvsname = "eeprom");
template<typename T>
T &get(int address, T &t) {
@ -117,11 +107,10 @@ class EEPROMClass {
template <class T> T writeAll (int address, const T &);
protected:
uint32_t _sector;
nvs_handle _handle;
uint8_t* _data;
size_t _size;
bool _dirty;
const esp_partition_t * _mypart;
const char* _name;
uint32_t _user_defined_size;
};

View File

@ -20,7 +20,6 @@
#include "fb_gfx.h"
#include "fd_forward.h"
#include "dl_lib.h"
#include "fr_forward.h"
#define ENROLL_CONFIRM_TIMES 5
@ -230,6 +229,7 @@ static esp_err_t capture_handler(httpd_req_t *req){
httpd_resp_set_type(req, "image/jpeg");
httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
size_t out_len, out_width, out_height;
uint8_t * out_buf;
@ -283,6 +283,7 @@ static esp_err_t capture_handler(httpd_req_t *req){
face_id = run_face_recognition(image_matrix, net_boxes);
}
draw_face_boxes(image_matrix, net_boxes, face_id);
free(net_boxes->score);
free(net_boxes->box);
free(net_boxes->landmark);
free(net_boxes);
@ -326,6 +327,8 @@ static esp_err_t stream_handler(httpd_req_t *req){
return res;
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
while(true){
detected = false;
face_id = 0;
@ -379,6 +382,7 @@ static esp_err_t stream_handler(httpd_req_t *req){
}
fr_recognize = esp_timer_get_time();
draw_face_boxes(image_matrix, net_boxes, face_id);
free(net_boxes->score);
free(net_boxes->box);
free(net_boxes->landmark);
free(net_boxes);
@ -625,15 +629,18 @@ void startCameraServer(){
ra_filter_init(&ra_filter, 20);
mtmn_config.type = FAST;
mtmn_config.min_face = 80;
mtmn_config.pyramid = 0.7;
mtmn_config.pyramid = 0.707;
mtmn_config.pyramid_times = 4;
mtmn_config.p_threshold.score = 0.6;
mtmn_config.p_threshold.nms = 0.7;
mtmn_config.p_threshold.candidate_number = 20;
mtmn_config.r_threshold.score = 0.7;
mtmn_config.r_threshold.nms = 0.7;
mtmn_config.r_threshold.candidate_number = 4;
mtmn_config.r_threshold.candidate_number = 10;
mtmn_config.o_threshold.score = 0.7;
mtmn_config.o_threshold.nms = 0.4;
mtmn_config.o_threshold.nms = 0.7;
mtmn_config.o_threshold.candidate_number = 1;
face_id_init(&id_list, FACE_ID_SAVE_NUMBER, ENROLL_CONFIRM_TIMES);

View File

@ -19,7 +19,7 @@ Author:
Pranav Cherukupalli <cherukupallip@gmail.com>
*/
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0;

View File

@ -40,8 +40,6 @@ Method to print the touchpad by which ESP32
has been awaken from sleep
*/
void print_wakeup_touchpad(){
touch_pad_t pin;
touchPin = esp_sleep_get_touchpad_wakeup_status();
switch(touchPin)

View File

@ -88,7 +88,7 @@ void ScanForSlave() {
Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
// Get BSSID => Mac Address of the Slave
int mac[6];
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
for (int ii = 0; ii < 6; ++ii ) {
slave.peer_addr[ii] = (uint8_t) mac[ii];
}
@ -124,17 +124,15 @@ bool manageSlave() {
}
Serial.print("Slave Status: ");
const esp_now_peer_info_t *peer = &slave;
const uint8_t *peer_addr = slave.peer_addr;
// check if the peer exists
bool exists = esp_now_is_peer_exist(peer_addr);
bool exists = esp_now_is_peer_exist(slave.peer_addr);
if ( exists) {
// Slave already paired.
Serial.println("Already Paired");
return true;
} else {
// Slave not paired, attempt pair
esp_err_t addStatus = esp_now_add_peer(peer);
esp_err_t addStatus = esp_now_add_peer(&slave);
if (addStatus == ESP_OK) {
// Pair success
Serial.println("Pair success");
@ -168,9 +166,7 @@ bool manageSlave() {
}
void deletePeer() {
const esp_now_peer_info_t *peer = &slave;
const uint8_t *peer_addr = slave.peer_addr;
esp_err_t delStatus = esp_now_del_peer(peer_addr);
esp_err_t delStatus = esp_now_del_peer(slave.peer_addr);
Serial.print("Slave Delete Status: ");
if (delStatus == ESP_OK) {
// Delete success

View File

@ -100,7 +100,7 @@ void ScanForSlave() {
// Get BSSID => Mac Address of the Slave
int mac[6];
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
for (int ii = 0; ii < 6; ++ii ) {
slaves[SlaveCnt].peer_addr[ii] = (uint8_t) mac[ii];
}
@ -127,8 +127,6 @@ void ScanForSlave() {
void manageSlave() {
if (SlaveCnt > 0) {
for (int i = 0; i < SlaveCnt; i++) {
const esp_now_peer_info_t *peer = &slaves[i];
const uint8_t *peer_addr = slaves[i].peer_addr;
Serial.print("Processing: ");
for (int ii = 0; ii < 6; ++ii ) {
Serial.print((uint8_t) slaves[i].peer_addr[ii], HEX);
@ -136,13 +134,13 @@ void manageSlave() {
}
Serial.print(" Status: ");
// check if the peer exists
bool exists = esp_now_is_peer_exist(peer_addr);
bool exists = esp_now_is_peer_exist(slaves[i].peer_addr);
if (exists) {
// Slave already paired.
Serial.println("Already Paired");
} else {
// Slave not paired, attempt pair
esp_err_t addStatus = esp_now_add_peer(peer);
esp_err_t addStatus = esp_now_add_peer(&slaves[i]);
if (addStatus == ESP_OK) {
// Pair success
Serial.println("Pair success");

View File

@ -52,7 +52,7 @@ void loop()
// Printout the received data plus the original values
for (i=0; i<60; i++)
{
Serial.printf("%08x=%08x ", my_data[i], data[i] );
Serial.printf("%08x=%08x ", my_data[i].val, data[i].val );
if (!((i+1)%4)) Serial.println("\n");
}
Serial.println("\n");

View File

@ -141,7 +141,6 @@ static bool xjtReceiveBit(size_t index, bool bit){
}
void parseRmt(rmt_data_t* items, size_t len, uint32_t* channels){
size_t chan = 0;
bool valid = true;
rmt_data_t* it = NULL;

View File

@ -62,7 +62,7 @@ void loop()
for (led=0; led<NR_OF_LEDS; led++) {
for (col=0; col<3; col++ ) {
for (bit=0; bit<8; bit++){
if ( (color[col] & (1<<(8-bit))) && (led == led_index) ) {
if ( (color[col] & (1<<(7-bit))) && (led == led_index) ) {
led_data[i].level0 = 1;
led_data[i].duration0 = 8;
led_data[i].level1 = 0;

View File

@ -96,7 +96,6 @@ void loop(void)
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
client.flush();
String s;
if (req == "/")
@ -115,6 +114,7 @@ void loop(void)
}
client.print(s);
client.stop();
Serial.println("Done with client");
}

View File

@ -165,8 +165,8 @@ void setup(){
return;
}
Serial.printf("Total space: %10lu\n", FFat.totalBytes());
Serial.printf("Free space: %10lu\n", FFat.freeBytes());
Serial.printf("Total space: %10u\n", FFat.totalBytes());
Serial.printf("Free space: %10u\n", FFat.freeBytes());
listDir(FFat, "/", 0);
writeFile(FFat, "/hello.txt", "Hello ");
appendFile(FFat, "/hello.txt", "World!\r\n");
@ -175,7 +175,7 @@ void setup(){
readFile(FFat, "/foo.txt");
deleteFile(FFat, "/foo.txt");
testFileIO(FFat, "/test.txt");
Serial.printf("Free space: %10lu\n", FFat.freeBytes());
Serial.printf("Free space: %10u\n", FFat.freeBytes());
deleteFile(FFat, "/test.txt");
Serial.println( "Test complete" );
}

View File

@ -0,0 +1,177 @@
#include "FS.h"
#include "FFat.h"
#include <time.h>
#include <WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
long timezone = 1;
byte daysavetime = 1;
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.print (file.name());
time_t t= file.getLastWrite();
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
if(levels){
listDir(fs, file.name(), levels -1);
}
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.print(file.size());
time_t t= file.getLastWrite();
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
}
file = root.openNextFile();
}
}
void createDir(fs::FS &fs, const char * path){
Serial.printf("Creating Dir: %s\n", path);
if(fs.mkdir(path)){
Serial.println("Dir created");
} else {
Serial.println("mkdir failed");
}
}
void removeDir(fs::FS &fs, const char * path){
Serial.printf("Removing Dir: %s\n", path);
if(fs.rmdir(path)){
Serial.println("Dir removed");
} else {
Serial.println("rmdir failed");
}
}
void readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if(!file){
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while(file.available()){
Serial.write(file.read());
}
file.close();
}
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
void appendFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void renameFile(fs::FS &fs, const char * path1, const char * path2){
Serial.printf("Renaming file %s to %s\n", path1, path2);
if (fs.rename(path1, path2)) {
Serial.println("File renamed");
} else {
Serial.println("Rename failed");
}
}
void deleteFile(fs::FS &fs, const char * path){
Serial.printf("Deleting file: %s\n", path);
if(fs.remove(path)){
Serial.println("File deleted");
} else {
Serial.println("Delete failed");
}
}
void setup(){
Serial.begin(115200);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Contacting Time Server");
configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
struct tm tmstruct ;
delay(2000);
tmstruct.tm_year = 0;
getLocalTime(&tmstruct, 5000);
Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1900,( tmstruct.tm_mon)+1, tmstruct.tm_mday,tmstruct.tm_hour , tmstruct.tm_min, tmstruct.tm_sec);
Serial.println("");
if(!FFat.begin(true)){
Serial.println("FFat Mount Failed");
return;
}
listDir(FFat, "/", 0);
removeDir(FFat, "/mydir");
createDir(FFat, "/mydir");
deleteFile(FFat, "/hello.txt");
writeFile(FFat, "/hello.txt", "Hello ");
appendFile(FFat, "/hello.txt", "World!\n");
listDir(FFat, "/", 0);
}
void loop(){
}

View File

@ -40,20 +40,26 @@ const esp_partition_t *check_ffat_partition(const char* label)
bool F_Fat::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles, const char * partitionLabel)
{
if(_wl_handle){
if(_wl_handle != WL_INVALID_HANDLE){
log_w("Already Mounted!");
return true;
}
if (!check_ffat_partition(partitionLabel)) return false;
if (!check_ffat_partition(partitionLabel)){
log_e("No fat partition found on flash");
return false;
}
esp_vfs_fat_mount_config_t conf = {
.format_if_mount_failed = formatOnFail,
.max_files = maxOpenFiles
.max_files = maxOpenFiles,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
esp_err_t err = esp_vfs_fat_spiflash_mount(basePath, partitionLabel, &conf, &_wl_handle);
if(err){
log_e("Mounting FFat partition failed! Error: %d", err);
esp_vfs_fat_spiflash_unmount(basePath, _wl_handle);
_wl_handle = WL_INVALID_HANDLE;
return false;
}
_impl->mountpoint(basePath);
@ -62,13 +68,13 @@ bool F_Fat::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles
void F_Fat::end()
{
if(_wl_handle){
if(_wl_handle != WL_INVALID_HANDLE){
esp_err_t err = esp_vfs_fat_spiflash_unmount(_impl->mountpoint(), _wl_handle);
if(err){
log_e("Unmounting FFat partition failed! Error: %d", err);
return;
}
_wl_handle = NULL;
_wl_handle = WL_INVALID_HANDLE;
_impl->mountpoint(NULL);
}
}
@ -76,14 +82,18 @@ void F_Fat::end()
bool F_Fat::format(bool full_wipe, char* partitionLabel)
{
esp_err_t result;
if(_wl_handle){
bool res = true;
if(_wl_handle != WL_INVALID_HANDLE){
log_w("Already Mounted!");
return false;
}
wl_handle_t temp_handle;
// Attempt to mount to see if there is already data
const esp_partition_t *ffat_partition = check_ffat_partition(partitionLabel);
if (!ffat_partition) return false;
if (!ffat_partition){
log_w("No partition!");
return false;
}
result = wl_mount(ffat_partition, &temp_handle);
if (result == ESP_OK) {
@ -91,15 +101,23 @@ bool F_Fat::format(bool full_wipe, char* partitionLabel)
uint32_t wipe_size = full_wipe ? wl_size(temp_handle) : 16384;
wl_erase_range(temp_handle, 0, wipe_size);
wl_unmount(temp_handle);
} else {
res = false;
log_w("wl_mount failed!");
}
// Now do a mount with format_if_fail (which it will)
esp_vfs_fat_mount_config_t conf = {
.format_if_mount_failed = true,
.max_files = 1
.max_files = 1,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
result = esp_vfs_fat_spiflash_mount("/format_ffat", partitionLabel, &conf, &temp_handle);
esp_vfs_fat_spiflash_unmount("/format_ffat", temp_handle);
return result;
if (result != ESP_OK){
res = false;
log_w("esp_vfs_fat_spiflash_mount failed!");
}
return res;
}
size_t F_Fat::totalBytes()
@ -109,7 +127,9 @@ size_t F_Fat::totalBytes()
BYTE pdrv = ff_diskio_get_pdrv_wl(_wl_handle);
char drv[3] = {(char)(48+pdrv), ':', 0};
FRESULT res = f_getfree(drv, &free_clust, &fs);
if ( f_getfree(drv, &free_clust, &fs) != FR_OK){
return 0;
}
tot_sect = (fs->n_fatent - 2) * fs->csize;
sect_size = CONFIG_WL_SECTOR_SIZE;
return tot_sect * sect_size;
@ -123,7 +143,9 @@ size_t F_Fat::freeBytes()
BYTE pdrv = ff_diskio_get_pdrv_wl(_wl_handle);
char drv[3] = {(char)(48+pdrv), ':', 0};
FRESULT res = f_getfree(drv, &free_clust, &fs);
if ( f_getfree(drv, &free_clust, &fs) != FR_OK){
return 0;
}
free_sect = free_clust * fs->csize;
sect_size = CONFIG_WL_SECTOR_SIZE;
return free_sect * sect_size;

View File

@ -37,7 +37,7 @@ public:
bool exists(const String& path);
private:
wl_handle_t _wl_handle;
wl_handle_t _wl_handle = WL_INVALID_HANDLE;
};
}

View File

@ -2,8 +2,8 @@ name=HTTPClient
version=1.2
author=Markus Sattler
maintainer=Markus Sattler
sentence=http Client for ESP32
sentence=HTTP Client for ESP32
paragraph=
category=Communication
url=https://github.com/Links2004/Arduino/tree/libraries/ESP8266HTTPClient
url=https://github.com/espressif/arduino-esp32/tree/master/libraries/HTTPClient
architectures=esp32

View File

@ -1,3 +1,4 @@
#include <HardwareSerial.h>
/**
* HTTPClient.cpp
*
@ -195,6 +196,11 @@ bool HTTPClient::begin(String url, const char* CAcert)
}
_secure = true;
_transportTraits = TransportTraitsPtr(new TLSTraits(CAcert));
if(!_transportTraits) {
log_e("could not create transport traits");
return false;
}
return true;
}
@ -215,6 +221,11 @@ bool HTTPClient::begin(String url)
return begin(url, (const char*)NULL);
}
_transportTraits = TransportTraitsPtr(new TransportTraits());
if(!_transportTraits) {
log_e("could not create transport traits");
return false;
}
return true;
}
#endif // HTTPCLIENT_1_1_COMPATIBLE
@ -333,7 +344,8 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, const char* CAcer
*/
void HTTPClient::end(void)
{
disconnect();
disconnect(false);
clear();
}
@ -342,7 +354,7 @@ void HTTPClient::end(void)
* disconnect
* close the TCP socket
*/
void HTTPClient::disconnect()
void HTTPClient::disconnect(bool preserveClient)
{
if(connected()) {
if(_client->available() > 0) {
@ -357,7 +369,9 @@ void HTTPClient::disconnect()
} else {
log_d("tcp stop\n");
_client->stop();
_client = nullptr;
if(!preserveClient) {
_client = nullptr;
}
#ifdef HTTPCLIENT_1_1_COMPATIBLE
if(_tcpDeprecated) {
_transportTraits.reset(nullptr);
@ -456,6 +470,7 @@ void HTTPClient::setTimeout(uint16_t timeout)
void HTTPClient::useHTTP10(bool useHTTP10)
{
_useHTTP10 = useHTTP10;
_reuse = !useHTTP10;
}
/**
@ -816,7 +831,8 @@ int HTTPClient::writeToStream(Stream * stream)
return returnError(HTTPC_ERROR_ENCODING);
}
end();
// end();
disconnect(true);
return ret;
}
@ -970,9 +986,12 @@ bool HTTPClient::hasHeader(const char* name)
*/
bool HTTPClient::connect(void)
{
if(connected()) {
log_d("already connected, try reuse!");
if(_reuse) {
log_d("already connected, reusing connection");
} else {
log_d("already connected, try reuse!");
}
while(_client->available() > 0) {
_client->read();
}
@ -980,8 +999,12 @@ bool HTTPClient::connect(void)
}
#ifdef HTTPCLIENT_1_1_COMPATIBLE
if(!_client) {
if(_transportTraits && !_client) {
_tcpDeprecated = _transportTraits->create();
if(!_tcpDeprecated) {
log_e("failed to create client");
return false;
}
_client = _tcpDeprecated.get();
}
#endif
@ -1080,9 +1103,12 @@ int HTTPClient::handleHeaderResponse()
return HTTPC_ERROR_NOT_CONNECTED;
}
clear();
_canReuse = _reuse;
String transferEncoding;
_returnCode = -1;
_size = -1;
_transferEncoding = HTTPC_TE_IDENTITY;
unsigned long lastDataTime = millis();
@ -1097,6 +1123,9 @@ int HTTPClient::handleHeaderResponse()
log_v("RX: '%s'", headerLine.c_str());
if(headerLine.startsWith("HTTP/1.")) {
if(_canReuse) {
_canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0');
}
_returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
} else if(headerLine.indexOf(':')) {
String headerName = headerLine.substring(0, headerLine.indexOf(':'));
@ -1107,8 +1136,10 @@ int HTTPClient::handleHeaderResponse()
_size = headerValue.toInt();
}
if(headerName.equalsIgnoreCase("Connection")) {
_canReuse = headerValue.equalsIgnoreCase("keep-alive");
if(_canReuse && headerName.equalsIgnoreCase("Connection")) {
if(headerValue.indexOf("close") >= 0 && headerValue.indexOf("keep-alive") < 0) {
_canReuse = false;
}
}
if(headerName.equalsIgnoreCase("Transfer-Encoding")) {

View File

@ -197,7 +197,7 @@ protected:
};
bool beginInternal(String url, const char* expectedProtocol);
void disconnect();
void disconnect(bool preserveClient = false);
void clear();
int returnError(int error);
bool connect(void);
@ -217,7 +217,7 @@ protected:
String _host;
uint16_t _port = 0;
int32_t _connectTimeout = -1;
bool _reuse = false;
bool _reuse = true;
uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _useHTTP10 = false;
bool _secure = false;

View File

@ -96,7 +96,7 @@ void loop() {
client.setCACert(rootCACertificate);
// Reading data over SSL may be slow, use an adequate timeout
client.setTimeout(12000);
client.setTimeout(12000 / 1000); // timeout argument is defined in seconds for setTimeout
// The line below is optional. It can be used to blink the LED on the board during flashing
// The LED will be on during download of one buffer of data from the network. The LED will

View File

@ -291,7 +291,7 @@ int8_t Preferences::getChar(const char* key, const int8_t defaultValue){
}
esp_err_t err = nvs_get_i8(_handle, key, &value);
if(err){
log_e("nvs_get_i8 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_i8 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -303,7 +303,7 @@ uint8_t Preferences::getUChar(const char* key, const uint8_t defaultValue){
}
esp_err_t err = nvs_get_u8(_handle, key, &value);
if(err){
log_e("nvs_get_u8 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_u8 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -315,7 +315,7 @@ int16_t Preferences::getShort(const char* key, const int16_t defaultValue){
}
esp_err_t err = nvs_get_i16(_handle, key, &value);
if(err){
log_e("nvs_get_i16 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_i16 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -327,7 +327,7 @@ uint16_t Preferences::getUShort(const char* key, const uint16_t defaultValue){
}
esp_err_t err = nvs_get_u16(_handle, key, &value);
if(err){
log_e("nvs_get_u16 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_u16 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -339,7 +339,7 @@ int32_t Preferences::getInt(const char* key, const int32_t defaultValue){
}
esp_err_t err = nvs_get_i32(_handle, key, &value);
if(err){
log_e("nvs_get_i32 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_i32 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -351,7 +351,7 @@ uint32_t Preferences::getUInt(const char* key, const uint32_t defaultValue){
}
esp_err_t err = nvs_get_u32(_handle, key, &value);
if(err){
log_e("nvs_get_u32 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_u32 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -371,7 +371,7 @@ int64_t Preferences::getLong64(const char* key, const int64_t defaultValue){
}
esp_err_t err = nvs_get_i64(_handle, key, &value);
if(err){
log_e("nvs_get_i64 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_i64 fail: %s %s", key, nvs_error(err));
}
return value;
}
@ -383,7 +383,7 @@ uint64_t Preferences::getULong64(const char* key, const uint64_t defaultValue){
}
esp_err_t err = nvs_get_u64(_handle, key, &value);
if(err){
log_e("nvs_get_u64 fail: %s %s", key, nvs_error(err));
log_v("nvs_get_u64 fail: %s %s", key, nvs_error(err));
}
return value;
}

Some files were not shown because too many files have changed in this diff Show More