static uint32_t on_srv_l2c_connect(tBTA_JV_L2CAP_SRV_OPEN *p_open, uint32_t id)
{
    uint32_t new_listen_slot_id = 0;
    lock_slot(&slot_lock);
    l2c_slot_t* srv_ls = find_l2c_slot_by_id(id);
    if(srv_ls)
    {
        l2c_slot_t* accept_ls = create_srv_accept_l2c_slot(srv_ls, (const bt_bdaddr_t*)p_open->rem_bda,
                                                           p_open->handle, p_open->new_listen_handle);
        if(accept_ls)
        {
            //start monitor the socket
            btsock_thread_add_fd(pth, srv_ls->fd, BTSOCK_L2CAP, SOCK_THREAD_FD_EXCEPTION, srv_ls->id);
            btsock_thread_add_fd(pth, accept_ls->fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, accept_ls->id);
            APPL_TRACE_DEBUG("sending connect signal & app fd:%dto app server to accept() the connection",
                             accept_ls->app_fd);
            APPL_TRACE_DEBUG("server fd:%d, psm:%d", srv_ls->fd, srv_ls->psm);
            send_app_connect_signal(srv_ls->fd, &accept_ls->addr, srv_ls->psm, 0, accept_ls->app_fd);
            accept_ls->app_fd = -1; //the fd is closed after sent to app
            new_listen_slot_id = srv_ls->id;
        }
    }
    unlock_slot(&slot_lock);
    return new_listen_slot_id;
}
int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR("cmd socket is not created. socket thread may not initialized");
        return FALSE;
    }
    if(flags & SOCK_THREAD_ADD_FD_SYNC)
    {
        //must executed in socket poll thread
        if(ts[h].thread_id == pthread_self())
        {
            //cleanup one-time flags
            flags &= ~SOCK_THREAD_ADD_FD_SYNC;
            add_poll(h, fd, type, flags, user_id);
            return TRUE;
        }
        APPL_TRACE_DEBUG("THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async");
    }
    sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};
    APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags);
    return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
}
static void cleanup_l2c_slot(l2c_slot_t* ls)
{
    APPL_TRACE_DEBUG("cleanup slot:%d, fd:%d, psm:%d, sdp_handle:0x%x",
                                        ls->id, ls->fd, ls->psm, ls->sdp_handle);
    if(ls->fd != -1)
    {
        shutdown(ls->fd, 2);
        close(ls->fd);
        ls->fd = -1;
    }

    if(ls->app_fd != -1)
    {
        close(ls->app_fd);
        ls->app_fd = -1;
    }
    if(ls->sdp_handle > 0)
    {
        del_l2c_sdp_rec(ls->sdp_handle, ls->service_uuid);
        ls->sdp_handle = 0;
    }
    if((ls->l2c_handle != INVALID_L2C_HANDLE) && !ls->f.closing && !ls->f.server)
    {
        APPL_TRACE_DEBUG("closing l2cap connection, l2c_handle:0x%x", ls->l2c_handle);
        BTA_JvL2capClose(ls->l2c_handle, (void*)ls->id);
        ls->l2c_handle = INVALID_L2C_HANDLE;
    }
    free_l2c_slot_psm(ls);
    free_gki_que(&ls->incoming_que);

    //cleanup the flag
    memset(&ls->f, 0, sizeof(ls->f));
    ls->in_use = FALSE;
}
static int process_cmd_sock(int h)
{
    sock_cmd_t cmd = {-1, 0, 0, 0, 0};
    int fd = ts[h].cmd_fdr;
    if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
    {
        APPL_TRACE_ERROR("recv cmd errno:%d", errno);
        return FALSE;
    }
    APPL_TRACE_DEBUG("cmd.id:%d", cmd.id);
    switch(cmd.id)
    {
        case CMD_ADD_FD:
            add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id);
            break;
        case CMD_WAKEUP:
            break;
        case CMD_USER_PRIVATE:
            asrt(ts[h].cmd_callback);
            if(ts[h].cmd_callback)
                ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id);
            break;
        case CMD_EXIT:
            return FALSE;
        default:
            APPL_TRACE_DEBUG("unknown cmd: %d", cmd.id);
             break;
    }
    return TRUE;
}
/*******************************************************************************
**
** Function         bta_hf_client_remove_sco
**
** Description      Removes the specified SCO from the system.
**                  If only_active is TRUE, then SCO is only removed if connected
**
** Returns          BOOLEAN   - TRUE if Sco removal was started
**
*******************************************************************************/
static BOOLEAN bta_hf_client_sco_remove(BOOLEAN only_active)
{
    BOOLEAN     removed_started = FALSE;
    tBTM_STATUS status;

    APPL_TRACE_DEBUG("%s %d", __FUNCTION__, only_active);

    if (bta_hf_client_cb.scb.sco_idx != BTM_INVALID_SCO_INDEX)
    {
        status = BTM_RemoveSco(bta_hf_client_cb.scb.sco_idx);

        APPL_TRACE_DEBUG("%s idx 0x%04x, status:0x%x", __FUNCTION__, bta_hf_client_cb.scb.sco_idx, status);

        if (status == BTM_CMD_STARTED)
        {
            removed_started = TRUE;
        }
        /* If no connection reset the sco handle */
        else if ( (status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR) )
        {
            bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX;
        }
    }
    return removed_started;
}
Beispiel #6
0
void bta_hf_client_send_at_bia(void)
{
    char *buf;
    int at_len;
    int i;

    APPL_TRACE_DEBUG("%s", __FUNCTION__);
    if (bta_hf_client_cb.scb.peer_version < HFP_VERSION_1_6) {
        APPL_TRACE_DEBUG("Remote does not Support AT+BIA");
        return;
    }

    buf = osi_malloc(BTA_HF_CLIENT_AT_MAX_LEN);
    if (buf == NULL) {
        APPL_TRACE_ERROR("No mem %s", __FUNCTION__);
        return;
    }
    at_len = snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "AT+BIA=");

    for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
        int sup = bta_hf_client_cb.scb.at_cb.indicator_lookup[i] == -1 ? 0 : 1;

        at_len += snprintf(buf + at_len, BTA_HF_CLIENT_AT_MAX_LEN - at_len, "%u,", sup);
    }

    buf[at_len - 1] = '\r';

    bta_hf_client_send_at(BTA_HF_CLIENT_AT_BIA, buf, at_len);
    osi_free(buf);
}
int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback)
{
    int ret = FALSE;
    asrt(callback || cmd_callback);
    lock_slot(&thread_slot_lock);
    int h = alloc_thread_slot();
    unlock_slot(&thread_slot_lock);
    APPL_TRACE_DEBUG("alloc_thread_slot ret:%d", h);
    if(h >= 0)
    {
        init_poll(h);
        if((ts[h].thread_id = create_thread(sock_poll_thread, (void*)(uintptr_t)h)) != -1)
        {
            APPL_TRACE_DEBUG("h:%d, thread id:%d", h, ts[h].thread_id);
            ts[h].callback = callback;
            ts[h].cmd_callback = cmd_callback;
        }
        else
        {
            free_thread_slot(h);
            h = -1;
        }
    }
    return h;
}
/*******************************************************************************
**
** Function         bta_ag_api_result
**
** Description      Handle an API result event.
**
**
** Returns          void
**
*******************************************************************************/
static void bta_ag_api_result(tBTA_AG_DATA *p_data)
{
    tBTA_AG_SCB     *p_scb;
    int             i;

    if (p_data->hdr.layer_specific != BTA_AG_HANDLE_ALL)
    {
        if ((p_scb = bta_ag_scb_by_idx(p_data->hdr.layer_specific)) != NULL)
        {
            APPL_TRACE_DEBUG("bta_ag_api_result: p_scb 0x%08x ", p_scb);
            bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
        }
    }
    else
    {
        for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, p_scb++)
        {
            if (p_scb->in_use && p_scb->svc_conn)
            {
                APPL_TRACE_DEBUG("bta_ag_api_result p_scb 0x%08x ", p_scb);
                bta_ag_sm_execute(p_scb, BTA_AG_API_RESULT_EVT, p_data);
            }
        }
    }
}
/*******************************************************************************
**
** Function         bta_ag_pm_sniff
**
** Description      Switch to sniff mode.
**
**
** Returns          TRUE if sniff attempted, FALSE otherwise.
**
*******************************************************************************/
static BOOLEAN bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE *p_peer_dev, UINT8 index)
{
    tBTM_PM_MODE    mode = BTM_PM_STS_ACTIVE;
    tBTM_PM_PWR_MD  pwr_md;
    tBTM_STATUS     status;
    UINT8* p = NULL;
    BTM_ReadPowerMode(p_peer_dev->peer_bdaddr, &mode);

#if (BTM_SSR_INCLUDED == TRUE)
    APPL_TRACE_DEBUG("bta_dm_pm_sniff cur:%d, idx:%d, info:x%x", mode, index, p_peer_dev->info);
    if (mode != BTM_PM_MD_SNIFF ||
        (HCI_SNIFF_SUB_RATE_SUPPORTED(BTM_ReadLocalFeatures ()) &&
         (((p = BTM_ReadRemoteFeatures(p_peer_dev->peer_bdaddr)) != NULL) &&
           HCI_SNIFF_SUB_RATE_SUPPORTED(p)) && !(p_peer_dev->info & BTA_DM_DI_USE_SSR)))
#else
    APPL_TRACE_DEBUG("bta_dm_pm_sniff cur:%d, idx:%d", mode, index);
    if(mode != BTM_PM_MD_SNIFF)
#endif
    {
#if (BTM_SSR_INCLUDED == TRUE)
        /* Dont initiate Sniff if controller has alreay accepted
         * remote sniff params. This avoid sniff loop issue with
         * some agrresive headsets who use sniff latencies more than
         * DUT supported range of Sniff intervals.*/
        if ((mode == BTM_PM_MD_SNIFF) && (p_peer_dev->info & BTA_DM_DI_ACP_SNIFF))
        {
            APPL_TRACE_DEBUG("bta_dm_pm_sniff: already in remote initiate sniff");
            return TRUE;
        }
#endif
        /* if the current mode is not sniff, issue the sniff command.
         * If sniff, but SSR is not used in this link, still issue the command */
        memcpy(&pwr_md, &p_bta_dm_pm_md[index], sizeof (tBTM_PM_PWR_MD));
        if (p_peer_dev->info & BTA_DM_DI_INT_SNIFF)
        {
            pwr_md.mode |= BTM_PM_MD_FORCE;
        }
        status = BTM_SetPowerMode (bta_dm_cb.pm_id, p_peer_dev->peer_bdaddr, &pwr_md);
        if (status == BTM_CMD_STORED|| status == BTM_CMD_STARTED)
        {
            p_peer_dev->info &= ~(BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF);
            p_peer_dev->info |= BTA_DM_DI_SET_SNIFF;
        }
        else if (status == BTM_SUCCESS)
        {
            APPL_TRACE_DEBUG("bta_dm_pm_sniff BTM_SetPowerMode() returns BTM_SUCCESS");
            p_peer_dev->info &= ~(BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF|BTA_DM_DI_SET_SNIFF);
        }
        else /* error */
        {
            APPL_TRACE_ERROR("bta_dm_pm_sniff BTM_SetPowerMode() returns ERROR status=%d", status);
            p_peer_dev->info &= ~(BTA_DM_DI_INT_SNIFF|BTA_DM_DI_ACP_SNIFF|BTA_DM_DI_SET_SNIFF);
        }
    }
    /* else already in sniff and is using SSR, do nothing */

    return TRUE;

}
Beispiel #10
0
/******************************************************************************
**
**          MAIN PARSING FUNCTION
**
**
*******************************************************************************/
void bta_hf_client_at_parse(char *buf, unsigned int len)
{
    APPL_TRACE_DEBUG("%s offset: %u len: %u", __FUNCTION__, bta_hf_client_cb.scb.at_cb.offset, len);

    if (len + bta_hf_client_cb.scb.at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
        unsigned int tmp = bta_hf_client_cb.scb.at_cb.offset;
        unsigned int space_left = BTA_HF_CLIENT_AT_PARSER_MAX_LEN - bta_hf_client_cb.scb.at_cb.offset;
        char *tmp_buff = osi_malloc(BTA_HF_CLIENT_AT_PARSER_MAX_LEN);
        if (tmp_buff == NULL) {
            APPL_TRACE_ERROR("No mem %s", __FUNCTION__);
            return;
        }
        APPL_TRACE_DEBUG("%s overrun, trying to recover", __FUNCTION__);

        /* fill up parser buffer */
        memcpy(bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, buf, space_left);
        len -= space_left;
        buf += space_left;
        bta_hf_client_cb.scb.at_cb.offset += space_left;

        /* find end of last complete command before proceeding */
        while (bta_hf_client_check_at_complete() == FALSE) {
            if (bta_hf_client_cb.scb.at_cb.offset == 0) {
                APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");

                bta_hf_client_at_reset();
                bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
                osi_free(tmp_buff);
                return;
            }

            bta_hf_client_cb.scb.at_cb.offset--;
        }

        /* cut buffer to complete AT event and keep cut data */
        tmp += space_left - bta_hf_client_cb.scb.at_cb.offset;
        memcpy(tmp_buff, bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, tmp);
        bta_hf_client_cb.scb.at_cb.buf[bta_hf_client_cb.scb.at_cb.offset] = '\0';

        /* parse */
        bta_hf_client_at_parse_start();
        bta_hf_client_at_clear_buf();

        /* recover cut data */
        memcpy(bta_hf_client_cb.scb.at_cb.buf, tmp_buff, tmp);
        bta_hf_client_cb.scb.at_cb.offset += tmp;

        osi_free(tmp_buff);
    }

    memcpy(bta_hf_client_cb.scb.at_cb.buf + bta_hf_client_cb.scb.at_cb.offset, buf, len);
    bta_hf_client_cb.scb.at_cb.offset += len;

    /* If last event is complete, parsing can be started */
    if (bta_hf_client_check_at_complete() == TRUE) {
        bta_hf_client_at_parse_start();
        bta_hf_client_at_clear_buf();
    }
}
Beispiel #11
0
bt_status_t btsock_rfc_listen(const char *service_name, const uint8_t *service_uuid, int channel, int *sock_fd, int flags) {
  assert(sock_fd != NULL);
  assert((service_uuid != NULL)
    || (channel >= 1 && channel <= MAX_RFC_CHANNEL)
	|| ((flags & BTSOCK_FLAG_NO_SDP) != 0));

  *sock_fd = INVALID_FD;

  // TODO(sharvil): not sure that this check makes sense; seems like a logic error to call
  // functions on RFCOMM sockets before initializing the module. Probably should be an assert.
  if (!is_init_done())
    return BT_STATUS_NOT_READY;

  if((flags & BTSOCK_FLAG_NO_SDP) == 0) {
    if(is_uuid_empty(service_uuid)) {
      APPL_TRACE_DEBUG("BTA_JvGetChannelId: service_uuid not set AND "
              "BTSOCK_FLAG_NO_SDP is not set - changing to SPP");
      service_uuid = UUID_SPP;  // Use serial port profile to listen to specified channel
    } else {
      //Check the service_uuid. overwrite the channel # if reserved
      int reserved_channel = get_reserved_rfc_channel(service_uuid);
      if (reserved_channel > 0) {
            channel = reserved_channel;
      }
    }
  }

  int status = BT_STATUS_FAIL;
  pthread_mutex_lock(&slot_lock);

  rfc_slot_t *slot = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, true);
  if (!slot) {
    LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__);
    goto out;
  }
  APPL_TRACE_DEBUG("BTA_JvGetChannelId: service_name: %s - channel: %d", service_name, channel);
  BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, UINT_TO_PTR(slot->id), channel);
  *sock_fd = slot->app_fd;    // Transfer ownership of fd to caller.
  /*TODO:
   * We are leaking one of the app_fd's - either the listen socket, or the connection socket.
   * WE need to close this in native, as the FD might belong to another process
    - This is the server socket FD
    - For accepted connections, we close the FD after passing it to JAVA.
    - Try to simply remove the = -1 to free the FD at rs cleanup.*/
