mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-03 23:47:08 +00:00
255 lines
10 KiB
C++
255 lines
10 KiB
C++
|
|
// *****************************************************************************
|
|
//
|
|
// test battery service
|
|
//
|
|
// *****************************************************************************
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "CppUTest/TestHarness.h"
|
|
#include "CppUTest/CommandLineTestRunner.h"
|
|
#include "CppUTestExt/MockSupport.h"
|
|
|
|
#include "hci.h"
|
|
#include "gap.h"
|
|
#include "btstack_util.h"
|
|
#include "bluetooth.h"
|
|
#include "bluetooth_gatt.h"
|
|
#include "ble/le_device_db.h"
|
|
#include "ble/gatt-service/bond_management_service_server.h"
|
|
#include "bond_management_service_profile.h"
|
|
#include "mock_att_server.h"
|
|
|
|
static uint32_t bond_management_features = 0xFFFFFF;
|
|
static uint8_t request[550];
|
|
|
|
// mocks
|
|
void gap_delete_bonding(bd_addr_type_t address_type, bd_addr_t address){
|
|
// traack call if needed
|
|
}
|
|
void gap_drop_link_key_for_bd_addr(bd_addr_t addr){
|
|
// traack call if needed
|
|
}
|
|
int gap_link_key_iterator_init(btstack_link_key_iterator_t * it){
|
|
return 1;
|
|
}
|
|
int gap_link_key_iterator_get_next(btstack_link_key_iterator_t * it, bd_addr_t bd_addr, link_key_t link_key, link_key_type_t * type){
|
|
// link keys!!
|
|
return 0;
|
|
}
|
|
void gap_link_key_iterator_done(btstack_link_key_iterator_t * it){
|
|
}
|
|
static hci_connection_t test_connection;
|
|
hci_connection_t * hci_connection_for_handle(hci_con_handle_t con_handle){
|
|
memset(test_connection.address, 0x33, 6);
|
|
test_connection.address_type = BD_ADDR_TYPE_ACL;
|
|
return &test_connection;
|
|
}
|
|
int le_device_db_max_count(void){
|
|
return 0;
|
|
}
|
|
void le_device_db_info(int index, int * addr_type, bd_addr_t addr, sm_key_t irk){
|
|
}
|
|
//
|
|
|
|
TEST_GROUP(BOND_MANAGEMENT_SERVICE_SERVER){
|
|
att_service_handler_t * service;
|
|
uint16_t con_handle;
|
|
uint16_t bm_features_value_handle;
|
|
uint16_t bm_control_point_value_handle;
|
|
|
|
void setup(void){
|
|
// setup database
|
|
att_set_db(profile_data);
|
|
bm_features_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BOND_MANAGEMENT_FEATURE);
|
|
bm_control_point_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BOND_MANAGEMENT_CONTROL_POINT);
|
|
// setup tx power service
|
|
con_handle = 0x00;
|
|
}
|
|
|
|
void validate_write_control_point(uint32_t local_flag, const char * local_auth_str, uint8_t remote_cmd, const char * remote_auth_str, uint16_t expected_outcome){
|
|
bond_management_service_server_init(local_flag);
|
|
service = mock_att_server_get_service();
|
|
bond_management_service_server_set_authorisation_string(local_auth_str);
|
|
|
|
request[0] = remote_cmd;
|
|
uint16_t remote_auth_str_len = 0;
|
|
if (remote_auth_str != NULL) {
|
|
remote_auth_str_len = strlen(remote_auth_str);
|
|
}
|
|
memcpy(&request[1], remote_auth_str, remote_auth_str_len);
|
|
uint16_t request_len = 1 + remote_auth_str_len;
|
|
int response = mock_att_service_write_callback(con_handle, bm_control_point_value_handle, ATT_TRANSACTION_MODE_NONE, 0, request, request_len);
|
|
CHECK_EQUAL(expected_outcome, response);
|
|
}
|
|
|
|
void teardown(){
|
|
mock_deinit();
|
|
}
|
|
};
|
|
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, lookup_attribute_handles){
|
|
bond_management_service_server_init(bond_management_features);
|
|
service = mock_att_server_get_service();
|
|
|
|
CHECK(bm_features_value_handle != 0);
|
|
CHECK(bm_control_point_value_handle != 0);
|
|
}
|
|
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, read_bm_features_value0){
|
|
uint8_t response[10];
|
|
uint16_t response_len;
|
|
|
|
bond_management_service_server_init(0x00);
|
|
service = mock_att_server_get_service();
|
|
|
|
// invalid attribute handle
|
|
response_len = mock_att_service_read_callback(con_handle, 0xffff, 0xffff, response, sizeof(response));
|
|
CHECK_EQUAL(0, response_len);
|
|
|
|
response_len = mock_att_service_read_callback(con_handle, bm_features_value_handle, 0, response, sizeof(response));
|
|
CHECK_EQUAL(3, response_len);
|
|
}
|
|
|
|
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, read_bm_features_value1){
|
|
uint8_t response[10];
|
|
uint16_t response_len;
|
|
|
|
bond_management_service_server_init(0xFF);
|
|
service = mock_att_server_get_service();
|
|
|
|
response_len = mock_att_service_read_callback(con_handle, bm_features_value_handle, 0, response, sizeof(response));
|
|
CHECK_EQUAL(3, response_len);
|
|
}
|
|
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, read_bm_features_value2){
|
|
uint8_t response[10];
|
|
uint16_t response_len;
|
|
|
|
bond_management_service_server_init(0xFFFF);
|
|
service = mock_att_server_get_service();
|
|
|
|
response_len = mock_att_service_read_callback(con_handle, bm_features_value_handle, 0, response, sizeof(response));
|
|
CHECK_EQUAL(3, response_len);
|
|
}
|
|
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, read_bm_features_value3){
|
|
uint8_t response[10];
|
|
uint16_t response_len;
|
|
|
|
// invalid attribute handle
|
|
bond_management_service_server_init(0xFFFFFF);
|
|
service = mock_att_server_get_service();
|
|
|
|
response_len = mock_att_service_read_callback(con_handle, bm_features_value_handle, 0, response, sizeof(response));
|
|
CHECK_EQUAL(3, response_len);
|
|
}
|
|
|
|
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_bm_control_point_0){
|
|
uint8_t request[520];
|
|
uint16_t request_len = sizeof(request);
|
|
int response;
|
|
|
|
// invalid attribute handle
|
|
bond_management_service_server_init(0xFFFFFF);
|
|
service = mock_att_server_get_service();
|
|
|
|
// wrong handle
|
|
response = mock_att_service_write_callback(con_handle, 0xffff, ATT_TRANSACTION_MODE_NONE, 0, request, request_len);
|
|
CHECK_EQUAL(response, 0);
|
|
|
|
// buffer size 0
|
|
response = mock_att_service_write_callback(con_handle, bm_control_point_value_handle, ATT_TRANSACTION_MODE_NONE, 0, NULL, 0);
|
|
CHECK_EQUAL(response, BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED);
|
|
|
|
// wrong cmd
|
|
request[0] = 20;
|
|
response = mock_att_service_write_callback(con_handle, bm_control_point_value_handle, ATT_TRANSACTION_MODE_NONE, 0, request, request_len);
|
|
CHECK_EQUAL(response, BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED);
|
|
|
|
// wrong authorisation code len: request_len > 512
|
|
request[0] = BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE;
|
|
response = mock_att_service_write_callback(con_handle, bm_control_point_value_handle, ATT_TRANSACTION_MODE_NONE, 0, request, request_len);
|
|
CHECK_EQUAL(response, BOND_MANAGEMENT_OPERATION_FAILED);
|
|
}
|
|
|
|
|
|
// locally no (string empty), remote no (string empty) -> OK
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ln_empty_rn_empty){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, NULL,
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, NULL, 0);
|
|
}
|
|
|
|
// locally no (string exists), remote no (string empty) -> OK
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ln_exists_rn_empty){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "local_auth_str",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, NULL, 0);
|
|
}
|
|
|
|
// locally no (string empty), remote yes (string exists) -> BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ln_empty_ry_exists){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "remote",
|
|
BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED);
|
|
}
|
|
|
|
// locally no (string exists), remote yes (string exists) -> BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ln_exists_ry_exists){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "local_auth_str",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "remote_auth_str",
|
|
BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED);
|
|
}
|
|
|
|
// locally no (string exists), remote yes, (string exact) -> BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ln_exists_ry_exact){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "auth_str",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "auth_str",
|
|
BOND_MANAGEMENT_CONTROL_POINT_OPCODE_NOT_SUPPORTED);
|
|
}
|
|
|
|
// locally yes (string empty), remote no (string empty) -> ATT_ERROR_INSUFFICIENT_AUTHORIZATION
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ly_empty_ry_empty){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE_WITH_AUTH, NULL,
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, NULL,
|
|
ATT_ERROR_INSUFFICIENT_AUTHORIZATION);
|
|
}
|
|
|
|
// locally yes (string exists), remote no (string empty) -> ATT_ERROR_INSUFFICIENT_AUTHORIZATION
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ly_exists_rn_empty){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE_WITH_AUTH, "local_auth_str",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, NULL,
|
|
ATT_ERROR_INSUFFICIENT_AUTHORIZATION);
|
|
}
|
|
|
|
// locally yes (string exists), remote yes (string exists) -> ATT_ERROR_INSUFFICIENT_AUTHORIZATION
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ly_exists_ry_exists){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE_WITH_AUTH, "local_auth_str",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "remote_auth_str",
|
|
ATT_ERROR_INSUFFICIENT_AUTHORIZATION);
|
|
}
|
|
|
|
// locally yes (string exists), remote yes, (string exact) -> OK
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ly_exists_ry_exact){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE_WITH_AUTH, "auth_str",
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "auth_str",
|
|
0);
|
|
}
|
|
|
|
// locally yes (string empty), remote yes (string exists) -> ATT_ERROR_INSUFFICIENT_AUTHORIZATION
|
|
TEST(BOND_MANAGEMENT_SERVICE_SERVER, write_control_point_ly_empty_ry_exists){
|
|
validate_write_control_point(BMF_DELETE_ACTIVE_BOND_CLASSIC_AND_LE_WITH_AUTH, NULL,
|
|
BOND_MANAGEMENT_CMD_DELETE_ACTIVE_BOND_CLASSIC_AND_LE, "remote",
|
|
ATT_ERROR_INSUFFICIENT_AUTHORIZATION);
|
|
}
|
|
|
|
int main (int argc, const char * argv[]){
|
|
return CommandLineTestRunner::RunAllTests(argc, argv);
|
|
}
|