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