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 #define __BTSTACK_FILE__ "hci_transport_h4.c" 39 40 /* 41 * hci_h4_transport.c 42 * 43 * HCI Transport API implementation for H4 protocol over POSIX with optional support for eHCILL 44 * 45 * Created by Matthias Ringwald on 4/29/09. 46 */ 47 48 #include "btstack_config.h" 49 50 #include "btstack_debug.h" 51 #include "hci.h" 52 #include "hci_transport.h" 53 #include "bluetooth_company_id.h" 54 #include "btstack_uart_block.h" 55 56 #define ENABLE_LOG_EHCILL 57 58 #ifdef ENABLE_EHCILL 59 60 // eHCILL commands 61 enum EHCILL_MESSAGES { 62 EHCILL_GO_TO_SLEEP_IND = 0x030, 63 EHCILL_GO_TO_SLEEP_ACK = 0x031, 64 EHCILL_WAKE_UP_IND = 0x032, 65 EHCILL_WAKE_UP_ACK = 0x033, 66 EHCILL_WAKEUP_SIGNAL = 0x034, 67 }; 68 69 static int hci_transport_h4_ehcill_outgoing_packet_ready(void); 70 static void hci_transport_h4_echill_send_wakeup_ind(void); 71 static void hci_transport_h4_ehcill_handle_command(uint8_t action); 72 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void); 73 static void hci_transport_h4_ehcill_handle_packet_sent(void); 74 static void hci_transport_h4_ehcill_open(void); 75 static void hci_transport_h4_ehcill_reset_statemachine(void); 76 static void hci_transport_h4_ehcill_send_ehcill_command(void); 77 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void); 78 static void hci_transport_h4_ehcill_trigger_wakeup(void); 79 80 typedef enum { 81 EHCILL_STATE_W2_SEND_SLEEP_ACK, 82 EHCILL_STATE_SLEEP, 83 EHCILL_STATE_W4_WAKEUP_IND_OR_ACK, 84 EHCILL_STATE_AWAKE 85 } EHCILL_STATE; 86 87 // eHCILL state machine 88 static EHCILL_STATE ehcill_state; 89 static uint8_t ehcill_command_to_send; 90 91 static btstack_uart_sleep_mode_t btstack_uart_sleep_mode; 92 93 // work around for eHCILL problem 94 static btstack_timer_source_t ehcill_sleep_ack_timer; 95 96 #endif 97 98 99 // assert pre-buffer for packet type is available 100 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) 101 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h 102 #endif 103 104 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); 105 106 typedef enum { 107 H4_W4_PACKET_TYPE, 108 H4_W4_EVENT_HEADER, 109 H4_W4_ACL_HEADER, 110 H4_W4_SCO_HEADER, 111 H4_W4_PAYLOAD, 112 } H4_STATE; 113 114 typedef enum { 115 TX_IDLE = 1, 116 TX_W4_PACKET_SENT, 117 #ifdef ENABLE_EHCILL 118 TX_W4_WAKEUP, 119 TX_W2_EHCILL_SEND, 120 TX_W4_EHCILL_SENT, 121 #endif 122 } TX_STATE; 123 124 // UART Driver + Config 125 static const btstack_uart_block_t * btstack_uart; 126 static btstack_uart_config_t uart_config; 127 128 // write state 129 static TX_STATE tx_state; 130 static uint8_t * tx_data; 131 static uint16_t tx_len; // 0 == no outgoing packet 132 133 static uint8_t packet_sent_event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; 134 135 static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; 136 137 // packet reader state machine 138 static H4_STATE h4_state; 139 static int bytes_to_read; 140 static int read_pos; 141 142 // incoming packet buffer 143 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) 144 static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE]; 145 146 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 147 static const uint8_t local_version_event_prefix[] = { 0x04, 0x0e, 0x0c, 0x01, 0x01, 0x10}; 148 static const uint8_t baud_rate_command_prefix[] = { 0x01, 0x36, 0xff, 0x04}; 149 static enum { 150 CC256X_WORKAROUND_IDLE, 151 CC256X_WORKAROUND_CHIPSET_DETECTED, 152 CC256X_WORKAROUND_BAUDRATE_COMMAND_SENT, 153 CC256X_WORKAROUND_DONE 154 } cc256x_workaround_state; 155 #endif 156 157 static int hci_transport_h4_set_baudrate(uint32_t baudrate){ 158 log_info("hci_transport_h4_set_baudrate %u", baudrate); 159 return btstack_uart->set_baudrate(baudrate); 160 } 161 162 static void hci_transport_h4_reset_statemachine(void){ 163 h4_state = H4_W4_PACKET_TYPE; 164 read_pos = 0; 165 bytes_to_read = 1; 166 } 167 168 static void hci_transport_h4_trigger_next_read(void){ 169 // log_info("hci_transport_h4_trigger_next_read: %u bytes", bytes_to_read); 170 btstack_uart->receive_block(&hci_packet[read_pos], bytes_to_read); 171 } 172 173 static void hci_transport_h4_block_read(void){ 174 175 read_pos += bytes_to_read; 176 177 switch (h4_state) { 178 case H4_W4_PACKET_TYPE: 179 switch (hci_packet[0]){ 180 case HCI_EVENT_PACKET: 181 bytes_to_read = HCI_EVENT_HEADER_SIZE; 182 h4_state = H4_W4_EVENT_HEADER; 183 break; 184 case HCI_ACL_DATA_PACKET: 185 bytes_to_read = HCI_ACL_HEADER_SIZE; 186 h4_state = H4_W4_ACL_HEADER; 187 break; 188 case HCI_SCO_DATA_PACKET: 189 bytes_to_read = HCI_SCO_HEADER_SIZE; 190 h4_state = H4_W4_SCO_HEADER; 191 break; 192 #ifdef ENABLE_EHCILL 193 case EHCILL_GO_TO_SLEEP_IND: 194 case EHCILL_GO_TO_SLEEP_ACK: 195 case EHCILL_WAKE_UP_IND: 196 case EHCILL_WAKE_UP_ACK: 197 hci_transport_h4_ehcill_handle_command(hci_packet[0]); 198 hci_transport_h4_reset_statemachine(); 199 break; 200 #endif 201 default: 202 log_error("hci_transport_h4: invalid packet type 0x%02x", hci_packet[0]); 203 hci_transport_h4_reset_statemachine(); 204 break; 205 } 206 break; 207 208 case H4_W4_EVENT_HEADER: 209 bytes_to_read = hci_packet[2]; 210 h4_state = H4_W4_PAYLOAD; 211 break; 212 213 case H4_W4_ACL_HEADER: 214 bytes_to_read = little_endian_read_16( hci_packet, 3); 215 // check ACL length 216 if (HCI_ACL_HEADER_SIZE + bytes_to_read > HCI_PACKET_BUFFER_SIZE){ 217 log_error("hci_transport_h4: invalid ACL payload len %d - only space for %u", bytes_to_read, HCI_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); 218 hci_transport_h4_reset_statemachine(); 219 break; 220 } 221 h4_state = H4_W4_PAYLOAD; 222 break; 223 224 case H4_W4_SCO_HEADER: 225 bytes_to_read = hci_packet[3]; 226 h4_state = H4_W4_PAYLOAD; 227 break; 228 229 case H4_W4_PAYLOAD: 230 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 231 if (cc256x_workaround_state == CC256X_WORKAROUND_IDLE 232 && memcmp(hci_packet, local_version_event_prefix, sizeof(local_version_event_prefix)) == 0){ 233 if (little_endian_read_16(hci_packet, 11) == BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC){ 234 // detect TI CC256x controller based on manufacturer 235 log_info("Detected CC256x controller"); 236 cc256x_workaround_state = CC256X_WORKAROUND_CHIPSET_DETECTED; 237 } else { 238 // work around not needed 239 log_info("Bluetooth controller not by TI"); 240 cc256x_workaround_state = CC256X_WORKAROUND_DONE; 241 } 242 } 243 #endif 244 packet_handler(hci_packet[0], &hci_packet[1], read_pos-1); 245 hci_transport_h4_reset_statemachine(); 246 break; 247 default: 248 break; 249 } 250 251 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 252 if (cc256x_workaround_state == CC256X_WORKAROUND_BAUDRATE_COMMAND_SENT){ 253 cc256x_workaround_state = CC256X_WORKAROUND_IDLE; 254 // avoid flowcontrol problem by reading expected hci command complete event of 7 bytes in a single block read 255 h4_state = H4_W4_PAYLOAD; 256 bytes_to_read = 7; 257 } 258 #endif 259 260 hci_transport_h4_trigger_next_read(); 261 } 262 263 static void hci_transport_h4_block_sent(void){ 264 switch (tx_state){ 265 case TX_W4_PACKET_SENT: 266 // packet fully sent, reset state 267 tx_len = 0; 268 tx_state = TX_IDLE; 269 270 #ifdef ENABLE_EHCILL 271 // notify eHCILL engine 272 hci_transport_h4_ehcill_handle_packet_sent(); 273 #endif 274 // notify upper stack that it can send again 275 packet_handler(HCI_EVENT_PACKET, &packet_sent_event[0], sizeof(packet_sent_event)); 276 break; 277 278 #ifdef ENABLE_EHCILL 279 case TX_W4_EHCILL_SENT: 280 case TX_W4_WAKEUP: 281 hci_transport_h4_ehcill_handle_ehcill_command_sent(); 282 break; 283 #endif 284 285 default: 286 break; 287 } 288 } 289 290 static int hci_transport_h4_can_send_now(uint8_t packet_type){ 291 return tx_state == TX_IDLE; 292 } 293 294 static int hci_transport_h4_send_packet(uint8_t packet_type, uint8_t * packet, int size){ 295 296 // store packet type before actual data and increase size 297 size++; 298 packet--; 299 *packet = packet_type; 300 301 #ifdef ENABLE_CC256X_BAUDRATE_CHANGE_FLOWCONTROL_BUG_WORKAROUND 302 if ((cc256x_workaround_state == CC256X_WORKAROUND_CHIPSET_DETECTED) 303 && (memcmp(packet, baud_rate_command_prefix, sizeof(baud_rate_command_prefix)) == 0)) { 304 log_info("CC256x baud rate command detected, expect command complete event next"); 305 cc256x_workaround_state = CC256X_WORKAROUND_BAUDRATE_COMMAND_SENT; 306 } 307 #endif 308 309 // store request 310 tx_len = size; 311 tx_data = packet; 312 313 #ifdef ENABLE_EHCILL 314 switch (ehcill_state){ 315 case EHCILL_STATE_SLEEP: 316 hci_transport_h4_ehcill_trigger_wakeup(); 317 return 0; 318 case EHCILL_STATE_W2_SEND_SLEEP_ACK: 319 log_info("eHILL: send next packet, state EHCILL_STATE_W2_SEND_SLEEP_ACK"); 320 return 0; 321 default: 322 break; 323 } 324 #endif 325 326 // start sending 327 tx_state = TX_W4_PACKET_SENT; 328 btstack_uart->send_block(packet, size); 329 return 0; 330 } 331 332 static void hci_transport_h4_init(const void * transport_config){ 333 // check for hci_transport_config_uart_t 334 if (!transport_config) { 335 log_error("hci_transport_h4: no config!"); 336 return; 337 } 338 if (((hci_transport_config_t*)transport_config)->type != HCI_TRANSPORT_CONFIG_UART) { 339 log_error("hci_transport_h4: config not of type != HCI_TRANSPORT_CONFIG_UART!"); 340 return; 341 } 342 343 // extract UART config from transport config 344 hci_transport_config_uart_t * hci_transport_config_uart = (hci_transport_config_uart_t*) transport_config; 345 uart_config.baudrate = hci_transport_config_uart->baudrate_init; 346 uart_config.flowcontrol = hci_transport_config_uart->flowcontrol; 347 uart_config.device_name = hci_transport_config_uart->device_name; 348 349 // setup UART driver 350 btstack_uart->init(&uart_config); 351 btstack_uart->set_block_received(&hci_transport_h4_block_read); 352 btstack_uart->set_block_sent(&hci_transport_h4_block_sent); 353 } 354 355 static int hci_transport_h4_open(void){ 356 int res = btstack_uart->open(); 357 if (res){ 358 return res; 359 } 360 hci_transport_h4_reset_statemachine(); 361 hci_transport_h4_trigger_next_read(); 362 363 tx_state = TX_IDLE; 364 365 #ifdef ENABLE_EHCILL 366 hci_transport_h4_ehcill_open(); 367 #endif 368 return 0; 369 } 370 371 static int hci_transport_h4_close(void){ 372 return btstack_uart->close(); 373 } 374 375 static void hci_transport_h4_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ 376 packet_handler = handler; 377 } 378 379 static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ 380 } 381 382 // 383 // --- main part of eHCILL implementation --- 384 // 385 386 #ifdef ENABLE_EHCILL 387 388 static void hci_transport_h4_ehcill_emit_sleep_state(int sleep_active){ 389 static int last_state = 0; 390 if (sleep_active == last_state) return; 391 last_state = sleep_active; 392 393 log_info("hci_transport_h4_ehcill_emit_sleep_state: %u", sleep_active); 394 uint8_t event[3]; 395 event[0] = HCI_EVENT_TRANSPORT_SLEEP_MODE; 396 event[1] = sizeof(event) - 2; 397 event[2] = sleep_active; 398 packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); 399 } 400 401 static void hci_transport_h4_ehcill_wakeup_handler(void){ 402 #ifdef ENABLE_LOG_EHCILL 403 log_info("eHCILL: UART wakeup received"); 404 #endif 405 hci_transport_h4_ehcill_handle_command(EHCILL_WAKEUP_SIGNAL); 406 } 407 408 static void hci_transport_h4_ehcill_open(void){ 409 hci_transport_h4_ehcill_reset_statemachine(); 410 411 // find best sleep mode to use: wake on CTS, wake on RX, none 412 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_OFF; 413 int supported_sleep_modes = 0; 414 if (btstack_uart->get_supported_sleep_modes){ 415 supported_sleep_modes = btstack_uart->get_supported_sleep_modes(); 416 } 417 if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE){ 418 log_info("eHCILL: using wake on CTS"); 419 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_HIGH_WAKE_ON_CTS_PULSE; 420 } else if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_LOW_WAKE_ON_RX_EDGE){ 421 log_info("eHCILL: using wake on RX"); 422 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_LOW_WAKE_ON_RX_EDGE; 423 } else { 424 log_info("eHCILL: UART driver does not provide compatible sleep mode"); 425 } 426 if (btstack_uart->set_wakeup_handler){ 427 btstack_uart->set_wakeup_handler(&hci_transport_h4_ehcill_wakeup_handler); 428 } 429 } 430 431 static void hci_transport_h4_echill_send_wakeup_ind(void){ 432 #ifdef ENABLE_LOG_EHCILL 433 log_info("eHCILL: send WAKEUP_IND"); 434 #endif 435 // update state 436 tx_state = TX_W4_WAKEUP; 437 ehcill_state = EHCILL_STATE_W4_WAKEUP_IND_OR_ACK; 438 ehcill_command_to_send = EHCILL_WAKE_UP_IND; 439 btstack_uart->send_block(&ehcill_command_to_send, 1); 440 } 441 442 static int hci_transport_h4_ehcill_outgoing_packet_ready(void){ 443 return tx_len != 0; 444 } 445 446 static void hci_transport_h4_ehcill_reset_statemachine(void){ 447 ehcill_state = EHCILL_STATE_AWAKE; 448 } 449 450 static void hci_transport_h4_ehcill_send_ehcill_command(void){ 451 #ifdef ENABLE_LOG_EHCILL 452 log_info("eHCILL: send command %02x", ehcill_command_to_send); 453 #endif 454 tx_state = TX_W4_EHCILL_SENT; 455 if (ehcill_command_to_send == EHCILL_GO_TO_SLEEP_ACK){ 456 ehcill_state = EHCILL_STATE_SLEEP; 457 } 458 btstack_uart->send_block(&ehcill_command_to_send, 1); 459 } 460 461 static void hci_transport_h4_ehcill_sleep_ack_timer_handler(btstack_timer_source_t * timer){ 462 UNUSED(timer); 463 #ifdef ENABLE_LOG_EHCILL 464 log_info("eHCILL: timer triggered"); 465 #endif 466 hci_transport_h4_ehcill_send_ehcill_command(); 467 } 468 469 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void){ 470 // setup timer 471 #ifdef ENABLE_LOG_EHCILL 472 log_info("eHCILL: set timer for sending command %02x", ehcill_command_to_send); 473 #endif 474 btstack_run_loop_set_timer_handler(&ehcill_sleep_ack_timer, &hci_transport_h4_ehcill_sleep_ack_timer_handler); 475 btstack_run_loop_set_timer(&ehcill_sleep_ack_timer, 50); 476 btstack_run_loop_add_timer(&ehcill_sleep_ack_timer); 477 } 478 479 static void hci_transport_h4_ehcill_trigger_wakeup(void){ 480 switch (tx_state){ 481 case TX_W2_EHCILL_SEND: 482 case TX_W4_EHCILL_SENT: 483 // wake up / sleep ack in progress, nothing to do now 484 return; 485 case TX_IDLE: 486 default: 487 // all clear, prepare for wakeup 488 break; 489 } 490 // UART needed again 491 hci_transport_h4_ehcill_emit_sleep_state(0); 492 if (btstack_uart_sleep_mode){ 493 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 494 } 495 hci_transport_h4_echill_send_wakeup_ind(); 496 } 497 498 static void hci_transport_h4_ehcill_schedule_ehcill_command(uint8_t command){ 499 #ifdef ENABLE_LOG_EHCILL 500 log_info("eHCILL: schedule eHCILL command %02x", command); 501 #endif 502 ehcill_command_to_send = command; 503 switch (tx_state){ 504 case TX_IDLE: 505 if (ehcill_command_to_send == EHCILL_WAKE_UP_ACK){ 506 // send right away 507 hci_transport_h4_ehcill_send_ehcill_command(); 508 } else { 509 // change state so BTstack cannot send and setup timer 510 tx_state = TX_W2_EHCILL_SEND; 511 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 512 } 513 break; 514 default: 515 break; 516 } 517 } 518 519 static void hci_transport_h4_ehcill_handle_command(uint8_t action){ 520 // log_info("hci_transport_h4_ehcill_handle: %x, state %u, defer_rx %u", action, ehcill_state, ehcill_defer_rx_size); 521 switch(ehcill_state){ 522 case EHCILL_STATE_AWAKE: 523 switch(action){ 524 case EHCILL_GO_TO_SLEEP_IND: 525 ehcill_state = EHCILL_STATE_W2_SEND_SLEEP_ACK; 526 #ifdef ENABLE_LOG_EHCILL 527 log_info("eHCILL: Received GO_TO_SLEEP_IND RX"); 528 #endif 529 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_GO_TO_SLEEP_ACK); 530 break; 531 default: 532 break; 533 } 534 break; 535 536 case EHCILL_STATE_W2_SEND_SLEEP_ACK: 537 switch(action){ 538 case EHCILL_WAKE_UP_IND: 539 ehcill_state = EHCILL_STATE_AWAKE; 540 hci_transport_h4_ehcill_emit_sleep_state(0); 541 if (btstack_uart_sleep_mode){ 542 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 543 } 544 #ifdef ENABLE_LOG_EHCILL 545 log_info("eHCILL: Received WAKE_UP_IND RX"); 546 #endif 547 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_WAKE_UP_ACK); 548 break; 549 550 default: 551 break; 552 } 553 break; 554 555 case EHCILL_STATE_SLEEP: 556 switch(action){ 557 case EHCILL_WAKEUP_SIGNAL: 558 hci_transport_h4_ehcill_emit_sleep_state(0); 559 if (btstack_uart_sleep_mode){ 560 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 561 } 562 break; 563 case EHCILL_WAKE_UP_IND: 564 ehcill_state = EHCILL_STATE_AWAKE; 565 hci_transport_h4_ehcill_emit_sleep_state(0); 566 if (btstack_uart_sleep_mode){ 567 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 568 } 569 #ifdef ENABLE_LOG_EHCILL 570 log_info("eHCILL: Received WAKE_UP_IND RX"); 571 #endif 572 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_WAKE_UP_ACK); 573 break; 574 575 default: 576 break; 577 } 578 break; 579 580 case EHCILL_STATE_W4_WAKEUP_IND_OR_ACK: 581 switch(action){ 582 case EHCILL_WAKE_UP_IND: 583 case EHCILL_WAKE_UP_ACK: 584 #ifdef ENABLE_LOG_EHCILL 585 log_info("eHCILL: Received WAKE_UP (%02x)", action); 586 #endif 587 tx_state = TX_W4_PACKET_SENT; 588 ehcill_state = EHCILL_STATE_AWAKE; 589 btstack_uart->send_block(tx_data, tx_len); 590 break; 591 default: 592 break; 593 } 594 break; 595 } 596 } 597 598 static void hci_transport_h4_ehcill_handle_packet_sent(void){ 599 #ifdef ENABLE_LOG_EHCILL 600 log_info("eHCILL: handle packet sent, command to send %02x", ehcill_command_to_send); 601 #endif 602 // now, send pending ehcill command if neccessary 603 switch (ehcill_command_to_send){ 604 case EHCILL_GO_TO_SLEEP_ACK: 605 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 606 break; 607 case EHCILL_WAKE_UP_IND: 608 hci_transport_h4_ehcill_send_ehcill_command(); 609 break; 610 default: 611 break; 612 } 613 } 614 615 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void){ 616 tx_state = TX_IDLE; 617 int command = ehcill_command_to_send; 618 ehcill_command_to_send = 0; 619 620 #ifdef ENABLE_LOG_EHCILL 621 log_info("eHCILL: handle eHCILL sent, command was %02x", command); 622 #endif 623 624 if (command == EHCILL_GO_TO_SLEEP_ACK) { 625 #ifdef ENABLE_LOG_EHCILL 626 log_info("eHCILL: GO_TO_SLEEP_ACK sent, enter sleep mode"); 627 #endif 628 // UART not needed after EHCILL_GO_TO_SLEEP_ACK was sent 629 if (btstack_uart_sleep_mode != BTSTACK_UART_SLEEP_OFF){ 630 btstack_uart->set_sleep(btstack_uart_sleep_mode); 631 } 632 hci_transport_h4_ehcill_emit_sleep_state(1); 633 } 634 // already packet ready? then start wakeup 635 if (hci_transport_h4_ehcill_outgoing_packet_ready()){ 636 hci_transport_h4_ehcill_emit_sleep_state(0); 637 if (btstack_uart_sleep_mode != BTSTACK_UART_SLEEP_OFF){ 638 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 639 } 640 if (command != EHCILL_WAKE_UP_IND){ 641 hci_transport_h4_echill_send_wakeup_ind(); 642 } 643 } 644 } 645 646 #endif 647 // --- end of eHCILL implementation --------- 648 649 static const hci_transport_t hci_transport_h4 = { 650 /* const char * name; */ "H4", 651 /* void (*init) (const void *transport_config); */ &hci_transport_h4_init, 652 /* int (*open)(void); */ &hci_transport_h4_open, 653 /* int (*close)(void); */ &hci_transport_h4_close, 654 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_h4_register_packet_handler, 655 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_h4_can_send_now, 656 /* int (*send_packet)(...); */ &hci_transport_h4_send_packet, 657 /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_h4_set_baudrate, 658 /* void (*reset_link)(void); */ NULL, 659 /* void (*set_sco_config)(uint16_t voice_setting, int num_connections); */ NULL, 660 }; 661 662 // configure and return h4 singleton 663 const hci_transport_t * hci_transport_h4_instance(const btstack_uart_block_t * uart_driver) { 664 btstack_uart = uart_driver; 665 return &hci_transport_h4; 666 } 667