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