Converting a uint8_t* to a bool

I'm transferring some data over bluetooth, and the data comes in as a byte array (uint_8*). How would I safely convert that to a single boolean value? I'm expecting a "1" or "0"; however, I want to make sure that it's not anything else.

I also get the array len as well. Thanks!

You won't covert the pointer but what it points to.

Why do you need an array to hold 0 or 1?

If you only have one element in the array, then just pretend that the one element in the array is a scalar variable.

I'm receiving a callback that takes as a parameter an array of unint_8 and a len. It's basically serialized data that should be a "1" or "0"; however, it's a generic pointer.

I guess I could just do a bitwise AND checking that len == 1 as well.

if (len == 1 && arr[0] & 1) {
   // means true
} else {
   // means false
}

czu001:

if (len == 1 && arr[0] & 1) {

// means true
} else {
  // means false
}

did that work???

if you need further help, please post your receiving and transmitting (if there is one) code so we can help you better

Note: if you are sending ASCII "0" or "1" it is not the number zero or one would will be receiving but the ASCII their representation. If it is a string that is being received, then is will also be terminated with the '\0' character.

It did not work. Here's the callback function that is coming in:

onCallback(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset);

I'm using the Adafruit nRF52840 Feather Express, and I'm receiving this callback as a value for the specific characteristic I'm writing. I'm using my iPhone to write a value to that characteristic (I can either send a HEX value or UTF-8 String).

When I send the "1" or "0" the len comes in as 1 (not 2). I was looking to see how ESP32 handles byte array data received, and they convert it to a std::string by casting it to a char*.

Perhaps it's easier to use the String object? From there, I should be able to use atoi, etc. At the cost of heap, but I think I'd be ok with that. I was hoping for a better way though.

String s = String((char*)data);

czu001:
It did not work. Here's the callback function that is coming in:

onCallback(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset);

I'm using the Adafruit nRF52840 Feather Express, and I'm receiving this callback as a value for the specific characteristic I'm writing. I'm using my iPhone to write a value to that characteristic (I can either send a HEX value or UTF-8 String).

When I send the "1" or "0" the len comes in as 1 (not 2). I was looking to see how ESP32 handles byte array data received, and they convert it to a std::string by casting it to a char*.

ESP32_BLE_Arduino/BLEValue.cpp at b232e7f5f0e87f36afbc2f4e03a2c49c48dd47bc · nkolban/ESP32_BLE_Arduino · GitHub
Perhaps it's easier to use the String object? From there, I should be able to use atoi, etc. At the cost of heap, but I think I'd be ok with that. I was hoping for a better way though.

String s = String((char*)data);

opps must be my browser coz we cannot see you CODE!

also when you are sending "0" or "1" as you say, what is your current output (try Serial.print it out if you don't have it already!) from your 'invisible' code?

if (len == 1 && arr[0] & 1) {
   // means true
} else {
   // means false
}

So, if the message is one byte long, and the value in the first element of the array is 1, that means true. And other length, or any other value, means false. I seriously doubt that.

Did you try printing the value in the 0th element of the array?

Post ALL of your code, so we can see EXACTLY what blunders you are making.

I ended up answering my own question, but here's my code for anyone else. The data coming in from the nRF52 Bluefruit API (and other BLE characteristic API's - ESP32 for instance) is an array of bytes. So, I simply cast each uint8_t as a char and put it into a buffer, add a null terminator to the end, and then operate on the buffer checking for expected data.

void BluetoothAdapter::_hibernate_characteristic_write_callback(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset) {
  // should not receive a longer value.. so ignore any data that comes in here
  // only expecting a "1"
  if (offset != 0) {
    LOG(LOG_TAG, "_hibernate_characteristic_write_callback() invalid offset [%d]", offset);
    return;
  }
  if (len != 1) {
    LOG(LOG_TAG, "_hibernate_characteristic_write_callback() invalid len [%d]", len);
    return;
  }

  char buffer[2];
  buffer[0] = (char)data[0];
  buffer[1] = 0;

  if (!Utils::isNumeric(buffer, strlen(buffer))) {
    LOG(LOG_TAG, "_hibernate_characteristic_write_callback() invalid len [%d]", len);
    return;
  }

  int value = atoi(buffer);
  if (value != 1) {
    LOG(LOG_TAG, "_hibernate_characteristic_write_callback() did not receive 1. Received: [%d]", value);
    return;
  }

  BluetoothAdapter::getInstance().onHibernateRequested();
}

I'm expecting a "1" for the Characteristic write value... anything else is ignored. I handle other callbacks in a similar fashion (expanding on the buffer as needed via the len parameter).

  int value = atoi(buffer);

You KNOW that buffer contains two characters, one of which is a NULL terminator. Do you REALLY need a variable that can hold a value in the range -32768 to 32767, to hold a value in the range 0 to 9?

Pissing away memory is never a good idea.

Your call to atoi is unnecessary. You already know, that your number is in data[0], so just do

uint8_t value = data[0] - '0';

Great points! Thanks so much for the help.