Arduino ESP32 how to assign BLEUUID object into string

0

Currently we are developing an android app that can advertise itself from the BLE(bluetooth low energy) to ESP32 devices. ESP32 collects the MAC address, device name, and service UUID and send the data to MySQL server. So far ESP32 can send the device name and MAC address but somehow, we have not able to send UUID data.

http://www.neilkolban.com/esp32/docs/cpp_utils/html/class_b_l_e_advertised_device.html

From the BLEadvertisedDevice library, some usefull information can be found. As far as I understand, getServiceUUID () returns a BlEUUID(http://www.neilkolban.com/esp32/docs/cpp_utils/html/class_b_l_e_u_u_i_d.html) object, and it has a toString method that takes the void argument(not the BLEadvertisedDevice object but BLEUUID object). My first question is why BLEadvertisedDevice does not take any arguments but BLEUUID takes void as a argument for the toString method. I tried to assign the object to string but no chance I tried these, whole code given below.

const char *dev_uuid;
dev_uuid = device.getServiceUUID().toString().c_str(); 

strcpy(dev_uuid, device.getServiceUUID().toString().c_str());

dev_uuid = device.getServiceUUID().toString();

strcpy(dev_uuid, device.getServiceUUID().toString();

Error logs are given below

This is the whole code

#include <WiFi.h>
#include <BLEDevice.h>
#include <BLEAdvertisedDevice.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

/*
  INSERT CREDENTIALS
*/

char ssid[] = "";    // your SSID
char pass[] = "";       // your SSID Password

IPAddress server_addr(192, 168, 1, xx); // IP of the MySQL *server* here
char user[] = "";              // MySQL user login username
char password[] = "";        // MySQL user login password

IPAddress local_IP(192, 168, 1, xx); // ESP 32 IP
IPAddress gateway(192, 168, 1, xx); // GATEWAY
IPAddress subnet(255, 255, 255, 0); // SUBNET
IPAddress primaryDNS(192, 168, 1, xx); // DNS

WiFiClient client;
MySQL_Connection conn((Client *)&client);

int LED_BUILTIN = 2;
int scanTime = 10;
int RSSI_data;
int device_count = 0;
char MAC_data[17];
char query[128];
const char *dev_name;
const char *uuid_string;

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
    }
};

char INSERT_DATA[] = "INSERT INTO yoklama.esp3_table (rssi, mac_address, device_name, dev_uuid) VALUES (%d,'%s','%s','%s')";

void setup()
{
  Serial.begin(115200);

  if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) {
    Serial.println("STA Failed to configure");
  }

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("ESP Mac Address: ");
  Serial.println(WiFi.macAddress());
  Serial.print("Subnet Mask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway IP: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("DNS: ");
  Serial.println(WiFi.dnsIP());
}

void loop()
{

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    WiFi.begin(ssid, pass);
    Serial.print("Trying to Connect");
  }

  if (conn.connect(server_addr, 3306, user, password)) {
    Serial.println("Connected to database!");
    delay(10000);
  }
  else
    Serial.println("Connection failed.");
  //conn.close();
  Serial.println("Scanning ...\n");
  BLEDevice::init("");
  BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
  BLEScanResults foundDevices = pBLEScan->start(scanTime);
  digitalWrite(LED_BUILTIN, LOW);
  device_count = foundDevices.getCount();
  Serial.printf("Cihaz sayısı: %d\n", device_count);

  Serial.print("Devices found: \n");  // THIS IS THE PART THE DATA IS SENT TO MYSQL
  for (uint32_t i = 0; i < device_count; i++)
  {
    digitalWrite(LED_BUILTIN, HIGH);
    BLEAdvertisedDevice device = foundDevices.getDevice(i);
    RSSI_data = device.getRSSI(); // CAN GET THE RSSI WITHOUT PROBLEM
    dev_name = device.getName().c_str(); // CAN GET THE DEV NAME WITHOUT PROBLEM
    strcpy( MAC_data, device.getAddress().toString().c_str()); // CAN GET THE MAC WITHOUT PROBLEM

    /* I NEED HELP TO GET THE UUID DATA SO FAR I TRIED THESE METHODS.

      dev_uuid = device.getServiceUUID().toString().c_str();
      strcpy(dev_uuid, device.getServiceUUID().toString().c_str());
      dev_uuid = device.getServiceUUID().toString();
      strcpy(dev_uuid, device.getServiceUUID().toString();

    */

    Serial.printf("MAC adres = %s --- ", MAC_data);
    Serial.printf("Device Name = '%s' --- ", dev_name);
    Serial.printf("RSSI =  %d --- ", RSSI_data);
    //Serial.printf("UUID %d\n", dev_uuid);


    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);

    sprintf(query, INSERT_DATA, RSSI_data, MAC_data, dev_name, dev_uuid);

    cur_mem->execute(query);
    delete cur_mem;
    delay(2000);

  }
  pBLEScan->clearResults();
  delay(300);

}

