/*******************************************************************************
**
** Function         l2cble_init_direct_conn
**
** Description      This function is to initate a direct connection
**
** Returns          TRUE connection initiated, FALSE otherwise.
**
*******************************************************************************/
BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
{
    tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
    tBTM_BLE_CB         *p_cb = &btm_cb.ble_ctr_cb;
    UINT16               scan_int, scan_win;
    BD_ADDR         init_addr;
    UINT8           init_addr_type = BLE_ADDR_PUBLIC,
                    own_addr_type = BLE_ADDR_PUBLIC;

    /* There can be only one BLE connection request outstanding at a time */
    if (p_dev_rec == NULL)
    {
        BTM_TRACE_WARNING0 ("unknown device, can not initate connection");
        return(FALSE);
    }

    scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
    scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;

    init_addr_type = p_lcb->ble_addr_type;
    memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);

    if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
                                        scan_win, /* UINT16 scan_win      */
                                        FALSE,                   /* UINT8 white_list     */
                                        p_lcb->ble_addr_type,          /* UINT8 addr_type_peer */
                                        p_lcb->remote_bd_addr,         /* BD_ADDR bda_peer     */
                                        BLE_ADDR_PUBLIC,         /* UINT8 addr_type_own  */
                                        (UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN),  /* UINT16 conn_int_min  */
                                        (UINT16) ((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MIN),  /* UINT16 conn_int_max  */
                                        (UINT16) ((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.slave_latency : 0), /* UINT16 conn_latency  */
                                        (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ? p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_SUP_TOUT_DEF), /* UINT16 conn_timeout  */
                                        0,                       /* UINT16 min_len       */
                                        0))                      /* UINT16 max_len       */
    {
        l2cu_release_lcb (p_lcb);
        L2CAP_TRACE_ERROR0("initate direct connection fail, no resources");
        return (FALSE);
    }
    else
    {
        p_lcb->link_state = LST_CONNECTING;
        memcpy (l2cb.ble_connecting_bda, p_lcb->remote_bd_addr, BD_ADDR_LEN);
        //Assigning below variable which is checked at LE conn cancel
        l2cb.is_ble_connecting=TRUE;
        btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_BLE_LINK_CONNECT_TOUT);
        btm_ble_set_conn_st (BLE_DIR_CONN);

        return (TRUE);
    }
}
int start_work_thread(void)
{
    adpcm_rec_cb.running = 1;

    if(adpcm_rec_cb.tid > 0)
    {
        BTM_TRACE_WARNING0("the pthread is already start,can't start again");
        return -1;
    }

    if (pthread_create(&adpcm_rec_cb.tid, (const pthread_attr_t *) NULL, (void*)work_task, NULL) < 0)
    {
        BTM_TRACE_ERROR0("uipc_thread_create pthread_create failed");
        return -1;
    }

    return 0;
}
/*******************************************************************************
**
** Function         BTM_SecDeleteDevice
**
** Description      Free resources associated with the device.
**
** Parameters:      bd_addr          - BD address of the peer
**
** Returns          TRUE if removed OK, FALSE if not found or ACL link is active
**
*******************************************************************************/
BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr)
{
    tBTM_SEC_DEV_REC  *p_dev_rec;

    if (BTM_IsAclConnectionUp(bd_addr))
    {
        BTM_TRACE_WARNING0("BTM_SecDeleteDevice FAILED: Cannot Delete when connection is active");
        return(FALSE);
    }

    if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
        return(FALSE);

    btm_sec_free_dev (p_dev_rec);

    /* Tell controller to get rid of the link key if it has one stored */
    BTM_DeleteStoredLinkKey (bd_addr, NULL);

    return(TRUE);
}
static void work_task(void *arg)
{
    BTM_TRACE_WARNING0("WORK THREAD START");
    while (1)
    {
        VOHOG_LOCK();
        if(adpcm_rec_cb.running)
        {
           if(adpcm_rec_cb.channel_status)
           {
                if(!isEmpty())
                {
                    if(getDATAfrombuffer(tempData,ADPCM_VOICE_DATA_BLOCK_SIZE))
                    {
                        if(UIPC_RTKBT_VR_Send_noblock(UIPC_CH_ID_RTKBT_VR_AUDIO, 0, tempData, ADPCM_VOICE_DATA_BLOCK_SIZE))
                        {
                            BTM_TRACE_DEBUG0("send data sucess");

                            adpcm_voice_data_buffer.ridx ++;
                            adpcm_voice_data_buffer.ridx %= ADPCM_VOICE_DATA_BUFFER_SIZE;

                        } else {
                            BTM_TRACE_ERROR0("send data failed");
                        }
                   }

                }
           }
        } else {
            if(adpcm_rec_cb.channel_status)
            {
                BTM_TRACE_WARNING0("close thread: channel is connected");
                if(isEmpty())
                {
                    BTM_TRACE_WARNING0("the buffer is empty, close socket");
                    resetBuffer();
                    UIPC_Close(UIPC_CH_ID_RTKBT_VR_AUDIO);
                    VOHOG_UNLOCK();
                    break;
                }  else {
                    BTM_TRACE_WARNING0("the buffer is not empty, send data");
                    if(getDATAfrombuffer(tempData,ADPCM_VOICE_DATA_BLOCK_SIZE))
                    {
                        if(UIPC_RTKBT_VR_Send_noblock(UIPC_CH_ID_RTKBT_VR_AUDIO, 0, tempData, ADPCM_VOICE_DATA_BLOCK_SIZE))
                        {
                            BTM_TRACE_DEBUG0("send data sucess");

                            adpcm_voice_data_buffer.ridx ++;
                            adpcm_voice_data_buffer.ridx %= ADPCM_VOICE_DATA_BUFFER_SIZE;

                        } else {
                            BTM_TRACE_ERROR0("send data failed,close socket");
                            resetBuffer();
                            UIPC_Close(UIPC_CH_ID_RTKBT_VR_AUDIO);
                            VOHOG_UNLOCK();
                            break;
                        }
                   }

                }
            }else {
                BTM_TRACE_WARNING0("close thread: the socket is not connected");
                VOHOG_UNLOCK();
                break;
            }

        }
        VOHOG_UNLOCK();
        usleep(1000);
    }
    adpcm_rec_cb.tid = 0;
    BTM_TRACE_WARNING0("VOICE THREAD DONE");
}
BOOLEAN adpcm_voice_encode(tBTA_ATT_HSDATA *att_data)
{
    //BTM_TRACE_DEBUG0("adpcm_voice_encode");
    uint8_t buffer[MAX_FRAME_SIZE];
    int size;
    int frame_size;
    UINT8       *p = NULL;
    FILE *fp;
    fp = fopen (RTK_STORAGE_PCM_FILE, "a+");
    if (fp == NULL)
    {
       BTM_TRACE_WARNING0("open file failed\n");
       return FALSE;
    }

    p = (UINT8*)(att_data->data+3);
    size = att_data->data_len - 3;

    /* we must receive 12 20-bytes packets followed by a 19-bytes packet */
    switch (size) {
    case 20:
        adpcm_rec_cb.n_20bytes_pkts++;
        if (adpcm_rec_cb.n_20bytes_pkts > 12){
            BTM_TRACE_DEBUG0("20bytes pkt is exceed 12");
            adpcm_rec_cb.n_20bytes_pkts = 1;
            memcpy(adpcm_rec_cb.buffer + (adpcm_rec_cb.n_20bytes_pkts - 1) * 20,p, 20);
        } else {
            memcpy(adpcm_rec_cb.buffer + (adpcm_rec_cb.n_20bytes_pkts - 1) * 20,p, 20);
        }
        break;
    case 19:
        if (adpcm_rec_cb.n_20bytes_pkts != 12) {
            BTM_TRACE_DEBUG0("20bytes pkt!=12,discard the frame");
            adpcm_rec_cb.n_20bytes_pkts = 0;
        } else {
            memcpy(adpcm_rec_cb.buffer + adpcm_rec_cb.n_20bytes_pkts * 20, p, 19);
            adpcm_rec_cb.n_20bytes_pkts = 0;
            frame_size = adpcm_decode(adpcm_rec_cb.adpcm_state, buffer, adpcm_rec_cb.buffer,ADPCM_ENCODED_FRAME_SIZE);
            BTM_TRACE_DEBUG1("frame size= %d",frame_size);
            if(frame_size == 1020)
            {
                fwrite(buffer, frame_size, 1, fp);
                if(adpcm_rec_cb.channel_status)
                {
                    if(isEmpty())
                    {
                        BTM_TRACE_DEBUG0("the buffer empty,send data to socket");
                        VOHOG_LOCK();
                        if(!UIPC_RTKBT_VR_Send_noblock(UIPC_CH_ID_RTKBT_VR_AUDIO, 0, buffer, frame_size))
                        {
                           BTM_TRACE_WARNING0("send data fail, save data to buffer");
                           saveDATAtobuffer(buffer, frame_size);
                        }
                        VOHOG_UNLOCK();
                    } else {
                        BTM_TRACE_DEBUG0("the buffer is not empty, save data to buffer");
                        saveDATAtobuffer(buffer, frame_size);
                    }
                } else {
                    if(!adpcm_rec_cb.channel_status)
                    {
                        BTM_TRACE_DEBUG0("socket is close");
                    }
                    saveDATAtobuffer(buffer, frame_size);
                }
            }else {
                BTM_TRACE_DEBUG0("frame_size is error");
            }
        }
        break;
    default:
        BTM_TRACE_DEBUG0("size is error");
    }
    //BTM_TRACE_DEBUG1("20bytes pkt= %d",adpcm_rec_cb.n_20bytes_pkts);
    free(att_data);
    //fseek(fp,0,SEEK_END);
    //int lSize = ftell(fp);
    //BTM_TRACE_WARNING1("file length %d\n",lSize);
    fclose(fp);
    return TRUE;
}