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