// Closes the interface.
// This routine is not thread safe.
static void cleanup(void)
{
    if (has_cleaned_up) {
        ALOGW("%s Already cleaned up for this session\n", __func__);
        return;
    }

    BTHCDBG("cleanup");

    if (hc_cb.worker_thread)
    {
        if (fwcfg_acked)
        {
            epilog_wait_timer();
            // Stop reading thread
            userial_close_reader();

            thread_post(hc_cb.worker_thread, event_epilog, NULL);
        }
        thread_free(hc_cb.worker_thread);

        pthread_mutex_lock(&hc_cb.worker_thread_lock);
        hc_cb.worker_thread = NULL;
        pthread_mutex_unlock(&hc_cb.worker_thread_lock);

        if (hc_cb.epilog_timer_created)
        {
            timer_delete(hc_cb.epilog_timer_id);
            hc_cb.epilog_timer_created = false;
        }
    }
    BTHCDBG("%s Finalizing cleanup\n", __func__);

    lpm_cleanup();
    userial_close();
    p_hci_if->cleanup();
    utils_cleanup();

    set_power(BT_VND_PWR_OFF);
    vendor_close();

    pthread_mutex_destroy(&hc_cb.worker_thread_lock);

    fwcfg_acked = false;
    bt_hc_cbacks = NULL;
    has_cleaned_up = true;
}
Exemple #2
0
/** Closes the interface */
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)
        {
            timer_delete(hc_cb.epilog_timer_id);
            hc_cb.epilog_timer_created = 0;
        }
    }

    lib_running = 0;

    lpm_cleanup();
    p_userial_if->close();
    p_hci_if->cleanup();
    utils_cleanup();

    /* Calling vendor-specific part */
    if (bt_vnd_if)
        bt_vnd_if->cleanup();

    fwcfg_acked = FALSE;
    bt_hc_cbacks = NULL;
}