/*******************************************************************************
**
** Function         bta_hf_client_rfc_close
**
** Description      RFCOMM connection closed.
**
**
** Returns          void
**
*******************************************************************************/
void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
{
    UNUSED(p_data);

    /* reinitialize stuff */
    bta_hf_client_cb.scb.peer_features = 0;
    bta_hf_client_cb.scb.chld_features = 0;
    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
    bta_hf_client_cb.scb.svc_conn = FALSE;
    bta_hf_client_cb.scb.send_at_reply = FALSE;
    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;

    bta_hf_client_at_reset();

    bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);

    /* call close cback */
    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);

    /* if not deregistering reopen server */
    if (bta_hf_client_cb.scb.deregister == FALSE)
    {
        /* Clear peer bd_addr so instance can be reused */
        bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);

        /* start server as it might got closed on open*/
        bta_hf_client_start_server();

        bta_hf_client_cb.scb.conn_handle = 0;

        /* Make sure SCO is shutdown */
        bta_hf_client_sco_shutdown(NULL);

        bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
    }
    /* else close port and deallocate scb */
    else
    {
        bta_hf_client_close_server();
        bta_hf_client_scb_disable();
    }
}
/*******************************************************************************
**
** Function         bta_pan_conn_close
**
** Description      process connection close event
**
**
**
** Returns          void
**
*******************************************************************************/
void bta_pan_conn_close(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
{

    tBTA_PAN_CLOSE data;
    BT_HDR *p_buf;

    data.handle = p_data->hdr.layer_specific;


    bta_sys_conn_close( BTA_ID_PAN ,p_scb->app_id, p_scb->bd_addr);

    /* free all queued up data buffers */
    while((p_buf = (BT_HDR *)GKI_dequeue(&p_scb->data_queue)) != NULL)
        GKI_freebuf(p_buf);

    GKI_init_q(&p_scb->data_queue);

    bta_pan_co_close(p_scb->handle, p_scb->app_id);

    bta_pan_scb_dealloc(p_scb);

    bta_pan_cb.p_cback(BTA_PAN_CLOSE_EVT, (tBTA_PAN *)&data);

}
/*******************************************************************************
**
** 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);
    }
}