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