xref: /btstack/src/hci_transport_h4.c (revision 8a23fc5312800685de9e8e4fa3907c561747a9c6)
1 /*
2  * Copyright (C) 2014 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 MATTHIAS
24  * RINGWALD 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 /*
39  *  hci_h4_transport.c
40  *
41  *  HCI Transport API implementation for H4 protocol over POSIX with optional support for eHCILL
42  *
43  *  Created by Matthias Ringwald on 4/29/09.
44  */
45 
46 #include "btstack_config.h"
47 
48 #include "btstack_debug.h"
49 #include "hci.h"
50 #include "hci_transport.h"
51 #include "btstack_uart_block.h"
52 
53 #ifdef HAVE_EHCILL
54 
55 // eHCILL commands
56 #define EHCILL_GO_TO_SLEEP_IND 0x030
57 #define EHCILL_GO_TO_SLEEP_ACK 0x031
58 #define EHCILL_WAKE_UP_IND     0x032
59 #define EHCILL_WAKE_UP_ACK     0x033
60 
61 static int  hci_transport_h4_ehcill_outgoing_packet_ready(void);
62 static int  hci_transport_h4_ehcill_sleep_mode_active(void);
63 static void hci_transport_h4_echill_send_wakeup_ind(void);
64 static void hci_transport_h4_ehcill_handle_command(uint8_t action);
65 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void);
66 static void hci_transport_h4_ehcill_handle_packet_sent(void);
67 static void hci_transport_h4_ehcill_open(void);
68 static void hci_transport_h4_ehcill_reset_statemachine(void);
69 static void hci_transport_h4_ehcill_send_ehcill_command(void);
70 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void);
71 static void hci_transport_h4_ehcill_trigger_wakeup(void);
72 
73 typedef enum {
74     EHCILL_STATE_SLEEP,
75     EHCILL_STATE_W4_ACK,
76     EHCILL_STATE_AWAKE
77 } EHCILL_STATE;
78 
79 // eHCILL state machine
80 static EHCILL_STATE ehcill_state;
81 static uint8_t      ehcill_command_to_send;
82 
83 // work around for eHCILL problem
84 static btstack_timer_source_t ehcill_sleep_ack_timer;
85 
86 #endif
87 
88 
89 // assert pre-buffer for packet type is available
90 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0)
91 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h
92 #endif
93 
94 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size);
95 
96 typedef enum {
97     H4_W4_PACKET_TYPE,
98     H4_W4_EVENT_HEADER,
99     H4_W4_ACL_HEADER,
100     H4_W4_SCO_HEADER,
101     H4_W4_PAYLOAD,
102 } H4_STATE;
103 
104 typedef enum {
105     TX_IDLE = 1,
106     TX_W4_PACKET_SENT,
107 #ifdef HAVE_EHCILL
108     TX_W4_WAKEUP,
109     TX_W2_EHCILL_SEND,
110     TX_W4_EHCILL_SENT,
111 #endif
112 } TX_STATE;
113 
114 // UART Driver + Config
115 static const btstack_uart_block_t * btstack_uart;
116 static btstack_uart_sleep_mode_t btstack_uart_sleep_mode;
117 static btstack_uart_config_t uart_config;
118 
119 // write state
120 static TX_STATE tx_state;
121 static uint8_t * tx_data;
122 static uint16_t  tx_len;   // 0 == no outgoing packet
123 
124 static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
125 
126 static  void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler;
127 
128 // packet reader state machine
129 static  H4_STATE h4_state;
130 static int bytes_to_read;
131 static int read_pos;
132 
133 // incoming packet buffer
134 static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + 1 + HCI_PACKET_BUFFER_SIZE]; // packet type + max(acl header + acl payload, event header + event data)
135 static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE];
136 
137 static int hci_transport_h4_set_baudrate(uint32_t baudrate){
138     log_info("hci_transport_h4_set_baudrate %u", baudrate);
139     return btstack_uart->set_baudrate(baudrate);
140 }
141 
142 static void hci_transport_h4_reset_statemachine(void){
143     h4_state = H4_W4_PACKET_TYPE;
144     read_pos = 0;
145     bytes_to_read = 1;
146 }
147 
148 static void hci_transport_h4_trigger_next_read(void){
149     // log_info("hci_transport_h4_trigger_next_read: %u bytes", bytes_to_read);
150     btstack_uart->receive_block(&hci_packet[read_pos], bytes_to_read);
151 }
152 
153 static void hci_transport_h4_block_read(void){
154 
155     read_pos += bytes_to_read;
156 
157     switch (h4_state) {
158         case H4_W4_PACKET_TYPE:
159             switch (hci_packet[0]){
160                 case HCI_EVENT_PACKET:
161                     bytes_to_read = HCI_EVENT_HEADER_SIZE;
162                     h4_state = H4_W4_EVENT_HEADER;
163                     break;
164                 case HCI_ACL_DATA_PACKET:
165                     bytes_to_read = HCI_ACL_HEADER_SIZE;
166                     h4_state = H4_W4_ACL_HEADER;
167                     break;
168                 case HCI_SCO_DATA_PACKET:
169                     bytes_to_read = HCI_SCO_HEADER_SIZE;
170                     h4_state = H4_W4_SCO_HEADER;
171                     break;
172 #ifdef HAVE_EHCILL
173                 case EHCILL_GO_TO_SLEEP_IND:
174                 case EHCILL_GO_TO_SLEEP_ACK:
175                 case EHCILL_WAKE_UP_IND:
176                 case EHCILL_WAKE_UP_ACK:
177                     hci_transport_h4_ehcill_handle_command(hci_packet[0]);
178                     hci_transport_h4_reset_statemachine();
179                     break;
180 #endif
181                 default:
182                     log_error("hci_transport_h4: invalid packet type 0x%02x", hci_packet[0]);
183                     hci_transport_h4_reset_statemachine();
184                     break;
185             }
186             break;
187 
188         case H4_W4_EVENT_HEADER:
189             bytes_to_read = hci_packet[2];
190             h4_state = H4_W4_PAYLOAD;
191             break;
192 
193         case H4_W4_ACL_HEADER:
194             bytes_to_read = little_endian_read_16( hci_packet, 3);
195             // check ACL length
196             if (HCI_ACL_HEADER_SIZE + bytes_to_read >  HCI_PACKET_BUFFER_SIZE){
197                 log_error("hci_transport_h4: invalid ACL payload len %u - only space for %u", bytes_to_read, HCI_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE);
198                 hci_transport_h4_reset_statemachine();
199                 break;
200             }
201             h4_state = H4_W4_PAYLOAD;
202             break;
203 
204         case H4_W4_SCO_HEADER:
205             bytes_to_read = hci_packet[3];
206             h4_state = H4_W4_PAYLOAD;
207             break;
208 
209         case H4_W4_PAYLOAD:
210             packet_handler(hci_packet[0], &hci_packet[1], read_pos-1);
211             hci_transport_h4_reset_statemachine();
212             break;
213         default:
214             break;
215     }
216     hci_transport_h4_trigger_next_read();
217 }
218 
219 static void hci_transport_h4_block_sent(void){
220     switch (tx_state){
221         case TX_W4_PACKET_SENT:
222             // packet fully sent, reset state
223             tx_len = 0;
224             tx_state = TX_IDLE;
225 
226 #ifdef HAVE_EHCILL
227             // notify eHCILL engine
228             hci_transport_h4_ehcill_handle_packet_sent();
229 #endif
230             // notify upper stack that it can send again
231             packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event));
232             break;
233 
234 #ifdef HAVE_EHCILL
235         case TX_W4_EHCILL_SENT:
236             hci_transport_h4_ehcill_handle_ehcill_command_sent();
237             break;
238 #endif
239 
240         default:
241             break;
242     }
243 }
244 
245 static int hci_transport_h4_can_send_now(uint8_t packet_type){
246     return tx_state == TX_IDLE;
247 }
248 
249 static int hci_transport_h4_send_packet(uint8_t packet_type, uint8_t * packet, int size){
250     // store packet type before actual data and increase size
251     size++;
252     packet--;
253     *packet = packet_type;
254 
255     // store request
256     tx_len   = size;
257     tx_data  = packet;
258 
259 #ifdef HAVE_EHCILL
260     if (hci_transport_h4_ehcill_sleep_mode_active()){
261         hci_transport_h4_ehcill_trigger_wakeup();
262         return 0;
263     }
264 #endif
265 
266     // start sending
267     tx_state = TX_W4_PACKET_SENT;
268     btstack_uart->send_block(packet, size);
269     return 0;
270 }
271 
272 static void hci_transport_h4_init(const void * transport_config){
273     // check for hci_transport_config_uart_t
274     if (!transport_config) {
275         log_error("hci_transport_h4: no config!");
276         return;
277     }
278     if (((hci_transport_config_t*)transport_config)->type != HCI_TRANSPORT_CONFIG_UART) {
279         log_error("hci_transport_h4: config not of type != HCI_TRANSPORT_CONFIG_UART!");
280         return;
281     }
282 
283     // extract UART config from transport config
284     hci_transport_config_uart_t * hci_transport_config_uart = (hci_transport_config_uart_t*) transport_config;
285     uart_config.baudrate    = hci_transport_config_uart->baudrate_init;
286     uart_config.flowcontrol = hci_transport_config_uart->flowcontrol;
287     uart_config.device_name = hci_transport_config_uart->device_name;
288 
289     // setup UART driver
290     btstack_uart->init(&uart_config);
291     btstack_uart->set_block_received(&hci_transport_h4_block_read);
292     btstack_uart->set_block_sent(&hci_transport_h4_block_sent);
293 }
294 
295 static int hci_transport_h4_open(void){
296     int res = btstack_uart->open();
297     if (res){
298         return res;
299     }
300     hci_transport_h4_reset_statemachine();
301     hci_transport_h4_trigger_next_read();
302 
303     tx_state = TX_IDLE;
304 
305 #ifdef HAVE_EHCILL
306     hci_transport_h4_ehcill_open();
307 #endif
308     return 0;
309 }
310 
311 static int hci_transport_h4_close(void){
312     return btstack_uart->close();
313 }
314 
315 static void hci_transport_h4_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
316     packet_handler = handler;
317 }
318 
319 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){
320 }
321 
322 //
323 // --- main part of eHCILL implementation ---
324 //
325 
326 #ifdef HAVE_EHCILL
327 
328 static void hci_transport_h4_ehcill_open(void){
329     hci_transport_h4_ehcill_reset_statemachine();
330 
331     // find best sleep mode to use: wake on CTS, wake on RX, none
332     btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_OFF;
333     int supported_sleep_modes = 0;
334     if (btstack_uart->get_supported_sleep_modes){
335         supported_sleep_modes = btstack_uart->get_supported_sleep_modes();
336     }
337     if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE){
338         log_info("eHCILL: using wake on CTS");
339         btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_HIGH_WAKE_ON_CTS_PULSE;
340     } else if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_LOW_WAKE_ON_RX_EDGE){
341         log_info("eHCILL: using wake on RX");
342         btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_LOW_WAKE_ON_RX_EDGE;
343     } else {
344         log_info("eHCILL: UART driver does not provide compatible sleep mode");
345     }
346 }
347 
348 static void hci_transport_h4_echill_send_wakeup_ind(void){
349     // update state
350     tx_state     = TX_W4_WAKEUP;
351     ehcill_state = EHCILL_STATE_W4_ACK;
352     ehcill_command_to_send = EHCILL_WAKE_UP_IND;
353     btstack_uart->send_block(&ehcill_command_to_send, 1);
354 }
355 
356 static int hci_transport_h4_ehcill_outgoing_packet_ready(void){
357     return tx_len != 0;
358 }
359 
360 static int  hci_transport_h4_ehcill_sleep_mode_active(void){
361     return ehcill_state == EHCILL_STATE_SLEEP;
362 }
363 
364 static void hci_transport_h4_ehcill_reset_statemachine(void){
365     ehcill_state = EHCILL_STATE_AWAKE;
366 }
367 
368 static void hci_transport_h4_ehcill_send_ehcill_command(void){
369     log_debug("eHCILL: send command %02x", ehcill_command_to_send);
370     tx_state = TX_W4_EHCILL_SENT;
371     btstack_uart->send_block(&ehcill_command_to_send, 1);
372 }
373 
374 static void hci_transport_h4_ehcill_sleep_ack_timer_handler(btstack_timer_source_t * timer){
375     log_debug("eHCILL: timer triggered");
376     hci_transport_h4_ehcill_send_ehcill_command();
377 }
378 
379 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void){
380     // setup timer
381     log_debug("eHCILL: set timer for sending command");
382     btstack_run_loop_set_timer_handler(&ehcill_sleep_ack_timer, &hci_transport_h4_ehcill_sleep_ack_timer_handler);
383     btstack_run_loop_set_timer(&ehcill_sleep_ack_timer, 50);
384     btstack_run_loop_add_timer(&ehcill_sleep_ack_timer);
385 
386     // TODO: trigger run loop
387     // btstack_run_loop_embedded_trigger();
388 }
389 
390 static void hci_transport_h4_ehcill_trigger_wakeup(void){
391     switch (tx_state){
392         case TX_W2_EHCILL_SEND:
393         case TX_W4_EHCILL_SENT:
394             // wake up / sleep ack in progress, nothing to do now
395             return;
396         case TX_IDLE:
397         default:
398             // all clear, prepare for wakeup
399             break;
400     }
401     // UART needed again
402     if (btstack_uart_sleep_mode){
403         btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF);
404     }
405     hci_transport_h4_echill_send_wakeup_ind();
406 }
407 
408 static void hci_transport_h4_ehcill_schedule_ecill_command(uint8_t command){
409     ehcill_command_to_send = command;
410     switch (tx_state){
411         case TX_IDLE:
412             if (ehcill_command_to_send == EHCILL_WAKE_UP_ACK){
413                 // send right away
414                 hci_transport_h4_ehcill_send_ehcill_command();
415             } else {
416                 // change state so BTstack cannot send and setup timer
417                 tx_state = TX_W2_EHCILL_SEND;
418                 hci_transport_h4_ehcill_sleep_ack_timer_setup();
419             }
420             break;
421         default:
422             break;
423     }
424 }
425 
426 static void hci_transport_h4_ehcill_handle_command(uint8_t action){
427     // log_info("hci_transport_h4_ehcill_handle: %x, state %u, defer_rx %u", action, ehcill_state, ehcill_defer_rx_size);
428     switch(ehcill_state){
429         case EHCILL_STATE_AWAKE:
430             switch(action){
431                 case EHCILL_GO_TO_SLEEP_IND:
432                     ehcill_state = EHCILL_STATE_SLEEP;
433                     log_info("eHCILL: GO_TO_SLEEP_IND RX");
434                     hci_transport_h4_ehcill_schedule_ecill_command(EHCILL_GO_TO_SLEEP_ACK);
435                     break;
436                 default:
437                     break;
438             }
439             break;
440 
441         case EHCILL_STATE_SLEEP:
442             switch(action){
443                 case EHCILL_WAKE_UP_IND:
444                     ehcill_state = EHCILL_STATE_AWAKE;
445                     log_info("eHCILL: WAKE_UP_IND RX");
446                     hci_transport_h4_ehcill_schedule_ecill_command(EHCILL_WAKE_UP_ACK);
447                     break;
448 
449                 default:
450                     break;
451             }
452             break;
453 
454         case EHCILL_STATE_W4_ACK:
455             switch(action){
456                 case EHCILL_WAKE_UP_IND:
457                 case EHCILL_WAKE_UP_ACK:
458                     log_info("eHCILL: WAKE_UP_IND or ACK");
459                     tx_state = TX_W4_PACKET_SENT;
460                     ehcill_state = EHCILL_STATE_AWAKE;
461                     btstack_uart->send_block(tx_data, tx_len);
462                     break;
463                 default:
464                     break;
465             }
466             break;
467     }
468 }
469 
470 static void hci_transport_h4_ehcill_handle_packet_sent(void){
471     // now, send pending ehcill command if neccessary
472     switch (ehcill_command_to_send){
473         case EHCILL_GO_TO_SLEEP_ACK:
474             hci_transport_h4_ehcill_sleep_ack_timer_setup();
475             break;
476         case EHCILL_WAKE_UP_IND:
477             hci_transport_h4_ehcill_send_ehcill_command();
478             break;
479         default:
480             break;
481     }
482 }
483 
484 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void){
485     tx_state = TX_IDLE;
486     int command = ehcill_command_to_send;
487     ehcill_command_to_send = 0;
488     if (command == EHCILL_GO_TO_SLEEP_ACK) {
489         log_info("eHCILL: GO_TO_SLEEP_ACK sent, enter sleep mode");
490         // UART not needed after EHCILL_GO_TO_SLEEP_ACK was sent
491         if (btstack_uart_sleep_mode != BTSTACK_UART_SLEEP_OFF){
492             btstack_uart->set_sleep(btstack_uart_sleep_mode);
493         }
494     }
495     // already packet ready? then start wakeup
496     if (hci_transport_h4_ehcill_outgoing_packet_ready()){
497         if (btstack_uart_sleep_mode){
498             btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF);
499         }
500         hci_transport_h4_echill_send_wakeup_ind();
501     }
502     // TODO: trigger run loop
503     // btstack_run_loop_embedded_trigger();
504 }
505 
506 #endif
507 // --- end of eHCILL implementation ---------
508 
509 static const hci_transport_t hci_transport_h4 = {
510     /* const char * name; */                                        "H4",
511     /* void   (*init) (const void *transport_config); */            &hci_transport_h4_init,
512     /* int    (*open)(void); */                                     &hci_transport_h4_open,
513     /* int    (*close)(void); */                                    &hci_transport_h4_close,
514     /* void   (*register_packet_handler)(void (*handler)(...); */   &hci_transport_h4_register_packet_handler,
515     /* int    (*can_send_packet_now)(uint8_t packet_type); */       &hci_transport_h4_can_send_now,
516     /* int    (*send_packet)(...); */                               &hci_transport_h4_send_packet,
517     /* int    (*set_baudrate)(uint32_t baudrate); */                &hci_transport_h4_set_baudrate,
518     /* void   (*reset_link)(void); */                               NULL,
519 };
520 
521 // configure and return h4 singleton
522 const hci_transport_t * hci_transport_h4_instance(const btstack_uart_block_t * uart_driver) {
523     btstack_uart = uart_driver;
524     return &hci_transport_h4;
525 }
526