test/gatt_server: test connection complete and disconnect events

This commit is contained in:
Milanka Ringwald 2021-12-15 20:38:34 +01:00
parent a8c93a4e4e
commit 8206902c42
3 changed files with 114 additions and 37 deletions

View File

@ -47,6 +47,10 @@ set(SOURCES
mock.c
)
# Enable ASAN
add_compile_options( -g -fsanitize=address)
add_link_options( -fsanitize=address)
# create static lib
add_library(btstack STATIC ${SOURCES})

View File

@ -31,7 +31,9 @@ static const uint8_t uuid128_no_bluetooth_base[] = { 0xFB, 0x34, 0x9B, 0x5F, 0
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 att_init_connection(uint16_t con_handle);
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);
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){
@ -64,20 +66,30 @@ static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_h
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 = 0x00;
att_con_handle = 0x01;
hci_setup_le_connection(att_con_handle);
att_init_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();
@ -111,10 +123,10 @@ TEST_GROUP(ATT_SERVER){
void teardown(void) {
mock_btstack_tlv_deinit(&tlv_context);
hci_deinit();
}
};
TEST(ATT_SERVER, gatt_server_get_value_handle_for_characteristic_with_uuid16){
// att_dump_attributes();
uint16_t value_handle;
@ -207,7 +219,6 @@ TEST(ATT_SERVER, att_server_get_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){
@ -218,11 +229,7 @@ TEST(ATT_SERVER, att_server_can_send_packet_now){
CHECK_EQUAL(0, status);
}
static btstack_context_callback_registration_t indication_callback;
TEST(ATT_SERVER, att_server_request_to_send_indication){
indication_callback.callback = &att_client_indication_callback;
int status = att_server_request_to_send_indication(&indication_callback, 0x55);
CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
@ -235,13 +242,73 @@ TEST(ATT_SERVER, att_server_request_to_send_indication){
CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
}
TEST(ATT_SERVER, att_server_request_to_send_notification){
int status = att_server_request_to_send_notification(&notification_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(&notification_callback, att_con_handle);
CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
status = att_server_request_to_send_notification(&notification_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(&notification_callback, 0x55);
CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
att_server_register_packet_handler(&att_event_packet_handler);
}
TEST(ATT_SERVER, opcode_ATT_WRITE_REQUEST){
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, 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, 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
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
little_endian_store_16(buffer, 3, att_con_handle);
mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer));
}
int main (int argc, const char * argv[]){
return CommandLineTestRunner::RunAllTests(argc, argv);
}

View File

@ -18,8 +18,8 @@ static btstack_packet_handler_t att_server_packet_handler;
static void (*registered_hci_event_handler) (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) = NULL;
static btstack_linked_list_t connections;
static const uint16_t max_mtu = 23;
static uint8_t l2cap_stack_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + 8 + max_mtu]; // pre buffer + HCI Header + L2CAP header
static uint16_t max_mtu = 23;
static uint8_t l2cap_stack_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + 8 + ATT_DEFAULT_MTU]; // pre buffer + HCI Header + L2CAP header
static uint16_t gatt_client_handle = 0x40;
static hci_connection_t hci_connection;
@ -62,7 +62,7 @@ int gap_reconnect_security_setup_active(hci_con_handle_t con_handle){
return 0;
}
void att_init_connection(uint16_t con_handle){
void hci_setup_le_connection(uint16_t con_handle){
hci_connection.att_connection.mtu = 23;
hci_connection.att_connection.con_handle = con_handle;
hci_connection.att_connection.max_mtu = 23;
@ -72,17 +72,32 @@ void att_init_connection(uint16_t con_handle){
hci_connection.att_server.ir_le_device_db_index = 0;
hci_connection.con_handle = con_handle;
if (btstack_linked_list_empty(&connections)){
btstack_linked_list_add(&connections, (btstack_linked_item_t *)&hci_connection);
}
}
void hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler){
registered_hci_event_handler = callback_handler->callback;
void mock_l2cap_set_max_mtu(uint16_t mtu){
max_mtu = mtu;
}
bool hci_can_send_acl_le_packet_now(void){
return true;
void hci_deinit(void){
hci_connection.att_connection.mtu = 0;
hci_connection.att_connection.con_handle = HCI_CON_HANDLE_INVALID;
hci_connection.att_connection.max_mtu = 0;
hci_connection.att_connection.encryption_key_size = 0;
hci_connection.att_connection.authenticated = 0;
hci_connection.att_connection.authorized = 0;
hci_connection.att_server.ir_le_device_db_index = 0;
hci_connection.att_server.notification_requests = NULL;
hci_connection.att_server.indication_requests = NULL;
connections = NULL;
}
void hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler){
registered_hci_event_handler = callback_handler->callback;
}
bool hci_can_send_command_packet_now(void){
@ -120,8 +135,7 @@ uint16_t l2cap_max_mtu(void){
}
uint16_t l2cap_max_le_mtu(void){
// printf("l2cap_max_mtu\n");
return max_mtu;
return max_mtu;
}
void l2cap_init(void){}
@ -150,7 +164,7 @@ void l2cap_request_can_send_fix_channel_now_event(uint16_t handle, uint16_t chan
uint8_t l2cap_send_prepared_connectionless(uint16_t handle, uint16_t cid, uint16_t len){
att_connection_t att_connection;
att_init_connection(handle);
hci_setup_le_connection(handle);
uint8_t response[max_mtu];
uint16_t response_len = att_handle_request(&att_connection, l2cap_get_outgoing_buffer(), len, &response[0]);
if (response_len){
@ -204,30 +218,17 @@ hci_connection_t * hci_connection_for_bd_addr_and_type(const bd_addr_t addr, bd_
return NULL;
}
hci_connection_t * hci_connection_for_handle(hci_con_handle_t con_handle){
if (con_handle != hci_connection.con_handle) return NULL;
return &hci_connection;
if (hci_connection.con_handle != con_handle){
return NULL;
}
return &hci_connection;
}
void hci_connections_get_iterator(btstack_linked_list_iterator_t *it){
// printf("hci_connections_get_iterator not implemented in mock backend\n");
btstack_linked_list_iterator_init(it, &connections);
}
// int hci_send_cmd(const hci_cmd_t *cmd, ...){
// // printf("hci_send_cmd opcode 0x%02x\n", cmd->opcode);
// return 0;
// }
// int hci_can_send_packet_now_using_packet_buffer(uint8_t packet_type){
// return 1;
// }
// void hci_disconnect_security_block(hci_con_handle_t con_handle){
// printf("hci_disconnect_security_block \n");
// }
// void hci_dump_log(const char * format, ...){
// printf("hci_disconnect_security_block \n");
// }
void l2cap_run(void){
}
@ -259,6 +260,10 @@ void mock_call_att_server_packet_handler(uint8_t packet_type, uint16_t channel,
(*att_server_packet_handler)(packet_type, channel, packet, size);
}
void mock_call_att_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
(*registered_hci_event_handler)(packet_type, channel, packet, size);
}
void att_dispatch_register_server(btstack_packet_handler_t packet_handler){
att_server_packet_handler = packet_handler;
}
@ -279,3 +284,4 @@ void att_dispatch_server_request_can_send_now_event(hci_con_handle_t con_handle)
att_server_packet_handler(HCI_EVENT_PACKET, 0, (uint8_t*)event, sizeof(event));
}
}