//        close(rs->app_fd);
  slot->app_fd = INVALID_FD;  // Drop our reference to the fd.
  btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, slot->id);

  status = BT_STATUS_SUCCESS;

out:;
  pthread_mutex_unlock(&slot_lock);
  return status;
}
/*******************************************************************************
**
** Function         bta_gattc_sm_execute
**
** Description      State machine event handling function for GATTC
**
**
** Returns          BOOLEAN  : TRUE if queued client request buffer can be immediately released
**                                        else FALSE
**
*******************************************************************************/
BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
{
    tBTA_GATTC_ST_TBL     state_table;
    UINT8               action;
    int                 i;
    BOOLEAN             rt = TRUE;
#if BTA_GATT_DEBUG == TRUE
    tBTA_GATTC_STATE in_state = p_clcb->state;
    UINT16         in_event = event;
    APPL_TRACE_DEBUG("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state,
                      gattc_state_code(in_state),
                      in_event,
                      gattc_evt_code(in_event));
#endif


    /* look up the state table for the current state */
    state_table = bta_gattc_st_tbl[p_clcb->state];

    event &= 0x00FF;

    /* set next state */
    p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE];

    /* execute action functions */
    for (i = 0; i < BTA_GATTC_ACTIONS; i++)
    {
        if ((action = state_table[event][i]) != BTA_GATTC_IGNORE)
        {
            (*bta_gattc_action[action])(p_clcb, p_data);
            if (p_clcb->p_q_cmd == p_data) {
                /* buffer is queued, don't free in the bta dispatcher.
                 * we free it ourselves when a completion event is received.
                 */
                rt = FALSE;
            }
        }
        else
        {
            break;
        }
    }

