xref: /btstack/src/hci.c (revision 06b35ec0015cf46daef32b3a848db95b5ef89e2c)
1 /*
2  *  hci.c
3  *
4  *  Created by Matthias Ringwald on 4/29/09.
5  *
6  */
7 
8 #include <unistd.h>
9 #include <stdarg.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include "hci.h"
13 #include "hci_dump.h"
14 
15 // the STACK is here
16 static hci_stack_t       hci_stack;
17 
18 /**
19  * get connection for given address
20  *
21  * @return connection OR NULL, if not found
22  */
23 static hci_connection_t *link_for_addr(bd_addr_t address){
24     linked_item_t *it;
25     for (it = (linked_item_t *) hci_stack.connections; it ; it = it->next){
26         if ( ! BD_ADDR_CMP( ((hci_connection_t *) it)->address, address) ){
27             return (hci_connection_t *) it;
28         }
29     }
30     return NULL;
31 }
32 
33 /**
34  * get connection for a given handle
35  *
36  * @return connection OR NULL, if not found
37  */
38 static hci_connection_t *link_for_handle(hci_con_handle_t con_handle){
39     linked_item_t *it;
40     for (it = (linked_item_t *) hci_stack.connections; it ; it = it->next){
41         if ( ((hci_connection_t *) it)->con_handle == con_handle){
42             return (hci_connection_t *) it;
43         }
44     }
45     return NULL;
46 }
47 
48 /**
49  * Dummy handler called by HCI
50  */
51 static void dummy_handler(uint8_t *packet, uint16_t size){
52 }
53 
54 /**
55  * Dummy control handler
56  */
57 static int null_control_function(void *config){
58     return 0;
59 }
60 static const char * null_control_name(void *config){
61     return "Hardware unknown";
62 }
63 static bt_control_t null_control = {
64     null_control_function,
65     null_control_function,
66     null_control_function,
67     null_control_name
68 };
69 
70 static void acl_handler(uint8_t *packet, int size){
71     hci_stack.acl_packet_handler(packet, size);
72 
73     // execute main loop
74     hci_run();
75 }
76 
77 static void event_handler(uint8_t *packet, int size){
78     bd_addr_t addr;
79 
80     // Get Num_HCI_Command_Packets
81     if (packet[0] == HCI_EVENT_COMMAND_COMPLETE ||
82         packet[0] == HCI_EVENT_COMMAND_STATUS){
83         hci_stack.num_cmd_packets = packet[2];
84     }
85 
86     // handle BT initialization
87     if (hci_stack.state == HCI_STATE_INITIALIZING){
88         // handle H4 synchronization loss on restart
89         // if (hci_stack.substate == 1 && packet[0] == HCI_EVENT_HARDWARE_ERROR){
90         //    hci_stack.substate = 0;
91         // }
92         // handle normal init sequence
93         if (hci_stack.substate % 2){
94             // odd: waiting for event
95             if (packet[0] == HCI_EVENT_COMMAND_COMPLETE){
96                 hci_stack.substate++;
97             }
98         }
99     }
100 
101     // link key request
102     if (packet[0] == HCI_EVENT_LINK_KEY_REQUEST){
103         bt_flip_addr(addr, &packet[2]);
104         hci_send_cmd(&hci_link_key_request_negative_reply, &addr);
105         return;
106     }
107 
108     // pin code request
109     if (packet[0] == HCI_EVENT_PIN_CODE_REQUEST){
110         bt_flip_addr(addr, &packet[2]);
111         hci_send_cmd(&hci_pin_code_request_reply, &addr, 4, "1234");
112     }
113 
114     hci_stack.event_packet_handler(packet, size);
115 
116 	// execute main loop
117 	hci_run();
118 }
119 
120 /** Register L2CAP handlers */
121 void hci_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size)){
122     hci_stack.event_packet_handler = handler;
123 }
124 void hci_register_acl_packet_handler  (void (*handler)(uint8_t *packet, uint16_t size)){
125     hci_stack.acl_packet_handler = handler;
126 }
127 
128 void hci_init(hci_transport_t *transport, void *config, bt_control_t *control){
129 
130     // reference to use transport layer implementation
131     hci_stack.hci_transport = transport;
132 
133     // references to used control implementation
134     if (control) {
135         hci_stack.control = control;
136     } else {
137         hci_stack.control = &null_control;
138     }
139 
140     // reference to used config
141     hci_stack.config = config;
142 
143     // empty cmd buffer
144     hci_stack.hci_cmd_buffer = malloc(3+255);
145 
146     // higher level handler
147     hci_stack.event_packet_handler = dummy_handler;
148     hci_stack.acl_packet_handler = dummy_handler;
149 
150     // register packet handlers with transport
151     transport->register_event_packet_handler( event_handler);
152     transport->register_acl_packet_handler( acl_handler);
153 }
154 
155 int hci_power_control(HCI_POWER_MODE power_mode){
156     if (power_mode == HCI_POWER_ON) {
157 
158         // set up state machine
159         hci_stack.num_cmd_packets = 1; // assume that one cmd can be sent
160         hci_stack.state = HCI_STATE_INITIALIZING;
161         hci_stack.substate = 0;
162 
163         // power on
164         hci_stack.control->on(hci_stack.config);
165 
166         // open low-level device
167         hci_stack.hci_transport->open(hci_stack.config);
168 
169     } else if (power_mode == HCI_POWER_OFF){
170 
171         // close low-level device
172         hci_stack.hci_transport->close(hci_stack.config);
173 
174         // power off
175         hci_stack.control->off(hci_stack.config);
176     }
177 
178 	// trigger next/first action
179 	hci_run();
180 
181     return 0;
182 }
183 
184 void hci_run(){
185     uint8_t micro_packet;
186     switch (hci_stack.state){
187         case HCI_STATE_INITIALIZING:
188             if (hci_stack.substate % 2) {
189                 // odd: waiting for command completion
190                 return;
191             }
192             if (hci_stack.num_cmd_packets == 0) {
193                 // cannot send command yet
194                 return;
195             }
196             switch (hci_stack.substate/2){
197                 case 0:
198                     hci_send_cmd(&hci_reset);
199                     break;
200 				case 1:
201 					hci_send_cmd(&hci_read_bd_addr);
202 					break;
203                 case 2:
204                     // ca. 15 sec
205                     hci_send_cmd(&hci_write_page_timeout, 0x6000);
206                     break;
207 				case 3:
208 					hci_send_cmd(&hci_write_scan_enable, 3); // 3 inq scan + page scan
209 					break;
210                 case 4:
211                     // done.
212                     hci_stack.state = HCI_STATE_WORKING;
213                     micro_packet = HCI_EVENT_BTSTACK_WORKING;
214                     hci_stack.event_packet_handler(&micro_packet, 1);
215                     break;
216                 default:
217                     break;
218             }
219             hci_stack.substate++;
220             break;
221         default:
222             break;
223     }
224 }
225 
226 
227 int hci_send_acl_packet(uint8_t *packet, int size){
228     return hci_stack.hci_transport->send_acl_packet(packet, size);
229 }
230 
231 int hci_send_cmd_packet(uint8_t *packet, int size){
232     if (READ_CMD_OGF(packet) != OGF_BTSTACK) {
233         hci_stack.num_cmd_packets--;
234         return hci_stack.hci_transport->send_cmd_packet(packet, size);
235     }
236 
237     hci_dump_packet( HCI_COMMAND_DATA_PACKET, 1, packet, size);
238 
239     // BTstack internal commands
240     uint8_t event[3];
241     switch (READ_CMD_OCF(packet)){
242         case HCI_BTSTACK_GET_STATE:
243             event[0] = HCI_EVENT_BTSTACK_STATE;
244             event[1] = 1;
245             event[2] = hci_stack.state;
246             hci_dump_packet( HCI_EVENT_PACKET, 0, event, 3);
247             hci_stack.event_packet_handler(event, 3);
248             break;
249         default:
250             // TODO log into hci dump as vendor specific "event"
251             printf("Error: command %u not implemented\n:", READ_CMD_OCF(packet));
252             break;
253     }
254     return 0;
255 }
256 
257 /**
258  * pre: numcmds >= 0 - it's allowed to send a command to the controller
259  */
260 int hci_send_cmd(hci_cmd_t *cmd, ...){
261     va_list argptr;
262     va_start(argptr, cmd);
263     uint8_t * hci_cmd_buffer = hci_stack.hci_cmd_buffer;
264     uint16_t size = hci_create_cmd_internal(hci_stack.hci_cmd_buffer, cmd, argptr);
265     va_end(argptr);
266     return hci_send_cmd_packet(hci_cmd_buffer, size);
267 }