xref: /btstack/port/stm32-f4discovery-usb/port/hci_transport_h2_stm32.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
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