I am trying to code a BLE device and send SSID & password from a phone to the device.
But I have been checking this code for a while but I cannot find where the error is. I used Arduino IDE and VCode to check brackets but still, I cannot find them. Can somebody help me?
It is showing me that a bracket is missing.
No matter what I do, it happens every time.
class MyServerCallbacks: public BLEServerCallbacks {
// TODO this doesn't take into account several clients being connected
void onConnect(BLEServer* pServer) {
Serial.println("BLE client connected");
};
void onDisconnect(BLEServer* pServer) {
Serial.println("BLE client disconnected");
pAdvertising->start();
}
};
class MyCallbackHandler: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() == 0) {
return;
}
Serial.println("Received over BLE: " + String((char *)&value[0]));
// Decode data
int keyIndex = 0;
for (int index = 0; index < value.length(); index ++) {
value[index] = (char) value[index] ^ (char) apName[keyIndex];
keyIndex++;
if (keyIndex >= strlen(apName)){
keyIndex = 0;
}
}
/** Json object for incoming data */
JsonObject& jsonIn = jsonBuffer.parseObject((char *)&value[0]);
if (jsonIn.success()) {
if (jsonIn.containsKey("ssid") && jsonIn.containsKey("password") {
ssid = jsonIn["ssid"].as<String>();
password = jsonIn["password"].as<String>();
Preferences preferences;
preferences.begin("WiFiCred", false);
preferences.putString("ssid", ssid);
preferences.putString("password", password);
preferences.putBool("valid", true);
preferences.end();
Serial.println("Received over bluetooth:");
Serial.println("primary SSID: "+ssid+" password: "+password);
connStatusChanged = true;
hasCredentials = true;
}
else if (jsonIn.containsKey("erase")) {
Serial.println("Received erase command");
Preferences preferences;
preferences.begin("WiFiCred", false);
preferences.clear();
preferences.end();
connStatusChanged = true;
hasCredentials = false;
ssid = "";
password = "";
}
else if (jsonIn.containsKey("reset")) {
WiFi.disconnect();
esp_restart();
}
}
else {
Serial.println("Received invalid JSON");
}
jsonBuffer.clear();
};
void onRead(BLECharacteristic *pCharacteristic) {
Serial.println("BLE onRead request");
String wifiCredentials;
/** Json object for outgoing data */
JsonObject& jsonOut = jsonBuffer.createObject();
jsonOut["ssid"] = ssid;
jsonOut["password"] = password;
// Convert JSON object into a string
jsonOut.printTo(wifiCredentials);
// encode the data
int keyIndex = 0;
Serial.println("Stored settings: " + wifiCredentials);
for (int index = 0; index < wifiCredentials.length(); index ++) {
wifiCredentials[index] = (char) wifiCredentials[index] ^ (char) apName[keyIndex];
keyIndex++;
if (keyIndex >= strlen(apName)){ keyIndex = 0;}
}
pCharacteristicWiFi->setValue((uint8_t*)&wifiCredentials[0],wifiCredentials.length());
jsonBuffer.clear();
}
};
/**
* initBLE
* Initialize BLE service and characteristic
* Start BLE server and service advertising
*/
void initBLE() {
// Initialize BLE and set output power
BLEDevice::init(apName);
BLEDevice::setPower(ESP_PWR_LVL_P7);
// Create BLE Server
pServer = BLEDevice::createServer();
// Set server callbacks
pServer->setCallbacks(new MyServerCallbacks());
// Create BLE Service
pService = pServer->createService(BLEUUID(SERVICE_UUID),20);
// Create BLE Characteristic for WiFi settings
pCharacteristicWiFi = pService->createCharacteristic(
BLEUUID(WIFI_UUID),
// WIFI_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristicWiFi->setCallbacks(new MyCallbackHandler());
// Start the service
pService->start();
// Start advertising
pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
/** Callback for receiving IP address from AP */
void gotIP(system_event_id_t event) {
isConnected = true;
connStatusChanged = true;
}
/** Callback for connection loss */
void lostCon(system_event_id_t event) {
isConnected = false;
connStatusChanged = true;
}
/**
scanWiFi
Scans for available networks
and decides if a switch between
allowed networks makes sense
@return <code>bool</code>
True if at least one allowed network was found
*/
bool scanWiFi() {
/** RSSI for primary network */
int8_t rssi;
/** Result of this function */
bool result = false;
Serial.println("Start scanning for networks");
WiFi.disconnect(true);
WiFi.enableSTA(true);
WiFi.mode(WIFI_STA);
// Scan for AP
int apNum = WiFi.scanNetworks(false,true,false,1000);
if (apNum == 0) {
Serial.println("Found no networks?????");
return false;
}
byte foundAP = 0;
bool found = false;
for (int index=0; index<apNum; index++) {
String found_ssid = WiFi.SSID(index);
Serial.println("Found AP: " + found_ssid + " RSSI: " + WiFi.RSSI(index));
if (!strcmp((const char*) &found_ssid[0], (const char*) &ssid[0])) {
Serial.println("Found AP");
foundAP++;
found = true;
rssi = WiFi.RSSI(index);
}
}
switch (foundAP) {
case 0:
result = false;
break;
case 1:
result = true;
break;
}
return result;
}
/**
* Start connection to AP
*/
void connectWiFi() {
// Setup callback function for successful connection
WiFi.onEvent(gotIP, SYSTEM_EVENT_STA_GOT_IP);
// Setup callback function for lost connection
WiFi.onEvent(lostCon, SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.disconnect(true);
WiFi.enableSTA(true);
WiFi.mode(WIFI_STA);
Serial.println();
Serial.print("Start connection to ");
Serial.println(ssid);
WiFi.begin(ssid.c_str(), password.c_str());
}
void setup() {
// Initialize Serial port
Serial.begin(115200);
// Create unique device name
createName();
// Send some device info
Serial.print("Build: ");
Serial.println(compileDate);
Preferences preferences;
preferences.begin("WiFiCred", false);
bool hasPref = preferences.getBool("valid", false);
if (hasPref) {
ssid = preferences.getString("ssid","");
password = preferences.getString("password","");
if (ssid.equals("") || password.equals("") {
Serial.println("Found preferences but credentials are invalid");
}
else {
Serial.println("Read from preferences:");
Serial.println("primary SSID: "+ssid+" password: "+password);
hasCredentials = true;
}
}
else {
Serial.println("Could not find preferences, need send data over BLE");
}
preferences.end();
// Start BLE server
initBLE();
if (hasCredentials) {
// Check for available AP's
if (!scanWiFi) {
Serial.println("Could not find any AP");
}
else {
// If AP was found, start connection
connectWiFi();
}
}
}
void loop() {
if (connStatusChanged) {
if (isConnected) {
Serial.print("Connected to AP: ");
Serial.print(WiFi.SSID());
Serial.print(" with IP: ");
Serial.print(WiFi.localIP());
Serial.print(" RSSI: ");
Serial.println(WiFi.RSSI());
}
else {
if (hasCredentials) {
Serial.println("Lost WiFi connection");
// Received WiFi credentials
if (!scanWiFi) { // Check for available AP's
Serial.println("Could not find any AP");
}
else { // If AP was found, start connection
connectWiFi();
}
}
}
connStatusChanged = false;
}
else{
Serial.println("Nothing changed");
}
}
You miss a closing parenthesis in this line of code:
if ( jsonIn.containsKey("ssid") && jsonIn.containsKey("password") {
should be:
if ( jsonIn.containsKey("ssid") && jsonIn.containsKey("password") ) {