xref: /btstack/test/fuzz/fuzz_hci_transport_h4.c (revision c9921182ab4b1f83e3e5c671446dca5ffdf45b90)
1 #include <stdint.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 
5 #include <btstack_util.h>
6 #include "hci_transport.h"
7 
8 static hci_transport_config_uart_t config = {
9         HCI_TRANSPORT_CONFIG_UART,
10         115200,
11         0,  // main baudrate
12         1,  // flow control
13         NULL,
14 };
15 
16 static uint8_t * read_request_buffer;
17 static uint32_t  read_request_len;
18 
19 static void (*block_received)(void);
20 
21 static int btstack_uart_fuzz_init(const btstack_uart_config_t * config){
22     return 0;
23 }
24 
25 static int btstack_uart_fuzz_open(void){
26     return 0;
27 }
28 
29 static int btstack_uart_fuzz_close(void){
30     return 0;
31 }
32 
33 static void btstack_uart_fuzz_set_block_received( void (*block_handler)(void)){
34     block_received = block_handler;
35 }
36 
37 static void btstack_uart_fuzz_set_block_sent( void (*block_handler)(void)){
38 }
39 
40 static void btstack_uart_fuzz_set_wakeup_handler( void (*the_wakeup_handler)(void)){
41 }
42 
43 static int btstack_uart_fuzz_set_parity(int parity){
44     return 0;
45 }
46 
47 static void btstack_uart_fuzz_send_block(const uint8_t *data, uint16_t size){
48 }
49 
50 static void btstack_uart_fuzz_receive_block(uint8_t *buffer, uint16_t len){
51     read_request_buffer = buffer;
52     read_request_len = len;
53 }
54 
55 static int btstack_uart_fuzz_set_baudrate(uint32_t baudrate){
56     return 0;
57 }
58 
59 static int btstack_uart_fuzz_get_supported_sleep_modes(void){
60     return BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE;
61 }
62 
63 static void btstack_uart_fuzz_set_sleep(btstack_uart_sleep_mode_t sleep_mode){
64 }
65 
66 btstack_uart_block_t uart_driver = {
67         /* int  (*init)(hci_transport_config_uart_t * config); */         &btstack_uart_fuzz_init,
68         /* int  (*open)(void); */                                         &btstack_uart_fuzz_open,
69         /* int  (*close)(void); */                                        &btstack_uart_fuzz_close,
70         /* void (*set_block_received)(void (*handler)(void)); */          &btstack_uart_fuzz_set_block_received,
71         /* void (*set_block_sent)(void (*handler)(void)); */              &btstack_uart_fuzz_set_block_sent,
72         /* int  (*set_baudrate)(uint32_t baudrate); */                    &btstack_uart_fuzz_set_baudrate,
73         /* int  (*set_parity)(int parity); */                             &btstack_uart_fuzz_set_parity,
74         /* int  (*set_flowcontrol)(int flowcontrol); */                   NULL,
75         /* void (*receive_block)(uint8_t *buffer, uint16_t len); */       &btstack_uart_fuzz_receive_block,
76         /* void (*send_block)(const uint8_t *buffer, uint16_t length); */ &btstack_uart_fuzz_send_block,
77         /* int (*get_supported_sleep_modes); */                           &btstack_uart_fuzz_get_supported_sleep_modes,
78         /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */    &btstack_uart_fuzz_set_sleep,
79         /* void (*set_wakeup_handler)(void (*handler)(void)); */          &btstack_uart_fuzz_set_wakeup_handler,
80 };
81 
82 static void packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){
83     switch (packet_type) {
84         case HCI_EVENT_PACKET:
85             if (size < 2) __builtin_trap();
86             if ((2 + packet[1]) != size)__builtin_trap();
87             break;
88         case HCI_SCO_DATA_PACKET:
89             if (size < 3) __builtin_trap();
90             if ((3 + packet[2]) != size)__builtin_trap();
91             break;
92         case HCI_ACL_DATA_PACKET:
93             if (size < 3) __builtin_trap();
94             if ((4 + little_endian_read_16( packet, 2)) != size)__builtin_trap();
95             break;
96         default:
97             __builtin_trap();
98             break;
99     }
100 }
101 
102 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
103     const hci_transport_t * transport = hci_transport_h4_instance(&uart_driver);
104     read_request_len = 0;
105     transport->init(&config);
106     transport->register_packet_handler(&packet_handler);
107     transport->open();
108     while (size > 0){
109         if (read_request_len == 0) __builtin_trap();
110 
111         uint16_t bytes_to_feed = btstack_min(read_request_len, size);
112         memcpy(read_request_buffer, data, bytes_to_feed);
113         size -= bytes_to_feed;
114         data += bytes_to_feed;
115         (*block_received)();
116     }
117     return 0;
118 }
119