예제 #1
0
/*******************************************************************************
**
** Function         bta_ag_close_servers
**
** Description      Close RFCOMM servers port for use by AG.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_close_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services)
{
    int i;

    services >>= BTA_HSP_SERVICE_ID;
    for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++, services >>= 1)
    {
        /* if service is set in mask */
        if (services & 1)
        {
            RFCOMM_RemoveServer(p_scb->serv_handle[i]);
            p_scb->serv_handle[i] = 0;
        }
    }
}
/*******************************************************************************
**
** Function         bta_ag_rfc_close
**
** Description      RFCOMM connection closed.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_rfc_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
{
    tBTA_AG_CLOSE    close;
    tBTA_SERVICE_MASK services;
    int i, num_active_conn = 0;
    UNUSED(p_data);

#ifdef  _WIN32_WCE
    /* The BTE RFCOMM automatically removes the connection when closed, but BTW does not */
    if (p_scb->conn_handle != 0)
        RFCOMM_RemoveConnection (p_scb->conn_handle);
#endif

    /* reinitialize stuff */
    p_scb->conn_service = 0;
    p_scb->peer_features = 0;
#if (BTM_WBS_INCLUDED == TRUE )
    p_scb->peer_codecs = BTA_AG_CODEC_NONE;
    p_scb->sco_codec = BTA_AG_CODEC_NONE;
    /* Clear these flags upon SLC teardown */
    p_scb->codec_updated = FALSE;
    p_scb->codec_fallback = FALSE;
    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
#endif
    p_scb->role = 0;
    p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    p_scb->svc_conn = FALSE;
    p_scb->hsp_version = HSP_VERSION_1_2;
    bta_ag_at_reinit(&p_scb->at_cb);

    /* stop timers */
    bta_sys_stop_timer(&p_scb->act_timer);
#if (BTM_WBS_INCLUDED == TRUE)
    bta_sys_stop_timer(&p_scb->cn_timer);
#endif

    close.hdr.handle = bta_ag_scb_to_idx(p_scb);
    close.hdr.app_id = p_scb->app_id;
    bdcpy(close.bd_addr, p_scb->peer_addr);

    bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);

    /* call close call-out */
    bta_ag_co_data_close(close.hdr.handle);

    /* call close cback */
    (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG *) &close);

    /* if not deregistering (deallocating) reopen registered servers */
    if (p_scb->dealloc == FALSE)
    {
        /* Clear peer bd_addr so instance can be reused */
        bdcpy(p_scb->peer_addr, bd_addr_null);

        /* start only unopened server */
        services = p_scb->reg_services;
        for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++)
        {
            if(p_scb->serv_handle[i])
                services &= ~((tBTA_SERVICE_MASK)1 << (BTA_HSP_SERVICE_ID + i));
        }
        bta_ag_start_servers(p_scb, services);

        p_scb->conn_handle = 0;

        /* Make sure SCO state is BTA_AG_SCO_SHUTDOWN_ST */
        bta_ag_sco_shutdown(p_scb, NULL);

        /* Check if all the SLCs are down */
        for (i = 0; i < BTA_AG_NUM_SCB; i++)
        {
            if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn)
                num_active_conn++;
        }

        if(!num_active_conn)
        {
            bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
        }

    }
    /* else close port and deallocate scb */
    else
    {
        RFCOMM_RemoveServer(p_scb->conn_handle);
        bta_ag_scb_dealloc(p_scb);
    }
}