Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb43534e authored by YK Jeffrey Chao's avatar YK Jeffrey Chao Committed by Android Git Automerger
Browse files

am 916080cf: Preload timeout and retry mechanism (1/3)

* commit '916080cf':
  Preload timeout and retry mechanism (1/3)
parents c8a31eb4 916080cf
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ extern void bte_load_did_conf(const char *p_path);

/** TODO: Move these to _common.h */
void bte_main_boot_entry(void);
void bte_main_enable(uint8_t *local_addr);
void bte_main_enable();
void bte_main_disable(void);
void bte_main_shutdown(void);
#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
@@ -296,6 +296,23 @@ static void btif_task(UINT32 params)
            BTA_EnableBluetooth(bte_dm_evt);
        }

        /*
         * Failed to initialize controller hardware, reset state and bring
         * down all threads
         */
        if (event == BT_EVT_HARDWARE_INIT_FAIL)
        {
            BTIF_TRACE_DEBUG0("btif_task: hardware init failed");
            bte_main_disable();
            btif_queue_release();
            GKI_task_self_cleanup(BTIF_TASK);
            bte_main_shutdown();
            btif_dut_mode = 0;
            btif_core_state = BTIF_CORE_STATE_DISABLED;
            HAL_CBACK(bt_hal_cbacks,adapter_state_changed_cb,BT_STATE_OFF);
            break;
        }

        if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
            break;

@@ -516,7 +533,7 @@ bt_status_t btif_enable_bluetooth(void)
    btif_core_state = BTIF_CORE_STATE_ENABLING;

    /* Create the GKI tasks and run them */
    bte_main_enable(btif_local_bd_addr.address);
    bte_main_enable();

    return BT_STATUS_SUCCESS;
}
@@ -731,6 +748,16 @@ bt_status_t btif_shutdown_bluetooth(void)

    btif_shutdown_pending = 0;

    if (btif_core_state == BTIF_CORE_STATE_ENABLING)
    {
        // Java layer abort BT ENABLING, could be due to ENABLE TIMEOUT
        // Direct call from cleanup()@bluetooth.c
        // bring down HCI/Vendor lib
        bte_main_disable();
        btif_core_state = BTIF_CORE_STATE_DISABLED;
        HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
    }

    GKI_destroy_task(BTIF_TASK);
    btif_queue_release();
    bte_main_shutdown();
+12 −2
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ void btsnoop_close(void);
bt_hc_callbacks_t *bt_hc_cbacks = NULL;
BUFFER_Q tx_q;
tHCI_IF *p_hci_if;
volatile uint8_t fwcfg_acked;

/******************************************************************************
**  Local type definitions
@@ -191,6 +192,7 @@ static int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr)
    }

    hc_cb.epilog_timer_created = 0;
    fwcfg_acked = FALSE;

    /* store reference to user callbacks */
    bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb;
@@ -360,10 +362,17 @@ static void cleanup( void )
    BTHCDBG("cleanup");

    if (lib_running)
    {
        if (fwcfg_acked == TRUE)
        {
            epilog_wait_timer();

            bthc_signal_event(HC_EVENT_EPILOG);
        }
        else
        {
            bthc_signal_event(HC_EVENT_EXIT);
        }

        pthread_join(hc_cb.worker_thread, NULL);

        if (hc_cb.epilog_timer_created == 1)
@@ -384,6 +393,7 @@ static void cleanup( void )
    if (bt_vnd_if)
        bt_vnd_if->cleanup();

    fwcfg_acked = FALSE;
    bt_hc_cbacks = NULL;
}

+3 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
******************************************************************************/

extern tHCI_IF *p_hci_if;
extern uint8_t fwcfg_acked;
void lpm_vnd_cback(uint8_t vnd_result);

/******************************************************************************
@@ -67,6 +68,8 @@ static void fwcfg_cb(bt_vendor_op_result_t result)
    bt_hc_postload_result_t status = (result == BT_VND_OP_RESULT_SUCCESS) ? \
                                     BT_HC_PRELOAD_SUCCESS : BT_HC_PRELOAD_FAIL;

    fwcfg_acked = TRUE;

    if (bt_hc_cbacks)
        bt_hc_cbacks->preload_cb(NULL, status);
}
+174 −18
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@
#include <fcntl.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <time.h>
#include <hardware/bluetooth.h>

#include "gki.h"
#include "bd.h"
@@ -48,9 +51,26 @@
#define HCI_LOGGING_FILENAME  "/data/misc/bluedroid/btsnoop_hci.log"
#endif

/* Stack preload process timeout period  */
#ifndef PRELOAD_START_TIMEOUT_MS
#define PRELOAD_START_TIMEOUT_MS 3000  // 3 seconds
#endif

