From 6c55686a8741a472f4ebd12a1734cc26bcaf15cf Mon Sep 17 00:00:00 2001 From: "mila@ringwald.ch" Date: Fri, 21 Mar 2014 23:20:12 +0000 Subject: [PATCH] ble client: implemented notifications and indications --- example/libusb/ble_client.c | 57 ++++++++++++++++++++++++++++--------- example/libusb/ble_client.h | 2 ++ include/btstack/hci_cmds.h | 3 +- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/example/libusb/ble_client.c b/example/libusb/ble_client.c index efc1abb2f..964f2028c 100644 --- a/example/libusb/ble_client.c +++ b/example/libusb/ble_client.c @@ -121,6 +121,15 @@ static uint16_t l2cap_max_mtu_for_handle(uint16_t handle){ // END Helper Functions + +static le_command_status_t att_confirmation(uint16_t peripheral_handle){ + if (!l2cap_can_send_conectionless_packet_now()) return BLE_PERIPHERAL_BUSY; + uint8_t request[1]; + request[0] = ATT_HANDLE_VALUE_CONFIRMATION; + l2cap_send_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, request, sizeof(request)); + return BLE_PERIPHERAL_OK; +} + 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; @@ -396,6 +405,13 @@ static void handle_peripheral_list(){ for (it = (linked_item_t *) le_connections; it ; it = it->next){ le_peripheral_t * peripheral = (le_peripheral_t *) it; // printf("handle_peripheral_list, status %u\n", peripheral->state); + + if (peripheral->send_confirmation){ + peripheral->send_confirmation = 0; + att_confirmation(peripheral->handle); + return; + } + switch (peripheral->state){ case P_W2_CONNECT: peripheral->state = P_W4_CONNECTED; @@ -1047,23 +1063,31 @@ static void report_gatt_included_service(le_peripheral_t * peripheral, uint8_t * (*le_central_callback)((le_central_event_t*)&event); } -static void report_gatt_long_characteristic_value_blob(le_peripheral_t * peripheral, uint8_t * value, int blob_length, int value_offset){ +static void send_characteristic_value_event(le_peripheral_t * peripheral, uint16_t handle, uint8_t * value, uint16_t length, uint16_t offset, uint8_t event_type){ le_characteristic_value_event_t event; - event.type = GATT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT; - event.characteristic_value_blob_length = blob_length; - event.characteristic_value_offset = value_offset; - event.characteristic_value = value; - (*le_central_callback)((le_central_event_t*)&event); -} - -static void report_gatt_characteristic_value(le_peripheral_t * peripheral, uint8_t * value, int length){ - le_characteristic_value_event_t event; - event.type = GATT_CHARACTERISTIC_VALUE_QUERY_RESULT; + event.type = event_type; + event.characteristic_value_handle = handle; event.characteristic_value_blob_length = length; event.characteristic_value = value; + event.characteristic_value_offset = offset; (*le_central_callback)((le_central_event_t*)&event); } +static void report_gatt_long_characteristic_value_blob(le_peripheral_t * peripheral, uint8_t * value, uint16_t blob_length, int value_offset){ + send_characteristic_value_event(peripheral, peripheral->characteristic_value_handle, value, blob_length, value_offset, GATT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT); +} + +static void report_gatt_notification(le_peripheral_t * peripheral, uint16_t handle, uint8_t * value, int length){ + send_characteristic_value_event(peripheral, handle, value, length, 0, GATT_NOTIFICATION); +} + +static void report_gatt_indication(le_peripheral_t * peripheral, uint16_t handle, uint8_t * value, int length){ + send_characteristic_value_event(peripheral, handle, value, length, 0, GATT_INDICATION); +} + +static void report_gatt_characteristic_value(le_peripheral_t * peripheral, uint16_t handle, uint8_t * value, int length){ + send_characteristic_value_event(peripheral, handle, value, length, 0, GATT_CHARACTERISTIC_VALUE_QUERY_RESULT); +} static void trigger_next_query(le_peripheral_t * peripheral, uint16_t last_result_handle, peripheral_state_t next_query_state, uint8_t complete_event_type){ if (last_result_handle < peripheral->end_group_handle){ @@ -1146,7 +1170,14 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa printf("ATT_READ_BY_GROUP_TYPE_RESPONSE"); break; } - + break; + case ATT_HANDLE_VALUE_NOTIFICATION: + report_gatt_notification(peripheral, READ_BT_16(packet,1), &packet[3], size-3); + break; + + case ATT_HANDLE_VALUE_INDICATION: + report_gatt_indication(peripheral, READ_BT_16(packet,1), &packet[3], size-3); + peripheral->send_confirmation = 1; break; case ATT_READ_BY_TYPE_RESPONSE: @@ -1201,7 +1232,7 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa } case P_W4_READ_CHARACTERISTIC_VALUE_RESULT: peripheral->state = P_CONNECTED; - report_gatt_characteristic_value(peripheral, &packet[1], size-1); + report_gatt_characteristic_value(peripheral, peripheral->characteristic_value_handle, &packet[1], size-1); break; default: break; diff --git a/example/libusb/ble_client.h b/example/libusb/ble_client.h index a6566053b..d5157c32e 100644 --- a/example/libusb/ble_client.h +++ b/example/libusb/ble_client.h @@ -155,6 +155,7 @@ typedef struct le_peripheral{ uint8_t* characteristic_value; uint8_t filter_with_uuid; + uint8_t send_confirmation; } le_peripheral_t; @@ -207,6 +208,7 @@ typedef struct le_characteristic_value{ typedef struct le_characteristic_value_event{ uint8_t type; + uint16_t characteristic_value_handle; uint16_t characteristic_value_blob_length; uint16_t characteristic_value_offset; uint8_t * characteristic_value; diff --git a/include/btstack/hci_cmds.h b/include/btstack/hci_cmds.h index d7b7a5347..87d7dda1d 100644 --- a/include/btstack/hci_cmds.h +++ b/include/btstack/hci_cmds.h @@ -238,7 +238,8 @@ extern "C" { #define GATT_CHARACTERISTIC_VALUE_WRITE_RESPONSE 0xAD #define GATT_LONG_CHARACTERISTIC_VALUE_WRITE_RESPONSE 0xAE #define GATT_LONG_CHARACTERISTIC_VALUE_WRITE_COMPLETE 0xAF - +#define GATT_NOTIFICATION 0xBC +#define GATT_INDICATION 0xBD // data: event(8), len(8), status (8), hci_handle (16), attribute_handle (16) #define ATT_HANDLE_VALUE_INDICATION_COMPLETE 0xBF