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 basic H4 protocol over POSIX 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 // #error "HCI Transport H4 POSIX does not support eHCILL yet. Please remove HAVE_EHCILL from your btstack-config.h" 55 // #endif 56 57 #ifdef HAVE_EHCILL 58 59 // eHCILL commands 60 #define EHCILL_GO_TO_SLEEP_IND 0x030 61 #define EHCILL_GO_TO_SLEEP_ACK 0x031 62 #define EHCILL_WAKE_UP_IND 0x032 63 #define EHCILL_WAKE_UP_ACK 0x033 64 65 static void hci_transport_h4_ehcill_handle(uint8_t action); 66 static void hci_transport_h4_ehcill_reset_statemachine(void); 67 static void hci_transport_h4_ehcill_send_ehcill_command(void); 68 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void); 69 static int hci_transport_h4_ehcill_outgoing_packet_ready(void); 70 static void hci_transport_h4_ehcill_reactivate_rx(void); 71 static void hci_transport_h4_echill_send_wakeup_ind(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 static uint8_t * ehcill_defer_rx_buffer; 83 static uint16_t ehcill_defer_rx_size = 0; 84 85 // work around for eHCILL problem 86 static btstack_timer_source_t ehcill_sleep_ack_timer; 87 88 static uint8_t * tx_data; 89 90 #endif 91 92 93 // assert pre-buffer for packet type is available 94 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) 95 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h 96 #endif 97 98 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); 99 100 typedef enum { 101 H4_W4_PACKET_TYPE, 102 H4_W4_EVENT_HEADER, 103 H4_W4_ACL_HEADER, 104 H4_W4_SCO_HEADER, 105 H4_W4_PAYLOAD, 106 } H4_STATE; 107 108 typedef enum { 109 TX_IDLE = 1, 110 TX_W4_PACKET_SENT, 111 #ifdef HAVE_EHCILL 112 TX_W4_WAKEUP, 113 TX_W2_EHCILL_SEND, 114 TX_W4_EHCILL_SENT, 115 #endif 116 } TX_STATE; 117 118 // UART Driver + Config 119 static const btstack_uart_block_t * btstack_uart; 120 static btstack_uart_config_t uart_config; 121 122 // write state 123 static TX_STATE tx_state; // updated from block_sent callback 124 static uint16_t tx_len; // 0 == no outgoing packet 125 static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 126 127 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; 128 129 // packet reader state machine 130 static H4_STATE h4_state; 131 static int bytes_to_read; 132 static int read_pos; 133 134 // incoming packet buffer 135 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) 136 static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE]; 137 138 static int hci_transport_h4_set_baudrate(uint32_t baudrate){ 139 log_info("hci_transport_h4_set_baudrate %u", baudrate); 140 return btstack_uart->set_baudrate(baudrate); 141 } 142 143 static void hci_transport_h4_reset_statemachine(void){ 144 h4_state = H4_W4_PACKET_TYPE; 145 read_pos = 0; 146 bytes_to_read = 1; 147 } 148 149 static void hci_transport_h4_trigger_next_read(void){ 150 // trigger next read 151 btstack_uart->receive_block(&hci_packet[read_pos], bytes_to_read); 152 } 153 154 static void hci_transport_h4_block_read(void){ 155 156 read_pos += bytes_to_read; 157 158 switch (h4_state) { 159 case H4_W4_PACKET_TYPE: 160 switch (hci_packet[0]){ 161 case HCI_EVENT_PACKET: 162 bytes_to_read = HCI_EVENT_HEADER_SIZE; 163 h4_state = H4_W4_EVENT_HEADER; 164 break; 165 case HCI_ACL_DATA_PACKET: 166 bytes_to_read = HCI_ACL_HEADER_SIZE; 167 h4_state = H4_W4_ACL_HEADER; 168 break; 169 case HCI_SCO_DATA_PACKET: 170 bytes_to_read = HCI_SCO_HEADER_SIZE; 171 h4_state = H4_W4_SCO_HEADER; 172 break; 173 #ifdef HAVE_EHCILL 174 case EHCILL_GO_TO_SLEEP_IND: 175 case EHCILL_GO_TO_SLEEP_ACK: 176 case EHCILL_WAKE_UP_IND: 177 case EHCILL_WAKE_UP_ACK: 178 bytes_to_read = 1; 179 hci_transport_h4_ehcill_handle(hci_packet[0]); 180 break; 181 #endif 182 default: 183 log_error("h4_process: invalid packet type 0x%02x", hci_packet[0]); 184 hci_transport_h4_reset_statemachine(); 185 break; 186 } 187 break; 188 189 case H4_W4_EVENT_HEADER: 190 bytes_to_read = hci_packet[2]; 191 h4_state = H4_W4_PAYLOAD; 192 break; 193 194 case H4_W4_ACL_HEADER: 195 bytes_to_read = little_endian_read_16( hci_packet, 3); 196 // check ACL length 197 if (HCI_ACL_HEADER_SIZE + bytes_to_read > HCI_PACKET_BUFFER_SIZE){ 198 log_error("h4_process: invalid ACL payload len %u - only space for %u", bytes_to_read, HCI_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); 199 hci_transport_h4_reset_statemachine(); 200 break; 201 } 202 h4_state = H4_W4_PAYLOAD; 203 break; 204 205 case H4_W4_SCO_HEADER: 206 bytes_to_read = hci_packet[3]; 207 h4_state = H4_W4_PAYLOAD; 208 break; 209 210 case H4_W4_PAYLOAD: 211 packet_handler(hci_packet[0], &hci_packet[1], read_pos-1); 212 hci_transport_h4_reset_statemachine(); 213 break; 214 default: 215 break; 216 } 217 hci_transport_h4_trigger_next_read(); 218 } 219 220 static void hci_transport_h4_block_sent(void){ 221 tx_state = TX_IDLE; 222 switch (tx_state){ 223 case TX_W4_PACKET_SENT: 224 // packet fully sent, reset state 225 tx_len = 0; 226 227 #ifdef HAVE_EHCILL 228 // now, send pending ehcill command if neccessary 229 switch (ehcill_command_to_send){ 230 case EHCILL_GO_TO_SLEEP_ACK: 231 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 232 break; 233 case EHCILL_WAKE_UP_IND: 234 hci_transport_h4_ehcill_send_ehcill_command(); 235 break; 236 default: 237 break; 238 } 239 #endif 240 // notify upper stack that it can send again 241 packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event)); 242 break; 243 244 #ifdef HAVE_EHCILL 245 case TX_W4_EHCILL_SENT: { 246 int command = ehcill_command_to_send; 247 ehcill_command_to_send = 0; 248 if (command == EHCILL_GO_TO_SLEEP_ACK) { 249 // UART not needed after EHCILL_GO_TO_SLEEP_ACK was sent 250 if (btstack_uart->get_supported_sleep_modes() & BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE){ 251 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_RTS_HIGH_WAKE_ON_CTS_PULSE); 252 } else if (btstack_uart->get_supported_sleep_modes() & BTSTACK_UART_SLEEP_MASK_RTS_LOW_WAKE_ON_RX_EDGE){ 253 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_RTS_LOW_WAKE_ON_RX_EDGE); 254 } 255 } 256 if (hci_transport_h4_ehcill_outgoing_packet_ready()){ 257 // already packet ready? then start wakeup 258 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 259 hci_transport_h4_ehcill_reactivate_rx(); 260 hci_transport_h4_echill_send_wakeup_ind(); 261 } 262 // TODO: trigger run loop 263 // btstack_run_loop_embedded_trigger(); 264 break; 265 } 266 #endif 267 268 default: 269 break; 270 } 271 } 272 273 static int hci_transport_h4_can_send_now(uint8_t packet_type){ 274 return tx_state == TX_IDLE; 275 } 276 277 static int hci_transport_h4_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 278 // store packet type before actual data and increase size 279 size++; 280 packet--; 281 *packet = packet_type; 282 283 tx_state = TX_W4_PACKET_SENT; 284 285 btstack_uart->send_block(packet, size); 286 return 0; 287 } 288 289 static void hci_transport_h4_init(const void * transport_config){ 290 // check for hci_transport_config_uart_t 291 if (!transport_config) { 292 log_error("hci_transport_h4: no config!"); 293 return; 294 } 295 if (((hci_transport_config_t*)transport_config)->type != HCI_TRANSPORT_CONFIG_UART) { 296 log_error("hci_transport_h4: config not of type != HCI_TRANSPORT_CONFIG_UART!"); 297 return; 298 } 299 300 // extract UART config from transport config 301 hci_transport_config_uart_t * hci_transport_config_uart = (hci_transport_config_uart_t*) transport_config; 302 uart_config.baudrate = hci_transport_config_uart->baudrate_init; 303 uart_config.flowcontrol = hci_transport_config_uart->flowcontrol; 304 uart_config.device_name = hci_transport_config_uart->device_name; 305 306 // setup UART driver 307 btstack_uart->init(&uart_config); 308 btstack_uart->set_block_received(&hci_transport_h4_block_read); 309 btstack_uart->set_block_sent(&hci_transport_h4_block_sent); 310 } 311 312 static int hci_transport_h4_open(void){ 313 int res = btstack_uart->open(); 314 if (res){ 315 return res; 316 } 317 hci_transport_h4_reset_statemachine(); 318 hci_transport_h4_trigger_next_read(); 319 320 tx_state = TX_IDLE; 321 322 #ifdef HAVE_EHCILL 323 hci_transport_h4_ehcill_reset_statemachine(); 324 #endif 325 return 0; 326 } 327 328 static int hci_transport_h4_close(void){ 329 return btstack_uart->close(); 330 } 331 332 static void hci_transport_h4_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 333 packet_handler = handler; 334 } 335 336 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 337 } 338 339 // --- main part of eHCILL implementation --- 340 341 #ifdef HAVE_EHCILL 342 343 static void hci_transport_h4_ehcill_reactivate_rx(void){ 344 if (!ehcill_defer_rx_size){ 345 log_error("EHCILL: NO RX REQUEST PENDING"); 346 return; 347 } 348 log_info ("EHCILL: Re-activate rx"); 349 // receive request, clears RTS 350 int rx_size = ehcill_defer_rx_size; 351 ehcill_defer_rx_size = 0; 352 btstack_uart->receive_block(ehcill_defer_rx_buffer, rx_size); 353 } 354 355 static void hci_transport_h4_echill_send_wakeup_ind(void){ 356 // update state 357 tx_state = TX_W4_WAKEUP; 358 ehcill_state = EHCILL_STATE_W4_ACK; 359 ehcill_command_to_send = EHCILL_WAKE_UP_IND; 360 btstack_uart->send_block(&ehcill_command_to_send, 1); 361 } 362 363 static int hci_transport_h4_ehcill_outgoing_packet_ready(void){ 364 return tx_len != 0; 365 } 366 367 // static int ehcill_sleep_mode_active(void){ 368 // return ehcill_state == EHCILL_STATE_SLEEP; 369 // } 370 371 static void hci_transport_h4_ehcill_reset_statemachine(void){ 372 ehcill_state = EHCILL_STATE_AWAKE; 373 } 374 375 static void hci_transport_h4_ehcill_send_ehcill_command(void){ 376 tx_state = TX_W4_EHCILL_SENT; 377 btstack_uart->send_block(&ehcill_command_to_send, 1); 378 } 379 380 static void hci_transport_h4_ehcill_sleep_ack_timer_handler(btstack_timer_source_t * timer){ 381 hci_transport_h4_ehcill_send_ehcill_command(); 382 } 383 384 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void){ 385 // setup timer 386 ehcill_sleep_ack_timer.process = &hci_transport_h4_ehcill_sleep_ack_timer_handler; 387 btstack_run_loop_set_timer(&ehcill_sleep_ack_timer, 50); 388 btstack_run_loop_add_timer(&ehcill_sleep_ack_timer); 389 // TODO: trigger run loop 390 // btstack_run_loop_embedded_trigger(); 391 } 392 393 static void hci_transport_h4_ehcill_schedule_ecill_command(uint8_t command){ 394 ehcill_command_to_send = command; 395 switch (tx_state){ 396 case TX_IDLE: 397 if (ehcill_command_to_send == EHCILL_WAKE_UP_ACK){ 398 // send right away 399 hci_transport_h4_ehcill_send_ehcill_command(); 400 } else { 401 // change state so BTstack cannot send and setup timer 402 tx_state = TX_W2_EHCILL_SEND; 403 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 404 } 405 break; 406 default: 407 break; 408 } 409 } 410 411 static void hci_transport_h4_ehcill_handle(uint8_t action){ 412 // log_info("hci_transport_h4_ehcill_handle: %x, state %u, defer_rx %u", action, ehcill_state, ehcill_defer_rx_size); 413 switch(ehcill_state){ 414 case EHCILL_STATE_AWAKE: 415 switch(action){ 416 case EHCILL_GO_TO_SLEEP_IND: 417 // 1. set RTS high - already done by BT RX ISR 418 // 2. enable CTS IRQ - CTS always enabled 419 ehcill_state = EHCILL_STATE_SLEEP; 420 log_info("EHCILL: GO_TO_SLEEP_IND RX"); 421 hci_transport_h4_ehcill_schedule_ecill_command(EHCILL_GO_TO_SLEEP_ACK); 422 break; 423 default: 424 break; 425 } 426 break; 427 428 case EHCILL_STATE_SLEEP: 429 switch(action){ 430 case EHCILL_WAKE_UP_IND: 431 ehcill_state = EHCILL_STATE_AWAKE; 432 log_info("EHCILL: WAKE_UP_IND RX"); 433 hci_transport_h4_ehcill_schedule_ecill_command(EHCILL_WAKE_UP_ACK); 434 break; 435 436 default: 437 break; 438 } 439 break; 440 441 case EHCILL_STATE_W4_ACK: 442 switch(action){ 443 case EHCILL_WAKE_UP_IND: 444 case EHCILL_WAKE_UP_ACK: 445 log_info("EHCILL: WAKE_UP_IND or ACK"); 446 tx_state = TX_W4_PACKET_SENT; 447 ehcill_state = EHCILL_STATE_AWAKE; 448 btstack_uart->send_block(tx_data, tx_len); 449 break; 450 default: 451 break; 452 } 453 break; 454 } 455 } 456 #endif 457 // --- end of eHCILL implementation --------- 458 459 static const hci_transport_t hci_transport_h4 = { 460 /* const char * name; */ "H4", 461 /* void (*init) (const void *transport_config); */ &hci_transport_h4_init, 462 /* int (*open)(void); */ &hci_transport_h4_open, 463 /* int (*close)(void); */ &hci_transport_h4_close, 464 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_h4_register_packet_handler, 465 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_h4_can_send_now, 466 /* int (*send_packet)(...); */ &hci_transport_h4_send_packet, 467 /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_h4_set_baudrate, 468 /* void (*reset_link)(void); */ NULL, 469 }; 470 471 // configure and return h4 singleton 472 const hci_transport_t * hci_transport_h4_instance(const btstack_uart_block_t * uart_driver) { 473 btstack_uart = uart_driver; 474 return &hci_transport_h4; 475 } 476