/* Stack preload process maximum retry attempts  */
#ifndef PRELOAD_MAX_RETRY_ATTEMPTS
#define PRELOAD_MAX_RETRY_ATTEMPTS 0
#endif

/*******************************************************************************
**  Local type definitions
*******************************************************************************/
/* Preload retry control block */
typedef struct
{
    int     retry_counts;
    BOOLEAN timer_created;
    timer_t timer_id;
} bt_preload_retry_cb_t;

/******************************************************************************
**  Variables
@@ -65,11 +85,16 @@ char hci_logfile[256] = HCI_LOGGING_FILENAME;
static bt_hc_interface_t *bt_hc_if=NULL;
static const bt_hc_callbacks_t hc_callbacks;
static BOOLEAN lpm_enabled = FALSE;
static bt_preload_retry_cb_t preload_retry_cb;

/*******************************************************************************
**  Static functions
*******************************************************************************/
static void bte_main_in_hw_init(void);
static void bte_hci_enable(void);
static void bte_hci_disable(void);
static void preload_start_wait_timer(void);
static void preload_stop_wait_timer(void);

/*******************************************************************************
**  Externs
@@ -80,6 +105,7 @@ BT_API extern void BTE_LoadStack(void);
BT_API void BTE_UnloadStack(void);
extern void scru_flip_bda (BD_ADDR dst, const BD_ADDR src);
extern void bte_load_conf(const char *p_path);
extern bt_bdaddr_t btif_local_bd_addr;


/*******************************************************************************
@@ -102,13 +128,15 @@ UINT32 bte_btu_stack[(BTE_BTU_STACK_SIZE + 3) / 4];
** Returns          None
**
******************************************************************************/
void bte_main_in_hw_init(void)
static void bte_main_in_hw_init(void)
{
    if ( (bt_hc_if = (bt_hc_interface_t *) bt_hc_get_interface()) \
         == NULL)
    {
        APPL_TRACE_ERROR0("!!! Failed to get BtHostControllerInterface !!!");
    }

    memset(&preload_retry_cb, 0, sizeof(bt_preload_retry_cb_t));
}

/******************************************************************************
@@ -159,7 +187,7 @@ void bte_main_shutdown()
** Returns          None
**
******************************************************************************/
void bte_main_enable(uint8_t *local_addr)
void bte_main_enable()
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

@@ -168,9 +196,53 @@ void bte_main_enable(uint8_t *local_addr)

    lpm_enabled = FALSE;

    bte_hci_enable();

    GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
                    (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
                    sizeof(bte_btu_stack));

    GKI_run(0);
}

/******************************************************************************
**
** Function         bte_main_disable
**
** Description      BTE MAIN API - Destroys all the BTE tasks. Should be called
**                  part of the Bluetooth stack disable sequence
**
** Returns          None
**
******************************************************************************/
void bte_main_disable(void)
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    preload_stop_wait_timer();
    bte_hci_disable();
    GKI_destroy_task(BTU_TASK);
    GKI_freeze();
}

/******************************************************************************
**
** Function         bte_hci_enable
**
** Description      Enable HCI & Vendor modules
**
** Returns          None
**
******************************************************************************/
static void bte_hci_enable(void)
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

    preload_start_wait_timer();

    if (bt_hc_if)
    {
        int result = bt_hc_if->init(&hc_callbacks, local_addr);
        int result = bt_hc_if->init(&hc_callbacks, btif_local_bd_addr.address);
        APPL_TRACE_EVENT1("libbt-hci init returns %d", result);

        assert(result == BT_HC_STATUS_SUCCESS);
@@ -200,25 +272,18 @@ void bte_main_enable(uint8_t *local_addr)

        bt_hc_if->preload(NULL);
    }

    GKI_create_task((TASKPTR)btu_task, BTU_TASK, BTE_BTU_TASK_STR,
                    (UINT16 *) ((UINT8 *)bte_btu_stack + BTE_BTU_STACK_SIZE),
                    sizeof(bte_btu_stack));

    GKI_run(0);
}

/******************************************************************************
**
** Function         bte_main_disable
** Function         bte_hci_disable
**
** Description      BTE MAIN API - Destroys all the BTE tasks. Should be called
**                  part of the Bluetooth stack disable sequence
** Description      Disable HCI & Vendor modules
**
** Returns          None
**
******************************************************************************/
void bte_main_disable(void)
static void bte_hci_disable(void)
{
    APPL_TRACE_DEBUG1("%s", __FUNCTION__);

@@ -226,11 +291,97 @@ void bte_main_disable(void)
    {
        bt_hc_if->cleanup();
        bt_hc_if->set_power(BT_HC_CHIP_PWR_OFF);
        if (hci_logging_enabled == TRUE)
            bt_hc_if->logging(BT_HC_LOGGING_OFF, hci_logfile);
    }
}

    GKI_destroy_task(BTU_TASK);
