diff --git a/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino b/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino index 069cdab4ebb..ebba036e812 100644 --- a/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino +++ b/libraries/BLE/examples/BLE5_extended_scan/BLE5_extended_scan.ino @@ -8,8 +8,9 @@ author: chegewara */ #ifndef SOC_BLE_50_SUPPORTED -#warning "Not compatible hardware" +#warning "This SoC does not support BLE5. Try using ESP32-C3, or ESP32-S3" #else + #include #include #include diff --git a/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino b/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino index ddd282aea7b..51935041fef 100644 --- a/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino +++ b/libraries/BLE/examples/BLE5_multi_advertising/BLE5_multi_advertising.ino @@ -6,6 +6,10 @@ author: chegewara */ +#ifndef CONFIG_BT_BLE_50_FEATURES_SUPPORTED + #error "This SoC does not support BLE5. Try using ESP32-C3, or ESP32-S3" +#else + #include #include @@ -152,3 +156,4 @@ void setup() { void loop() { delay(2000); } +#endif \ No newline at end of file diff --git a/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino b/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino index 26f686cd1bd..123a5d13ffe 100644 --- a/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino +++ b/libraries/BLE/examples/BLE5_periodic_advertising/BLE5_periodic_advertising.ino @@ -5,6 +5,9 @@ author: chegewara */ +#ifndef CONFIG_BT_BLE_50_FEATURES_SUPPORTED + #error "This SoC does not support BLE5. Try using ESP32-C3, or ESP32-S3" +#else #include #include @@ -73,3 +76,4 @@ void setup() { void loop() { delay(2000); } +#endif \ No newline at end of file diff --git a/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino b/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino index b28e4e36661..c3d9eb6cd2b 100644 --- a/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino +++ b/libraries/BLE/examples/BLE5_periodic_sync/BLE5_periodic_sync.ino @@ -8,7 +8,7 @@ author: chegewara */ #ifndef SOC_BLE_50_SUPPORTED -#warning "Not compatible hardware" +#warning "This SoC does not support BLE5. Try using ESP32-C3, or ESP32-S3" #else #include #include diff --git a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino b/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino deleted file mode 100644 index d3938ee02fa..00000000000 --- a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino +++ /dev/null @@ -1,192 +0,0 @@ -/* - EddystoneURL beacon by BeeGee - EddystoneURL frame specification https://github.com/google/eddystone/blob/master/eddystone-url/README.md - -*/ - -/* - Create a BLE server that will send periodic Eddystone URL frames. - The design of creating the BLE server is: - 1. Create a BLE Server - 2. Create advertising data - 3. Start advertising. - 4. wait - 5. Stop advertising. - 6. deep sleep - -*/ -#include "sys/time.h" - -#include - -#include "BLEDevice.h" -#include "BLEUtils.h" -#include "BLEBeacon.h" -#include "BLEAdvertising.h" -#include "BLEEddystoneURL.h" - -#include "esp_sleep.h" - -#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up -RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory -RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory - -// See the following for generating UUIDs: -// https://www.uuidgenerator.net/ -BLEAdvertising *pAdvertising; -struct timeval now; - -#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) - -static const char *eddystone_url_prefix_subs[] = { - "http://www.", - "https://www.", - "http://", - "https://", - "urn:uuid:", - NULL -}; - -static const char *eddystone_url_suffix_subs[] = { - ".com/", - ".org/", - ".edu/", - ".net/", - ".info/", - ".biz/", - ".gov/", - ".com", - ".org", - ".edu", - ".net", - ".info", - ".biz", - ".gov", - NULL -}; - -static int string_begin_with(const char *str, const char *prefix) -{ - int prefix_len = strlen(prefix); - if (strncmp(prefix, str, prefix_len) == 0) - { - return prefix_len; - } - return 0; -} - -void setBeacon() -{ - BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); - BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); - - const char url[] = "https://d.giesecke.tk"; - - int scheme_len, ext_len = 1, i, idx, url_idx; - char *ret_data; - int url_len = strlen(url); - - ret_data = (char *)calloc(1, url_len + 13); - - ret_data[0] = 2; // Len - ret_data[1] = 0x01; // Type Flags - ret_data[2] = 0x06; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 - ret_data[3] = 3; // Len - ret_data[4] = 0x03; // Type 16-Bit UUID - ret_data[5] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB - ret_data[6] = 0xFE; // Eddystone UUID 1 MSB - ret_data[7] = 19; // Length of Beacon Data - ret_data[8] = 0x16; // Type Service Data - ret_data[9] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB - ret_data[10] = 0xFE; // Eddystone UUID 1 MSB - ret_data[11] = 0x10; // Eddystone Frame Type - ret_data[12] = 0xF4; // Beacons TX power at 0m - - i = 0, idx = 13, url_idx = 0; - - //replace prefix - scheme_len = 0; - while (eddystone_url_prefix_subs[i] != NULL) - { - if ((scheme_len = string_begin_with(url, eddystone_url_prefix_subs[i])) > 0) - { - ret_data[idx] = i; - idx++; - url_idx += scheme_len; - break; - } - i++; - } - while (url_idx < url_len) - { - i = 0; - ret_data[idx] = url[url_idx]; - ext_len = 1; - while (eddystone_url_suffix_subs[i] != NULL) - { - if ((ext_len = string_begin_with(&url[url_idx], eddystone_url_suffix_subs[i])) > 0) - { - ret_data[idx] = i; - break; - } - else - { - ext_len = 1; //inc 1 - } - i++; - } - url_idx += ext_len; - idx++; - } - ret_data[7] = idx - 8; - - Serial.printf("struct size %d url size %d reported len %d\n", - url_len + 13, - url_len, ret_data[7]); - - Serial.printf("URL in data %s\n", &ret_data[13]); - - std::string eddyStoneData(ret_data); - - oAdvertisementData.addData(eddyStoneData); - oScanResponseData.setName("URLBeacon"); - pAdvertising->setAdvertisementData(oAdvertisementData); - pAdvertising->setScanResponseData(oScanResponseData); -} - -void setup() -{ - - Serial.begin(115200); - gettimeofday(&now, NULL); - - Serial.printf("start ESP32 %lu\n", bootcount++); - - Serial.printf("deep sleep (%llds since last reset, %llds since last boot)\n", now.tv_sec, now.tv_sec - last); - - last = now.tv_sec; - - // Create the BLE Device - BLEDevice::init("URLBeacon"); - - BLEDevice::setPower(ESP_PWR_LVL_N12); - - // Create the BLE Server - // BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage - - pAdvertising = BLEDevice::getAdvertising(); - - setBeacon(); - // Start advertising - pAdvertising->start(); - Serial.println("Advertizing started..."); - delay(10000); - pAdvertising->stop(); - Serial.printf("enter deep sleep\n"); - esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); - Serial.printf("in deep sleep\n"); -} - -void loop() -{ -} diff --git a/libraries/BLE/examples/BLE_Beacon_Scanner/.skip.esp32s2 b/libraries/BLE/examples/Beacon_Scanner/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_Beacon_Scanner/.skip.esp32s2 rename to libraries/BLE/examples/Beacon_Scanner/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino b/libraries/BLE/examples/Beacon_Scanner/Beacon_Scanner.ino similarity index 56% rename from libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino rename to libraries/BLE/examples/Beacon_Scanner/Beacon_Scanner.ino index 6a615eadb81..ce36dd7ac4d 100644 --- a/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino +++ b/libraries/BLE/examples/Beacon_Scanner/Beacon_Scanner.ino @@ -2,6 +2,7 @@ Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp Ported to Arduino ESP32 by Evandro Copercini Changed to a beacon scanner to report iBeacon, EddystoneURL and EddystoneTLM beacons by beegee-tokyo + Upgraded Eddystone part by Tomas Pilny on Feb 20, 2023 */ #include @@ -38,10 +39,10 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks if (advertisedDevice.haveManufacturerData() == true) { - std::string strManufacturerData = advertisedDevice.getManufacturerData(); + String strManufacturerData = advertisedDevice.getManufacturerData(); uint8_t cManufacturerData[100]; - strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0); + memcpy(cManufacturerData, strManufacturerData.c_str(), strManufacturerData.length()); if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00) { @@ -63,62 +64,34 @@ class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks } } - uint8_t *payLoad = advertisedDevice.getPayload(); - // search for Eddystone Service Data in the advertising payload - // *payload shall point to eddystone data or to its end when not found - const uint8_t serviceDataEddystone[3] = {0x16, 0xAA, 0xFE}; // it has Eddystone BLE UUID - const size_t payLoadLen = advertisedDevice.getPayloadLength(); - uint8_t *payLoadEnd = payLoad + payLoadLen - 1; // address of the end of payLoad space - while (payLoad < payLoadEnd) { - if (payLoad[1] == serviceDataEddystone[0] && payLoad[2] == serviceDataEddystone[1] && payLoad[3] == serviceDataEddystone[2]) { - // found! - payLoad += 4; - break; + if (advertisedDevice.getFrameType() == BLE_EDDYSTONE_URL_FRAME) + { + Serial.println("Found an EddystoneURL beacon!"); + BLEEddystoneURL EddystoneURL = BLEEddystoneURL(&advertisedDevice); + Serial.printf("URL bytes: 0x"); + String url = EddystoneURL.getURL(); + for(auto byte : url){ + Serial.printf("%02X", byte); } - payLoad += *payLoad + 1; // payLoad[0] has the field Length + Serial.printf("\n"); + Serial.printf("Decoded URL: %s\n", EddystoneURL.getDecodedURL().c_str()); + Serial.printf("EddystoneURL.getDecodedURL(): %s\n", EddystoneURL.getDecodedURL().c_str()); + Serial.printf("TX power %d (Raw 0x%02X)\n", EddystoneURL.getPower(), EddystoneURL.getPower()); + Serial.println("\n"); } - if (payLoad < payLoadEnd) // Eddystone Service Data and respective BLE UUID were found + if (advertisedDevice.getFrameType() == BLE_EDDYSTONE_TLM_FRAME) { - if (*payLoad == 0x10) - { - Serial.println("Found an EddystoneURL beacon!"); - BLEEddystoneURL foundEddyURL = BLEEddystoneURL(); - uint8_t URLLen = *(payLoad - 4) - 3; // Get Field Length less 3 bytes (type and UUID) - foundEddyURL.setData(std::string((char*)payLoad, URLLen)); - std::string bareURL = foundEddyURL.getURL(); - if (bareURL[0] == 0x00) - { - // dumps all bytes in advertising payload - Serial.println("DATA-->"); - uint8_t *payLoad = advertisedDevice.getPayload(); - for (int idx = 0; idx < payLoadLen; idx++) - { - Serial.printf("0x%02X ", payLoad[idx]); - } - Serial.println("\nInvalid Data"); - return; - } - - Serial.printf("Found URL: %s\n", foundEddyURL.getURL().c_str()); - Serial.printf("Decoded URL: %s\n", foundEddyURL.getDecodedURL().c_str()); - Serial.printf("TX power %d\n", foundEddyURL.getPower()); - Serial.println("\n"); - } - else if (*payLoad == 0x20) - { Serial.println("Found an EddystoneTLM beacon!"); - BLEEddystoneTLM eddystoneTLM; - eddystoneTLM.setData(std::string((char*)payLoad, 14)); - Serial.printf("Reported battery voltage: %dmV\n", eddystoneTLM.getVolt()); - Serial.printf("Reported temperature: %.2f°C (raw data=0x%04X)\n", eddystoneTLM.getTemp(), eddystoneTLM.getRawTemp()); - Serial.printf("Reported advertise count: %lu\n", eddystoneTLM.getCount()); - Serial.printf("Reported time since last reboot: %lus\n", eddystoneTLM.getTime()); + BLEEddystoneTLM EddystoneTLM(&advertisedDevice); + Serial.printf("Reported battery voltage: %dmV\n", EddystoneTLM.getVolt()); + Serial.printf("Reported temperature: %.2f°C (raw data=0x%04X)\n", EddystoneTLM.getTemp(), EddystoneTLM.getRawTemp()); + Serial.printf("Reported advertise count: %lu\n", EddystoneTLM.getCount()); + Serial.printf("Reported time since last reboot: %lus\n", EddystoneTLM.getTime()); Serial.println("\n"); - Serial.print(eddystoneTLM.toString().c_str()); + Serial.print(EddystoneTLM.toString().c_str()); Serial.println("\n"); } - } } }; diff --git a/libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md b/libraries/BLE/examples/Beacon_Scanner/Beacon_Scanner.md similarity index 100% rename from libraries/BLE/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md rename to libraries/BLE/examples/Beacon_Scanner/Beacon_Scanner.md diff --git a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/.skip.esp32s2 b/libraries/BLE/examples/Client/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_EddystoneTLM_Beacon/.skip.esp32s2 rename to libraries/BLE/examples/Client/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_client/BLE_client.ino b/libraries/BLE/examples/Client/Client.ino similarity index 98% rename from libraries/BLE/examples/BLE_client/BLE_client.ino rename to libraries/BLE/examples/Client/Client.ino index 74ae8b7532d..5d7f5d5c57a 100644 --- a/libraries/BLE/examples/BLE_client/BLE_client.ino +++ b/libraries/BLE/examples/Client/Client.ino @@ -80,7 +80,7 @@ bool connectToServer() { // Read the value of the characteristic. if(pRemoteCharacteristic->canRead()) { - std::string value = pRemoteCharacteristic->readValue(); + String value = pRemoteCharacteristic->readValue(); Serial.print("The characteristic value was: "); Serial.println(value.c_str()); } diff --git a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/.skip.esp32h2 b/libraries/BLE/examples/EddystoneTLM_Beacon/.skip.esp32h2 similarity index 100% rename from libraries/BLE/examples/BLE_EddystoneTLM_Beacon/.skip.esp32h2 rename to libraries/BLE/examples/EddystoneTLM_Beacon/.skip.esp32h2 diff --git a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/.skip.esp32s2 b/libraries/BLE/examples/EddystoneTLM_Beacon/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_EddystoneURL_Beacon/.skip.esp32s2 rename to libraries/BLE/examples/EddystoneTLM_Beacon/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino b/libraries/BLE/examples/EddystoneTLM_Beacon/EddystoneTLM_Beacon.ino similarity index 62% rename from libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino rename to libraries/BLE/examples/EddystoneTLM_Beacon/EddystoneTLM_Beacon.ino index d68529b7d58..c608133c7d1 100644 --- a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino +++ b/libraries/BLE/examples/EddystoneTLM_Beacon/EddystoneTLM_Beacon.ino @@ -28,6 +28,7 @@ #include "esp_sleep.h" #define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up +#define BEACON_POWER ESP_PWR_LVL_N12 RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory @@ -46,37 +47,18 @@ time_t lastTenth; // for the temperature value. It is a 8.8 fixed-point notation void setBeacon() { - char beacon_data[25]; - uint16_t beconUUID = 0xFEAA; - uint16_t volt = random(2800, 3700); // 3300mV = 3.3V - float tempFloat = random(-3000, 3000) / 100.0f; - Serial.printf("Random temperature is %.2f°C\n", tempFloat); - int temp = (int)(tempFloat * 256); - Serial.printf("Converted to 8.8 format %0X%0X\n", (temp >> 8) & 0xFF, (temp & 0xFF)); + BLEEddystoneTLM EddystoneTLM; + EddystoneTLM.setVolt((uint16_t)random(2800, 3700)); // 3300mV = 3.3V + EddystoneTLM.setTemp(random(-3000, 3000) / 100.0f); // 3000 = 30.00 ˚C + Serial.printf("Random Battery voltage is %d mV = 0x%04X\n", EddystoneTLM.getVolt(), EddystoneTLM.getVolt()); + Serial.printf("Random temperature is %.2f°C\n", EddystoneTLM.getTemp()); + Serial.printf("Converted to 8.8 format: 0x%04X\n", EddystoneTLM.getRawTemp()); BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); + oScanResponseData.setServiceData(BLEUUID((uint16_t)0xFEAA), String(EddystoneTLM.getData().c_str(), EddystoneTLM.getData().length())); - oScanResponseData.setFlags(0x06); // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 - oScanResponseData.setCompleteServices(BLEUUID(beconUUID)); - - beacon_data[0] = 0x20; // Eddystone Frame Type (Unencrypted Eddystone-TLM) - beacon_data[1] = 0x00; // TLM version - beacon_data[2] = (volt >> 8); // Battery voltage, 1 mV/bit i.e. 0xCE4 = 3300mV = 3.3V - beacon_data[3] = (volt & 0xFF); // - beacon_data[4] = (temp >> 8); // Beacon temperature - beacon_data[5] = (temp & 0xFF); // - beacon_data[6] = ((bootcount & 0xFF000000) >> 24); // Advertising PDU count - beacon_data[7] = ((bootcount & 0xFF0000) >> 16); // - beacon_data[8] = ((bootcount & 0xFF00) >> 8); // - beacon_data[9] = (bootcount & 0xFF); // - beacon_data[10] = ((lastTenth & 0xFF000000) >> 24); // Time since power-on or reboot as 0.1 second resolution counter - beacon_data[11] = ((lastTenth & 0xFF0000) >> 16); // - beacon_data[12] = ((lastTenth & 0xFF00) >> 8); // - beacon_data[13] = (lastTenth & 0xFF); // - - oScanResponseData.setServiceData(BLEUUID(beconUUID), std::string(beacon_data, 14)); - oAdvertisementData.setName("TLMBeacon"); + oAdvertisementData.setName("ESP32 TLM Beacon"); pAdvertising->setAdvertisementData(oAdvertisementData); pAdvertising->setScanResponseData(oScanResponseData); } @@ -95,7 +77,7 @@ void setup() // Create the BLE Device BLEDevice::init("TLMBeacon"); - BLEDevice::setPower(ESP_PWR_LVL_N12); + BLEDevice::setPower(BEACON_POWER); pAdvertising = BLEDevice::getAdvertising(); diff --git a/libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.md b/libraries/BLE/examples/EddystoneTLM_Beacon/EddystoneTLM_Beacon.md similarity index 100% rename from libraries/BLE/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.md rename to libraries/BLE/examples/EddystoneTLM_Beacon/EddystoneTLM_Beacon.md diff --git a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/.skip.esp32h2 b/libraries/BLE/examples/EddystoneURL_Beacon/.skip.esp32h2 similarity index 100% rename from libraries/BLE/examples/BLE_EddystoneURL_Beacon/.skip.esp32h2 rename to libraries/BLE/examples/EddystoneURL_Beacon/.skip.esp32h2 diff --git a/libraries/BLE/examples/BLE_client/.skip.esp32s2 b/libraries/BLE/examples/EddystoneURL_Beacon/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_client/.skip.esp32s2 rename to libraries/BLE/examples/EddystoneURL_Beacon/.skip.esp32s2 diff --git a/libraries/BLE/examples/EddystoneURL_Beacon/EddystoneURL_Beacon.ino b/libraries/BLE/examples/EddystoneURL_Beacon/EddystoneURL_Beacon.ino new file mode 100644 index 00000000000..d2d9b2d25d2 --- /dev/null +++ b/libraries/BLE/examples/EddystoneURL_Beacon/EddystoneURL_Beacon.ino @@ -0,0 +1,109 @@ +/* + EddystoneURL beacon by BeeGee + EddystoneURL frame specification https://github.com/google/eddystone/blob/master/eddystone-url/README.md + + Upgraded on: Feb 20, 2023 + By: Tomas Pilny +*/ + +/* + Create a BLE server that will send periodic Eddystone URL frames. + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create advertising data + 3. Start advertising. + 4. wait + 5. Stop advertising. + 6. deep sleep + +*/ +#include "sys/time.h" + +#include + +#include "BLEDevice.h" +#include "BLEUtils.h" +#include "BLEBeacon.h" +#include "BLEAdvertising.h" +#include "BLEEddystoneURL.h" +#include "esp_sleep.h" + +char unprintable[] = {0x01, 0xFF, 0xDE, 0xAD}; +String URL[] = { + "http://www.espressif.com/", // prefix 0x00, suffix 0x00 + "https://www.texas.gov", // prefix 0x01, suffix 0x0D + "http://en.mapy.cz", // prefix 0x02, no valid suffix + "https://arduino.cc", // prefix 0x03, no valid suffix + "google.com", // URL without specified prefix - the function will assume default prefix "http://www." = 0x00 + "diginfo.tv", // URL without specified prefix - the function will assume default prefix "http://www." = 0x00 +// "http://www.URLsAbove17BytesAreNotAllowed.com", // Too long URL - setSmartURL() will return 0 = ERR +// "", // Empty string - setSmartURL() will return 0 = ERR +// String(unprintable), // Unprintable characters / corrupted String - setSmartURL() will return 0 = ERR +}; + +#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up +#define BEACON_POWER ESP_PWR_LVL_N12 +RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory +RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ +BLEAdvertising *pAdvertising; +struct timeval now; + +int setBeacon() +{ + BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); + BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); + + BLEEddystoneURL EddystoneURL; + EddystoneURL.setPower(BEACON_POWER); // This is only information about the power. The actual power is set by `BLEDevice::setPower(BEACON_POWER)` + if(EddystoneURL.setSmartURL(URL[bootcount%(sizeof(URL)/sizeof(URL[0]))])){ + String frame = EddystoneURL.getFrame(); + String data(EddystoneURL.getFrame().c_str(), frame.length()); + oAdvertisementData.addData(data); + oScanResponseData.setName("ESP32 URLBeacon"); + pAdvertising->setAdvertisementData(oAdvertisementData); + pAdvertising->setScanResponseData(oScanResponseData); + Serial.printf("Advertise URL \"%s\"\n", URL[bootcount%(sizeof(URL)/sizeof(URL[0]))].c_str()); + return 1; // OK + }else{ + Serial.println("Smart URL set ERR"); + return 0; // ERR + } +} + +void setup() +{ + Serial.begin(115200); + gettimeofday(&now, NULL); + + Serial.printf("Start ESP32 %lu\n", bootcount++); + Serial.printf("Deep sleep (%llds since last reset, %llds since last boot)\n", now.tv_sec, now.tv_sec - last); + + last = now.tv_sec; + + // Create the BLE Device + BLEDevice::init("URLBeacon"); + BLEDevice::setPower(BEACON_POWER); + + // Create the BLE Server + // BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage + + pAdvertising = BLEDevice::getAdvertising(); + + if(setBeacon()){ + // Start advertising + pAdvertising->start(); + Serial.println("Advertising started..."); + delay(10000); + pAdvertising->stop(); + } + Serial.println("Enter deep sleep"); + bootcount++; + esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); +} + +void loop() +{ +} diff --git a/libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.md b/libraries/BLE/examples/EddystoneURL_Beacon/EddystoneURL_Beacon.md similarity index 100% rename from libraries/BLE/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.md rename to libraries/BLE/examples/EddystoneURL_Beacon/EddystoneURL_Beacon.md diff --git a/libraries/BLE/examples/BLE_iBeacon/.skip.esp32s2 b/libraries/BLE/examples/Notify/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_iBeacon/.skip.esp32s2 rename to libraries/BLE/examples/Notify/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_notify/BLE_notify.ino b/libraries/BLE/examples/Notify/Notify.ino similarity index 100% rename from libraries/BLE/examples/BLE_notify/BLE_notify.ino rename to libraries/BLE/examples/Notify/Notify.ino diff --git a/libraries/BLE/examples/BLE_notify/.skip.esp32s2 b/libraries/BLE/examples/Scan/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_notify/.skip.esp32s2 rename to libraries/BLE/examples/Scan/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_scan/BLE_scan.ino b/libraries/BLE/examples/Scan/Scan.ino similarity index 100% rename from libraries/BLE/examples/BLE_scan/BLE_scan.ino rename to libraries/BLE/examples/Scan/Scan.ino diff --git a/libraries/BLE/examples/BLE_scan/.skip.esp32s2 b/libraries/BLE/examples/Server/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_scan/.skip.esp32s2 rename to libraries/BLE/examples/Server/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_server/BLE_server.ino b/libraries/BLE/examples/Server/Server.ino similarity index 100% rename from libraries/BLE/examples/BLE_server/BLE_server.ino rename to libraries/BLE/examples/Server/Server.ino diff --git a/libraries/BLE/examples/BLE_server/.skip.esp32s2 b/libraries/BLE/examples/Server_multiconnect/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_server/.skip.esp32s2 rename to libraries/BLE/examples/Server_multiconnect/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_server_multiconnect/BLE_server_multiconnect.ino b/libraries/BLE/examples/Server_multiconnect/Server_multiconnect.ino similarity index 100% rename from libraries/BLE/examples/BLE_server_multiconnect/BLE_server_multiconnect.ino rename to libraries/BLE/examples/Server_multiconnect/Server_multiconnect.ino diff --git a/libraries/BLE/examples/BLE_server_multiconnect/.skip.esp32s2 b/libraries/BLE/examples/UART/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_server_multiconnect/.skip.esp32s2 rename to libraries/BLE/examples/UART/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_uart/BLE_uart.ino b/libraries/BLE/examples/UART/UART.ino similarity index 98% rename from libraries/BLE/examples/BLE_uart/BLE_uart.ino rename to libraries/BLE/examples/UART/UART.ino index 35b570b9192..3a50bf75499 100644 --- a/libraries/BLE/examples/BLE_uart/BLE_uart.ino +++ b/libraries/BLE/examples/UART/UART.ino @@ -50,7 +50,7 @@ class MyServerCallbacks: public BLEServerCallbacks { class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { - std::string rxValue = pCharacteristic->getValue(); + String rxValue = pCharacteristic->getValue(); if (rxValue.length() > 0) { Serial.println("*********"); diff --git a/libraries/BLE/examples/BLE_uart/.skip.esp32s2 b/libraries/BLE/examples/Write/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_uart/.skip.esp32s2 rename to libraries/BLE/examples/Write/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_write/BLE_write.ino b/libraries/BLE/examples/Write/Write.ino similarity index 97% rename from libraries/BLE/examples/BLE_write/BLE_write.ino rename to libraries/BLE/examples/Write/Write.ino index 24a0cd23d7a..138bfa603ef 100644 --- a/libraries/BLE/examples/BLE_write/BLE_write.ino +++ b/libraries/BLE/examples/Write/Write.ino @@ -16,7 +16,7 @@ class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { - std::string value = pCharacteristic->getValue(); + String value = pCharacteristic->getValue(); if (value.length() > 0) { Serial.println("*********"); diff --git a/libraries/BLE/examples/BLE_write/.skip.esp32s2 b/libraries/BLE/examples/iBeacon/.skip.esp32s2 similarity index 100% rename from libraries/BLE/examples/BLE_write/.skip.esp32s2 rename to libraries/BLE/examples/iBeacon/.skip.esp32s2 diff --git a/libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino b/libraries/BLE/examples/iBeacon/iBeacon.ino similarity index 95% rename from libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino rename to libraries/BLE/examples/iBeacon/iBeacon.ino index 5ebcec65077..e7885269520 100644 --- a/libraries/BLE/examples/BLE_iBeacon/BLE_iBeacon.ino +++ b/libraries/BLE/examples/iBeacon/iBeacon.ino @@ -49,7 +49,7 @@ class MyServerCallbacks: public BLEServerCallbacks { class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { - std::string rxValue = pCharacteristic->getValue(); + String rxValue = pCharacteristic->getValue(); if (rxValue.length() > 0) { Serial.println("*********"); diff --git a/libraries/BLE/library.properties b/libraries/BLE/library.properties index b7823141b0d..4f91de22f35 100644 --- a/libraries/BLE/library.properties +++ b/libraries/BLE/library.properties @@ -1,4 +1,4 @@ -name=ESP32 BLE Arduino +name=BLE version=2.0.0 author=Neil Kolban maintainer=Dariusz Krempa diff --git a/libraries/BLE/src/BLEAddress.cpp b/libraries/BLE/src/BLEAddress.cpp index 13f6501bf72..9bed3518116 100644 --- a/libraries/BLE/src/BLEAddress.cpp +++ b/libraries/BLE/src/BLEAddress.cpp @@ -42,7 +42,7 @@ BLEAddress::BLEAddress(esp_bd_addr_t address) { * * @param [in] stringAddress The hex representation of the address. */ -BLEAddress::BLEAddress(std::string stringAddress) { +BLEAddress::BLEAddress(String stringAddress) { if (stringAddress.length() != 17) return; int data[6]; @@ -109,11 +109,11 @@ esp_bd_addr_t *BLEAddress::getNative() { * * @return The string representation of the address. */ -std::string BLEAddress::toString() { +String BLEAddress::toString() { 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); + String ret(res); free(res); return ret; } // toString diff --git a/libraries/BLE/src/BLEAddress.h b/libraries/BLE/src/BLEAddress.h index 83f01879270..cca2c6c385b 100644 --- a/libraries/BLE/src/BLEAddress.h +++ b/libraries/BLE/src/BLEAddress.h @@ -8,6 +8,7 @@ #ifndef COMPONENTS_CPP_UTILS_BLEADDRESS_H_ #define COMPONENTS_CPP_UTILS_BLEADDRESS_H_ #include "soc/soc_caps.h" +#include "WString.h" #if SOC_BLE_SUPPORTED #include "sdkconfig.h" @@ -24,7 +25,7 @@ class BLEAddress { public: BLEAddress(esp_bd_addr_t address); - BLEAddress(std::string stringAddress); + BLEAddress(String stringAddress); bool equals(BLEAddress otherAddress); bool operator==(const BLEAddress& otherAddress) const; bool operator!=(const BLEAddress& otherAddress) const; @@ -32,8 +33,8 @@ class BLEAddress { bool operator<=(const BLEAddress& otherAddress) const; bool operator>(const BLEAddress& otherAddress) const; bool operator>=(const BLEAddress& otherAddress) const; - esp_bd_addr_t* getNative(); - std::string toString(); + esp_bd_addr_t* getNative(); + String toString(); private: esp_bd_addr_t m_address; diff --git a/libraries/BLE/src/BLEAdvertisedDevice.cpp b/libraries/BLE/src/BLEAdvertisedDevice.cpp index 03e15ce16b8..987d5c13876 100644 --- a/libraries/BLE/src/BLEAdvertisedDevice.cpp +++ b/libraries/BLE/src/BLEAdvertisedDevice.cpp @@ -72,7 +72,7 @@ uint16_t BLEAdvertisedDevice::getAppearance() { * @brief Get the manufacturer data. * @return The manufacturer data of the advertised device. */ -std::string BLEAdvertisedDevice::getManufacturerData() { +String BLEAdvertisedDevice::getManufacturerData() { return m_manufacturerData; } // getManufacturerData @@ -81,7 +81,7 @@ std::string BLEAdvertisedDevice::getManufacturerData() { * @brief Get the name. * @return The name of the advertised device. */ -std::string BLEAdvertisedDevice::getName() { +String BLEAdvertisedDevice::getName() { return m_name; } // getName @@ -115,15 +115,15 @@ int BLEAdvertisedDevice::getServiceDataCount() { * @brief Get the service data. * @return The ServiceData of the advertised device. */ -std::string BLEAdvertisedDevice::getServiceData() { - return m_serviceData.empty() ? std::string() : m_serviceData.front(); +String BLEAdvertisedDevice::getServiceData() { + return m_serviceData.empty() ? String() : m_serviceData.front(); } //getServiceData /** * @brief Get the service data. * @return The ServiceData of the advertised device. */ -std::string BLEAdvertisedDevice::getServiceData(int i) { +String BLEAdvertisedDevice::getServiceData(int i) { return m_serviceData[i]; } //getServiceData @@ -296,7 +296,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len) switch(ad_type) { case ESP_BLE_AD_TYPE_NAME_CMPL: { // Adv Data Type: 0x09 - setName(std::string(reinterpret_cast(payload), length)); + setName(String(reinterpret_cast(payload), length)); break; } // ESP_BLE_AD_TYPE_NAME_CMPL @@ -343,7 +343,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len) // See CSS Part A 1.4 Manufacturer Specific Data case ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE: { - setManufacturerData(std::string(reinterpret_cast(payload), length)); + setManufacturerData(String(reinterpret_cast(payload), length)); break; } // ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE @@ -355,7 +355,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len) uint16_t uuid = *(uint16_t*)payload; setServiceDataUUID(BLEUUID(uuid)); if (length > 2) { - setServiceData(std::string(reinterpret_cast(payload + 2), length - 2)); + setServiceData(String(reinterpret_cast(payload + 2), length - 2)); } break; } //ESP_BLE_AD_TYPE_SERVICE_DATA @@ -368,7 +368,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len) uint32_t uuid = *(uint32_t*) payload; setServiceDataUUID(BLEUUID(uuid)); if (length > 4) { - setServiceData(std::string(reinterpret_cast(payload + 4), length - 4)); + setServiceData(String(reinterpret_cast(payload + 4), length - 4)); } break; } //ESP_BLE_AD_TYPE_32SERVICE_DATA @@ -381,7 +381,7 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len) setServiceDataUUID(BLEUUID(payload, (size_t)16, false)); if (length > 16) { - setServiceData(std::string(reinterpret_cast(payload + 16), length - 16)); + setServiceData(String(reinterpret_cast(payload + 16), length - 16)); } break; } //ESP_BLE_AD_TYPE_32SERVICE_DATA @@ -444,10 +444,10 @@ void BLEAdvertisedDevice::setAppearance(uint16_t appearance) { * @brief Set the manufacturer data for this device. * @param [in] The discovered manufacturer data. */ -void BLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) { +void BLEAdvertisedDevice::setManufacturerData(String manufacturerData) { m_manufacturerData = manufacturerData; m_haveManufacturerData = true; - char* pHex = BLEUtils::buildHexData(nullptr, (uint8_t*) m_manufacturerData.data(), (uint8_t) m_manufacturerData.length()); + char* pHex = BLEUtils::buildHexData(nullptr, (uint8_t*) m_manufacturerData.c_str(), (uint8_t) m_manufacturerData.length()); log_d("- manufacturer data: %s", pHex); free(pHex); } // setManufacturerData @@ -457,7 +457,7 @@ void BLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) { * @brief Set the name for this device. * @param [in] name The discovered name. */ -void BLEAdvertisedDevice::setName(std::string name) { +void BLEAdvertisedDevice::setName(String name) { m_name = name; m_haveName = true; log_d("- setName(): name: %s", m_name.c_str()); @@ -507,7 +507,7 @@ void BLEAdvertisedDevice::setServiceUUID(BLEUUID serviceUUID) { * @brief Set the ServiceData value. * @param [in] data ServiceData value. */ -void BLEAdvertisedDevice::setServiceData(std::string serviceData) { +void BLEAdvertisedDevice::setServiceData(String serviceData) { m_serviceData.push_back(serviceData); // Save the service data that we received. } //setServiceData @@ -537,8 +537,8 @@ void BLEAdvertisedDevice::setTXPower(int8_t txPower) { * @brief Create a string representation of this device. * @return A string representation of this device. */ -std::string BLEAdvertisedDevice::toString() { - std::string res = "Name: " + getName() + ", Address: " + getAddress().toString(); +String BLEAdvertisedDevice::toString() { + String res = "Name: " + getName() + ", Address: " + getAddress().toString(); if (haveAppearance()) { char val[6]; snprintf(val, sizeof(val), "%d", getAppearance()); @@ -546,7 +546,7 @@ std::string BLEAdvertisedDevice::toString() { res += val; } if (haveManufacturerData()) { - char *pHex = BLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().data(), getManufacturerData().length()); + char *pHex = BLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().c_str(), getManufacturerData().length()); res += ", manufacturer data: "; res += pHex; free(pHex); @@ -584,6 +584,22 @@ esp_ble_addr_type_t BLEAdvertisedDevice::getAddressType() { return m_addressType; } +ble_frame_type_t BLEAdvertisedDevice::getFrameType(){ + for(int i = 0; i < m_payloadLength; ++i){ + log_d("check [%d]=0x%02X", i, m_payload[i]); + if(m_payload[i] == 0x16 && m_payloadLength >= i+3 && m_payload[i+1] == 0xAA && m_payload[i+2] == 0xFE && m_payload[i+3] == 0x00){ + return BLE_EDDYSTONE_UUID_FRAME; + } + if(m_payload[i] == 0x16 && m_payloadLength >= i+3 && m_payload[i+1] == 0xAA && m_payload[i+2] == 0xFE && m_payload[i+3] == 0x10){ + return BLE_EDDYSTONE_URL_FRAME; + } + if(m_payload[i] == 0x16 && m_payloadLength >= i+3 && m_payload[i+1] == 0xAA && m_payload[i+2] == 0xFE && m_payload[i+3] == 0x20){ + return BLE_EDDYSTONE_TLM_FRAME; + } + } + return BLE_UNKNOWN_FRAME; +} + void BLEAdvertisedDevice::setAddressType(esp_ble_addr_type_t type) { m_addressType = type; } diff --git a/libraries/BLE/src/BLEAdvertisedDevice.h b/libraries/BLE/src/BLEAdvertisedDevice.h index 5d05c26343b..e449a0c0799 100644 --- a/libraries/BLE/src/BLEAdvertisedDevice.h +++ b/libraries/BLE/src/BLEAdvertisedDevice.h @@ -9,17 +9,24 @@ #define COMPONENTS_CPP_UTILS_BLEADVERTISEDDEVICE_H_ #include "soc/soc_caps.h" #if SOC_BLE_SUPPORTED + #include "sdkconfig.h" #if defined(CONFIG_BLUEDROID_ENABLED) #include #include -#include #include "BLEAddress.h" #include "BLEScan.h" #include "BLEUUID.h" +typedef enum { + BLE_UNKNOWN_FRAME, + BLE_EDDYSTONE_UUID_FRAME, + BLE_EDDYSTONE_URL_FRAME, + BLE_EDDYSTONE_TLM_FRAME, + BLE_FRAME_MAX +} ble_frame_type_t; class BLEScan; /** @@ -34,12 +41,12 @@ class BLEAdvertisedDevice { BLEAddress getAddress(); uint16_t getAppearance(); - std::string getManufacturerData(); - std::string getName(); + String getManufacturerData(); + String getName(); int getRSSI(); BLEScan* getScan(); - std::string getServiceData(); - std::string getServiceData(int i); + String getServiceData(); + String getServiceData(int i); BLEUUID getServiceDataUUID(); BLEUUID getServiceDataUUID(int i); BLEUUID getServiceUUID(); @@ -48,9 +55,10 @@ class BLEAdvertisedDevice { int getServiceDataUUIDCount(); int getServiceUUIDCount(); int8_t getTXPower(); - uint8_t* getPayload(); - size_t getPayloadLength(); + uint8_t* getPayload(); + size_t getPayloadLength(); esp_ble_addr_type_t getAddressType(); + ble_frame_type_t getFrameType(); void setAddressType(esp_ble_addr_type_t type); @@ -63,7 +71,7 @@ class BLEAdvertisedDevice { bool haveServiceUUID(); bool haveTXPower(); - std::string toString(); + String toString(); private: friend class BLEScan; @@ -74,11 +82,11 @@ class BLEAdvertisedDevice { void setAdFlag(uint8_t adFlag); void setAdvertizementResult(uint8_t* payload); void setAppearance(uint16_t appearance); - void setManufacturerData(std::string manufacturerData); - void setName(std::string name); + void setManufacturerData(String manufacturerData); + void setName(String name); void setRSSI(int rssi); void setScan(BLEScan* pScan); - void setServiceData(std::string data); + void setServiceData(String data); void setServiceDataUUID(BLEUUID uuid); void setServiceUUID(const char* serviceUUID); void setServiceUUID(BLEUUID serviceUUID); @@ -95,13 +103,13 @@ class BLEAdvertisedDevice { uint8_t m_adFlag; uint16_t m_appearance; int m_deviceType; - std::string m_manufacturerData; - std::string m_name; + String m_manufacturerData; + String m_name; BLEScan* m_pScan; int m_rssi; std::vector m_serviceUUIDs; int8_t m_txPower; - std::vector m_serviceData; + std::vector m_serviceData; std::vector m_serviceDataUUIDs; uint8_t* m_payload; size_t m_payloadLength = 0; diff --git a/libraries/BLE/src/BLEAdvertising.cpp b/libraries/BLE/src/BLEAdvertising.cpp index 30ff7644999..0c105cfb8d3 100644 --- a/libraries/BLE/src/BLEAdvertising.cpp +++ b/libraries/BLE/src/BLEAdvertising.cpp @@ -155,7 +155,7 @@ void BLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connectWh void BLEAdvertising::setAdvertisementData(BLEAdvertisementData& advertisementData) { log_v(">> setAdvertisementData"); esp_err_t errRc = ::esp_ble_gap_config_adv_data_raw( - (uint8_t*)advertisementData.getPayload().data(), + (uint8_t*)advertisementData.getPayload().c_str(), advertisementData.getPayload().length()); if (errRc != ESP_OK) { log_e("esp_ble_gap_config_adv_data_raw: %d %s", errRc, GeneralUtils::errorToString(errRc)); @@ -172,7 +172,7 @@ void BLEAdvertising::setAdvertisementData(BLEAdvertisementData& advertisementDat void BLEAdvertising::setScanResponseData(BLEAdvertisementData& advertisementData) { log_v(">> setScanResponseData"); esp_err_t errRc = ::esp_ble_gap_config_scan_rsp_data_raw( - (uint8_t*)advertisementData.getPayload().data(), + (uint8_t*)advertisementData.getPayload().c_str(), advertisementData.getPayload().length()); if (errRc != ESP_OK) { log_e("esp_ble_gap_config_scan_rsp_data_raw: %d %s", errRc, GeneralUtils::errorToString(errRc)); @@ -296,11 +296,11 @@ void BLEAdvertising::setDeviceAddress(esp_bd_addr_t addr, esp_ble_addr_type_t ty * @brief Add data to the payload to be advertised. * @param [in] data The data to be added to the payload. */ -void BLEAdvertisementData::addData(std::string data) { +void BLEAdvertisementData::addData(String data) { if ((m_payload.length() + data.length()) > ESP_BLE_ADV_DATA_LEN_MAX) { return; } - m_payload.append(data); + m_payload.concat(data); } // addData @@ -315,7 +315,7 @@ void BLEAdvertisementData::setAppearance(uint16_t appearance) { char cdata[2]; cdata[0] = 3; cdata[1] = ESP_BLE_AD_TYPE_APPEARANCE; // 0x19 - addData(std::string(cdata, 2) + std::string((char*) &appearance, 2)); + addData(String(cdata, 2) + String((char*) &appearance, 2)); } // setAppearance @@ -330,7 +330,7 @@ void BLEAdvertisementData::setCompleteServices(BLEUUID uuid) { // [Len] [0x02] [LL] [HH] cdata[0] = 3; cdata[1] = ESP_BLE_AD_TYPE_16SRV_CMPL; // 0x03 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->uuid.uuid16, 2)); + addData(String(cdata, 2) + String((char*) &uuid.getNative()->uuid.uuid16, 2)); break; } @@ -338,7 +338,7 @@ void BLEAdvertisementData::setCompleteServices(BLEUUID uuid) { // [Len] [0x04] [LL] [LL] [HH] [HH] cdata[0] = 5; cdata[1] = ESP_BLE_AD_TYPE_32SRV_CMPL; // 0x05 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->uuid.uuid32, 4)); + addData(String(cdata, 2) + String((char*) &uuid.getNative()->uuid.uuid32, 4)); break; } @@ -346,7 +346,7 @@ void BLEAdvertisementData::setCompleteServices(BLEUUID uuid) { // [Len] [0x04] [0] [1] ... [15] cdata[0] = 17; cdata[1] = ESP_BLE_AD_TYPE_128SRV_CMPL; // 0x07 - addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->uuid.uuid128, 16)); + addData(String(cdata, 2) + String((char*) uuid.getNative()->uuid.uuid128, 16)); break; } @@ -372,7 +372,7 @@ void BLEAdvertisementData::setFlags(uint8_t flag) { cdata[0] = 2; cdata[1] = ESP_BLE_AD_TYPE_FLAG; // 0x01 cdata[2] = flag; - addData(std::string(cdata, 3)); + addData(String(cdata, 3)); } // setFlag @@ -381,12 +381,12 @@ void BLEAdvertisementData::setFlags(uint8_t flag) { * @brief Set manufacturer specific data. * @param [in] data Manufacturer data. */ -void BLEAdvertisementData::setManufacturerData(std::string data) { +void BLEAdvertisementData::setManufacturerData(String data) { 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); + addData(String(cdata, 2) + data); log_d("BLEAdvertisementData", "<< setManufacturerData"); } // setManufacturerData @@ -395,12 +395,12 @@ void BLEAdvertisementData::setManufacturerData(std::string data) { * @brief Set the name. * @param [in] The complete name of the device. */ -void BLEAdvertisementData::setName(std::string name) { +void BLEAdvertisementData::setName(String name) { 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); + addData(String(cdata, 2) + name); log_d("BLEAdvertisementData", "<< setName"); } // setName @@ -416,7 +416,7 @@ void BLEAdvertisementData::setPartialServices(BLEUUID uuid) { // [Len] [0x02] [LL] [HH] cdata[0] = 3; cdata[1] = ESP_BLE_AD_TYPE_16SRV_PART; // 0x02 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->uuid.uuid16, 2)); + addData(String(cdata, 2) + String((char *) &uuid.getNative()->uuid.uuid16, 2)); break; } @@ -424,7 +424,7 @@ void BLEAdvertisementData::setPartialServices(BLEUUID uuid) { // [Len] [0x04] [LL] [LL] [HH] [HH] cdata[0] = 5; cdata[1] = ESP_BLE_AD_TYPE_32SRV_PART; // 0x04 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->uuid.uuid32, 4)); + addData(String(cdata, 2) + String((char *) &uuid.getNative()->uuid.uuid32, 4)); break; } @@ -432,7 +432,7 @@ void BLEAdvertisementData::setPartialServices(BLEUUID uuid) { // [Len] [0x04] [0] [1] ... [15] cdata[0] = 17; cdata[1] = ESP_BLE_AD_TYPE_128SRV_PART; // 0x06 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->uuid.uuid128, 16)); + addData(String(cdata, 2) + String((char *) &uuid.getNative()->uuid.uuid128, 16)); break; } @@ -447,14 +447,14 @@ void BLEAdvertisementData::setPartialServices(BLEUUID uuid) { * @param [in] uuid The UUID to set with the service data. Size of UUID will be used. * @param [in] data The data to be associated with the service data advert. */ -void BLEAdvertisementData::setServiceData(BLEUUID uuid, std::string data) { +void BLEAdvertisementData::setServiceData(BLEUUID uuid, String data) { char cdata[2]; switch (uuid.bitSize()) { case 16: { // [Len] [0x16] [UUID16] data cdata[0] = data.length() + 3; cdata[1] = ESP_BLE_AD_TYPE_SERVICE_DATA; // 0x16 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->uuid.uuid16, 2) + data); + addData(String(cdata, 2) + String((char*) &uuid.getNative()->uuid.uuid16, 2) + data); break; } @@ -462,7 +462,7 @@ void BLEAdvertisementData::setServiceData(BLEUUID uuid, std::string data) { // [Len] [0x20] [UUID32] data cdata[0] = data.length() + 5; cdata[1] = ESP_BLE_AD_TYPE_32SERVICE_DATA; // 0x20 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->uuid.uuid32, 4) + data); + addData(String(cdata, 2) + String((char*) &uuid.getNative()->uuid.uuid32, 4) + data); break; } @@ -470,7 +470,7 @@ void BLEAdvertisementData::setServiceData(BLEUUID uuid, std::string data) { // [Len] [0x21] [UUID128] data cdata[0] = data.length() + 17; cdata[1] = ESP_BLE_AD_TYPE_128SERVICE_DATA; // 0x21 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->uuid.uuid128, 16) + data); + addData(String(cdata, 2) + String((char*) &uuid.getNative()->uuid.uuid128, 16) + data); break; } @@ -484,12 +484,12 @@ void BLEAdvertisementData::setServiceData(BLEUUID uuid, std::string data) { * @brief Set the short name. * @param [in] The short name of the device. */ -void BLEAdvertisementData::setShortName(std::string name) { +void BLEAdvertisementData::setShortName(String name) { 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); + addData(String(cdata, 2) + name); log_d("BLEAdvertisementData", "<< setShortName"); } // setShortName @@ -498,7 +498,7 @@ void BLEAdvertisementData::setShortName(std::string name) { * @brief Retrieve the payload that is to be advertised. * @return The payload that is to be advertised. */ -std::string BLEAdvertisementData::getPayload() { +String BLEAdvertisementData::getPayload() { return m_payload; } // getPayload diff --git a/libraries/BLE/src/BLEAdvertising.h b/libraries/BLE/src/BLEAdvertising.h index 4236c25e3c1..775400f557b 100644 --- a/libraries/BLE/src/BLEAdvertising.h +++ b/libraries/BLE/src/BLEAdvertising.h @@ -28,17 +28,17 @@ class BLEAdvertisementData { void setAppearance(uint16_t appearance); void setCompleteServices(BLEUUID uuid); void setFlags(uint8_t); - void setManufacturerData(std::string data); - void setName(std::string name); + void setManufacturerData(String data); + void setName(String name); void setPartialServices(BLEUUID uuid); - void setServiceData(BLEUUID uuid, std::string data); - void setShortName(std::string name); - void addData(std::string data); // Add data to the payload. - std::string getPayload(); // Retrieve the current advert payload. + void setServiceData(BLEUUID uuid, String data); + void setShortName(String name); + void addData(String data); // Add data to the payload. + String getPayload(); // Retrieve the current advert payload. private: friend class BLEAdvertising; - std::string m_payload; // The payload of the advertisement. + String m_payload; // The payload of the advertisement. }; // BLEAdvertisementData diff --git a/libraries/BLE/src/BLEBeacon.cpp b/libraries/BLE/src/BLEBeacon.cpp index 512300a5223..641ac47cd8c 100644 --- a/libraries/BLE/src/BLEBeacon.cpp +++ b/libraries/BLE/src/BLEBeacon.cpp @@ -9,7 +9,6 @@ #include "sdkconfig.h" #if defined(CONFIG_BLUEDROID_ENABLED) -#include #include "BLEBeacon.h" #include "esp32-hal-log.h" @@ -26,8 +25,8 @@ BLEBeacon::BLEBeacon() { memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID)); } // BLEBeacon -std::string BLEBeacon::getData() { - return std::string((char*) &m_beaconData, sizeof(m_beaconData)); +String BLEBeacon::getData() { + return String((char*) &m_beaconData, sizeof(m_beaconData)); } // getData uint16_t BLEBeacon::getMajor() { @@ -53,12 +52,12 @@ int8_t BLEBeacon::getSignalPower() { /** * Set the raw data for the beacon record. */ -void BLEBeacon::setData(std::string data) { +void BLEBeacon::setData(String data) { if (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)); + memcpy(&m_beaconData, data.c_str(), sizeof(m_beaconData)); } // setData void BLEBeacon::setMajor(uint16_t major) { diff --git a/libraries/BLE/src/BLEBeacon.h b/libraries/BLE/src/BLEBeacon.h index 27c811e8d1e..2adcda6abcb 100644 --- a/libraries/BLE/src/BLEBeacon.h +++ b/libraries/BLE/src/BLEBeacon.h @@ -29,13 +29,13 @@ class BLEBeacon { } __attribute__((packed)) m_beaconData; public: BLEBeacon(); - std::string getData(); + String getData(); uint16_t getMajor(); uint16_t getMinor(); uint16_t getManufacturerId(); BLEUUID getProximityUUID(); int8_t getSignalPower(); - void setData(std::string data); + void setData(String data); void setMajor(uint16_t major); void setMinor(uint16_t minor); void setManufacturerId(uint16_t manufacturerId); diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 62c478582e6..d4ac6a7039b 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -178,7 +178,7 @@ BLEUUID BLECharacteristic::getUUID() { * @brief Retrieve the current value of the characteristic. * @return A pointer to storage containing the current characteristic value. */ -std::string BLECharacteristic::getValue() { +String BLECharacteristic::getValue() { return m_value.getValue(); } // getValue @@ -376,19 +376,19 @@ void BLECharacteristic::handleGATTServerEvent( esp_gatt_rsp_t rsp; if (param->read.is_long) { - std::string value = m_value.getValue(); + String value = m_value.getValue(); if (value.length() - m_value.getReadOffset() < maxOffset) { // This is the last in the chain rsp.attr_value.len = value.length() - m_value.getReadOffset(); rsp.attr_value.offset = m_value.getReadOffset(); - memcpy(rsp.attr_value.value, value.data() + rsp.attr_value.offset, rsp.attr_value.len); + memcpy(rsp.attr_value.value, value.c_str() + rsp.attr_value.offset, rsp.attr_value.len); m_value.setReadOffset(0); } else { // There will be more to come. rsp.attr_value.len = maxOffset; rsp.attr_value.offset = m_value.getReadOffset(); - memcpy(rsp.attr_value.value, value.data() + rsp.attr_value.offset, rsp.attr_value.len); + memcpy(rsp.attr_value.value, value.c_str() + rsp.attr_value.offset, rsp.attr_value.len); m_value.setReadOffset(rsp.attr_value.offset + maxOffset); } } else { // read.is_long == false @@ -397,19 +397,19 @@ void BLECharacteristic::handleGATTServerEvent( // Invoke the read callback. m_pCallbacks->onRead(this, param); - std::string value = m_value.getValue(); + String value = m_value.getValue(); if (value.length() + 1 > maxOffset) { // Too big for a single shot entry. m_value.setReadOffset(maxOffset); rsp.attr_value.len = maxOffset; rsp.attr_value.offset = 0; - memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len); + memcpy(rsp.attr_value.value, value.c_str(), rsp.attr_value.len); } else { // Will fit in a single packet with no callbacks required. rsp.attr_value.len = value.length(); rsp.attr_value.offset = 0; - memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len); + memcpy(rsp.attr_value.value, value.c_str(), rsp.attr_value.len); } } rsp.attr_value.handle = param->read.handle; @@ -497,7 +497,7 @@ void BLECharacteristic::notify(bool is_notification) { m_pCallbacks->onNotify(this); // Invoke the notify callback. - GeneralUtils::hexDump((uint8_t*)m_value.getValue().data(), m_value.getValue().length()); + GeneralUtils::hexDump((uint8_t*)m_value.getValue().c_str(), m_value.getValue().length()); if (getService()->getServer()->getConnectedCount() == 0) { log_v("<< notify: No connected clients."); @@ -535,7 +535,7 @@ void BLECharacteristic::notify(bool is_notification) { 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. + getHandle(), length, (uint8_t*)m_value.getValue().c_str(), !is_notification); // The need_confirm = false makes this a notify. if (errRc != ESP_OK) { log_e("<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc)); m_semaphoreConfEvt.give(); @@ -679,8 +679,8 @@ void BLECharacteristic::setValue(uint8_t* data, size_t length) { * @param [in] Set the value of the characteristic. * @return N/A. */ -void BLECharacteristic::setValue(std::string value) { - setValue((uint8_t*)(value.data()), value.length()); +void BLECharacteristic::setValue(String value) { + setValue((uint8_t*)(value.c_str()), value.length()); } // setValue void BLECharacteristic::setValue(uint16_t& data16) { @@ -751,8 +751,8 @@ void BLECharacteristic::setWriteProperty(bool value) { * @brief Return a string representation of the characteristic. * @return A string representation of the characteristic. */ -std::string BLECharacteristic::toString() { - std::string res = "UUID: " + m_bleUUID.toString() + ", handle : 0x"; +String BLECharacteristic::toString() { + String res = "UUID: " + m_bleUUID.toString() + ", handle : 0x"; char hex[5]; snprintf(hex, sizeof(hex), "%04x", m_handle); res += hex; diff --git a/libraries/BLE/src/BLECharacteristic.h b/libraries/BLE/src/BLECharacteristic.h index 2a87d8f0aa7..3ff9397475d 100644 --- a/libraries/BLE/src/BLECharacteristic.h +++ b/libraries/BLE/src/BLECharacteristic.h @@ -36,14 +36,14 @@ class BLEDescriptorMap { BLEDescriptor* getByUUID(const char* uuid); BLEDescriptor* getByUUID(BLEUUID uuid); BLEDescriptor* getByHandle(uint16_t handle); - std::string toString(); + String toString(); void handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param); BLEDescriptor* getFirst(); BLEDescriptor* getNext(); private: - std::map m_uuidMap; + std::map m_uuidMap; std::map m_handleMap; - std::map::iterator m_iterator; + std::map::iterator m_iterator; }; @@ -63,7 +63,7 @@ class BLECharacteristic { BLEDescriptor* getDescriptorByUUID(const char* descriptorUUID); BLEDescriptor* getDescriptorByUUID(BLEUUID descriptorUUID); BLEUUID getUUID(); - std::string getValue(); + String getValue(); uint8_t* getData(); size_t getLength(); @@ -75,7 +75,7 @@ class BLECharacteristic { void setNotifyProperty(bool value); void setReadProperty(bool value); void setValue(uint8_t* data, size_t size); - void setValue(std::string value); + void setValue(String value); void setValue(uint16_t& data16); void setValue(uint32_t& data32); void setValue(int& data32); @@ -83,7 +83,7 @@ class BLECharacteristic { void setValue(double& data64); void setWriteProperty(bool value); void setWriteNoResponseProperty(bool value); - std::string toString(); + String toString(); uint16_t getHandle(); void setAccessPermissions(esp_gatt_perm_t perm); diff --git a/libraries/BLE/src/BLECharacteristicMap.cpp b/libraries/BLE/src/BLECharacteristicMap.cpp index 2348c290481..c574b53edcd 100644 --- a/libraries/BLE/src/BLECharacteristicMap.cpp +++ b/libraries/BLE/src/BLECharacteristicMap.cpp @@ -23,7 +23,7 @@ * @return The characteristic. */ BLECharacteristic* BLECharacteristicMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); + return m_handleMap.at(handle); } // getByHandle @@ -43,13 +43,13 @@ BLECharacteristic* BLECharacteristicMap::getByUUID(const char* uuid) { * @return The characteristic. */ BLECharacteristic* BLECharacteristicMap::getByUUID(BLEUUID uuid) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } - //return m_uuidMap.at(uuid.toString()); - return nullptr; + for (auto &myPair : m_uuidMap) { + if (myPair.first->getUUID().equals(uuid)) { + return myPair.first; + } + } + //return m_uuidMap.at(uuid.toString()); + return nullptr; } // getByUUID @@ -58,11 +58,11 @@ BLECharacteristic* BLECharacteristicMap::getByUUID(BLEUUID uuid) { * @return The first characteristic in the map. */ BLECharacteristic* BLECharacteristicMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - BLECharacteristic* pRet = m_iterator->first; - m_iterator++; - return pRet; + m_iterator = m_uuidMap.begin(); + if (m_iterator == m_uuidMap.end()) return nullptr; + BLECharacteristic* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getFirst @@ -71,10 +71,10 @@ BLECharacteristic* BLECharacteristicMap::getFirst() { * @return The next characteristic in the map. */ BLECharacteristic* BLECharacteristicMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - BLECharacteristic* pRet = m_iterator->first; - m_iterator++; - return pRet; + if (m_iterator == m_uuidMap.end()) return nullptr; + BLECharacteristic* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getNext @@ -85,10 +85,10 @@ BLECharacteristic* BLECharacteristicMap::getNext() { * @param [in] param */ void BLECharacteristicMap::handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param) { - // Invoke the handler for every Service we have. - for (auto& myPair : m_uuidMap) { - myPair.first->handleGATTServerEvent(event, gatts_if, param); - } + // Invoke the handler for every Service we have. + for (auto& myPair : m_uuidMap) { + myPair.first->handleGATTServerEvent(event, gatts_if, param); + } } // handleGATTServerEvent @@ -99,7 +99,7 @@ void BLECharacteristicMap::handleGATTServerEvent(esp_gatts_cb_event_t event, esp * @return N/A. */ void BLECharacteristicMap::setByHandle(uint16_t handle, BLECharacteristic* characteristic) { - m_handleMap.insert(std::pair(handle, characteristic)); + m_handleMap.insert(std::pair(handle, characteristic)); } // setByHandle @@ -110,7 +110,7 @@ void BLECharacteristicMap::setByHandle(uint16_t handle, BLECharacteristic* chara * @return N/A. */ void BLECharacteristicMap::setByUUID(BLECharacteristic* pCharacteristic, BLEUUID uuid) { - m_uuidMap.insert(std::pair(pCharacteristic, uuid.toString())); + m_uuidMap.insert(std::pair(pCharacteristic, uuid.toString())); } // setByUUID @@ -118,19 +118,19 @@ void BLECharacteristicMap::setByUUID(BLECharacteristic* pCharacteristic, BLEUUID * @brief Return a string representation of the characteristic map. * @return A string representation of the characteristic map. */ -std::string BLECharacteristicMap::toString() { - std::string res; - int count = 0; - char hex[5]; - for (auto &myPair: m_uuidMap) { - if (count > 0) {res += "\n";} - snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); - count++; - res += "handle: 0x"; - res += hex; - res += ", uuid: " + myPair.first->getUUID().toString(); - } - return res; +String BLECharacteristicMap::toString() { + String res; + int count = 0; + char hex[5]; + for (auto &myPair: m_uuidMap) { + if (count > 0) {res += "\n";} + snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); + count++; + res += "handle: 0x"; + res += hex; + res += ", uuid: " + myPair.first->getUUID().toString(); + } + return res; } // toString diff --git a/libraries/BLE/src/BLEClient.cpp b/libraries/BLE/src/BLEClient.cpp index 7ccfdb05d3f..ae82c2417a1 100644 --- a/libraries/BLE/src/BLEClient.cpp +++ b/libraries/BLE/src/BLEClient.cpp @@ -46,11 +46,11 @@ */ BLEClient::BLEClient() { - m_pClientCallbacks = nullptr; - m_conn_id = ESP_GATT_IF_NONE; - m_gattc_if = ESP_GATT_IF_NONE; - m_haveServices = false; - m_isConnected = false; // Initially, we are flagged as not connected. + m_pClientCallbacks = nullptr; + m_conn_id = ESP_GATT_IF_NONE; + m_gattc_if = ESP_GATT_IF_NONE; + m_haveServices = false; + m_isConnected = false; // Initially, we are flagged as not connected. } // BLEClient @@ -58,13 +58,13 @@ BLEClient::BLEClient() { * @brief Destructor. */ BLEClient::~BLEClient() { - // We may have allocated service references associated with this client. Before we are finished - // with the client, we must release resources. - for (auto &myPair : m_servicesMap) { - delete myPair.second; - } - m_servicesMap.clear(); - m_servicesMapByInstID.clear(); + // We may have allocated service references associated with this client. Before we are finished + // with the client, we must release resources. + for (auto &myPair : m_servicesMap) { + delete myPair.second; + } + m_servicesMap.clear(); + m_servicesMapByInstID.clear(); } // ~BLEClient @@ -73,23 +73,23 @@ BLEClient::~BLEClient() { * */ void BLEClient::clearServices() { - log_v(">> clearServices"); - // Delete all the services. - for (auto &myPair : m_servicesMap) { - delete myPair.second; - } - m_servicesMap.clear(); - m_haveServices = false; - log_v("<< clearServices"); + log_v(">> clearServices"); + // Delete all the services. + for (auto &myPair : m_servicesMap) { + delete myPair.second; + } + m_servicesMap.clear(); + m_haveServices = false; + log_v("<< clearServices"); } // clearServices /** * Add overloaded function to ease connect to peer device with not public address */ bool BLEClient::connect(BLEAdvertisedDevice* device) { - BLEAddress address = device->getAddress(); - esp_ble_addr_type_t type = device->getAddressType(); - return connect(address, type); + BLEAddress address = device->getAddress(); + esp_ble_addr_type_t type = device->getAddressType(); + return connect(address, type); } /** @@ -98,59 +98,59 @@ bool BLEClient::connect(BLEAdvertisedDevice* device) { * @return True on success. */ bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) { - log_v(">> 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. - m_appId = BLEDevice::m_appId++; - BLEDevice::addPeerDevice(this, true, m_appId); - m_semaphoreRegEvt.take("connect"); - - // 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) { - log_e("esp_ble_gattc_app_register: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - BLEDevice::removePeerDevice(m_appId, true); - return false; - } - - uint32_t rc = m_semaphoreRegEvt.wait("connect"); - - if (rc != ESP_GATT_OK) { - // fixes ESP_GATT_NO_RESOURCES error mostly - log_e("esp_ble_gattc_app_register_error: rc=%d", rc); - BLEDevice::removePeerDevice(m_appId, true); - // not sure if this is needed here - // esp_ble_gattc_app_unregister(m_gattc_if); - // m_gattc_if = ESP_GATT_IF_NONE; - return false; - } - - m_peerAddress = address; - - // Perform the open connection request against the target BLE Server. - m_semaphoreOpenEvt.take("connect"); - errRc = ::esp_ble_gattc_open( - m_gattc_if, - *getPeerAddress().getNative(), // address - type, // Note: This was added on 2018-04-03 when the latest ESP-IDF was detected to have changed the signature. - 1 // direct connection <-- maybe needs to be changed in case of direct indirect connection??? - ); - if (errRc != ESP_OK) { - log_e("esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - BLEDevice::removePeerDevice(m_appId, true); - return false; - } - - rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. - // check the status of the connection and cleanup in case of failure - if (rc != ESP_GATT_OK) { - BLEDevice::removePeerDevice(m_appId, true); - esp_ble_gattc_app_unregister(m_gattc_if); - m_gattc_if = ESP_GATT_IF_NONE; - } - log_v("<< connect(), rc=%d", rc==ESP_GATT_OK); - return rc == ESP_GATT_OK; + m_appId = BLEDevice::m_appId++; + BLEDevice::addPeerDevice(this, true, m_appId); + m_semaphoreRegEvt.take("connect"); + + // 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) { + log_e("esp_ble_gattc_app_register: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + BLEDevice::removePeerDevice(m_appId, true); + return false; + } + + uint32_t rc = m_semaphoreRegEvt.wait("connect"); + + if (rc != ESP_GATT_OK) { + // fixes ESP_GATT_NO_RESOURCES error mostly + log_e("esp_ble_gattc_app_register_error: rc=%d", rc); + BLEDevice::removePeerDevice(m_appId, true); + // not sure if this is needed here + // esp_ble_gattc_app_unregister(m_gattc_if); + // m_gattc_if = ESP_GATT_IF_NONE; + return false; + } + + m_peerAddress = address; + + // Perform the open connection request against the target BLE Server. + m_semaphoreOpenEvt.take("connect"); + errRc = ::esp_ble_gattc_open( + m_gattc_if, + *getPeerAddress().getNative(), // address + type, // Note: This was added on 2018-04-03 when the latest ESP-IDF was detected to have changed the signature. + 1 // direct connection <-- maybe needs to be changed in case of direct indirect connection??? + ); + if (errRc != ESP_OK) { + log_e("esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + BLEDevice::removePeerDevice(m_appId, true); + return false; + } + + rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. + // check the status of the connection and cleanup in case of failure + if (rc != ESP_GATT_OK) { + BLEDevice::removePeerDevice(m_appId, true); + esp_ble_gattc_app_unregister(m_gattc_if); + m_gattc_if = ESP_GATT_IF_NONE; + } + log_v("<< connect(), rc=%d", rc==ESP_GATT_OK); + return rc == ESP_GATT_OK; } // connect @@ -159,13 +159,13 @@ bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) { * @return N/A. */ void BLEClient::disconnect() { - log_v(">> disconnect()"); - esp_err_t errRc = ::esp_ble_gattc_close(getGattcIf(), getConnId()); - if (errRc != ESP_OK) { - log_e("esp_ble_gattc_close: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - return; - } - log_v("<< disconnect()"); + log_v(">> disconnect()"); + esp_err_t errRc = ::esp_ble_gattc_close(getGattcIf(), getConnId()); + if (errRc != ESP_OK) { + log_e("esp_ble_gattc_close: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + return; + } + log_v("<< disconnect()"); } // disconnect @@ -173,190 +173,190 @@ void BLEClient::disconnect() { * @brief Handle GATT Client events */ void BLEClient::gattClientEventHandler( - esp_gattc_cb_event_t event, - esp_gatt_if_t gattc_if, - esp_ble_gattc_cb_param_t* evtParam) { - - log_d("gattClientEventHandler [esp_gatt_if: %d] ... %s", - gattc_if, BLEUtils::gattClientEventTypeToString(event).c_str()); - - // it is possible to receive events from other connections while waiting for registration - if (m_gattc_if == ESP_GATT_IF_NONE && event != ESP_GATTC_REG_EVT) { - return; - } - - // Execute handler code based on the type of event received. - switch(event) { - - case ESP_GATTC_SRVC_CHG_EVT: - log_i("SERVICE CHANGED"); - break; - - case ESP_GATTC_CLOSE_EVT: { - // esp_ble_gattc_app_unregister(m_appId); - // BLEDevice::removePeerDevice(m_gattc_if, true); - break; - } - - // - // ESP_GATTC_DISCONNECT_EVT - // - // disconnect: - // - esp_gatt_status_t status - // - uint16_t conn_id - // - esp_bd_addr_t remote_bda - case ESP_GATTC_DISCONNECT_EVT: { - if (evtParam->disconnect.conn_id != getConnId()) break; - // If we receive a disconnect event, set the class flag that indicates that we are - // no longer connected. - bool m_wasConnected = m_isConnected; - m_isConnected = false; - esp_ble_gattc_app_unregister(m_gattc_if); - m_gattc_if = ESP_GATT_IF_NONE; - m_semaphoreOpenEvt.give(ESP_GATT_IF_NONE); - m_semaphoreRssiCmplEvt.give(); - m_semaphoreSearchCmplEvt.give(1); - BLEDevice::removePeerDevice(m_appId, true); - if (m_wasConnected && m_pClientCallbacks != nullptr) { - m_pClientCallbacks->onDisconnect(this); - } - break; - } // ESP_GATTC_DISCONNECT_EVT - - // - // ESP_GATTC_OPEN_EVT - // - // open: - // - esp_gatt_status_t status - // - uint16_t conn_id - // - esp_bd_addr_t remote_bda - // - case ESP_GATTC_OPEN_EVT: { - m_conn_id = evtParam->open.conn_id; - if (evtParam->open.status == ESP_GATT_OK) { - m_isConnected = true; // Flag us as connected. - if (m_pClientCallbacks != nullptr) { - m_pClientCallbacks->onConnect(this); - } - } else { - log_e("Failed to connect, status=%s", GeneralUtils::errorToString(evtParam->open.status)); - } - m_semaphoreOpenEvt.give(evtParam->open.status); - break; - } // ESP_GATTC_OPEN_EVT - - - // - // ESP_GATTC_REG_EVT - // - // reg: - // esp_gatt_status_t status - // uint16_t app_id - // - case ESP_GATTC_REG_EVT: { - m_gattc_if = gattc_if; - // pass on the registration status result, in case of failure - m_semaphoreRegEvt.give(evtParam->reg.status); - break; - } // ESP_GATTC_REG_EVT - - case ESP_GATTC_CFG_MTU_EVT: - if (evtParam->cfg_mtu.conn_id != getConnId()) break; - if(evtParam->cfg_mtu.status != ESP_GATT_OK) { - log_e("Config mtu failed"); - } - m_mtu = evtParam->cfg_mtu.mtu; - break; - - case ESP_GATTC_CONNECT_EVT: { - if (evtParam->connect.conn_id != getConnId()) break; - BLEDevice::updatePeerDevice(this, true, m_appId); - esp_err_t errRc = esp_ble_gattc_send_mtu_req(gattc_if, evtParam->connect.conn_id); - if (errRc != ESP_OK) { - log_e("esp_ble_gattc_send_mtu_req: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - } + esp_gattc_cb_event_t event, + esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t* evtParam) { + + log_d("gattClientEventHandler [esp_gatt_if: %d] ... %s", + gattc_if, BLEUtils::gattClientEventTypeToString(event).c_str()); + + // it is possible to receive events from other connections while waiting for registration + if (m_gattc_if == ESP_GATT_IF_NONE && event != ESP_GATTC_REG_EVT) { + return; + } + + // Execute handler code based on the type of event received. + switch(event) { + + case ESP_GATTC_SRVC_CHG_EVT: + log_i("SERVICE CHANGED"); + break; + + case ESP_GATTC_CLOSE_EVT: { + // esp_ble_gattc_app_unregister(m_appId); + // BLEDevice::removePeerDevice(m_gattc_if, true); + break; + } + + // + // ESP_GATTC_DISCONNECT_EVT + // + // disconnect: + // - esp_gatt_status_t status + // - uint16_t conn_id + // - esp_bd_addr_t remote_bda + case ESP_GATTC_DISCONNECT_EVT: { + if (evtParam->disconnect.conn_id != getConnId()) break; + // If we receive a disconnect event, set the class flag that indicates that we are + // no longer connected. + bool m_wasConnected = m_isConnected; + m_isConnected = false; + esp_ble_gattc_app_unregister(m_gattc_if); + m_gattc_if = ESP_GATT_IF_NONE; + m_semaphoreOpenEvt.give(ESP_GATT_IF_NONE); + m_semaphoreRssiCmplEvt.give(); + m_semaphoreSearchCmplEvt.give(1); + BLEDevice::removePeerDevice(m_appId, true); + if (m_wasConnected && m_pClientCallbacks != nullptr) { + m_pClientCallbacks->onDisconnect(this); + } + break; + } // ESP_GATTC_DISCONNECT_EVT + + // + // ESP_GATTC_OPEN_EVT + // + // open: + // - esp_gatt_status_t status + // - uint16_t conn_id + // - esp_bd_addr_t remote_bda + // + case ESP_GATTC_OPEN_EVT: { + m_conn_id = evtParam->open.conn_id; + if (evtParam->open.status == ESP_GATT_OK) { + m_isConnected = true; // Flag us as connected. + if (m_pClientCallbacks != nullptr) { + m_pClientCallbacks->onConnect(this); + } + } else { + log_e("Failed to connect, status=%s", GeneralUtils::errorToString(evtParam->open.status)); + } + m_semaphoreOpenEvt.give(evtParam->open.status); + break; + } // ESP_GATTC_OPEN_EVT + + + // + // ESP_GATTC_REG_EVT + // + // reg: + // esp_gatt_status_t status + // uint16_t app_id + // + case ESP_GATTC_REG_EVT: { + m_gattc_if = gattc_if; + // pass on the registration status result, in case of failure + m_semaphoreRegEvt.give(evtParam->reg.status); + break; + } // ESP_GATTC_REG_EVT + + case ESP_GATTC_CFG_MTU_EVT: + if (evtParam->cfg_mtu.conn_id != getConnId()) break; + if(evtParam->cfg_mtu.status != ESP_GATT_OK) { + log_e("Config mtu failed"); + } + m_mtu = evtParam->cfg_mtu.mtu; + break; + + case ESP_GATTC_CONNECT_EVT: { + if (evtParam->connect.conn_id != getConnId()) break; + BLEDevice::updatePeerDevice(this, true, m_appId); + esp_err_t errRc = esp_ble_gattc_send_mtu_req(gattc_if, evtParam->connect.conn_id); + if (errRc != ESP_OK) { + 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){ - esp_ble_set_encryption(evtParam->connect.remote_bda, BLEDevice::m_securityLevel); - } -#endif // CONFIG_BLE_SMP_ENABLE - break; - } // ESP_GATTC_CONNECT_EVT - - // - // ESP_GATTC_SEARCH_CMPL_EVT - // - // search_cmpl: - // - esp_gatt_status_t status - // - uint16_t conn_id - // - case ESP_GATTC_SEARCH_CMPL_EVT: { - if (evtParam->search_cmpl.conn_id != getConnId()) break; - esp_ble_gattc_cb_param_t* p_data = (esp_ble_gattc_cb_param_t*)evtParam; - if (p_data->search_cmpl.status != ESP_GATT_OK){ - log_e("search service failed, error status = %x", p_data->search_cmpl.status); - break; - } + if(BLEDevice::m_securityLevel){ + esp_ble_set_encryption(evtParam->connect.remote_bda, BLEDevice::m_securityLevel); + } +#endif // CONFIG_BLE_SMP_ENABLE + break; + } // ESP_GATTC_CONNECT_EVT + + // + // ESP_GATTC_SEARCH_CMPL_EVT + // + // search_cmpl: + // - esp_gatt_status_t status + // - uint16_t conn_id + // + case ESP_GATTC_SEARCH_CMPL_EVT: { + if (evtParam->search_cmpl.conn_id != getConnId()) break; + esp_ble_gattc_cb_param_t* p_data = (esp_ble_gattc_cb_param_t*)evtParam; + if (p_data->search_cmpl.status != ESP_GATT_OK){ + 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) { - // log_i("Get service information from remote device"); - // } else if (p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_NVS_FLASH) { - // log_i("Get service information from flash"); - // } else { - // log_i("unknown service source"); - // } +// commented out just for now to keep backward compatibility + // if(p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_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) { + // log_i("Get service information from flash"); + // } else { + // log_i("unknown service source"); + // } #endif - m_semaphoreSearchCmplEvt.give(0); - break; - } // ESP_GATTC_SEARCH_CMPL_EVT - - - // - // ESP_GATTC_SEARCH_RES_EVT - // - // search_res: - // - uint16_t conn_id - // - uint16_t start_handle - // - uint16_t end_handle - // - esp_gatt_id_t srvc_id - // - case ESP_GATTC_SEARCH_RES_EVT: { - if (evtParam->search_res.conn_id != getConnId()) break; - BLEUUID uuid = BLEUUID(evtParam->search_res.srvc_id); - BLERemoteService* pRemoteService = new BLERemoteService( - evtParam->search_res.srvc_id, - this, - evtParam->search_res.start_handle, - evtParam->search_res.end_handle - ); - m_servicesMap.insert(std::pair(uuid.toString(), pRemoteService)); - m_servicesMapByInstID.insert(std::pair(pRemoteService, evtParam->search_res.srvc_id.inst_id)); - break; - } // ESP_GATTC_SEARCH_RES_EVT - - - default: { - break; - } - } // Switch - - // Pass the request on to all services. - for (auto &myPair : m_servicesMap) { - myPair.second->gattClientEventHandler(event, gattc_if, evtParam); - } + m_semaphoreSearchCmplEvt.give(0); + break; + } // ESP_GATTC_SEARCH_CMPL_EVT + + + // + // ESP_GATTC_SEARCH_RES_EVT + // + // search_res: + // - uint16_t conn_id + // - uint16_t start_handle + // - uint16_t end_handle + // - esp_gatt_id_t srvc_id + // + case ESP_GATTC_SEARCH_RES_EVT: { + if (evtParam->search_res.conn_id != getConnId()) break; + BLEUUID uuid = BLEUUID(evtParam->search_res.srvc_id); + BLERemoteService* pRemoteService = new BLERemoteService( + evtParam->search_res.srvc_id, + this, + evtParam->search_res.start_handle, + evtParam->search_res.end_handle + ); + m_servicesMap.insert(std::pair(uuid.toString(), pRemoteService)); + m_servicesMapByInstID.insert(std::pair(pRemoteService, evtParam->search_res.srvc_id.inst_id)); + break; + } // ESP_GATTC_SEARCH_RES_EVT + + + default: { + break; + } + } // Switch + + // Pass the request on to all services. + for (auto &myPair : m_servicesMap) { + myPair.second->gattClientEventHandler(event, gattc_if, evtParam); + } } // gattClientEventHandler uint16_t BLEClient::getConnId() { - return m_conn_id; + return m_conn_id; } // getConnId esp_gatt_if_t BLEClient::getGattcIf() { - return m_gattc_if; + return m_gattc_if; } // getGattcIf @@ -366,7 +366,7 @@ esp_gatt_if_t BLEClient::getGattcIf() { * Returns the Bluetooth device address of the %BLE peer to which this client is connected. */ BLEAddress BLEClient::getPeerAddress() { - return m_peerAddress; + return m_peerAddress; } // getAddress @@ -375,23 +375,23 @@ BLEAddress BLEClient::getPeerAddress() { * @return The RSSI value. */ int BLEClient::getRssi() { - log_v(">> getRssi()"); - if (!isConnected()) { - 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 - // an ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT to indicate completion. - // - m_semaphoreRssiCmplEvt.take("getRssi"); - esp_err_t rc = ::esp_ble_gap_read_rssi(*getPeerAddress().getNative()); - if (rc != ESP_OK) { - log_e("<< getRssi: esp_ble_gap_read_rssi: rc=%d %s", rc, GeneralUtils::errorToString(rc)); - return 0; - } - int rssiValue = m_semaphoreRssiCmplEvt.wait("getRssi"); - log_v("<< getRssi(): %d", rssiValue); - return rssiValue; + log_v(">> getRssi()"); + if (!isConnected()) { + 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 + // an ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT to indicate completion. + // + m_semaphoreRssiCmplEvt.take("getRssi"); + esp_err_t rc = ::esp_ble_gap_read_rssi(*getPeerAddress().getNative()); + if (rc != ESP_OK) { + log_e("<< getRssi: esp_ble_gap_read_rssi: rc=%d %s", rc, GeneralUtils::errorToString(rc)); + return 0; + } + int rssiValue = m_semaphoreRssiCmplEvt.wait("getRssi"); + log_v("<< getRssi(): %d", rssiValue); + return rssiValue; } // getRssi @@ -412,25 +412,25 @@ BLERemoteService* BLEClient::getService(const char* uuid) { * @throws BLEUuidNotFound */ BLERemoteService* BLEClient::getService(BLEUUID uuid) { - log_v(">> 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 // device what services it has in which case we have nothing to match against. If we have not // asked the device about its services, then we do that now. Once we get the results we can then // examine the services map to see if it has the service we are looking for. - if (!m_haveServices) { - getServices(); - } - std::string uuidStr = uuid.toString(); - for (auto &myPair : m_servicesMap) { - if (myPair.first == uuidStr) { - log_v("<< getService: found the service with uuid: %s", uuid.toString().c_str()); - return myPair.second; - } - } // End of each of the services. - log_v("<< getService: not found"); - return nullptr; + if (!m_haveServices) { + getServices(); + } + String uuidStr = uuid.toString(); + for (auto &myPair : m_servicesMap) { + if (myPair.first == uuidStr) { + log_v("<< getService: found the service with uuid: %s", uuid.toString().c_str()); + return myPair.second; + } + } // End of each of the services. + log_v("<< getService: not found"); + return nullptr; } // getService @@ -440,7 +440,7 @@ BLERemoteService* BLEClient::getService(BLEUUID uuid) { * services and wait until we have received them all. * @return N/A */ -std::map* BLEClient::getServices() { +std::map* BLEClient::getServices() { /* * Design * ------ @@ -448,25 +448,25 @@ std::map* 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. */ - log_v(">> getServices"); + log_v(">> getServices"); // TODO implement retrieving services from cache - clearServices(); // Clear any services that may exist. - - esp_err_t errRc = esp_ble_gattc_search_service( - getGattcIf(), - getConnId(), - NULL // Filter UUID - ); - - m_semaphoreSearchCmplEvt.take("getServices"); - if (errRc != ESP_OK) { - 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); - log_v("<< getServices"); - return &m_servicesMap; + clearServices(); // Clear any services that may exist. + + esp_err_t errRc = esp_ble_gattc_search_service( + getGattcIf(), + getConnId(), + NULL // Filter UUID + ); + + m_semaphoreSearchCmplEvt.take("getServices"); + if (errRc != ESP_OK) { + 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); + log_v("<< getServices"); + return &m_servicesMap; } // getServices @@ -476,11 +476,11 @@ std::map* BLEClient::getServices() { * @param [in] characteristicUUID The characteristic whose value we wish to read. * @throws BLEUuidNotFound */ -std::string BLEClient::getValue(BLEUUID serviceUUID, BLEUUID characteristicUUID) { - log_v(">> getValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); - std::string ret = getService(serviceUUID)->getCharacteristic(characteristicUUID)->readValue(); - log_v("<> getValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); + String ret = getService(serviceUUID)->getCharacteristic(characteristicUUID)->readValue(); + log_v("<read_rssi_cmpl.rssi); - break; - } // ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT - - default: - break; - } + esp_gap_ble_cb_event_t event, + esp_ble_gap_cb_param_t* param) { + log_d("BLEClient ... handling GAP event!"); + switch (event) { + // + // ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT + // + // read_rssi_cmpl + // - esp_bt_status_t status + // - int8_t rssi + // - esp_bd_addr_t remote_addr + // + case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT: { + m_semaphoreRssiCmplEvt.give((uint32_t) param->read_rssi_cmpl.rssi); + break; + } // ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT + + default: + break; + } } // handleGAPEvent @@ -519,7 +519,7 @@ void BLEClient::handleGAPEvent( * @return True if we are connected and false if we are not connected. */ bool BLEClient::isConnected() { - return m_isConnected; + return m_isConnected; } // isConnected @@ -529,7 +529,7 @@ bool BLEClient::isConnected() { * @brief Set the callbacks that will be invoked. */ void BLEClient::setClientCallbacks(BLEClientCallbacks* pClientCallbacks) { - m_pClientCallbacks = pClientCallbacks; + m_pClientCallbacks = pClientCallbacks; } // setClientCallbacks @@ -539,44 +539,44 @@ void BLEClient::setClientCallbacks(BLEClientCallbacks* pClientCallbacks) { * @param [in] characteristicUUID The characteristic whose value we wish to write. * @throws BLEUuidNotFound */ -void BLEClient::setValue(BLEUUID serviceUUID, BLEUUID characteristicUUID, std::string value) { - log_v(">> setValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); - getService(serviceUUID)->getCharacteristic(characteristicUUID)->writeValue(value); - log_v("<< setValue"); +void BLEClient::setValue(BLEUUID serviceUUID, BLEUUID characteristicUUID, String value) { + log_v(">> setValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); + getService(serviceUUID)->getCharacteristic(characteristicUUID)->writeValue(value); + log_v("<< setValue"); } // setValue uint16_t BLEClient::getMTU() { - return m_mtu; + return m_mtu; } /** - @brief Set the local and remote MTU size. - Should be called once after client connects if MTU size needs to be changed. - @return bool indicating if MTU was successfully set locally and on remote. + @brief Set the local and remote MTU size. + Should be called once after client connects if MTU size needs to be changed. + @return bool indicating if MTU was successfully set locally and on remote. */ bool BLEClient::setMTU(uint16_t mtu) { - esp_err_t err = esp_ble_gatt_set_local_mtu(mtu); //First must set local MTU value. - if (err == ESP_OK) - { - err = esp_ble_gattc_send_mtu_req(m_gattc_if,m_conn_id); //Once local is set successfully set remote size - if (err!=ESP_OK) - { - log_e("Error setting send MTU request MTU: %d err=%d", mtu,err); - return false; - } - } - else - { - log_e("can't set local mtu value: %d", mtu); - return false; - } - log_v("<< setLocalMTU"); - - m_mtu = mtu; //successfully changed - - return true; + esp_err_t err = esp_ble_gatt_set_local_mtu(mtu); //First must set local MTU value. + if (err == ESP_OK) + { + err = esp_ble_gattc_send_mtu_req(m_gattc_if,m_conn_id); //Once local is set successfully set remote size + if (err!=ESP_OK) + { + log_e("Error setting send MTU request MTU: %d err=%d", mtu,err); + return false; + } + } + else + { + log_e("can't set local mtu value: %d", mtu); + return false; + } + log_v("<< setLocalMTU"); + + m_mtu = mtu; //successfully changed + + return true; } @@ -586,14 +586,14 @@ bool BLEClient::setMTU(uint16_t mtu) * @brief Return a string representation of this client. * @return A string representation of this client. */ -std::string BLEClient::toString() { - std::string res = "peer address: " + m_peerAddress.toString(); - res += "\nServices:\n"; - for (auto &myPair : m_servicesMap) { - res += myPair.second->toString() + "\n"; - // myPair.second is the value - } - return res; +String BLEClient::toString() { + String res = "peer address: " + m_peerAddress.toString(); + res += "\nServices:\n"; + for (auto &myPair : m_servicesMap) { + res += myPair.second->toString() + "\n"; + // myPair.second is the value + } + return res; } // toString #endif /* CONFIG_BLUEDROID_ENABLED */ diff --git a/libraries/BLE/src/BLEClient.h b/libraries/BLE/src/BLEClient.h index a87d0277223..0207a214b66 100644 --- a/libraries/BLE/src/BLEClient.h +++ b/libraries/BLE/src/BLEClient.h @@ -33,63 +33,62 @@ class BLEAdvertisedDevice; */ class BLEClient { public: - BLEClient(); - ~BLEClient(); - - bool connect(BLEAdvertisedDevice* device); - bool connect(BLEAddress address, esp_ble_addr_type_t type = BLE_ADDR_TYPE_PUBLIC); // Connect to the remote BLE Server - void disconnect(); // Disconnect from the remote BLE Server - BLEAddress getPeerAddress(); // Get the address of the remote BLE Server - int getRssi(); // Get the RSSI of the remote BLE Server - std::map* getServices(); // Get a map of the services offered by the remote BLE Server - BLERemoteService* getService(const char* uuid); // Get a reference to a specified service offered by the remote BLE server. - BLERemoteService* getService(BLEUUID uuid); // Get a reference to a specified service offered by the remote BLE server. - std::string getValue(BLEUUID serviceUUID, BLEUUID characteristicUUID); // Get the value of a given characteristic at a given service. - - - void handleGAPEvent( - esp_gap_ble_cb_event_t event, - esp_ble_gap_cb_param_t* param); - - bool isConnected(); // Return true if we are connected. - - void setClientCallbacks(BLEClientCallbacks *pClientCallbacks); - void setValue(BLEUUID serviceUUID, BLEUUID characteristicUUID, std::string value); // Set the value of a given characteristic at a given service. - - std::string toString(); // Return a string representation of this client. - uint16_t getConnId(); - esp_gatt_if_t getGattcIf(); - uint16_t getMTU(); - bool setMTU(uint16_t mtu); - + BLEClient(); + ~BLEClient(); + + bool connect(BLEAdvertisedDevice* device); + bool connect(BLEAddress address, esp_ble_addr_type_t type = BLE_ADDR_TYPE_PUBLIC); // Connect to the remote BLE Server + void disconnect(); // Disconnect from the remote BLE Server + BLEAddress getPeerAddress(); // Get the address of the remote BLE Server + int getRssi(); // Get the RSSI of the remote BLE Server + std::map* getServices(); // Get a map of the services offered by the remote BLE Server + BLERemoteService* getService(const char* uuid); // Get a reference to a specified service offered by the remote BLE server. + BLERemoteService* getService(BLEUUID uuid); // Get a reference to a specified service offered by the remote BLE server. + String getValue(BLEUUID serviceUUID, BLEUUID characteristicUUID); // Get the value of a given characteristic at a given service. + + void handleGAPEvent( + esp_gap_ble_cb_event_t event, + esp_ble_gap_cb_param_t* param); + + bool isConnected(); // Return true if we are connected. + + void setClientCallbacks(BLEClientCallbacks *pClientCallbacks); + void setValue(BLEUUID serviceUUID, BLEUUID characteristicUUID, String value); // Set the value of a given characteristic at a given service. + + String toString(); // Return a string representation of this client. + uint16_t getConnId(); + esp_gatt_if_t getGattcIf(); + uint16_t getMTU(); + bool setMTU(uint16_t mtu); + uint16_t m_appId; private: - friend class BLEDevice; - friend class BLERemoteService; - friend class BLERemoteCharacteristic; - friend class BLERemoteDescriptor; - - void gattClientEventHandler( - esp_gattc_cb_event_t event, - esp_gatt_if_t gattc_if, - esp_ble_gattc_cb_param_t* param); - - BLEAddress m_peerAddress = BLEAddress((uint8_t*)"\0\0\0\0\0\0"); // The BD address of the remote server. - uint16_t m_conn_id; -// int m_deviceType; - esp_gatt_if_t m_gattc_if; - bool m_haveServices = false; // Have we previously obtain the set of services from the remote server. - bool m_isConnected = false; // Are we currently connected. - - BLEClientCallbacks* m_pClientCallbacks; - FreeRTOS::Semaphore m_semaphoreRegEvt = FreeRTOS::Semaphore("RegEvt"); - FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt"); - FreeRTOS::Semaphore m_semaphoreSearchCmplEvt = FreeRTOS::Semaphore("SearchCmplEvt"); - FreeRTOS::Semaphore m_semaphoreRssiCmplEvt = FreeRTOS::Semaphore("RssiCmplEvt"); - std::map m_servicesMap; - std::map m_servicesMapByInstID; - void clearServices(); // Clear any existing services. - uint16_t m_mtu = 23; + friend class BLEDevice; + friend class BLERemoteService; + friend class BLERemoteCharacteristic; + friend class BLERemoteDescriptor; + + void gattClientEventHandler( + esp_gattc_cb_event_t event, + esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t* param); + + BLEAddress m_peerAddress = BLEAddress((uint8_t*)"\0\0\0\0\0\0"); // The BD address of the remote server. + uint16_t m_conn_id; +// int m_deviceType; + esp_gatt_if_t m_gattc_if; + bool m_haveServices = false; // Have we previously obtain the set of services from the remote server. + bool m_isConnected = false; // Are we currently connected. + + BLEClientCallbacks* m_pClientCallbacks; + FreeRTOS::Semaphore m_semaphoreRegEvt = FreeRTOS::Semaphore("RegEvt"); + FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt"); + FreeRTOS::Semaphore m_semaphoreSearchCmplEvt = FreeRTOS::Semaphore("SearchCmplEvt"); + FreeRTOS::Semaphore m_semaphoreRssiCmplEvt = FreeRTOS::Semaphore("RssiCmplEvt"); + std::map m_servicesMap; + std::map m_servicesMapByInstID; + void clearServices(); // Clear any existing services. + uint16_t m_mtu = 23; }; // class BLEDevice @@ -98,9 +97,9 @@ uint16_t m_appId; */ class BLEClientCallbacks { public: - virtual ~BLEClientCallbacks() {}; - virtual void onConnect(BLEClient *pClient) = 0; - virtual void onDisconnect(BLEClient *pClient) = 0; + virtual ~BLEClientCallbacks() {}; + virtual void onConnect(BLEClient *pClient) = 0; + virtual void onDisconnect(BLEClient *pClient) = 0; }; #endif /* CONFIG_BLUEDROID_ENABLED */ diff --git a/libraries/BLE/src/BLEDescriptor.cpp b/libraries/BLE/src/BLEDescriptor.cpp index 652d82f01a3..d39c3b43d6c 100644 --- a/libraries/BLE/src/BLEDescriptor.cpp +++ b/libraries/BLE/src/BLEDescriptor.cpp @@ -27,20 +27,20 @@ * @brief BLEDescriptor constructor. */ BLEDescriptor::BLEDescriptor(const char* uuid, uint16_t len) : BLEDescriptor(BLEUUID(uuid), len) { -} +} /** * @brief BLEDescriptor constructor. */ BLEDescriptor::BLEDescriptor(BLEUUID uuid, uint16_t max_len) { - m_bleUUID = uuid; - m_value.attr_len = 0; // Initial length is 0. - m_value.attr_max_len = max_len; // Maximum length of the data. - m_handle = NULL_HANDLE; // Handle is initially unknown. - m_pCharacteristic = nullptr; // No initial characteristic. - m_pCallback = nullptr; // No initial callback. - - m_value.attr_value = (uint8_t*) malloc(max_len); // Allocate storage for the value. + m_bleUUID = uuid; + m_value.attr_len = 0; // Initial length is 0. + m_value.attr_max_len = max_len; // Maximum length of the data. + m_handle = NULL_HANDLE; // Handle is initially unknown. + m_pCharacteristic = nullptr; // No initial characteristic. + m_pCallback = nullptr; // No initial callback. + + m_value.attr_value = (uint8_t*) malloc(max_len); // Allocate storage for the value. } // BLEDescriptor @@ -48,7 +48,7 @@ BLEDescriptor::BLEDescriptor(BLEUUID uuid, uint16_t max_len) { * @brief BLEDescriptor destructor. */ BLEDescriptor::~BLEDescriptor() { - free(m_value.attr_value); // Release the storage we created in the constructor. + free(m_value.attr_value); // Release the storage we created in the constructor. } // ~BLEDescriptor @@ -57,31 +57,31 @@ BLEDescriptor::~BLEDescriptor() { * @param [in] pCharacteristic The characteristic to which to register this descriptor. */ void BLEDescriptor::executeCreate(BLECharacteristic* pCharacteristic) { - log_v(">> executeCreate(): %s", toString().c_str()); - - if (m_handle != NULL_HANDLE) { - log_e("Descriptor already has a handle."); - return; - } - - m_pCharacteristic = pCharacteristic; // Save the characteristic associated with this service. - - esp_attr_control_t control; - control.auto_rsp = ESP_GATT_AUTO_RSP; - m_semaphoreCreateEvt.take("executeCreate"); - esp_err_t errRc = ::esp_ble_gatts_add_char_descr( - pCharacteristic->getService()->getHandle(), - getUUID().getNative(), - (esp_gatt_perm_t)m_permissions, - &m_value, - &control); - if (errRc != ESP_OK) { - log_e("<< esp_ble_gatts_add_char_descr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - return; - } - - m_semaphoreCreateEvt.wait("executeCreate"); - log_v("<< executeCreate"); + log_v(">> executeCreate(): %s", toString().c_str()); + + if (m_handle != NULL_HANDLE) { + log_e("Descriptor already has a handle."); + return; + } + + m_pCharacteristic = pCharacteristic; // Save the characteristic associated with this service. + + esp_attr_control_t control; + control.auto_rsp = ESP_GATT_AUTO_RSP; + m_semaphoreCreateEvt.take("executeCreate"); + esp_err_t errRc = ::esp_ble_gatts_add_char_descr( + pCharacteristic->getService()->getHandle(), + getUUID().getNative(), + (esp_gatt_perm_t)m_permissions, + &m_value, + &control); + if (errRc != ESP_OK) { + log_e("<< esp_ble_gatts_add_char_descr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + return; + } + + m_semaphoreCreateEvt.wait("executeCreate"); + log_v("<< executeCreate"); } // executeCreate @@ -90,7 +90,7 @@ void BLEDescriptor::executeCreate(BLECharacteristic* pCharacteristic) { * @return The handle for this descriptor. */ uint16_t BLEDescriptor::getHandle() { - return m_handle; + return m_handle; } // getHandle @@ -99,7 +99,7 @@ uint16_t BLEDescriptor::getHandle() { * @return The length (in bytes) of the value of this descriptor. */ size_t BLEDescriptor::getLength() { - return m_value.attr_len; + return m_value.attr_len; } // getLength @@ -107,7 +107,7 @@ size_t BLEDescriptor::getLength() { * @brief Get the UUID of the descriptor. */ BLEUUID BLEDescriptor::getUUID() { - return m_bleUUID; + return m_bleUUID; } // getUUID @@ -117,7 +117,7 @@ BLEUUID BLEDescriptor::getUUID() { * @return A pointer to the value of this descriptor. */ uint8_t* BLEDescriptor::getValue() { - return m_value.attr_value; + return m_value.attr_value; } // getValue @@ -128,77 +128,77 @@ uint8_t* BLEDescriptor::getValue() { * @param [in] param */ void BLEDescriptor::handleGATTServerEvent( - esp_gatts_cb_event_t event, - esp_gatt_if_t gatts_if, - esp_ble_gatts_cb_param_t* param) { - switch (event) { - // ESP_GATTS_ADD_CHAR_DESCR_EVT - // - // add_char_descr: - // - esp_gatt_status_t status - // - uint16_t attr_handle - // - uint16_t service_handle - // - esp_bt_uuid_t char_uuid - case ESP_GATTS_ADD_CHAR_DESCR_EVT: { - if (m_pCharacteristic != nullptr && - m_bleUUID.equals(BLEUUID(param->add_char_descr.descr_uuid)) && - m_pCharacteristic->getService()->getHandle() == param->add_char_descr.service_handle && - m_pCharacteristic == m_pCharacteristic->getService()->getLastCreatedCharacteristic()) { - setHandle(param->add_char_descr.attr_handle); - m_semaphoreCreateEvt.give(); - } - break; - } // ESP_GATTS_ADD_CHAR_DESCR_EVT - - // ESP_GATTS_WRITE_EVT - A request to write the value of a descriptor has arrived. - // - // write: - // - uint16_t conn_id - // - uint16_t trans_id - // - esp_bd_addr_t bda - // - uint16_t handle - // - uint16_t offset - // - bool need_rsp - // - bool is_prep - // - uint16_t len - // - uint8_t *value - case ESP_GATTS_WRITE_EVT: { - if (param->write.handle == m_handle) { - setValue(param->write.value, param->write.len); // Set the value of the descriptor. - - if (m_pCallback != nullptr) { // We have completed the write, if there is a user supplied callback handler, invoke it now. - m_pCallback->onWrite(this); // Invoke the onWrite callback handler. - } - } // End of ... this is our handle. - - break; - } // ESP_GATTS_WRITE_EVT - - // ESP_GATTS_READ_EVT - A request to read the value of a descriptor has arrived. - // - // read: - // - uint16_t conn_id - // - uint32_t trans_id - // - esp_bd_addr_t bda - // - uint16_t handle - // - uint16_t offset - // - bool is_long - // - bool need_rsp - // - case ESP_GATTS_READ_EVT: { - if (param->read.handle == m_handle) { // If this event is for this descriptor ... process it - - if (m_pCallback != nullptr) { // If we have a user supplied callback, invoke it now. - m_pCallback->onRead(this); // Invoke the onRead callback method in the callback handler. - } - - } // End of this is our handle - break; - } // ESP_GATTS_READ_EVT - - default: - break; - } // switch event + esp_gatts_cb_event_t event, + esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t* param) { + switch (event) { + // ESP_GATTS_ADD_CHAR_DESCR_EVT + // + // add_char_descr: + // - esp_gatt_status_t status + // - uint16_t attr_handle + // - uint16_t service_handle + // - esp_bt_uuid_t char_uuid + case ESP_GATTS_ADD_CHAR_DESCR_EVT: { + if (m_pCharacteristic != nullptr && + m_bleUUID.equals(BLEUUID(param->add_char_descr.descr_uuid)) && + m_pCharacteristic->getService()->getHandle() == param->add_char_descr.service_handle && + m_pCharacteristic == m_pCharacteristic->getService()->getLastCreatedCharacteristic()) { + setHandle(param->add_char_descr.attr_handle); + m_semaphoreCreateEvt.give(); + } + break; + } // ESP_GATTS_ADD_CHAR_DESCR_EVT + + // ESP_GATTS_WRITE_EVT - A request to write the value of a descriptor has arrived. + // + // write: + // - uint16_t conn_id + // - uint16_t trans_id + // - esp_bd_addr_t bda + // - uint16_t handle + // - uint16_t offset + // - bool need_rsp + // - bool is_prep + // - uint16_t len + // - uint8_t *value + case ESP_GATTS_WRITE_EVT: { + if (param->write.handle == m_handle) { + setValue(param->write.value, param->write.len); // Set the value of the descriptor. + + if (m_pCallback != nullptr) { // We have completed the write, if there is a user supplied callback handler, invoke it now. + m_pCallback->onWrite(this); // Invoke the onWrite callback handler. + } + } // End of ... this is our handle. + + break; + } // ESP_GATTS_WRITE_EVT + + // ESP_GATTS_READ_EVT - A request to read the value of a descriptor has arrived. + // + // read: + // - uint16_t conn_id + // - uint32_t trans_id + // - esp_bd_addr_t bda + // - uint16_t handle + // - uint16_t offset + // - bool is_long + // - bool need_rsp + // + case ESP_GATTS_READ_EVT: { + if (param->read.handle == m_handle) { // If this event is for this descriptor ... process it + + if (m_pCallback != nullptr) { // If we have a user supplied callback, invoke it now. + m_pCallback->onRead(this); // Invoke the onRead callback method in the callback handler. + } + + } // End of this is our handle + break; + } // ESP_GATTS_READ_EVT + + default: + break; + } // switch event } // handleGATTServerEvent @@ -207,9 +207,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) { - log_v(">> setCallbacks: 0x%x", (uint32_t) pCallback); - m_pCallback = pCallback; - log_v("<< setCallbacks"); + log_v(">> setCallbacks: 0x%x", (uint32_t) pCallback); + m_pCallback = pCallback; + log_v("<< setCallbacks"); } // setCallbacks @@ -220,9 +220,9 @@ void BLEDescriptor::setCallbacks(BLEDescriptorCallbacks* pCallback) { * @return N/A. */ void BLEDescriptor::setHandle(uint16_t handle) { - log_v(">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle); - m_handle = handle; - log_v("<< setHandle()"); + log_v(">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle); + m_handle = handle; + log_v("<< setHandle()"); } // setHandle @@ -232,16 +232,16 @@ void BLEDescriptor::setHandle(uint16_t handle) { * @param [in] length The length of the data in bytes. */ void BLEDescriptor::setValue(uint8_t* data, size_t length) { - if (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; - memcpy(m_value.attr_value, data, length); - if (m_handle != NULL_HANDLE) { - esp_ble_gatts_set_attr_value(m_handle, length, (const uint8_t *)data); - log_d("Set the value in the GATTS database using handle 0x%x", m_handle); - } + if (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; + memcpy(m_value.attr_value, data, length); + if (m_handle != NULL_HANDLE) { + esp_ble_gatts_set_attr_value(m_handle, length, (const uint8_t *)data); + log_d("Set the value in the GATTS database using handle 0x%x", m_handle); + } } // setValue @@ -249,23 +249,23 @@ void BLEDescriptor::setValue(uint8_t* data, size_t length) { * @brief Set the value of the descriptor. * @param [in] value The value of the descriptor in string form. */ -void BLEDescriptor::setValue(std::string value) { - setValue((uint8_t*) value.data(), value.length()); +void BLEDescriptor::setValue(String value) { + setValue((uint8_t*) value.c_str(), value.length()); } // setValue void BLEDescriptor::setAccessPermissions(esp_gatt_perm_t perm) { - m_permissions = perm; + m_permissions = perm; } /** * @brief Return a string representation of the descriptor. * @return A string representation of the descriptor. */ -std::string BLEDescriptor::toString() { - char hex[5]; - snprintf(hex, sizeof(hex), "%04x", m_handle); - std::string res = "UUID: " + m_bleUUID.toString() + ", handle: 0x" + hex; - return res; +String BLEDescriptor::toString() { + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", m_handle); + String res = "UUID: " + m_bleUUID.toString() + ", handle: 0x" + hex; + return res; } // toString @@ -276,8 +276,8 @@ BLEDescriptorCallbacks::~BLEDescriptorCallbacks() {} * @param [in] pDescriptor The descriptor that is the source of the event. */ void BLEDescriptorCallbacks::onRead(BLEDescriptor* pDescriptor) { - log_d("BLEDescriptorCallbacks", ">> onRead: default"); - log_d("BLEDescriptorCallbacks", "<< onRead"); + log_d("BLEDescriptorCallbacks", ">> onRead: default"); + log_d("BLEDescriptorCallbacks", "<< onRead"); } // onRead @@ -286,8 +286,8 @@ void BLEDescriptorCallbacks::onRead(BLEDescriptor* pDescriptor) { * @param [in] pDescriptor The descriptor that is the source of the event. */ void BLEDescriptorCallbacks::onWrite(BLEDescriptor* pDescriptor) { - log_d("BLEDescriptorCallbacks", ">> onWrite: default"); - log_d("BLEDescriptorCallbacks", "<< onWrite"); + log_d("BLEDescriptorCallbacks", ">> onWrite: default"); + log_d("BLEDescriptorCallbacks", "<< onWrite"); } // onWrite diff --git a/libraries/BLE/src/BLEDescriptor.h b/libraries/BLE/src/BLEDescriptor.h index bf4cfb91361..2e834079de3 100644 --- a/libraries/BLE/src/BLEDescriptor.h +++ b/libraries/BLE/src/BLEDescriptor.h @@ -27,39 +27,39 @@ class BLEDescriptorCallbacks; */ class BLEDescriptor { public: - BLEDescriptor(const char* uuid, uint16_t max_len = 100); - BLEDescriptor(BLEUUID uuid, uint16_t max_len = 100); - virtual ~BLEDescriptor(); + BLEDescriptor(const char* uuid, uint16_t max_len = 100); + BLEDescriptor(BLEUUID uuid, uint16_t max_len = 100); + virtual ~BLEDescriptor(); - uint16_t getHandle(); // Get the handle of the descriptor. - size_t getLength(); // Get the length of the value of the descriptor. - BLEUUID getUUID(); // Get the UUID of the descriptor. - uint8_t* getValue(); // Get a pointer to the value of the descriptor. - void handleGATTServerEvent( - esp_gatts_cb_event_t event, - esp_gatt_if_t gatts_if, - esp_ble_gatts_cb_param_t* param); + uint16_t getHandle(); // Get the handle of the descriptor. + size_t getLength(); // Get the length of the value of the descriptor. + BLEUUID getUUID(); // Get the UUID of the descriptor. + uint8_t* getValue(); // Get a pointer to the value of the descriptor. + void handleGATTServerEvent( + esp_gatts_cb_event_t event, + esp_gatt_if_t gatts_if, + esp_ble_gatts_cb_param_t* param); - void setAccessPermissions(esp_gatt_perm_t perm); // Set the permissions of the descriptor. - void setCallbacks(BLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor. - void setValue(uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data. - void setValue(std::string value); // Set the value of the descriptor as a data buffer. + void setAccessPermissions(esp_gatt_perm_t perm); // Set the permissions of the descriptor. + void setCallbacks(BLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor. + void setValue(uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data. + void setValue(String value); // Set the value of the descriptor as a data buffer. - std::string toString(); // Convert the descriptor to a string representation. + String toString(); // Convert the descriptor to a string representation. private: - friend class BLEDescriptorMap; - friend class BLECharacteristic; - BLEUUID m_bleUUID; - uint16_t m_handle; - BLEDescriptorCallbacks* m_pCallback; - BLECharacteristic* m_pCharacteristic; - esp_gatt_perm_t m_permissions = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE; - FreeRTOS::Semaphore m_semaphoreCreateEvt = FreeRTOS::Semaphore("CreateEvt"); - esp_attr_value_t m_value; + friend class BLEDescriptorMap; + friend class BLECharacteristic; + BLEUUID m_bleUUID; + uint16_t m_handle; + BLEDescriptorCallbacks* m_pCallback; + BLECharacteristic* m_pCharacteristic; + esp_gatt_perm_t m_permissions = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE; + FreeRTOS::Semaphore m_semaphoreCreateEvt = FreeRTOS::Semaphore("CreateEvt"); + esp_attr_value_t m_value; - void executeCreate(BLECharacteristic* pCharacteristic); - void setHandle(uint16_t handle); + void executeCreate(BLECharacteristic* pCharacteristic); + void setHandle(uint16_t handle); }; // BLEDescriptor @@ -72,9 +72,9 @@ class BLEDescriptor { */ class BLEDescriptorCallbacks { public: - virtual ~BLEDescriptorCallbacks(); - virtual void onRead(BLEDescriptor* pDescriptor); - virtual void onWrite(BLEDescriptor* pDescriptor); + virtual ~BLEDescriptorCallbacks(); + virtual void onRead(BLEDescriptor* pDescriptor); + virtual void onWrite(BLEDescriptor* pDescriptor); }; #endif /* CONFIG_BLUEDROID_ENABLED */ diff --git a/libraries/BLE/src/BLEDescriptorMap.cpp b/libraries/BLE/src/BLEDescriptorMap.cpp index 10cca4dc48f..50f23d76541 100644 --- a/libraries/BLE/src/BLEDescriptorMap.cpp +++ b/libraries/BLE/src/BLEDescriptorMap.cpp @@ -61,7 +61,7 @@ BLEDescriptor* BLEDescriptorMap::getByHandle(uint16_t handle) { * @return N/A. */ void BLEDescriptorMap::setByUUID(const char* uuid, BLEDescriptor* pDescriptor){ - m_uuidMap.insert(std::pair(pDescriptor, uuid)); + m_uuidMap.insert(std::pair(pDescriptor, uuid)); } // setByUUID @@ -73,7 +73,7 @@ void BLEDescriptorMap::setByUUID(const char* uuid, BLEDescriptor* pDescriptor){ * @return N/A. */ void BLEDescriptorMap::setByUUID(BLEUUID uuid, BLEDescriptor* pDescriptor) { - m_uuidMap.insert(std::pair(pDescriptor, uuid.toString())); + m_uuidMap.insert(std::pair(pDescriptor, uuid.toString())); } // setByUUID @@ -92,8 +92,8 @@ void BLEDescriptorMap::setByHandle(uint16_t handle, BLEDescriptor* pDescriptor) * @brief Return a string representation of the descriptor map. * @return A string representation of the descriptor map. */ -std::string BLEDescriptorMap::toString() { - std::string res; +String BLEDescriptorMap::toString() { + String res; char hex[5]; int count = 0; for (auto &myPair : m_uuidMap) { diff --git a/libraries/BLE/src/BLEDevice.cpp b/libraries/BLE/src/BLEDevice.cpp index 87d6603b588..141e8eb96b9 100644 --- a/libraries/BLE/src/BLEDevice.cpp +++ b/libraries/BLE/src/BLEDevice.cpp @@ -318,11 +318,11 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr; * @param [in] serviceUUID * @param [in] characteristicUUID */ -/* STATIC */ std::string BLEDevice::getValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID) { +/* STATIC */ String BLEDevice::getValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID) { 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); + String ret = pClient->getValue(serviceUUID, characteristicUUID); pClient->disconnect(); log_v("<< getValue"); return ret; @@ -333,7 +333,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr; * @brief Initialize the %BLE environment. * @param deviceName The device name of the device. */ -/* STATIC */ void BLEDevice::init(std::string deviceName) { +/* STATIC */ void BLEDevice::init(String deviceName) { if(!initialized){ initialized = true; // Set the initialization flag to ensure we are only initialized once. @@ -477,7 +477,7 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr; * @param [in] serviceUUID * @param [in] characteristicUUID */ -/* STATIC */ void BLEDevice::setValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID, std::string value) { +/* STATIC */ void BLEDevice::setValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID, String value) { 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); @@ -490,8 +490,8 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr; * @brief Return a string representation of the nature of this device. * @return A string representation of the nature of this device. */ -/* STATIC */ std::string BLEDevice::toString() { - std::string res = "BD Address: " + getAddress().toString(); +/* STATIC */ String BLEDevice::toString() { + String res = "BD Address: " + getAddress().toString(); return res; } // toString diff --git a/libraries/BLE/src/BLEDevice.h b/libraries/BLE/src/BLEDevice.h index b938072079b..805517ce842 100644 --- a/libraries/BLE/src/BLEDevice.h +++ b/libraries/BLE/src/BLEDevice.h @@ -38,11 +38,11 @@ class BLEDevice { static BLEServer* createServer(); // Cretae a new BLE server. static BLEAddress getAddress(); // Retrieve our own local BD address. static BLEScan* getScan(); // Get the scan object - static std::string getValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID); // Get the value of a characteristic of a service on a server. - static void init(std::string deviceName); // Initialize the local BLE environment. + static String getValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID); // Get the value of a characteristic of a service on a server. + static void init(String deviceName); // Initialize the local BLE environment. static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); // Set our power level. - static void setValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID, std::string value); // Set the value of a characteristic on a service on a server. - static std::string toString(); // Return a string representation of our device. + static void setValue(BLEAddress bdAddress, BLEUUID serviceUUID, BLEUUID characteristicUUID, String value); // Set the value of a characteristic on a service on a server. + static String toString(); // Return a string representation of our device. static void whiteListAdd(BLEAddress address); // Add an entry to the BLE white list. static void whiteListRemove(BLEAddress address); // Remove an entry from the BLE white list. static void setEncryptionLevel(esp_ble_sec_act_t level); diff --git a/libraries/BLE/src/BLEEddystoneTLM.cpp b/libraries/BLE/src/BLEEddystoneTLM.cpp index 8492fc1f867..4e6bdfe492a 100644 --- a/libraries/BLE/src/BLEEddystoneTLM.cpp +++ b/libraries/BLE/src/BLEEddystoneTLM.cpp @@ -22,29 +22,39 @@ static const char LOG_TAG[] = "BLEEddystoneTLM"; BLEEddystoneTLM::BLEEddystoneTLM() { - beaconUUID = 0xFEAA; - m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; - m_eddystoneData.version = 0; - m_eddystoneData.volt = 3300; // 3300mV = 3.3V - m_eddystoneData.temp = (uint16_t) ((float) 23.00)/256; - m_eddystoneData.advCount = 0; - m_eddystoneData.tmil = 0; + m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; + m_eddystoneData.version = 0; + m_eddystoneData.volt = 3300; // 3300mV = 3.3V + m_eddystoneData.temp = (uint16_t) ((float) 23.00)/256; + m_eddystoneData.advCount = 0; + m_eddystoneData.tmil = 0; } // BLEEddystoneTLM -std::string BLEEddystoneTLM::getData() { - return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); +BLEEddystoneTLM::BLEEddystoneTLM(BLEAdvertisedDevice *advertisedDevice){ + char* payload = (char*)advertisedDevice->getPayload(); + for(int i = 0; i < advertisedDevice->getPayloadLength(); ++i){ + if(payload[i] == 0x16 && advertisedDevice->getPayloadLength() >= i+2+sizeof(m_eddystoneData) && payload[i+1] == 0xAA && payload[i+2] == 0xFE && payload[i+3] == 0x20){ + log_d("Eddystone TLM data frame starting at byte [%d]", i+3); + setData(String(payload+i+3, sizeof(m_eddystoneData))); + break; + } + } +} + +String BLEEddystoneTLM::getData() { + return String((char*) &m_eddystoneData, sizeof(m_eddystoneData)); } // getData BLEUUID BLEEddystoneTLM::getUUID() { - return BLEUUID(beaconUUID); + return beaconUUID; } // getUUID uint8_t BLEEddystoneTLM::getVersion() { - return m_eddystoneData.version; + return m_eddystoneData.version; } // getVersion uint16_t BLEEddystoneTLM::getVolt() { - return ENDIAN_CHANGE_U16(m_eddystoneData.volt); + return ENDIAN_CHANGE_U16(m_eddystoneData.volt); } // getVolt float BLEEddystoneTLM::getTemp() { @@ -52,25 +62,25 @@ float BLEEddystoneTLM::getTemp() { } // getTemp uint16_t BLEEddystoneTLM::getRawTemp() { - return ENDIAN_CHANGE_U16(m_eddystoneData.temp); + return ENDIAN_CHANGE_U16(m_eddystoneData.temp); } // getRawTemp uint32_t BLEEddystoneTLM::getCount() { - return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); + return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); } // getCount uint32_t BLEEddystoneTLM::getTime() { - return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; + return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; } // getTime -std::string BLEEddystoneTLM::toString() { - std::string out = ""; +String BLEEddystoneTLM::toString() { + String out = ""; uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); char val[12]; - out += "Version "; // + std::string(m_eddystoneData.version); - snprintf(val, sizeof(val), "%d", m_eddystoneData.version); - out += val; + out += "Version " + String(m_eddystoneData.version); + //snprintf(val, sizeof(val), "%d", m_eddystoneData.version); + //out += val; out += "\n"; out += "Battery Voltage "; // + ENDIAN_CHANGE_U16(m_eddystoneData.volt); snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt)); @@ -116,9 +126,10 @@ std::string BLEEddystoneTLM::toString() { /** * Set the raw data for the beacon record. * Example: - * uint8_t *payLoad = advertisedDevice.getPayload(); - * eddystoneTLM.setData(std::string((char*)payLoad+22, advertisedDevice.getPayloadLength() - 22)); - * Note: the offset 22 works for current implementation of example BLE_EddystoneTLM Beacon.ino, however it is not static and will be reimplemented + * uint8_t *payload = advertisedDevice.getPayload(); + * eddystoneTLM.setData(String((char*)payload+22, advertisedDevice.getPayloadLength() - 22)); + * Note: the offset 22 works for current implementation of example BLE_EddystoneTLM Beacon.ino, however + * the position is not static and it is programmers responsibility to align the data. * Data frame: * | Field || Len | Type | UUID | EddyStone TLM | * | Offset || 0 | 1 | 2 | 4 | @@ -131,37 +142,38 @@ std::string BLEEddystoneTLM::toString() { * | Len || 1 B | 1 B | 2 B | 2 B | 4 B | 4 B | * | Data || 0x20 | ?? | ?? | ?? | ?? | ?? | | | | | | | | | */ -void BLEEddystoneTLM::setData(std::string data) { - if (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()); +void BLEEddystoneTLM::setData(String data) { + if (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.c_str(), data.length()); } // setData void BLEEddystoneTLM::setUUID(BLEUUID l_uuid) { - beaconUUID = l_uuid.getNative()->uuid.uuid16; + beaconUUID = l_uuid; } // setUUID void BLEEddystoneTLM::setVersion(uint8_t version) { - m_eddystoneData.version = version; + m_eddystoneData.version = version; } // setVersion +// Set voltage in ESP32 native Big endian and convert it to little endian used for BLE Frame void BLEEddystoneTLM::setVolt(uint16_t volt) { - m_eddystoneData.volt = volt; + m_eddystoneData.volt = ENDIAN_CHANGE_U16(volt); } // setVolt void BLEEddystoneTLM::setTemp(float temp) { - m_eddystoneData.temp = EDDYSTONE_TEMP_FLOAT_TO_U16(temp); + m_eddystoneData.temp = EDDYSTONE_TEMP_FLOAT_TO_U16(temp); } // setTemp void BLEEddystoneTLM::setCount(uint32_t advCount) { - m_eddystoneData.advCount = advCount; + m_eddystoneData.advCount = advCount; } // setCount void BLEEddystoneTLM::setTime(uint32_t tmil) { - m_eddystoneData.tmil = tmil; + m_eddystoneData.tmil = tmil; } // setTime -#endif +#endif /* CONFIG_BLUEDROID_ENABLED */ #endif /* SOC_BLE_SUPPORTED */ diff --git a/libraries/BLE/src/BLEEddystoneTLM.cppwithheadder b/libraries/BLE/src/BLEEddystoneTLM.cppwithheadder new file mode 100644 index 00000000000..fe3701529ad --- /dev/null +++ b/libraries/BLE/src/BLEEddystoneTLM.cppwithheadder @@ -0,0 +1,202 @@ +/* + * BLEEddystoneTLM.cpp + * + * Created on: Mar 12, 2018 + * Author: pcbreflux + * Edited on: Mar 20, 2020 by beegee-tokyo + * Fix temperature value (8.8 fixed format) + * Fix time stamp (0.1 second resolution) + * Fixes based on EddystoneTLM frame specification https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md + * + */ +#include "sdkconfig.h" +#if defined(CONFIG_BLUEDROID_ENABLED) +#include +#include +#include "esp32-hal-log.h" +#include "BLEEddystoneTLM.h" + +static const char LOG_TAG[] = "BLEEddystoneTLM"; + +BLEEddystoneTLM::BLEEddystoneTLM() { + m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; + m_eddystoneData.version = 0; + m_eddystoneData.volt = 3300; // 3300mV = 3.3V + m_eddystoneData.temp = (uint16_t) ((float) 23.00)/256; + m_eddystoneData.advCount = 0; + m_eddystoneData.tmil = 0; + _initHeadder(); +} // BLEEddystoneTLM + +BLEEddystoneTLM::BLEEddystoneTLM(BLEAdvertisedDevice *advertisedDevice){ + char* payload = (char*)advertisedDevice->getPayload(); + for(int i = 0; i < advertisedDevice->getPayloadLength(); ++i){ + if(payload[i] == 0x16 && advertisedDevice->getPayloadLength() >= i+2+sizeof(m_eddystoneData) && payload[i+1] == 0xAA && payload[i+2] == 0xFE && payload[i+3] == 0x20){ + log_d("Eddystone TLM data frame starting at byte [%d]", i+3); + setData(std::string(payload+i+3, sizeof(m_eddystoneData))); + break; + } + } + _initHeadder(); +} + +String BLEEddystoneTLM::getData() { + return String((char*) &m_eddystoneData, sizeof(m_eddystoneData)); +} // getData + +BLEUUID BLEEddystoneTLM::getUUID() { + return beaconUUID; +} // getUUID + +uint8_t BLEEddystoneTLM::getVersion() { + return m_eddystoneData.version; +} // getVersion + +uint16_t BLEEddystoneTLM::getVolt() { + return ENDIAN_CHANGE_U16(m_eddystoneData.volt); +} // getVolt + +float BLEEddystoneTLM::getTemp() { + return EDDYSTONE_TEMP_U16_TO_FLOAT(m_eddystoneData.temp); +} // getTemp + +uint16_t BLEEddystoneTLM::getRawTemp() { + return ENDIAN_CHANGE_U16(m_eddystoneData.temp); +} // getRawTemp + +uint32_t BLEEddystoneTLM::getCount() { + return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); +} // getCount + +uint32_t BLEEddystoneTLM::getTime() { + return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; +} // getTime + +String BLEEddystoneTLM::getFrame(){ + String frame(BLEHeadder); + frame += String((char*) &m_eddystoneData, sizeof(m_eddystoneData)); + log_d("Compiled frame of length %d Bytes", frame.length()); + for(int i = 0; i < frame.length(); ++i){ + log_d("[%d]=0x%02X",i, frame[i]); + } + return frame; +} // getServiceData + +String BLEEddystoneTLM::toString() { + String out = ""; + uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); + char val[12]; + + out += "Version "; // + std::string(m_eddystoneData.version); + snprintf(val, sizeof(val), "%d", m_eddystoneData.version); + out += val; + out += "\n"; + out += "Battery Voltage "; // + ENDIAN_CHANGE_U16(m_eddystoneData.volt); + snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt)); + out += val; + out += " mV\n"; + + out += "Temperature "; + snprintf(val, sizeof(val), "%.2f", ((int16_t)ENDIAN_CHANGE_U16(m_eddystoneData.temp)) / 256.0f); + out += val; + out += " C\n"; + + out += "Adv. Count "; + snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U32(m_eddystoneData.advCount)); + out += val; + out += "\n"; + + out += "Time in seconds "; + snprintf(val, sizeof(val), "%d", rawsec/10); + out += val; + out += "\n"; + + out += "Time "; + + snprintf(val, sizeof(val), "%04d", rawsec / 864000); + out += val; + out += "."; + + snprintf(val, sizeof(val), "%02d", (rawsec / 36000) % 24); + out += val; + out += ":"; + + snprintf(val, sizeof(val), "%02d", (rawsec / 600) % 60); + out += val; + out += ":"; + + snprintf(val, sizeof(val), "%02d", (rawsec / 10) % 60); + out += val; + out += "\n"; + + return out; +} // toString + +/** + * Set the raw data for the beacon record. + * Example: + * uint8_t *payload = advertisedDevice.getPayload(); + * eddystoneTLM.setData(std::string((char*)payload+22, advertisedDevice.getPayloadLength() - 22)); + * Note: the offset 22 works for current implementation of example BLE_EddystoneTLM Beacon.ino, however + * the position is not static and it is programmers responsibility to align the data. + * Data frame: + * | Field || Len | Type | UUID | EddyStone TLM | + * | Offset || 0 | 1 | 2 | 4 | + * | Len || 1 B | 1 B | 2 B | 14 B | + * | Data || ?? | ?? | 0xAA | 0xFE | ??? | + * + * EddyStone TLM frame: + * | Field || Type | Version | Batt mV | Beacon temp | Cnt since boot | Time since boot | + * | Offset || 0 | 1 | 2 | 4 | 6 | 10 | + * | Len || 1 B | 1 B | 2 B | 2 B | 4 B | 4 B | + * | Data || 0x20 | ?? | ?? | ?? | ?? | ?? | | | | | | | | | + */ +void BLEEddystoneTLM::setData(std::string data) { + if (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()); +} // setData + +void BLEEddystoneTLM::setUUID(BLEUUID l_uuid) { + beaconUUID = l_uuid; +} // setUUID + +void BLEEddystoneTLM::setVersion(uint8_t version) { + m_eddystoneData.version = version; +} // setVersion + +// Set voltage in ESP32 native Big endian and convert it to little endian used for BLE Frame +void BLEEddystoneTLM::setVolt(uint16_t volt) { + m_eddystoneData.volt = ENDIAN_CHANGE_U16(volt); +} // setVolt + +void BLEEddystoneTLM::setTemp(float temp) { + m_eddystoneData.temp = EDDYSTONE_TEMP_FLOAT_TO_U16(temp); +} // setTemp + +void BLEEddystoneTLM::setCount(uint32_t advCount) { + m_eddystoneData.advCount = advCount; +} // setCount + +void BLEEddystoneTLM::setTime(uint32_t tmil) { + m_eddystoneData.tmil = tmil; +} // setTime + +void BLEEddystoneTLM::_initHeadder(){ + BLEHeadder[0] = 0x02; // Len + BLEHeadder[1] = 0x01; // Type Flags + BLEHeadder[2] = 0x06; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 + BLEHeadder[3] = 0x03; // Len + BLEHeadder[4] = 0x03; // Type 16-Bit UUID + BLEHeadder[5] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB + BLEHeadder[6] = 0xFE; // Eddystone UUID 1 MSB + BLEHeadder[7] = 0x11; // Length of TLM Beacon Data is constant 17 B (not counting the length field itself) + BLEHeadder[8] = 0x16; // Type Service Data + BLEHeadder[9] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB + BLEHeadder[10] = 0xFE; // Eddystone UUID 1 MSB + BLEHeadder[11] = 0x20; // Eddystone Frame Type - TLM +} + +#endif \ No newline at end of file diff --git a/libraries/BLE/src/BLEEddystoneTLM.h b/libraries/BLE/src/BLEEddystoneTLM.h index 0bb28f88916..dab28c72c14 100644 --- a/libraries/BLE/src/BLEEddystoneTLM.h +++ b/libraries/BLE/src/BLEEddystoneTLM.h @@ -11,6 +11,7 @@ #if SOC_BLE_SUPPORTED #include "BLEUUID.h" +#include #define EDDYSTONE_TLM_FRAME_TYPE 0x20 #define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8)) @@ -26,7 +27,8 @@ class BLEEddystoneTLM { public: BLEEddystoneTLM(); - std::string getData(); + BLEEddystoneTLM(BLEAdvertisedDevice *advertisedDevice); + String getData(); BLEUUID getUUID(); uint8_t getVersion(); uint16_t getVolt(); @@ -34,8 +36,8 @@ class BLEEddystoneTLM { uint16_t getRawTemp(); uint32_t getCount(); uint32_t getTime(); - std::string toString(); - void setData(std::string data); + String toString(); + void setData(String data); void setUUID(BLEUUID l_uuid); void setVersion(uint8_t version); void setVolt(uint16_t volt); @@ -44,7 +46,7 @@ class BLEEddystoneTLM { void setTime(uint32_t tmil); private: - uint16_t beaconUUID; + BLEUUID beaconUUID; struct { uint8_t frameType; uint8_t version; @@ -53,7 +55,6 @@ class BLEEddystoneTLM { uint32_t advCount; uint32_t tmil; } __attribute__((packed)) m_eddystoneData; - }; // BLEEddystoneTLM #endif /* SOC_BLE_SUPPORTED */ diff --git a/libraries/BLE/src/BLEEddystoneURL.cpp b/libraries/BLE/src/BLEEddystoneURL.cpp index a68966d2ef8..c10e00c1f6f 100644 --- a/libraries/BLE/src/BLEEddystoneURL.cpp +++ b/libraries/BLE/src/BLEEddystoneURL.cpp @@ -3,6 +3,8 @@ * * Created on: Mar 12, 2018 * Author: pcbreflux + * Upgraded on: Feb 20, 2023 + * By: Tomas Pilny */ #include "soc/soc_caps.h" #if SOC_BLE_SUPPORTED @@ -13,140 +15,276 @@ #include "esp32-hal-log.h" #include "BLEEddystoneURL.h" -static const char LOG_TAG[] = "BLEEddystoneURL"; +String EDDYSTONE_URL_PREFIX[] = { + "http://www.", // 0x00 + "https://www.", // 0x01 + "http://", // 0x02 + "https://", // 0x03 + "" // Any other code number results in empty string +}; + +String EDDYSTONE_URL_SUFFIX[] = { + ".com/", // 0x00 + ".org/", // 0x01 + ".edu/", // 0x02 + ".net/", // 0x03 + ".info/", // 0x04 + ".biz/", // 0x05 + ".gov/", // 0x06 + ".com", // 0x07 + ".org", // 0x08 + ".edu", // 0x09 + ".net", // 0x0A + ".info", // 0x0B + ".biz", // 0x0C + ".gov", // 0x0D + "" // Any other code number results in empty string +}; BLEEddystoneURL::BLEEddystoneURL() { - beaconUUID = 0xFEAA; - lengthURL = 0; - m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE; - m_eddystoneData.advertisedTxPower = 0; - memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); + lengthURL = 0; + m_eddystoneData.advertisedTxPower = 0; + memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); + _initHeadder(); } // BLEEddystoneURL -std::string BLEEddystoneURL::getData() { - return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); +BLEEddystoneURL::BLEEddystoneURL(BLEAdvertisedDevice *advertisedDevice){ + const char *payload = (char*)advertisedDevice->getPayload(); + memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); + lengthURL = 0; + m_eddystoneData.advertisedTxPower = 0; + for(int i = 0; i < advertisedDevice->getPayloadLength(); ++i){ + if(payload[i] == 0x16 && advertisedDevice->getPayloadLength() >= i+2+sizeof(m_eddystoneData) && payload[i+1] == 0xAA && payload[i+2] == 0xFE && payload[i+3] == 0x10){ + lengthURL = payload[i-1] - 5; // Subtracting 5 Bytes containing header and other data which are not actual URL data + m_eddystoneData.advertisedTxPower = payload[i+1]; + if(lengthURL <= 18){ + setData(String(payload+i+4, lengthURL+1)); + }else{ + log_e("Too long URL %d", lengthURL); + } + } + } + _initHeadder(); +} + +String BLEEddystoneURL::getData() { + return String((char*) &m_eddystoneData, sizeof(m_eddystoneData)); } // getData +String BLEEddystoneURL::getFrame() { + BLEHeadder[7] = lengthURL + 5; // Fill in real: Type + 2B UUID + Frame Type + Tx power + URL (note: the Byte holding the length does not count itself) + String frame(BLEHeadder, sizeof(BLEHeadder)); + frame += String((char*) &m_eddystoneData, lengthURL+1); // + 1 for TX power + + return frame; +} // getFrame + BLEUUID BLEEddystoneURL::getUUID() { - return BLEUUID(beaconUUID); + uint16_t uuid = (((uint16_t)BLEHeadder[10]) << 8) | BLEHeadder[9]; + return BLEUUID(uuid); } // getUUID int8_t BLEEddystoneURL::getPower() { - return m_eddystoneData.advertisedTxPower; + return m_eddystoneData.advertisedTxPower; } // getPower -std::string BLEEddystoneURL::getURL() { - return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url)); +String BLEEddystoneURL::getURL() { + return String((char*) &m_eddystoneData.url, lengthURL); } // getURL -std::string BLEEddystoneURL::getDecodedURL() { - std::string decodedURL = ""; - - switch (m_eddystoneData.url[0]) { - case 0x00: - decodedURL += "http://www."; - break; - case 0x01: - decodedURL += "https://www."; - break; - case 0x02: - decodedURL += "http://"; - break; - case 0x03: - decodedURL += "https://"; - break; - default: - decodedURL += m_eddystoneData.url[0]; - } - - for (int i = 1; i < lengthURL; i++) { - if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) { - decodedURL += m_eddystoneData.url[i]; - } else { - switch (m_eddystoneData.url[i]) { - case 0x00: - decodedURL += ".com/"; - break; - case 0x01: - decodedURL += ".org/"; - break; - case 0x02: - decodedURL += ".edu/"; - break; - case 0x03: - decodedURL += ".net/"; - break; - case 0x04: - decodedURL += ".info/"; - break; - case 0x05: - decodedURL += ".biz/"; - break; - case 0x06: - decodedURL += ".gov/"; - break; - case 0x07: - decodedURL += ".com"; - break; - case 0x08: - decodedURL += ".org"; - break; - case 0x09: - decodedURL += ".edu"; - break; - case 0x0A: - decodedURL += ".net"; - break; - case 0x0B: - decodedURL += ".info"; - break; - case 0x0C: - decodedURL += ".biz"; - break; - case 0x0D: - decodedURL += ".gov"; - break; - default: - break; - } - } - } - return decodedURL; -} // getDecodedURL +String BLEEddystoneURL::getPrefix(){ + if(m_eddystoneData.url[0] <= 0x03){ + return EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]]; + }else{ + return ""; + } +} +String BLEEddystoneURL::getSuffix(){ + if(m_eddystoneData.url[lengthURL-1] <= 0x0D){ + return EDDYSTONE_URL_SUFFIX[m_eddystoneData.url[lengthURL-1]]; + }else{ + return ""; + } +} +String BLEEddystoneURL::getDecodedURL() { + std::string decodedURL = ""; + decodedURL += getPrefix().c_str(); + if(decodedURL.length() == 0){ // No prefix extracted - interpret byte [0] as character + decodedURL += (char)m_eddystoneData.url[0]; + } + for(int i = 1; i < lengthURL; i++) { + if (m_eddystoneData.url[i] >= 33 && m_eddystoneData.url[i] < 127) { + decodedURL += (char)m_eddystoneData.url[i]; + }else{ + if(i != lengthURL-1 || m_eddystoneData.url[i] > 0x0D){ // Ignore last Byte and values used for suffix + log_e("Unexpected unprintable char in URL 0x%02X: m_eddystoneData.url[%d]", m_eddystoneData.url[i], i); + } + } + } + decodedURL += getSuffix().c_str(); + return String(decodedURL.c_str()); +} // getDecodedURL /** * Set the raw data for the beacon record. + * Example: + * uint8_t *payload = advertisedDevice.getPayload(); + * eddystoneTLM.setData(String((char*)payload+11, advertisedDevice.getPayloadLength() - 11)); + * Note: the offset 11 works for current implementation of example BLE_EddystoneTLM Beacon.ino, however + * the position is not static and it is programmers responsibility to align the data. + * Data frame: + * | Field || Len | Type | UUID | EddyStone URL | + * | Offset || 0 | 1 | 2 | 4 | + * | Len || 1 B | 1 B | 2 B | up to 20 B | + * | Data || ?? | ?? | 0xAA | 0xFE | ??? | + * + * EddyStone TLM frame: + * | Field || Type | TX Power | URL prefix | URL | + * | Offset || 0 | 1 | 2 | 3 | + * | Len || 1 B | 1 B | 1 B | 0-17 B | + * | Data || 0x10 | ?? | ?? | ?? | */ -void BLEEddystoneURL::setData(std::string data) { - if (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)); - memcpy(&m_eddystoneData, data.data(), data.length()); - lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url)); +void BLEEddystoneURL::setData(String data) { + if (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)); + memcpy(&m_eddystoneData, data.c_str(), data.length()); + lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url)); } // setData void BLEEddystoneURL::setUUID(BLEUUID l_uuid) { - beaconUUID = l_uuid.getNative()->uuid.uuid16; + uint16_t beaconUUID = l_uuid.getNative()->uuid.uuid16; + BLEHeadder[10] = beaconUUID >> 8; + BLEHeadder[9] = beaconUUID & 0x00FF; } // setUUID + +void BLEEddystoneURL::setPower(esp_power_level_t advertisedTxPower) { + int tx_power; + switch(advertisedTxPower){ + case ESP_PWR_LVL_N12: // 12dbm + tx_power = -12; + break; + case ESP_PWR_LVL_N9: // -9dbm + tx_power = -9; + break; + case ESP_PWR_LVL_N6: // -6dbm + tx_power = -6; + break; + case ESP_PWR_LVL_N3: // -3dbm + tx_power = -3; + break; + case ESP_PWR_LVL_N0: // 0dbm + tx_power = 0; + break; + case ESP_PWR_LVL_P3: // +3dbm + tx_power = +3; + break; + case ESP_PWR_LVL_P6: // +6dbm + tx_power = +6; + break; + case ESP_PWR_LVL_P9: // +9dbm + tx_power = +9; + break; + default: tx_power = 0; + } + m_eddystoneData.advertisedTxPower = int8_t((tx_power - -100) / 2); +} // setPower + + void BLEEddystoneURL::setPower(int8_t advertisedTxPower) { - m_eddystoneData.advertisedTxPower = advertisedTxPower; + m_eddystoneData.advertisedTxPower = advertisedTxPower; } // setPower -void BLEEddystoneURL::setURL(std::string url) { +// Set URL bytes including prefix and optional suffix +// | Field | Prefix | URL + optional Suffix | +// | Offset | 0 | 1 | +// | Length | 1 B | 0 - 17 B | +// | Example | 0x02 | 0x676F6F676C65 0x07 | +// | Decoded | http:// | g o o g l e .com | +void BLEEddystoneURL::setURL(String url) { if (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; + 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)); - memcpy(m_eddystoneData.url, url.data(), url.length()); + memcpy(m_eddystoneData.url, url.c_str(), url.length()); lengthURL = url.length(); } // setURL +int BLEEddystoneURL::setSmartURL(String url) { + if(url.length() == 0){ + log_e("URL String has 0 length"); + return 0; // ERROR + } + for(auto character : url){ + if(!isPrintable(character)){ + log_e("URL contains unprintable character(s)"); + return 0; // ERROR + } + } + bool hasPrefix = false; + bool hasSuffix = false; + m_eddystoneData.url[0] = 0x00; // Init with default prefix "http://www." + uint8_t suffix = 0x0E; // Init with empty string + log_d("Encode url \"%s\" with length %d", url.c_str(), url.length()); + for(uint8_t i = 0; i < 4; ++i){ + if(url.substring(0, EDDYSTONE_URL_PREFIX[i].length()) == EDDYSTONE_URL_PREFIX[i]){ + m_eddystoneData.url[0] = i; + hasPrefix = true; + break; + } + } + + if(hasPrefix == false){ + log_w("Prefix not found - using default prefix \"http://www.\" = 0x00\n\tNote: URL must contain one of the prefixes: \"http://www.\", \"https://www.\", \"http://\", \"https://\""); + } + + for(uint8_t i = 0; i < 0x0E; ++i){ + std::string std_url(url.c_str()); + std::string std_suffix(EDDYSTONE_URL_SUFFIX[i].c_str()); + size_t found_pos = std_url.find(std_suffix); + if(found_pos != std::string::npos){ + hasSuffix = true; + suffix = i; + break; + } + } + + size_t baseUrlLen = url.length() - (hasPrefix ? EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length() : 0) - EDDYSTONE_URL_SUFFIX[suffix].length(); + lengthURL = baseUrlLen + 1 + (hasSuffix ? 1 : 0); + if(lengthURL > 18){ + log_e("Encoded URL is too long %d B - max 18 B", lengthURL); + return 0; // ERROR + } + String baseUrl = url.substring((hasPrefix ? EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length() : 0), baseUrlLen+(hasPrefix ? EDDYSTONE_URL_PREFIX[m_eddystoneData.url[0]].length() : 0)); + memcpy((void*)(m_eddystoneData.url+1), (void*)baseUrl.c_str(), baseUrl.length()); // substr for Arduino String + + if(hasSuffix){ + m_eddystoneData.url[1+baseUrlLen] = suffix; + } + + return 1; // OK +} // setSmartURL + +void BLEEddystoneURL::_initHeadder(){ + BLEHeadder[0] = 0x02; // Len + BLEHeadder[1] = 0x01; // Type Flags + BLEHeadder[2] = 0x06; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 + BLEHeadder[3] = 0x03; // Len + BLEHeadder[4] = 0x03; // Type 16-Bit UUID + BLEHeadder[5] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB + BLEHeadder[6] = 0xFE; // Eddystone UUID 1 MSB + BLEHeadder[7] = 0x00; // Length of Beacon Data shall be calculated later + BLEHeadder[8] = 0x16; // Type Service Data + BLEHeadder[9] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB + BLEHeadder[10] = 0xFE; // Eddystone UUID 1 MSB + BLEHeadder[11] = 0x10; // Eddystone Frame Type - URL +} #endif #endif /* SOC_BLE_SUPPORTED */ diff --git a/libraries/BLE/src/BLEEddystoneURL.h b/libraries/BLE/src/BLEEddystoneURL.h index a1e3d7f9045..7f6e114f894 100644 --- a/libraries/BLE/src/BLEEddystoneURL.h +++ b/libraries/BLE/src/BLEEddystoneURL.h @@ -3,6 +3,9 @@ * * Created on: Mar 12, 2018 * Author: pcbreflux + * Upgraded on: Feb 20, 2023 + * By: Tomas Pilny + * */ #ifndef _BLEEddystoneURL_H_ @@ -11,9 +14,14 @@ #if SOC_BLE_SUPPORTED #include "BLEUUID.h" +#include +#include "esp_bt.h" #define EDDYSTONE_URL_FRAME_TYPE 0x10 +extern String EDDYSTONE_URL_PREFIX[]; +extern String EDDYSTONE_URL_SUFFIX[]; + /** * @brief Representation of a beacon. * See: @@ -21,26 +29,31 @@ */ class BLEEddystoneURL { public: - BLEEddystoneURL(); - std::string getData(); - BLEUUID getUUID(); - int8_t getPower(); - std::string getURL(); - std::string getDecodedURL(); - void setData(std::string data); - void setUUID(BLEUUID l_uuid); - void setPower(int8_t advertisedTxPower); - void setURL(std::string url); + BLEEddystoneURL(); + BLEEddystoneURL(BLEAdvertisedDevice *advertisedDevice); + String getData(); + String getFrame(); + BLEUUID getUUID(); + int8_t getPower(); + String getURL(); + String getPrefix(); + String getSuffix(); + String getDecodedURL(); + void setData(String data); + void setUUID(BLEUUID l_uuid); + void setPower(int8_t advertisedTxPower); + void setPower(esp_power_level_t advertisedTxPower); + void setURL(String url); + int setSmartURL(String url); private: - uint16_t beaconUUID; - uint8_t lengthURL; - struct { - uint8_t frameType; - int8_t advertisedTxPower; - uint8_t url[18]; // 18 bytes: 1 byte for URL scheme + up to 17 bytes of URL - } __attribute__((packed)) m_eddystoneData; - + uint8_t lengthURL; // Describes the length of the URL part including prefix and optional suffix - max 18 B (excluding TX power, frame type and preceding header) + struct { + int8_t advertisedTxPower; + uint8_t url[18]; // Byte [0] is for prefix. Last valid byte **can** contain suffix - i.e. the next byte after the URL + } __attribute__((packed)) m_eddystoneData; + void _initHeadder(); + char BLEHeadder[12]; }; // BLEEddystoneURL #endif /* SOC_BLE_SUPPORTED */ diff --git a/libraries/BLE/src/BLEEddystoneURL.h.orig b/libraries/BLE/src/BLEEddystoneURL.h.orig new file mode 100644 index 00000000000..57722d0b769 --- /dev/null +++ b/libraries/BLE/src/BLEEddystoneURL.h.orig @@ -0,0 +1,66 @@ +/* + * BLEEddystoneURL.cpp + * + * Created on: Mar 12, 2018 + * Author: pcbreflux + * Upgraded on: Feb 17, 2023 + * By: Tomas Pilny + * + */ + +#ifndef _BLEEddystoneURL_H_ +#define _BLEEddystoneURL_H_ +#include "BLEUUID.h" +#include +#include + +#define EDDYSTONE_URL_FRAME_TYPE 0x10 + +extern String EDDYSTONE_URL_PREFIX[]; +extern String EDDYSTONE_URL_SUFFIX[]; + +/** + * @brief Representation of a beacon. + * See: + * * https://github.com/google/eddystone + */ +class BLEEddystoneURL { +public: + BLEEddystoneURL(); + BLEEddystoneURL(BLEAdvertisedDevice *advertisedDevice); + std::string getData(); + String getFrame(); + BLEUUID getUUID(); + int8_t getPower(); + std::string getURL(); + String getPrefix(); + String getSuffix(); + std::string getDecodedURL(); + void setData(std::string data); + void setUUID(BLEUUID l_uuid); + void setPower(int8_t advertisedTxPower); + void setURL(std::string url); + int setSmartURL(String url); + +private: +<<<<<<< Updated upstream + uint16_t beaconUUID; + uint8_t lengthURL; + struct { + uint8_t frameType; + int8_t advertisedTxPower; + uint8_t url[18]; // 18 bytes: 1 byte for URL scheme + up to 17 bytes of URL + } __attribute__((packed)) m_eddystoneData; + +======= + uint8_t lengthURL; // Describes length of URL part including prefix and suffix - max 18 B (excluding TX power, frame type and preceding header) + struct { + int8_t advertisedTxPower; + uint8_t url[18]; // Byte [0] is for prefix. Last byte **can** contain suffix + } __attribute__((packed)) m_eddystoneData; + void _initHeadder(); + char BLEHeadder[12]; +>>>>>>> Stashed changes +}; // BLEEddystoneURL + +#endif /* _BLEEddystoneURL_H_ */ diff --git a/libraries/BLE/src/BLEHIDDevice.cpp b/libraries/BLE/src/BLEHIDDevice.cpp index 0aff716d08e..27d88044cec 100644 --- a/libraries/BLE/src/BLEHIDDevice.cpp +++ b/libraries/BLE/src/BLEHIDDevice.cpp @@ -89,7 +89,7 @@ BLECharacteristic* BLEHIDDevice::manufacturer() { * @brief Set manufacturer name * @param [in] name manufacturer name */ -void BLEHIDDevice::manufacturer(std::string name) { +void BLEHIDDevice::manufacturer(String name) { m_manufacturerCharacteristic->setValue(name); } diff --git a/libraries/BLE/src/BLEHIDDevice.h b/libraries/BLE/src/BLEHIDDevice.h index ecab1f52ed0..956dbada806 100644 --- a/libraries/BLE/src/BLEHIDDevice.h +++ b/libraries/BLE/src/BLEHIDDevice.h @@ -44,7 +44,7 @@ class BLEHIDDevice { BLEService* batteryService(); BLECharacteristic* manufacturer(); - void manufacturer(std::string name); + void manufacturer(String name); //BLECharacteristic* pnp(); void pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version); //BLECharacteristic* hidInfo(); diff --git a/libraries/BLE/src/BLERemoteCharacteristic.cpp b/libraries/BLE/src/BLERemoteCharacteristic.cpp index 996fc8d741a..9854984cbe5 100644 --- a/libraries/BLE/src/BLERemoteCharacteristic.cpp +++ b/libraries/BLE/src/BLERemoteCharacteristic.cpp @@ -187,7 +187,7 @@ void BLERemoteCharacteristic::gattClientEventHandler(esp_gattc_cb_event_t event, // At this point, we have determined that the event is for us, so now we save the value // and unlock the semaphore to ensure that the requestor of the data can continue. if (evtParam->read.status == ESP_GATT_OK) { - m_value = std::string((char*) evtParam->read.value, evtParam->read.value_len); + m_value = String((char*) evtParam->read.value, evtParam->read.value_len); if(m_rawData != nullptr) free(m_rawData); m_rawData = (uint8_t*) calloc(evtParam->read.value_len, sizeof(uint8_t)); memcpy(m_rawData, evtParam->read.value, evtParam->read.value_len); @@ -304,7 +304,7 @@ void BLERemoteCharacteristic::retrieveDescriptors() { this ); - m_descriptorMap.insert(std::pair(pNewRemoteDescriptor->getUUID().toString(), pNewRemoteDescriptor)); + m_descriptorMap.insert(std::pair(pNewRemoteDescriptor->getUUID().toString(), pNewRemoteDescriptor)); offset++; } // while true @@ -316,7 +316,7 @@ void BLERemoteCharacteristic::retrieveDescriptors() { /** * @brief Retrieve the map of descriptors keyed by UUID. */ -std::map* BLERemoteCharacteristic::getDescriptors() { +std::map* BLERemoteCharacteristic::getDescriptors() { return &m_descriptorMap; } // getDescriptors @@ -339,7 +339,7 @@ uint16_t BLERemoteCharacteristic::getHandle() { */ BLERemoteDescriptor* BLERemoteCharacteristic::getDescriptor(BLEUUID uuid) { log_v(">> getDescriptor: uuid: %s", uuid.toString().c_str()); - std::string v = uuid.toString(); + String v = uuid.toString(); for (auto &myPair : m_descriptorMap) { if (myPair.first == v) { log_v("<< getDescriptor: found"); @@ -374,9 +374,9 @@ BLEUUID BLERemoteCharacteristic::getUUID() { * @return The unsigned 16 bit value. */ uint16_t BLERemoteCharacteristic::readUInt16() { - std::string value = readValue(); + String value = readValue(); if (value.length() >= 2) { - return *(uint16_t*)(value.data()); + return *(uint16_t*)(value.c_str()); } return 0; } // readUInt16 @@ -387,9 +387,9 @@ uint16_t BLERemoteCharacteristic::readUInt16() { * @return the unsigned 32 bit value. */ uint32_t BLERemoteCharacteristic::readUInt32() { - std::string value = readValue(); + String value = readValue(); if (value.length() >= 4) { - return *(uint32_t*)(value.data()); + return *(uint32_t*)(value.c_str()); } return 0; } // readUInt32 @@ -400,7 +400,7 @@ uint32_t BLERemoteCharacteristic::readUInt32() { * @return The value as a byte */ uint8_t BLERemoteCharacteristic::readUInt8() { - std::string value = readValue(); + String value = readValue(); if (value.length() >= 1) { return (uint8_t)value[0]; } @@ -412,9 +412,9 @@ uint8_t BLERemoteCharacteristic::readUInt8() { * @return the float value. */ float BLERemoteCharacteristic::readFloat() { - std::string value = readValue(); + String value = readValue(); if (value.length() >= 4) { - return *(float*)(value.data()); + return *(float*)(value.c_str()); } return 0.0; } // readFloat @@ -423,13 +423,13 @@ float BLERemoteCharacteristic::readFloat() { * @brief Read the value of the remote characteristic. * @return The value of the remote characteristic. */ -std::string BLERemoteCharacteristic::readValue() { +String BLERemoteCharacteristic::readValue() { 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()) { log_e("Disconnected"); - return std::string(); + return String(); } m_semaphoreReadCharEvt.take("readValue"); @@ -448,7 +448,7 @@ std::string BLERemoteCharacteristic::readValue() { return ""; } - // Block waiting for the event that indicates that the read has completed. When it has, the std::string found + // Block waiting for the event that indicates that the read has completed. When it has, the String found // in m_value will contain our data. m_semaphoreReadCharEvt.wait("readValue"); @@ -531,8 +531,8 @@ void BLERemoteCharacteristic::removeDescriptors() { * @brief Convert a BLERemoteCharacteristic to a string representation; * @return a String representation. */ -std::string BLERemoteCharacteristic::toString() { - std::string res = "Characteristic: uuid: " + m_uuid.toString(); +String BLERemoteCharacteristic::toString() { + String res = "Characteristic: uuid: " + m_uuid.toString(); char val[6]; res += ", handle: "; snprintf(val, sizeof(val), "%d", getHandle()); @@ -551,8 +551,8 @@ std::string BLERemoteCharacteristic::toString() { * @param [in] response Do we expect a response? * @return N/A. */ -void BLERemoteCharacteristic::writeValue(std::string newValue, bool response) { - writeValue((uint8_t*)newValue.data(), newValue.length(), response); +void BLERemoteCharacteristic::writeValue(String newValue, bool response) { + writeValue((uint8_t*)newValue.c_str(), newValue.length(), response); } // writeValue @@ -576,7 +576,7 @@ void BLERemoteCharacteristic::writeValue(uint8_t newValue, bool response) { * @param [in] response Whether we require a response from the write. */ void BLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool response) { - // writeValue(std::string((char*)data, length), response); + // writeValue(String((char*)data, length), response); log_v(">> writeValue(), length: %d", length); // Check to see that we are connected. diff --git a/libraries/BLE/src/BLERemoteCharacteristic.h b/libraries/BLE/src/BLERemoteCharacteristic.h index e9f6b97fab7..1ba4ec3c04d 100644 --- a/libraries/BLE/src/BLERemoteCharacteristic.h +++ b/libraries/BLE/src/BLERemoteCharacteristic.h @@ -12,8 +12,6 @@ #include "sdkconfig.h" #if defined(CONFIG_BLUEDROID_ENABLED) - -#include #include #include @@ -41,20 +39,20 @@ class BLERemoteCharacteristic { bool canWrite(); bool canWriteNoResponse(); BLERemoteDescriptor* getDescriptor(BLEUUID uuid); - std::map* getDescriptors(); + std::map* getDescriptors(); BLERemoteService* getRemoteService(); uint16_t getHandle(); BLEUUID getUUID(); - std::string readValue(); + String readValue(); uint8_t readUInt8(); uint16_t readUInt16(); uint32_t readUInt32(); float readFloat(); void registerForNotify(notify_callback _callback, bool notifications = true, bool descriptorRequiresRegistration = true); void writeValue(uint8_t* data, size_t length, bool response = false); - void writeValue(std::string newValue, bool response = false); + void writeValue(String newValue, bool response = false); void writeValue(uint8_t newValue, bool response = false); - std::string toString(); + String toString(); uint8_t* readRawData(); void setAuth(esp_gatt_auth_req_t auth); @@ -79,12 +77,12 @@ class BLERemoteCharacteristic { FreeRTOS::Semaphore m_semaphoreReadCharEvt = FreeRTOS::Semaphore("ReadCharEvt"); FreeRTOS::Semaphore m_semaphoreRegForNotifyEvt = FreeRTOS::Semaphore("RegForNotifyEvt"); FreeRTOS::Semaphore m_semaphoreWriteCharEvt = FreeRTOS::Semaphore("WriteCharEvt"); - std::string m_value; + String m_value; uint8_t *m_rawData; notify_callback m_notifyCallback; // We maintain a map of descriptors owned by this characteristic keyed by a string representation of the UUID. - std::map m_descriptorMap; + std::map m_descriptorMap; }; // BLERemoteCharacteristic #endif /* CONFIG_BLUEDROID_ENABLED */ diff --git a/libraries/BLE/src/BLERemoteDescriptor.cpp b/libraries/BLE/src/BLERemoteDescriptor.cpp index dba4de29980..92554e328e8 100644 --- a/libraries/BLE/src/BLERemoteDescriptor.cpp +++ b/libraries/BLE/src/BLERemoteDescriptor.cpp @@ -15,13 +15,13 @@ #include "esp32-hal-log.h" BLERemoteDescriptor::BLERemoteDescriptor( - uint16_t handle, - BLEUUID uuid, - BLERemoteCharacteristic* pRemoteCharacteristic) { + uint16_t handle, + BLEUUID uuid, + BLERemoteCharacteristic* pRemoteCharacteristic) { - m_handle = handle; - m_uuid = uuid; - m_pRemoteCharacteristic = pRemoteCharacteristic; + m_handle = handle; + m_uuid = uuid; + m_pRemoteCharacteristic = pRemoteCharacteristic; m_auth = ESP_GATT_AUTH_REQ_NONE; } @@ -31,7 +31,7 @@ BLERemoteDescriptor::BLERemoteDescriptor( * @return The handle associated with this remote descriptor. */ uint16_t BLERemoteDescriptor::getHandle() { - return m_handle; + return m_handle; } // getHandle @@ -40,7 +40,7 @@ uint16_t BLERemoteDescriptor::getHandle() { * @return The characteristic that owns this descriptor. */ BLERemoteCharacteristic* BLERemoteDescriptor::getRemoteCharacteristic() { - return m_pRemoteCharacteristic; + return m_pRemoteCharacteristic; } // getRemoteCharacteristic @@ -49,100 +49,100 @@ BLERemoteCharacteristic* BLERemoteDescriptor::getRemoteCharacteristic() { * @return The UUID associated this remote descriptor. */ BLEUUID BLERemoteDescriptor::getUUID() { - return m_uuid; + return m_uuid; } // getUUID void BLERemoteDescriptor::gattClientEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* evtParam) { - switch(event) { - // ESP_GATTC_READ_DESCR_EVT - // This event indicates that the server has responded to the read request. - // - // read: - // - esp_gatt_status_t status - // - uint16_t conn_id - // - uint16_t handle - // - uint8_t* value - // - uint16_t value_len - case ESP_GATTC_READ_DESCR_EVT: - // If this event is not for us, then nothing further to do. - if (evtParam->read.handle != getHandle()) break; - // At this point, we have determined that the event is for us, so now we save the value - if (evtParam->read.status == ESP_GATT_OK) { - // it will read the cached value of the descriptor - m_value = std::string((char*) evtParam->read.value, evtParam->read.value_len); - } else { - m_value = ""; - } - // Unlock the semaphore to ensure that the requestor of the data can continue. - m_semaphoreReadDescrEvt.give(); - break; - - case ESP_GATTC_WRITE_DESCR_EVT: - if (evtParam->write.handle != getHandle()) - break; - m_semaphoreWriteDescrEvt.give(); - break; - default: - break; - } + switch(event) { + // ESP_GATTC_READ_DESCR_EVT + // This event indicates that the server has responded to the read request. + // + // read: + // - esp_gatt_status_t status + // - uint16_t conn_id + // - uint16_t handle + // - uint8_t* value + // - uint16_t value_len + case ESP_GATTC_READ_DESCR_EVT: + // If this event is not for us, then nothing further to do. + if (evtParam->read.handle != getHandle()) break; + // At this point, we have determined that the event is for us, so now we save the value + if (evtParam->read.status == ESP_GATT_OK) { + // it will read the cached value of the descriptor + m_value = String((char*) evtParam->read.value, evtParam->read.value_len); + } else { + m_value = ""; + } + // Unlock the semaphore to ensure that the requestor of the data can continue. + m_semaphoreReadDescrEvt.give(); + break; + + case ESP_GATTC_WRITE_DESCR_EVT: + if (evtParam->write.handle != getHandle()) + break; + m_semaphoreWriteDescrEvt.give(); + break; + default: + break; + } } -std::string BLERemoteDescriptor::readValue() { - log_v(">> readValue: %s", toString().c_str()); +String BLERemoteDescriptor::readValue() { + log_v(">> readValue: %s", toString().c_str()); - // Check to see that we are connected. - if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) { - log_e("Disconnected"); - return std::string(); - } + // Check to see that we are connected. + if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) { + log_e("Disconnected"); + return String(); + } - m_semaphoreReadDescrEvt.take("readValue"); + m_semaphoreReadDescrEvt.take("readValue"); - // Ask the BLE subsystem to retrieve the value for the remote hosted characteristic. - esp_err_t errRc = ::esp_ble_gattc_read_char_descr( - m_pRemoteCharacteristic->getRemoteService()->getClient()->getGattcIf(), - m_pRemoteCharacteristic->getRemoteService()->getClient()->getConnId(), // The connection ID to the BLE server - getHandle(), // The handle of this characteristic - m_auth); // Security + // Ask the BLE subsystem to retrieve the value for the remote hosted characteristic. + esp_err_t errRc = ::esp_ble_gattc_read_char_descr( + m_pRemoteCharacteristic->getRemoteService()->getClient()->getGattcIf(), + m_pRemoteCharacteristic->getRemoteService()->getClient()->getConnId(), // The connection ID to the BLE server + getHandle(), // The handle of this characteristic + m_auth); // Security - if (errRc != ESP_OK) { - log_e("esp_ble_gattc_read_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - return ""; - } + if (errRc != ESP_OK) { + log_e("esp_ble_gattc_read_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + return ""; + } - // Block waiting for the event that indicates that the read has completed. When it has, the std::string found - // in m_value will contain our data. - m_semaphoreReadDescrEvt.wait("readValue"); + // Block waiting for the event that indicates that the read has completed. When it has, the String found + // in m_value will contain our data. + m_semaphoreReadDescrEvt.wait("readValue"); - log_v("<< readValue(): length: %d", m_value.length()); - return m_value; + log_v("<< readValue(): length: %d", m_value.length()); + return m_value; } // readValue uint8_t BLERemoteDescriptor::readUInt8() { - std::string value = readValue(); - if (value.length() >= 1) { - return (uint8_t) value[0]; - } - return 0; + String value = readValue(); + if (value.length() >= 1) { + return (uint8_t) value[0]; + } + return 0; } // readUInt8 uint16_t BLERemoteDescriptor::readUInt16() { - std::string value = readValue(); - if (value.length() >= 2) { - return *(uint16_t*) value.data(); - } - return 0; + String value = readValue(); + if (value.length() >= 2) { + return *(uint16_t*) value.c_str(); + } + return 0; } // readUInt16 uint32_t BLERemoteDescriptor::readUInt32() { - std::string value = readValue(); - if (value.length() >= 4) { - return *(uint32_t*) value.data(); - } - return 0; + String value = readValue(); + if (value.length() >= 4) { + return *(uint32_t*) value.c_str(); + } + return 0; } // readUInt32 @@ -150,13 +150,13 @@ uint32_t BLERemoteDescriptor::readUInt32() { * @brief Return a string representation of this BLE Remote Descriptor. * @retun A string representation of this BLE Remote Descriptor. */ -std::string BLERemoteDescriptor::toString() { - char val[6]; - snprintf(val, sizeof(val), "%d", getHandle()); - std::string res = "handle: "; - res += val; - res += ", uuid: " + getUUID().toString(); - return res; +String BLERemoteDescriptor::toString() { + char val[6]; + snprintf(val, sizeof(val), "%d", getHandle()); + String res = "handle: "; + res += val; + res += ", uuid: " + getUUID().toString(); + return res; } // toString @@ -167,30 +167,30 @@ std::string BLERemoteDescriptor::toString() { * @param [in] response True if we expect a response. */ void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response) { - log_v(">> writeValue: %s", toString().c_str()); - // Check to see that we are connected. - if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) { - log_e("Disconnected"); - return; - } - - m_semaphoreWriteDescrEvt.take("writeValue"); - - esp_err_t errRc = ::esp_ble_gattc_write_char_descr( - m_pRemoteCharacteristic->getRemoteService()->getClient()->getGattcIf(), - m_pRemoteCharacteristic->getRemoteService()->getClient()->getConnId(), - getHandle(), - length, // Data length - data, // Data - response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP, - m_auth - ); - if (errRc != ESP_OK) { - log_e("esp_ble_gattc_write_char_descr: %d", errRc); - } - - m_semaphoreWriteDescrEvt.wait("writeValue"); - log_v("<< writeValue"); + log_v(">> writeValue: %s", toString().c_str()); + // Check to see that we are connected. + if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) { + log_e("Disconnected"); + return; + } + + m_semaphoreWriteDescrEvt.take("writeValue"); + + esp_err_t errRc = ::esp_ble_gattc_write_char_descr( + m_pRemoteCharacteristic->getRemoteService()->getClient()->getGattcIf(), + m_pRemoteCharacteristic->getRemoteService()->getClient()->getConnId(), + getHandle(), + length, // Data length + data, // Data + response ? ESP_GATT_WRITE_TYPE_RSP : ESP_GATT_WRITE_TYPE_NO_RSP, + m_auth + ); + if (errRc != ESP_OK) { + log_e("esp_ble_gattc_write_char_descr: %d", errRc); + } + + m_semaphoreWriteDescrEvt.wait("writeValue"); + log_v("<< writeValue"); } // writeValue @@ -199,8 +199,8 @@ void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response * @param [in] newValue The data to send to the remote descriptor. * @param [in] response True if we expect a response. */ -void BLERemoteDescriptor::writeValue(std::string newValue, bool response) { - writeValue((uint8_t*) newValue.data(), newValue.length(), response); +void BLERemoteDescriptor::writeValue(String newValue, bool response) { + writeValue((uint8_t*) newValue.c_str(), newValue.length(), response); } // writeValue @@ -210,7 +210,7 @@ void BLERemoteDescriptor::writeValue(std::string newValue, bool response) { * @param [in] True if we expect a response. */ void BLERemoteDescriptor::writeValue(uint8_t newValue, bool response) { - writeValue(&newValue, 1, response); + writeValue(&newValue, 1, response); } // writeValue /** diff --git a/libraries/BLE/src/BLERemoteDescriptor.h b/libraries/BLE/src/BLERemoteDescriptor.h index 1276b93ad04..5b9cb355595 100644 --- a/libraries/BLE/src/BLERemoteDescriptor.h +++ b/libraries/BLE/src/BLERemoteDescriptor.h @@ -26,33 +26,33 @@ class BLERemoteCharacteristic; */ class BLERemoteDescriptor { public: - uint16_t getHandle(); - BLERemoteCharacteristic* getRemoteCharacteristic(); - BLEUUID getUUID(); - std::string readValue(void); - uint8_t readUInt8(void); - uint16_t readUInt16(void); - uint32_t readUInt32(void); - std::string toString(void); - void writeValue(uint8_t* data, size_t length, bool response = false); - void writeValue(std::string newValue, bool response = false); - void writeValue(uint8_t newValue, bool response = false); + uint16_t getHandle(); + BLERemoteCharacteristic* getRemoteCharacteristic(); + BLEUUID getUUID(); + String readValue(void); + uint8_t readUInt8(void); + uint16_t readUInt16(void); + uint32_t readUInt32(void); + String toString(void); + void writeValue(uint8_t* data, size_t length, bool response = false); + void writeValue(String newValue, bool response = false); + void writeValue(uint8_t newValue, bool response = false); void setAuth(esp_gatt_auth_req_t auth); - void gattClientEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* evtParam); + void gattClientEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* evtParam); private: - friend class BLERemoteCharacteristic; - BLERemoteDescriptor( - uint16_t handle, - BLEUUID uuid, - BLERemoteCharacteristic* pRemoteCharacteristic - ); - uint16_t m_handle; // Server handle of this descriptor. - BLEUUID m_uuid; // UUID of this descriptor. - std::string m_value; // Last received value of the descriptor. - BLERemoteCharacteristic* m_pRemoteCharacteristic; // Reference to the Remote characteristic of which this descriptor is associated. - FreeRTOS::Semaphore m_semaphoreReadDescrEvt = FreeRTOS::Semaphore("ReadDescrEvt"); - FreeRTOS::Semaphore m_semaphoreWriteDescrEvt = FreeRTOS::Semaphore("WriteDescrEvt"); + friend class BLERemoteCharacteristic; + BLERemoteDescriptor( + uint16_t handle, + BLEUUID uuid, + BLERemoteCharacteristic* pRemoteCharacteristic + ); + uint16_t m_handle; // Server handle of this descriptor. + BLEUUID m_uuid; // UUID of this descriptor. + String m_value; // Last received value of the descriptor. + BLERemoteCharacteristic* m_pRemoteCharacteristic; // Reference to the Remote characteristic of which this descriptor is associated. + FreeRTOS::Semaphore m_semaphoreReadDescrEvt = FreeRTOS::Semaphore("ReadDescrEvt"); + FreeRTOS::Semaphore m_semaphoreWriteDescrEvt = FreeRTOS::Semaphore("WriteDescrEvt"); esp_gatt_auth_req_t m_auth; diff --git a/libraries/BLE/src/BLERemoteService.cpp b/libraries/BLE/src/BLERemoteService.cpp index 41344108be8..874687748ba 100644 --- a/libraries/BLE/src/BLERemoteService.cpp +++ b/libraries/BLE/src/BLERemoteService.cpp @@ -20,37 +20,37 @@ #pragma GCC diagnostic warning "-Wunused-but-set-parameter" BLERemoteService::BLERemoteService( - esp_gatt_id_t srvcId, - BLEClient* pClient, - uint16_t startHandle, - uint16_t endHandle - ) { - - log_v(">> BLERemoteService()"); - m_srvcId = srvcId; - m_pClient = pClient; - m_uuid = BLEUUID(m_srvcId); - m_haveCharacteristics = false; - m_startHandle = startHandle; - m_endHandle = endHandle; - - log_v("<< BLERemoteService()"); + esp_gatt_id_t srvcId, + BLEClient* pClient, + uint16_t startHandle, + uint16_t endHandle + ) { + + log_v(">> BLERemoteService()"); + m_srvcId = srvcId; + m_pClient = pClient; + m_uuid = BLEUUID(m_srvcId); + m_haveCharacteristics = false; + m_startHandle = startHandle; + m_endHandle = endHandle; + + log_v("<< BLERemoteService()"); } BLERemoteService::~BLERemoteService() { - removeCharacteristics(); + removeCharacteristics(); } /* static bool compareSrvcId(esp_gatt_srvc_id_t id1, esp_gatt_srvc_id_t id2) { - if (id1.id.inst_id != id2.id.inst_id) { - return false; - } - if (!BLEUUID(id1.id.uuid).equals(BLEUUID(id2.id.uuid))) { - return false; - } - return true; + if (id1.id.inst_id != id2.id.inst_id) { + return false; + } + if (!BLEUUID(id1.id.uuid).equals(BLEUUID(id2.id.uuid))) { + return false; + } + return true; } // compareSrvcId */ @@ -58,64 +58,64 @@ static bool compareSrvcId(esp_gatt_srvc_id_t id1, esp_gatt_srvc_id_t id2) { * @brief Handle GATT Client events */ void BLERemoteService::gattClientEventHandler( - esp_gattc_cb_event_t event, - esp_gatt_if_t gattc_if, - esp_ble_gattc_cb_param_t* evtParam) { - switch (event) { - // - // ESP_GATTC_GET_CHAR_EVT - // - // get_char: - // - esp_gatt_status_t status - // - uin1t6_t conn_id - // - esp_gatt_srvc_id_t srvc_id - // - esp_gatt_id_t char_id - // - esp_gatt_char_prop_t char_prop - // - /* - case ESP_GATTC_GET_CHAR_EVT: { - // Is this event for this service? If yes, then the local srvc_id and the event srvc_id will be - // the same. - if (compareSrvcId(m_srvcId, evtParam->get_char.srvc_id) == false) { - break; - } - - // If the status is NOT OK then we have a problem and continue. - if (evtParam->get_char.status != ESP_GATT_OK) { - m_semaphoreGetCharEvt.give(); - break; - } - - // This is an indication that we now have the characteristic details for a characteristic owned - // by this service so remember it. - m_characteristicMap.insert(std::pair( - BLEUUID(evtParam->get_char.char_id.uuid).toString(), - new BLERemoteCharacteristic(evtParam->get_char.char_id, evtParam->get_char.char_prop, this) )); - - - // Now that we have received a characteristic, lets ask for the next one. - esp_err_t errRc = ::esp_ble_gattc_get_characteristic( - m_pClient->getGattcIf(), - m_pClient->getConnId(), - &m_srvcId, - &evtParam->get_char.char_id); - if (errRc != ESP_OK) { - log_e("esp_ble_gattc_get_characteristic: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - break; - } - - //m_semaphoreGetCharEvt.give(); - break; - } // ESP_GATTC_GET_CHAR_EVT + esp_gattc_cb_event_t event, + esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t* evtParam) { + switch (event) { + // + // ESP_GATTC_GET_CHAR_EVT + // + // get_char: + // - esp_gatt_status_t status + // - uin1t6_t conn_id + // - esp_gatt_srvc_id_t srvc_id + // - esp_gatt_id_t char_id + // - esp_gatt_char_prop_t char_prop + // + /* + case ESP_GATTC_GET_CHAR_EVT: { + // Is this event for this service? If yes, then the local srvc_id and the event srvc_id will be + // the same. + if (compareSrvcId(m_srvcId, evtParam->get_char.srvc_id) == false) { + break; + } + + // If the status is NOT OK then we have a problem and continue. + if (evtParam->get_char.status != ESP_GATT_OK) { + m_semaphoreGetCharEvt.give(); + break; + } + + // This is an indication that we now have the characteristic details for a characteristic owned + // by this service so remember it. + m_characteristicMap.insert(std::pair( + BLEUUID(evtParam->get_char.char_id.uuid).toString(), + new BLERemoteCharacteristic(evtParam->get_char.char_id, evtParam->get_char.char_prop, this) )); + + + // Now that we have received a characteristic, lets ask for the next one. + esp_err_t errRc = ::esp_ble_gattc_get_characteristic( + m_pClient->getGattcIf(), + m_pClient->getConnId(), + &m_srvcId, + &evtParam->get_char.char_id); + if (errRc != ESP_OK) { + log_e("esp_ble_gattc_get_characteristic: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + break; + } + + //m_semaphoreGetCharEvt.give(); + break; + } // ESP_GATTC_GET_CHAR_EVT */ - default: - break; - } // switch - - // Send the event to each of the characteristics owned by this service. - for (auto &myPair : m_characteristicMapByHandle) { - myPair.second->gattClientEventHandler(event, gattc_if, evtParam); - } + default: + break; + } // switch + + // Send the event to each of the characteristics owned by this service. + for (auto &myPair : m_characteristicMapByHandle) { + myPair.second->gattClientEventHandler(event, gattc_if, evtParam); + } } // gattClientEventHandler @@ -128,7 +128,7 @@ void BLERemoteService::gattClientEventHandler( BLERemoteCharacteristic* BLERemoteService::getCharacteristic(const char* uuid) { return getCharacteristic(BLEUUID(uuid)); } // getCharacteristic - + /** * @brief Get the characteristic object for the UUID. * @param [in] uuid Characteristic uuid. @@ -142,17 +142,17 @@ BLERemoteCharacteristic* BLERemoteService::getCharacteristic(BLEUUID uuid) { // device what characteristics it has in which case we have nothing to match against. If we have not // asked the device about its characteristics, then we do that now. Once we get the results we can then // examine the characteristics map to see if it has the characteristic we are looking for. - if (!m_haveCharacteristics) { - retrieveCharacteristics(); - } - std::string v = uuid.toString(); - for (auto &myPair : m_characteristicMap) { - if (myPair.first == v) { - return myPair.second; - } - } - // throw new BLEUuidNotFoundException(); // <-- we dont want exception here, which will cause app crash, we want to search if any characteristic can be found one after another - return nullptr; + if (!m_haveCharacteristics) { + retrieveCharacteristics(); + } + String v = uuid.toString(); + for (auto &myPair : m_characteristicMap) { + if (myPair.first == v) { + return myPair.second; + } + } + // throw new BLEUuidNotFoundException(); // <-- we dont want exception here, which will cause app crash, we want to search if any characteristic can be found one after another + return nullptr; } // getCharacteristic @@ -162,54 +162,54 @@ BLERemoteCharacteristic* BLERemoteService::getCharacteristic(BLEUUID uuid) { * @return N/A */ void BLERemoteService::retrieveCharacteristics() { - 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 = 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(), - m_startHandle, - m_endHandle, - &result, - &count, - offset - ); - - if (status == ESP_GATT_INVALID_OFFSET) { // We have reached the end of the entries. - break; - } - - if (status != ESP_GATT_OK) { // If we got an error, end. - log_e("esp_ble_gattc_get_all_char: %s", BLEUtils::gattStatusToString(status).c_str()); - break; - } - - if (count == 0) { // If we failed to get any new records, end. - break; - } - - 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( - result.char_handle, - BLEUUID(result.uuid), - result.properties, - this - ); - - m_characteristicMap.insert(std::pair(pNewRemoteCharacteristic->getUUID().toString(), pNewRemoteCharacteristic)); - m_characteristicMapByHandle.insert(std::pair(result.char_handle, pNewRemoteCharacteristic)); - offset++; // Increment our count of number of descriptors found. - } // Loop forever (until we break inside the loop). - - m_haveCharacteristics = true; // Remember that we have received the characteristics. - log_v("<< getCharacteristics()"); + 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 = 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(), + m_startHandle, + m_endHandle, + &result, + &count, + offset + ); + + if (status == ESP_GATT_INVALID_OFFSET) { // We have reached the end of the entries. + break; + } + + if (status != ESP_GATT_OK) { // If we got an error, end. + log_e("esp_ble_gattc_get_all_char: %s", BLEUtils::gattStatusToString(status).c_str()); + break; + } + + if (count == 0) { // If we failed to get any new records, end. + break; + } + + 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( + result.char_handle, + BLEUUID(result.uuid), + result.properties, + this + ); + + m_characteristicMap.insert(std::pair(pNewRemoteCharacteristic->getUUID().toString(), pNewRemoteCharacteristic)); + m_characteristicMapByHandle.insert(std::pair(result.char_handle, pNewRemoteCharacteristic)); + offset++; // Increment our count of number of descriptors found. + } // Loop forever (until we break inside the loop). + + m_haveCharacteristics = true; // Remember that we have received the characteristics. + log_v("<< getCharacteristics()"); } // getCharacteristics @@ -217,16 +217,16 @@ void BLERemoteService::retrieveCharacteristics() { * @brief Retrieve a map of all the characteristics of this service. * @return A map of all the characteristics of this service. */ -std::map* BLERemoteService::getCharacteristics() { - 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(); - } - log_v("<< getCharacteristics() for service: %s", getUUID().toString().c_str()); - return &m_characteristicMap; +std::map* BLERemoteService::getCharacteristics() { + 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(); + } + log_v("<< getCharacteristics() for service: %s", getUUID().toString().c_str()); + return &m_characteristicMap; } // getCharacteristics /** @@ -234,29 +234,29 @@ std::map* BLERemoteService::getCharacteri * @return A map of all the characteristics of this service. */ std::map* 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; + // 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** pCharacteristicMap) { - log_v(">> getCharacteristics() for service: %s", getUUID().toString().c_str()); - (void)pCharacteristicMap; - // 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(); - } - log_v("<< getCharacteristics() for service: %s", getUUID().toString().c_str()); - *pCharacteristicMap = &m_characteristicMapByHandle; + log_v(">> getCharacteristics() for service: %s", getUUID().toString().c_str()); + (void)pCharacteristicMap; + // 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(); + } + log_v("<< getCharacteristics() for service: %s", getUUID().toString().c_str()); + *pCharacteristicMap = &m_characteristicMapByHandle; } // Get the characteristics map. /** @@ -264,44 +264,44 @@ void BLERemoteService::getCharacteristics(std::map> getHandle: service: %s", getUUID().toString().c_str()); - log_v("<< getHandle: %d 0x%.2x", getStartHandle(), getStartHandle()); - return getStartHandle(); + log_v(">> getHandle: service: %s", getUUID().toString().c_str()); + log_v("<< getHandle: %d 0x%.2x", getStartHandle(), getStartHandle()); + return getStartHandle(); } // getHandle BLEUUID BLERemoteService::getUUID() { - return m_uuid; + return m_uuid; } /** * @brief Read the value of a characteristic associated with this service. */ -std::string BLERemoteService::getValue(BLEUUID characteristicUuid) { - log_v(">> readValue: uuid: %s", characteristicUuid.toString().c_str()); - std::string ret = getCharacteristic(characteristicUuid)->readValue(); - log_v("<< readValue"); - return ret; +String BLERemoteService::getValue(BLEUUID characteristicUuid) { + log_v(">> readValue: uuid: %s", characteristicUuid.toString().c_str()); + String ret = getCharacteristic(characteristicUuid)->readValue(); + log_v("<< readValue"); + return ret; } // readValue @@ -314,12 +314,12 @@ std::string BLERemoteService::getValue(BLEUUID characteristicUuid) { * @return N/A. */ void BLERemoteService::removeCharacteristics() { - m_characteristicMap.clear(); // Clear the map - for (auto &myPair : m_characteristicMapByHandle) { - delete myPair.second; - // delete the characteristics only once - } - m_characteristicMapByHandle.clear(); // Clear the map + m_characteristicMap.clear(); // Clear the map + for (auto &myPair : m_characteristicMapByHandle) { + delete myPair.second; + // delete the characteristics only once + } + m_characteristicMapByHandle.clear(); // Clear the map } // removeCharacteristics @@ -329,10 +329,10 @@ void BLERemoteService::removeCharacteristics() { * @param [in] value The value to set. * @throws BLEUuidNotFound */ -void BLERemoteService::setValue(BLEUUID characteristicUuid, std::string value) { - log_v(">> setValue: uuid: %s", characteristicUuid.toString().c_str()); - getCharacteristic(characteristicUuid)->writeValue(value); - log_v("<< setValue"); +void BLERemoteService::setValue(BLEUUID characteristicUuid, String value) { + log_v(">> setValue: uuid: %s", characteristicUuid.toString().c_str()); + getCharacteristic(characteristicUuid)->writeValue(value); + log_v("<< setValue"); } // setValue @@ -340,26 +340,26 @@ void BLERemoteService::setValue(BLEUUID characteristicUuid, std::string value) { * @brief Create a string representation of this remote service. * @return A string representation of this remote service. */ -std::string BLERemoteService::toString() { - 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) { - res += "\n" + myPair.second->toString(); - // myPair.second is the value - } - return res; +String BLERemoteService::toString() { + 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) { + res += "\n" + myPair.second->toString(); + // myPair.second is the value + } + return res; } // toString diff --git a/libraries/BLE/src/BLERemoteService.h b/libraries/BLE/src/BLERemoteService.h index d9034ef6053..6907260ea31 100644 --- a/libraries/BLE/src/BLERemoteService.h +++ b/libraries/BLE/src/BLERemoteService.h @@ -35,16 +35,16 @@ class BLERemoteService { BLERemoteCharacteristic* getCharacteristic(const char* uuid); // Get the specified characteristic reference. BLERemoteCharacteristic* getCharacteristic(BLEUUID uuid); // Get the specified characteristic reference. BLERemoteCharacteristic* getCharacteristic(uint16_t uuid); // Get the specified characteristic reference. - std::map* getCharacteristics(); + std::map* getCharacteristics(); std::map* getCharacteristicsByHandle(); // Get the characteristics map. void getCharacteristics(std::map** pCharacteristicMap); BLEClient* getClient(void); // Get a reference to the client associated with this service. uint16_t getHandle(); // Get the handle of this service. BLEUUID getUUID(void); // Get the UUID of this service. - std::string getValue(BLEUUID characteristicUuid); // Get the value of a characteristic. - void setValue(BLEUUID characteristicUuid, std::string value); // Set the value of a characteristic. - std::string toString(void); + String getValue(BLEUUID characteristicUuid); // Get the value of a characteristic. + void setValue(BLEUUID characteristicUuid, String value); // Set the value of a characteristic. + String toString(void); private: // Private constructor ... never meant to be created by a user application. @@ -70,7 +70,7 @@ class BLERemoteService { // Properties // We maintain a map of characteristics owned by this service keyed by a string representation of the UUID. - std::map m_characteristicMap; + std::map m_characteristicMap; // We maintain a map of characteristics owned by this service keyed by a handle. std::map m_characteristicMapByHandle; diff --git a/libraries/BLE/src/BLEScan.cpp b/libraries/BLE/src/BLEScan.cpp index 02286cfda70..87d0deb2e47 100644 --- a/libraries/BLE/src/BLEScan.cpp +++ b/libraries/BLE/src/BLEScan.cpp @@ -130,7 +130,7 @@ void BLEScan::handleGAPEvent( m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice); } if (!m_wantDuplicates && !found) { // if no callback and not want duplicate, and not already in vector, record it - m_scanResults.m_vectorAdvertisedDevices.insert(std::pair(advertisedAddress.toString(), advertisedDevice)); + m_scanResults.m_vectorAdvertisedDevices.insert(std::pair(advertisedAddress.toString(), advertisedDevice)); shouldDelete = false; } if (shouldDelete) { @@ -386,7 +386,7 @@ void BLEScan::setWindow(uint16_t windowMSecs) { bool BLEScan::start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue) { log_v(">> start(duration=%d)", duration); - m_semaphoreScanEnd.take(std::string("start")); + m_semaphoreScanEnd.take(String("start")); m_scanCompleteCB = scanCompleteCB; // Save the callback to be invoked when the scan completes. // if we are connecting to devices that are advertising even after being connected, multiconnecting peripherals diff --git a/libraries/BLE/src/BLEScan.h b/libraries/BLE/src/BLEScan.h index 606d41e6541..1e35586f7be 100644 --- a/libraries/BLE/src/BLEScan.h +++ b/libraries/BLE/src/BLEScan.h @@ -53,7 +53,7 @@ class BLEScanResults { private: friend BLEScan; - std::map m_vectorAdvertisedDevices; + std::map m_vectorAdvertisedDevices; }; /** diff --git a/libraries/BLE/src/BLEServer.h b/libraries/BLE/src/BLEServer.h index 0e31ff5ac4a..ef2d8f9af7e 100644 --- a/libraries/BLE/src/BLEServer.h +++ b/libraries/BLE/src/BLEServer.h @@ -47,7 +47,7 @@ class BLEServiceMap { void setByHandle(uint16_t handle, BLEService* service); void setByUUID(const char* uuid, BLEService* service); void setByUUID(BLEUUID uuid, BLEService* service); - std::string toString(); + String toString(); BLEService* getFirst(); BLEService* getNext(); void removeService(BLEService *service); @@ -55,8 +55,8 @@ class BLEServiceMap { private: std::map m_handleMap; - std::map m_uuidMap; - std::map::iterator m_iterator; + std::map m_uuidMap; + std::map::iterator m_iterator; }; diff --git a/libraries/BLE/src/BLEService.cpp b/libraries/BLE/src/BLEService.cpp index c40a5059c9e..554db974ca8 100644 --- a/libraries/BLE/src/BLEService.cpp +++ b/libraries/BLE/src/BLEService.cpp @@ -383,8 +383,8 @@ BLECharacteristic* BLEService::getCharacteristic(BLEUUID uuid) { * * Its handle * @return A string representation of this service. */ -std::string BLEService::toString() { - std::string res = "UUID: " + getUUID().toString(); +String BLEService::toString() { + String res = "UUID: " + getUUID().toString(); char hex[5]; snprintf(hex, sizeof(hex), "%04x", getHandle()); res += ", handle: 0x"; diff --git a/libraries/BLE/src/BLEService.h b/libraries/BLE/src/BLEService.h index 4c479343c9a..2d8a03b1fba 100644 --- a/libraries/BLE/src/BLEService.h +++ b/libraries/BLE/src/BLEService.h @@ -35,13 +35,13 @@ class BLECharacteristicMap { BLECharacteristic* getByHandle(uint16_t handle); BLECharacteristic* getFirst(); BLECharacteristic* getNext(); - std::string toString(); + String toString(); void handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param); private: - std::map m_uuidMap; + std::map m_uuidMap; std::map m_handleMap; - std::map::iterator m_iterator; + std::map::iterator m_iterator; }; @@ -63,7 +63,7 @@ class BLEService { BLEServer* getServer(); void start(); void stop(); - std::string toString(); + String toString(); uint16_t getHandle(); uint8_t m_instId = 0; diff --git a/libraries/BLE/src/BLEServiceMap.cpp b/libraries/BLE/src/BLEServiceMap.cpp index c70b567fe2c..eab54cf08bf 100644 --- a/libraries/BLE/src/BLEServiceMap.cpp +++ b/libraries/BLE/src/BLEServiceMap.cpp @@ -56,7 +56,7 @@ BLEService* BLEServiceMap::getByHandle(uint16_t handle) { * @return N/A. */ void BLEServiceMap::setByUUID(BLEUUID uuid, BLEService* service) { - m_uuidMap.insert(std::pair(service, uuid.toString())); + m_uuidMap.insert(std::pair(service, uuid.toString())); } // setByUUID @@ -75,8 +75,8 @@ void BLEServiceMap::setByHandle(uint16_t handle, BLEService* service) { * @brief Return a string representation of the service map. * @return A string representation of the service map. */ -std::string BLEServiceMap::toString() { - std::string res; +String BLEServiceMap::toString() { + String res; char hex[5]; for (auto &myPair: m_handleMap) { res += "handle: 0x"; diff --git a/libraries/BLE/src/BLEUUID.cpp b/libraries/BLE/src/BLEUUID.cpp index d91a5eae094..d34537203ed 100644 --- a/libraries/BLE/src/BLEUUID.cpp +++ b/libraries/BLE/src/BLEUUID.cpp @@ -66,7 +66,8 @@ static void memrcpy(uint8_t* target, uint8_t* source, uint32_t size) { * * @param [in] value The string to build a UUID from. */ -BLEUUID::BLEUUID(std::string value) { +BLEUUID::BLEUUID(String value) { + //Serial.printf("BLEUUID constructor from String=\"%s\"\n", value.c_str()); m_valueSet = true; if (value.length() == 4) { m_uuid.len = ESP_UUID_LEN_16; @@ -94,11 +95,12 @@ BLEUUID::BLEUUID(std::string value) { i+=2; } } - else if (value.length() == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be investigated (lack of time) + else if (value.length() == 16) { // How we can have 16 byte length string representing 128 bit uuid??? needs to be investigated (lack of time) - maybe raw data encoded as String (128b==16B)? m_uuid.len = ESP_UUID_LEN_128; - memrcpy(m_uuid.uuid.uuid128, (uint8_t*)value.data(), 16); + memrcpy(m_uuid.uuid.uuid128, (uint8_t*)value.c_str(), 16); } else if (value.length() == 36) { + //log_d("36 characters:"); // If the length of the string is 36 bytes then we will assume it is a long hex string in // UUID format. m_uuid.len = ESP_UUID_LEN_128; @@ -119,8 +121,13 @@ BLEUUID::BLEUUID(std::string value) { log_e("ERROR: UUID value not 2, 4, 16 or 36 bytes"); m_valueSet = false; } -} //BLEUUID(std::string) +} //BLEUUID(String) +/* +BLEUUID::BLEUUID(String value) { + this.BLEUUID(String(value.c_str(), value.length())); +} //BLEUUID(String) +*/ /** * @brief Create a UUID from 16 bytes of memory. @@ -248,7 +255,7 @@ bool BLEUUID::equals(BLEUUID uuid) { * NNNNNNNN * */ -BLEUUID BLEUUID::fromString(std::string _uuid) { +BLEUUID BLEUUID::fromString(String _uuid) { uint8_t start = 0; if (strstr(_uuid.c_str(), "0x") != nullptr) { // If the string starts with 0x, skip those characters. start = 2; @@ -256,10 +263,10 @@ BLEUUID BLEUUID::fromString(std::string _uuid) { uint8_t len = _uuid.length() - start; // Calculate the length of the string we are going to use. if(len == 4) { - uint16_t x = strtoul(_uuid.substr(start, len).c_str(), NULL, 16); + uint16_t x = strtoul(_uuid.substring(start, start+len).c_str(), NULL, 16); return BLEUUID(x); } else if (len == 8) { - uint32_t x = strtoul(_uuid.substr(start, len).c_str(), NULL, 16); + uint32_t x = strtoul(_uuid.substring(start, start+len).c_str(), NULL, 16); return BLEUUID(x); } else if (len == 36) { return BLEUUID(_uuid); @@ -350,20 +357,20 @@ BLEUUID BLEUUID::to128() { * * @return A string representation of the UUID. */ -std::string BLEUUID::toString() { +String BLEUUID::toString() { if (!m_valueSet) return ""; // If we have no value, nothing to format. // If the UUIDs are 16 or 32 bit, pad correctly. if (m_uuid.len == ESP_UUID_LEN_16) { // If the UUID is 16bit, pad correctly. char hex[9]; snprintf(hex, sizeof(hex), "%08x", m_uuid.uuid.uuid16); - return std::string(hex) + "-0000-1000-8000-00805f9b34fb"; + return String(hex) + "-0000-1000-8000-00805f9b34fb"; } // End 16bit UUID if (m_uuid.len == ESP_UUID_LEN_32) { // If the UUID is 32bit, pad correctly. char hex[9]; snprintf(hex, sizeof(hex), "%08lx", m_uuid.uuid.uuid32); - return std::string(hex) + "-0000-1000-8000-00805f9b34fb"; + return String(hex) + "-0000-1000-8000-00805f9b34fb"; } // End 32bit UUID // The UUID is not 16bit or 32bit which means that it is 128bit. @@ -381,7 +388,7 @@ std::string BLEUUID::toString() { 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); + String res(hex); free(hex); return res; } // toString diff --git a/libraries/BLE/src/BLEUUID.h b/libraries/BLE/src/BLEUUID.h index ba05c3f2a4e..7101f0e0fa2 100644 --- a/libraries/BLE/src/BLEUUID.h +++ b/libraries/BLE/src/BLEUUID.h @@ -8,10 +8,10 @@ #ifndef COMPONENTS_CPP_UTILS_BLEUUID_H_ #define COMPONENTS_CPP_UTILS_BLEUUID_H_ #include "soc/soc_caps.h" +#include "WString.h" #if SOC_BLE_SUPPORTED #include "sdkconfig.h" -#include #if CONFIG_BLUEDROID_ENABLED #include @@ -20,23 +20,23 @@ */ class BLEUUID { public: - BLEUUID(std::string uuid); - BLEUUID(uint16_t uuid); - BLEUUID(uint32_t uuid); - BLEUUID(esp_bt_uuid_t uuid); - BLEUUID(uint8_t* pData, size_t size, bool msbFirst); - BLEUUID(esp_gatt_id_t gattId); - BLEUUID(); - uint8_t bitSize(); // Get the number of bits in this uuid. - bool equals(BLEUUID uuid); - esp_bt_uuid_t* getNative(); - BLEUUID to128(); - std::string toString(); - static BLEUUID fromString(std::string uuid); // Create a BLEUUID from a string + BLEUUID(String uuid); + BLEUUID(uint16_t uuid); + BLEUUID(uint32_t uuid); + BLEUUID(esp_bt_uuid_t uuid); + BLEUUID(uint8_t* pData, size_t size, bool msbFirst); + BLEUUID(esp_gatt_id_t gattId); + BLEUUID(); + uint8_t bitSize(); // Get the number of bits in this uuid. + bool equals(BLEUUID uuid); + esp_bt_uuid_t* getNative(); + BLEUUID to128(); + String toString(); + static BLEUUID fromString(String uuid); // Create a BLEUUID from a string private: - esp_bt_uuid_t m_uuid; // The underlying UUID structure that this class wraps. - bool m_valueSet = false; // Is there a value set for this instance. + esp_bt_uuid_t m_uuid; // The underlying UUID structure that this class wraps. + bool m_valueSet = false; // Is there a value set for this instance. }; // BLEUUID #endif /* CONFIG_BLUEDROID_ENABLED */ diff --git a/libraries/BLE/src/BLEUtils.cpp b/libraries/BLE/src/BLEUtils.cpp index efa2d4ee08e..c226a13e663 100644 --- a/libraries/BLE/src/BLEUtils.cpp +++ b/libraries/BLE/src/BLEUtils.cpp @@ -28,11 +28,6 @@ #include "esp32-hal-log.h" -/* -static std::map g_addressMap; -static std::map g_connIdMap; -*/ - typedef struct { uint32_t assignedNumber; const char* name; @@ -606,8 +601,8 @@ static const gattService_t g_gattServices[] = { * @param [in] prop Characteristic properties. * @return A string representation of characteristic properties. */ -std::string BLEUtils::characteristicPropertiesToString(esp_gatt_char_prop_t prop) { - std::string res = "broadcast: "; +String BLEUtils::characteristicPropertiesToString(esp_gatt_char_prop_t prop) { + 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"); @@ -627,8 +622,8 @@ std::string BLEUtils::characteristicPropertiesToString(esp_gatt_char_prop_t prop /** * @brief Convert an esp_gatt_id_t to a string. */ -static std::string gattIdToString(esp_gatt_id_t gattId) { - std::string res = "uuid: " + BLEUUID(gattId.uuid).toString() + ", inst_id: "; +static String gattIdToString(esp_gatt_id_t gattId) { + String res = "uuid: " + BLEUUID(gattId.uuid).toString() + ", inst_id: "; char val[8]; snprintf(val, sizeof(val), "%d", (int)gattId.inst_id); res += val; @@ -660,10 +655,10 @@ const char* BLEUtils::addressTypeToString(esp_ble_addr_type_t type) { /** * @brief Convert the BLE Advertising Data flags to a string. * @param adFlags The flags to convert - * @return std::string A string representation of the advertising flags. + * @return String A string representation of the advertising flags. */ -std::string BLEUtils::adFlagsToString(uint8_t adFlags) { - std::string res; +String BLEUtils::adFlagsToString(uint8_t adFlags) { + String res; if (adFlags & (1 << 0)) { res += "[LE Limited Discoverable Mode] "; } @@ -810,8 +805,8 @@ char* BLEUtils::buildHexData(uint8_t* target, uint8_t* source, uint8_t length) { * @param [in] length Length of memory. * @return A string representation of a piece of memory. */ -std::string BLEUtils::buildPrintData(uint8_t* source, size_t length) { - std::string res; +String BLEUtils::buildPrintData(uint8_t* source, size_t length) { + String res; for (int i = 0; i < length; i++) { char c = *source; res += (isprint(c) ? c : '.'); @@ -826,7 +821,7 @@ std::string BLEUtils::buildPrintData(uint8_t* source, size_t length) { * @param [in] reason The close reason. * @return A string representation of the reason. */ -std::string BLEUtils::gattCloseReasonToString(esp_gatt_conn_reason_t reason) { +String BLEUtils::gattCloseReasonToString(esp_gatt_conn_reason_t reason) { switch (reason) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG case ESP_GATT_CONN_UNKNOWN: { @@ -864,7 +859,7 @@ std::string BLEUtils::gattCloseReasonToString(esp_gatt_conn_reason_t reason) { } // gattCloseReasonToString -std::string BLEUtils::gattClientEventTypeToString(esp_gattc_cb_event_t eventType) { +String BLEUtils::gattClientEventTypeToString(esp_gattc_cb_event_t eventType) { switch (eventType) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG case ESP_GATTC_ACL_EVT: @@ -962,7 +957,7 @@ std::string BLEUtils::gattClientEventTypeToString(esp_gattc_cb_event_t eventType * @param [in] eventType A GATT server event code. * @return A string representation of the GATT server event code. */ -std::string BLEUtils::gattServerEventTypeToString(esp_gatts_cb_event_t eventType) { +String BLEUtils::gattServerEventTypeToString(esp_gatts_cb_event_t eventType) { switch (eventType) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG case ESP_GATTS_REG_EVT: @@ -1344,7 +1339,7 @@ void BLEUtils::dumpGattClientEvent( // If the status of the event shows that we have a value other than ESP_GATT_OK then the // characteristic fields are not set to a usable value .. so don't try and log them. if (evtParam->get_char.status == ESP_GATT_OK) { - std::string description = "Unknown"; + String description = "Unknown"; if (evtParam->get_char.char_id.uuid.len == ESP_UUID_LEN_16) { description = BLEUtils::gattCharacteristicUUIDToString(evtParam->get_char.char_id.uuid.uuid.uuid16); } @@ -1617,6 +1612,7 @@ void BLEUtils::dumpGattServerEvent( // - uint32_t trans_id // - esp_bd_addr_t bda // - uint8_t exec_write_flag +#ifdef ARDUHAL_LOG_LEVEL_VERBOSE case ESP_GATTS_EXEC_WRITE_EVT: { char* pWriteFlagText; switch (evtParam->exec_write.exec_write_flag) { @@ -1643,7 +1639,7 @@ void BLEUtils::dumpGattServerEvent( pWriteFlagText); break; } // ESP_GATTS_DISCONNECT_EVT - +#endif case ESP_GATTS_MTU_EVT: { log_v("[conn_id: %d, mtu: %d]", @@ -1823,11 +1819,11 @@ const char* BLEUtils::gapEventToString(uint32_t eventType) { } // gapEventToString -std::string BLEUtils::gattCharacteristicUUIDToString(uint32_t characteristicUUID) { +String BLEUtils::gattCharacteristicUUIDToString(uint32_t characteristicUUID) { const characteristicMap_t* p = g_characteristicsMappings; while (strlen(p->name) > 0) { if (p->assignedNumber == characteristicUUID) { - return std::string(p->name); + return String(p->name); } p++; } @@ -1840,11 +1836,11 @@ std::string BLEUtils::gattCharacteristicUUIDToString(uint32_t characteristicUUID * @param [in] descriptorUUID UUID of the descriptor to be returned as a string. * @return The string representation of a descriptor UUID. */ -std::string BLEUtils::gattDescriptorUUIDToString(uint32_t descriptorUUID) { +String BLEUtils::gattDescriptorUUIDToString(uint32_t descriptorUUID) { gattdescriptor_t* p = (gattdescriptor_t*) g_descriptor_ids; while (strlen(p->name) > 0) { if (p->assignedNumber == descriptorUUID) { - return std::string(p->name); + return String(p->name); } p++; } @@ -1856,8 +1852,8 @@ std::string BLEUtils::gattDescriptorUUIDToString(uint32_t descriptorUUID) { * @brief Return a string representation of an esp_gattc_service_elem_t. * @return A string representation of an esp_gattc_service_elem_t. */ -std::string BLEUtils::gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement) { - std::string res; +String BLEUtils::gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement) { + String res; char val[6]; res += "[uuid: " + BLEUUID(pGATTCServiceElement->uuid).toString() + ", start_handle: "; snprintf(val, sizeof(val), "%d", pGATTCServiceElement->start_handle); @@ -1879,16 +1875,16 @@ std::string BLEUtils::gattcServiceElementToString(esp_gattc_service_elem_t* pGAT /** * @brief Convert an esp_gatt_srvc_id_t to a string. */ -std::string BLEUtils::gattServiceIdToString(esp_gatt_srvc_id_t srvcId) { +String BLEUtils::gattServiceIdToString(esp_gatt_srvc_id_t srvcId) { return gattIdToString(srvcId.id); } // gattServiceIdToString -std::string BLEUtils::gattServiceToString(uint32_t serviceId) { +String BLEUtils::gattServiceToString(uint32_t serviceId) { gattService_t* p = (gattService_t*) g_gattServices; while (strlen(p->name) > 0) { if (p->assignedNumber == serviceId) { - return std::string(p->name); + return String(p->name); } p++; } @@ -1902,7 +1898,7 @@ std::string BLEUtils::gattServiceToString(uint32_t serviceId) { * @param [in] status The status to convert. * @return A string representation of the status. */ -std::string BLEUtils::gattStatusToString(esp_gatt_status_t status) { +String BLEUtils::gattStatusToString(esp_gatt_status_t status) { switch (status) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG case ESP_GATT_OK: @@ -1999,12 +1995,12 @@ std::string BLEUtils::gattStatusToString(esp_gatt_status_t status) { -std::string BLEUtils::getMember(uint32_t memberId) { +String BLEUtils::getMember(uint32_t memberId) { member_t* p = (member_t*) members_ids; while (strlen(p->name) > 0) { if (p->assignedNumber == memberId) { - return std::string(p->name); + return String(p->name); } p++; } diff --git a/libraries/BLE/src/BLEUtils.h b/libraries/BLE/src/BLEUtils.h index a141fbfe903..d0ec8348130 100644 --- a/libraries/BLE/src/BLEUtils.h +++ b/libraries/BLE/src/BLEUtils.h @@ -24,11 +24,11 @@ class BLEUtils { public: static const char* addressTypeToString(esp_ble_addr_type_t type); - static std::string adFlagsToString(uint8_t adFlags); + static String adFlagsToString(uint8_t adFlags); static const char* advTypeToString(uint8_t advType); static char* buildHexData(uint8_t* target, uint8_t* source, uint8_t length); - static std::string buildPrintData(uint8_t* source, size_t length); - static std::string characteristicPropertiesToString(esp_gatt_char_prop_t prop); + static String buildPrintData(uint8_t* source, size_t length); + static String characteristicPropertiesToString(esp_gatt_char_prop_t prop); static const char* devTypeToString(esp_bt_dev_type_t type); static esp_gatt_id_t buildGattId(esp_bt_uuid_t uuid, uint8_t inst_id = 0); static esp_gatt_srvc_id_t buildGattSrvcId(esp_gatt_id_t gattId, bool is_primary = true); @@ -47,16 +47,16 @@ class BLEUtils { static BLEClient* findByAddress(BLEAddress address); static BLEClient* findByConnId(uint16_t conn_id); static const char* gapEventToString(uint32_t eventType); - static std::string gattCharacteristicUUIDToString(uint32_t characteristicUUID); - static std::string gattClientEventTypeToString(esp_gattc_cb_event_t eventType); - static std::string gattCloseReasonToString(esp_gatt_conn_reason_t reason); - static std::string gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement); - static std::string gattDescriptorUUIDToString(uint32_t descriptorUUID); - static std::string gattServerEventTypeToString(esp_gatts_cb_event_t eventType); - static std::string gattServiceIdToString(esp_gatt_srvc_id_t srvcId); - static std::string gattServiceToString(uint32_t serviceId); - static std::string gattStatusToString(esp_gatt_status_t status); - static std::string getMember(uint32_t memberId); + static String gattCharacteristicUUIDToString(uint32_t characteristicUUID); + static String gattClientEventTypeToString(esp_gattc_cb_event_t eventType); + static String gattCloseReasonToString(esp_gatt_conn_reason_t reason); + static String gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement); + static String gattDescriptorUUIDToString(uint32_t descriptorUUID); + static String gattServerEventTypeToString(esp_gatts_cb_event_t eventType); + static String gattServiceIdToString(esp_gatt_srvc_id_t srvcId); + static String gattServiceToString(uint32_t serviceId); + static String gattStatusToString(esp_gatt_status_t status); + static String getMember(uint32_t memberId); static void registerByAddress(BLEAddress address, BLEClient* pDevice); static void registerByConnId(uint16_t conn_id, BLEClient* pDevice); static const char* searchEventTypeToString(esp_gap_search_evt_t searchEvt); diff --git a/libraries/BLE/src/BLEValue.cpp b/libraries/BLE/src/BLEValue.cpp index 8554753fe4b..e67bba4d18e 100644 --- a/libraries/BLE/src/BLEValue.cpp +++ b/libraries/BLE/src/BLEValue.cpp @@ -24,7 +24,7 @@ BLEValue::BLEValue() { * The accumulation is a growing set of data that is added to until a commit or cancel. * @param [in] part A message part being added. */ -void BLEValue::addPart(std::string part) { +void BLEValue::addPart(String part) { log_v(">> addPart: length=%d", part.length()); m_accumulation += part; } // addPart @@ -38,7 +38,7 @@ void BLEValue::addPart(std::string part) { */ void BLEValue::addPart(uint8_t* pData, size_t length) { log_v(">> addPart: length=%d", length); - m_accumulation += std::string((char*) pData, length); + m_accumulation += String((char*) pData, length); } // addPart @@ -73,7 +73,7 @@ void BLEValue::commit() { * @return A pointer to the data. */ uint8_t* BLEValue::getData() { - return (uint8_t*) m_value.data(); + return (uint8_t*) m_value.c_str(); } @@ -98,7 +98,7 @@ uint16_t BLEValue::getReadOffset() { /** * @brief Get the current value. */ -std::string BLEValue::getValue() { +String BLEValue::getValue() { return m_value; } // getValue @@ -115,7 +115,7 @@ void BLEValue::setReadOffset(uint16_t readOffset) { /** * @brief Set the current value. */ -void BLEValue::setValue(std::string value) { +void BLEValue::setValue(String value) { m_value = value; } // setValue @@ -126,7 +126,7 @@ void BLEValue::setValue(std::string value) { * @param [in] The length of the new current value. */ void BLEValue::setValue(uint8_t* pData, size_t length) { - m_value = std::string((char*) pData, length); + m_value = String((char*) pData, length); } // setValue diff --git a/libraries/BLE/src/BLEValue.h b/libraries/BLE/src/BLEValue.h index 745899e8b32..0740a6999c2 100644 --- a/libraries/BLE/src/BLEValue.h +++ b/libraries/BLE/src/BLEValue.h @@ -8,34 +8,34 @@ #ifndef COMPONENTS_CPP_UTILS_BLEVALUE_H_ #define COMPONENTS_CPP_UTILS_BLEVALUE_H_ #include "soc/soc_caps.h" +#include "WString.h" #if SOC_BLE_SUPPORTED #include "sdkconfig.h" #if defined(CONFIG_BLUEDROID_ENABLED) -#include /** * @brief The model of a %BLE value. */ class BLEValue { public: - BLEValue(); - void addPart(std::string part); - void addPart(uint8_t* pData, size_t length); - void cancel(); - void commit(); - uint8_t* getData(); - size_t getLength(); - uint16_t getReadOffset(); - std::string getValue(); - void setReadOffset(uint16_t readOffset); - void setValue(std::string value); - void setValue(uint8_t* pData, size_t length); + BLEValue(); + void addPart(String part); + void addPart(uint8_t* pData, size_t length); + void cancel(); + void commit(); + uint8_t* getData(); + size_t getLength(); + uint16_t getReadOffset(); + String getValue(); + void setReadOffset(uint16_t readOffset); + void setValue(String value); + void setValue(uint8_t* pData, size_t length); private: - std::string m_accumulation; - uint16_t m_readOffset; - std::string m_value; + String m_accumulation; + uint16_t m_readOffset; + String m_value; }; #endif /* CONFIG_BLUEDROID_ENABLED */ diff --git a/libraries/BLE/src/FreeRTOS.cpp b/libraries/BLE/src/FreeRTOS.cpp index bab471dc44a..69417275dc4 100644 --- a/libraries/BLE/src/FreeRTOS.cpp +++ b/libraries/BLE/src/FreeRTOS.cpp @@ -30,8 +30,8 @@ void FreeRTOS::sleep(uint32_t ms) { * @param[in] param An optional parameter to be passed to the started task. * @param[in] stackSize An optional paremeter supplying the size of the stack in which to run the task. */ -void FreeRTOS::startTask(void task(void*), std::string taskName, void* param, uint32_t stackSize) { - ::xTaskCreate(task, taskName.data(), stackSize, param, 5, NULL); +void FreeRTOS::startTask(void task(void*), String taskName, void* param, uint32_t stackSize) { + ::xTaskCreate(task, taskName.c_str(), stackSize, param, 5, NULL); } // startTask @@ -59,7 +59,7 @@ uint32_t FreeRTOS::getTimeSinceStart() { * @param [in] owner A debug tag. * @return The value associated with the semaphore. */ -uint32_t FreeRTOS::Semaphore::wait(std::string owner) { +uint32_t FreeRTOS::Semaphore::wait(String owner) { log_v(">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); if (m_usePthreads) { @@ -85,7 +85,7 @@ uint32_t FreeRTOS::Semaphore::wait(std::string owner) { * @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) { +bool FreeRTOS::Semaphore::timedWait(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) { @@ -111,7 +111,7 @@ bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) { } // wait -FreeRTOS::Semaphore::Semaphore(std::string name) { +FreeRTOS::Semaphore::Semaphore(String name) { m_usePthreads = false; // Are we using pThreads or FreeRTOS? if (m_usePthreads) { pthread_mutex_init(&m_pthread_mutex, nullptr); @@ -121,7 +121,7 @@ FreeRTOS::Semaphore::Semaphore(std::string name) { } m_name = name; - m_owner = std::string(""); + m_owner = String(""); m_value = 0; } @@ -141,7 +141,7 @@ FreeRTOS::Semaphore::~Semaphore() { */ void FreeRTOS::Semaphore::give() { log_v("Semaphore giving: %s", toString().c_str()); - m_owner = std::string(""); + m_owner = String(""); if (m_usePthreads) { pthread_mutex_unlock(&m_pthread_mutex); @@ -185,7 +185,7 @@ void FreeRTOS::Semaphore::giveFromISR() { * @param [in] owner The new owner (for debugging) * @return True if we took the semaphore. */ -bool FreeRTOS::Semaphore::take(std::string owner) { +bool FreeRTOS::Semaphore::take(String owner) { log_v("Semaphore taking: %s for %s", toString().c_str(), owner.c_str()); bool rc = false; if (m_usePthreads) { @@ -210,7 +210,7 @@ bool FreeRTOS::Semaphore::take(std::string owner) { * @param [in] owner The new owner (for debugging) * @return True if we took the semaphore. */ -bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) { +bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, String owner) { log_v("Semaphore taking: %s for %s", toString().c_str(), owner.c_str()); bool rc = false; if (m_usePthreads) { @@ -233,9 +233,9 @@ bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) { * @brief Create a string representation of the semaphore. * @return A string representation of the semaphore. */ -std::string FreeRTOS::Semaphore::toString() { +String FreeRTOS::Semaphore::toString() { char hex[9]; - std::string res = "name: " + m_name + " (0x"; + String res = "name: " + m_name + " (0x"; snprintf(hex, sizeof(hex), "%08lx", (uint32_t)m_semaphore); res += hex; res += "), owner: " + m_owner; @@ -247,7 +247,7 @@ std::string FreeRTOS::Semaphore::toString() { * @brief Set the name of the semaphore. * @param [in] name The name of the semaphore. */ -void FreeRTOS::Semaphore::setName(std::string name) { +void FreeRTOS::Semaphore::setName(String name) { m_name = name; } // setName diff --git a/libraries/BLE/src/GeneralUtils.cpp b/libraries/BLE/src/GeneralUtils.cpp index 8eef970faff..0c86bf40dd5 100644 --- a/libraries/BLE/src/GeneralUtils.cpp +++ b/libraries/BLE/src/GeneralUtils.cpp @@ -30,7 +30,7 @@ static int base64EncodedLength(size_t length) { } // base64EncodedLength -static int base64EncodedLength(const std::string& in) { +static int base64EncodedLength(const String& in) { return base64EncodedLength(in.length()); } // base64EncodedLength @@ -55,16 +55,17 @@ static void a4_to_a3(unsigned char* a3, unsigned char* a4) { * @param [in] in * @param [out] out */ -bool GeneralUtils::base64Encode(const std::string& in, std::string* out) { +bool GeneralUtils::base64Encode(const String& in, String* out) { + std::string std_in(in.c_str()); + std::string std_out(out->c_str()); int i = 0, j = 0; size_t enc_len = 0; unsigned char a3[3]; unsigned char a4[4]; + std_out.resize(base64EncodedLength(in)); - out->resize(base64EncodedLength(in)); - - int input_len = in.size(); - std::string::const_iterator input = in.begin(); + int input_len = std_in.length(); + std::string::const_iterator input = std_in.begin(); while (input_len--) { a3[i++] = *(input++); @@ -72,7 +73,7 @@ bool GeneralUtils::base64Encode(const std::string& in, std::string* out) { a3_to_a4(a4, a3); for (i = 0; i < 4; i++) { - (*out)[enc_len++] = kBase64Alphabet[a4[i]]; + (std_out)[enc_len++] = kBase64Alphabet[a4[i]]; } i = 0; @@ -87,15 +88,16 @@ bool GeneralUtils::base64Encode(const std::string& in, std::string* out) { a3_to_a4(a4, a3); for (j = 0; j < i + 1; j++) { - (*out)[enc_len++] = kBase64Alphabet[a4[j]]; + (std_out)[enc_len++] = kBase64Alphabet[a4[j]]; } while ((i++ < 3)) { - (*out)[enc_len++] = '='; + (std_out)[enc_len++] = '='; } } + *out = String(std_out.c_str()); - return (enc_len == out->size()); + return (enc_len == out->length()); } // base64Encode @@ -121,27 +123,28 @@ void GeneralUtils::dumpInfo() { * @param [in] c The character to look form. * @return True if the string ends with the given character. */ -bool GeneralUtils::endsWith(std::string str, char c) { - if (str.empty()) { +bool GeneralUtils::endsWith(String str, char c) { + if (str.length() == 0) { return false; } - if (str.at(str.length() - 1) == c) { + if (str.charAt(str.length() - 1) == c) { return true; } return false; } // endsWidth - -static int DecodedLength(const std::string& in) { +/* +static int DecodedLength(const String& in) { int numEq = 0; - int n = (int) in.size(); + int n = (int) in.length(); - for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { + //for (String::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { + for (int it = in.length()-1; in.charAt(it) == '='; --it) { ++numEq; } return ((6 * n) / 8) - numEq; } // DecodedLength - +*/ static unsigned char b64_lookup(unsigned char c) { if(c >='A' && c <='Z') return c - 'A'; @@ -158,23 +161,24 @@ static unsigned char b64_lookup(unsigned char c) { * @param [in] in The string to be decoded. * @param [out] out The resulting data. */ -bool GeneralUtils::base64Decode(const std::string& in, std::string* out) { +bool GeneralUtils::base64Decode(const String& in, String* out) { int i = 0, j = 0; size_t dec_len = 0; unsigned char a3[3]; unsigned char a4[4]; - int input_len = in.size(); - std::string::const_iterator input = in.begin(); + int input_len = in.length(); + int input_iterator = 0; - out->resize(DecodedLength(in)); + //out->resize(DecodedLength(in)); while (input_len--) { - if (*input == '=') { + //if (*input == '=') { + if (in[input_iterator] == '=') { break; } - a4[i++] = *(input++); + a4[i++] = in[input_iterator++]; if (i == 4) { for (i = 0; i <4; i++) { a4[i] = b64_lookup(a4[i]); @@ -183,7 +187,8 @@ bool GeneralUtils::base64Decode(const std::string& in, std::string* out) { a4_to_a3(a3,a4); for (i = 0; i < 3; i++) { - (*out)[dec_len++] = a3[i]; + out->concat(a3[i]); + dec_len++; } i = 0; @@ -206,14 +211,14 @@ bool GeneralUtils::base64Decode(const std::string& in, std::string* out) { } } - return (dec_len == out->size()); + return (dec_len == out->length()); } // base64Decode /* void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) { uint32_t index=0; - std::stringstream ascii; - std::stringstream hex; + Stringstream ascii; + Stringstream hex; char asciiBuf[80]; char hexBuf[80]; hex.str(""); @@ -251,8 +256,8 @@ void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) { /* void GeneralUtils::hexDump(uint8_t* pData, uint32_t length) { uint32_t index=0; - static std::stringstream ascii; - static std::stringstream hex; + static Stringstream ascii; + static Stringstream hex; hex.str(""); ascii.str(""); while(index < length) { @@ -331,11 +336,11 @@ void GeneralUtils::hexDump(const uint8_t* pData, uint32_t length) { * @param ip The 4 byte IP address. * @return A string representation of the IP address. */ -std::string GeneralUtils::ipToString(uint8_t *ip) { +String GeneralUtils::ipToString(uint8_t *ip) { 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); + String res(val); free(val); return res; } // ipToString @@ -347,17 +352,18 @@ std::string GeneralUtils::ipToString(uint8_t *ip) { * @param [in] delimiter The delimiter characters. * @return A vector of strings that are the split of the input. */ -std::vector GeneralUtils::split(std::string source, char delimiter) { +std::vector GeneralUtils::split(String source, char delimiter) { // See also: https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g - std::vector strings; + std::vector strings; std::size_t current, previous = 0; - current = source.find(delimiter); + std::string std_source(source.c_str()); + current = std_source.find(delimiter); while (current != std::string::npos) { - strings.push_back(trim(source.substr(previous, current - previous))); + strings.push_back(trim(source.substring(previous, current))); previous = current + 1; - current = source.find(delimiter, previous); + current = std_source.find(delimiter, previous); } - strings.push_back(trim(source.substr(previous, current - previous))); + strings.push_back(trim(source.substring(previous, current))); return strings; } // split @@ -523,9 +529,9 @@ const char* GeneralUtils::wifiErrorToString(uint8_t errCode) { * @param [in] value The string to convert to lower case. * @return A lower case representation of the string. */ -std::string GeneralUtils::toLower(std::string& value) { +String GeneralUtils::toLower(String& value) { // Question: Could this be improved with a signature of: - // std::string& GeneralUtils::toLower(std::string& value) + // String& GeneralUtils::toLower(String& value) std::transform(value.begin(), value.end(), value.begin(), ::tolower); return value; } // toLower @@ -534,9 +540,10 @@ std::string GeneralUtils::toLower(std::string& value) { /** * @brief Remove white space from a string. */ -std::string GeneralUtils::trim(const std::string& str) { - size_t first = str.find_first_not_of(' '); +String GeneralUtils::trim(const String& str) { + std::string std_str(str.c_str()); + size_t first = std_str.find_first_not_of(' '); if (std::string::npos == first) return str; - size_t last = str.find_last_not_of(' '); - return str.substr(first, (last - first + 1)); + size_t last = std_str.find_last_not_of(' '); + return str.substring(first, (last + 1)); } // trim diff --git a/libraries/BLE/src/GeneralUtils.h b/libraries/BLE/src/GeneralUtils.h index 8eecbd4d029..285261be1bc 100644 --- a/libraries/BLE/src/GeneralUtils.h +++ b/libraries/BLE/src/GeneralUtils.h @@ -7,6 +7,7 @@ #ifndef COMPONENTS_CPP_UTILS_GENERALUTILS_H_ #define COMPONENTS_CPP_UTILS_GENERALUTILS_H_ +#include "Arduino.h" #include #include #include @@ -18,17 +19,17 @@ */ class GeneralUtils { public: - static bool base64Decode(const std::string& in, std::string* out); - static bool base64Encode(const std::string& in, std::string* out); + static bool base64Decode(const String& in, String* out); + static bool base64Encode(const String& in, String* out); static void dumpInfo(); - static bool endsWith(std::string str, char c); + static bool endsWith(String str, char c); static const char* errorToString(esp_err_t errCode); static const char* wifiErrorToString(uint8_t value); static void hexDump(const uint8_t* pData, uint32_t length); - static std::string ipToString(uint8_t* ip); - static std::vector split(std::string source, char delimiter); - static std::string toLower(std::string& value); - static std::string trim(const std::string& str); + static String ipToString(uint8_t* ip); + static std::vector split(String source, char delimiter); + static String toLower(String& value); + static String trim(const String& str); }; diff --git a/libraries/BLE/src/RTOS.h b/libraries/BLE/src/RTOS.h index d2065a73d66..65362a94958 100644 --- a/libraries/BLE/src/RTOS.h +++ b/libraries/BLE/src/RTOS.h @@ -8,8 +8,8 @@ #ifdef __cplusplus #ifndef MAIN_FREERTOS_H_ #define MAIN_FREERTOS_H_ +#include "Arduino.h" #include -#include #include #include // Include the base FreeRTOS definitions. @@ -24,31 +24,31 @@ class FreeRTOS { public: static void sleep(uint32_t ms); - static void startTask(void task(void*), std::string taskName, void* param = nullptr, uint32_t stackSize = 2048); + static void startTask(void task(void*), String taskName, void* param = nullptr, uint32_t stackSize = 2048); static void deleteTask(TaskHandle_t pTask = nullptr); static uint32_t getTimeSinceStart(); class Semaphore { public: - Semaphore(std::string owner = ""); + Semaphore(String owner = ""); ~Semaphore(); void give(); void give(uint32_t value); void giveFromISR(); - void setName(std::string name); - bool take(std::string owner = ""); - bool take(uint32_t timeoutMs, std::string owner = ""); - std::string toString(); - uint32_t wait(std::string owner = ""); - bool timedWait(std::string owner = "", uint32_t timeoutMs = portMAX_DELAY); + void setName(String name); + bool take(String owner = ""); + bool take(uint32_t timeoutMs, String owner = ""); + String toString(); + uint32_t wait(String owner = ""); + bool timedWait(String owner = "", uint32_t timeoutMs = portMAX_DELAY); uint32_t value(){ return m_value; }; private: SemaphoreHandle_t m_semaphore; pthread_mutex_t m_pthread_mutex; - std::string m_name; - std::string m_owner; + String m_name; + String m_owner; uint32_t m_value; bool m_usePthreads;