nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.35k stars 710 forks source link

How to work with data in notify callback function for BLE Client #979

Open CarSanoja opened 4 years ago

CarSanoja commented 4 years ago

I am trying to access the data sent to me from the server every time the notification is lifted. However, it doesn't let me access through the feature class through the RedValue() function, any special reason why I can't do it?

The other option is to use the pData function variable, however, I will receive both integers and strings, how can I transform these data and save the received data?

_`static void notifyCallback_flag (BLERemoteCharacteristic pBLERemoteCharacteristic, uint8_t pData, sizet length, bool isNotify) {

ESP_LOGD(__func__, "Notify callback for characteristic ");

ESP_LOGD(__func__, "Characteristic UUID: %s", pBLERemoteCharacteristic->getUUID().toString().c_str());

ESP_LOGD(__func__, "Message arrived ");

std::string characteristic_uuid = pBLERemoteCharacteristic->getUUID().toString();

Serial.print("Data: ");

Serial.println(length);

// Print out the message that we received

for (int i = 0; i < length; i++)

  Serial.print((char)pData[i]);

Serial.println();

ESP_LOGD(__func__, "PRUEBAA cred_list_len value: ");

switch (BLEFlagOption(characteristic_uuid)){

  case opt:

  {

    ESP_LOGD(__func__, "Receiving FLAG credentials length");

    *cred_list_pointer = (int)pData;

    ESP_LOGD(__func__, "cred_list_len value: %d", pData);

    break;

  }
  default:
  {
    break;
  }  
}

}`

By (int)pData instead of receiving a 1, I'm getting a value of "1073617712"

It would be great to be able to extract the value directly from the class if possible instead of transforming the data if possible.

Thanks in advance.

CarSanoja commented 4 years ago

Just as update, I had to implement a function to get this value: ` int parse_notify( uint8_t *input, size_t size )

int i, val;

val = 0;

for (int i = 0 ; i < size; i++ )

    val = val * 10 + input[i];

return( val );

` It will be nice to know if exits any method embedded in the library to do the same

chegewara commented 4 years ago

By (int)pData instead of receiving a 1, I'm getting a value of "1073617712"

This is exactly what you should get. pData is a pointer, which means its memory address which is in this case 0x3FFE1B30. Try this int val = *(int*)pData; This will works only in case you are sending 4 bytes length integer value. Of course you can check length and parse pData accordingly.

CarSanoja commented 4 years ago

Thank you very much for your answer @chegewara . In case you send strings in the message, how could you get from the same variable to a new std::string variable?

I hope you can help me

chegewara commented 4 years ago

To play this game, programming, you have to think that every data is nothing more than bunch of bytes, except situation when you play with bits, but thats different story. When you have type of uint8_t * then you can cast it to any type you want, but that does not mean you will get always good result, you have o know that data you want to cast is really type of that you cast to. So, if you you know you have string in pData the you just cast to char* str = (char*)pData or if you want std:string then std::string myString(pData, length);.

CarSanoja commented 4 years ago

Thanks for your answer, I tried but it didn't work out well. However I implemented the following and it worked perfectly. std::string new_data( length, 0 ); for ( int i = 0; i < length; ++i ) new_data[ i ] = (char)pData[ i ]; Thanks again for the help

chegewara commented 4 years ago

Sorry, try this: std::string myString((char*)pData, length);