// ***************************************************************************** // // test rfcomm query tests // // ***************************************************************************** #include #include #include #include #include "CppUTest/TestHarness.h" #include "CppUTest/CommandLineTestRunner.h" #include "hci.h" #include "ble/att_db.h" #include "ble/att_db_util.h" #include "ble/att_server.h" #include "btstack_util.h" #include "bluetooth.h" #include "btstack_tlv.h" #include "mock_btstack_tlv.h" #include "bluetooth_gatt.h" static uint8_t battery_level = 100; static const uint8_t uuid128_with_bluetooth_base[] = { 0x00, 0x00, 0xBB, 0xBB, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; static const uint8_t uuid128_no_bluetooth_base[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00 }; extern "C" void l2cap_can_send_fixed_channel_packet_now_set_status(uint8_t status); extern "C" void mock_call_att_server_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); extern "C" void hci_setup_le_connection(uint16_t con_handle); extern "C" void mock_call_att_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); extern "C" void mock_l2cap_set_max_mtu(uint16_t mtu); extern "C" void hci_setup_classic_connection(uint16_t con_handle); extern "C" void set_cmac_ready(int ready); static uint8_t att_request[255]; static uint16_t att_write_request(uint16_t request_type, uint16_t attribute_handle, uint16_t value_length, const uint8_t * value){ att_request[0] = request_type; little_endian_store_16(att_request, 1, attribute_handle); (void)memcpy(&att_request[3], value, value_length); return 3 + value_length; } static uint16_t att_read_request(uint16_t request_type, uint16_t attribute_handle){ att_request[0] = request_type; little_endian_store_16(att_request, 1, attribute_handle); return 3; } static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ UNUSED(connection_handle); UNUSED(att_handle); UNUSED(offset); UNUSED(buffer); UNUSED(buffer_size); return 0; } static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){ UNUSED(connection_handle); UNUSED(att_handle); UNUSED(transaction_mode); UNUSED(offset); UNUSED(buffer); UNUSED(buffer_size); return 0; } static void att_client_indication_callback(void * context){ } static void att_client_notification_callback(void * context){ } static void att_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { } TEST_GROUP(ATT_SERVER){ uint16_t att_con_handle; mock_btstack_tlv_t tlv_context; const btstack_tlv_t * tlv_impl; btstack_context_callback_registration_t indication_callback; btstack_context_callback_registration_t notification_callback; void setup(void){ att_con_handle = 0x01; hci_setup_le_connection(att_con_handle); tlv_impl = mock_btstack_tlv_init_instance(&tlv_context); btstack_tlv_set_instance(tlv_impl, &tlv_context); l2cap_can_send_fixed_channel_packet_now_set_status(1); indication_callback.callback = &att_client_indication_callback; notification_callback.callback = &att_client_notification_callback; // init att db util and add a service and characteristic att_db_util_init(); // 0x180F att_db_util_add_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE); // 0x2A19 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_WRITE | ATT_PROPERTY_READ | ATT_PROPERTY_INDICATE, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // 0x2A1B att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_STATE, ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // 0x2A1A att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_POWER_STATE, ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); // 0x2A49 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_FEATURE, ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // 0x2A35 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_MEASUREMENT, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); att_db_util_add_characteristic_uuid128(uuid128_no_bluetooth_base, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // 0x2A38btstack_tlv_set_instance att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); att_db_util_add_characteristic_uuid128(uuid128_with_bluetooth_base, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // 0x2AAB att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME, ATT_PROPERTY_WRITE_WITHOUT_RESPONSE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // 0x2A5C att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CSC_FEATURE, ATT_PROPERTY_AUTHENTICATED_SIGNED_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); // setup ATT server att_server_init(att_db_util_get_address(), att_read_callback, att_write_callback); } void teardown(void) { mock_btstack_tlv_deinit(&tlv_context); att_server_deinit(); hci_deinit(); } }; TEST(ATT_SERVER, gatt_server_get_value_handle_for_characteristic_with_uuid16){ // att_dump_attributes(); uint16_t value_handle; // start handle > value handle value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0xf000, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); CHECK_EQUAL(0, value_handle); // end handle < value handle value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0x02, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); CHECK_EQUAL(0, value_handle); // search value handle for unknown UUID value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xffff); CHECK_EQUAL(0, value_handle); value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0); CHECK_EQUAL(0, value_handle); // search value handle after one with uuid128_no_bluetooth_base value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION); CHECK_EQUAL(0x0014, value_handle); // search value handle after one with uuid128_with_bluetooth_base value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME); CHECK_EQUAL(0x001a, value_handle); // search value handle registered with bluetooth_base value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xbbbb); CHECK_EQUAL(0x0017, value_handle); // correct read value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); CHECK_EQUAL(0x03, value_handle); } TEST(ATT_SERVER, att_server_indicate){ static uint8_t value[] = {0x55}; uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); uint8_t status; // invalid connection handle status = att_server_indicate(0x50, value_handle, &value[0], 0); CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); // L2CAP cannot send l2cap_can_send_fixed_channel_packet_now_set_status(0); status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); l2cap_can_send_fixed_channel_packet_now_set_status(1); // correct command status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(ERROR_CODE_SUCCESS, status); // already in progress status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS, status); } TEST(ATT_SERVER, att_server_notify){ static uint8_t value[] = {0x55}; uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); uint8_t status; // invalid connection handle status = att_server_notify(0x50, value_handle, &value[0], 0); CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); // L2CAP cannot send l2cap_can_send_fixed_channel_packet_now_set_status(0); status = att_server_notify(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); l2cap_can_send_fixed_channel_packet_now_set_status(1); // correct command status = att_server_notify(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(ERROR_CODE_SUCCESS, status); } TEST(ATT_SERVER, att_server_get_mtu){ // invalid connection handle uint8_t mtu = att_server_get_mtu(0x50); CHECK_EQUAL(0, mtu); mtu = att_server_get_mtu(att_con_handle); CHECK_EQUAL(23, mtu); } TEST(ATT_SERVER, att_server_request_can_send_now_event){ att_server_request_can_send_now_event(att_con_handle); } TEST(ATT_SERVER, att_server_can_send_packet_now){ int status = att_server_can_send_packet_now(att_con_handle); CHECK_EQUAL(1, status); status = att_server_can_send_packet_now(0x50); CHECK_EQUAL(0, status); } TEST(ATT_SERVER, att_server_request_to_send_indication){ int status = att_server_request_to_send_indication(&indication_callback, 0x55); CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); l2cap_can_send_fixed_channel_packet_now_set_status(0); status = att_server_request_to_send_indication(&indication_callback, att_con_handle); CHECK_EQUAL(ERROR_CODE_SUCCESS, status); status = att_server_request_to_send_indication(&indication_callback, att_con_handle); CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); } TEST(ATT_SERVER, att_server_request_to_send_notification){ int status = att_server_request_to_send_notification(¬ification_callback, 0x55); CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); l2cap_can_send_fixed_channel_packet_now_set_status(0); status = att_server_request_to_send_notification(¬ification_callback, att_con_handle); CHECK_EQUAL(ERROR_CODE_SUCCESS, status); status = att_server_request_to_send_notification(¬ification_callback, att_con_handle); CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); } TEST(ATT_SERVER, att_server_register_can_send_now_callback){ int status = att_server_register_can_send_now_callback(¬ification_callback, 0x55); CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); att_server_register_packet_handler(&att_event_packet_handler); } TEST(ATT_SERVER, att_packet_handler_ATT_DATA_PACKET){ uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); uint8_t buffer[] = {1, 0}; uint16_t att_request_len = att_write_request(ATT_WRITE_REQUEST, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_ATT_DATA_PACKET1){ uint16_t value_handle; uint16_t att_request_len; value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); att_request_len = att_read_request(ATT_READ_REQUEST, value_handle); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_invalid_opcode){ uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_POWER_STATE); uint8_t buffer[] = {1, 0}; uint16_t att_request_len = att_write_request(0xFF, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_ATT_HANDLE_VALUE_CONFIRMATION){ hci_setup_le_connection(att_con_handle); static uint8_t value[] = {0x55}; uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); l2cap_can_send_fixed_channel_packet_now_set_status(1); // correct command uint8_t status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(ERROR_CODE_SUCCESS, status); static uint8_t buffer[0]; uint16_t att_request_len = att_write_request(ATT_HANDLE_VALUE_CONFIRMATION, value_handle, 0, buffer); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_ATT_WRITE_COMMAND){ uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); static uint8_t buffer[] = {0x55}; uint16_t att_request_len = att_write_request(ATT_WRITE_COMMAND, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_ATT_WRITE_COMMAND_wrong_buffer_size){ uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); static uint8_t buffer[] = {0x55}; att_write_request(ATT_SIGNED_WRITE_COMMAND, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], ATT_REQUEST_BUFFER_SIZE + 100); } TEST(ATT_SERVER, att_packet_handler_ATT_WRITE_COMMAND_signed_write_confirmation){ hci_setup_le_connection(att_con_handle); uint8_t signed_write_value[] = {0x12}; uint8_t hash[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; uint16_t signed_write_characteristic_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CSC_FEATURE); uint8_t att_request[20]; int value_length = sizeof(signed_write_value); att_request[0] = ATT_SIGNED_WRITE_COMMAND; little_endian_store_16(att_request, 1, signed_write_characteristic_handle); memcpy(&att_request[3], signed_write_value, value_length); little_endian_store_32(att_request, 3 + value_length, 0); reverse_64(hash, &att_request[3 + value_length + 4]); // wrong size mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], value_length + 12u); set_cmac_ready(0); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], value_length + 12u + 3u); set_cmac_ready(1); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], value_length + 12u + 3u); // set ir_lookup_active = 1 uint8_t buffer[20]; buffer[0] = SM_EVENT_IDENTITY_RESOLVING_STARTED; buffer[1] = 9; little_endian_store_16(buffer, 2, att_con_handle); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], 11); mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], value_length + 12u + 3u); buffer[0] = SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED; buffer[1] = 18; // H1B1B2 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], 11); } TEST(ATT_SERVER, att_packet_handler_ATT_UNKNOWN_PACKET){ uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); uint8_t buffer[] = {1, 0}; uint16_t att_request_len = att_write_request(ATT_WRITE_REQUEST, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(0xFF, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_HCI_EVENT_PACKET_L2CAP_EVENT_CAN_SEND_NOW){ uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); // local cid uint8_t buffer[] = {1, 0}; uint16_t att_request_len = att_write_request(L2CAP_EVENT_CAN_SEND_NOW, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(HCI_EVENT_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_HCI_EVENT_PACKET_ATT_EVENT_MTU_EXCHANGE_COMPLETE){ uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); uint8_t buffer[4]; // invalid con handle memset(buffer, 0, sizeof(buffer)); little_endian_store_16(buffer, 2, 256); uint16_t att_request_len = att_write_request(ATT_EVENT_MTU_EXCHANGE_COMPLETE, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(HCI_EVENT_PACKET, 0, &att_request[0], att_request_len); little_endian_store_16(buffer, 0, att_con_handle); att_request_len = att_write_request(ATT_EVENT_MTU_EXCHANGE_COMPLETE, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(HCI_EVENT_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, att_packet_handler_HCI_EVENT_PACKET_ATT_EVENT_UNKNOWN){ uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); uint8_t buffer[] = {1, 0}; // unknown subevent uint16_t att_request_len = att_write_request(0x7bu, value_handle, sizeof(buffer), buffer); mock_call_att_server_packet_handler(HCI_EVENT_PACKET, att_con_handle, &att_request[0], att_request_len); } TEST(ATT_SERVER, connection_complete_event){ uint8_t buffer[21]; buffer[0] = HCI_EVENT_LE_META; buffer[1] = 19; buffer[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE; // call with wrong con_handle little_endian_store_16(buffer,4,HCI_CON_HANDLE_INVALID); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); // call with correct con_handle little_endian_store_16(buffer,4,att_con_handle); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); // use max MTU > ATT_REQUEST_BUFFER_SIZE mock_l2cap_set_max_mtu(ATT_REQUEST_BUFFER_SIZE + 10); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); // wrong subevent buffer[2] = 0xFF; mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); } TEST(ATT_SERVER, unknown_packet_type){ uint8_t buffer[21]; buffer[0] = HCI_EVENT_LE_META; buffer[1] = 1; buffer[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE; mock_call_att_packet_handler(0xFF, 0, &buffer[0], sizeof(buffer)); } TEST(ATT_SERVER, connection_disconnect_complete_event) { uint8_t buffer[6]; buffer[0] = HCI_EVENT_DISCONNECTION_COMPLETE; buffer[1] = 19; buffer[2] = 0; // call with wrong con_handle hci_setup_le_connection(att_con_handle); little_endian_store_16(buffer, 3, HCI_CON_HANDLE_INVALID); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); // call with correct con_handle, classic connection hci_setup_classic_connection(att_con_handle); little_endian_store_16(buffer, 3, att_con_handle); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); // call with correct con_handle, le connection hci_setup_le_connection(att_con_handle); little_endian_store_16(buffer, 3, att_con_handle); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); hci_setup_le_connection(att_con_handle); static uint8_t value[] = {0x55}; uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); l2cap_can_send_fixed_channel_packet_now_set_status(1); // correct command uint8_t status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); CHECK_EQUAL(ERROR_CODE_SUCCESS, status); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); } static void test_hci_event_encryption_events(hci_con_handle_t con_handle, uint8_t con_handle_index, uint8_t * buffer, uint16_t buffer_size){ // call with wrong con_handle hci_setup_le_connection(con_handle); little_endian_store_16(buffer, con_handle_index, HCI_CON_HANDLE_INVALID); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], buffer_size); // call with correct con_handle, classic connection hci_setup_classic_connection(con_handle); little_endian_store_16(buffer, con_handle_index, con_handle); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], buffer_size); // call with correct con_handle, le connection hci_setup_le_connection(con_handle); little_endian_store_16(buffer, con_handle_index, con_handle); mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], buffer_size); } TEST(ATT_SERVER, hci_event_encryption_key_refresh_complete_event) { uint8_t buffer[5]; buffer[0] = HCI_EVENT_ENCRYPTION_KEY_REFRESH_COMPLETE; buffer[1] = 3; buffer[2] = 0; // con_handle (2) test_hci_event_encryption_events(att_con_handle, 3, buffer, sizeof(buffer)); } TEST(ATT_SERVER, hci_event_encryption_change_v2_event) { uint8_t buffer[7]; buffer[0] = HCI_EVENT_ENCRYPTION_CHANGE_V2; buffer[1] = 5; buffer[2] = 0; // con_handle (2) // encryption_key_size buffer[6] = 1; // encryption_enabled (1) buffer[5] = 0; test_hci_event_encryption_events(att_con_handle, 3, buffer, sizeof(buffer)); // encryption_enabled (1) buffer[5] = 1; test_hci_event_encryption_events(att_con_handle, 3, buffer, sizeof(buffer)); } TEST(ATT_SERVER, hci_event_encryption_change_event) { uint8_t buffer[6]; buffer[0] = HCI_EVENT_ENCRYPTION_CHANGE; buffer[1] = 4; buffer[2] = 0; // con_handle (2)att_packet_handler_ATT_UNKNOWN_PACKET // encryption_enabled (1) buffer[5] = 0; test_hci_event_encryption_events(att_con_handle, 3, buffer, sizeof(buffer)); // encryption_enabled (1) buffer[5] = 1; test_hci_event_encryption_events(att_con_handle, 3, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_identity_resolving_started_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_IDENTITY_RESOLVING_STARTED; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_identity_resolving_succeeded_event) { uint8_t buffer[20]; buffer[0] = SM_EVENT_IDENTITY_RESOLVING_SUCCEEDED; buffer[1] = 18; // H1B1B2 test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_identity_resolving_failed_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_IDENTITY_RESOLVING_FAILED; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } // TEST(ATT_SERVER, sm_event_just_works_request_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_JUST_WORKS_REQUEST; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_passkey_display_number_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_PASSKEY_DISPLAY_NUMBER; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_passkey_input_number_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_PASSKEY_INPUT_NUMBER; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_numeric_comparison_request_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_NUMERIC_COMPARISON_REQUEST; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_identity_created_event) { uint8_t buffer[20]; buffer[0] = SM_EVENT_IDENTITY_CREATED; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_pairing_complete_event) { uint8_t buffer[11]; buffer[0] = SM_EVENT_PAIRING_COMPLETE; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, sm_event_authorization_result_event) { uint8_t buffer[12]; buffer[0] = SM_EVENT_AUTHORIZATION_RESULT; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, unknown_event) { uint8_t buffer[11]; buffer[0] = 0xFF; buffer[1] = 9; test_hci_event_encryption_events(att_con_handle, 2, buffer, sizeof(buffer)); } TEST(ATT_SERVER, att_server_register_service_handler) { att_service_handler_t test_service; test_service.read_callback = att_read_callback; test_service.write_callback = att_write_callback; uint16_t start_handle = 0; uint16_t end_handle = 0xffff; int service_found = gatt_server_get_handle_range_for_service_with_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE, &start_handle, &end_handle); CHECK_EQUAL(service_found, 1); test_service.start_handle = start_handle; test_service.end_handle = end_handle; att_server_register_service_handler(&test_service); test_service.start_handle = start_handle; test_service.end_handle = 0; att_server_register_service_handler(&test_service); test_service.start_handle = 0; test_service.end_handle = end_handle; att_server_register_service_handler(&test_service); test_service.start_handle = 0; test_service.end_handle = 0; att_server_register_service_handler(&test_service); } int main (int argc, const char * argv[]){ return CommandLineTestRunner::RunAllTests(argc, argv); }