gatt_client.c (b3f03c843f6a029757848cf4db52890477de181b) | gatt_client.c (a6121b51b229b883431c4a1600b0f46db31d32dc) |
---|---|
1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 663 unchanged lines hidden (view full) --- 672 emit_gatt_included_service_query_result_event(peripheral, include_handle, peripheral->query_start_handle, 673 peripheral->query_end_handle, uuid128); 674} 675 676// @returns packet pointer 677// @note assume that value is part of an l2cap buffer - overwrite HCI + L2CAP packet headers 678static const int characteristic_value_event_header_size = 8; 679static uint8_t * setup_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * value, uint16_t length){ | 1/* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright --- 663 unchanged lines hidden (view full) --- 672 emit_gatt_included_service_query_result_event(peripheral, include_handle, peripheral->query_start_handle, 673 peripheral->query_end_handle, uuid128); 674} 675 676// @returns packet pointer 677// @note assume that value is part of an l2cap buffer - overwrite HCI + L2CAP packet headers 678static const int characteristic_value_event_header_size = 8; 679static uint8_t * setup_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * value, uint16_t length){ |
680#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 681 // avoid using pre ATT headers. 682 return NULL; 683#endif |
|
680 // before the value inside the ATT PDU 681 uint8_t * packet = value - characteristic_value_event_header_size; 682 packet[0] = type; 683 packet[1] = characteristic_value_event_header_size - 2 + length; 684 little_endian_store_16(packet, 2, con_handle); 685 little_endian_store_16(packet, 4, attribute_handle); 686 little_endian_store_16(packet, 6, length); 687 return packet; 688} 689 690// @returns packet pointer 691// @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 692static const int long_characteristic_value_event_header_size = 10; 693static uint8_t * setup_long_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * value, uint16_t length){ | 684 // before the value inside the ATT PDU 685 uint8_t * packet = value - characteristic_value_event_header_size; 686 packet[0] = type; 687 packet[1] = characteristic_value_event_header_size - 2 + length; 688 little_endian_store_16(packet, 2, con_handle); 689 little_endian_store_16(packet, 4, attribute_handle); 690 little_endian_store_16(packet, 6, length); 691 return packet; 692} 693 694// @returns packet pointer 695// @note assume that value is part of an l2cap buffer - overwrite parts of the HCI/L2CAP/ATT packet (4/4/3) bytes 696static const int long_characteristic_value_event_header_size = 10; 697static uint8_t * setup_long_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * value, uint16_t length){ |
698#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 699 // avoid using pre ATT headers. 700 return NULL; 701#endif |
|
694#if defined(HCI_INCOMING_PRE_BUFFER_SIZE) && (HCI_INCOMING_PRE_BUFFER_SIZE >= 10 - 8) // L2CAP Header (4) - ACL Header (4) 695 // before the value inside the ATT PDU 696 uint8_t * packet = value - long_characteristic_value_event_header_size; 697 packet[0] = type; 698 packet[1] = long_characteristic_value_event_header_size - 2 + length; 699 little_endian_store_16(packet, 2, con_handle); 700 little_endian_store_16(packet, 4, attribute_handle); 701 little_endian_store_16(packet, 6, offset); --- 40 unchanged lines hidden (view full) --- 742static void report_gatt_long_characteristic_descriptor(gatt_client_t * peripheral, uint16_t descriptor_handle, uint8_t *blob, uint16_t blob_length, uint16_t value_offset){ 743 uint8_t * packet = setup_long_characteristic_value_packet(GATT_EVENT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, peripheral->con_handle, descriptor_handle, value_offset, blob, blob_length); 744 if (!packet) return; 745 emit_event_new(peripheral->callback, packet, blob_length + long_characteristic_value_event_header_size); 746} 747 748static void report_gatt_all_characteristic_descriptors(gatt_client_t * peripheral, uint8_t * packet, uint16_t size, uint16_t pair_size){ 749 int i; | 702#if defined(HCI_INCOMING_PRE_BUFFER_SIZE) && (HCI_INCOMING_PRE_BUFFER_SIZE >= 10 - 8) // L2CAP Header (4) - ACL Header (4) 703 // before the value inside the ATT PDU 704 uint8_t * packet = value - long_characteristic_value_event_header_size; 705 packet[0] = type; 706 packet[1] = long_characteristic_value_event_header_size - 2 + length; 707 little_endian_store_16(packet, 2, con_handle); 708 little_endian_store_16(packet, 4, attribute_handle); 709 little_endian_store_16(packet, 6, offset); --- 40 unchanged lines hidden (view full) --- 750static void report_gatt_long_characteristic_descriptor(gatt_client_t * peripheral, uint16_t descriptor_handle, uint8_t *blob, uint16_t blob_length, uint16_t value_offset){ 751 uint8_t * packet = setup_long_characteristic_value_packet(GATT_EVENT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT, peripheral->con_handle, descriptor_handle, value_offset, blob, blob_length); 752 if (!packet) return; 753 emit_event_new(peripheral->callback, packet, blob_length + long_characteristic_value_event_header_size); 754} 755 756static void report_gatt_all_characteristic_descriptors(gatt_client_t * peripheral, uint8_t * packet, uint16_t size, uint16_t pair_size){ 757 int i; |
750 for (i = 0; i<size; i+=pair_size){ | 758 for (i = 0; (i + pair_size) <= size; i += pair_size){ |
751 uint16_t descriptor_handle = little_endian_read_16(packet,i); 752 uint8_t uuid128[16]; 753 uint16_t uuid16 = 0; 754 if (pair_size == 4){ 755 uuid16 = little_endian_read_16(packet,i+2); 756 uuid_add_bluetooth_prefix(uuid128, uuid16); 757 } else { 758 reverse_128(&packet[i+2], uuid128); --- 394 unchanged lines hidden (view full) --- 1153 default: 1154 break; 1155 } 1156 1157 gatt_client_run(); 1158} 1159 1160static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ | 759 uint16_t descriptor_handle = little_endian_read_16(packet,i); 760 uint8_t uuid128[16]; 761 uint16_t uuid16 = 0; 762 if (pair_size == 4){ 763 uuid16 = little_endian_read_16(packet,i+2); 764 uuid_add_bluetooth_prefix(uuid128, uuid16); 765 } else { 766 reverse_128(&packet[i+2], uuid128); --- 394 unchanged lines hidden (view full) --- 1161 default: 1162 break; 1163 } 1164 1165 gatt_client_run(); 1166} 1167 1168static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ |
1161 | |
1162 gatt_client_t * peripheral; | 1169 gatt_client_t * peripheral; |
1170 if (size < 1) return; |
|
1163 1164 if (packet_type == HCI_EVENT_PACKET) { 1165 switch (packet[0]){ 1166 case L2CAP_EVENT_CAN_SEND_NOW: 1167 gatt_client_run(); 1168 break; 1169 // att_server has negotiated the mtu for this connection, cache if context exists 1170 case ATT_EVENT_MTU_EXCHANGE_COMPLETE: | 1171 1172 if (packet_type == HCI_EVENT_PACKET) { 1173 switch (packet[0]){ 1174 case L2CAP_EVENT_CAN_SEND_NOW: 1175 gatt_client_run(); 1176 break; 1177 // att_server has negotiated the mtu for this connection, cache if context exists 1178 case ATT_EVENT_MTU_EXCHANGE_COMPLETE: |
1179 if (size < 6) break; |
|
1171 peripheral = get_gatt_client_context_for_handle(handle); 1172 if (peripheral == NULL) break; 1173 peripheral->mtu = little_endian_read_16(packet, 4); 1174 break; 1175 default: 1176 break; 1177 } 1178 return; 1179 } 1180 1181 if (packet_type != ATT_DATA_PACKET) return; 1182 1183 // special cases: notifications don't need a context while indications motivate creating one 1184 switch (packet[0]){ 1185 case ATT_HANDLE_VALUE_NOTIFICATION: | 1180 peripheral = get_gatt_client_context_for_handle(handle); 1181 if (peripheral == NULL) break; 1182 peripheral->mtu = little_endian_read_16(packet, 4); 1183 break; 1184 default: 1185 break; 1186 } 1187 return; 1188 } 1189 1190 if (packet_type != ATT_DATA_PACKET) return; 1191 1192 // special cases: notifications don't need a context while indications motivate creating one 1193 switch (packet[0]){ 1194 case ATT_HANDLE_VALUE_NOTIFICATION: |
1195 if (size < 3) return; |
|
1186 report_gatt_notification(handle, little_endian_read_16(packet,1), &packet[3], size-3); 1187 return; 1188 case ATT_HANDLE_VALUE_INDICATION: 1189 peripheral = provide_context_for_conn_handle(handle); 1190 break; 1191 default: 1192 peripheral = get_gatt_client_context_for_handle(handle); 1193 break; 1194 } 1195 1196 if (peripheral == NULL) return; 1197 1198 switch (packet[0]){ 1199 case ATT_EXCHANGE_MTU_RESPONSE: 1200 { | 1196 report_gatt_notification(handle, little_endian_read_16(packet,1), &packet[3], size-3); 1197 return; 1198 case ATT_HANDLE_VALUE_INDICATION: 1199 peripheral = provide_context_for_conn_handle(handle); 1200 break; 1201 default: 1202 peripheral = get_gatt_client_context_for_handle(handle); 1203 break; 1204 } 1205 1206 if (peripheral == NULL) return; 1207 1208 switch (packet[0]){ 1209 case ATT_EXCHANGE_MTU_RESPONSE: 1210 { |
1211 if (size < 3) break; |
|
1201 uint16_t remote_rx_mtu = little_endian_read_16(packet, 1); 1202 uint16_t local_rx_mtu = l2cap_max_le_mtu(); 1203 peripheral->mtu = (remote_rx_mtu < local_rx_mtu) ? remote_rx_mtu : local_rx_mtu; 1204 peripheral->mtu_state = MTU_EXCHANGED; 1205 emit_gatt_mtu_exchanged_result_event(peripheral, peripheral->mtu); 1206 break; 1207 } 1208 case ATT_READ_BY_GROUP_TYPE_RESPONSE: 1209 switch(peripheral->gatt_client_state){ 1210 case P_W4_SERVICE_QUERY_RESULT: 1211 report_gatt_services(peripheral, packet, size); 1212 trigger_next_service_query(peripheral, get_last_result_handle_from_service_list(packet, size)); 1213 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1214 break; 1215 default: 1216 break; 1217 } 1218 break; 1219 case ATT_HANDLE_VALUE_INDICATION: | 1212 uint16_t remote_rx_mtu = little_endian_read_16(packet, 1); 1213 uint16_t local_rx_mtu = l2cap_max_le_mtu(); 1214 peripheral->mtu = (remote_rx_mtu < local_rx_mtu) ? remote_rx_mtu : local_rx_mtu; 1215 peripheral->mtu_state = MTU_EXCHANGED; 1216 emit_gatt_mtu_exchanged_result_event(peripheral, peripheral->mtu); 1217 break; 1218 } 1219 case ATT_READ_BY_GROUP_TYPE_RESPONSE: 1220 switch(peripheral->gatt_client_state){ 1221 case P_W4_SERVICE_QUERY_RESULT: 1222 report_gatt_services(peripheral, packet, size); 1223 trigger_next_service_query(peripheral, get_last_result_handle_from_service_list(packet, size)); 1224 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1225 break; 1226 default: 1227 break; 1228 } 1229 break; 1230 case ATT_HANDLE_VALUE_INDICATION: |
1231 if (size < 3) break; |
|
1220 report_gatt_indication(handle, little_endian_read_16(packet,1), &packet[3], size-3); 1221 peripheral->send_confirmation = 1; 1222 break; 1223 1224 case ATT_READ_BY_TYPE_RESPONSE: 1225 switch (peripheral->gatt_client_state){ 1226 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT: 1227 report_gatt_characteristics(peripheral, packet, size); 1228 trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size)); 1229 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR 1230 break; 1231 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT: 1232 report_gatt_characteristics(peripheral, packet, size); 1233 trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size)); 1234 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR 1235 break; 1236 case P_W4_INCLUDED_SERVICE_QUERY_RESULT: 1237 { | 1232 report_gatt_indication(handle, little_endian_read_16(packet,1), &packet[3], size-3); 1233 peripheral->send_confirmation = 1; 1234 break; 1235 1236 case ATT_READ_BY_TYPE_RESPONSE: 1237 switch (peripheral->gatt_client_state){ 1238 case P_W4_ALL_CHARACTERISTICS_OF_SERVICE_QUERY_RESULT: 1239 report_gatt_characteristics(peripheral, packet, size); 1240 trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size)); 1241 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR 1242 break; 1243 case P_W4_CHARACTERISTIC_WITH_UUID_QUERY_RESULT: 1244 report_gatt_characteristics(peripheral, packet, size); 1245 trigger_next_characteristic_query(peripheral, get_last_result_handle_from_characteristics_list(packet, size)); 1246 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done, or by ATT_ERROR 1247 break; 1248 case P_W4_INCLUDED_SERVICE_QUERY_RESULT: 1249 { |
1250 if (size < 2) break; |
|
1238 uint16_t uuid16 = 0; 1239 uint16_t pair_size = packet[1]; 1240 1241 if (pair_size < 7){ | 1251 uint16_t uuid16 = 0; 1252 uint16_t pair_size = packet[1]; 1253 1254 if (pair_size < 7){ |
1255 if (size < 8) break; |
|
1242 // UUIDs not available, query first included service 1243 peripheral->start_group_handle = little_endian_read_16(packet, 2); // ready for next query 1244 peripheral->query_start_handle = little_endian_read_16(packet, 4); 1245 peripheral->query_end_handle = little_endian_read_16(packet,6); 1246 peripheral->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY; 1247 break; 1248 } 1249 1250 uint16_t offset; | 1256 // UUIDs not available, query first included service 1257 peripheral->start_group_handle = little_endian_read_16(packet, 2); // ready for next query 1258 peripheral->query_start_handle = little_endian_read_16(packet, 4); 1259 peripheral->query_end_handle = little_endian_read_16(packet,6); 1260 peripheral->gatt_client_state = P_W2_SEND_INCLUDED_SERVICE_WITH_UUID_QUERY; 1261 break; 1262 } 1263 1264 uint16_t offset; |
1251 for (offset = 2; offset < size; offset += pair_size){ | 1265 for (offset = 2; (offset + 8) < size; offset += pair_size){ |
1252 uint16_t include_handle = little_endian_read_16(packet, offset); 1253 peripheral->query_start_handle = little_endian_read_16(packet,offset+2); 1254 peripheral->query_end_handle = little_endian_read_16(packet,offset+4); 1255 uuid16 = little_endian_read_16(packet, offset+6); 1256 report_gatt_included_service_uuid16(peripheral, include_handle, uuid16); 1257 } 1258 1259 trigger_next_included_service_query(peripheral, get_last_result_handle_from_included_services_list(packet, size)); --- 50 unchanged lines hidden (view full) --- 1310 break; 1311 1312 case ATT_FIND_BY_TYPE_VALUE_RESPONSE: 1313 { 1314 uint8_t pair_size = 4; 1315 int i; 1316 uint16_t start_group_handle; 1317 uint16_t end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results | 1266 uint16_t include_handle = little_endian_read_16(packet, offset); 1267 peripheral->query_start_handle = little_endian_read_16(packet,offset+2); 1268 peripheral->query_end_handle = little_endian_read_16(packet,offset+4); 1269 uuid16 = little_endian_read_16(packet, offset+6); 1270 report_gatt_included_service_uuid16(peripheral, include_handle, uuid16); 1271 } 1272 1273 trigger_next_included_service_query(peripheral, get_last_result_handle_from_included_services_list(packet, size)); --- 50 unchanged lines hidden (view full) --- 1324 break; 1325 1326 case ATT_FIND_BY_TYPE_VALUE_RESPONSE: 1327 { 1328 uint8_t pair_size = 4; 1329 int i; 1330 uint16_t start_group_handle; 1331 uint16_t end_group_handle= 0xffff; // asserts GATT_EVENT_QUERY_COMPLETE is emitted if no results |
1318 for (i = 1; i<size; i+=pair_size){ | 1332 for (i = 1; (i + pair_size) <= size; i += pair_size){ |
1319 start_group_handle = little_endian_read_16(packet,i); 1320 end_group_handle = little_endian_read_16(packet,i+2); 1321 emit_gatt_service_query_result_event(peripheral, start_group_handle, end_group_handle, peripheral->uuid128); 1322 } 1323 trigger_next_service_by_uuid_query(peripheral, end_group_handle); 1324 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1325 break; 1326 } 1327 case ATT_FIND_INFORMATION_REPLY: 1328 { | 1333 start_group_handle = little_endian_read_16(packet,i); 1334 end_group_handle = little_endian_read_16(packet,i+2); 1335 emit_gatt_service_query_result_event(peripheral, start_group_handle, end_group_handle, peripheral->uuid128); 1336 } 1337 trigger_next_service_by_uuid_query(peripheral, end_group_handle); 1338 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done 1339 break; 1340 } 1341 case ATT_FIND_INFORMATION_REPLY: 1342 { |
1343 if (size < 2) break; 1344 |
|
1329 uint8_t pair_size = 4; 1330 if (packet[1] == 2){ 1331 pair_size = 18; 1332 } | 1345 uint8_t pair_size = 4; 1346 if (packet[1] == 2){ 1347 pair_size = 18; 1348 } |
1349 uint16_t offset = 2; 1350 1351 if (size < (pair_size + offset)) break; |
|
1333 uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size); 1334 1335#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1336 log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", peripheral->gatt_client_state); 1337 if (peripheral->gatt_client_state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){ 1338 // iterate over descriptors looking for CCC 1339 if (pair_size == 4){ | 1352 uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size); 1353 1354#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY 1355 log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", peripheral->gatt_client_state); 1356 if (peripheral->gatt_client_state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){ 1357 // iterate over descriptors looking for CCC 1358 if (pair_size == 4){ |
1340 int offset = 2; 1341 while (offset < size){ | 1359 while ((offset + 4) <= size){ |
1342 uint16_t uuid16 = little_endian_read_16(packet, offset + 2); 1343 if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){ 1344 peripheral->client_characteristic_configuration_handle = little_endian_read_16(packet, offset); 1345 peripheral->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 1346 log_info("CCC found %x", peripheral->client_characteristic_configuration_handle); 1347 break; 1348 } 1349 offset += pair_size; --- 124 unchanged lines hidden (view full) --- 1474 emit_gatt_complete_event(peripheral, ATT_ERROR_SUCCESS); 1475 break; 1476 default: 1477 break; 1478 } 1479 break; 1480 1481 case ATT_ERROR_RESPONSE: | 1360 uint16_t uuid16 = little_endian_read_16(packet, offset + 2); 1361 if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){ 1362 peripheral->client_characteristic_configuration_handle = little_endian_read_16(packet, offset); 1363 peripheral->gatt_client_state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 1364 log_info("CCC found %x", peripheral->client_characteristic_configuration_handle); 1365 break; 1366 } 1367 offset += pair_size; --- 124 unchanged lines hidden (view full) --- 1492 emit_gatt_complete_event(peripheral, ATT_ERROR_SUCCESS); 1493 break; 1494 default: 1495 break; 1496 } 1497 break; 1498 1499 case ATT_ERROR_RESPONSE: |
1482 | 1500 if (size < 5) return; |
1483 switch (packet[4]){ 1484 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: { 1485 switch(peripheral->gatt_client_state){ 1486 case P_W4_SERVICE_QUERY_RESULT: 1487 case P_W4_SERVICE_WITH_UUID_RESULT: 1488 case P_W4_INCLUDED_SERVICE_QUERY_RESULT: 1489 case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT: 1490 gatt_client_handle_transaction_complete(peripheral); --- 641 unchanged lines hidden (view full) --- 2132uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 2133 gatt_client_t * context = provide_context_for_conn_handle(con_handle); 2134 if (context == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2135 if (context->write_without_response_callback != NULL) return GATT_CLIENT_IN_WRONG_STATE; 2136 context->write_without_response_callback = callback; 2137 att_dispatch_client_request_can_send_now_event(context->con_handle); 2138 return ERROR_CODE_SUCCESS; 2139} | 1501 switch (packet[4]){ 1502 case ATT_ERROR_ATTRIBUTE_NOT_FOUND: { 1503 switch(peripheral->gatt_client_state){ 1504 case P_W4_SERVICE_QUERY_RESULT: 1505 case P_W4_SERVICE_WITH_UUID_RESULT: 1506 case P_W4_INCLUDED_SERVICE_QUERY_RESULT: 1507 case P_W4_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT: 1508 gatt_client_handle_transaction_complete(peripheral); --- 641 unchanged lines hidden (view full) --- 2150uint8_t gatt_client_request_can_write_without_response_event(btstack_packet_handler_t callback, hci_con_handle_t con_handle){ 2151 gatt_client_t * context = provide_context_for_conn_handle(con_handle); 2152 if (context == NULL) return BTSTACK_MEMORY_ALLOC_FAILED; 2153 if (context->write_without_response_callback != NULL) return GATT_CLIENT_IN_WRONG_STATE; 2154 context->write_without_response_callback = callback; 2155 att_dispatch_client_request_can_send_now_event(context->con_handle); 2156 return ERROR_CODE_SUCCESS; 2157} |
2158 2159#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 2160void gatt_client_att_packet_handler_fuzz(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ 2161 gatt_client_att_packet_handler(packet_type, handle, packet, size); 2162} 2163#endif |
|