diff --git a/example/libusb/ble_client.c b/example/libusb/ble_client.c index cdb2d6c11..8cb19e75d 100644 --- a/example/libusb/ble_client.c +++ b/example/libusb/ble_client.c @@ -1194,19 +1194,17 @@ static void report_gatt_characteristic_value(le_peripheral_t * peripheral, uint1 send_characteristic_value_event(peripheral, handle, value, length, 0, GATT_CHARACTERISTIC_VALUE_QUERY_RESULT); } -static void report_gatt_characteristic_descriptor(le_peripheral_t * peripheral, uint16_t handle, uint8_t * uuid128, uint16_t uuid16, uint8_t *value, uint16_t value_length, uint16_t value_offset, uint8_t event_type){ +static void report_gatt_characteristic_descriptor(le_peripheral_t * peripheral, uint16_t handle, uint8_t *value, uint16_t value_length, uint16_t value_offset, uint8_t event_type){ le_characteristic_descriptor_event_t event; event.type = event_type; // GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT; le_characteristic_descriptor_t descriptor; descriptor.handle = handle; - descriptor.uuid16 = uuid16; + descriptor.uuid16 = peripheral->uuid16; descriptor.value_offset = value_offset; - if (uuid128){ - memcpy(descriptor.uuid128, uuid128, 16); - } else { - sdp_normalize_uuid((uint8_t*) &descriptor.uuid128, descriptor.uuid16); - } + if (peripheral->uuid128){ + memcpy(descriptor.uuid128, peripheral->uuid128, 16); + } descriptor.value = value; descriptor.value_length = value_length; @@ -1400,7 +1398,7 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa case P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT:{ peripheral->state = P_CONNECTED; - report_gatt_characteristic_descriptor(peripheral, peripheral->attribute_handle, peripheral->uuid128, peripheral->uuid16, &packet[1], size-1, 0, GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT); + report_gatt_characteristic_descriptor(peripheral, peripheral->attribute_handle, &packet[1], size-1, 0, GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT); break; } default: @@ -1470,7 +1468,7 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa break; case P_W4_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_RESULT: report_gatt_characteristic_descriptor(peripheral, peripheral->attribute_handle, - peripheral->uuid128, peripheral->uuid16, &packet[1], received_blob_length, + &packet[1], received_blob_length, peripheral->attribute_offset, GATT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT); trigger_next_blob_query(peripheral, P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY, GATT_LONG_CHARACTERISTIC_DESCRIPTOR_QUERY_COMPLETE, received_blob_length); break; diff --git a/test/gatt_client/gatt_client.c b/test/gatt_client/gatt_client.c index 4abf59ad2..78d7cb6a6 100644 --- a/test/gatt_client/gatt_client.c +++ b/test/gatt_client/gatt_client.c @@ -41,7 +41,8 @@ typedef enum { DISCOVER_CHARACTERISTICS_BY_UUID128, DISCOVER_CHARACTERISTICS_FOR_SERVICE_BY_UUID, - DISCOVER_CHARACTERISTIC_DESCRIPTORS + DISCOVER_READ_WRITE_CHARACTERISTIC_DESCRIPTORS, + WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION } current_test_t; current_test_t test = IDLE; @@ -91,9 +92,9 @@ static void hexdump2(void const *data, int size){ } static void dump_characteristic(le_characteristic_t * characteristic){ - //printf(" {0x%02x, 0x%02x}", characteristic->start_handle, characteristic->end_handle); - //printUUID(characteristic->uuid128, characteristic->uuid16); - printUUID1(characteristic->uuid128); + printf("\n *** characteristic *** properties 0x%02x, handles {0x%02x, 0x%02x}", characteristic->properties, characteristic->start_handle, characteristic->end_handle); + printUUID(characteristic->uuid128, characteristic->uuid16); + //printf(" UUID: "); printUUID1(characteristic->uuid128); } static void dump_ad_event(ad_event_t * e){ @@ -108,10 +109,11 @@ static void dump_service(le_service_t * service){ } static void dump_descriptor(le_characteristic_descriptor_t * descriptor){ - printf(" *** descriptor *** handle 0x%02x, value ", descriptor->handle); - hexdump2(descriptor->value, descriptor->value_length); - printf(" UUID\n"); - printUUID1(descriptor->uuid128); + printf("\n *** descriptor *** handle 0x%02x ", descriptor->handle); + printUUID(descriptor->uuid128, descriptor->uuid16); + printf(" Value: "); hexdump2(descriptor->value, descriptor->value_length); + //printf(" UUID: "); printUUID1(descriptor->uuid128); + //printf("\n"); } static void dump_characteristic_value(le_characteristic_value_event_t * event){ @@ -250,17 +252,55 @@ static void handle_le_central_event(le_central_event_t * event){ break; case GATT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT: descriptors[result_index++] = ((le_characteristic_descriptor_event_t *) event)->characteristic_descriptor; - dump_descriptor(&descriptors[result_index-1]); break; case GATT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_COMPLETE: result_found = 1; break; + case GATT_CHARACTERISTIC_DESCRIPTOR_QUERY_RESULT: + descriptors[result_index++] = ((le_characteristic_descriptor_event_t *) event)->characteristic_descriptor; + // dump_descriptor(&descriptors[result_index-1]); + result_found = 1; + break; default: printf("handle_le_central_event"); break; } } +extern "C" int att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature){ + printf("gatt client test, att_write_callback mode %u, handle 0x%04x, offset %u, data ", transaction_mode, handle, offset); + hexdump2(buffer, buffer_size); + switch(test){ + case DISCOVER_READ_WRITE_CHARACTERISTIC_DESCRIPTORS: + case WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: + CHECK_EQUAL(ATT_TRANSACTION_MODE_NONE, transaction_mode); + CHECK_EQUAL(0x0028, handle); + CHECK_EQUAL(0, offset); + CHECK_EQUAL_ARRAY(indication, buffer, buffer_size); + result_found = 1; + break; + default: + break; + } + return 0; +} + +extern "C" uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ + printf("gatt client test, att_read_callback_t handle 0x%04x, offset %u, buffer %p, buffer_size %u\n", handle, offset, buffer, buffer_size); + switch(test){ + case DISCOVER_READ_WRITE_CHARACTERISTIC_DESCRIPTORS: + case WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION: + CHECK_EQUAL(0x0028, handle); + CHECK_EQUAL(0, offset); + CHECK_EQUAL_ARRAY(0, buffer, buffer_size); + result_found = 1; + break; + default: + break; + } +} + + TEST_GROUP(GATTClient){ int acl_buffer_size; uint8_t acl_buffer[27]; @@ -283,6 +323,8 @@ TEST_GROUP(GATTClient){ le_central_register_handler(handle_le_central_event); mock_simulate_hci_state_working(); att_set_db(profile_data); + att_set_write_callback(&att_write_callback); + att_set_read_callback(&att_read_callback); connect(); } }; @@ -392,8 +434,8 @@ TEST(GATTClient, TestDiscoverCharacteristics4ServiceByUUID16){ CHECK(result_found); } -TEST(GATTClient, TestDiscoverCharacteristicDescriptors){ - test = DISCOVER_CHARACTERISTIC_DESCRIPTORS; +TEST(GATTClient, TestDiscoverWriteReadCharacteristicDescriptors){ + test = DISCOVER_READ_WRITE_CHARACTERISTIC_DESCRIPTORS; le_central_discover_primary_services_by_uuid16(&test_device, 0xF000); CHECK(result_found); @@ -410,8 +452,53 @@ TEST(GATTClient, TestDiscoverCharacteristicDescriptors){ CHECK_EQUAL(0x2902, descriptors[0].uuid16); CHECK_EQUAL(0x2900, descriptors[1].uuid16); CHECK_EQUAL(0x2901, descriptors[2].uuid16); + + result_found = 0; + le_central_read_characteristic_descriptor(&test_device, &descriptors[0]); + CHECK(result_found); + + result_found = 0; + le_central_write_characteristic_descriptor(&test_device, &descriptors[0], sizeof(indication), indication); + CHECK(result_found); } + +TEST(GATTClient, TestWriteClientCharacteristicConfiguration){ + test = WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION; + le_central_discover_primary_services_by_uuid16(&test_device, 0xF000); + CHECK(result_found); + + result_found = 0; + result_index = 0; + le_central_discover_characteristics_for_service_by_uuid16(&test_device, &services[0], 0xF100); + CHECK(result_found); + + result_found = 0; + le_central_write_client_characteristic_configuration(&test_device, &characteristics[0], GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION); + CHECK(result_found); +} + + + + +/* +le_command_status_t le_central_read_long_characteristic_descriptor(le_peripheral_t *context, le_characteristic_descriptor_t * descriptor); +le_command_status_t le_central_write_long_characteristic_descriptor(le_peripheral_t *context, le_characteristic_descriptor_t * descriptor, uint16_t length, uint8_t * data); + +// Reads value of characteristic using characteristic value handle +le_command_status_t le_central_read_value_of_characteristic(le_peripheral_t *context, le_characteristic_t *characteristic); +le_command_status_t le_central_read_value_of_characteristic_using_value_handle(le_peripheral_t *context, uint16_t characteristic_value_handle); + +// Reads long caharacteristic value. +le_command_status_t le_central_read_long_value_of_characteristic(le_peripheral_t *context, le_characteristic_t *characteristic); +le_command_status_t le_central_read_long_value_of_characteristic_using_value_handle(le_peripheral_t *context, uint16_t characteristic_value_handle); + +le_command_status_t le_central_write_value_of_characteristic_without_response(le_peripheral_t *context, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); +le_command_status_t le_central_write_value_of_characteristic(le_peripheral_t *context, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); + +le_command_status_t le_central_write_long_value_of_characteristic(le_peripheral_t *context, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); +le_command_status_t le_central_reliable_write_long_value_of_characteristic(le_peripheral_t *context, uint16_t characteristic_value_handle, uint16_t length, uint8_t * data); +*/ int main (int argc, const char * argv[]){ return CommandLineTestRunner::RunAllTests(argc, argv); }