Đức Thanh Nguyễn
Đức Thanh Nguyễn

Reputation: 9365

ESP32 BLE Arduino: writeValue method of BLERemoteCharacteristic makes ESP hang

Using a ESP32 BLE connected to Arduino IDE, I'm now trying to Get Notification Attributes by sending command to Control Point of Apple Notification Center Service (ANCS). This is the code

static void NotificationSourceNotifyCallback(
  BLERemoteCharacteristic* pNotificationSourceCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify)
{
    // Serial.print("Notification Source callback for characteristic ");
    // Serial.print(pNotificationSourceCharacteristic->getUUID().toString().c_str());
    // Serial.println();

    // Check if this is a "new notification" event
    if(pData[0] == 0) {
        for (size_t i = 0; i < length; i++) {
            Serial.print("0x");
            if (pData[i] < 0x10) {
                Serial.print("0");  // Add leading zero for single-digit hex
            }
            Serial.print(pData[i], HEX);  // Print as hexadecimal
            Serial.print(" ");
        }
        Serial.println();
        Serial.println("New notification!");

        uint32_t notificationUID = 0;
        notificationUID |= pData[4] << 24;  // Most significant byte
        notificationUID |= pData[5] << 16;
        notificationUID |= pData[6] << 8;
        notificationUID |= pData[7];  // Least significant byte

        // Print the NotificationUID
        Serial.print("Notification UID: ");
        Serial.println(notificationUID, DEC);

        // Print the category of the notification
        Serial.print("  Category: ");
        switch(pData[2]) {
            case 0: Serial.println("Other"); break;
            case 1: Serial.println("Incoming call"); break;
            case 2: Serial.println("Missed call"); break;
            case 3: Serial.println("Voicemail"); break;
            case 4: Serial.println("Social"); break;
            case 5: Serial.println("Schedule"); break;
            case 6: Serial.println("Email"); break;
            case 7: Serial.println("News"); break;
            case 8: Serial.println("Health"); break;
            case 9: Serial.println("Business"); break;
            case 10: Serial.println("Location"); break;
            case 11: Serial.println("Entertainment"); break;
            default: break;
        }

        // Create the Get Notification Attributes command
        uint8_t notificationAttributesCommand[] = {
            0x00,  // Command ID: Get Notification Attributes
            (uint8_t)(notificationUID >> 24),  // Notification UID (4 bytes)
            (uint8_t)(notificationUID >> 16),
            (uint8_t)(notificationUID >> 8),
            (uint8_t)(notificationUID),  // 32-bit Notification UID
            0x00  // Attribute IDs: App Identifier, Title, Message
        };

        // Send the command to the Control Point characteristic
        if (pControlPointCharacteristic != nullptr) {
              Serial.println("Sending Get Notification Attributes command to Control Point...");
              
              // Delay to ensure timing issues are not causing the hang
              delay(1000);
              Serial.println("After delaying 1s...");
              try {
                // pControlPointCharacteristic->writeValue(notificationAttributesCommand, sizeof(notificationAttributesCommand));
                // pControlPointCharacteristic->getDescriptor(BLEUUID("69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9"))->writeValue(notificationAttributesCommand, sizeof(notificationAttributesCommand),true);
                if(pControlPointCharacteristic->canWrite()) {
                  Serial.println("can write!");
                }
              } catch (...) {
                Serial.println("Not good");    
              }
              
              delay(1000);
              Serial.println("Write successful");

          } else {
              Serial.println("Control Point characteristic is null");
          }
    }

}

I tried:

pControlPointCharacteristic->writeValue(notificationAttributesCommand, sizeof(notificationAttributesCommand));

pControlPointCharacteristic->getDescriptor(BLEUUID("69D1D8F3-45E1-49A8-9821-9BBDFDAAD9D9"))->writeValue(notificationAttributesCommand, sizeof(notificationAttributesCommand),true);
                

It's not working and makes my esp32 board hang. What would I do to send a command to ANCS Control Point and get back the title, message of a iOS notification?

Thank you.

Upvotes: 0

Views: 30

Answers (1)

Đức Thanh Nguyễn
Đức Thanh Nguyễn

Reputation: 9365

I figured out what makes my esp32 hang: I put the writeValue call of

pControlPointCharacteristic->writeValue(notificationAttributesCommand, sizeof(notificationAttributesCommand));

in the wrong place.

What I did was: introduce a new flag variable and change the flag in NotificationSourceNotifyCallback then do the writeValue in loop() function.

I still cannot write to the Control Point Characteristic just yet because I encountered another error of invalid command format (Error 161 or 0xA1)

Invalid command (0xA1): The command was improperly formatted.
More info: under Error Codes section here:
https://developer.apple.com/library/archive/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html#//apple_ref/doc/uid/TP40013460-CH1-SW7

Upvotes: 0

Related Questions