1 /*
2 * Copyright (C) 2020 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "hci_transport_h2_stm32.c"
39
40 /*
41 * hci_transport_h2_stm32.c
42 *
43 * HCI Transport API implementation for STM32Cube USB Host Stack
44 */
45
46 // include STM32 first to avoid warning about redefinition of UNUSED
47 #include "usb_host.h"
48 #include "usbh_bluetooth.h"
49
50 #include <stddef.h>
51
52 #include "hci_transport_h2_stm32.h"
53
54 #include "bluetooth.h"
55
56 #include "btstack_debug.h"
57 #include "btstack_run_loop.h"
58
59 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = NULL;
60
61 // data source for integration with BTstack Runloop
62 static btstack_data_source_t transport_data_source;
63
hci_transport_h2_stm32_process(btstack_data_source_t * ds,btstack_data_source_callback_type_t callback_type)64 static void hci_transport_h2_stm32_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
65 switch (callback_type){
66 case DATA_SOURCE_CALLBACK_POLL:
67 MX_USB_HOST_Process();
68 break;
69 default:
70 break;
71 }
72 }
73
hci_transport_h2_stm32_block_sent(void)74 static void hci_transport_h2_stm32_block_sent(void) {
75 static const uint8_t packet_sent_event[] = {HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
76 // notify upper stack that it can send again
77 packet_handler(HCI_EVENT_PACKET, (uint8_t *) &packet_sent_event[0], sizeof(packet_sent_event));
78 }
79
hci_transport_h2_stm32_packet_received(uint8_t packet_type,uint8_t * packet,uint16_t size)80 static void hci_transport_h2_stm32_packet_received(uint8_t packet_type, uint8_t * packet, uint16_t size){
81 packet_handler(packet_type, packet, size);
82 }
83
hci_transport_h2_stm32_init(const void * transport_config)84 static void hci_transport_h2_stm32_init(const void * transport_config){
85 UNUSED(transport_config);
86 usbh_bluetooth_set_packet_sent(&hci_transport_h2_stm32_block_sent);
87 usbh_bluetooth_set_packet_received(&hci_transport_h2_stm32_packet_received);
88 log_info("hci_transport_h2_stm32_init");
89 }
90
hci_transport_h2_stm32_open(void)91 static int hci_transport_h2_stm32_open(void){
92 // set up polling data_source
93 btstack_run_loop_set_data_source_handler(&transport_data_source, &hci_transport_h2_stm32_process);
94 btstack_run_loop_enable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
95 btstack_run_loop_add_data_source(&transport_data_source);
96 return 0;
97 }
98
hci_transport_h2_stm32_close(void)99 static int hci_transport_h2_stm32_close(void){
100 // remove data source
101 btstack_run_loop_disable_data_source_callbacks(&transport_data_source, DATA_SOURCE_CALLBACK_POLL);
102 btstack_run_loop_remove_data_source(&transport_data_source);
103 return -1;
104 }
105
hci_transport_h2_stm32_register_packet_handler(void (* handler)(uint8_t packet_type,uint8_t * packet,uint16_t size))106 static void hci_transport_h2_stm32_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
107 packet_handler = handler;
108 }
109
hci_transport_h2_stm32_can_send_now(uint8_t packet_type)110 static int hci_transport_h2_stm32_can_send_now(uint8_t packet_type){
111 return usbh_bluetooth_can_send_now();
112 }
113
hci_transport_h2_stm32_send_packet(uint8_t packet_type,uint8_t * packet,int size)114 static int hci_transport_h2_stm32_send_packet(uint8_t packet_type, uint8_t * packet, int size){
115 switch (packet_type){
116 case HCI_COMMAND_DATA_PACKET:
117 usbh_bluetooth_send_cmd(packet, size);
118 return 0;
119 case HCI_ACL_DATA_PACKET:
120 usbh_bluetooth_send_acl(packet, size);
121 return 0;
122 default:
123 break;
124 }
125 return -1;
126 }
127
hci_transport_h2_stm32_set_sco_config(uint16_t voice_setting,int num_connections)128 static void hci_transport_h2_stm32_set_sco_config(uint16_t voice_setting, int num_connections){
129 log_info("hci_transport_h2_stm32_send_packet, voice 0x%02x, num connections %u", voice_setting, num_connections);
130 }
131
hci_transport_h2_stm32_instance(void)132 const hci_transport_t * hci_transport_h2_stm32_instance(void) {
133
134 static const hci_transport_t instance = {
135 /* const char * name; */ "H4",
136 /* void (*init) (const void *transport_config); */ &hci_transport_h2_stm32_init,
137 /* int (*open)(void); */ &hci_transport_h2_stm32_open,
138 /* int (*close)(void); */ &hci_transport_h2_stm32_close,
139 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_h2_stm32_register_packet_handler,
140 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_h2_stm32_can_send_now,
141 /* int (*send_packet)(...); */ &hci_transport_h2_stm32_send_packet,
142 /* int (*set_baudrate)(uint32_t baudrate); */ NULL,
143 /* void (*reset_link)(void); */ NULL,
144 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ &hci_transport_h2_stm32_set_sco_config,
145 };
146 return &instance;
147 }
148