diff --git a/example/embedded/ancs_client_demo.c b/example/embedded/ancs_client_demo.c index 4498621c8..19d073ad7 100644 --- a/example/embedded/ancs_client_demo.c +++ b/example/embedded/ancs_client_demo.c @@ -107,17 +107,18 @@ static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t * static void ancs_callback(uint8_t packet_type, uint8_t *packet, uint16_t size){ const char * attribute_name; - switch (packet[0]){ - case ANCS_EVENT_CLIENT_CONNECTED: + if (packet[0] != HCI_EVENT_ANCS_META) return; + switch (packet[2]){ + case ANCS_SUBEVENT_CLIENT_CONNECTED: printf("ANCS Client: Connected\n"); break; - case ANCS_EVENT_CLIENT_DISCONNECTED: + case ANCS_SUBEVENT_CLIENT_DISCONNECTED: printf("ANCS Client: Disconnected\n"); break; - case ANCS_EVENT_CLIENT_NOTIFICATION: - attribute_name = ancs_client_attribute_name_for_id(ancs_event_client_notification_get_attribute_id(packet)); + case ANCS_SUBEVENT_CLIENT_NOTIFICATION: + attribute_name = ancs_client_attribute_name_for_id(ancs_subevent_client_notification_get_attribute_id(packet)); if (!attribute_name) break; - printf("Notification: %s - %s\n", attribute_name, ancs_event_client_notification_get_text(packet)); + printf("Notification: %s - %s\n", attribute_name, ancs_subevent_client_notification_get_text(packet)); break; default: break; diff --git a/port/arduino/examples/ANCS/ANCS.ino b/port/arduino/examples/ANCS/ANCS.ino index 324a1db50..43054eee2 100644 --- a/port/arduino/examples/ANCS/ANCS.ino +++ b/port/arduino/examples/ANCS/ANCS.ino @@ -74,20 +74,21 @@ void loop(void){ /* LISTING_START(ANCSCallback): ANCS Callback */ void ancs_callback(uint8_t packet_type, uint8_t *packet, uint16_t size){ const char * attribute_name; + if (packet[0] != HCI_EVENT_ANCS_META) return; switch (packet[0]){ - case ANCS_EVENT_CLIENT_CONNECTED: + case ANCS_SUBEVENT_CLIENT_CONNECTED: Serial.println("ANCS Client: Connected"); break; - case ANCS_EVENT_CLIENT_DISCONNECTED: + case ANCS_SUBEVENT_CLIENT_DISCONNECTED: Serial.println("ANCS Client: Disconnected"); break; - case ANCS_EVENT_CLIENT_NOTIFICATION: - attribute_name = ancs_client_attribute_name_for_id(ancs_client_notification_event_get_attribute_id(packet)); + case ANCS_SUBEVENT_CLIENT_NOTIFICATION: + attribute_name = ancs_client_attribute_name_for_id(ancs_subevent_client_notification_get_attribute_id(packet)); if (!attribute_name) break; Serial.print("Notification: "); Serial.print(attribute_name); Serial.print(" - "); - Serial.println(ancs_client_notification_event_get_text(packet)); + Serial.println(ancs_subevent_client_notification_get_text(packet)); break; default: break; diff --git a/src/ble/ancs_client.c b/src/ble/ancs_client.c index 90bc329f1..1a0088b59 100644 --- a/src/ble/ancs_client.c +++ b/src/ble/ancs_client.c @@ -42,16 +42,16 @@ #include #include -#include "btstack_run_loop.h" -#include "classic/sdp_util.h" - #include "ancs_client.h" #include "ble/att_db.h" -#include "btstack_debug.h" -#include "gap.h" #include "ble/gatt_client.h" #include "ble/sm.h" +#include "btstack_debug.h" +#include "btstack_event.h" +#include "btstack_run_loop.h" +#include "classic/sdp_util.h" +#include "gap.h" // ancs_client.h Start typedef enum ancs_chunk_parser_state { @@ -113,23 +113,25 @@ void ancs_client_register_callback(void (*handler)(uint8_t packet_type, uint8_t static void notify_client_text(int event_type){ if (!client_handler) return; - uint8_t event[6 + sizeof(ancs_notification_buffer) + 1]; - event[0] = event_type; - event[1] = 6 + ancs_attribute_len; - little_endian_store_16(event, 2, gc_handle); - little_endian_store_16(event, 4, ancs_attribute_id); - memcpy(&event[6], ancs_notification_buffer, ancs_attribute_len); + uint8_t event[7 + sizeof(ancs_notification_buffer) + 1]; + event[0] = HCI_EVENT_ANCS_META; + event[1] = 5 + ancs_attribute_len; + event[2] = event_type; + little_endian_store_16(event, 3, gc_handle); + little_endian_store_16(event, 5, ancs_attribute_id); + memcpy(&event[7], ancs_notification_buffer, ancs_attribute_len); // we're nice - event[6+ancs_attribute_len] = 0; + event[7+ancs_attribute_len] = 0; (*client_handler)(HCI_EVENT_PACKET, event, event[1] + 2); } static void notify_client_simple(int event_type){ if (!client_handler) return; - uint8_t event[4]; - event[0] = event_type; - event[1] = 2; - little_endian_store_16(event, 2, gc_handle); + uint8_t event[5]; + event[0] = HCI_EVENT_ANCS_META; + event[1] = 3; + event[2] = event_type; + little_endian_store_16(event, 3, gc_handle); (*client_handler)(HCI_EVENT_PACKET, event, sizeof(event)); } @@ -167,7 +169,7 @@ static void ancs_chunk_parser_handle_byte(uint8_t data){ break; case W4_ATTRIBUTE_COMPLETE: ancs_notification_buffer[ancs_bytes_received] = 0; - notify_client_text(ANCS_EVENT_CLIENT_NOTIFICATION); + notify_client_text(ANCS_SUBEVENT_CLIENT_NOTIFICATION); ancs_bytes_received = 0; ancs_bytes_needed = 1; chunk_parser_state = W4_ATTRIBUTE_ID; @@ -175,28 +177,6 @@ static void ancs_chunk_parser_handle_byte(uint8_t data){ } } -static void extract_service(gatt_client_service_t * service, uint8_t * packet){ - service->start_group_handle = little_endian_read_16(packet, 4); - service->end_group_handle = little_endian_read_16(packet, 6); - service->uuid16 = 0; - reverse_128(&packet[8], service->uuid128); - if (uuid_has_bluetooth_prefix(service->uuid128)){ - service->uuid16 = big_endian_read_32(service->uuid128, 0); - } -} - -static void extract_characteristic(gatt_client_characteristic_t * characteristic, uint8_t * packet){ - characteristic->start_handle = little_endian_read_16(packet, 4); - characteristic->value_handle = little_endian_read_16(packet, 6); - characteristic->end_handle = little_endian_read_16(packet, 8); - characteristic->properties = little_endian_read_16(packet, 10); - characteristic->uuid16 = 0; - reverse_128(&packet[12], characteristic->uuid128); - if (uuid_has_bluetooth_prefix(characteristic->uuid128)){ - characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0); - } -} - static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ int connection_encrypted; @@ -207,7 +187,7 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac switch (packet[2]) { case HCI_SUBEVENT_LE_CONNECTION_COMPLETE: gc_handle = little_endian_read_16(packet, 4); - printf("Connection handle 0x%04x, request encryption\n", gc_handle); + log_info("Connection handle 0x%04x, request encryption", gc_handle); // we need to be paired to enable notifications tc_state = TC_W4_ENCRYPTED_CONNECTION; @@ -226,13 +206,13 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac if (tc_state != TC_W4_ENCRYPTED_CONNECTION) return; // let's start - printf("\nANCS Client - CONNECTED, discover ANCS service\n"); + log_info("\nANCS Client - CONNECTED, discover ANCS service"); tc_state = TC_W4_SERVICE_RESULT; gatt_client_discover_primary_services_by_uuid128(handle_hci_event, gc_handle, ancs_service_uuid); return; case HCI_EVENT_DISCONNECTION_COMPLETE: - notify_client_simple(ANCS_EVENT_CLIENT_DISCONNECTED); + notify_client_simple(ANCS_SUBEVENT_CLIENT_DISCONNECTED); return; default: @@ -248,17 +228,17 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac case TC_W4_SERVICE_RESULT: switch(packet[0]){ case GATT_EVENT_SERVICE_QUERY_RESULT: - extract_service(&ancs_service, packet); + gatt_event_service_query_result_get_service(packet, &ancs_service); ancs_service_found = 1; break; case GATT_EVENT_QUERY_COMPLETE: if (!ancs_service_found){ - printf("ANCS Service not found"); + log_info("ANCS Service not found"); tc_state = TC_IDLE; break; } tc_state = TC_W4_CHARACTERISTIC_RESULT; - printf("ANCS Client - Discover characteristics for ANCS SERVICE \n"); + log_info("ANCS Client - Discover characteristics for ANCS SERVICE "); gatt_client_discover_characteristics_for_service(handle_hci_event, gc_handle, &ancs_service); break; default: @@ -269,28 +249,28 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac case TC_W4_CHARACTERISTIC_RESULT: switch(packet[0]){ case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT: - extract_characteristic(&characteristic, packet); + gatt_event_characteristic_query_result_get_characteristic(packet, &characteristic); if (memcmp(characteristic.uuid128, ancs_notification_source_uuid, 16) == 0){ - printf("ANCS Notification Source Characterisic found\n"); + log_info("ANCS Notification Source Characterisic found"); ancs_notification_source_characteristic = characteristic; ancs_characteristcs++; break; } if (memcmp(characteristic.uuid128, ancs_control_point_uuid, 16) == 0){ - printf("ANCS Control Point found\n"); + log_info("ANCS Control Point found"); ancs_control_point_characteristic = characteristic; ancs_characteristcs++; break; } if (memcmp(characteristic.uuid128, ancs_data_source_uuid, 16) == 0){ - printf("ANCS Data Source Characterisic found\n"); + log_info("ANCS Data Source Characterisic found"); ancs_data_source_characteristic = characteristic; ancs_characteristcs++; break; } break; case GATT_EVENT_QUERY_COMPLETE: - printf("ANCS Characteristcs count %u\n", ancs_characteristcs); + log_info("ANCS Characteristcs count %u", ancs_characteristcs); tc_state = TC_W4_NOTIFICATION_SOURCE_SUBSCRIBED; gatt_client_write_client_characteristic_configuration(handle_hci_event, gc_handle, &ancs_notification_source_characteristic, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); @@ -302,7 +282,7 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac case TC_W4_NOTIFICATION_SOURCE_SUBSCRIBED: switch(packet[0]){ case GATT_EVENT_QUERY_COMPLETE: - printf("ANCS Notification Source subscribed\n"); + log_info("ANCS Notification Source subscribed"); tc_state = TC_W4_DATA_SOURCE_SUBSCRIBED; gatt_client_listen_for_characteristic_value_updates(&client_notification, gc_handle, &ancs_data_source_characteristic); gatt_client_write_client_characteristic_configuration(handle_hci_event, gc_handle, &ancs_data_source_characteristic, @@ -315,9 +295,9 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac case TC_W4_DATA_SOURCE_SUBSCRIBED: switch(packet[0]){ case GATT_EVENT_QUERY_COMPLETE: - printf("ANCS Data Source subscribed\n"); + log_info("ANCS Data Source subscribed"); tc_state = TC_SUBSCRIBED; - notify_client_simple(ANCS_EVENT_CLIENT_CONNECTED); + notify_client_simple(ANCS_SUBEVENT_CLIENT_CONNECTED); break; default: break; @@ -337,7 +317,7 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac } } else if (value_handle == ancs_notification_source_characteristic.value_handle){ ancs_notification_uid = little_endian_read_32(value, 4); - printf("Notification received: EventID %02x, EventFlags %02x, CategoryID %02x, CategoryCount %u, UID %04x\n", + log_info("Notification received: EventID %02x, EventFlags %02x, CategoryID %02x, CategoryCount %u, UID %04x", value[0], value[1], value[2], value[3], (int) ancs_notification_uid); static uint8_t get_notification_attributes[] = {0, 0,0,0,0, 0, 1,32,0, 2,32,0, 3,32,0, 4, 5}; little_endian_store_32(get_notification_attributes, 1, ancs_notification_uid); @@ -346,8 +326,8 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac gatt_client_write_value_of_characteristic(handle_hci_event, gc_handle, ancs_control_point_characteristic.value_handle, sizeof(get_notification_attributes), get_notification_attributes); } else { - printf("Unknown Source: "); - printf_hexdump(value , value_length); + log_info("Unknown Source: "); + log_info_hexdump(value , value_length); } break; default: diff --git a/src/btstack_defines.h b/src/btstack_defines.h index 4fef8d941..556ea9442 100644 --- a/src/btstack_defines.h +++ b/src/btstack_defines.h @@ -753,12 +753,18 @@ typedef uint8_t sm_key_t[16]; #define GAP_LE_EVENT_ADVERTISING_REPORT 0xE2 +// Meta Events, see below for sub events #define HCI_EVENT_HSP_META 0xE8 - #define HCI_EVENT_HFP_META 0xE9 +#define HCI_EVENT_ANCS_META 0xEA - -// HSP Subevents +// Potential other meta groups + // #define HCI_EVENT_BNEP_META 0xxx +// #define HCI_EVENT_GAP_META 0xxx +// #define HCI_EVENT_GATT_META 0xxx +// #define HCI_EVENT_PAN_META 0xxx +// #define HCI_EVENT_SDP_META 0xxx +// #define HCI_EVENT_SM_META 0xxx /** * @format 11 @@ -840,32 +846,26 @@ typedef uint8_t sm_key_t[16]; // ANCS Client /** - * @format H + * @format 1H + * @param subevent_code * @param handle */ -#define ANCS_EVENT_CLIENT_CONNECTED 0xF0 +#define ANCS_SUBEVENT_CLIENT_CONNECTED 0xF0 /** - * @format H2T + * @format 1H2T + * @param subevent_code * @param handle * @param attribute_id * @param text */ -#define ANCS_EVENT_CLIENT_NOTIFICATION 0xF1 +#define ANCS_SUBEVENT_CLIENT_NOTIFICATION 0xF1 /** - * @format H + * @format 1H + * @param subevent_code * @param handle */ -#define ANCS_EVENT_CLIENT_DISCONNECTED 0xF2 - -// #define HCI_EVENT_HFP_META 0xxx -// #define HCI_EVENT_GATT_META 0xxx -// #define HCI_EVENT_SDP_META 0xxx -// #define HCI_EVENT_ANCS_META 0xxx -// #define HCI_EVENT_SM_META 0xxx -// #define HCI_EVENT_GAP_META 0xxx -// #define HCI_EVENT_BNEP_META 0xxx -// #define HCI_EVENT_PAN_META 0xxx +#define ANCS_SUBEVENT_CLIENT_DISCONNECTED 0xF2 #endif diff --git a/src/btstack_event.h b/src/btstack_event.h index bebf3df0d..8ad639151 100644 --- a/src/btstack_event.h +++ b/src/btstack_event.h @@ -51,7 +51,6 @@ extern "C" { #endif -#include "btstack_config.h" #include "btstack_util.h" #include @@ -1378,55 +1377,82 @@ static inline uint8_t sm_event_authorization_result_get_authorization_result(con #ifdef ENABLE_BLE /** - * @brief Get field handle from event ancs_event_client_connected + * @brief Get field subevent_code from event ancs_subevent_client_connected + * @param Event packet + * @return subevent_code + * @note: btstack_type 1 + */ +static inline uint8_t ancs_subevent_client_connected_get_subevent_code(const uint8_t * event){ + return event[2]; +} +/** + * @brief Get field handle from event ancs_subevent_client_connected * @param Event packet * @return handle * @note: btstack_type H */ -static inline hci_con_handle_t ancs_event_client_connected_get_handle(const uint8_t * event){ - return little_endian_read_16(event, 2); +static inline hci_con_handle_t ancs_subevent_client_connected_get_handle(const uint8_t * event){ + return little_endian_read_16(event, 3); } #endif #ifdef ENABLE_BLE /** - * @brief Get field handle from event ancs_event_client_notification + * @brief Get field subevent_code from event ancs_subevent_client_notification + * @param Event packet + * @return subevent_code + * @note: btstack_type 1 + */ +static inline uint8_t ancs_subevent_client_notification_get_subevent_code(const uint8_t * event){ + return event[2]; +} +/** + * @brief Get field handle from event ancs_subevent_client_notification * @param Event packet * @return handle * @note: btstack_type H */ -static inline hci_con_handle_t ancs_event_client_notification_get_handle(const uint8_t * event){ - return little_endian_read_16(event, 2); +static inline hci_con_handle_t ancs_subevent_client_notification_get_handle(const uint8_t * event){ + return little_endian_read_16(event, 3); } /** - * @brief Get field attribute_id from event ancs_event_client_notification + * @brief Get field attribute_id from event ancs_subevent_client_notification * @param Event packet * @return attribute_id * @note: btstack_type 2 */ -static inline uint16_t ancs_event_client_notification_get_attribute_id(const uint8_t * event){ - return little_endian_read_16(event, 4); +static inline uint16_t ancs_subevent_client_notification_get_attribute_id(const uint8_t * event){ + return little_endian_read_16(event, 5); } /** - * @brief Get field text from event ancs_event_client_notification + * @brief Get field text from event ancs_subevent_client_notification * @param Event packet * @return text * @note: btstack_type T */ -static inline const char * ancs_event_client_notification_get_text(const uint8_t * event){ - return (const char *) &event[6]; +static inline const char * ancs_subevent_client_notification_get_text(const uint8_t * event){ + return (const char *) &event[7]; } #endif #ifdef ENABLE_BLE /** - * @brief Get field handle from event ancs_event_client_disconnected + * @brief Get field subevent_code from event ancs_subevent_client_disconnected + * @param Event packet + * @return subevent_code + * @note: btstack_type 1 + */ +static inline uint8_t ancs_subevent_client_disconnected_get_subevent_code(const uint8_t * event){ + return event[2]; +} +/** + * @brief Get field handle from event ancs_subevent_client_disconnected * @param Event packet * @return handle * @note: btstack_type H */ -static inline hci_con_handle_t ancs_event_client_disconnected_get_handle(const uint8_t * event){ - return little_endian_read_16(event, 2); +static inline hci_con_handle_t ancs_subevent_client_disconnected_get_handle(const uint8_t * event){ + return little_endian_read_16(event, 3); } #endif