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 %u - 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_open(void){ 337 hci_transport_h4_ehcill_reset_statemachine(); 338 339 // find best sleep mode to use: wake on CTS, wake on RX, none 340 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_OFF; 341 int supported_sleep_modes = 0; 342 if (btstack_uart->get_supported_sleep_modes){ 343 supported_sleep_modes = btstack_uart->get_supported_sleep_modes(); 344 } 345 if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE){ 346 log_info("eHCILL: using wake on CTS"); 347 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_HIGH_WAKE_ON_CTS_PULSE; 348 } else if (supported_sleep_modes & BTSTACK_UART_SLEEP_MASK_RTS_LOW_WAKE_ON_RX_EDGE){ 349 log_info("eHCILL: using wake on RX"); 350 btstack_uart_sleep_mode = BTSTACK_UART_SLEEP_RTS_LOW_WAKE_ON_RX_EDGE; 351 } else { 352 log_info("eHCILL: UART driver does not provide compatible sleep mode"); 353 } 354 } 355 356 static void hci_transport_h4_echill_send_wakeup_ind(void){ 357 #ifdef ENABLE_LOG_EHCILL 358 log_info("eHCILL: send WAKEUP_IND"); 359 #endif 360 // update state 361 tx_state = TX_W4_WAKEUP; 362 ehcill_state = EHCILL_STATE_W4_WAKEUP_IND_OR_ACK; 363 ehcill_command_to_send = EHCILL_WAKE_UP_IND; 364 btstack_uart->send_block(&ehcill_command_to_send, 1); 365 } 366 367 static int hci_transport_h4_ehcill_outgoing_packet_ready(void){ 368 return tx_len != 0; 369 } 370 371 static void hci_transport_h4_ehcill_reset_statemachine(void){ 372 ehcill_state = EHCILL_STATE_AWAKE; 373 } 374 375 static void hci_transport_h4_ehcill_send_ehcill_command(void){ 376 #ifdef ENABLE_LOG_EHCILL 377 log_info("eHCILL: send command %02x", ehcill_command_to_send); 378 #endif 379 tx_state = TX_W4_EHCILL_SENT; 380 if (ehcill_command_to_send == EHCILL_GO_TO_SLEEP_ACK){ 381 ehcill_state = EHCILL_STATE_SLEEP; 382 } 383 btstack_uart->send_block(&ehcill_command_to_send, 1); 384 } 385 386 static void hci_transport_h4_ehcill_sleep_ack_timer_handler(btstack_timer_source_t * timer){ 387 #ifdef ENABLE_LOG_EHCILL 388 log_info("eHCILL: timer triggered"); 389 #endif 390 hci_transport_h4_ehcill_send_ehcill_command(); 391 } 392 393 static void hci_transport_h4_ehcill_sleep_ack_timer_setup(void){ 394 // setup timer 395 #ifdef ENABLE_LOG_EHCILL 396 log_info("eHCILL: set timer for sending command %02x", ehcill_command_to_send); 397 #endif 398 btstack_run_loop_set_timer_handler(&ehcill_sleep_ack_timer, &hci_transport_h4_ehcill_sleep_ack_timer_handler); 399 btstack_run_loop_set_timer(&ehcill_sleep_ack_timer, 50); 400 btstack_run_loop_add_timer(&ehcill_sleep_ack_timer); 401 } 402 403 static void hci_transport_h4_ehcill_trigger_wakeup(void){ 404 switch (tx_state){ 405 case TX_W2_EHCILL_SEND: 406 case TX_W4_EHCILL_SENT: 407 // wake up / sleep ack in progress, nothing to do now 408 return; 409 case TX_IDLE: 410 default: 411 // all clear, prepare for wakeup 412 break; 413 } 414 // UART needed again 415 if (btstack_uart_sleep_mode){ 416 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 417 } 418 hci_transport_h4_echill_send_wakeup_ind(); 419 } 420 421 static void hci_transport_h4_ehcill_schedule_ehcill_command(uint8_t command){ 422 #ifdef ENABLE_LOG_EHCILL 423 log_info("eHCILL: schedule eHCILL command %02x", command); 424 #endif 425 ehcill_command_to_send = command; 426 switch (tx_state){ 427 case TX_IDLE: 428 if (ehcill_command_to_send == EHCILL_WAKE_UP_ACK){ 429 // send right away 430 hci_transport_h4_ehcill_send_ehcill_command(); 431 } else { 432 // change state so BTstack cannot send and setup timer 433 tx_state = TX_W2_EHCILL_SEND; 434 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 435 } 436 break; 437 default: 438 break; 439 } 440 } 441 442 static void hci_transport_h4_ehcill_handle_command(uint8_t action){ 443 // log_info("hci_transport_h4_ehcill_handle: %x, state %u, defer_rx %u", action, ehcill_state, ehcill_defer_rx_size); 444 switch(ehcill_state){ 445 case EHCILL_STATE_AWAKE: 446 switch(action){ 447 case EHCILL_GO_TO_SLEEP_IND: 448 ehcill_state = EHCILL_STATE_W2_SEND_SLEEP_ACK; 449 #ifdef ENABLE_LOG_EHCILL 450 log_info("eHCILL: Received GO_TO_SLEEP_IND RX"); 451 #endif 452 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_GO_TO_SLEEP_ACK); 453 break; 454 default: 455 break; 456 } 457 break; 458 459 case EHCILL_STATE_SLEEP: 460 case EHCILL_STATE_W2_SEND_SLEEP_ACK: 461 switch(action){ 462 case EHCILL_WAKE_UP_IND: 463 ehcill_state = EHCILL_STATE_AWAKE; 464 #ifdef ENABLE_LOG_EHCILL 465 log_info("eHCILL: Received WAKE_UP_IND RX"); 466 #endif 467 hci_transport_h4_ehcill_schedule_ehcill_command(EHCILL_WAKE_UP_ACK); 468 break; 469 470 default: 471 break; 472 } 473 break; 474 475 case EHCILL_STATE_W4_WAKEUP_IND_OR_ACK: 476 switch(action){ 477 case EHCILL_WAKE_UP_IND: 478 case EHCILL_WAKE_UP_ACK: 479 #ifdef ENABLE_LOG_EHCILL 480 log_info("eHCILL: Received WAKE_UP (%02x)", action); 481 #endif 482 tx_state = TX_W4_PACKET_SENT; 483 ehcill_state = EHCILL_STATE_AWAKE; 484 btstack_uart->send_block(tx_data, tx_len); 485 break; 486 default: 487 break; 488 } 489 break; 490 } 491 } 492 493 static void hci_transport_h4_ehcill_handle_packet_sent(void){ 494 #ifdef ENABLE_LOG_EHCILL 495 log_info("eHCILL: handle packet sent, command to send %02x", ehcill_command_to_send); 496 #endif 497 // now, send pending ehcill command if neccessary 498 switch (ehcill_command_to_send){ 499 case EHCILL_GO_TO_SLEEP_ACK: 500 hci_transport_h4_ehcill_sleep_ack_timer_setup(); 501 break; 502 case EHCILL_WAKE_UP_IND: 503 hci_transport_h4_ehcill_send_ehcill_command(); 504 break; 505 default: 506 break; 507 } 508 } 509 510 static void hci_transport_h4_ehcill_handle_ehcill_command_sent(void){ 511 tx_state = TX_IDLE; 512 int command = ehcill_command_to_send; 513 ehcill_command_to_send = 0; 514 515 #ifdef ENABLE_LOG_EHCILL 516 log_info("eHCILL: handle eHCILL sent, command was %02x", command); 517 #endif 518 519 if (command == EHCILL_GO_TO_SLEEP_ACK) { 520 #ifdef ENABLE_LOG_EHCILL 521 log_info("eHCILL: GO_TO_SLEEP_ACK sent, enter sleep mode"); 522 #endif 523 // UART not needed after EHCILL_GO_TO_SLEEP_ACK was sent 524 if (btstack_uart_sleep_mode != BTSTACK_UART_SLEEP_OFF){ 525 btstack_uart->set_sleep(btstack_uart_sleep_mode); 526 } 527 } 528 // already packet ready? then start wakeup 529 if (hci_transport_h4_ehcill_outgoing_packet_ready()){ 530 if (btstack_uart_sleep_mode){ 531 btstack_uart->set_sleep(BTSTACK_UART_SLEEP_OFF); 532 } 533 if (command != EHCILL_WAKE_UP_IND){ 534 hci_transport_h4_echill_send_wakeup_ind(); 535 } 536 } 537 } 538 539 #endif 540 // --- end of eHCILL implementation --------- 541 542 static const hci_transport_t hci_transport_h4 = { 543 /* const char * name; */ "H4", 544 /* void (*init) (const void *transport_config); */ &hci_transport_h4_init, 545 /* int (*open)(void); */ &hci_transport_h4_open, 546 /* int (*close)(void); */ &hci_transport_h4_close, 547 /* void (*register_packet_handler)(void (*handler)(...); */ &hci_transport_h4_register_packet_handler, 548 /* int (*can_send_packet_now)(uint8_t packet_type); */ &hci_transport_h4_can_send_now, 549 /* int (*send_packet)(...); */ &hci_transport_h4_send_packet, 550 /* int (*set_baudrate)(uint32_t baudrate); */ &hci_transport_h4_set_baudrate, 551 /* void (*reset_link)(void); */ NULL, 552 }; 553 554 // configure and return h4 singleton 555 const hci_transport_t * hci_transport_h4_instance(const btstack_uart_block_t * uart_driver) { 556 btstack_uart = uart_driver; 557 return &hci_transport_h4; 558 } 559