Reputation: 9365
I'm now trying to write to the Control Point Characteristic according to the ANCS - Apple Notification Center Service using an Arduino ESP32.
This is my current definition for the notification attributes command to send to the Control Point Characteristic:
uint8_t notificationAttributesCommand[7];
notificationAttributesCommand[0] = 0x00; // Command ID: Get Notification Attributes
notificationAttributesCommand[1] = (uint8_t)(notificationUID >> 24); // Notification UID (Most significant byte)
notificationAttributesCommand[2] = (uint8_t)(notificationUID >> 16); // Second byte
notificationAttributesCommand[3] = (uint8_t)(notificationUID >> 8); // Third byte
notificationAttributesCommand[4] = (uint8_t)(notificationUID); // Least significant byte
// Attribute IDs and their maximum length (as per your specification)
notificationAttributesCommand[5] = 0x01; // Attribute ID for App Identifier
And this is how I send it in my loop()
function:
void loop() {
if (newNotificationFlag) {
// Send the command to the Control Point characteristic
if (pControlPointCharacteristic != nullptr) {
Serial.println("Sending Get Notification Attributes command to Control Point...");
if (pControlPointCharacteristic->canWrite()) {
Serial.println("before writing to pControlPointCharacteristic!");
pControlPointCharacteristic->writeValue(notificationAttributesCommand, sizeof(notificationAttributesCommand), true);
Serial.println("after writing to pControlPointCharacteristic!");
} else {
Serial.println("loop(): Control Point Characteristic cannot be written.");
}
} else {
Serial.println("Control Point characteristic is null");
}
// Reset the flag
newNotificationFlag = false;
}
}
I have modified the code from BLERemoteCharacteristic.cpp
to output the log like this:
case ESP_GATTC_WRITE_CHAR_EVT:
{
log_d("case ESP_GATTC_WRITE_CHAR_EVT");
// Determine if this event is for us and, if not, pass onwards.
if (evtParam->write.handle != getHandle()) {
break;
}
// Check the write status to confirm if it was successful
// Check the write status to confirm if it was successful or if an error occurred
if (evtParam->write.status == ESP_GATT_OK) {
log_d("Write to Control Point characteristic was successful.");
} else {
// Handle specific ANCS error codes
switch (evtParam->write.status) {
case 0xA0:
log_d("Write to Control Point characteristic failed. Error: Unknown command (0xA0). The commandID was not recognized by the NP.");
break;
case 0xA1:
log_d("Write to Control Point characteristic failed. Error: Invalid command (0xA1). The command was improperly formatted.");
break;
case 0xA2:
log_d("Write to Control Point characteristic failed. Error: Invalid parameter (0xA2). One of the parameters (e.g., NotificationUID) does not refer to an existing object on the NP.");
break;
case 0xA3:
log_d("Write to Control Point characteristic failed. Error: Action failed (0xA3). The action was not performed.");
break;
default:
log_d("Write to Control Point characteristic failed. Unknown error status: %d", evtParam->write.status);
break;
}
}
// Error Codes
// https://developer.apple.com/library/archive/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/Specification/Specification.html#//apple_ref/doc/uid/TP40013460-CH1-SW7
// When writing to the Control Point characteristic, an NC may receive the following ANCS-specific error codes:
// There is nothing further we need to do here. This is merely an indication
// that the write has completed and we can unlock the caller.
m_semaphoreWriteCharEvt.give();
log_d("after m_semaphoreWriteCharEvt.give, There is nothing further we need to do here. This is merely an indication that the write has completed and we can unlock the caller.");
break;
} // ESP_GATTC_WRITE_CHAR_EVT
Upon deployment and testing, I get this log:
15:35:25.617 -> [577839][D][BLEDevice.cpp:138] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_NOTIFY_EVT
15:35:25.617 -> [577852][D][BLEClient.cpp:185] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_NOTIFY_EVT
15:35:25.661 -> [577863][D][BLERemoteCharacteristic.cpp:154] gattClientEventHandler(): case ESP_GATTC_NOTIFY_EVT
15:35:25.661 -> [577871][D][BLERemoteCharacteristic.cpp:154] gattClientEventHandler(): case ESP_GATTC_NOTIFY_EVT
15:35:25.661 -> [577880][D][BLERemoteCharacteristic.cpp:159] gattClientEventHandler(): @Invoking callback for notification on characteristic Characteristic: uuid: 9fbf120d-6301-42d9-8c58-25e699a21dbd, handle: 40 0x0028, props: broadcast: 0, read: 0, write_nr: 0, write: 0, notify: 1, indicate: 0, auth: 0
15:35:25.681 -> 0x00 0x10 0x00 0x0C 0x0D 0x00 0x00 0x00
15:35:25.681 -> New notification!
15:35:25.681 -> Notification UID: 218103808
15:35:25.681 -> Category: Other
15:35:25.681 -> Sending Get Notification Attr[577906][D][BLERemoteCharacteristic.cpp:154] gattClientEventHandler(): case ESP_GATTC_NOTIFY_EVT
15:35:25.713 -> ibutes command to Control Point...
15:35:25.713 -> before writing to pControlPointCharacteristic!
15:35:25.713 -> [577925][D][BLERemoteCharacteristic.cpp:598] writeValue(): >> writeValue(), length: 7
15:35:25.713 -> [577941][D][BLERemoteCharacteristic.cpp:606] writeValue(): 1. Before m_semaphoreWriteCharEvt.take
15:35:25.713 -> [577949][D][BLERemoteCharacteristic.cpp:610] writeValue(): 2. After m_semaphoreWriteCharEvt.take
15:35:25.746 -> [577958][D][BLERemoteCharacteristic.cpp:617] writeValue(): 3. Before errRc != ESP_OK
15:35:25.746 -> [577966][D][BLERemoteCharacteristic.cpp:624] writeValue(): 4. Before m_semaphoreWriteCharEvt.wait
15:35:25.811 -> [578051][D][BLEDevice.cpp:138] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_WRITE_CHAR_EVT
15:35:25.843 -> [578062][D][BLEClient.cpp:185] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_WRITE_CHAR_EVT
15:35:25.843 -> [578073][D][BLERemoteCharacteristic.cpp:241] gattClientEventHandler(): case ESP_GATTC_WRITE_CHAR_EVT
15:35:25.843 -> [578082][D][BLERemoteCharacteristic.cpp:258] gattClientEventHandler(): Write to Control Point characteristic failed. Error: Invalid command (0xA1). The command was improperly formatted.
15:35:25.875 -> [578098][D][BLERemoteCharacteristic.cpp:626] writeValue():[ 557.8 0A9f8t]e[rD ]m[_BsLeEmRaepmhootreeCWhrairtaecCthearriEsvtti.cw.ait:279] gattClientEventHandler(): after m_semaphoreWriteCharEvt.give, There is nothing further we need to do here. This is merely an indication that the write has completed and we can unlock the caller.
15:35:25.907 -> after writing to pControlPointCharacteristic!
15:35:25.907 -> [578127][D][BLERemoteCharacteristic.cpp:241] gattClientEventHandler(): case ESP_GATTC_WRITE_CHAR_EVT
15:35:25.907 -> [578140][D][BLERemoteCharacteristic.cpp:241] gattClientEventHandler(): case ESP_GATTC_WRITE_CHAR_EVT
I'm focusing on this particular line:
Write to Control Point characteristic failed. Error: Invalid command (0xA1). The command was improperly formatted.
Can someone tell me what is wrong with my get command definition? Thank you
Upvotes: 1
Views: 29