add gatt_client_read_value_of_characteristics_by_uuid16/128

This commit is contained in:
Matthias Ringwald 2015-10-02 12:20:53 +02:00
parent b0beacba68
commit 3f4e6e214e
2 changed files with 102 additions and 7 deletions

View File

@ -253,17 +253,29 @@ static void att_find_by_type_value_request(uint16_t request_type, uint16_t attri
}
// precondition: can_send_packet_now == TRUE
static void att_read_by_type_or_group_request(uint16_t request_type, uint16_t attribute_group_type, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){
static void att_read_by_type_or_group_request_for_uuid16(uint16_t request_type, uint16_t uuid16, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){
l2cap_reserve_packet_buffer();
uint8_t * request = l2cap_get_outgoing_buffer();
request[0] = request_type;
bt_store_16(request, 1, start_handle);
bt_store_16(request, 3, end_handle);
bt_store_16(request, 5, attribute_group_type);
bt_store_16(request, 5, uuid16);
l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 7);
}
// precondition: can_send_packet_now == TRUE
static void att_read_by_type_or_group_request_for_uuid128(uint16_t request_type, uint8_t * uuid128, uint16_t peripheral_handle, uint16_t start_handle, uint16_t end_handle){
l2cap_reserve_packet_buffer();
uint8_t * request = l2cap_get_outgoing_buffer();
request[0] = request_type;
bt_store_16(request, 1, start_handle);
bt_store_16(request, 3, end_handle);
swap128(uuid128, &request[5]);
l2cap_send_prepared_connectionless(peripheral_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, 21);
}
// precondition: can_send_packet_now == TRUE
static void att_read_request(uint16_t request_type, uint16_t peripheral_handle, uint16_t attribute_handle){
l2cap_reserve_packet_buffer();
@ -351,7 +363,7 @@ static uint16_t write_blob_length(gatt_client_t * peripheral){
}
static void send_gatt_services_request(gatt_client_t *peripheral){
att_read_by_type_or_group_request(ATT_READ_BY_GROUP_TYPE_REQUEST, GATT_PRIMARY_SERVICE_UUID, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_GROUP_TYPE_REQUEST, GATT_PRIMARY_SERVICE_UUID, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
}
static void send_gatt_by_uuid_request(gatt_client_t *peripheral, uint16_t attribute_group_type){
@ -375,11 +387,11 @@ static void send_gatt_included_service_uuid_request(gatt_client_t *peripheral){
}
static void send_gatt_included_service_request(gatt_client_t *peripheral){
att_read_by_type_or_group_request(ATT_READ_BY_TYPE_REQUEST, GATT_INCLUDE_SERVICE_UUID, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_INCLUDE_SERVICE_UUID, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
}
static void send_gatt_characteristic_request(gatt_client_t *peripheral){
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);
att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_CHARACTERISTICS_UUID, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
}
static void send_gatt_characteristic_descriptor_request(gatt_client_t *peripheral){
@ -390,6 +402,14 @@ static void send_gatt_read_characteristic_value_request(gatt_client_t *periphera
att_read_request(ATT_READ_REQUEST, peripheral->handle, peripheral->attribute_handle);
}
static void send_gatt_read_by_type_request(gatt_client_t * peripheral){
if (peripheral->uuid16){
att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, peripheral->uuid16, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
} else {
att_read_by_type_or_group_request_for_uuid128(ATT_READ_BY_TYPE_REQUEST, peripheral->uuid128, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
}
}
static void send_gatt_read_blob_request(gatt_client_t *peripheral){
att_read_blob_request(ATT_READ_BLOB_REQUEST, peripheral->handle, peripheral->attribute_handle, peripheral->attribute_offset);
}
@ -415,7 +435,7 @@ static void send_gatt_cancel_prepared_write_request(gatt_client_t * peripheral){
}
static void send_gatt_read_client_characteristic_configuration_request(gatt_client_t * peripheral){
att_read_by_type_or_group_request(ATT_READ_BY_TYPE_REQUEST, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
att_read_by_type_or_group_request_for_uuid16(ATT_READ_BY_TYPE_REQUEST, GATT_CLIENT_CHARACTERISTICS_CONFIGURATION, peripheral->handle, peripheral->start_group_handle, peripheral->end_group_handle);
}
static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * peripheral){
@ -547,7 +567,6 @@ static void report_gatt_characteristics(gatt_client_t * peripheral, uint8_t * pa
}
}
static void report_gatt_included_service(gatt_client_t * peripheral, uint8_t *uuid128, uint16_t uuid16){
le_service_t service;
service.uuid16 = uuid16;
@ -668,6 +687,10 @@ static inline void trigger_next_characteristic_descriptor_query(gatt_client_t *
trigger_next_query(peripheral, last_result_handle, P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY);
}
static inline void trigger_next_read_by_type_query(gatt_client_t * peripheral, uint16_t last_result_handle){
trigger_next_query(peripheral, last_result_handle, P_W2_SEND_READ_BY_TYPE_REQUEST);
}
static inline void trigger_next_prepare_write_query(gatt_client_t * peripheral, gatt_client_state_t next_query_state, gatt_client_state_t done_state){
peripheral->attribute_offset += write_blob_length(peripheral);
uint16_t next_blob_length = write_blob_length(peripheral);
@ -692,6 +715,7 @@ static inline void trigger_next_blob_query(gatt_client_t * peripheral, gatt_clie
peripheral->gatt_client_state = next_query_state;
}
static int is_value_valid(gatt_client_t *peripheral, uint8_t *packet, uint16_t size){
uint16_t attribute_handle = READ_BT_16(packet, 1);
uint16_t value_offset = READ_BT_16(packet, 3);
@ -791,6 +815,11 @@ static void gatt_client_run(void){
send_gatt_read_blob_request(peripheral);
return;
case P_W2_SEND_READ_BY_TYPE_REQUEST:
peripheral->gatt_client_state = P_W4_READ_BY_TYPE_RESPONSE;
send_gatt_read_by_type_request(peripheral);
break;
case P_W2_SEND_WRITE_CHARACTERISTIC_VALUE:
peripheral->gatt_client_state = P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT;
send_gatt_write_attribute_value_request(peripheral);
@ -1006,6 +1035,18 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
peripheral->client_characteristic_configuration_handle = READ_BT_16(packet, 2);
peripheral->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
break;
case P_W4_READ_BY_TYPE_RESPONSE: {
uint16_t pair_size = packet[1];
uint16_t offset;
uint16_t last_result_handle = 0;
for (offset = 2; offset < size ; offset += pair_size){
uint16_t value_handle = READ_BT_16(packet, offset);
report_gatt_characteristic_value(peripheral, value_handle, &packet[offset+2], pair_size-2);
last_result_handle = value_handle;
}
trigger_next_read_by_type_query(peripheral, last_result_handle);
break;
}
default:
break;
}
@ -1180,6 +1221,14 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
gatt_client_handle_transaction_complete(peripheral);
emit_gatt_complete_event(peripheral, 0);
break;
case P_W4_READ_BY_TYPE_RESPONSE:
gatt_client_handle_transaction_complete(peripheral);
if (peripheral->start_group_handle == peripheral->query_start_handle){
emit_gatt_complete_event(peripheral, ATT_ERROR_ATTRIBUTE_NOT_FOUND);
} else {
emit_gatt_complete_event(peripheral, 0);
}
break;
default:
gatt_client_report_error_if_pending(peripheral, packet[4]);
break;
@ -1388,6 +1437,43 @@ le_command_status_t gatt_client_read_value_of_characteristic_using_value_handle(
return BLE_PERIPHERAL_OK;
}
le_command_status_t gatt_client_read_value_of_characteristics_by_uuid16(uint16_t gatt_client_id, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16){
gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
if (!peripheral) return (le_command_status_t) BTSTACK_MEMORY_ALLOC_FAILED;
if (!is_ready(peripheral)) return BLE_PERIPHERAL_IN_WRONG_STATE;
peripheral->subclient_id = gatt_client_id;
peripheral->start_group_handle = start_handle;
peripheral->end_group_handle = end_handle;
peripheral->query_start_handle = start_handle;
peripheral->query_end_handle = end_handle;
peripheral->uuid16 = uuid16;
sdp_normalize_uuid((uint8_t*) &(peripheral->uuid128), uuid16);
peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
gatt_client_run();
return BLE_PERIPHERAL_OK;
}
le_command_status_t gatt_client_read_value_of_characteristics_by_uuid128(uint16_t gatt_client_id, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle, uint8_t * uuid128){
gatt_client_t * peripheral = provide_context_for_conn_handle_and_start_timer(con_handle);
if (!peripheral) return (le_command_status_t) BTSTACK_MEMORY_ALLOC_FAILED;
if (!is_ready(peripheral)) return BLE_PERIPHERAL_IN_WRONG_STATE;
peripheral->subclient_id = gatt_client_id;
peripheral->start_group_handle = start_handle;
peripheral->end_group_handle = end_handle;
peripheral->query_start_handle = start_handle;
peripheral->query_end_handle = end_handle;
peripheral->uuid16 = 0;
memcpy(peripheral->uuid128, uuid128, 16);
peripheral->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
gatt_client_run();
return BLE_PERIPHERAL_OK;
}
le_command_status_t gatt_client_read_value_of_characteristic(uint16_t gatt_client_id, uint16_t handle, le_characteristic_t *characteristic){
return gatt_client_read_value_of_characteristic_using_value_handle(gatt_client_id, handle, characteristic->value_handle);
}

View File

@ -77,6 +77,9 @@ typedef enum {
P_W2_SEND_READ_BLOB_QUERY,
P_W4_READ_BLOB_RESULT,
P_W2_SEND_READ_BY_TYPE_REQUEST,
P_W4_READ_BY_TYPE_RESPONSE,
P_W2_SEND_WRITE_CHARACTERISTIC_VALUE,
P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT,
@ -299,6 +302,12 @@ le_command_status_t gatt_client_discover_characteristic_descriptors(uint16_t gat
le_command_status_t gatt_client_read_value_of_characteristic(uint16_t gatt_client_id, uint16_t con_handle, le_characteristic_t *characteristic);
le_command_status_t gatt_client_read_value_of_characteristic_using_value_handle(uint16_t gatt_client_id, uint16_t con_handle, uint16_t characteristic_value_handle);
/**
* @brief Reads the characteric value of all characteristics with the uuid. For each found, an le_characteristic_value_event_t with type set to GATT_CHARACTERISTIC_VALUE_QUERY_RESULT will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_QUERY_COMPLETE, marks the end of read.
*/
le_command_status_t gatt_client_read_value_of_characteristics_by_uuid16(uint16_t gatt_client_id, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16);
le_command_status_t gatt_client_read_value_of_characteristics_by_uuid128(uint16_t gatt_client_id, uint16_t con_handle, uint16_t start_handle, uint16_t end_handle, uint8_t * uuid128);
/**
* @brief Reads the long characteristic value using the characteristic's value handle. The value will be returned in several blobs. For each blob, an le_characteristic_value_event_t with type set to GATT_CHARACTERISTIC_VALUE_QUERY_RESULT and updated value offset will be generated and passed to the registered callback. The gatt_complete_event_t with type set to GATT_QUERY_COMPLETE, mark the end of read.
*/