/*******************************************************************************
**
** Function        preload_wait_timeout
**
** Description     Timeout thread of preload watchdog timer
**
** Returns         None
**
*******************************************************************************/
static void preload_wait_timeout(union sigval arg)
{
    APPL_TRACE_ERROR2("...preload_wait_timeout (retried:%d/max-retry:%d)...",
                        preload_retry_cb.retry_counts,
                        PRELOAD_MAX_RETRY_ATTEMPTS);

    GKI_freeze();
    if (preload_retry_cb.retry_counts++ < PRELOAD_MAX_RETRY_ATTEMPTS)
    {
        bte_hci_disable();
        GKI_delay(100);
        bte_hci_enable();
    }
    else
    {
        /* Notify BTIF_TASK that the init procedure had failed*/
        GKI_send_event(BTIF_TASK, BT_EVT_HARDWARE_INIT_FAIL);
    }
}

/*******************************************************************************
**
** Function        preload_start_wait_timer
**
** Description     Launch startup watchdog timer
**
** Returns         None
**
*******************************************************************************/
static void preload_start_wait_timer(void)
{
    int status;
    struct itimerspec ts;
    struct sigevent se;
    UINT32 timeout_ms = PRELOAD_START_TIMEOUT_MS;

    if (preload_retry_cb.timer_created == FALSE)
    {
        se.sigev_notify = SIGEV_THREAD;
        se.sigev_value.sival_ptr = &preload_retry_cb.timer_id;
        se.sigev_notify_function = preload_wait_timeout;
        se.sigev_notify_attributes = NULL;

        status = timer_create(CLOCK_MONOTONIC, &se, &preload_retry_cb.timer_id);

        if (status == 0)
            preload_retry_cb.timer_created = TRUE;
    }

    if (preload_retry_cb.timer_created == TRUE)
    {
        ts.it_value.tv_sec = timeout_ms/1000;
        ts.it_value.tv_nsec = 1000000*(timeout_ms%1000);
        ts.it_interval.tv_sec = 0;
        ts.it_interval.tv_nsec = 0;

        status = timer_settime(preload_retry_cb.timer_id, 0, &ts, 0);
        if (status == -1)
            APPL_TRACE_ERROR0("Failed to fire preload watchdog timer");
    }
}

/*******************************************************************************
**
** Function        preload_stop_wait_timer
**
** Description     Stop preload watchdog timer
**
** Returns         None
**
*******************************************************************************/
static void preload_stop_wait_timer(void)
{
    if (preload_retry_cb.timer_created == TRUE)
    {
        timer_delete(preload_retry_cb.timer_id);
        preload_retry_cb.timer_created = FALSE;
    }
}

/******************************************************************************
@@ -380,9 +531,14 @@ static void preload_cb(TRANSAC transac, bt_hc_preload_result_t result)
{
    APPL_TRACE_EVENT1("HC preload_cb %d [0:SUCCESS 1:FAIL]", result);


    if (result == BT_HC_PRELOAD_SUCCESS)
    {
        preload_stop_wait_timer();

        /* notify BTU task that libbt-hci is ready */
    /* even if PRELOAD process failed */
    GKI_send_event(BTU_TASK, TASK_MBOX_0_EVT_MASK);
        GKI_send_event(BTU_TASK, BT_EVT_PRELOAD_CMPL);
    }
}

/******************************************************************************
+28 −4
Original line number Diff line number Diff line
@@ -169,11 +169,35 @@ BTU_API UINT32 btu_task (UINT32 param)

#if (defined(HCISU_H4_INCLUDED) && HCISU_H4_INCLUDED == TRUE)
    /* wait an event that HCISU is ready */
    BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_API,
                "btu_task pending for preload complete event");

    for (;;)
    {
        event = GKI_wait (0xFFFF, 0);
        if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
        {
            /* indicates BT ENABLE abort */
            BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,
                        "btu_task start abort!");
            return (0);
        }
        else if (event & BT_EVT_PRELOAD_CMPL)
        {
            break;
        }
        else
        {
            BT_TRACE_1(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,
                "btu_task ignore evt %04x while pending for preload complete",
                event);
        }
    }

    BT_TRACE_0(TRACE_LAYER_BTU, TRACE_TYPE_API,
                "btu_task received preload complete event");
#endif

    /* Initialize the mandatory core stack control blocks
       (BTU, BTM, L2CAP, and SDP)
     */
Loading