Error for the: dev_uuid = device.getServiceUUID().toString().c_str(); It compiles but from the serial monitor :

08:58:59.404 -> entry 0x400806a8
08:58:59.914 -> Connecting to 
08:59:00.421 -> .
08:59:00.421 -> WiFi connected!
08:59:00.421 -> IP address: 192.168.1.
08:59:00.421 -> ESP Mac Address: 80:7D:3A:99:82:D4
08:59:00.421 -> Subnet Mask: 255.255.255.0
08:59:00.421 -> Gateway IP: 192.168.1
08:59:00.421 -> DNS: 192.168.1
08:59:00.454 -> Connected to database!
08:59:10.459 -> Scanning...
08:59:10.459 -> 
08:59:21.115 -> Cihaz sayısı: 8
08:59:21.115 -> Devices found: 
08:59:21.115 -> Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
08:59:21.115 -> Core 1 register dump:
08:59:21.115 -> PC      : 0x4000c2e0  PS      : 0x00060430  A0      : 0x800d3160  A1      : 0x3ffcecb0  
08:59:21.115 -> A2      : 0x3ffced30  A3      : 0x00000000  A4      : 0x00000013  A5      : 0x3ffced30  
08:59:21.150 -> A6      : 0x00000000  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffcec70  
08:59:21.150 -> A10     : 0x00000000  A11     : 0x3ffced7c  A12     : 0x3ffced7c  A13     : 0x00000000  
08:59:21.150 -> A14     : 0x00000000  A15     : 0x5b0a0a20  SAR     : 0x0000001e  EXCCAUSE: 0x0000001c  
08:59:21.150 -> EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
08:59:21.185 -> 
08:59:21.185 -> Backtrace: 0x4000c2e0:0x3ffcecb0 0x400d315d:0x3ffcecc0 0x400d188a:0x3ffcece0 0x400d821d:0x3ffcee00 0x4008e095:0x3ffcee20
08:59:21.185 -> 
08:59:21.185 -> Rebooting...
08:59:21.185 -> ets Jun  8 2016 00:22:57

Error for the: strcpy(dev_uuid,device.getServiceUUID().toString().c_str());

C:\Users\...\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/newlib/string.h:30:15: note:   initializing argument 1 of 'char* strcpy(char*, const char*)'

 char  *_EXFUN(strcpy,(char *__restrict, const char *__restrict));

Error for the: strcpy(dev_uuid,device.getServiceUUID().toString());

invalid conversion from 'const char*' to 'char*' [-fpermissive]

Error for the: dev_uuid = device.getServiceUUID().toString());

cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' to 'const char*' in assignment
c++
arduino
bluetooth-lowenergy
esp32
asked on Stack Overflow Jul 8, 2019 by Emre Kiratli

2 Answers

1

In your code:

const char *dev_uuid;
dev_uuid = device.getServiceUUID().toString().c_str(); 

strcpy(dev_uuid, device.getServiceUUID().toString().c_str());

dev_uuid = device.getServiceUUID().toString();

strcpy(dev_uuid, device.getServiceUUID().toString();

Your strcpy() attempts cannot possibly work the way you wrote them. You have an uninitialized pointer (dev_uuid) and you're copying data into... wherever it happens to point to. This is why you're getting panics.

Use a String object, not a C string, instead:

String dev_uuid;

dev_uuid = device.getServiceUUID().toString();

There's a huge difference between the Arduino String class and C strings. Generally if you see a toString() method, it's the Arduino String class. Reading the documentation should make it clear that a method returns a String; if it does, you should assign the return value to a String.

C strings are much more difficult to work with. You're directly manipulating pointers to memory and the contents of memory. They always need one byte more for their null termination character than their length indicates. You need to make sure that there's memory allocated for them before you copy into them.

answered on Stack Overflow Jul 8, 2019 by romkey
0

Update on this.

dev_uuid = device.getServiceUUID().toString().c_str(); This is the correct method.

While getting the scan results if the advertiser device does not have an UUID set dev_uuid returns null and cannot print or anything. You can add .haveServiceUUID method to return a bool value and if it is true then you can get the UUID without problem. Otherwise if the advertiser device does not have an UUID set you get a problem which results in Guru Meditation Error: Core

if (advertisedDevice.haveServiceUUID ()) dev_uuid = advertisedDevice.toString().c_str();

answered on Stack Overflow Jul 11, 2019 by Emre Kiratli

User contributions licensed under CC BY-SA 3.0