diff --git a/example/libusb/ble_client.c b/example/libusb/ble_client.c index e2ed9e22b..468e809a2 100644 --- a/example/libusb/ble_client.c +++ b/example/libusb/ble_client.c @@ -113,6 +113,18 @@ static uint16_t l2cap_max_mtu_for_handle(uint16_t handle){ return l2cap_max_mtu(); } // END Helper Functions +static le_command_status_t att_find_information_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){ + if (!l2cap_can_send_conectionless_packet_now()) return BLE_PERIPHERAL_BUSY; + + uint8_t request[5]; + request[0] = request_type; + bt_store_16(request, 1, start_handle); + bt_store_16(request, 3, end_handle); + + l2cap_send_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, request, sizeof(request)); + return BLE_PERIPHERAL_OK; +} + static le_command_status_t att_find_by_type_value_request(uint16_t request_type, uint16_t attribute_group_type, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle, uint8_t * value, uint16_t value_size){ if (!l2cap_can_send_conectionless_packet_now()) return BLE_PERIPHERAL_BUSY; @@ -184,6 +196,10 @@ static le_command_status_t send_gatt_characteristic_request(le_peripheral_t *per return att_read_by_type_or_group_request(ATT_READ_BY_TYPE_REQUEST, GATT_CHARACTERISTICS_UUID, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle); } +static le_command_status_t send_gatt_characteristic_descriptor_request(le_peripheral_t *peripheral){ + return att_find_information_request(ATT_FIND_INFORMATION_REQUEST, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle); +} + static inline void send_gatt_complete_event(le_peripheral_t * peripheral, uint8_t type, uint8_t status){ le_peripheral_event_t event; event.type = type; @@ -341,13 +357,19 @@ static void handle_peripheral_list(){ if (status != BLE_PERIPHERAL_OK) break; peripheral->state = P_W4_CHARACTERISTIC_QUERY_RESULT; break; + case P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY: - // TODO: status = send_gatt_characteristic_request(peripheral); if (status != BLE_PERIPHERAL_OK) break; peripheral->state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; break; + case P_W2_SEND_CHARACTERISTIC_DESCRIPTOR_QUERY: + status = send_gatt_characteristic_descriptor_request(peripheral); + if (status != BLE_PERIPHERAL_OK) break; + peripheral->state = P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT; + break; + case P_W2_SEND_INCLUDED_SERVICE_QUERY: status = send_gatt_included_service_request(peripheral); if (status != BLE_PERIPHERAL_OK) break; @@ -535,6 +557,16 @@ le_command_status_t le_central_discover_characteristics_for_service_by_uuid128(l return le_central_discover_characteristics_for_handle_range_by_uuid128(peripheral, service->start_group_handle, service->end_group_handle, uuid128); } +le_command_status_t le_central_discover_characteristic_descriptors(le_peripheral_t *peripheral, le_characteristic_t *characteristic){ + if (peripheral->state != P_CONNECTED) return BLE_PERIPHERAL_IN_WRONG_STATE; + peripheral->start_group_handle = characteristic->value_handle + 1; + peripheral->end_group_handle = characteristic->end_handle; + + peripheral->state = P_W2_SEND_CHARACTERISTIC_DESCRIPTOR_QUERY; + + gatt_client_run(); + return BLE_PERIPHERAL_OK; +} void test_client(); @@ -839,6 +871,9 @@ static inline void trigger_next_characteristic_by_uuid_query(le_peripheral_t * p trigger_next_query(peripheral, last_result_handle, P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY, GATT_CHARACTERISTIC_QUERY_COMPLETE); } +static inline void trigger_next_characteristic_descriptor_query(le_peripheral_t * peripheral, uint16_t last_result_handle){ + trigger_next_query(peripheral, last_result_handle, P_W2_SEND_CHARACTERISTIC_DESCRIPTOR_QUERY, GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_COMPLETE); +} static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ if (packet_type != ATT_DATA_PACKET) return; @@ -918,7 +953,6 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa break; case ATT_FIND_BY_TYPE_VALUE_RESPONSE: { - printf("ATT_FIND_BY_TYPE_VALUE_RESPONSE \n"); uint8_t pair_size = 4; le_service_t service; le_service_event_t event; @@ -937,6 +971,27 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa trigger_next_service_by_uuid_query(peripheral, service.end_group_handle); break; } + case ATT_FIND_INFORMATION_REPLY: + { + uint8_t pair_size = 4; + le_characteristic_descriptor_t descriptor; + le_characteristic_descriptor_event_t event; + event.type = GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT; + + int i; + for (i = 1; istate); switch (packet[4]){ @@ -955,15 +1010,20 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa send_gatt_complete_event(peripheral, GATT_CHARACTERISTIC_QUERY_COMPLETE, 0); break; + case P_W4_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT: + peripheral->state = P_CONNECTED; + + break; case P_W4_INCLUDED_SERVICE_QUERY_RESULT: peripheral->state = P_CONNECTED; - send_gatt_complete_event(peripheral, GATT_INCLUDED_SERVICE_QUERY_COMPLETE, 0); + send_gatt_complete_event(peripheral, GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_COMPLETE, 0); break; default: printf("ATT_ERROR_ATTRIBUTE_NOT_FOUND in 0x%02x\n", peripheral->state); return; } + break; } default: diff --git a/example/libusb/ble_client.h b/example/libusb/ble_client.h index 756fcfb0f..a5fbbe293 100644 --- a/example/libusb/ble_client.h +++ b/example/libusb/ble_client.h @@ -85,6 +85,8 @@ typedef enum { P_W4_CHARACTERISTIC_QUERY_RESULT, P_W2_SEND_CHARACTERISTIC_WITH_UUID_QUERY, P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT, + P_W2_SEND_CHARACTERISTIC_DESCRIPTOR_QUERY, + P_W4_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, P_W2_SEND_INCLUDED_SERVICE_QUERY, P_W4_INCLUDED_SERVICE_QUERY_RESULT, @@ -166,6 +168,18 @@ typedef struct le_characteristic_event{ le_characteristic_t characteristic; } le_characteristic_event_t; +typedef struct le_characteristic_descriptor{ + uint16_t handle; + uint16_t uuid16; +} le_characteristic_descriptor_t; + + +typedef struct le_characteristic_descriptor_event{ + uint8_t type; + le_characteristic_descriptor_t characteristic_descriptor; +} le_characteristic_descriptor_event_t; + + void le_central_init(); void le_central_register_handler(void (*le_callback)(le_central_event_t * event)); @@ -206,6 +220,7 @@ le_command_status_t le_central_discover_characteristics_in_handle_range_by_uuid1 le_command_status_t le_central_discover_characteristics_for_service_by_uuid16 (le_peripheral_t *context, le_service_t *service, uint16_t uuid16); le_command_status_t le_central_discover_characteristics_for_service_by_uuid128(le_peripheral_t *context, le_service_t *service, uint8_t * uuid128); +le_command_status_t le_central_discover_characteristic_descriptors(le_peripheral_t *context, le_characteristic_t *characteristic); le_command_status_t le_central_read_value_of_characteristic(le_peripheral_t *context, uint16_t characteristic_handle); diff --git a/include/btstack/hci_cmds.h b/include/btstack/hci_cmds.h index 92db52448..241f065da 100644 --- a/include/btstack/hci_cmds.h +++ b/include/btstack/hci_cmds.h @@ -230,6 +230,8 @@ extern "C" { #define GATT_CHARACTERISTIC_QUERY_COMPLETE 0xA5 #define GATT_INCLUDED_SERVICE_QUERY_RESULT 0xA6 #define GATT_INCLUDED_SERVICE_QUERY_COMPLETE 0xA7 +#define GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT 0xA8 +#define GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_COMPLETE 0xA9 // data: event(8), len(8), status (8), hci_handle (16), attribute_handle (16) #define ATT_HANDLE_VALUE_INDICATION_COMPLETE 0xAF