mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-03 16:14:11 +00:00
gatt_client: extract gatt_client_handle_att_response
This commit is contained in:
parent
0fde3c5edb
commit
cf8e571806
@ -1380,47 +1380,10 @@ static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t chann
|
||||
gatt_client_run();
|
||||
}
|
||||
|
||||
static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
|
||||
gatt_client_t * gatt_client;
|
||||
if (size < 1u) return;
|
||||
|
||||
if (packet_type == HCI_EVENT_PACKET) {
|
||||
switch (packet[0]){
|
||||
case L2CAP_EVENT_CAN_SEND_NOW:
|
||||
gatt_client_run();
|
||||
break;
|
||||
// att_server has negotiated the mtu for this connection, cache if context exists
|
||||
case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
|
||||
if (size < 6u) break;
|
||||
gatt_client = gatt_client_get_context_for_handle(handle);
|
||||
if (gatt_client == NULL) break;
|
||||
gatt_client->mtu = little_endian_read_16(packet, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet_type != ATT_DATA_PACKET) return;
|
||||
|
||||
// special cases: notifications & indications motivate creating context
|
||||
switch (packet[0]){
|
||||
case ATT_HANDLE_VALUE_NOTIFICATION:
|
||||
case ATT_HANDLE_VALUE_INDICATION:
|
||||
gatt_client_provide_context_for_handle(handle, &gatt_client);
|
||||
break;
|
||||
default:
|
||||
gatt_client = gatt_client_get_context_for_handle(handle);
|
||||
break;
|
||||
}
|
||||
|
||||
if (gatt_client == NULL) return;
|
||||
|
||||
static void gatt_client_handle_att_response(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size) {
|
||||
uint8_t error_code;
|
||||
switch (packet[0]){
|
||||
case ATT_EXCHANGE_MTU_RESPONSE:
|
||||
{
|
||||
switch (packet[0]) {
|
||||
case ATT_EXCHANGE_MTU_RESPONSE: {
|
||||
if (size < 3u) break;
|
||||
uint16_t remote_rx_mtu = little_endian_read_16(packet, 1);
|
||||
uint16_t local_rx_mtu = l2cap_max_le_mtu();
|
||||
@ -1430,8 +1393,8 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
gatt_client->mtu = mtu;
|
||||
gatt_client->mtu_state = MTU_EXCHANGED;
|
||||
|
||||
// set per connection mtu state
|
||||
hci_connection_t * hci_connection = hci_connection_for_handle(handle);
|
||||
// set per connection mtu state - for fixed channel
|
||||
hci_connection_t *hci_connection = hci_connection_for_handle(gatt_client->con_handle);
|
||||
hci_connection->att_connection.mtu = gatt_client->mtu;
|
||||
hci_connection->att_connection.mtu_exchanged = true;
|
||||
|
||||
@ -1439,7 +1402,7 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
}
|
||||
case ATT_READ_BY_GROUP_TYPE_RESPONSE:
|
||||
switch(gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_SERVICE_QUERY_RESULT:
|
||||
report_gatt_services(gatt_client, packet, size);
|
||||
trigger_next_service_query(gatt_client, get_last_result_handle_from_service_list(packet, size));
|
||||
@ -1458,26 +1421,27 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
report_gatt_indication(gatt_client, little_endian_read_16(packet, 1u), &packet[3], size - 3u);
|
||||
gatt_client->send_confirmation = 1;
|
||||
break;
|
||||
|
||||
|
||||
case ATT_READ_BY_TYPE_RESPONSE:
|
||||
switch (gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT:
|
||||
report_gatt_characteristics(gatt_client, packet, size);
|
||||
trigger_next_characteristic_query(gatt_client, get_last_result_handle_from_characteristics_list(packet, size));
|
||||
trigger_next_characteristic_query(gatt_client,
|
||||
get_last_result_handle_from_characteristics_list(packet, size));
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
|
||||
break;
|
||||
case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT:
|
||||
report_gatt_characteristics(gatt_client, packet, size);
|
||||
trigger_next_characteristic_query(gatt_client, get_last_result_handle_from_characteristics_list(packet, size));
|
||||
trigger_next_characteristic_query(gatt_client,
|
||||
get_last_result_handle_from_characteristics_list(packet, size));
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR
|
||||
break;
|
||||
case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
|
||||
{
|
||||
case P_W4_INCLUDED_SERVICE_QUERY_RESULT: {
|
||||
if (size < 2u) break;
|
||||
uint16_t uuid16 = 0;
|
||||
uint16_t pair_size = packet[1];
|
||||
|
||||
if (pair_size == 6u){
|
||||
|
||||
if (pair_size == 6u) {
|
||||
if (size < 8u) break;
|
||||
// UUIDs not available, query first included service
|
||||
gatt_client->start_group_handle = little_endian_read_16(packet, 2); // ready for next query
|
||||
@ -1491,15 +1455,17 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
|
||||
// UUIDs included, report all of them
|
||||
uint16_t offset;
|
||||
for (offset = 2u; (offset + 8u) <= size; offset += pair_size){
|
||||
for (offset = 2u; (offset + 8u) <= size; offset += pair_size) {
|
||||
uint16_t include_handle = little_endian_read_16(packet, offset);
|
||||
gatt_client->query_start_handle = little_endian_read_16(packet, offset + 2u);
|
||||
gatt_client->query_end_handle = little_endian_read_16(packet, offset + 4u);
|
||||
uuid16 = little_endian_read_16(packet, offset+6u);
|
||||
uuid16 = little_endian_read_16(packet, offset + 6u);
|
||||
report_gatt_included_service_uuid16(gatt_client, include_handle, uuid16);
|
||||
}
|
||||
|
||||
trigger_next_included_service_query(gatt_client, get_last_result_handle_from_included_services_list(packet, size));
|
||||
trigger_next_included_service_query(gatt_client,
|
||||
get_last_result_handle_from_included_services_list(packet,
|
||||
size));
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
}
|
||||
@ -1513,11 +1479,12 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
uint16_t pair_size = packet[1];
|
||||
// set last result handle to last valid handle, only used if pair_size invalid
|
||||
uint16_t last_result_handle = 0xffff;
|
||||
if (pair_size > 2){
|
||||
if (pair_size > 2) {
|
||||
uint16_t offset;
|
||||
for (offset = 2; offset < size ; offset += pair_size){
|
||||
for (offset = 2; offset < size; offset += pair_size) {
|
||||
uint16_t value_handle = little_endian_read_16(packet, offset);
|
||||
report_gatt_characteristic_value(gatt_client, value_handle, &packet[offset + 2u], pair_size - 2u);
|
||||
report_gatt_characteristic_value(gatt_client, value_handle, &packet[offset + 2u],
|
||||
pair_size - 2u);
|
||||
last_result_handle = value_handle;
|
||||
}
|
||||
}
|
||||
@ -1529,9 +1496,9 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
}
|
||||
break;
|
||||
case ATT_READ_RESPONSE:
|
||||
switch (gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT:
|
||||
if (size >= 17){
|
||||
if (size >= 17) {
|
||||
uint8_t uuid128[16];
|
||||
reverse_128(&packet[1], uuid128);
|
||||
report_gatt_included_service_uuid128(gatt_client, gatt_client->start_group_handle, uuid128);
|
||||
@ -1548,21 +1515,25 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
|
||||
case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client_handle_transaction_complete(gatt_client);
|
||||
report_gatt_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u, 0u);
|
||||
report_gatt_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1],
|
||||
size - 1u, 0u);
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
|
||||
break;
|
||||
|
||||
// Use ATT_READ_REQUEST for first blob of Read Long Characteristic
|
||||
// Use ATT_READ_REQUEST for first blob of Read Long Characteristic
|
||||
case P_W4_READ_BLOB_RESULT:
|
||||
report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1], size - 1u, gatt_client->attribute_offset);
|
||||
report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1],
|
||||
size - 1u, gatt_client->attribute_offset);
|
||||
trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, size - 1u);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
|
||||
// Use ATT_READ_REQUEST for first blob of Read Long Characteristic Descriptor
|
||||
// Use ATT_READ_REQUEST for first blob of Read Long Characteristic Descriptor
|
||||
case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1], size-1u, gatt_client->attribute_offset);
|
||||
trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, size-1u);
|
||||
report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle, &packet[1],
|
||||
size - 1u, gatt_client->attribute_offset);
|
||||
trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY,
|
||||
size - 1u);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
|
||||
@ -1570,28 +1541,27 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATT_FIND_BY_TYPE_VALUE_RESPONSE:
|
||||
{
|
||||
|
||||
case ATT_FIND_BY_TYPE_VALUE_RESPONSE: {
|
||||
uint8_t pair_size = 4;
|
||||
int i;
|
||||
uint16_t start_group_handle;
|
||||
uint16_t end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results
|
||||
for (i = 1u; (i + pair_size) <= size; i += pair_size){
|
||||
start_group_handle = little_endian_read_16(packet,i);
|
||||
end_group_handle = little_endian_read_16(packet,i+2);
|
||||
emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle, gatt_client->uuid128);
|
||||
uint16_t end_group_handle = 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results
|
||||
for (i = 1u; (i + pair_size) <= size; i += pair_size) {
|
||||
start_group_handle = little_endian_read_16(packet, i);
|
||||
end_group_handle = little_endian_read_16(packet, i + 2);
|
||||
emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle,
|
||||
gatt_client->uuid128);
|
||||
}
|
||||
trigger_next_service_by_uuid_query(gatt_client, end_group_handle);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
}
|
||||
case ATT_FIND_INFORMATION_REPLY:
|
||||
{
|
||||
case ATT_FIND_INFORMATION_REPLY: {
|
||||
if (size < 2u) break;
|
||||
|
||||
uint8_t pair_size = 4;
|
||||
if (packet[1u] == 2u){
|
||||
if (packet[1u] == 2u) {
|
||||
pair_size = 18;
|
||||
}
|
||||
uint16_t offset = 2;
|
||||
@ -1632,7 +1602,7 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
}
|
||||
|
||||
case ATT_WRITE_RESPONSE:
|
||||
switch (gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
|
||||
gatt_client_handle_transaction_complete(gatt_client);
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
|
||||
@ -1649,12 +1619,13 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATT_READ_BLOB_RESPONSE:{
|
||||
uint16_t received_blob_length = size-1u;
|
||||
switch(gatt_client->gatt_client_state){
|
||||
|
||||
case ATT_READ_BLOB_RESPONSE: {
|
||||
uint16_t received_blob_length = size - 1u;
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_READ_BLOB_RESULT:
|
||||
report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1], received_blob_length, gatt_client->attribute_offset);
|
||||
report_gatt_long_characteristic_value_blob(gatt_client, gatt_client->attribute_handle, &packet[1],
|
||||
received_blob_length, gatt_client->attribute_offset);
|
||||
trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_QUERY, received_blob_length);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
@ -1662,7 +1633,8 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
report_gatt_long_characteristic_descriptor(gatt_client, gatt_client->attribute_handle,
|
||||
&packet[1], received_blob_length,
|
||||
gatt_client->attribute_offset);
|
||||
trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, received_blob_length);
|
||||
trigger_next_blob_query(gatt_client, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY,
|
||||
received_blob_length);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
default:
|
||||
@ -1671,32 +1643,34 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
}
|
||||
case ATT_PREPARE_WRITE_RESPONSE:
|
||||
switch (gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_PREPARE_WRITE_SINGLE_RESULT:
|
||||
gatt_client_handle_transaction_complete(gatt_client);
|
||||
if (is_value_valid(gatt_client, packet, size)){
|
||||
if (is_value_valid(gatt_client, packet, size)) {
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
|
||||
} else {
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_DATA_MISMATCH);
|
||||
}
|
||||
break;
|
||||
|
||||
case P_W4_PREPARE_WRITE_RESULT:{
|
||||
case P_W4_PREPARE_WRITE_RESULT: {
|
||||
gatt_client->attribute_offset = little_endian_read_16(packet, 3);
|
||||
trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
}
|
||||
case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:{
|
||||
case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT: {
|
||||
gatt_client->attribute_offset = little_endian_read_16(packet, 3);
|
||||
trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR, P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR);
|
||||
trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR,
|
||||
P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
}
|
||||
case P_W4_PREPARE_RELIABLE_WRITE_RESULT:{
|
||||
if (is_value_valid(gatt_client, packet, size)){
|
||||
case P_W4_PREPARE_RELIABLE_WRITE_RESULT: {
|
||||
if (is_value_valid(gatt_client, packet, size)) {
|
||||
gatt_client->attribute_offset = little_endian_read_16(packet, 3);
|
||||
trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_RELIABLE_WRITE, P_W2_EXECUTE_PREPARED_WRITE);
|
||||
trigger_next_prepare_write_query(gatt_client, P_W2_PREPARE_RELIABLE_WRITE,
|
||||
P_W2_EXECUTE_PREPARED_WRITE);
|
||||
// GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
|
||||
break;
|
||||
}
|
||||
@ -1707,9 +1681,9 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ATT_EXECUTE_WRITE_RESPONSE:
|
||||
switch (gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
|
||||
gatt_client_handle_transaction_complete(gatt_client);
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
|
||||
@ -1728,12 +1702,12 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ATT_READ_MULTIPLE_RESPONSE:
|
||||
switch(gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_READ_MULTIPLE_RESPONSE:
|
||||
report_gatt_characteristic_value(gatt_client, 0u, &packet[1], size - 1u);
|
||||
gatt_client_handle_transaction_complete(gatt_client);
|
||||
@ -1747,9 +1721,9 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
case ATT_ERROR_RESPONSE:
|
||||
if (size < 5u) return;
|
||||
error_code = packet[4];
|
||||
switch (error_code){
|
||||
switch (error_code) {
|
||||
case ATT_ERROR_ATTRIBUTE_NOT_FOUND: {
|
||||
switch(gatt_client->gatt_client_state){
|
||||
switch (gatt_client->gatt_client_state) {
|
||||
case P_W4_SERVICE_QUERY_RESULT:
|
||||
case P_W4_SERVICE_WITH_UUID_RESULT:
|
||||
case P_W4_INCLUDED_SERVICE_QUERY_RESULT:
|
||||
@ -1765,7 +1739,7 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
break;
|
||||
case P_W4_READ_BY_TYPE_RESPONSE:
|
||||
gatt_client_handle_transaction_complete(gatt_client);
|
||||
if (gatt_client->start_group_handle == gatt_client->query_start_handle){
|
||||
if (gatt_client->start_group_handle == gatt_client->query_start_handle) {
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_ATTRIBUTE_NOT_FOUND);
|
||||
} else {
|
||||
emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
|
||||
@ -1780,111 +1754,151 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
|
||||
|
||||
#ifdef ENABLE_GATT_CLIENT_PAIRING
|
||||
|
||||
case ATT_ERROR_INSUFFICIENT_AUTHENTICATION:
|
||||
case ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
|
||||
case ATT_ERROR_INSUFFICIENT_ENCRYPTION: {
|
||||
case ATT_ERROR_INSUFFICIENT_AUTHENTICATION:
|
||||
case ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
|
||||
case ATT_ERROR_INSUFFICIENT_ENCRYPTION: {
|
||||
|
||||
// security too low
|
||||
if (gatt_client->security_counter > 0) {
|
||||
gatt_client_report_error_if_pending(gatt_client, error_code);
|
||||
break;
|
||||
}
|
||||
// start security
|
||||
gatt_client->security_counter++;
|
||||
// security too low
|
||||
if (gatt_client->security_counter > 0) {
|
||||
gatt_client_report_error_if_pending(gatt_client, error_code);
|
||||
break;
|
||||
}
|
||||
// start security
|
||||
gatt_client->security_counter++;
|
||||
|
||||
// setup action
|
||||
int retry = 1;
|
||||
switch (gatt_client->gatt_client_state){
|
||||
case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY ;
|
||||
break;
|
||||
case P_W4_READ_BLOB_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
|
||||
break;
|
||||
case P_W4_READ_BY_TYPE_RESPONSE:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
|
||||
break;
|
||||
case P_W4_READ_MULTIPLE_RESPONSE:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
|
||||
break;
|
||||
case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
|
||||
break;
|
||||
case P_W4_PREPARE_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_WRITE;
|
||||
break;
|
||||
case P_W4_PREPARE_WRITE_SINGLE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
|
||||
break;
|
||||
case P_W4_PREPARE_RELIABLE_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
|
||||
break;
|
||||
case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
|
||||
break;
|
||||
case P_W4_CANCEL_PREPARED_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
|
||||
break;
|
||||
case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
|
||||
break;
|
||||
case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
|
||||
break;
|
||||
case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
|
||||
break;
|
||||
case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
|
||||
break;
|
||||
case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
|
||||
break;
|
||||
case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
|
||||
break;
|
||||
case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR;
|
||||
break;
|
||||
// setup action
|
||||
int retry = 1;
|
||||
switch (gatt_client->gatt_client_state){
|
||||
case P_W4_READ_CHARACTERISTIC_VALUE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_VALUE_QUERY ;
|
||||
break;
|
||||
case P_W4_READ_BLOB_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_QUERY;
|
||||
break;
|
||||
case P_W4_READ_BY_TYPE_RESPONSE:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_BY_TYPE_REQUEST;
|
||||
break;
|
||||
case P_W4_READ_MULTIPLE_RESPONSE:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_MULTIPLE_REQUEST;
|
||||
break;
|
||||
case P_W4_WRITE_CHARACTERISTIC_VALUE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_VALUE;
|
||||
break;
|
||||
case P_W4_PREPARE_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_WRITE;
|
||||
break;
|
||||
case P_W4_PREPARE_WRITE_SINGLE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_SINGLE;
|
||||
break;
|
||||
case P_W4_PREPARE_RELIABLE_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_RELIABLE_WRITE;
|
||||
break;
|
||||
case P_W4_EXECUTE_PREPARED_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE;
|
||||
break;
|
||||
case P_W4_CANCEL_PREPARED_WRITE_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE;
|
||||
break;
|
||||
case P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH;
|
||||
break;
|
||||
case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY;
|
||||
break;
|
||||
case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY;
|
||||
break;
|
||||
case P_W4_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_WRITE_CHARACTERISTIC_DESCRIPTOR;
|
||||
break;
|
||||
case P_W4_CLIENT_CHARACTERISTIC_CONFIGURATION_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
|
||||
break;
|
||||
case P_W4_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_PREPARE_WRITE_CHARACTERISTIC_DESCRIPTOR;
|
||||
break;
|
||||
case P_W4_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR_RESULT:
|
||||
gatt_client->gatt_client_state = P_W2_EXECUTE_PREPARED_WRITE_CHARACTERISTIC_DESCRIPTOR;
|
||||
break;
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
case P_W4_SEND_SINGED_WRITE_DONE:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
|
||||
break;
|
||||
case P_W4_SEND_SINGED_WRITE_DONE:
|
||||
gatt_client->gatt_client_state = P_W2_SEND_SIGNED_WRITE;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log_info("retry not supported for state %x", gatt_client->gatt_client_state);
|
||||
retry = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_info("retry not supported for state %x", gatt_client->gatt_client_state);
|
||||
retry = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!retry) {
|
||||
gatt_client_report_error_if_pending(gatt_client, error_code);
|
||||
if (!retry) {
|
||||
gatt_client_report_error_if_pending(gatt_client, error_code);
|
||||
break;
|
||||
}
|
||||
|
||||
log_info("security error, start pairing");
|
||||
|
||||
// start pairing for higher security level
|
||||
gatt_client->wait_for_authentication_complete = 1;
|
||||
gatt_client->pending_error_code = error_code;
|
||||
sm_request_pairing(gatt_client->con_handle);
|
||||
break;
|
||||
}
|
||||
|
||||
log_info("security error, start pairing");
|
||||
|
||||
// start pairing for higher security level
|
||||
gatt_client->wait_for_authentication_complete = 1;
|
||||
gatt_client->pending_error_code = error_code;
|
||||
sm_request_pairing(gatt_client->con_handle);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// nothing we can do about that
|
||||
// nothing we can do about that
|
||||
case ATT_ERROR_INSUFFICIENT_AUTHORIZATION:
|
||||
default:
|
||||
gatt_client_report_error_if_pending(gatt_client, error_code);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
|
||||
break;
|
||||
}
|
||||
gatt_client_run();
|
||||
}
|
||||
|
||||
static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size) {
|
||||
gatt_client_t *gatt_client;
|
||||
if (size < 1u) return;
|
||||
|
||||
if (packet_type == HCI_EVENT_PACKET) {
|
||||
switch (packet[0]) {
|
||||
case L2CAP_EVENT_CAN_SEND_NOW:
|
||||
gatt_client_run();
|
||||
break;
|
||||
// att_server has negotiated the mtu for this connection, cache if context exists
|
||||
case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
|
||||
if (size < 6u) break;
|
||||
gatt_client = gatt_client_get_context_for_handle(handle);
|
||||
if (gatt_client == NULL) break;
|
||||
gatt_client->mtu = little_endian_read_16(packet, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet_type != ATT_DATA_PACKET) return;
|
||||
|
||||
// special cases: notifications & indications motivate creating context
|
||||
switch (packet[0]) {
|
||||
case ATT_HANDLE_VALUE_NOTIFICATION:
|
||||
case ATT_HANDLE_VALUE_INDICATION:
|
||||
gatt_client_provide_context_for_handle(handle, &gatt_client);
|
||||
break;
|
||||
default:
|
||||
gatt_client = gatt_client_get_context_for_handle(handle);
|
||||
break;
|
||||
}
|
||||
|
||||
if (gatt_client != NULL) {
|
||||
gatt_client_handle_att_response(gatt_client, packet, size);
|
||||
gatt_client_run();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LE_SIGNED_WRITE
|
||||
|
Loading…
x
Reference in New Issue
Block a user