static int h4_open(void *transport_config){ // open uart hal_uart_dma_init(); hal_uart_dma_set_block_received(h4_block_received); hal_uart_dma_set_block_sent(h4_block_sent); // set up data_source run_loop_add_data_source(&hci_transport_h4_dma_ds); // h4_init_sm(); tx_state = TX_IDLE; return 0; }
static int h4_process(struct data_source *ds) { // notify about packet sent if (tx_state == TX_DONE){ // reset state tx_state = TX_IDLE; uint8_t event[] = { DAEMON_EVENT_HCI_PACKET_SENT, 0 }; packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); } if (h4_state != H4_PACKET_RECEIVED) return 0; packet_handler(hci_packet[0], &hci_packet[1], read_pos-1); h4_init_sm(); return 0; }
static void h4_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) { // notify about packet sent if (tx_state == TX_DONE){ // reset state tx_state = TX_IDLE; uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0 }; packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); } if (h4_state != H4_PACKET_RECEIVED) return; packet_handler(hci_packet[0], &hci_packet[1], read_pos-1); h4_init_sm(); return; }
static int h4_open(void){ // open uart hal_uart_dma_init(); hal_uart_dma_set_block_received(h4_block_received); hal_uart_dma_set_block_sent(h4_block_sent); // set up data_source btstack_run_loop_set_data_source_handler(&hci_transport_h4_dma_ds, &h4_process); btstack_run_loop_enable_data_source_callbacks(&hci_transport_h4_dma_ds, DATA_SOURCE_CALLBACK_POLL); btstack_run_loop_add_data_source(&hci_transport_h4_dma_ds); // h4_init_sm(); tx_state = TX_IDLE; return 0; }
static void h4_block_received(void){ read_pos += bytes_to_read; // act switch (h4_state) { case H4_W4_PACKET_TYPE: switch (hci_packet[0]) { case HCI_EVENT_PACKET: h4_state = H4_W4_EVENT_HEADER; bytes_to_read = HCI_EVENT_HEADER_SIZE; break; case HCI_ACL_DATA_PACKET: h4_state = H4_W4_ACL_HEADER; bytes_to_read = HCI_ACL_HEADER_SIZE; break; case HCI_SCO_DATA_PACKET: h4_state = H4_W4_SCO_HEADER; bytes_to_read = HCI_SCO_HEADER_SIZE; break; default: log_error("h4_process: invalid packet type 0x%02x", hci_packet[0]); h4_init_sm(); return; } break; case H4_W4_EVENT_HEADER: bytes_to_read = hci_packet[2]; if (bytes_to_read == 0) { h4_state = H4_PACKET_RECEIVED; break; } h4_state = H4_W4_PAYLOAD; break; case H4_W4_ACL_HEADER: bytes_to_read = little_endian_read_16( hci_packet, 3); // check ACL length if (HCI_ACL_HEADER_SIZE + bytes_to_read > HCI_PACKET_BUFFER_SIZE){ log_error("h4_process: invalid ACL payload len %u - only space for %u", bytes_to_read, HCI_PACKET_BUFFER_SIZE - HCI_ACL_HEADER_SIZE); h4_init_sm(); return; } if (bytes_to_read == 0) { h4_state = H4_PACKET_RECEIVED; break; } h4_state = H4_W4_PAYLOAD; break; case H4_W4_SCO_HEADER: bytes_to_read = hci_packet[3]; if (bytes_to_read == 0) { h4_state = H4_PACKET_RECEIVED; break; } h4_state = H4_W4_PAYLOAD; break; case H4_W4_PAYLOAD: h4_state = H4_PACKET_RECEIVED; bytes_to_read = 0; // trigger run loop btstack_run_loop_embedded_trigger(); break; default: bytes_to_read = 0; break; } // read next block if (bytes_to_read) { hal_uart_dma_receive_block(&hci_packet[read_pos], bytes_to_read); } }