While cstring does not contain data.

Hi all,

I am trying to write a bit of code that has a while "this variable" or "this variable" does not contain data do "this". However I have not been able to write code to do this yet!

I thought this would work.....

  while (wifiSSID || wifiPassword == NULL) { //while not received

.....but it doesn't.

Any help would be awesome!

Thanks,

Zeb

Why does nobody ever Read this before posting a programming question.

Please please please copy and paste ALL of your code using code tags. There are things that I need to know that I cannot guess from your code snippet.

If these are truly c-strings then there is a way to get their length (strlen) and you probably want to know if the length is or is not zero.

Another way would be to simply check if the first char in the array is the null character.

Hi SteveMann and vaj4088,

I am really sorry for not posting all my code!

Here it is:

//https://github.com/Buffalchill/ESP32-BLE-Appinventor2

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

bool newData = false; //varaible for storing if there is new data
bool dataAvailable = false; //varaible for storing if there is data available

char receivedData[50]; //store received data

char *wifiSSID;
char *wifiPassword;

BLECharacteristic *pCharacteristic; //create object

bool deviceConnected = false; //variable for storing if BLE is connected

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

/* UUIDs */
#define SERVICE_UUID           "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"


class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    /* ON BLE DISCONNECTION */
    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

/* WHEN BLE DATA IS RECEIVED */
class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {

      std::string rxValue = pCharacteristic->getValue(); //get the data

      /* STORE THE DATA */
      if (rxValue.length() > 0) {
        for (int i = 0; i < rxValue.length(); i++)
          newData = true; //notify that data has been received
      }

      /* IF THERE IS UNREAD DATA */
      if (newData == true) {
        receivedData[rxValue.length() + 1] = {};
        strcpy(receivedData, rxValue.c_str());
        newData = false;
        dataAvailable = true;
      }
    }
};

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

  // Create the BLE Device
  BLEDevice::init("UART Service");

  // Create the BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  BLEService *pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_TX,
                      BLECharacteristic::PROPERTY_READ
                    );

  pCharacteristic->addDescriptor(new BLE2902());

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_RX,
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setCallbacks(new MyCallbacks());

  // Start the service
  pService->start();

  // Start advertising
  pServer->getAdvertising()->start(); //be available for connection
  Serial.println("Waiting a client connection to notify...");
}

void loop() {
  /* if (deviceConnected) {
    char datastring[] = "ESP32";
    Serial.println("*** Sent Value:  ***");
    Serial.println (datastring);
    pCharacteristic->setValue(datastring);
    pCharacteristic->notify();
    } */

  /* WAIT FOR WIFI SSID AND PASSWORD TO BE RECEIVED */
  while ((strlen(wifiSSID) || strlen(wifiPassword)) == NULL) { //while not received
    if (dataAvailable == true) {
      Serial.println("Data");
      if (strstr(receivedData, "SSID")) { //if data received include the word "lat" (received the latitude)
        Serial.print("SSID");
        strcpy(wifiSSID, receivedData);
        Serial.println(wifiSSID);

        char datastring[] = "Success!";
        Serial.println("*** Sent Value:  ***");
        Serial.println (datastring);
        pCharacteristic->setValue(datastring);
        pCharacteristic->notify();
        dataAvailable = false;
      }

      if (strstr(receivedData, "PASSWORD")) { //if data received include the word "lat" (received the latitude)
        Serial.println("Data");
        Serial.print("PASSWORD");
        strcpy(wifiPassword, receivedData);
        Serial.println(wifiPassword);

        char datastring[] = "Success!";
        Serial.println("*** Sent Value:  ***");
        Serial.println (datastring);
        pCharacteristic->setValue(datastring);
        pCharacteristic->notify();
        dataAvailable = false;
      }
    }
  }
  delay (1000);
}

vaj4088 I am working with the strlen command but no success yet:

  while ((strlen(wifiSSID) || strlen(wifiPassword)) == NULL) { //while not received

What am I doing wrong here?

Thanks,

Zeb

Also tried:

  while ((strlen(wifiSSID) == NULL) || (strlen(wifiPassword) ==NULL)) { //while not received

I have no idea. But

You should first test if a pointer is not NULL before working with it (getting strlen in this case).
Better

  while (wifiSSID == NULL  || wifiPassword == NULL)
strcpy(wifiSSID, receivedData);

You should not copy something to a pointer if that pointer has not be initialised to a memory area sufficient space. The better way is to use an array instead of a pointer to solve this.
3)
Though NULL and zero are basically the same (in our world), the result of strlen is a number (0 .. )

I have spent the last six months actively avoiding the String class, but c-strings and pointers are still my weak area.

I believe that your problem is that wifiSSID and wifiPassword are not initialized, so the contents are unknown.

I would try this:

char *wifiSSID = '/0';
char *wifiPassword = '/0';

This would insure that strlen() would be == 0.

Have you tried putting a Serial.print() before the line:

while ((strlen(wifiSSID) || strlen(wifiPassword)) == NULL) { //while not received

to see what is being evaluated?

@SteveMann

char *wifiSSID = '/0';

That would be a pointer to a single character; at the moment that you try a strcpy with more than one character, you will overwrite another variable. I'm not sure what the length of a wifiSSID can be, but below allows for a 9 character SSID plus a terminating '\0'.

// adjust to needs
char wifiSSID[10];

And it should be '\0', but that is not the point of this reply.

1 Like

Thanks guys it's working!

sterretje:
And it should be '\0', but that is not the point of this reply.

Thanks for the update.

As I said, pointers are my single point of failure, so I am always learning.
Overnight, it occurred to me that the OP code was wrong in the initialization of the char array because the pointer declared this way doesn't point to any allocated memory.

so, char wifiSSID[10]; is the correct fix.

ZebH:
Thanks guys it's working!

You had several suggestions. Please elaborate on what fixed your issue for the benefit of the next person with a similar problem.

It is amazing what having the code will turn up. I wonder what the code looks like now.

Hi guys,

The cstrings been Pointers was the problem SteveMann! Thanks for your help!

I will post the completed code ASAP!

Thanks again,

Zeb