1 2 // ***************************************************************************** 3 // 4 // test rfcomm query tests 5 // 6 // ***************************************************************************** 7 8 9 #include <stdint.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include "CppUTest/TestHarness.h" 15 #include "CppUTest/CommandLineTestRunner.h" 16 17 #include "hci_cmd.h" 18 19 #include "btstack_memory.h" 20 #include "hci.h" 21 #include "hci_dump.h" 22 #include "ble/gatt_client.h" 23 #include "ble/att_db.h" 24 #include "profile.h" 25 #include "expected_results.h" 26 27 extern "C" void hci_setup_le_connection(uint16_t con_handle); 28 29 static uint16_t gatt_client_handle = 0x40; 30 static int gatt_query_complete = 0; 31 32 typedef enum { 33 IDLE, 34 DISCOVER_PRIMARY_SERVICES, 35 DISCOVER_PRIMARY_SERVICE_WITH_UUID16, 36 DISCOVER_PRIMARY_SERVICE_WITH_UUID128, 37 38 DISCOVER_INCLUDED_SERVICE_FOR_SERVICE_WITH_UUID16, 39 DISCOVER_INCLUDED_SERVICE_FOR_SERVICE_WITH_UUID128, 40 41 DISCOVER_CHARACTERISTICS_FOR_SERVICE_WITH_UUID16, 42 DISCOVER_CHARACTERISTICS_FOR_SERVICE_WITH_UUID128, 43 DISCOVER_CHARACTERISTICS_BY_UUID16, 44 DISCOVER_CHARACTERISTICS_BY_UUID128, 45 DISCOVER_CHARACTERISTICS_FOR_SERVICE_BY_UUID, 46 47 READ_CHARACTERISTIC_VALUE, 48 READ_LONG_CHARACTERISTIC_VALUE, 49 WRITE_CHARACTERISTIC_VALUE, 50 WRITE_LONG_CHARACTERISTIC_VALUE, 51 52 DISCOVER_CHARACTERISTIC_DESCRIPTORS, 53 READ_CHARACTERISTIC_DESCRIPTOR, 54 WRITE_CHARACTERISTIC_DESCRIPTOR, 55 WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION, 56 READ_LONG_CHARACTERISTIC_DESCRIPTOR, 57 WRITE_LONG_CHARACTERISTIC_DESCRIPTOR, 58 WRITE_RELIABLE_LONG_CHARACTERISTIC_VALUE, 59 WRITE_CHARACTERISTIC_VALUE_WITHOUT_RESPONSE 60 } current_test_t; 61 62 current_test_t test = IDLE; 63 64 uint8_t characteristic_uuid128[] = {0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb}; 65 uint16_t characteristic_uuid16 = 0xF000; 66 67 static int result_index; 68 static uint8_t result_counter; 69 70 static gatt_client_service_t services[50]; 71 static gatt_client_service_t included_services[50]; 72 73 static gatt_client_characteristic_t characteristics[50]; 74 static gatt_client_characteristic_descriptor_t descriptors[50]; 75 76 void mock_simulate_discover_primary_services_response(void); 77 void mock_simulate_att_exchange_mtu_response(void); 78 79 void CHECK_EQUAL_ARRAY(const uint8_t * expected, uint8_t * actual, int size){ 80 for (int i=0; i<size; i++){ 81 BYTES_EQUAL(expected[i], actual[i]); 82 } 83 } 84 85 void pUUID128(const uint8_t *uuid) { 86 printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 87 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], 88 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); 89 } 90 91 //static int counter = 0; 92 void CHECK_EQUAL_GATT_ATTRIBUTE(const uint8_t * exp_uuid, const uint8_t * exp_handles, uint8_t * uuid, uint16_t start_handle, uint16_t end_handle){ 93 CHECK_EQUAL_ARRAY(exp_uuid, uuid, 16); 94 if (!exp_handles) return; 95 CHECK_EQUAL(exp_handles[0], start_handle); 96 CHECK_EQUAL(exp_handles[1], end_handle); 97 } 98 99 // ----------------------------------------------------- 100 101 static void verify_primary_services_with_uuid16(void){ 102 CHECK_EQUAL(1, result_index); 103 CHECK_EQUAL_GATT_ATTRIBUTE(primary_service_uuid16, primary_service_uuid16_handles, services[0].uuid128, services[0].start_group_handle, services[0].end_group_handle); 104 } 105 106 107 static void verify_primary_services_with_uuid128(void){ 108 CHECK_EQUAL(1, result_index); 109 CHECK_EQUAL_GATT_ATTRIBUTE(primary_service_uuid128, primary_service_uuid128_handles, services[0].uuid128, services[0].start_group_handle, services[0].end_group_handle); 110 } 111 112 static void verify_primary_services(void){ 113 CHECK_EQUAL(6, result_index); 114 for (int i=0; i<result_index; i++){ 115 CHECK_EQUAL_GATT_ATTRIBUTE(primary_service_uuids[i], NULL, services[i].uuid128, services[i].start_group_handle, services[i].end_group_handle); 116 } 117 } 118 119 static void verify_included_services_uuid16(void){ 120 CHECK_EQUAL(1, result_index); 121 CHECK_EQUAL_GATT_ATTRIBUTE(included_services_uuid16, included_services_uuid16_handles, included_services[0].uuid128, included_services[0].start_group_handle, included_services[0].end_group_handle); 122 } 123 124 static void verify_included_services_uuid128(void){ 125 CHECK_EQUAL(2, result_index); 126 for (int i=0; i<result_index; i++){ 127 CHECK_EQUAL_GATT_ATTRIBUTE(included_services_uuid128[i], included_services_uuid128_handles[i], included_services[i].uuid128, included_services[i].start_group_handle, included_services[i].end_group_handle); 128 } 129 } 130 131 static void verify_charasteristics(void){ 132 CHECK_EQUAL(15, result_index); 133 for (int i=0; i<result_index; i++){ 134 CHECK_EQUAL_GATT_ATTRIBUTE(characteristic_uuids[i], characteristic_handles[i], characteristics[i].uuid128, characteristics[i].start_handle, characteristics[i].end_handle); 135 } 136 } 137 138 static void verify_blob(uint16_t value_length, uint16_t value_offset, uint8_t * value){ 139 uint8_t * expected_value = (uint8_t*)&long_value[value_offset]; 140 CHECK(value_length); 141 CHECK_EQUAL_ARRAY(expected_value, value, value_length); 142 if (value_offset + value_length != sizeof(long_value)) return; 143 result_counter++; 144 } 145 146 static void handle_ble_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 147 if (packet_type != HCI_EVENT_PACKET) return; 148 uint8_t status; 149 gatt_client_service_t service; 150 gatt_client_characteristic_t characteristic; 151 gatt_client_characteristic_descriptor_t descriptor; 152 switch (packet[0]){ 153 case GATT_EVENT_QUERY_COMPLETE: 154 status = packet[4]; 155 gatt_query_complete = 1; 156 if (status){ 157 gatt_query_complete = 0; 158 printf("GATT_EVENT_QUERY_COMPLETE failed with status 0x%02X\n", status); 159 } 160 break; 161 case GATT_EVENT_SERVICE_QUERY_RESULT: 162 service.start_group_handle = little_endian_read_16(packet, 4); 163 service.end_group_handle = little_endian_read_16(packet, 6); 164 service.uuid16 = 0; 165 reverse_128(&packet[8], service.uuid128); 166 if (uuid_has_bluetooth_prefix(service.uuid128)){ 167 service.uuid16 = big_endian_read_32(service.uuid128, 0); 168 } 169 services[result_index++] = service; 170 result_counter++; 171 break; 172 case GATT_EVENT_INCLUDED_SERVICE_QUERY_RESULT: 173 service.start_group_handle = little_endian_read_16(packet, 6); 174 service.end_group_handle = little_endian_read_16(packet, 8); 175 service.uuid16 = 0; 176 reverse_128(&packet[10], service.uuid128); 177 if (uuid_has_bluetooth_prefix(service.uuid128)){ 178 service.uuid16 = big_endian_read_32(service.uuid128, 0); 179 } 180 included_services[result_index++] = service; 181 result_counter++; 182 break; 183 case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT: 184 characteristic.start_handle = little_endian_read_16(packet, 4); 185 characteristic.value_handle = little_endian_read_16(packet, 6); 186 characteristic.end_handle = little_endian_read_16(packet, 8); 187 characteristic.properties = little_endian_read_16(packet, 10); 188 characteristic.uuid16 = 0; 189 reverse_128(&packet[12], characteristic.uuid128); 190 if (uuid_has_bluetooth_prefix(characteristic.uuid128)){ 191 characteristic.uuid16 = big_endian_read_32(characteristic.uuid128, 0); 192 } 193 characteristics[result_index++] = characteristic; 194 result_counter++; 195 break; 196 case GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT: 197 descriptor.handle = little_endian_read_16(packet, 4); 198 reverse_128(&packet[6], descriptor.uuid128); 199 if (uuid_has_bluetooth_prefix(descriptor.uuid128)){ 200 descriptor.uuid16 = big_endian_read_32(descriptor.uuid128, 0); 201 } 202 descriptors[result_index++] = descriptor; 203 result_counter++; 204 break; 205 case GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT: 206 case GATT_EVENT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT: 207 CHECK_EQUAL(short_value_length, little_endian_read_16(packet, 6)); 208 CHECK_EQUAL_ARRAY((uint8_t*)short_value, &packet[8], short_value_length); 209 result_counter++; 210 break; 211 case GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT: 212 case GATT_EVENT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT: 213 verify_blob(little_endian_read_16(packet, 8), little_endian_read_16(packet, 6), &packet[10]); 214 result_counter++; 215 break; 216 } 217 } 218 219 extern "C" int att_write_callback(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){ 220 switch(test){ 221 case WRITE_CHARACTERISTIC_DESCRIPTOR: 222 case WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: 223 CHECK_EQUAL(ATT_TRANSACTION_MODE_NONE, transaction_mode); 224 CHECK_EQUAL(0, offset); 225 CHECK_EQUAL_ARRAY(indication, buffer, 2); 226 result_counter++; 227 break; 228 case WRITE_CHARACTERISTIC_VALUE: 229 CHECK_EQUAL(ATT_TRANSACTION_MODE_NONE, transaction_mode); 230 CHECK_EQUAL(0, offset); 231 CHECK_EQUAL_ARRAY((uint8_t *)short_value, buffer, short_value_length); 232 result_counter++; 233 break; 234 case WRITE_LONG_CHARACTERISTIC_DESCRIPTOR: 235 case WRITE_LONG_CHARACTERISTIC_VALUE: 236 case WRITE_RELIABLE_LONG_CHARACTERISTIC_VALUE: 237 if (transaction_mode == ATT_TRANSACTION_MODE_VALIDATE) break; 238 if (transaction_mode == ATT_TRANSACTION_MODE_EXECUTE) break; 239 CHECK_EQUAL(ATT_TRANSACTION_MODE_ACTIVE, transaction_mode); 240 CHECK_EQUAL_ARRAY((uint8_t *)&long_value[offset], buffer, buffer_size); 241 if (offset + buffer_size != sizeof(long_value)) break; 242 result_counter++; 243 break; 244 default: 245 break; 246 } 247 return 0; 248 } 249 250 int copy_bytes(uint8_t * value, uint16_t value_length, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ 251 int blob_length = value_length - offset; 252 if (blob_length >= buffer_size) blob_length = buffer_size; 253 254 memcpy(buffer, &value[offset], blob_length); 255 return blob_length; 256 } 257 258 extern "C" uint16_t att_read_callback(uint16_t handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ 259 //printf("gatt client test, att_read_callback_t handle 0x%04x, offset %u, buffer %p, buffer_size %u\n", handle, offset, buffer, buffer_size); 260 switch(test){ 261 case READ_CHARACTERISTIC_DESCRIPTOR: 262 case READ_CHARACTERISTIC_VALUE: 263 result_counter++; 264 if (buffer){ 265 return copy_bytes((uint8_t *)short_value, short_value_length, offset, buffer, buffer_size); 266 } 267 return short_value_length; 268 case READ_LONG_CHARACTERISTIC_DESCRIPTOR: 269 case READ_LONG_CHARACTERISTIC_VALUE: 270 result_counter++; 271 if (buffer) { 272 return copy_bytes((uint8_t *)long_value, long_value_length, offset, buffer, buffer_size); 273 } 274 return long_value_length; 275 default: 276 break; 277 } 278 return 0; 279 } 280 281 // static const char * decode_status(uint8_t status){ 282 // switch (status){ 283 // case 0: return "0"; 284 // case GATT_CLIENT_IN_WRONG_STATE: return "GATT_CLIENT_IN_WRONG_STATE"; 285 // case GATT_CLIENT_DIFFERENT_CONTEXT_FOR_ADDRESS_ALREADY_EXISTS: return "GATT_CLIENT_DIFFERENT_CONTEXT_FOR_ADDRESS_ALREADY_EXISTS"; 286 // case GATT_CLIENT_NOT_CONNECTED: return "GATT_CLIENT_NOT_CONNECTED"; 287 // case GATT_CLIENT_VALUE_TOO_LONG: return "GATT_CLIENT_VALUE_TOO_LONG"; 288 // case GATT_CLIENT_BUSY: return "GATT_CLIENT_BUSY"; 289 // case GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED: return "GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED"; 290 // case GATT_CLIENTCHARACTERISTIC_INDICATION_NOT_SUPPORTED: return "GATT_CLIENTCHARACTERISTIC_INDICATION_NOT_SUPPORTED"; 291 // } 292 // } 293 294 TEST_GROUP(GATTClient){ 295 int acl_buffer_size; 296 uint8_t acl_buffer[27]; 297 uint8_t status; 298 299 void setup(void){ 300 result_counter = 0; 301 result_index = 0; 302 test = IDLE; 303 hci_setup_le_connection(gatt_client_handle); 304 } 305 306 void reset_query_state(void){ 307 gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); 308 gatt_client->gatt_client_state = P_READY; 309 310 gatt_query_complete = 0; 311 result_counter = 0; 312 result_index = 0; 313 } 314 315 void set_wrong_gatt_client_state(void){ 316 gatt_client_t * gatt_client = gatt_client_get_client(gatt_client_handle); 317 CHECK_TRUE(gatt_client != NULL); 318 gatt_client->gatt_client_state = P_W2_SEND_SERVICE_QUERY; 319 } 320 }; 321 322 323 TEST(GATTClient, TestDiscoverPrimaryServices){ 324 test = DISCOVER_PRIMARY_SERVICES; 325 status = gatt_client_discover_primary_services(handle_ble_client_event, HCI_CON_HANDLE_INVALID); 326 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 327 328 set_wrong_gatt_client_state(); 329 status = gatt_client_discover_primary_services(handle_ble_client_event, gatt_client_handle); 330 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 331 332 reset_query_state(); 333 status = gatt_client_discover_primary_services(handle_ble_client_event, gatt_client_handle); 334 CHECK_EQUAL(0, status); 335 CHECK_EQUAL(1, gatt_query_complete); 336 verify_primary_services(); 337 CHECK_EQUAL(1, gatt_query_complete); 338 } 339 340 TEST(GATTClient, TestDiscoverPrimaryServicesByUUID16){ 341 test = DISCOVER_PRIMARY_SERVICE_WITH_UUID16; 342 reset_query_state(); 343 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 344 CHECK_EQUAL(0, status); 345 CHECK_EQUAL(1, result_counter); 346 verify_primary_services_with_uuid16(); 347 CHECK_EQUAL(1, gatt_query_complete); 348 } 349 350 TEST(GATTClient, TestDiscoverPrimaryServicesByUUID128){ 351 test = DISCOVER_PRIMARY_SERVICE_WITH_UUID128; 352 status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, gatt_client_handle, primary_service_uuid128); 353 CHECK_EQUAL(0, status); 354 CHECK_EQUAL(1, result_counter); 355 verify_primary_services_with_uuid128(); 356 CHECK_EQUAL(1, gatt_query_complete); 357 } 358 359 TEST(GATTClient, TestFindIncludedServicesForServiceWithUUID16){ 360 test = DISCOVER_INCLUDED_SERVICE_FOR_SERVICE_WITH_UUID16; 361 reset_query_state(); 362 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 363 CHECK_EQUAL(0, status); 364 CHECK_EQUAL(1, gatt_query_complete); 365 366 reset_query_state(); 367 status = gatt_client_find_included_services_for_service(handle_ble_client_event, gatt_client_handle, &services[0]); 368 CHECK_EQUAL(0, status); 369 CHECK_EQUAL(1, gatt_query_complete); 370 verify_included_services_uuid16(); 371 } 372 373 TEST(GATTClient, TestFindIncludedServicesForServiceWithUUID128){ 374 test = DISCOVER_INCLUDED_SERVICE_FOR_SERVICE_WITH_UUID128; 375 reset_query_state(); 376 status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, gatt_client_handle, primary_service_uuid128); 377 CHECK_EQUAL(0, status); 378 CHECK_EQUAL(1, gatt_query_complete); 379 380 reset_query_state(); 381 status = gatt_client_find_included_services_for_service(handle_ble_client_event, gatt_client_handle, &services[0]); 382 CHECK_EQUAL(0, status); 383 CHECK_EQUAL(1, gatt_query_complete); 384 verify_included_services_uuid128(); 385 } 386 387 TEST(GATTClient, TestDiscoverCharacteristicsForService){ 388 test = DISCOVER_CHARACTERISTICS_FOR_SERVICE_WITH_UUID16; 389 reset_query_state(); 390 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 391 CHECK_EQUAL(0, status); 392 CHECK_EQUAL(1, gatt_query_complete); 393 394 reset_query_state(); 395 status = gatt_client_discover_characteristics_for_service(handle_ble_client_event, gatt_client_handle, &services[0]); 396 CHECK_EQUAL(0, status); 397 CHECK_EQUAL(1, gatt_query_complete); 398 verify_charasteristics(); 399 } 400 401 TEST(GATTClient, TestDiscoverCharacteristicsByUUID16){ 402 test = DISCOVER_CHARACTERISTICS_BY_UUID16; 403 reset_query_state(); 404 status = gatt_client_discover_characteristics_for_handle_range_by_uuid16(handle_ble_client_event, gatt_client_handle, 0x30, 0x32, 0xF102); 405 CHECK_EQUAL(0, status); 406 CHECK_EQUAL(1, gatt_query_complete); 407 CHECK_EQUAL(1, result_counter); 408 } 409 410 TEST(GATTClient, TestDiscoverCharacteristicsByUUID128){ 411 test = DISCOVER_CHARACTERISTICS_BY_UUID128; 412 reset_query_state(); 413 status = gatt_client_discover_characteristics_for_handle_range_by_uuid128(handle_ble_client_event, gatt_client_handle, characteristic_handles[1][0], characteristic_handles[1][1], characteristic_uuids[1]); 414 CHECK_EQUAL(0, status); 415 CHECK_EQUAL(1, gatt_query_complete); 416 CHECK_EQUAL(1, result_counter); 417 } 418 419 TEST(GATTClient, TestDiscoverCharacteristics4ServiceByUUID128){ 420 test = DISCOVER_CHARACTERISTICS_FOR_SERVICE_BY_UUID; 421 reset_query_state(); 422 status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, gatt_client_handle, primary_service_uuid128); 423 CHECK_EQUAL(0, status); 424 CHECK_EQUAL(1, gatt_query_complete); 425 CHECK_EQUAL(1, result_counter); 426 427 reset_query_state(); 428 uint8_t characteristic_uuid[] = {0x00, 0x00, 0xF2, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 429 status = gatt_client_discover_characteristics_for_service_by_uuid128(handle_ble_client_event, gatt_client_handle, &services[0], characteristic_uuid); 430 CHECK_EQUAL(0, status); 431 CHECK_EQUAL(1, gatt_query_complete); 432 CHECK_EQUAL(1, result_counter); 433 434 reset_query_state(); 435 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF200); 436 CHECK_EQUAL(0, status); 437 CHECK_EQUAL(1, gatt_query_complete); 438 CHECK_EQUAL(1, result_counter); 439 } 440 441 TEST(GATTClient, TestDiscoverCharacteristics4ServiceByUUID16){ 442 test = DISCOVER_CHARACTERISTICS_FOR_SERVICE_BY_UUID; 443 reset_query_state(); 444 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 445 CHECK_EQUAL(0, status); 446 CHECK_EQUAL(1, gatt_query_complete); 447 CHECK_EQUAL(1, result_counter); 448 449 reset_query_state(); 450 uint8_t characteristic_uuid[]= { 0x00, 0x00, 0xF1, 0x05, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 451 status = gatt_client_discover_characteristics_for_service_by_uuid128(handle_ble_client_event, gatt_client_handle, &services[0], characteristic_uuid); 452 CHECK_EQUAL(0, status); 453 CHECK_EQUAL(1, gatt_query_complete); 454 CHECK_EQUAL(1, result_counter); 455 456 reset_query_state(); 457 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 458 CHECK_EQUAL(0, status); 459 CHECK_EQUAL(1, gatt_query_complete); 460 CHECK_EQUAL(1, result_counter); 461 } 462 463 TEST(GATTClient, TestDiscoverCharacteristicDescriptor){ 464 test = DISCOVER_CHARACTERISTIC_DESCRIPTORS; 465 466 reset_query_state(); 467 // invalid con handle 468 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, HCI_CON_HANDLE_INVALID, service_uuid16); 469 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 470 471 set_wrong_gatt_client_state(); 472 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 473 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 474 475 reset_query_state(); 476 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 477 CHECK_EQUAL(0, status); 478 CHECK_EQUAL(1, gatt_query_complete); 479 CHECK_EQUAL(1, result_counter); 480 481 reset_query_state(); 482 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 483 CHECK_EQUAL(0, status); 484 CHECK_EQUAL(1, gatt_query_complete); 485 CHECK_EQUAL(1, result_counter); 486 487 reset_query_state(); 488 status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 489 CHECK_EQUAL(0, status); 490 CHECK_EQUAL(1, gatt_query_complete); 491 CHECK(result_counter); 492 CHECK_EQUAL(3, result_index); 493 CHECK_EQUAL(0x2902, descriptors[0].uuid16); 494 CHECK_EQUAL(0x2900, descriptors[1].uuid16); 495 CHECK_EQUAL(0x2901, descriptors[2].uuid16); 496 } 497 498 TEST(GATTClient, TestWriteClientCharacteristicConfiguration){ 499 test = WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; 500 reset_query_state(); 501 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 502 CHECK_EQUAL(0, status); 503 CHECK_EQUAL(1, gatt_query_complete); 504 CHECK_EQUAL(1, result_counter); 505 506 reset_query_state(); 507 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 508 CHECK_EQUAL(0, status); 509 CHECK_EQUAL(1, gatt_query_complete); 510 CHECK_EQUAL(1, result_counter); 511 512 // invalid con handle 513 status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); 514 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 515 516 set_wrong_gatt_client_state(); 517 status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, gatt_client_handle, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); 518 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 519 520 reset_query_state(); 521 status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, gatt_client_handle, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); 522 CHECK_EQUAL(0, status); 523 CHECK_EQUAL(1, gatt_query_complete); 524 CHECK_EQUAL(1, result_counter); 525 526 reset_query_state(); 527 characteristics->properties = 0; 528 status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, gatt_client_handle, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); 529 CHECK_EQUAL(GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED, status); 530 531 reset_query_state(); 532 characteristics->properties = 0; 533 status = gatt_client_write_client_characteristic_configuration(handle_ble_client_event, gatt_client_handle, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION); 534 CHECK_EQUAL(GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED, status); 535 } 536 537 TEST(GATTClient, TestReadCharacteristicDescriptor){ 538 test = READ_CHARACTERISTIC_DESCRIPTOR; 539 reset_query_state(); 540 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 541 CHECK_EQUAL(0, status); 542 CHECK_EQUAL(1, gatt_query_complete); 543 CHECK_EQUAL(1, result_counter); 544 545 reset_query_state(); 546 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 547 CHECK_EQUAL(0, status); 548 CHECK_EQUAL(1, gatt_query_complete); 549 CHECK_EQUAL(1, result_counter); 550 551 reset_query_state(); 552 status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 553 CHECK_EQUAL(0, status); 554 CHECK_EQUAL(1, gatt_query_complete); 555 CHECK_EQUAL(3, result_counter); 556 557 reset_query_state(); 558 status = gatt_client_read_characteristic_descriptor(handle_ble_client_event, gatt_client_handle, &descriptors[0]); 559 CHECK_EQUAL(0, status); 560 CHECK_EQUAL(1, gatt_query_complete); 561 CHECK_EQUAL(3, result_counter); 562 563 // invalid con handle 564 status = gatt_client_read_characteristic_descriptor(handle_ble_client_event, HCI_CON_HANDLE_INVALID, &descriptors[0]); 565 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 566 567 set_wrong_gatt_client_state(); 568 status = gatt_client_read_characteristic_descriptor(handle_ble_client_event, gatt_client_handle, &descriptors[0]); 569 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 570 } 571 572 TEST(GATTClient, TestReadCharacteristicValue){ 573 test = READ_CHARACTERISTIC_VALUE; 574 reset_query_state(); 575 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 576 CHECK_EQUAL(0, status); 577 CHECK_EQUAL(1, gatt_query_complete); 578 CHECK_EQUAL(1, result_counter); 579 580 reset_query_state(); 581 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 582 CHECK_EQUAL(0, status); 583 CHECK_EQUAL(1, gatt_query_complete); 584 CHECK_EQUAL(1, result_counter); 585 586 reset_query_state(); 587 status = gatt_client_read_value_of_characteristic(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 588 CHECK_EQUAL(0, status); 589 CHECK_EQUAL(1, gatt_query_complete); 590 CHECK_EQUAL(3, result_counter); 591 } 592 593 TEST(GATTClient, TestWriteCharacteristicValue){ 594 test = WRITE_CHARACTERISTIC_VALUE; 595 reset_query_state(); 596 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 597 CHECK_EQUAL(0, status); 598 CHECK_EQUAL(1, gatt_query_complete); 599 CHECK_EQUAL(1, result_counter); 600 601 reset_query_state(); 602 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 603 CHECK_EQUAL(0, status); 604 CHECK_EQUAL(1, gatt_query_complete); 605 CHECK_EQUAL(1, result_counter); 606 607 // invalid con handle 608 status = gatt_client_write_value_of_characteristic(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, short_value_length, (uint8_t*)short_value); 609 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 610 611 set_wrong_gatt_client_state(); 612 status = gatt_client_write_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, short_value_length, (uint8_t*)short_value); 613 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 614 615 616 reset_query_state(); 617 status = gatt_client_write_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, short_value_length, (uint8_t*)short_value); 618 CHECK_EQUAL(0, status); 619 CHECK_EQUAL(1, gatt_query_complete); 620 } 621 622 TEST(GATTClient, TestWriteCharacteristicDescriptor){ 623 test = WRITE_CHARACTERISTIC_DESCRIPTOR; 624 reset_query_state(); 625 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 626 CHECK_EQUAL(0, status); 627 CHECK_EQUAL(1, gatt_query_complete); 628 CHECK_EQUAL(1, result_counter); 629 630 reset_query_state(); 631 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 632 CHECK_EQUAL(0, status); 633 CHECK_EQUAL(1, gatt_query_complete); 634 CHECK_EQUAL(1, result_counter); 635 636 reset_query_state(); 637 status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 638 CHECK_EQUAL(0, status); 639 CHECK_EQUAL(1, gatt_query_complete); 640 CHECK_EQUAL(3, result_counter); 641 642 reset_query_state(); 643 status = gatt_client_write_characteristic_descriptor(handle_ble_client_event, gatt_client_handle, &descriptors[0], sizeof(indication), indication); 644 CHECK_EQUAL(0, status); 645 CHECK_EQUAL(1, gatt_query_complete); 646 } 647 648 TEST(GATTClient, TestReadLongCharacteristicValue){ 649 test = READ_LONG_CHARACTERISTIC_VALUE; 650 reset_query_state(); 651 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 652 CHECK_EQUAL(0, status); 653 CHECK_EQUAL(1, gatt_query_complete); 654 CHECK_EQUAL(1, result_counter); 655 656 reset_query_state(); 657 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 658 CHECK_EQUAL(0, status); 659 CHECK_EQUAL(1, gatt_query_complete); 660 CHECK_EQUAL(1, result_counter); 661 662 reset_query_state(); 663 status = gatt_client_read_long_value_of_characteristic(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 664 CHECK_EQUAL(0, status); 665 CHECK_EQUAL(1, gatt_query_complete); 666 CHECK_EQUAL(4, result_counter); 667 } 668 669 TEST(GATTClient, TestReadLongCharacteristicDescriptor){ 670 test = READ_LONG_CHARACTERISTIC_DESCRIPTOR; 671 reset_query_state(); 672 status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, gatt_client_handle, primary_service_uuid128); 673 CHECK_EQUAL(0, status); 674 CHECK_EQUAL(1, gatt_query_complete); 675 CHECK_EQUAL(1, result_counter); 676 677 reset_query_state(); 678 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF200); 679 CHECK_EQUAL(0, status); 680 CHECK_EQUAL(1, gatt_query_complete); 681 CHECK_EQUAL(1, result_counter); 682 683 reset_query_state(); 684 status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 685 CHECK_EQUAL(0, status); 686 CHECK_EQUAL(1, gatt_query_complete); 687 CHECK_EQUAL(3, result_counter); 688 689 reset_query_state(); 690 result_counter = 0; 691 status = gatt_client_read_long_characteristic_descriptor(handle_ble_client_event, gatt_client_handle, &descriptors[0]); 692 CHECK_EQUAL(0, status); 693 CHECK_EQUAL(1, gatt_query_complete); 694 CHECK_EQUAL(4, result_counter); 695 } 696 697 698 TEST(GATTClient, TestWriteLongCharacteristicDescriptor){ 699 test = WRITE_LONG_CHARACTERISTIC_DESCRIPTOR; 700 reset_query_state(); 701 status = gatt_client_discover_primary_services_by_uuid128(handle_ble_client_event, gatt_client_handle, primary_service_uuid128); 702 CHECK_EQUAL(0, status); 703 CHECK_EQUAL(1, gatt_query_complete); 704 CHECK_EQUAL(1, result_counter); 705 706 reset_query_state(); 707 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF200); 708 CHECK_EQUAL(0, status); 709 CHECK_EQUAL(1, gatt_query_complete); 710 CHECK_EQUAL(1, result_counter); 711 712 reset_query_state(); 713 status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 714 CHECK_EQUAL(0, status); 715 CHECK_EQUAL(1, gatt_query_complete); 716 CHECK_EQUAL(3, result_counter); 717 718 result_counter = 0; 719 status = gatt_client_write_long_characteristic_descriptor(handle_ble_client_event, gatt_client_handle, &descriptors[0], sizeof(long_value), (uint8_t *)long_value); 720 CHECK_EQUAL(0, status); 721 CHECK_EQUAL(1, gatt_query_complete); 722 CHECK_EQUAL(1, result_counter); 723 } 724 725 TEST(GATTClient, TestWriteLongCharacteristicValue){ 726 test = WRITE_LONG_CHARACTERISTIC_VALUE; 727 reset_query_state(); 728 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 729 CHECK_EQUAL(0, status); 730 CHECK_EQUAL(1, gatt_query_complete); 731 CHECK_EQUAL(1, result_counter); 732 733 reset_query_state(); 734 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 735 CHECK_EQUAL(0, status); 736 CHECK_EQUAL(1, gatt_query_complete); 737 CHECK_EQUAL(1, result_counter); 738 739 740 reset_query_state(); 741 status = gatt_client_write_long_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); 742 CHECK_EQUAL(0, status); 743 CHECK_EQUAL(1, gatt_query_complete); 744 } 745 746 TEST(GATTClient, TestWriteReliableLongCharacteristicValue){ 747 test = WRITE_RELIABLE_LONG_CHARACTERISTIC_VALUE; 748 reset_query_state(); 749 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 750 CHECK_EQUAL(0, status); 751 CHECK_EQUAL(1, gatt_query_complete); 752 CHECK_EQUAL(1, result_counter); 753 754 reset_query_state(); 755 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 756 CHECK_EQUAL(0, status); 757 CHECK_EQUAL(1, gatt_query_complete); 758 CHECK_EQUAL(1, result_counter); 759 760 // invalid con handle 761 status = gatt_client_reliable_write_long_value_of_characteristic(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); 762 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 763 764 set_wrong_gatt_client_state(); 765 status = gatt_client_reliable_write_long_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); 766 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 767 768 reset_query_state(); 769 status = gatt_client_reliable_write_long_value_of_characteristic(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); 770 CHECK_EQUAL(0, status); 771 CHECK_EQUAL(1, gatt_query_complete); 772 } 773 774 TEST(GATTClient, gatt_client_write_long_value_of_characteristic_with_offset){ 775 reset_query_state(); 776 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 777 CHECK_EQUAL(0, status); 778 CHECK_EQUAL(1, gatt_query_complete); 779 CHECK_EQUAL(1, result_counter); 780 781 reset_query_state(); 782 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 783 CHECK_EQUAL(0, status); 784 CHECK_EQUAL(1, gatt_query_complete); 785 CHECK_EQUAL(1, result_counter); 786 787 reset_query_state(); 788 status = gatt_client_write_long_value_of_characteristic_with_offset(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, 0, long_value_length, (uint8_t*)long_value); 789 CHECK_EQUAL(0, status); 790 791 reset_query_state(); 792 // invalid con handle 793 status = gatt_client_write_long_value_of_characteristic_with_offset(handle_ble_client_event, HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, 0, long_value_length, (uint8_t*)long_value); 794 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 795 796 reset_query_state(); 797 set_wrong_gatt_client_state(); 798 status = gatt_client_write_long_value_of_characteristic_with_offset(handle_ble_client_event, gatt_client_handle, characteristics[0].value_handle, 0, long_value_length, (uint8_t*)long_value); 799 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 800 } 801 802 TEST(GATTClient, gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset){ 803 reset_query_state(); 804 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 805 CHECK_EQUAL(0, status); 806 CHECK_EQUAL(1, gatt_query_complete); 807 CHECK_EQUAL(1, result_counter); 808 809 reset_query_state(); 810 status = gatt_client_discover_characteristic_descriptors(handle_ble_client_event, gatt_client_handle, &characteristics[0]); 811 CHECK_EQUAL(0, status); 812 CHECK_EQUAL(1, gatt_query_complete); 813 CHECK(result_counter); 814 CHECK_EQUAL(3, result_index); 815 CHECK_EQUAL(0x2902, descriptors[0].uuid16); 816 CHECK_EQUAL(0x2900, descriptors[1].uuid16); 817 CHECK_EQUAL(0x2901, descriptors[2].uuid16); 818 819 reset_query_state(); 820 status = gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(handle_ble_client_event, gatt_client_handle, descriptors[0].handle, 0); 821 CHECK_EQUAL(0, status); 822 823 reset_query_state(); 824 // invalid con handle 825 status = gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(handle_ble_client_event, HCI_CON_HANDLE_INVALID, descriptors[0].handle, 0); 826 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 827 828 reset_query_state(); 829 set_wrong_gatt_client_state(); 830 status = gatt_client_read_long_characteristic_descriptor_using_descriptor_handle_with_offset(handle_ble_client_event, gatt_client_handle, descriptors[0].handle, 0); 831 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 832 } 833 834 TEST(GATTClient, gatt_client_read_multiple_characteristic_values){ 835 reset_query_state(); 836 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 837 CHECK_EQUAL(0, status); 838 CHECK_EQUAL(1, gatt_query_complete); 839 CHECK_EQUAL(1, result_counter); 840 841 reset_query_state(); 842 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 843 CHECK_EQUAL(0, status); 844 CHECK_EQUAL(1, gatt_query_complete); 845 CHECK_EQUAL(1, result_counter); 846 847 uint16_t value_handles[] = {characteristics[0].value_handle}; 848 849 reset_query_state(); 850 status = gatt_client_read_multiple_characteristic_values(handle_ble_client_event, gatt_client_handle, 1, value_handles); 851 CHECK_EQUAL(0, status); 852 853 reset_query_state(); 854 // invalid con handle 855 status = gatt_client_read_multiple_characteristic_values(handle_ble_client_event, HCI_CON_HANDLE_INVALID, 1, value_handles); 856 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 857 858 reset_query_state(); 859 set_wrong_gatt_client_state(); 860 status = gatt_client_read_multiple_characteristic_values(handle_ble_client_event, gatt_client_handle, 1, value_handles); 861 CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 862 } 863 864 TEST(GATTClient, gatt_client_write_value_of_characteristic_without_response){ 865 reset_query_state(); 866 status = gatt_client_discover_primary_services_by_uuid16(handle_ble_client_event, gatt_client_handle, service_uuid16); 867 CHECK_EQUAL(0, status); 868 CHECK_EQUAL(1, gatt_query_complete); 869 CHECK_EQUAL(1, result_counter); 870 871 reset_query_state(); 872 status = gatt_client_discover_characteristics_for_service_by_uuid16(handle_ble_client_event, gatt_client_handle, &services[0], 0xF100); 873 CHECK_EQUAL(0, status); 874 CHECK_EQUAL(1, gatt_query_complete); 875 CHECK_EQUAL(1, result_counter); 876 877 uint16_t value_handles[] = {characteristics[0].value_handle}; 878 879 reset_query_state(); 880 // invalid con handle 881 status = gatt_client_write_value_of_characteristic_without_response(HCI_CON_HANDLE_INVALID, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); 882 CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 883 884 reset_query_state(); 885 set_wrong_gatt_client_state(); 886 status = gatt_client_write_value_of_characteristic_without_response(gatt_client_handle, characteristics[0].value_handle, long_value_length, (uint8_t*)long_value); 887 CHECK_EQUAL(GATT_CLIENT_VALUE_TOO_LONG, status); 888 889 reset_query_state(); 890 891 status = gatt_client_write_value_of_characteristic_without_response(gatt_client_handle, characteristics[0].value_handle, 19, (uint8_t*)long_value); 892 CHECK_EQUAL(0, status); 893 894 } 895 896 int main (int argc, const char * argv[]){ 897 att_set_db(profile_data); 898 att_set_write_callback(&att_write_callback); 899 att_set_read_callback(&att_read_callback); 900 901 gatt_client_init(); 902 903 return CommandLineTestRunner::RunAllTests(argc, argv); 904 } 905