diff --git a/src/ble/gatt_client.c b/src/ble/gatt_client.c index 2c8db4ada..f41f26418 100644 --- a/src/ble/gatt_client.c +++ b/src/ble/gatt_client.c @@ -479,17 +479,23 @@ static void send_gatt_signed_write_request(gatt_client_t * gatt_client, uint32_t #endif static uint16_t get_last_result_handle_from_service_list(uint8_t * packet, uint16_t size){ + if (size < 2) return 0xffff; uint8_t attr_length = packet[1]; + if ((2 + attr_length) > size) return 0xffff; return little_endian_read_16(packet, size - attr_length + 2u); } static uint16_t get_last_result_handle_from_characteristics_list(uint8_t * packet, uint16_t size){ + if (size < 2) return 0xffff; uint8_t attr_length = packet[1]; + if ((2 + attr_length) > size) return 0xffff; return little_endian_read_16(packet, size - attr_length + 3u); } static uint16_t get_last_result_handle_from_included_services_list(uint8_t * packet, uint16_t size){ + if (size < 2) return 0xffff; uint8_t attr_length = packet[1]; + if ((2 + attr_length) > size) return 0xffff; return little_endian_read_16(packet, size - attr_length); } @@ -609,11 +615,12 @@ static void emit_gatt_mtu_exchanged_result_event(gatt_client_t * gatt_client, ui } /// static void report_gatt_services(gatt_client_t * gatt_client, uint8_t * packet, uint16_t size){ + if (size < 2) return; uint8_t attr_length = packet[1]; uint8_t uuid_length = attr_length - 4u; int i; - for (i = 2; i < size; i += attr_length){ + for (i = 2; (i+attr_length) <= size; i += attr_length){ uint16_t start_group_handle = little_endian_read_16(packet,i); uint16_t end_group_handle = little_endian_read_16(packet,i+2); uint8_t uuid128[16]; @@ -622,8 +629,10 @@ static void report_gatt_services(gatt_client_t * gatt_client, uint8_t * packet, if (uuid_length == 2u){ uuid16 = little_endian_read_16(packet, i+4); uuid_add_bluetooth_prefix((uint8_t*) &uuid128, uuid16); - } else { + } else if (uuid_length == 16u) { reverse_128(&packet[i+4], uuid128); + } else { + return; } emit_gatt_service_query_result_event(gatt_client, start_group_handle, end_group_handle, uuid128); } @@ -1410,12 +1419,15 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, #endif 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 = little_endian_read_16(packet, offset); - report_gatt_characteristic_value(gatt_client, value_handle, &packet[offset + 2u], pair_size - 2u); - last_result_handle = value_handle; + // set last result handle to last valid handle, only used if pair_size invalid + uint16_t last_result_handle = 0xffff; + if (pair_size > 2){ + uint16_t offset; + 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); + last_result_handle = value_handle; + } } trigger_next_read_by_type_query(gatt_client, last_result_handle); break; @@ -1427,9 +1439,11 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, case ATT_READ_RESPONSE: switch (gatt_client->gatt_client_state){ case P_W4_INCLUDED_SERVICE_UUID_WITH_QUERY_RESULT: { - uint8_t uuid128[16]; - reverse_128(&packet[1], uuid128); - report_gatt_included_service_uuid128(gatt_client, gatt_client->start_group_handle, uuid128); + 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); + } trigger_next_included_service_query(gatt_client, gatt_client->start_group_handle); // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done break;