From e09cd29c74b357423710c3be1967aa6612bca0c7 Mon Sep 17 00:00:00 2001 From: Christopher Collins Date: Thu, 6 Jul 2017 16:24:18 -0700 Subject: [PATCH] Give HCI socket transport its own task. This prevents deadlock while the host waits for a command-complete event from the controller. X-Original-Commit: 06551943b9aca46e39e4df20dd34575737ddb9e5 --- nimble/transport/socket/src/ble_hci_socket.c | 37 ++++++++++++++++---- nimble/transport/socket/syscfg.yml | 7 ++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c index be12a912d..951d43321 100755 --- a/nimble/transport/socket/src/ble_hci_socket.c +++ b/nimble/transport/socket/src/ble_hci_socket.c @@ -43,6 +43,7 @@ #include #include #include +#include "os/os.h" #if MYNEWT_VAL(BLE_SOCK_USE_TCP) #include @@ -139,6 +140,11 @@ STATS_NAME_END(hci_sock_stats) #define BLE_HCI_UART_H4_SKIP_CMD 0x81 #define BLE_HCI_UART_H4_SKIP_ACL 0x82 +#define BLE_SOCK_STACK_SIZE \ + OS_STACK_ALIGN(MYNEWT_VAL(BLE_SOCK_STACK_SIZE)) + +struct os_task ble_sock_task; + static struct os_mempool ble_hci_sock_evt_hi_pool; static void *ble_hci_sock_evt_hi_buf; static struct os_mempool ble_hci_sock_evt_lo_pool; @@ -158,7 +164,7 @@ static void *ble_hci_sock_rx_acl_arg; static struct ble_hci_sock_state { int sock; - struct os_eventq *evq; + struct os_eventq evq; struct os_event ev; struct os_callout timer; @@ -399,7 +405,7 @@ ble_hci_sock_rx_ev(struct os_event *ev) rc = ble_hci_sock_rx_msg(); if (rc == 0) { - os_eventq_put(ble_hci_sock_state.evq, &ble_hci_sock_state.ev); + os_eventq_put(&ble_hci_sock_state.evq, &ble_hci_sock_state.ev); } else { os_callout_reset(&ble_hci_sock_state.timer, OS_TICKS_PER_SEC / 100); } @@ -712,12 +718,29 @@ ble_hci_trans_reset(void) return 0; } -void -ble_hci_sock_set_evq(struct os_eventq *evq) +static void +ble_hci_sock_ack_handler(void *arg) { - ble_hci_sock_state.evq = evq; + while (1) { + os_eventq_run(&ble_hci_sock_state.evq); + } +} + +static void +ble_hci_sock_init_task(void) +{ + os_stack_t *pstack; + + pstack = malloc(sizeof(os_stack_t)*BLE_SOCK_STACK_SIZE); + assert(pstack); + + os_task_init(&ble_sock_task, "sock", ble_hci_sock_ack_handler, NULL, + MYNEWT_VAL(BLE_SOCK_TASK_PRIO), OS_WAIT_FOREVER, pstack, + BLE_SOCK_STACK_SIZE); + + os_eventq_init(&ble_hci_sock_state.evq); os_callout_stop(&ble_hci_sock_state.timer); - os_callout_init(&ble_hci_sock_state.timer, ble_hci_sock_state.evq, + os_callout_init(&ble_hci_sock_state.timer, &ble_hci_sock_state.evq, ble_hci_sock_rx_ev, NULL); } @@ -740,7 +763,7 @@ ble_hci_sock_init(void) memset(&ble_hci_sock_state, 0, sizeof(ble_hci_sock_state)); ble_hci_sock_state.sock = -1; - ble_hci_sock_set_evq(os_eventq_dflt_get()); + ble_hci_sock_init_task(); ble_hci_sock_state.ev.ev_cb = ble_hci_sock_rx_ev; /* diff --git a/nimble/transport/socket/syscfg.yml b/nimble/transport/socket/syscfg.yml index 477d49351..530850064 100644 --- a/nimble/transport/socket/syscfg.yml +++ b/nimble/transport/socket/syscfg.yml @@ -64,3 +64,10 @@ syscfg.defs: description: 'linux kernel device' value: 0 + BLE_SOCK_TASK_PRIO: + description: 'Priority of the HCI socket task.' + value: 9 + + BLE_SOCK_STACK_SIZE: + description: 'Size of the HCI socket stack (units=words).' + value: 80