xref: /btstack/test/gap/hci_test.cpp (revision 5308d607716dbfcb99a3b9b238a8d3d356aa1ae3)
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"
14d3762d15SMatthias Ringwald #include "ble/gatt_client.h"
15d3762d15SMatthias Ringwald #include "btstack_event.h"
16d3762d15SMatthias Ringwald #include "hci_dump.h"
17d3762d15SMatthias Ringwald #include "hci_dump_posix_fs.h"
18d3762d15SMatthias Ringwald #include "btstack_debug.h"
19fcebe167SMilanka Ringwald #include "btstack_util.h"
20fcebe167SMilanka Ringwald #include "btstack_run_loop_posix.h"
21d3762d15SMatthias Ringwald 
22d3762d15SMatthias Ringwald typedef struct {
23d3762d15SMatthias Ringwald     uint8_t type;
24d3762d15SMatthias Ringwald     uint16_t size;
25d3762d15SMatthias Ringwald     uint8_t  buffer[258];
26d3762d15SMatthias Ringwald } hci_packet_t;
27d3762d15SMatthias Ringwald 
28d3762d15SMatthias Ringwald #define MAX_HCI_PACKETS 10
29d3762d15SMatthias Ringwald static uint16_t transport_count_packets;
30d3762d15SMatthias Ringwald static hci_packet_t transport_packets[MAX_HCI_PACKETS];
3128739e5fSMatthias Ringwald static int can_send_now = 1;
32d3762d15SMatthias Ringwald static  void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size);
33d3762d15SMatthias Ringwald 
34*5308d607SMatthias Ringwald #if 0
35*5308d607SMatthias Ringwald static btstack_timer_source_t packet_sent_timer;
36*5308d607SMatthias Ringwald 
37d3762d15SMatthias Ringwald static const uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
38d3762d15SMatthias Ringwald 
39*5308d607SMatthias Ringwald // sm_trigger_run allows to schedule callback from main run loop // reduces stack depth
40*5308d607SMatthias Ringwald static void hci_transport_emit_packet_sent(btstack_timer_source_t * ts){
41*5308d607SMatthias Ringwald     UNUSED(ts);
42*5308d607SMatthias Ringwald     // notify upper stack that it can send again
43*5308d607SMatthias Ringwald     can_send_now = 1;
44*5308d607SMatthias Ringwald     packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event));
45*5308d607SMatthias Ringwald }
46*5308d607SMatthias Ringwald 
47*5308d607SMatthias Ringwald static void hci_transport_trigger_packet_sent(void) {
48*5308d607SMatthias Ringwald     btstack_run_loop_remove_timer(&packet_sent_timer);
49*5308d607SMatthias Ringwald     btstack_run_loop_set_timer_handler(&packet_sent_timer, &hci_transport_emit_packet_sent);
50*5308d607SMatthias Ringwald     btstack_run_loop_set_timer(&packet_sent_timer, 0);
51*5308d607SMatthias Ringwald     btstack_run_loop_add_timer(&packet_sent_timer);
52d3762d15SMatthias Ringwald }
53d3762d15SMatthias Ringwald 
54d3762d15SMatthias Ringwald static int hci_transport_test_can_send_now(uint8_t packet_type){
5528739e5fSMatthias Ringwald     return can_send_now;
56d3762d15SMatthias Ringwald }
57*5308d607SMatthias Ringwald #endif
58*5308d607SMatthias Ringwald 
59*5308d607SMatthias Ringwald static int hci_transport_test_set_baudrate(uint32_t baudrate){
60*5308d607SMatthias Ringwald     return 0;
61*5308d607SMatthias Ringwald }
62d3762d15SMatthias Ringwald 
63d3762d15SMatthias Ringwald static int hci_transport_test_send_packet(uint8_t packet_type, uint8_t * packet, int size){
64d3762d15SMatthias Ringwald     btstack_assert(transport_count_packets < MAX_HCI_PACKETS);
65d3762d15SMatthias Ringwald     memcpy(transport_packets[transport_count_packets].buffer, packet, size);
66d3762d15SMatthias Ringwald     transport_packets[transport_count_packets].type = packet_type;
67d3762d15SMatthias Ringwald     transport_packets[transport_count_packets].size = size;
68d3762d15SMatthias Ringwald     transport_count_packets++;
69d3762d15SMatthias Ringwald     return 0;
70d3762d15SMatthias Ringwald }
71d3762d15SMatthias Ringwald 
72d3762d15SMatthias Ringwald static void hci_transport_test_init(const void * transport_config){
73d3762d15SMatthias Ringwald }
74d3762d15SMatthias Ringwald 
75d3762d15SMatthias Ringwald static int hci_transport_test_open(void){
76d3762d15SMatthias Ringwald     return 0;
77d3762d15SMatthias Ringwald }
78d3762d15SMatthias Ringwald 
79d3762d15SMatthias Ringwald static int hci_transport_test_close(void){
80d3762d15SMatthias Ringwald     return 0;
81d3762d15SMatthias Ringwald }
82d3762d15SMatthias Ringwald 
83d3762d15SMatthias Ringwald static void hci_transport_test_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
84d3762d15SMatthias Ringwald     packet_handler = handler;
85d3762d15SMatthias Ringwald }
86d3762d15SMatthias Ringwald 
87d3762d15SMatthias Ringwald static const hci_transport_t hci_transport_test = {
88d3762d15SMatthias Ringwald         /* const char * name; */                                        "TEST",
89d3762d15SMatthias Ringwald         /* void   (*init) (const void *transport_config); */            &hci_transport_test_init,
90d3762d15SMatthias Ringwald         /* int    (*open)(void); */                                     &hci_transport_test_open,
91d3762d15SMatthias Ringwald         /* int    (*close)(void); */                                    &hci_transport_test_close,
92d3762d15SMatthias Ringwald         /* void   (*register_packet_handler)(void (*handler)(...); */   &hci_transport_test_register_packet_handler,
93*5308d607SMatthias Ringwald         /* int    (*can_send_packet_now)(uint8_t packet_type); */       NULL,
94d3762d15SMatthias Ringwald         /* int    (*send_packet)(...); */                               &hci_transport_test_send_packet,
95d3762d15SMatthias Ringwald         /* int    (*set_baudrate)(uint32_t baudrate); */                &hci_transport_test_set_baudrate,
96d3762d15SMatthias Ringwald         /* void   (*reset_link)(void); */                               NULL,
97d3762d15SMatthias Ringwald         /* void   (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL,
98d3762d15SMatthias Ringwald };
99d3762d15SMatthias Ringwald 
100d3762d15SMatthias Ringwald static uint16_t next_hci_packet;
101d3762d15SMatthias Ringwald 
102*5308d607SMatthias Ringwald void CHECK_EQUAL_ARRAY(const uint8_t * expected, const uint8_t * actual, int size){
103d3762d15SMatthias Ringwald     for (int i=0; i<size; i++){
104d3762d15SMatthias Ringwald         BYTES_EQUAL(expected[i], actual[i]);
105d3762d15SMatthias Ringwald     }
106d3762d15SMatthias Ringwald }
107d3762d15SMatthias Ringwald 
108d3762d15SMatthias Ringwald void CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command){
109d3762d15SMatthias Ringwald     uint16_t actual_opcode = little_endian_read_16(transport_packets[next_hci_packet].buffer, 0);
110d3762d15SMatthias Ringwald     next_hci_packet++;
111d3762d15SMatthias Ringwald     CHECK_EQUAL(expected_hci_command->opcode, actual_opcode);
112d3762d15SMatthias Ringwald }
113d3762d15SMatthias Ringwald 
114d3762d15SMatthias Ringwald TEST_GROUP(HCI){
115566df4e8SMatthias Ringwald         hci_stack_t * hci_stack;
116566df4e8SMatthias Ringwald 
117d3762d15SMatthias Ringwald     void setup(void){
118d3762d15SMatthias Ringwald             transport_count_packets = 0;
11928739e5fSMatthias Ringwald             can_send_now = 1;
120d3762d15SMatthias Ringwald             next_hci_packet = 0;
121d3762d15SMatthias Ringwald             hci_init(&hci_transport_test, NULL);
122566df4e8SMatthias Ringwald             hci_stack = hci_get_stack();
123d3762d15SMatthias Ringwald             hci_simulate_working_fuzz();
124d3762d15SMatthias Ringwald             hci_setup_test_connections_fuzz();
125d3762d15SMatthias Ringwald             // register for HCI events
126d3762d15SMatthias Ringwald             mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1);
127d3762d15SMatthias Ringwald         }
128d3762d15SMatthias Ringwald         void teardown(void){
129d3762d15SMatthias Ringwald             mock().clear();
130d3762d15SMatthias Ringwald         }
131d3762d15SMatthias Ringwald };
132d3762d15SMatthias Ringwald 
133d3762d15SMatthias Ringwald TEST(HCI, GetSetConnectionRange){
134d3762d15SMatthias Ringwald     le_connection_parameter_range_t range;
135d3762d15SMatthias Ringwald     gap_get_connection_parameter_range(&range);
136d3762d15SMatthias Ringwald     gap_set_connection_parameter_range(&range);
137d3762d15SMatthias Ringwald }
138d3762d15SMatthias Ringwald 
139d3762d15SMatthias Ringwald TEST(HCI, ConnectionRangeValid){
140d3762d15SMatthias Ringwald     le_connection_parameter_range_t range = {
141fcebe167SMilanka Ringwald             .le_conn_interval_min = 1,
142fcebe167SMilanka Ringwald             .le_conn_interval_max = 10,
143fcebe167SMilanka Ringwald             .le_conn_latency_min = 1,
144fcebe167SMilanka Ringwald             .le_conn_latency_max = 10,
145fcebe167SMilanka Ringwald             .le_supervision_timeout_min = 1,
146fcebe167SMilanka Ringwald             .le_supervision_timeout_max = 10
147d3762d15SMatthias Ringwald     };
148d3762d15SMatthias Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 0, 0, 0, 0));
149fcebe167SMilanka Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 11, 0, 0));
150fcebe167SMilanka Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 11, 0));
151d3762d15SMatthias Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 0, 0, 0));
152d3762d15SMatthias Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 0, 0));
153d3762d15SMatthias Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 10, 0));
154d3762d15SMatthias Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 0));
155d3762d15SMatthias Ringwald     CHECK_EQUAL( 0, gap_connection_parameter_range_included(&range, 2, 9, 5, 11));
156d3762d15SMatthias Ringwald     CHECK_EQUAL( 1, gap_connection_parameter_range_included(&range, 2, 9, 5, 5));
157d3762d15SMatthias Ringwald }
158d3762d15SMatthias Ringwald 
159fcebe167SMilanka Ringwald TEST(HCI, other_functions){
160fcebe167SMilanka Ringwald     gap_set_scan_phys(1);
161fcebe167SMilanka Ringwald     gap_set_connection_phys(1);
162fcebe167SMilanka Ringwald     hci_enable_custom_pre_init();
163fcebe167SMilanka Ringwald     gap_whitelist_clear();
164fcebe167SMilanka Ringwald }
165fcebe167SMilanka Ringwald 
166fcebe167SMilanka Ringwald TEST(HCI, gap_whitelist_add_remove){
167fcebe167SMilanka Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL;
168fcebe167SMilanka Ringwald     bd_addr_t addr = { 0 };
169fcebe167SMilanka Ringwald 
170fcebe167SMilanka Ringwald     uint8_t status = gap_whitelist_add(addr_type, addr);
171fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
172fcebe167SMilanka Ringwald 
173fcebe167SMilanka Ringwald     status = gap_whitelist_add(addr_type, addr);
174fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
175fcebe167SMilanka Ringwald 
176fcebe167SMilanka Ringwald     status = gap_whitelist_remove(addr_type, addr);
177fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
178fcebe167SMilanka Ringwald 
179fcebe167SMilanka Ringwald     status = gap_whitelist_remove(addr_type, addr);
180e406aa8dSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
181fcebe167SMilanka Ringwald 
182fcebe167SMilanka Ringwald     status = gap_whitelist_remove(BD_ADDR_TYPE_SCO, addr);
183fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
184fcebe167SMilanka Ringwald }
185fcebe167SMilanka Ringwald 
186fcebe167SMilanka Ringwald TEST(HCI, gap_connect_with_whitelist){
187fcebe167SMilanka Ringwald     uint8_t status = gap_connect_with_whitelist();
188fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
189fcebe167SMilanka Ringwald 
19028739e5fSMatthias Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
19128739e5fSMatthias Ringwald     bd_addr_t addr = { 0 };
19228739e5fSMatthias Ringwald     gap_auto_connection_start(addr_type, addr);
19328739e5fSMatthias Ringwald 
194fcebe167SMilanka Ringwald     status = gap_connect_with_whitelist();
195fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
196fcebe167SMilanka Ringwald }
197fcebe167SMilanka Ringwald 
198fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_start_stop){
199fcebe167SMilanka Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
200fcebe167SMilanka Ringwald     bd_addr_t addr = { 0 };
201fcebe167SMilanka Ringwald 
202fcebe167SMilanka Ringwald     uint8_t status = gap_auto_connection_start(addr_type, addr);
203fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
204fcebe167SMilanka Ringwald 
205fcebe167SMilanka Ringwald     status = gap_auto_connection_stop(addr_type, addr);
206fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
207fcebe167SMilanka Ringwald }
208fcebe167SMilanka Ringwald 
209fcebe167SMilanka Ringwald TEST(HCI, gap_auto_connection_stop_all){
210fcebe167SMilanka Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
211fcebe167SMilanka Ringwald     bd_addr_t addr = { 0 };
212fcebe167SMilanka Ringwald 
213fcebe167SMilanka Ringwald     uint8_t status = gap_auto_connection_start(addr_type, addr);
214fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
215fcebe167SMilanka Ringwald 
216fcebe167SMilanka Ringwald     status = gap_auto_connection_stop_all();
217fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
218fcebe167SMilanka Ringwald }
219fcebe167SMilanka Ringwald 
220fcebe167SMilanka Ringwald TEST(HCI, gap_read_rssi){
221fcebe167SMilanka Ringwald     int status = gap_read_rssi(HCI_CON_HANDLE_INVALID);
222fcebe167SMilanka Ringwald     CHECK_EQUAL(0, status);
223fcebe167SMilanka Ringwald 
224fcebe167SMilanka Ringwald     status = gap_read_rssi(0x01);
225fcebe167SMilanka Ringwald     CHECK_EQUAL(1, status);
226fcebe167SMilanka Ringwald }
227fcebe167SMilanka Ringwald 
228fcebe167SMilanka Ringwald TEST(HCI, gap_le_connection_interval){
229fcebe167SMilanka Ringwald     uint16_t con_interval = gap_le_connection_interval(HCI_CON_HANDLE_INVALID);
230fcebe167SMilanka Ringwald     CHECK_EQUAL(0, con_interval);
231fcebe167SMilanka Ringwald 
232fcebe167SMilanka Ringwald     con_interval = gap_le_connection_interval(0x01);
233fcebe167SMilanka Ringwald     CHECK_EQUAL(0, con_interval);
234fcebe167SMilanka Ringwald }
235fcebe167SMilanka Ringwald 
236fcebe167SMilanka Ringwald 
237fcebe167SMilanka Ringwald TEST(HCI, gap_get_connection_type){
238fcebe167SMilanka Ringwald     gap_connection_type_t type = gap_get_connection_type(HCI_CON_HANDLE_INVALID);
239fcebe167SMilanka Ringwald     CHECK_EQUAL(GAP_CONNECTION_INVALID, type);
240fcebe167SMilanka Ringwald 
241fcebe167SMilanka Ringwald     type = gap_get_connection_type(0x01);
242fcebe167SMilanka Ringwald     CHECK_EQUAL(GAP_CONNECTION_ACL, type);
243fcebe167SMilanka Ringwald }
244fcebe167SMilanka Ringwald 
245fcebe167SMilanka Ringwald TEST(HCI, gap_le_set_phy){
246fcebe167SMilanka Ringwald     uint8_t status = gap_le_set_phy(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0);
247fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
248fcebe167SMilanka Ringwald 
249fcebe167SMilanka Ringwald     status = gap_le_set_phy(0x01, 0, 0, 0, 0);
250fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
251fcebe167SMilanka Ringwald }
252fcebe167SMilanka Ringwald 
253fcebe167SMilanka Ringwald TEST(HCI, hci_connection_for_bd_addr_and_type){
254fcebe167SMilanka Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_ACL;
255fcebe167SMilanka Ringwald     bd_addr_t addr = { 0 };
256fcebe167SMilanka Ringwald 
257fcebe167SMilanka Ringwald     hci_connection_t * con = hci_connection_for_bd_addr_and_type(addr , addr_type);
258fcebe167SMilanka Ringwald     CHECK_EQUAL(NULL, con);
259fcebe167SMilanka Ringwald }
260fcebe167SMilanka Ringwald 
261fcebe167SMilanka Ringwald TEST(HCI, hci_number_free_acl_slots_for_handle){
262fcebe167SMilanka Ringwald     int free_acl_slots_num = hci_number_free_acl_slots_for_handle(HCI_CON_HANDLE_INVALID);
263fcebe167SMilanka Ringwald     CHECK_EQUAL(0, free_acl_slots_num);
264fcebe167SMilanka Ringwald }
265fcebe167SMilanka Ringwald 
266566df4e8SMatthias Ringwald TEST(HCI, hci_send_acl_packet_buffer_no_connection){
267566df4e8SMatthias Ringwald     hci_reserve_packet_buffer();
268566df4e8SMatthias Ringwald     uint8_t status = hci_send_acl_packet_buffer(16);
269566df4e8SMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
270566df4e8SMatthias Ringwald }
271566df4e8SMatthias Ringwald 
272fcebe167SMilanka Ringwald TEST(HCI, hci_send_acl_packet_buffer){
273fcebe167SMilanka Ringwald     hci_reserve_packet_buffer();
274566df4e8SMatthias Ringwald     uint8_t * packet = hci_get_outgoing_packet_buffer();
275566df4e8SMatthias Ringwald     uint8_t flags = 0x02;
276566df4e8SMatthias Ringwald     // LE Packet
277566df4e8SMatthias Ringwald     uint16_t acl_len = 50;
278566df4e8SMatthias Ringwald     hci_stack->le_data_packets_length = acl_len - 10;;
279566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, 0x05 | (flags << 12));
280566df4e8SMatthias Ringwald     uint8_t status = hci_send_acl_packet_buffer(acl_len);
281566df4e8SMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
282566df4e8SMatthias Ringwald     hci_stack->le_data_packets_length = 0;
283fcebe167SMilanka Ringwald }
284fcebe167SMilanka Ringwald 
285fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_packet){
286fcebe167SMilanka Ringwald     bd_addr_t addr = { 0 };
287fcebe167SMilanka Ringwald 
288fcebe167SMilanka Ringwald     uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1);
289fcebe167SMilanka Ringwald     CHECK_EQUAL(0, status);
290fcebe167SMilanka Ringwald 
291fcebe167SMilanka Ringwald     uint8_t i;
292fcebe167SMilanka Ringwald     for (i = 0; i < 3; i++){
293fcebe167SMilanka Ringwald         status = hci_send_cmd(&hci_le_create_connection,
294fcebe167SMilanka Ringwald             1000,      // scan interval: 625 ms
295fcebe167SMilanka Ringwald             1000,      // scan interval: 625 ms
296fcebe167SMilanka Ringwald             i,         // don't use whitelist
297fcebe167SMilanka Ringwald             0,         // peer address type: public
298fcebe167SMilanka Ringwald             addr,      // remote bd addr
299fcebe167SMilanka Ringwald             0, // random or public
300fcebe167SMilanka Ringwald             80,        // conn interval min
301fcebe167SMilanka Ringwald             80,        // conn interval max (3200 * 0.625)
302fcebe167SMilanka Ringwald             0,         // conn latency
303fcebe167SMilanka Ringwald             2000,      // supervision timeout
304fcebe167SMilanka Ringwald             0,         // min ce length
305fcebe167SMilanka Ringwald             1000       // max ce length
306fcebe167SMilanka Ringwald         );
307fcebe167SMilanka Ringwald         CHECK_EQUAL(0, status);
308fcebe167SMilanka Ringwald     }
309fcebe167SMilanka Ringwald }
310fcebe167SMilanka Ringwald 
311fcebe167SMilanka Ringwald TEST(HCI, hci_send_cmd_va_arg){
312fcebe167SMilanka Ringwald     hci_reserve_packet_buffer();
313fcebe167SMilanka Ringwald     uint8_t status = hci_send_cmd(&hci_write_loopback_mode, 1);
314fcebe167SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
315fcebe167SMilanka Ringwald }
316fcebe167SMilanka Ringwald 
317fcebe167SMilanka Ringwald TEST(HCI, hci_power_control){
318fcebe167SMilanka Ringwald     int status = hci_power_control(HCI_POWER_ON);
319fcebe167SMilanka Ringwald     CHECK_EQUAL(0, status);
320fcebe167SMilanka Ringwald }
321fcebe167SMilanka Ringwald 
322d3762d15SMatthias Ringwald TEST(HCI, NumPeripherals){
323d3762d15SMatthias Ringwald     gap_set_max_number_peripheral_connections(1);
324d3762d15SMatthias Ringwald }
325d3762d15SMatthias Ringwald 
326d3762d15SMatthias Ringwald TEST(HCI, MaxAclLen){
327d3762d15SMatthias Ringwald     hci_max_acl_data_packet_length();
328d3762d15SMatthias Ringwald }
329d3762d15SMatthias Ringwald 
330d3762d15SMatthias Ringwald TEST(HCI, Flushable){
331d3762d15SMatthias Ringwald     hci_non_flushable_packet_boundary_flag_supported();
332d3762d15SMatthias Ringwald }
333d3762d15SMatthias Ringwald 
334d3762d15SMatthias Ringwald TEST(HCI, RemovePacketHandler){
335d3762d15SMatthias Ringwald     hci_remove_event_handler(NULL);
336d3762d15SMatthias Ringwald }
337d3762d15SMatthias Ringwald 
338d3762d15SMatthias Ringwald static void dummy_fn(const void * config){};
339d3762d15SMatthias Ringwald TEST(HCI, SetChipset){
340d3762d15SMatthias Ringwald     hci_set_chipset(NULL);
341d3762d15SMatthias Ringwald     btstack_chipset_t chipset_driver = { 0 };
342d3762d15SMatthias Ringwald     hci_set_chipset(NULL);
343d3762d15SMatthias Ringwald     chipset_driver.init = dummy_fn;
344d3762d15SMatthias Ringwald }
345d3762d15SMatthias Ringwald 
346d3762d15SMatthias Ringwald TEST(HCI, SetControl){
347d3762d15SMatthias Ringwald     btstack_control_t hardware_control = { .init = &dummy_fn};
348d3762d15SMatthias Ringwald     hci_set_control(&hardware_control);
349d3762d15SMatthias Ringwald }
350d3762d15SMatthias Ringwald 
351d3762d15SMatthias Ringwald //TEST(HCI, Close){
352d3762d15SMatthias Ringwald //    hci_close();
353d3762d15SMatthias Ringwald //}
354d3762d15SMatthias Ringwald 
355d3762d15SMatthias Ringwald TEST(HCI, SetPublicAddress){
356d3762d15SMatthias Ringwald     bd_addr_t addr = { 0 };
357d3762d15SMatthias Ringwald     hci_set_bd_addr(addr);
358d3762d15SMatthias Ringwald }
359d3762d15SMatthias Ringwald 
360d3762d15SMatthias Ringwald TEST(HCI, DisconnectSecurityBlock){
361d3762d15SMatthias Ringwald     hci_disconnect_security_block(HCI_CON_HANDLE_INVALID);
362d3762d15SMatthias Ringwald     hci_disconnect_security_block(3);
363d3762d15SMatthias Ringwald }
364d3762d15SMatthias Ringwald 
365d3762d15SMatthias Ringwald TEST(HCI, SetDuplicateFilter){
366d3762d15SMatthias Ringwald     gap_set_scan_duplicate_filter(true);
367d3762d15SMatthias Ringwald }
368d3762d15SMatthias Ringwald 
369d3762d15SMatthias Ringwald TEST(HCI, ConnectCancel){
37028739e5fSMatthias Ringwald     uint8_t status;
37128739e5fSMatthias Ringwald     status = gap_connect_with_whitelist();
37228739e5fSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
37328739e5fSMatthias Ringwald     gap_connect_cancel();
37428739e5fSMatthias Ringwald 
37528739e5fSMatthias Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
37628739e5fSMatthias Ringwald     bd_addr_t addr = { 0 };
37728739e5fSMatthias Ringwald     gap_connect(addr, addr_type);
378d3762d15SMatthias Ringwald     gap_connect_cancel();
379d3762d15SMatthias Ringwald }
380d3762d15SMatthias Ringwald 
381d3762d15SMatthias Ringwald TEST(HCI, SetGapConnParams){
382d3762d15SMatthias Ringwald     gap_set_connection_parameters(0, 0, 0, 0, 0, 0, 0, 0);
383d3762d15SMatthias Ringwald }
384d3762d15SMatthias Ringwald 
385d3762d15SMatthias Ringwald TEST(HCI, UpdateConnParams){
386d3762d15SMatthias Ringwald     gap_update_connection_parameters(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0);
387d3762d15SMatthias Ringwald     gap_update_connection_parameters(5, 0, 0, 0, 0);
388d3762d15SMatthias Ringwald }
389d3762d15SMatthias Ringwald 
390d3762d15SMatthias Ringwald TEST(HCI, RequestConnParamUpdate){
391d3762d15SMatthias Ringwald     gap_request_connection_parameter_update(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0);
392d3762d15SMatthias Ringwald     gap_request_connection_parameter_update(5, 0, 0, 0, 0);
393d3762d15SMatthias Ringwald }
394d3762d15SMatthias Ringwald 
395d3762d15SMatthias Ringwald TEST(HCI, SetScanResponse){
396d3762d15SMatthias Ringwald     gap_scan_response_set_data(0, NULL);
397d3762d15SMatthias Ringwald }
398d3762d15SMatthias Ringwald 
399d3762d15SMatthias Ringwald TEST(HCI, SetAddrType){
400d3762d15SMatthias Ringwald     hci_le_set_own_address_type(0);
401d3762d15SMatthias Ringwald     hci_le_set_own_address_type(1);
402d3762d15SMatthias Ringwald }
403d3762d15SMatthias Ringwald 
404d3762d15SMatthias Ringwald TEST(HCI, AdvEnable){
405d3762d15SMatthias Ringwald     gap_advertisements_enable(0);
406d3762d15SMatthias Ringwald     gap_advertisements_enable(1);
407d3762d15SMatthias Ringwald }
408d3762d15SMatthias Ringwald 
409d3762d15SMatthias Ringwald TEST(HCI, SetRandomAddr){
410d3762d15SMatthias Ringwald     bd_addr_t addr = { 0 };
411d3762d15SMatthias Ringwald     hci_le_random_address_set(addr);
412d3762d15SMatthias Ringwald }
413d3762d15SMatthias Ringwald 
414d3762d15SMatthias Ringwald TEST(HCI, Disconnect){
415d3762d15SMatthias Ringwald     gap_disconnect(HCI_CON_HANDLE_INVALID);
416d3762d15SMatthias Ringwald     gap_disconnect(5);
417d3762d15SMatthias Ringwald }
418d3762d15SMatthias Ringwald 
419d3762d15SMatthias Ringwald TEST(HCI, GetRole){
420d3762d15SMatthias Ringwald     gap_get_role(HCI_CON_HANDLE_INVALID);
421d3762d15SMatthias Ringwald     gap_get_role(5);
422d3762d15SMatthias Ringwald }
42328739e5fSMatthias Ringwald TEST(HCI, hci_is_le_identity_address_type_other){
42428739e5fSMatthias Ringwald     hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_PUBLIC_IDENTITY);
42528739e5fSMatthias Ringwald     hci_is_le_identity_address_type(BD_ADDR_TYPE_LE_RANDOM);
42628739e5fSMatthias Ringwald }
42728739e5fSMatthias Ringwald 
42828739e5fSMatthias Ringwald TEST(HCI, hci_can_send_command_packet_now){
42928739e5fSMatthias Ringwald     can_send_now = 0;
43028739e5fSMatthias Ringwald     hci_can_send_command_packet_now();
43128739e5fSMatthias Ringwald     can_send_now = 1;
43228739e5fSMatthias Ringwald     hci_can_send_command_packet_now();
43328739e5fSMatthias Ringwald }
43428739e5fSMatthias Ringwald 
43528739e5fSMatthias Ringwald TEST(HCI, hci_can_send_prepared_acl_packet_now){
43628739e5fSMatthias Ringwald     can_send_now = 0;
43728739e5fSMatthias Ringwald     hci_can_send_prepared_acl_packet_now(0);
43828739e5fSMatthias Ringwald     can_send_now = 1;
43928739e5fSMatthias Ringwald     hci_can_send_prepared_acl_packet_now(0);
44028739e5fSMatthias Ringwald }
44128739e5fSMatthias Ringwald 
44228739e5fSMatthias Ringwald TEST(HCI, hci_can_send_acl_le_packet_now) {
44328739e5fSMatthias Ringwald     can_send_now = 0;
44428739e5fSMatthias Ringwald     hci_can_send_acl_le_packet_now();
44528739e5fSMatthias Ringwald     can_send_now = 1;
44628739e5fSMatthias Ringwald     hci_can_send_acl_le_packet_now();
44728739e5fSMatthias Ringwald }
448566df4e8SMatthias Ringwald TEST(HCI, hci_number_free_acl_slots_for_connection_type) {
449566df4e8SMatthias Ringwald     CHECK_EQUAL(0, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_UNKNOWN));
450566df4e8SMatthias Ringwald     CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_ACL));
451566df4e8SMatthias Ringwald     CHECK_EQUAL(255, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC));
452566df4e8SMatthias Ringwald     // tweak stack
453566df4e8SMatthias Ringwald     hci_stack_t * hci_stack = hci_get_stack();
454566df4e8SMatthias Ringwald     hci_stack->le_acl_packets_total_num = 1;
455566df4e8SMatthias Ringwald     CHECK_EQUAL(1, hci_number_free_acl_slots_for_connection_type(BD_ADDR_TYPE_LE_PUBLIC));
45628739e5fSMatthias Ringwald }
45728739e5fSMatthias Ringwald 
458566df4e8SMatthias Ringwald // TEST(HCI, hci_close) {
459566df4e8SMatthias Ringwald //     hci_close();
460566df4e8SMatthias Ringwald // }
461566df4e8SMatthias Ringwald 
46228739e5fSMatthias Ringwald TEST(HCI, gap_connect) {
46328739e5fSMatthias Ringwald     bd_addr_type_t addr_type = BD_ADDR_TYPE_LE_PUBLIC;
46428739e5fSMatthias Ringwald     bd_addr_t addr = { 0 };
46528739e5fSMatthias Ringwald 
46628739e5fSMatthias Ringwald     uint8_t status;
46728739e5fSMatthias Ringwald     status = gap_connect(addr, addr_type);
46828739e5fSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
46928739e5fSMatthias Ringwald     status = gap_connect(addr, addr_type);
47028739e5fSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
47128739e5fSMatthias Ringwald }
47228739e5fSMatthias Ringwald 
47328739e5fSMatthias Ringwald TEST(HCI, hci_emit_state) {
47428739e5fSMatthias Ringwald     hci_emit_state();
47528739e5fSMatthias Ringwald }
47628739e5fSMatthias Ringwald 
47728739e5fSMatthias Ringwald TEST(HCI, gap_request_connection_subrating) {
47828739e5fSMatthias Ringwald     int status = gap_request_connection_subrating(HCI_CON_HANDLE_INVALID, 0, 0, 0, 0, 0);
47928739e5fSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
48028739e5fSMatthias Ringwald     status = gap_request_connection_subrating(0x01, 0, 0, 0, 0, 0);
48128739e5fSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
48228739e5fSMatthias Ringwald }
48328739e5fSMatthias Ringwald 
48428739e5fSMatthias Ringwald 
48528739e5fSMatthias Ringwald TEST(HCI, hci_set_hardware_error_callback) {
48628739e5fSMatthias Ringwald     hci_set_hardware_error_callback(NULL);
48728739e5fSMatthias Ringwald }
48828739e5fSMatthias Ringwald 
48928739e5fSMatthias Ringwald TEST(HCI, hci_disconnect_all) {
49028739e5fSMatthias Ringwald     hci_disconnect_all();
49128739e5fSMatthias Ringwald }
49228739e5fSMatthias Ringwald 
49328739e5fSMatthias Ringwald TEST(HCI, hci_get_manufacturer) {
49428739e5fSMatthias Ringwald     hci_get_manufacturer();
49528739e5fSMatthias Ringwald }
49628739e5fSMatthias Ringwald TEST(HCI, gap_authorization_state) {
49728739e5fSMatthias Ringwald     gap_authorization_state(HCI_CON_HANDLE_INVALID);
49828739e5fSMatthias Ringwald }
49928739e5fSMatthias Ringwald #ifdef ENABLE_LE_PRIVACY_ADDRESS_RESOLUTION
50028739e5fSMatthias Ringwald TEST(HCI, hci_load_le_device_db_entry_into_resolving_list) {
50128739e5fSMatthias Ringwald     hci_load_le_device_db_entry_into_resolving_list(0);
50228739e5fSMatthias Ringwald }
50328739e5fSMatthias Ringwald 
50428739e5fSMatthias Ringwald TEST(HCI, hci_remove_le_device_db_entry_from_resolving_list) {
50528739e5fSMatthias Ringwald     hci_remove_le_device_db_entry_from_resolving_list(0);
50628739e5fSMatthias Ringwald }
50728739e5fSMatthias Ringwald 
50828739e5fSMatthias Ringwald TEST(HCI, gap_load_resolving_list_from_le_device_db) {
50928739e5fSMatthias Ringwald     gap_load_resolving_list_from_le_device_db();
51028739e5fSMatthias Ringwald }
51128739e5fSMatthias Ringwald #endif
51228739e5fSMatthias Ringwald 
51328739e5fSMatthias Ringwald TEST(HCI, gap_privacy_client) {
51428739e5fSMatthias Ringwald     gap_privacy_client_t client;
51528739e5fSMatthias Ringwald     gap_privacy_client_register(&client);
51628739e5fSMatthias Ringwald     gap_privacy_client_ready(&client);
51728739e5fSMatthias Ringwald     gap_privacy_client_unregister(&client);
51828739e5fSMatthias Ringwald }
519d3762d15SMatthias Ringwald 
520566df4e8SMatthias Ringwald TEST(HCI, acl_handling) {
521566df4e8SMatthias Ringwald     uint16_t con_handle = 1;
522566df4e8SMatthias Ringwald     uint8_t flags = 0;
523566df4e8SMatthias Ringwald 
524566df4e8SMatthias Ringwald     uint8_t packet[16];
525566df4e8SMatthias Ringwald     // no connection for invalid handle
526566df4e8SMatthias Ringwald     memset(packet, 0xff, sizeof(packet));
527566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
528566df4e8SMatthias Ringwald     // invalid length
529566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
530566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
531566df4e8SMatthias Ringwald     // fix length
532566df4e8SMatthias Ringwald     little_endian_store_16(packet, 2, 12);
533566df4e8SMatthias Ringwald     little_endian_store_16(packet, 6, 8);
534566df4e8SMatthias Ringwald 
535566df4e8SMatthias Ringwald     // unexpected acl continuation
536566df4e8SMatthias Ringwald     flags = 0x01;
537566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
538566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
539566df4e8SMatthias Ringwald     // invalid packet boundary flags
540566df4e8SMatthias Ringwald     flags = 0x03;
541566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
542566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
543566df4e8SMatthias Ringwald     // oversized first fragment
544566df4e8SMatthias Ringwald     flags = 0x02;
545566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
546566df4e8SMatthias Ringwald     little_endian_store_16(packet, 2, 1996);
547566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, 2000);
548566df4e8SMatthias Ringwald 
549566df4e8SMatthias Ringwald     // 1a store first flushable fragment
550566df4e8SMatthias Ringwald     flags = 0x02;
551566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
552566df4e8SMatthias Ringwald     little_endian_store_16(packet, 2, 12);
553566df4e8SMatthias Ringwald     little_endian_store_16(packet, 4, 20);
554566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
555566df4e8SMatthias Ringwald 
556566df4e8SMatthias Ringwald     // 1b another first non-flushable
557566df4e8SMatthias Ringwald     flags = 0x06;
558566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
559566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
560566df4e8SMatthias Ringwald 
561566df4e8SMatthias Ringwald     // 1c another first
562566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, sizeof(packet));
563566df4e8SMatthias Ringwald 
564566df4e8SMatthias Ringwald     // oversized continuation fragment
565566df4e8SMatthias Ringwald     flags = 0x01;
566566df4e8SMatthias Ringwald     little_endian_store_16(packet, 0, con_handle | (flags << 12));
567566df4e8SMatthias Ringwald     little_endian_store_16(packet, 2, 1996);
568566df4e8SMatthias Ringwald     packet_handler(HCI_ACL_DATA_PACKET, packet, 2000);
569566df4e8SMatthias Ringwald }
570566df4e8SMatthias Ringwald TEST(HCI, gap_le_get_own_address) {
571566df4e8SMatthias Ringwald     uint8_t  addr_type;
572566df4e8SMatthias Ringwald     bd_addr_t addr;
573566df4e8SMatthias Ringwald     hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_PUBLIC;
574566df4e8SMatthias Ringwald     gap_le_get_own_address(&addr_type, addr);
575566df4e8SMatthias Ringwald     hci_stack->le_own_addr_type = BD_ADDR_TYPE_LE_RANDOM;
576566df4e8SMatthias Ringwald     gap_le_get_own_address(&addr_type, addr);
577566df4e8SMatthias Ringwald }
578566df4e8SMatthias Ringwald 
579566df4e8SMatthias Ringwald static void simulate_hci_command_complete(uint16_t opcode, uint8_t status) {
580*5308d607SMatthias Ringwald     uint8_t packet[2 + 255];
581566df4e8SMatthias Ringwald     packet[0] = HCI_EVENT_COMMAND_COMPLETE;
582566df4e8SMatthias Ringwald     packet[1] = sizeof(packet) - 2;
583566df4e8SMatthias Ringwald     packet[2] = 1;
584566df4e8SMatthias Ringwald     little_endian_store_16(packet, 3, opcode);
585566df4e8SMatthias Ringwald     packet[5] = status;
586566df4e8SMatthias Ringwald     packet_handler(HCI_EVENT_PACKET, packet, sizeof(packet));
587566df4e8SMatthias Ringwald }
588566df4e8SMatthias Ringwald 
589566df4e8SMatthias Ringwald TEST(HCI, handle_command_complete_event) {
590566df4e8SMatthias Ringwald     struct {
591566df4e8SMatthias Ringwald         uint16_t opcode;
592566df4e8SMatthias Ringwald         uint8_t status;
593566df4e8SMatthias Ringwald     } variations[] = {
594566df4e8SMatthias Ringwald         {HCI_OPCODE_HCI_READ_LOCAL_NAME, ERROR_CODE_SUCCESS},
595566df4e8SMatthias Ringwald         {HCI_OPCODE_HCI_READ_LOCAL_NAME, ERROR_CODE_UNKNOWN_HCI_COMMAND },
596566df4e8SMatthias Ringwald         {HCI_OPCODE_HCI_READ_BUFFER_SIZE, ERROR_CODE_SUCCESS},
597566df4e8SMatthias Ringwald         {HCI_OPCODE_HCI_READ_RSSI, ERROR_CODE_SUCCESS},
598566df4e8SMatthias Ringwald         {HCI_OPCODE_HCI_READ_RSSI, ERROR_CODE_UNKNOWN_HCI_COMMAND},
599566df4e8SMatthias Ringwald     };
600566df4e8SMatthias Ringwald     for (uint8_t i = 0; i < sizeof(variations) / sizeof(variations[0]); i++) {
601566df4e8SMatthias Ringwald         // extras
602566df4e8SMatthias Ringwald         uint16_t opcode = variations[i].opcode;
603566df4e8SMatthias Ringwald         uint8_t status = variations[i].status;
604566df4e8SMatthias Ringwald         switch (opcode) {
605566df4e8SMatthias Ringwald             default:
606566df4e8SMatthias Ringwald                 break;
607566df4e8SMatthias Ringwald         }
608566df4e8SMatthias Ringwald         simulate_hci_command_complete(opcode, status);
609566df4e8SMatthias Ringwald         switch (opcode) {
610566df4e8SMatthias Ringwald             default:
611566df4e8SMatthias Ringwald                 break;
612566df4e8SMatthias Ringwald         }
613566df4e8SMatthias Ringwald     }
614566df4e8SMatthias Ringwald }
615566df4e8SMatthias Ringwald 
616d3762d15SMatthias Ringwald int main (int argc, const char * argv[]){
617fcebe167SMilanka Ringwald     btstack_run_loop_init(btstack_run_loop_posix_get_instance());
618d3762d15SMatthias Ringwald     return CommandLineTestRunner::RunAllTests(argc, argv);
619d3762d15SMatthias Ringwald }
620