#if BTA_GATT_DEBUG == TRUE
    if (in_state != p_clcb->state)
    {
        APPL_TRACE_DEBUG("GATTC State Change: [%s] -> [%s] after Event [%s]",
                          gattc_state_code(in_state),
                          gattc_state_code(p_clcb->state),
                          gattc_evt_code(in_event));
    }
#endif
    return rt;
}
Beispiel #13
0
static void bta_hf_client_handle_clcc(UINT16 idx, UINT16 dir, UINT16 status, UINT16 mode, UINT16 mpty, char *numstr, UINT16 type)
{
    APPL_TRACE_DEBUG("%s idx: %u dir: %u status: %u mode: %u mpty: %u",
                     __FUNCTION__, idx, dir, status, mode, mpty);

    if (numstr) {
        APPL_TRACE_DEBUG("%s number: %s  type: %u", __FUNCTION__, numstr, type);
    }

    bta_hf_client_clcc(idx, dir, status, mpty, numstr);
}
static void *l2cap_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data)
{
    int rc;
    void* new_user_data = NULL;
    APPL_TRACE_DEBUG("event=%s", jv_evt[event]);

    switch (event)
    {
    case BTA_JV_L2CAP_START_EVT:
        on_srv_l2c_listen_started(&p_data->l2c_start, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_CL_INIT_EVT:
        on_cl_l2c_init(&p_data->l2c_cl_init, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_OPEN_EVT:
        BTA_JvSetPmProfile(p_data->l2c_open.handle,BTA_JV_PM_ID_1,BTA_JV_CONN_OPEN);
        on_cli_l2c_connect(&p_data->l2c_open, (uint32_t)user_data);
        break;
    case BTA_JV_L2CAP_SRV_OPEN_EVT:
        BTA_JvSetPmProfile(p_data->l2c_srv_open.handle,BTA_JV_PM_ALL,BTA_JV_CONN_OPEN);
        new_user_data = (void*)on_srv_l2c_connect(&p_data->l2c_srv_open, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_CLOSE_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_CLOSE_EVT: user_data:%d", (uint32_t)user_data);
        on_l2c_close(&p_data->l2c_close, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_READ_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_READ_EVT not used");
        break;

    case BTA_JV_L2CAP_WRITE_EVT:
        on_l2c_write_done(&p_data->l2c_write, (uint32_t)user_data);
        break;

    case BTA_JV_L2CAP_DATA_IND_EVT:
        APPL_TRACE_DEBUG("BTA_JV_L2CAP_DATA_IND_EVT not used");
        break;

    case BTA_JV_L2CAP_CONG_EVT:
        //on_l2c_cong(&p_data->l2c_cong);
        on_l2c_outgoing_congest(&p_data->l2c_cong, (uint32_t)user_data);
        break;
    default:
        APPL_TRACE_ERROR("unhandled event %d, slot id:%d", event, (uint32_t)user_data);
        break;
    }
    return new_user_data;
}
Beispiel #15
0
/*******************************************************************************
**
** Function         bta_gatts_find_srvc_cb_by_srvc_id
**
** Description      find the service control block by service ID.
**
** Returns          pointer to the rcb.
**
*******************************************************************************/
tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id)
{
    UINT8 i;
    APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id  service_id=%d", service_id);
    for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++) {
        if (p_cb->srvc_cb[i].in_use &&
                p_cb->srvc_cb[i].service_id == service_id) {
            APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id  found service cb index =%d", i);
            return &p_cb->srvc_cb[i];
        }
    }
    return NULL;
}
Beispiel #16
0
static void bta_hf_client_handle_cind_value(UINT32 index, UINT32 value)
{
    APPL_TRACE_DEBUG("%s index: %u value: %u", __FUNCTION__, index, value);

    if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
        return;
    }

    if (service_index == index) {
        if (value == 0) {
            service_availability = FALSE;
        } else {
            service_availability = TRUE;
        }
    }
    if (bta_hf_client_cb.scb.at_cb.indicator_lookup[index] == -1) {
        return;
    }

    /* get the real array index from lookup table */
    index = bta_hf_client_cb.scb.at_cb.indicator_lookup[index];

    /* Ignore out of range values */
    if (value > bta_hf_client_indicators[index].max ||
            value < bta_hf_client_indicators[index].min) {
        return;
    }

    /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
    bta_hf_client_ind(index, value);
}
Beispiel #17
0
/* handles a single indicator descriptor - registers it for value changing events */
static void bta_hf_client_handle_cind_list_item(char *name, UINT32 min, UINT32 max, UINT32 index)
{

    UINT8 i = 0;

    APPL_TRACE_DEBUG("%s %u.%s <%u:%u>", __FUNCTION__, index, name, min, max);

    /* look for a matching indicator on list of supported ones */
    for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
        if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
            service_index = index;
        }
        /* look for a match - search one sign further than indicators name to check for string end */
        /* It will distinguish 'callheld' which could be matched by strncmp as 'call'.               */
        if (strncmp(name, bta_hf_client_indicators[i].name, bta_hf_client_indicators[i].namelen) != 0) {
            continue;
        }

        /* index - enumerates value position in the incoming sequence                      */
        /* if name matches one of the known indicators, add its incoming position          */
        /* to lookup table for easy value->indicator matching later, when only values come  */
        bta_hf_client_cb.scb.at_cb.indicator_lookup[index] = i;

        return;
    }
}
Beispiel #18
0
static void bta_hf_client_handle_error(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
{
    APPL_TRACE_DEBUG("%s %u %u", __FUNCTION__, type, cme);

    bta_hf_client_stop_at_resp_timer();

    if (!bta_hf_client_cb.scb.svc_conn) {
        bta_hf_client_slc_seq(TRUE);
        return;
    }

    switch (bta_hf_client_cb.scb.at_cb.current_cmd) {
    case BTA_HF_CLIENT_AT_BIA:
        break;
    case BTA_HF_CLIENT_AT_BCC:
    case BTA_HF_CLIENT_AT_BCS:
        bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
        break;
    case BTA_HF_CLIENT_AT_CLIP: //last cmd is post slc seq
        if (bta_hf_client_cb.scb.send_at_reply == FALSE) {
            bta_hf_client_cb.scb.send_at_reply = TRUE;
        }
        break;
    default:
        if (bta_hf_client_cb.scb.send_at_reply) {
            bta_hf_client_at_result(type, cme);
        }
        break;
    }

    bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;

    bta_hf_client_send_queued_at();
}
Beispiel #19
0
static void bta_hf_client_free_at_hold_timer(void)
{
    APPL_TRACE_DEBUG("%s", __FUNCTION__);

    bta_hf_client_cb.scb.at_cb.hold_timer_on = FALSE;
    bta_sys_free_timer(&bta_hf_client_cb.scb.at_cb.hold_timer);
}
Beispiel #20
0
/*******************************************************************************
**
** Function         bta_ag_start_servers
**
** Description      Setup RFCOMM servers for use by AG.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_start_servers(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK services)
{
    int i;
    int bta_ag_port_status;

    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)
        {
            BTM_SetSecurityLevel(FALSE, "", bta_ag_sec_id[i], p_scb->serv_sec_mask,
                BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, bta_ag_cb.profile[i].scn);

            bta_ag_port_status =  RFCOMM_CreateConnection(bta_ag_uuid[i], bta_ag_cb.profile[i].scn,
                TRUE, BTA_AG_MTU, (UINT8 *) bd_addr_any, &(p_scb->serv_handle[i]),
                bta_ag_mgmt_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);

            if( bta_ag_port_status  == PORT_SUCCESS )
            {
                bta_ag_setup_port(p_scb, p_scb->serv_handle[i]);
            }
            else
            {
                /* TODO: CR#137125 to handle to error properly */
                APPL_TRACE_DEBUG("bta_ag_start_servers: RFCOMM_CreateConnection returned error:%d", bta_ag_port_status);
            }
        }
    }
}
int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)
{
    if(h < 0 || h >= MAX_THREAD)
    {
        APPL_TRACE_ERROR("invalid bt thread handle:%d", h);
        return FALSE;
    }
    if(ts[h].cmd_fdw == -1)
    {
        APPL_TRACE_ERROR("cmd socket is not created. socket thread may not initialized");
        return FALSE;
    }
    sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id};
    APPL_TRACE_DEBUG("post cmd type:%d, size:%d, h:%d, ", type, size, h);
    sock_cmd_t* cmd_send = &cmd;
    int size_send = sizeof(cmd);
    if(data && size)
    {
        size_send = sizeof(cmd) + size;
        cmd_send = (sock_cmd_t*)alloca(size_send);
        if(cmd_send)
        {
            *cmd_send = cmd;
            memcpy(cmd_send + 1, data, size);
        }
        else
        {
            APPL_TRACE_ERROR("alloca failed at h:%d, cmd type:%d, size:%d", h, type, size_send);
            return FALSE;
        }
    }
    return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send;
}
Beispiel #22
0
static void bta_hf_client_dump_at(void)
{
    char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
    char *p1, *p2;

    p1 = bta_hf_client_cb.scb.at_cb.buf;
    p2 = dump;

    while (*p1 != '\0') {
        if (*p1 == '\r') {
            strlcpy(p2, "<cr>", 4);
            p2 += 4;
        } else if (*p1 == '\n') {
            strlcpy(p2, "<lf>", 4);
            p2 += 4;
        } else {
            *p2 = *p1;
            p2++;
        }
        p1++;
    }

    *p2 = '\0';

    APPL_TRACE_DEBUG("%s %s", __FUNCTION__, dump);
}
Beispiel #23
0
static void bta_hf_client_queue_at(tBTA_HF_CLIENT_AT_CMD cmd, const char *buf, UINT16 buf_len)
{
    tBTA_HF_CLIENT_AT_QCMD *new_cmd;

    APPL_TRACE_DEBUG("%s", __FUNCTION__);

    if ((new_cmd = (tBTA_HF_CLIENT_AT_QCMD *) osi_malloc(sizeof(tBTA_HF_CLIENT_AT_QCMD))) != NULL) {
        new_cmd->cmd = cmd;
        new_cmd->buf_len = buf_len;
        new_cmd->next = NULL;
        memcpy(new_cmd->buf, buf, buf_len);

        if (bta_hf_client_cb.scb.at_cb.queued_cmd != NULL) {
            tBTA_HF_CLIENT_AT_QCMD *qcmd = bta_hf_client_cb.scb.at_cb.queued_cmd;

            while (qcmd->next != NULL) {
                qcmd = qcmd->next;
            }

            qcmd->next = new_cmd;
        } else {
            bta_hf_client_cb.scb.at_cb.queued_cmd = new_cmd;
        }
    }
}
static char *bta_hf_client_skip_unknown(char *buffer)
{
    char *start;
    char *tmp;

    tmp = strstr(buffer, "\r\n");
    if (tmp == NULL)
    {
        return NULL;
    }

    buffer += 2;
    start = buffer;

    tmp = strstr(buffer, "\r\n");
    if (tmp == NULL)
    {
        return NULL;
    }

    buffer = tmp + 2;

    APPL_TRACE_DEBUG("%s %.*s", __FUNCTION__, buffer - start - 2, start);

    return buffer;
}
Beispiel #25
0
/*******************************************************************************
**
** Function         bta_pan_scb_alloc
**
** Description      Allocate a PAN server control block.
**
**
** Returns          pointer to the scb, or NULL if none could be allocated.
**
*******************************************************************************/
tBTA_PAN_SCB *bta_pan_scb_alloc(void)
{
    tBTA_PAN_SCB     *p_scb = &bta_pan_cb.scb[0];
    int             i;

    for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
    {
        if (!p_scb->in_use)
        {
            p_scb->in_use = TRUE;
            p_scb->is_idle_timer_started = FALSE;
            p_scb->idle_tle.param = (UINT32) bta_pan_idle_timeout_handler;
            p_scb->idle_tle.data = (UINT32) p_scb;
            APPL_TRACE_DEBUG("bta_pan_scb_alloc: %d, scb: %p", i, p_scb);
            break;
        }
    }

    if (i == BTA_PAN_NUM_CONN)
    {
        /* out of scbs */
        p_scb = NULL;
        APPL_TRACE_WARNING("Out of scbs");
    }
    return p_scb;
}
Beispiel #26
0
/*******************************************************************************
**
** Function         bta_ag_scb_alloc
**
** Description      Allocate an AG service control block.
**
**
** Returns          pointer to the scb, or NULL if none could be allocated.
**
*******************************************************************************/
static tBTA_AG_SCB *bta_ag_scb_alloc(void)
{
    tBTA_AG_SCB     *p_scb = &bta_ag_cb.scb[0];
    int             i;

    for (i = 0; i < BTA_AG_NUM_SCB; i++, p_scb++)
    {
        if (!p_scb->in_use)
        {
            /* initialize variables */
            p_scb->in_use = TRUE;
            p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
#if (BTM_WBS_INCLUDED == TRUE )
            p_scb->codec_updated = FALSE;
#endif
            /* set up timers */
            p_scb->act_timer.param = (UINT32) p_scb;
            p_scb->act_timer.p_cback = bta_ag_timer_cback;
#if (BTM_WBS_INCLUDED == TRUE)
            /* set eSCO mSBC setting to T2 as the preferred */
            p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
#endif
            APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
            break;
        }
    }

    if (i == BTA_AG_NUM_SCB)
    {
        /* out of scbs */
        p_scb = NULL;
        APPL_TRACE_WARNING("Out of ag scbs");
    }
    return p_scb;
}
Beispiel #27
0
static void bta_hf_client_handle_cnum( char *numstr, UINT16 type, UINT16 service)
{
    APPL_TRACE_DEBUG("%s number: %s type: %u service: %u", __FUNCTION__, numstr, type, service);

    /* TODO: should number be modified according to type? */
    bta_hf_client_cnum(numstr, service);
}
Beispiel #28
0
static void bta_hf_client_send_at(tBTA_HF_CLIENT_AT_CMD cmd, char *buf, UINT16 buf_len)
{
    if ((bta_hf_client_cb.scb.at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE ||
            bta_hf_client_cb.scb.svc_conn == FALSE) &&
            bta_hf_client_cb.scb.at_cb.hold_timer_on == FALSE) {
        UINT16  len;

#ifdef BTA_HF_CLIENT_AT_DUMP
        APPL_TRACE_DEBUG("%s %.*s", __FUNCTION__, buf_len - 1, buf);
#endif

        bta_hf_client_cb.scb.at_cb.current_cmd = cmd;
        /* Generate fake responses for these because they won't reliably work */
        if (!service_availability &&
                (cmd == BTA_HF_CLIENT_AT_CNUM || cmd == BTA_HF_CLIENT_AT_COPS)) {
            APPL_TRACE_WARNING("%s: No service, skipping %d command", __FUNCTION__, cmd);
            bta_hf_client_handle_ok();
            return;
        }

        PORT_WriteData(bta_hf_client_cb.scb.conn_handle, buf, buf_len, &len);

        bta_hf_client_start_at_resp_timer();

        return;
    }

    bta_hf_client_queue_at(cmd, buf, buf_len);
}
Beispiel #29
0
/*******************************************************************************
**
** Function         BTA_GATTC_DeregisterForNotifications
**
** Description      This function is called to de-register for notification of a service.
**
** Parameters       client_if - client interface.
**                  remote_bda - target GATT server.
**                  handle - GATT characteristic handle.
**
** Returns          OK if deregistration succeed, otherwise failed.
**
*******************************************************************************/
tBTA_GATT_STATUS BTA_GATTC_DeregisterForNotifications (tBTA_GATTC_IF client_if,
                                                       BD_ADDR bda, UINT16 handle)
{
    if (!handle) {
        APPL_TRACE_ERROR("%s: deregistration failed, handle is 0", __func__);
        return BTA_GATT_ILLEGAL_PARAMETER;
    }

    tBTA_GATTC_RCB *p_clreg = bta_gattc_cl_get_regcb(client_if);
    if (p_clreg == NULL) {
        APPL_TRACE_ERROR("%s client_if: %d not registered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
            __func__, client_if, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
        return BTA_GATT_ILLEGAL_PARAMETER;
    }

    for (int i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
        if (p_clreg->notif_reg[i].in_use &&
            !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
            p_clreg->notif_reg[i].handle == handle) {
            APPL_TRACE_DEBUG("%s deregistered bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
                __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
            memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
            return BTA_GATT_OK;
        }
    }

    APPL_TRACE_ERROR("%s registration not found bd_addr:%02x:%02x:%02x:%02x:%02x:%02x",
        __func__, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
    return BTA_GATT_ERROR;
}
static l2c_slot_t* alloc_l2c_slot(const bt_bdaddr_t *addr, const char* name, const uint8_t* uuid, int channel, int flags, BOOLEAN server)
{
    int security = 0;
    if(flags & BTSOCK_FLAG_ENCRYPT)
        security |= server ? BTM_SEC_IN_ENCRYPT : BTM_SEC_OUT_ENCRYPT;
    if(flags & BTSOCK_FLAG_AUTH) {
        security |= server ? BTM_SEC_IN_AUTHENTICATE : BTM_SEC_OUT_AUTHENTICATE;
    }
    l2c_slot_t* ls = find_free_slot();
    if(ls)
    {
        int fds[2] = {-1, -1};
        if(socketpair(AF_LOCAL, SOCK_STREAM, 0, fds))
        {
            APPL_TRACE_ERROR("socketpair failed, errno:%d", errno);
            return NULL;
        }
        ls->fd = fds[0];
        ls->app_fd = fds[1];

        APPL_TRACE_DEBUG("alloc_l2c_slot fd %d and app fd  %d is_server %d", ls->fd, ls->app_fd, server);
        ls->security = security;
        ls->psm = channel;
        if(uuid)
            memcpy(ls->service_uuid, uuid, sizeof(ls->service_uuid));
        else memset(ls->service_uuid, 0, sizeof(ls->service_uuid));
        if(name && *name)
            strlcpy(ls->service_name, name, sizeof(ls->service_name) -1);
        if(addr)
            ls->addr = *addr;
        ls->in_use = TRUE;
        ls->f.server = server;
    }
    return ls;
}