1d3762d15SMatthias Ringwald #include <stdint.h>
2d3762d15SMatthias Ringwald #include <stdio.h>
3d3762d15SMatthias Ringwald #include <stdlib.h>
4d3762d15SMatthias Ringwald #include <string.h>
5d3762d15SMatthias Ringwald
6d3762d15SMatthias Ringwald #include "CppUTest/TestHarness.h"
7d3762d15SMatthias Ringwald #include "CppUTest/CommandLineTestRunner.h"
8d3762d15SMatthias Ringwald #include "CppUTestExt/MockSupport.h"
9d3762d15SMatthias Ringwald
10d3762d15SMatthias Ringwald #include "hci_cmd.h"
11d3762d15SMatthias Ringwald
12d3762d15SMatthias Ringwald #include "btstack_memory.h"
13d3762d15SMatthias Ringwald #include "hci.h"
14*1520bf5bSMatthias Ringwald
15*1520bf5bSMatthias Ringwald #include <bluetooth_company_id.h>
16*1520bf5bSMatthias Ringwald
17d3762d15SMatthias Ringwald #include "ble/gatt_client.h"
18d3762d15SMatthias Ringwald #include "btstack_event.h"
19d3762d15SMatthias Ringwald #include "hci_dump.h"
20d3762d15SMatthias Ringwald #include "hci_dump_posix_fs.h"
21d3762d15SMatthias Ringwald #include "btstack_debug.h"
22fcebe167SMilanka Ringwald #include "btstack_util.h"
23fcebe167SMilanka Ringwald #include "btstack_run_loop_posix.h"
24d3762d15SMatthias Ringwald
25d3762d15SMatthias Ringwald typedef struct {
26d3762d15SMatthias Ringwald uint8_t type;
27d3762d15SMatthias Ringwald uint16_t size;
28d3762d15SMatthias Ringwald uint8_t buffer[258];
29d3762d15SMatthias Ringwald } hci_packet_t;
30d3762d15SMatthias Ringwald
31d3762d15SMatthias Ringwald #define MAX_HCI_PACKETS 10
32d3762d15SMatthias Ringwald static uint16_t transport_count_packets;
33d3762d15SMatthias Ringwald static hci_packet_t transport_packets[MAX_HCI_PACKETS];
3428739e5fSMatthias Ringwald static int can_send_now = 1;
35d3762d15SMatthias Ringwald static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size);
36d3762d15SMatthias Ringwald
375308d607SMatthias Ringwald #if 0
385308d607SMatthias Ringwald static btstack_timer_source_t packet_sent_timer;
395308d607SMatthias Ringwald
40d3762d15SMatthias Ringwald static const uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
41d3762d15SMatthias Ringwald
425308d607SMatthias Ringwald // sm_trigger_run allows to schedule callback from main run loop // reduces stack depth
435308d607SMatthias Ringwald static void hci_transport_emit_packet_sent(btstack_timer_source_t * ts){
445308d607SMatthias Ringwald UNUSED(ts);
455308d607SMatthias Ringwald // notify upper stack that it can send again
465308d607SMatthias Ringwald can_send_now = 1;
475308d607SMatthias Ringwald packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event));
485308d607SMatthias Ringwald }
495308d607SMatthias Ringwald
505308d607SMatthias Ringwald static void hci_transport_trigger_packet_sent(void) {
515308d607SMatthias Ringwald btstack_run_loop_remove_timer(&packet_sent_timer);
525308d607SMatthias Ringwald btstack_run_loop_set_timer_handler(&packet_sent_timer, &hci_transport_emit_packet_sent);
535308d607SMatthias Ringwald btstack_run_loop_set_timer(&packet_sent_timer, 0);
545308d607SMatthias Ringwald btstack_run_loop_add_timer(&packet_sent_timer);
55d3762d15SMatthias Ringwald }
56d3762d15SMatthias Ringwald
57d3762d15SMatthias Ringwald static int hci_transport_test_can_send_now(uint8_t packet_type){
5828739e5fSMatthias Ringwald return can_send_now;
59d3762d15SMatthias Ringwald }
605308d607SMatthias Ringwald #endif
615308d607SMatthias Ringwald
hci_transport_test_set_baudrate(uint32_t baudrate)625308d607SMatthias Ringwald static int hci_transport_test_set_baudrate(uint32_t baudrate){
635308d607SMatthias Ringwald return 0;
645308d607SMatthias Ringwald }
65d3762d15SMatthias Ringwald
hci_transport_test_send_packet(uint8_t packet_type,uint8_t * packet,int size)66d3762d15SMatthias Ringwald static int hci_transport_test_send_packet(uint8_t packet_type, uint8_t * packet, int size){
67d3762d15SMatthias Ringwald btstack_assert(transport_count_packets < MAX_HCI_PACKETS);
68d3762d15SMatthias Ringwald memcpy(transport_packets[transport_count_packets].buffer, packet, size);
69d3762d15SMatthias Ringwald transport_packets[transport_count_packets].type = packet_type;
70d3762d15SMatthias Ringwald transport_packets[transport_count_packets].size = size;
71d3762d15SMatthias Ringwald transport_count_packets++;
72d3762d15SMatthias Ringwald return 0;
73d3762d15SMatthias Ringwald }
74d3762d15SMatthias Ringwald
hci_transport_test_init(const void * transport_config)75d3762d15SMatthias Ringwald static void hci_transport_test_init(const void * transport_config){
76d3762d15SMatthias Ringwald }
77d3762d15SMatthias Ringwald
hci_transport_test_open(void)78d3762d15SMatthias Ringwald static int hci_transport_test_open(void){
79d3762d15SMatthias Ringwald return 0;
80d3762d15SMatthias Ringwald }
81d3762d15SMatthias Ringwald
hci_transport_test_close(void)82d3762d15SMatthias Ringwald static int hci_transport_test_close(void){
83d3762d15SMatthias Ringwald return 0;
84d3762d15SMatthias Ringwald }
85d3762d15SMatthias Ringwald
hci_transport_test_register_packet_handler(void (* handler)(uint8_t packet_type,uint8_t * packet,uint16_t size))86d3762d15SMatthias Ringwald static void hci_transport_test_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
87d3762d15SMatthias Ringwald packet_handler = handler;
88d3762d15SMatthias Ringwald }
89d3762d15SMatthias Ringwald
90d3762d15SMatthias Ringwald static const hci_transport_t hci_transport_test = {
91d3762d15SMatthias Ringwald /* const char * name; */ "TEST",
92d3762d15SMatthias Ringwald /* void (*init) (const void *transport_config); */ &hci_transport_test_init,
93d3762d15SMatthias Ringwald /* int (*open)(void); */ &hci_transport_test_open,
94d3762d15SMatthias Ringwald /* int (*close)(void); */ &hci_transport_test_close,
95d3762d15SMatthias Ringwald /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_test_register_packet_handler,
965308d607SMatthias Ringwald /* int (*can_send_packet_now)(uint8_t packet_type); */ NULL,
97d3762d15SMatthias Ringwald /* int (*send_packet)(...); */ &hci_transport_test_send_packet,
98d3762d15SMatthias Ringwald /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_test_set_baudrate,
99d3762d15SMatthias Ringwald /* void (*reset_link)(void); */ NULL,
100d3762d15SMatthias Ringwald /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL,
101d3762d15SMatthias Ringwald };
102d3762d15SMatthias Ringwald
103d3762d15SMatthias Ringwald static uint16_t next_hci_packet;
104d3762d15SMatthias Ringwald
CHECK_EQUAL_ARRAY(const uint8_t * expected,const uint8_t * actual,int size)1055308d607SMatthias Ringwald void CHECK_EQUAL_ARRAY(const uint8_t * expected, const uint8_t * actual, int size){
106d3762d15SMatthias Ringwald for (int i=0; i<size; i++){
107d3762d15SMatthias Ringwald BYTES_EQUAL(expected[i], actual[i]);
108d3762d15SMatthias Ringwald }
109d3762d15SMatthias Ringwald }
110d3762d15SMatthias Ringwald
CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command)111d3762d15SMatthias Ringwald void CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command){
112d3762d15SMatthias Ringwald uint16_t actual_opcode = little_endian_read_16(transport_packets[next_hci_packet].buffer, 0);
113d3762d15SMatthias Ringwald next_hci_packet++;
114d3762d15SMatthias Ringwald CHECK_EQUAL(expected_hci_command->opcode, actual_opcode);
115d3762d15SMatthias Ringwald }
116d3762d15SMatthias Ringwald
TEST_GROUP(HCI)117d3762d15SMatthias Ringwald TEST_GROUP(HCI){
118566df4e8SMatthias Ringwald hci_stack_t * hci_stack;
119566df4e8SMatthias Ringwald
120d3762d15SMatthias Ringwald void setup(void){
121d3762d15SMatthias Ringwald transport_count_packets = 0;
12228739e5fSMatthias Ringwald can_send_now = 1;
123d3762d15SMatthias Ringwald next_hci_packet = 0;
124d3762d15SMatthias Ringwald hci_init(&hci_transport_test, NULL);
125566df4e8SMatthias Ringwald hci_stack = hci_get_stack();
126d3762d15SMatthias Ringwald hci_simulate_working_fuzz();
127d3762d15SMatthias Ringwald hci_setup_test_connections_fuzz();
128d3762d15SMatthias Ringwald // register for HCI events
129d3762d15SMatthias Ringwald mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1);
130d3762d15SMatthias Ringwald }
131d3762d15SMatthias Ringwald void teardown(void){
132d3762d15SMatthias Ringwald mock().clear();
133d3762d15SMatthias Ringwald }
134d3762d15SMatthias Ringwald };
135d3762d15SMatthias Ringwald
TEST(HCI,GetSetConnectionRange)136d3762d15SMatthias Ringwald TEST(HCI, GetSetConnectionRange){
137d3762d15SMatthias Ringwald le_connection_parameter_range_t range;
138d3762d15SMatthias Ringwald gap_get_connection_parameter_range(&range);
139d3762d15SMatthias Ringwald gap_set_connection_parameter_range(&range);
140d3762d15SMatthias Ringwald }
141d3762d15SMatthias Ringwald
TEST(HCI,ConnectionRangeValid)142d3762d15SMatthias Ringwald TEST(HCI, ConnectionRangeValid){
143d3762d15SMatthias Ringwald le_connection_parameter_range_t range = {
144fcebe167SMilanka Ringwald .le_conn_interval_min = 1,
145fcebe167SMilanka Ringwald .le_conn_interval_max = 10,
146fcebe167SMilanka Ringwald .le_conn_latency_min = 1,
147fcebe167SMilanka Ringwald .le_conn_latency_max = 10,
148fcebe167SMilanka Ringwald .le_supervision_timeout_min = 1,
149fcebe167SMilanka Ringwald .le_supervision_timeout_max = 10
150d3762d15SMatthias Ringwald };
151d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 0, 0, 0, 0));
152fcebe167SMilanka Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 11, 0, 0));
153fcebe167SMilanka Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 11, 0));
154d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 0, 0, 0));
155d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 0, 0));
156d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 10, 0));
157d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 0));
158d3762d15SMatthias Ringwald CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 11));
159d3762d15SMatthias Ringwald CHECK_EQUAL( 1, gap_connection_parameter_range_included(&range, 2, 9, 5, 5));
160d3762d15SMatthias Ringwald }
161d3762d15SMatthias Ringwald
TEST(HCI,other_functions)162fcebe167SMilanka Ringwald TEST(HCI, other_functions){
163fcebe167SMilanka Ringwald gap_set_scan_phys(1);
164fcebe167SMilanka Ringwald gap_set_connection_phys(1);
165fcebe167SMilanka Ringwald hci_enable_custom_pre_init();
166fcebe167SMilanka Ringwald gap_whitelist_clear();
167fcebe167SMilanka Ringwald }
168fcebe167SMilanka Ringwald
TEST(HCI,gap_whitelist_add_remove)169fcebe167SMilanka Ringwald TEST(HCI, gap_whitelist_add_remove){
170fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL;
171fcebe167SMilanka Ringwald bd_addr_t addr = { 0 };
172fcebe167SMilanka Ringwald
173fcebe167SMilanka Ringwald uint8_t status = gap_whitelist_add(addr_type, addr);
174fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
175fcebe167SMilanka Ringwald
176fcebe167SMilanka Ringwald status = gap_whitelist_add(addr_type, addr);
177fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
178fcebe167SMilanka Ringwald
179fcebe167SMilanka Ringwald status = gap_whitelist_remove(addr_type, addr);
180fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
181fcebe167SMilanka Ringwald
182fcebe167SMilanka Ringwald status = gap_whitelist_remove(addr_type, addr);
183e406aa8dSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
184fcebe167SMilanka Ringwald
185fcebe167SMilanka Ringwald status = gap_whitelist_remove(BD_ADDR_TYPE_SCO, addr);
186fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
187fcebe167SMilanka Ringwald }
188fcebe167SMilanka Ringwald
TEST(HCI,gap_connect_with_whitelist)189fcebe167SMilanka Ringwald TEST(HCI, gap_connect_with_whitelist){
190fcebe167SMilanka Ringwald uint8_t status = gap_connect_with_whitelist();
191fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
192fcebe167SMilanka Ringwald
19328739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
19428739e5fSMatthias Ringwald bd_addr_t addr = { 0 };
19528739e5fSMatthias Ringwald gap_auto_connection_start(addr_type, addr);
19628739e5fSMatthias Ringwald
197fcebe167SMilanka Ringwald status = gap_connect_with_whitelist();
198fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
199fcebe167SMilanka Ringwald }
200fcebe167SMilanka Ringwald
TEST(HCI,gap_auto_connection_start_stop)201fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_start_stop){
202fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
203fcebe167SMilanka Ringwald bd_addr_t addr = { 0 };
204fcebe167SMilanka Ringwald
205fcebe167SMilanka Ringwald uint8_t status = gap_auto_connection_start(addr_type, addr);
206fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
207fcebe167SMilanka Ringwald
208fcebe167SMilanka Ringwald status = gap_auto_connection_stop(addr_type, addr);
209fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
210fcebe167SMilanka Ringwald }
211fcebe167SMilanka Ringwald
TEST(HCI,gap_auto_connection_stop_all)212fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_stop_all){
213fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
214fcebe167SMilanka Ringwald bd_addr_t addr = { 0 };
215fcebe167SMilanka Ringwald
216fcebe167SMilanka Ringwald uint8_t status = gap_auto_connection_start(addr_type, addr);
217fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
218fcebe167SMilanka Ringwald
219fcebe167SMilanka Ringwald status = gap_auto_connection_stop_all();
220fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
221fcebe167SMilanka Ringwald }
222fcebe167SMilanka Ringwald
TEST(HCI,gap_read_rssi)223fcebe167SMilanka Ringwald TEST(HCI, gap_read_rssi){
224fcebe167SMilanka Ringwald int status = gap_read_rssi(HCI_CON_HANDLE_INVALID);
225fcebe167SMilanka Ringwald CHECK_EQUAL(0, status);
226fcebe167SMilanka Ringwald
227fcebe167SMilanka Ringwald status = gap_read_rssi(0x01);
228fcebe167SMilanka Ringwald CHECK_EQUAL(1, status);
229fcebe167SMilanka Ringwald }
230fcebe167SMilanka Ringwald
TEST(HCI,gap_le_connection_interval)231fcebe167SMilanka Ringwald TEST(HCI, gap_le_connection_interval){
232fcebe167SMilanka Ringwald uint16_t con_interval = gap_le_connection_interval(HCI_CON_HANDLE_INVALID);
233fcebe167SMilanka Ringwald CHECK_EQUAL(0, con_interval);
234fcebe167SMilanka Ringwald
235fcebe167SMilanka Ringwald con_interval = gap_le_connection_interval(0x01);
236fcebe167SMilanka Ringwald CHECK_EQUAL(0, con_interval);
237fcebe167SMilanka Ringwald }
238fcebe167SMilanka Ringwald
239fcebe167SMilanka Ringwald
TEST(HCI,gap_get_connection_type)240fcebe167SMilanka Ringwald TEST(HCI, gap_get_connection_type){
241fcebe167SMilanka Ringwald gap_connection_type_t type = gap_get_connection_type(HCI_CON_HANDLE_INVALID);
242fcebe167SMilanka Ringwald CHECK_EQUAL(GAP_CONNECTION_INVALID, type);
243fcebe167SMilanka Ringwald
244fcebe167SMilanka Ringwald type = gap_get_connection_type(0x01);
245fcebe167SMilanka Ringwald CHECK_EQUAL(GAP_CONNECTION_ACL, type);
246fcebe167SMilanka Ringwald }
247fcebe167SMilanka Ringwald
TEST(HCI,gap_le_set_phy)248fcebe167SMilanka Ringwald TEST(HCI, gap_le_set_phy){
249fcebe167SMilanka Ringwald uint8_t status = gap_le_set_phy(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0);
250fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
251fcebe167SMilanka Ringwald
252fcebe167SMilanka Ringwald status = gap_le_set_phy(0x01, 0, 0, 0, 0);
253fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
254fcebe167SMilanka Ringwald }
255fcebe167SMilanka Ringwald
TEST(HCI,hci_connection_for_bd_addr_and_type)256fcebe167SMilanka Ringwald TEST(HCI, hci_connection_for_bd_addr_and_type){
257fcebe167SMilanka Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL;
258fcebe167SMilanka Ringwald bd_addr_t addr = { 0 };
259fcebe167SMilanka Ringwald
260fcebe167SMilanka Ringwald hci_connection_t * con = hci_connection_for_bd_addr_and_type(addr , addr_type);
261fcebe167SMilanka Ringwald CHECK_EQUAL(NULL, con);
262fcebe167SMilanka Ringwald }
263fcebe167SMilanka Ringwald
TEST(HCI,hci_number_free_acl_slots_for_handle)264fcebe167SMilanka Ringwald TEST(HCI, hci_number_free_acl_slots_for_handle){
265fcebe167SMilanka Ringwald int free_acl_slots_num = hci_number_free_acl_slots_for_handle(HCI_CON_HANDLE_INVALID);
266fcebe167SMilanka Ringwald CHECK_EQUAL(0, free_acl_slots_num);
267fcebe167SMilanka Ringwald }
268fcebe167SMilanka Ringwald
TEST(HCI,hci_send_acl_packet_buffer_no_connection)269566df4e8SMatthias Ringwald TEST(HCI, hci_send_acl_packet_buffer_no_connection){
270566df4e8SMatthias Ringwald hci_reserve_packet_buffer();
271566df4e8SMatthias Ringwald uint8_t status = hci_send_acl_packet_buffer(16);
272566df4e8SMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
273566df4e8SMatthias Ringwald }
274566df4e8SMatthias Ringwald
TEST(HCI,hci_send_acl_packet_buffer)275fcebe167SMilanka Ringwald TEST(HCI, hci_send_acl_packet_buffer){
276fcebe167SMilanka Ringwald hci_reserve_packet_buffer();
277566df4e8SMatthias Ringwald uint8_t * packet = hci_get_outgoing_packet_buffer();
278566df4e8SMatthias Ringwald uint8_t flags = 0x02;
279566df4e8SMatthias Ringwald // LE Packet
280566df4e8SMatthias Ringwald uint16_t acl_len = 50;
281566df4e8SMatthias Ringwald hci_stack->le_data_packets_length = acl_len - 10;;
282566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, 0x05 | (flags << 12));
283566df4e8SMatthias Ringwald uint8_t status = hci_send_acl_packet_buffer(acl_len);
284566df4e8SMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
285566df4e8SMatthias Ringwald hci_stack->le_data_packets_length = 0;
286fcebe167SMilanka Ringwald }
287fcebe167SMilanka Ringwald
TEST(HCI,hci_send_cmd_packet)288fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_packet){
289fcebe167SMilanka Ringwald bd_addr_t addr = { 0 };
290fcebe167SMilanka Ringwald
291fcebe167SMilanka Ringwald uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1);
292fcebe167SMilanka Ringwald CHECK_EQUAL(0, status);
293fcebe167SMilanka Ringwald
294fcebe167SMilanka Ringwald uint8_t i;
295fcebe167SMilanka Ringwald for (i = 0; i < 3; i++){
296fcebe167SMilanka Ringwald status = hci_send_cmd(&hci_le_create_connection,
297fcebe167SMilanka Ringwald 1000, // scan interval: 625 ms
298fcebe167SMilanka Ringwald 1000, // scan interval: 625 ms
299fcebe167SMilanka Ringwald i, // don't use whitelist
300fcebe167SMilanka Ringwald 0, // peer address type: public
301fcebe167SMilanka Ringwald addr, // remote bd addr
302fcebe167SMilanka Ringwald 0, // random or public
303fcebe167SMilanka Ringwald 80, // conn interval min
304fcebe167SMilanka Ringwald 80, // conn interval max (3200 * 0.625)
305fcebe167SMilanka Ringwald 0, // conn latency
306fcebe167SMilanka Ringwald 2000, // supervision timeout
307fcebe167SMilanka Ringwald 0, // min ce length
308fcebe167SMilanka Ringwald 1000 // max ce length
309fcebe167SMilanka Ringwald );
310fcebe167SMilanka Ringwald CHECK_EQUAL(0, status);
311fcebe167SMilanka Ringwald }
312fcebe167SMilanka Ringwald }
313fcebe167SMilanka Ringwald
TEST(HCI,hci_send_cmd_va_arg)314fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_va_arg){
315fcebe167SMilanka Ringwald hci_reserve_packet_buffer();
316fcebe167SMilanka Ringwald uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1);
317fcebe167SMilanka Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
318fcebe167SMilanka Ringwald }
319fcebe167SMilanka Ringwald
TEST(HCI,hci_power_control)320fcebe167SMilanka Ringwald TEST(HCI, hci_power_control){
321fcebe167SMilanka Ringwald int status = hci_power_control(HCI_POWER_ON);
322fcebe167SMilanka Ringwald CHECK_EQUAL(0, status);
323fcebe167SMilanka Ringwald }
324fcebe167SMilanka Ringwald
TEST(HCI,NumPeripherals)325d3762d15SMatthias Ringwald TEST(HCI, NumPeripherals){
326d3762d15SMatthias Ringwald gap_set_max_number_peripheral_connections(1);
327d3762d15SMatthias Ringwald }
328d3762d15SMatthias Ringwald
TEST(HCI,MaxAclLen)329d3762d15SMatthias Ringwald TEST(HCI, MaxAclLen){
330d3762d15SMatthias Ringwald hci_max_acl_data_packet_length();
331d3762d15SMatthias Ringwald }
332d3762d15SMatthias Ringwald
TEST(HCI,Flushable)333d3762d15SMatthias Ringwald TEST(HCI, Flushable){
334d3762d15SMatthias Ringwald hci_non_flushable_packet_boundary_flag_supported();
335d3762d15SMatthias Ringwald }
336d3762d15SMatthias Ringwald
TEST(HCI,RemovePacketHandler)337d3762d15SMatthias Ringwald TEST(HCI, RemovePacketHandler){
338d3762d15SMatthias Ringwald hci_remove_event_handler(NULL);
339d3762d15SMatthias Ringwald }
340d3762d15SMatthias Ringwald
dummy_fn(const void * config)341d3762d15SMatthias Ringwald static void dummy_fn(const void * config){};
TEST(HCI,SetChipset)342d3762d15SMatthias Ringwald TEST(HCI, SetChipset){
343d3762d15SMatthias Ringwald hci_set_chipset(NULL);
344d3762d15SMatthias Ringwald btstack_chipset_t chipset_driver = { 0 };
345d3762d15SMatthias Ringwald hci_set_chipset(NULL);
346d3762d15SMatthias Ringwald chipset_driver.init = dummy_fn;
347d3762d15SMatthias Ringwald }
348d3762d15SMatthias Ringwald
TEST(HCI,SetControl)349d3762d15SMatthias Ringwald TEST(HCI, SetControl){
350d3762d15SMatthias Ringwald btstack_control_t hardware_control = { .init = &dummy_fn};
351d3762d15SMatthias Ringwald hci_set_control(&hardware_control);
352d3762d15SMatthias Ringwald }
353d3762d15SMatthias Ringwald
354d3762d15SMatthias Ringwald //TEST(HCI, Close){
355d3762d15SMatthias Ringwald // hci_close();
356d3762d15SMatthias Ringwald //}
357d3762d15SMatthias Ringwald
TEST(HCI,SetPublicAddress)358d3762d15SMatthias Ringwald TEST(HCI, SetPublicAddress){
359d3762d15SMatthias Ringwald bd_addr_t addr = { 0 };
360d3762d15SMatthias Ringwald hci_set_bd_addr(addr);
361d3762d15SMatthias Ringwald }
362d3762d15SMatthias Ringwald
TEST(HCI,DisconnectSecurityBlock)363d3762d15SMatthias Ringwald TEST(HCI, DisconnectSecurityBlock){
364d3762d15SMatthias Ringwald hci_disconnect_security_block(HCI_CON_HANDLE_INVALID);
365d3762d15SMatthias Ringwald hci_disconnect_security_block(3);
366d3762d15SMatthias Ringwald }
367d3762d15SMatthias Ringwald
TEST(HCI,SetDuplicateFilter)368d3762d15SMatthias Ringwald TEST(HCI, SetDuplicateFilter){
369d3762d15SMatthias Ringwald gap_set_scan_duplicate_filter(true);
370d3762d15SMatthias Ringwald }
371d3762d15SMatthias Ringwald
TEST(HCI,ConnectCancel)372d3762d15SMatthias Ringwald TEST(HCI, ConnectCancel){
37328739e5fSMatthias Ringwald uint8_t status;
37428739e5fSMatthias Ringwald status = gap_connect_with_whitelist();
37528739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
37628739e5fSMatthias Ringwald gap_connect_cancel();
37728739e5fSMatthias Ringwald
37828739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
37928739e5fSMatthias Ringwald bd_addr_t addr = { 0 };
38028739e5fSMatthias Ringwald gap_connect(addr, addr_type);
381d3762d15SMatthias Ringwald gap_connect_cancel();
382d3762d15SMatthias Ringwald }
383d3762d15SMatthias Ringwald
TEST(HCI,SetGapConnParams)384d3762d15SMatthias Ringwald TEST(HCI, SetGapConnParams){
385d3762d15SMatthias Ringwald gap_set_connection_parameters(0, 0, 0, 0, 0, 0, 0, 0);
386d3762d15SMatthias Ringwald }
387d3762d15SMatthias Ringwald
TEST(HCI,UpdateConnParams)388d3762d15SMatthias Ringwald TEST(HCI, UpdateConnParams){
389d3762d15SMatthias Ringwald gap_update_connection_parameters(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0);
390d3762d15SMatthias Ringwald gap_update_connection_parameters(5, 0, 0, 0, 0);
391d3762d15SMatthias Ringwald }
392d3762d15SMatthias Ringwald
TEST(HCI,RequestConnParamUpdate)393d3762d15SMatthias Ringwald TEST(HCI, RequestConnParamUpdate){
394d3762d15SMatthias Ringwald gap_request_connection_parameter_update(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0);
395d3762d15SMatthias Ringwald gap_request_connection_parameter_update(5, 0, 0, 0, 0);
396d3762d15SMatthias Ringwald }
397d3762d15SMatthias Ringwald
TEST(HCI,SetScanResponse)398d3762d15SMatthias Ringwald TEST(HCI, SetScanResponse){
399d3762d15SMatthias Ringwald gap_scan_response_set_data(0, NULL);
400d3762d15SMatthias Ringwald }
401d3762d15SMatthias Ringwald
TEST(HCI,SetAddrType)402d3762d15SMatthias Ringwald TEST(HCI, SetAddrType){
403d3762d15SMatthias Ringwald hci_le_set_own_address_type(0);
404d3762d15SMatthias Ringwald hci_le_set_own_address_type(1);
405d3762d15SMatthias Ringwald }
406d3762d15SMatthias Ringwald
TEST(HCI,AdvEnable)407d3762d15SMatthias Ringwald TEST(HCI, AdvEnable){
408d3762d15SMatthias Ringwald gap_advertisements_enable(0);
409d3762d15SMatthias Ringwald gap_advertisements_enable(1);
410d3762d15SMatthias Ringwald }
411d3762d15SMatthias Ringwald
TEST(HCI,SetRandomAddr)412d3762d15SMatthias Ringwald TEST(HCI, SetRandomAddr){
413d3762d15SMatthias Ringwald bd_addr_t addr = { 0 };
414d3762d15SMatthias Ringwald hci_le_random_address_set(addr);
415d3762d15SMatthias Ringwald }
416d3762d15SMatthias Ringwald
TEST(HCI,Disconnect)417d3762d15SMatthias Ringwald TEST(HCI, Disconnect){
418d3762d15SMatthias Ringwald gap_disconnect(HCI_CON_HANDLE_INVALID);
419d3762d15SMatthias Ringwald gap_disconnect(5);
420d3762d15SMatthias Ringwald }
421d3762d15SMatthias Ringwald
TEST(HCI,GetRole)422d3762d15SMatthias Ringwald TEST(HCI, GetRole){
423d3762d15SMatthias Ringwald gap_get_role(HCI_CON_HANDLE_INVALID);
424d3762d15SMatthias Ringwald gap_get_role(5);
425d3762d15SMatthias Ringwald }
TEST(HCI,hci_is_le_identity_address_type_other)42628739e5fSMatthias Ringwald TEST(HCI, hci_is_le_identity_address_type_other){
42728739e5fSMatthias Ringwald hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_PUBLIC_IDENTITY);
42828739e5fSMatthias Ringwald hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_RANDOM);
42928739e5fSMatthias Ringwald }
43028739e5fSMatthias Ringwald
TEST(HCI,hci_can_send_command_packet_now)43128739e5fSMatthias Ringwald TEST(HCI, hci_can_send_command_packet_now){
43228739e5fSMatthias Ringwald can_send_now = 0;
43328739e5fSMatthias Ringwald hci_can_send_command_packet_now();
43428739e5fSMatthias Ringwald can_send_now = 1;
43528739e5fSMatthias Ringwald hci_can_send_command_packet_now();
43628739e5fSMatthias Ringwald }
43728739e5fSMatthias Ringwald
TEST(HCI,hci_can_send_prepared_acl_packet_now)43828739e5fSMatthias Ringwald TEST(HCI, hci_can_send_prepared_acl_packet_now){
43928739e5fSMatthias Ringwald can_send_now = 0;
44028739e5fSMatthias Ringwald hci_can_send_prepared_acl_packet_now(0);
44128739e5fSMatthias Ringwald can_send_now = 1;
44228739e5fSMatthias Ringwald hci_can_send_prepared_acl_packet_now(0);
44328739e5fSMatthias Ringwald }
44428739e5fSMatthias Ringwald
TEST(HCI,hci_can_send_acl_le_packet_now)44528739e5fSMatthias Ringwald TEST(HCI, hci_can_send_acl_le_packet_now) {
44628739e5fSMatthias Ringwald can_send_now = 0;
44728739e5fSMatthias Ringwald hci_can_send_acl_le_packet_now();
44828739e5fSMatthias Ringwald can_send_now = 1;
44928739e5fSMatthias Ringwald hci_can_send_acl_le_packet_now();
45028739e5fSMatthias Ringwald }
TEST(HCI,hci_number_free_acl_slots_for_connection_type)451566df4e8SMatthias Ringwald TEST(HCI, hci_number_free_acl_slots_for_connection_type) {
452566df4e8SMatthias Ringwald CHECK_EQUAL(0, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_UNKNOWN));
453566df4e8SMatthias Ringwald CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_ACL));
454566df4e8SMatthias Ringwald CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC));
455566df4e8SMatthias Ringwald // tweak stack
456566df4e8SMatthias Ringwald hci_stack_t * hci_stack = hci_get_stack();
457566df4e8SMatthias Ringwald hci_stack->le_acl_packets_total_num = 1;
458566df4e8SMatthias Ringwald CHECK_EQUAL(1, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC));
45928739e5fSMatthias Ringwald }
46028739e5fSMatthias Ringwald
461566df4e8SMatthias Ringwald // TEST(HCI, hci_close) {
462566df4e8SMatthias Ringwald // hci_close();
463566df4e8SMatthias Ringwald // }
464566df4e8SMatthias Ringwald
TEST(HCI,gap_connect)46528739e5fSMatthias Ringwald TEST(HCI, gap_connect) {
46628739e5fSMatthias Ringwald bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
46728739e5fSMatthias Ringwald bd_addr_t addr = { 0 };
46828739e5fSMatthias Ringwald
46928739e5fSMatthias Ringwald uint8_t status;
47028739e5fSMatthias Ringwald status = gap_connect(addr, addr_type);
47128739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
47228739e5fSMatthias Ringwald status = gap_connect(addr, addr_type);
47328739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
47428739e5fSMatthias Ringwald }
47528739e5fSMatthias Ringwald
TEST(HCI,hci_emit_state)47628739e5fSMatthias Ringwald TEST(HCI, hci_emit_state) {
47728739e5fSMatthias Ringwald hci_emit_state();
47828739e5fSMatthias Ringwald }
47928739e5fSMatthias Ringwald
TEST(HCI,gap_request_connection_subrating)48028739e5fSMatthias Ringwald TEST(HCI, gap_request_connection_subrating) {
48128739e5fSMatthias Ringwald int status = gap_request_connection_subrating(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0, 0);
48228739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
48328739e5fSMatthias Ringwald status = gap_request_connection_subrating(0x01, 0, 0, 0, 0, 0);
48428739e5fSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
48528739e5fSMatthias Ringwald }
48628739e5fSMatthias Ringwald
48728739e5fSMatthias Ringwald
TEST(HCI,hci_set_hardware_error_callback)48828739e5fSMatthias Ringwald TEST(HCI, hci_set_hardware_error_callback) {
48928739e5fSMatthias Ringwald hci_set_hardware_error_callback(NULL);
49028739e5fSMatthias Ringwald }
49128739e5fSMatthias Ringwald
TEST(HCI,hci_disconnect_all)49228739e5fSMatthias Ringwald TEST(HCI, hci_disconnect_all) {
49328739e5fSMatthias Ringwald hci_disconnect_all();
49428739e5fSMatthias Ringwald }
49528739e5fSMatthias Ringwald
TEST(HCI,hci_get_manufacturer)49628739e5fSMatthias Ringwald TEST(HCI, hci_get_manufacturer) {
49728739e5fSMatthias Ringwald hci_get_manufacturer();
49828739e5fSMatthias Ringwald }
TEST(HCI,gap_authorization_state)49928739e5fSMatthias Ringwald TEST(HCI, gap_authorization_state) {
50028739e5fSMatthias Ringwald gap_authorization_state(HCI_CON_HANDLE_INVALID);
50128739e5fSMatthias Ringwald }
50228739e5fSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
TEST(HCI,hci_load_le_device_db_entry_into_resolving_list)50328739e5fSMatthias Ringwald TEST(HCI, hci_load_le_device_db_entry_into_resolving_list) {
50428739e5fSMatthias Ringwald hci_load_le_device_db_entry_into_resolving_list(0);
50528739e5fSMatthias Ringwald }
50628739e5fSMatthias Ringwald
TEST(HCI,hci_remove_le_device_db_entry_from_resolving_list)50728739e5fSMatthias Ringwald TEST(HCI, hci_remove_le_device_db_entry_from_resolving_list) {
50828739e5fSMatthias Ringwald hci_remove_le_device_db_entry_from_resolving_list(0);
50928739e5fSMatthias Ringwald }
51028739e5fSMatthias Ringwald
TEST(HCI,gap_load_resolving_list_from_le_device_db)51128739e5fSMatthias Ringwald TEST(HCI, gap_load_resolving_list_from_le_device_db) {
51228739e5fSMatthias Ringwald gap_load_resolving_list_from_le_device_db();
51328739e5fSMatthias Ringwald }
51428739e5fSMatthias Ringwald #endif
51528739e5fSMatthias Ringwald
TEST(HCI,gap_privacy_client)51628739e5fSMatthias Ringwald TEST(HCI, gap_privacy_client) {
51728739e5fSMatthias Ringwald gap_privacy_client_t client;
51828739e5fSMatthias Ringwald gap_privacy_client_register(&client);
51928739e5fSMatthias Ringwald gap_privacy_client_ready(&client);
52028739e5fSMatthias Ringwald gap_privacy_client_unregister(&client);
52128739e5fSMatthias Ringwald }
522d3762d15SMatthias Ringwald
TEST(HCI,acl_handling)523566df4e8SMatthias Ringwald TEST(HCI, acl_handling) {
524566df4e8SMatthias Ringwald uint16_t con_handle = 1;
525566df4e8SMatthias Ringwald uint8_t flags = 0;
526566df4e8SMatthias Ringwald
527566df4e8SMatthias Ringwald uint8_t packet[16];
528566df4e8SMatthias Ringwald // no connection for invalid handle
529566df4e8SMatthias Ringwald memset(packet, 0xff, sizeof(packet));
530566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
531566df4e8SMatthias Ringwald // invalid length
532566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
533566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
534566df4e8SMatthias Ringwald // fix length
535566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 12);
536566df4e8SMatthias Ringwald little_endian_store_16(packet, 6, 8);
537566df4e8SMatthias Ringwald
538566df4e8SMatthias Ringwald // unexpected acl continuation
539566df4e8SMatthias Ringwald flags = 0x01;
540566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
541566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
542566df4e8SMatthias Ringwald // invalid packet boundary flags
543566df4e8SMatthias Ringwald flags = 0x03;
544566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
545566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
546566df4e8SMatthias Ringwald // oversized first fragment
547566df4e8SMatthias Ringwald flags = 0x02;
548566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
549566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 1996);
550566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, 2000);
551566df4e8SMatthias Ringwald
552566df4e8SMatthias Ringwald // 1a store first flushable fragment
553566df4e8SMatthias Ringwald flags = 0x02;
554566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
555566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 12);
556566df4e8SMatthias Ringwald little_endian_store_16(packet, 4, 20);
557566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
558566df4e8SMatthias Ringwald
559566df4e8SMatthias Ringwald // 1b another first non-flushable
560566df4e8SMatthias Ringwald flags = 0x06;
561566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
562566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
563566df4e8SMatthias Ringwald
564566df4e8SMatthias Ringwald // 1c another first
565566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
566566df4e8SMatthias Ringwald
567566df4e8SMatthias Ringwald // oversized continuation fragment
568566df4e8SMatthias Ringwald flags = 0x01;
569566df4e8SMatthias Ringwald little_endian_store_16(packet, 0, con_handle | (flags << 12));
570566df4e8SMatthias Ringwald little_endian_store_16(packet, 2, 1996);
571566df4e8SMatthias Ringwald packet_handler(HCI_ACL_DATA_PACKET, packet, 2000);
572566df4e8SMatthias Ringwald }
TEST(HCI,gap_le_get_own_address)573566df4e8SMatthias Ringwald TEST(HCI, gap_le_get_own_address) {
574566df4e8SMatthias Ringwald uint8_t addr_type;
575566df4e8SMatthias Ringwald bd_addr_t addr;
576566df4e8SMatthias Ringwald hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC;
577566df4e8SMatthias Ringwald gap_le_get_own_address(&addr_type, addr);
578566df4e8SMatthias Ringwald hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_RANDOM;
579566df4e8SMatthias Ringwald gap_le_get_own_address(&addr_type, addr);
580566df4e8SMatthias Ringwald }
581566df4e8SMatthias Ringwald
simulate_hci_command_complete(uint16_t opcode,uint8_t status,uint8_t variant)582*1520bf5bSMatthias Ringwald static void simulate_hci_command_complete(uint16_t opcode, uint8_t status, uint8_t variant) {
5835308d607SMatthias Ringwald uint8_t packet[2 + 255];
584566df4e8SMatthias Ringwald packet[0] = HCI_EVENT_COMMAND_COMPLETE;
585566df4e8SMatthias Ringwald packet[1] = sizeof(packet) - 2;
586566df4e8SMatthias Ringwald packet[2] = 1;
587566df4e8SMatthias Ringwald little_endian_store_16(packet, 3, opcode);
588566df4e8SMatthias Ringwald packet[5] = status;
589*1520bf5bSMatthias Ringwald switch (opcode) {
590*1520bf5bSMatthias Ringwald case HCI_OPCODE_HCI_LE_READ_BUFFER_SIZE:
591*1520bf5bSMatthias Ringwald little_endian_store_16(packet, 6, 2000);
592*1520bf5bSMatthias Ringwald break;
593*1520bf5bSMatthias Ringwald case HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION:
594*1520bf5bSMatthias Ringwald switch (variant) {
595*1520bf5bSMatthias Ringwald case 0:
596*1520bf5bSMatthias Ringwald little_endian_store_16(packet, 10, BLUETOOTH_COMPANY_ID_BROADCOM_CORPORATION);
597*1520bf5bSMatthias Ringwald break;
598*1520bf5bSMatthias Ringwald case 1:
599*1520bf5bSMatthias Ringwald little_endian_store_16(packet, 10, BLUETOOTH_COMPANY_ID_INFINEON_TECHNOLOGIES_AG);
600*1520bf5bSMatthias Ringwald break;
601*1520bf5bSMatthias Ringwald case 2:
602*1520bf5bSMatthias Ringwald little_endian_store_16(packet, 10, BLUETOOTH_COMPANY_ID_CYPRESS_SEMICONDUCTOR);
603*1520bf5bSMatthias Ringwald break;
604*1520bf5bSMatthias Ringwald }
605*1520bf5bSMatthias Ringwald break;
606*1520bf5bSMatthias Ringwald default:
607*1520bf5bSMatthias Ringwald break;
608*1520bf5bSMatthias Ringwald }
609566df4e8SMatthias Ringwald packet_handler(HCI_EVENT_PACKET, packet, sizeof(packet));
610566df4e8SMatthias Ringwald }
611566df4e8SMatthias Ringwald
TEST(HCI,handle_command_complete_event)612566df4e8SMatthias Ringwald TEST(HCI, handle_command_complete_event) {
613566df4e8SMatthias Ringwald struct {
614566df4e8SMatthias Ringwald uint16_t opcode;
615566df4e8SMatthias Ringwald uint8_t status;
616*1520bf5bSMatthias Ringwald uint8_t variants;
617566df4e8SMatthias Ringwald } variations[] = {
618*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_READ_LOCAL_NAME, .status = ERROR_CODE_SUCCESS},
619*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_READ_LOCAL_NAME, .status = ERROR_CODE_UNKNOWN_HCI_COMMAND },
620*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_READ_BUFFER_SIZE, .status = ERROR_CODE_SUCCESS},
621*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_READ_RSSI, .status = ERROR_CODE_SUCCESS},
622*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_READ_RSSI, .status = ERROR_CODE_UNKNOWN_HCI_COMMAND},
623*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_LE_READ_BUFFER_SIZE },
624*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_LE_READ_BUFFER_SIZE_V2 },
625*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_LE_READ_MAXIMUM_DATA_LENGTH },
626*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION, .variants = 3},
627566df4e8SMatthias Ringwald };
628566df4e8SMatthias Ringwald for (uint8_t i = 0; i < sizeof(variations) / sizeof(variations[0]); i++) {
629566df4e8SMatthias Ringwald // extras
630566df4e8SMatthias Ringwald uint16_t opcode = variations[i].opcode;
631566df4e8SMatthias Ringwald uint8_t status = variations[i].status;
632*1520bf5bSMatthias Ringwald uint8_t variants = btstack_max(1, variations[i].variants);
633566df4e8SMatthias Ringwald switch (opcode) {
634566df4e8SMatthias Ringwald default:
635566df4e8SMatthias Ringwald break;
636566df4e8SMatthias Ringwald }
637*1520bf5bSMatthias Ringwald for (uint8_t j=0; j < variants; j++) {
638*1520bf5bSMatthias Ringwald simulate_hci_command_complete(opcode, status, j);
639*1520bf5bSMatthias Ringwald }
640566df4e8SMatthias Ringwald switch (opcode) {
641566df4e8SMatthias Ringwald default:
642566df4e8SMatthias Ringwald break;
643566df4e8SMatthias Ringwald }
644566df4e8SMatthias Ringwald }
645566df4e8SMatthias Ringwald }
646566df4e8SMatthias Ringwald
simulate_hci_command_status(uint16_t opcode,uint8_t status,uint8_t variant)647*1520bf5bSMatthias Ringwald static void simulate_hci_command_status(uint16_t opcode, uint8_t status, uint8_t variant) {
648*1520bf5bSMatthias Ringwald uint8_t packet[2 + 255];
649*1520bf5bSMatthias Ringwald packet[0] = HCI_EVENT_COMMAND_STATUS;
650*1520bf5bSMatthias Ringwald packet[1] = sizeof(packet) - 2;
651*1520bf5bSMatthias Ringwald packet[2] = status;
652*1520bf5bSMatthias Ringwald packet[3] = 1;
653*1520bf5bSMatthias Ringwald little_endian_store_16(packet, 4, opcode);
654*1520bf5bSMatthias Ringwald switch (opcode) {
655*1520bf5bSMatthias Ringwald default:
656*1520bf5bSMatthias Ringwald break;
657*1520bf5bSMatthias Ringwald }
658*1520bf5bSMatthias Ringwald packet_handler(HCI_EVENT_PACKET, packet, sizeof(packet));
659*1520bf5bSMatthias Ringwald }
660*1520bf5bSMatthias Ringwald
TEST(HCI,handle_command_status_event)661*1520bf5bSMatthias Ringwald TEST(HCI, handle_command_status_event) {
662*1520bf5bSMatthias Ringwald struct {
663*1520bf5bSMatthias Ringwald uint16_t opcode;
664*1520bf5bSMatthias Ringwald uint8_t status;
665*1520bf5bSMatthias Ringwald uint8_t variants;
666*1520bf5bSMatthias Ringwald } variations[] = {
667*1520bf5bSMatthias Ringwald {.opcode = HCI_OPCODE_HCI_LE_CREATE_CONNECTION, .status = ERROR_CODE_COMMAND_DISALLOWED, .variants = 2},
668*1520bf5bSMatthias Ringwald };
669*1520bf5bSMatthias Ringwald
670*1520bf5bSMatthias Ringwald // default address: 66:55:44:33:00:01
671*1520bf5bSMatthias Ringwald bd_addr_t addr = { 0x66, 0x55, 0x44, 0x33, 0x00, 0x00};
672*1520bf5bSMatthias Ringwald
673*1520bf5bSMatthias Ringwald for (uint8_t i = 0; i < sizeof(variations) / sizeof(variations[0]); i++) {
674*1520bf5bSMatthias Ringwald // extras
675*1520bf5bSMatthias Ringwald uint16_t opcode = variations[i].opcode;
676*1520bf5bSMatthias Ringwald uint8_t status = variations[i].status;
677*1520bf5bSMatthias Ringwald uint8_t variants = btstack_max(1, variations[i].variants);
678*1520bf5bSMatthias Ringwald for (uint8_t j=0; j < variants; j++) {
679*1520bf5bSMatthias Ringwald switch (opcode) {
680*1520bf5bSMatthias Ringwald case HCI_OPCODE_HCI_LE_CREATE_CONNECTION:
681*1520bf5bSMatthias Ringwald hci_stack->outgoing_addr_type = BD_ADDR_TYPE_LE_PUBLIC;
682*1520bf5bSMatthias Ringwald addr[5] = 0x05 + j;
683*1520bf5bSMatthias Ringwald memcpy(hci_stack->outgoing_addr, &addr, sizeof(addr));
684*1520bf5bSMatthias Ringwald break;
685*1520bf5bSMatthias Ringwald default:
686*1520bf5bSMatthias Ringwald break;
687*1520bf5bSMatthias Ringwald }
688*1520bf5bSMatthias Ringwald simulate_hci_command_status(opcode, status, j);
689*1520bf5bSMatthias Ringwald switch (opcode) {
690*1520bf5bSMatthias Ringwald default:
691*1520bf5bSMatthias Ringwald break;
692*1520bf5bSMatthias Ringwald }
693*1520bf5bSMatthias Ringwald }
694*1520bf5bSMatthias Ringwald }
695*1520bf5bSMatthias Ringwald }
696*1520bf5bSMatthias Ringwald
main(int argc,const char * argv[])697d3762d15SMatthias Ringwald int main (int argc, const char * argv[]){
698fcebe167SMilanka Ringwald btstack_run_loop_init(btstack_run_loop_posix_get_instance());
699d3762d15SMatthias Ringwald return CommandLineTestRunner::RunAllTests(argc, argv);
700d3762d15SMatthias Ringwald }
701