1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "CppUTest/TestHarness.h"
7 #include "CppUTest/CommandLineTestRunner.h"
8 #include "CppUTestExt/MockSupport.h"
9
10 #include "hci_cmd.h"
11
12 #include "btstack_memory.h"
13 #include "hci.h"
14 #include "ble/gatt_client.h"
15 #include "btstack_event.h"
16 #include "hci_dump.h"
17 #include "hci_dump_posix_fs.h"
18 #include "btstack_debug.h"
19
20 typedef struct {
21 uint8_t type;
22 uint16_t size;
23 uint8_t buffer[258];
24 } hci_packet_t;
25
26 #define MAX_HCI_PACKETS 10
27 static uint16_t transport_count_packets;
28 static hci_packet_t transport_packets[MAX_HCI_PACKETS];
29
30 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size);
31
32 static const uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
33
hci_transport_test_set_baudrate(uint32_t baudrate)34 static int hci_transport_test_set_baudrate(uint32_t baudrate){
35 return 0;
36 }
37
hci_transport_test_can_send_now(uint8_t packet_type)38 static int hci_transport_test_can_send_now(uint8_t packet_type){
39 return 1;
40 }
41
hci_transport_test_send_packet(uint8_t packet_type,uint8_t * packet,int size)42 static int hci_transport_test_send_packet(uint8_t packet_type, uint8_t * packet, int size){
43 btstack_assert(transport_count_packets < MAX_HCI_PACKETS);
44 memcpy(transport_packets[transport_count_packets].buffer, packet, size);
45 transport_packets[transport_count_packets].type = packet_type;
46 transport_packets[transport_count_packets].size = size;
47 transport_count_packets++;
48 // notify upper stack that it can send again
49 packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event));
50 return 0;
51 }
52
hci_transport_test_init(const void * transport_config)53 static void hci_transport_test_init(const void * transport_config){
54 }
55
hci_transport_test_open(void)56 static int hci_transport_test_open(void){
57 return 0;
58 }
59
hci_transport_test_close(void)60 static int hci_transport_test_close(void){
61 return 0;
62 }
63
hci_transport_test_register_packet_handler(void (* handler)(uint8_t packet_type,uint8_t * packet,uint16_t size))64 static void hci_transport_test_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
65 packet_handler = handler;
66 }
67
68 static const hci_transport_t hci_transport_test = {
69 /* const char * name; */ "TEST",
70 /* void (*init) (const void *transport_config); */ &hci_transport_test_init,
71 /* int (*open)(void); */ &hci_transport_test_open,
72 /* int (*close)(void); */ &hci_transport_test_close,
73 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_test_register_packet_handler,
74 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_test_can_send_now,
75 /* int (*send_packet)(...); */ &hci_transport_test_send_packet,
76 /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_test_set_baudrate,
77 /* void (*reset_link)(void); */ NULL,
78 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL,
79 };
80
81 static uint16_t next_hci_packet;
82
CHECK_EQUAL_ARRAY(const uint8_t * expected,uint8_t * actual,int size)83 void CHECK_EQUAL_ARRAY(const uint8_t * expected, uint8_t * actual, int size){
84 for (int i=0; i<size; i++){
85 BYTES_EQUAL(expected[i], actual[i]);
86 }
87 }
88
CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command)89 void CHECK_HCI_COMMAND(const hci_cmd_t * expected_hci_command){
90 uint16_t actual_opcode = little_endian_read_16(transport_packets[next_hci_packet].buffer, 0);
91 next_hci_packet++;
92 CHECK_EQUAL(expected_hci_command->opcode, actual_opcode);
93 }
94
TEST_GROUP(GAP_LE)95 TEST_GROUP(GAP_LE){
96 void setup(void){
97 transport_count_packets = 0;
98 next_hci_packet = 0;
99 hci_init(&hci_transport_test, NULL);
100 hci_simulate_working_fuzz();
101 // register for HCI events
102 mock().expectOneCall("hci_can_send_packet_now_using_packet_buffer").andReturnValue(1);
103 }
104 void teardown(void){
105 mock().clear();
106 }
107 };
108
TEST(GAP_LE,ScanStart)109 TEST(GAP_LE, ScanStart){
110 log_info("TEST(GAP_LE, ScanStart)");
111 gap_start_scan();
112 CHECK_EQUAL(1, transport_count_packets);
113 CHECK_HCI_COMMAND(&hci_le_set_scan_enable);
114 }
TEST(GAP_LE,ScanStartStop)115 TEST(GAP_LE, ScanStartStop){
116 log_info("TEST(GAP_LE, ScanStartStop)");
117 gap_start_scan();
118 gap_stop_scan();
119 CHECK_EQUAL(2, transport_count_packets);
120 CHECK_HCI_COMMAND(&hci_le_set_scan_enable);
121 CHECK_HCI_COMMAND(&hci_le_set_scan_enable);
122 }
123
TEST(GAP_LE,ScanStartParam)124 TEST(GAP_LE, ScanStartParam){
125 log_info("TEST(GAP_LE, ScanStartParam)");
126 gap_start_scan();
127 gap_set_scan_parameters(0, 10, 10);
128 CHECK_EQUAL(4, transport_count_packets);
129 CHECK_HCI_COMMAND(&hci_le_set_scan_enable);
130 CHECK_HCI_COMMAND(&hci_le_set_scan_enable);
131 CHECK_HCI_COMMAND(&hci_le_set_scan_parameters);
132 CHECK_HCI_COMMAND(&hci_le_set_scan_enable);
133 }
134
main(int argc,const char * argv[])135 int main (int argc, const char * argv[]){
136 // log into file using HCI_DUMP_PACKETLOGGER format
137 const char * pklg_path = "hci_dump.pklg";
138 hci_dump_posix_fs_open(pklg_path, HCI_DUMP_PACKETLOGGER);
139 hci_dump_init(hci_dump_posix_fs_get_instance());
140 printf("Packet Log: %s\n", pklg_path);
141
142 return CommandLineTestRunner::RunAllTests(argc, argv);
143 }
144