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