/*******************************************************************************
**
** Function         nfc_hal_dm_set_config
**
** Description      Send NCI config items to NFCC
**
** Returns          tHAL_NFC_STATUS
**
*******************************************************************************/
tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size,
                                       UINT8 *p_param_tlvs,
                                       tNFC_HAL_NCI_CBACK *p_cback)
{
    UINT8  *p_buff, *p;
    UINT8  num_param = 0, param_len, rem_len, *p_tlv;
    UINT16 cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1;
    tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;

    if ((tlv_size == 0)||(p_param_tlvs == NULL))
    {
        return status;
    }

    if ((p_buff = (UINT8 *) GKI_getbuf ((UINT16)(NCI_MSG_HDR_SIZE + tlv_size))) != NULL)
    {
        p = p_buff;

        NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE);
        NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_SET_CONFIG);
        UINT8_TO_STREAM  (p, (UINT8) (tlv_size + 1));

        rem_len = tlv_size;
        p_tlv   = p_param_tlvs;
        while (rem_len > 1)
        {
            num_param++;                /* number of params */

            p_tlv ++;                   /* param type   */
            param_len = *p_tlv++;       /* param length */

            rem_len -= 2;               /* param type and length */
            if (rem_len >= param_len)
            {
                rem_len -= param_len;
                p_tlv   += param_len;   /* next param_type */

                if (rem_len == 0)
                {
                    status = HAL_NFC_STATUS_OK;
                    break;
                }
            }
            else
            {
                /* error found */
                break;
            }
        }

        if (status == HAL_NFC_STATUS_OK)
        {
            UINT8_TO_STREAM (p, num_param);
            ARRAY_TO_STREAM (p, p_param_tlvs, tlv_size);

            nfc_hal_dm_send_nci_cmd (p_buff, cmd_len, p_cback);
        }
        else
        {
            HAL_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV");
        }

        GKI_freebuf (p_buff);
    }

    return status;
}
Beispiel #2
0
/*******************************************************************************
**
** Function         gatt_process_read_rsp
**
** Description      This function is called to handle the read BLOB response
**
**
** Returns          void
**
*******************************************************************************/
void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb,  UINT8 op_code,
                           UINT16 len, UINT8 *p_data)
{
    UINT16      offset = p_clcb->counter;
    UINT8       * p= p_data;

    if (p_clcb->operation == GATTC_OPTYPE_READ)
    {
        if (p_clcb->op_subtype != GATT_READ_BY_HANDLE)
        {
            p_clcb->counter = len;
            gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p);
        }
        else
        {

            /* allocate GKI buffer holding up long attribute value  */
            if (!p_clcb->p_attr_buf)
                p_clcb->p_attr_buf = (UINT8 *)GKI_getbuf(GATT_MAX_ATTR_LEN);

            /* copy attrobute value into cb buffer  */
            if (p_clcb->p_attr_buf && offset < GATT_MAX_ATTR_LEN)
            {
                if ((len + offset) > GATT_MAX_ATTR_LEN)
                    len = GATT_MAX_ATTR_LEN - offset;

                p_clcb->counter += len;

                memcpy(p_clcb->p_attr_buf + offset, p, len);

                /* send next request if needed  */

                if (len == (p_tcb->payload_size - 1) && /* full packet for read or read blob rsp */
                    len + offset < GATT_MAX_ATTR_LEN)
                {
                    GATT_TRACE_DEBUG3("full pkt issue read blob for remianing bytes old offset=%d len=%d new offset=%d",
                                      offset, len, p_clcb->counter);
                    gatt_act_read(p_clcb, p_clcb->counter);
                }
                else /* end of request, send callback */
                {
                    gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p_clcb->p_attr_buf);
                }
            }
            else /* exception, should not happen */
            {
                GATT_TRACE_ERROR2("attr offset = %d p_attr_buf = %d ", offset, p_clcb->p_attr_buf);
                gatt_end_operation(p_clcb, GATT_NO_RESOURCES, (void *)p_clcb->p_attr_buf);
            }
        }
    }
    else
    {
        if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
            p_clcb->op_subtype == GATT_DISC_INC_SRVC &&
            p_clcb->read_uuid128.wait_for_read_rsp )
        {
            p_clcb->s_handle = p_clcb->read_uuid128.next_disc_start_hdl;
            p_clcb->read_uuid128.wait_for_read_rsp = FALSE;
            if (len == LEN_UUID_128)
            {

                memcpy(p_clcb->read_uuid128.result.value.incl_service.service_type.uu.uuid128, p, len);
                p_clcb->read_uuid128.result.value.incl_service.service_type.len = LEN_UUID_128;
                if ( p_clcb->p_reg->app_cb.p_disc_res_cb)
                    (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id, p_clcb->op_subtype, &p_clcb->read_uuid128.result);
                gatt_act_discovery(p_clcb) ;
            }
            else
            {
                gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void *)p);
            }
        }
    }

}
Beispiel #3
0
/*******************************************************************************
**
** Function         mca_ccb_hdl_req
**
** Description      This function is called when a MCAP request is received from
**                  the peer. It calls the application callback function to
**                  report the event.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_hdl_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    BT_HDR  *p_pkt = &p_data->hdr;
    BT_HDR  *p_buf;
    UINT8   *p, *p_start;
    tMCA_DCB    *p_dcb;
    tMCA_CTRL       evt_data;
    tMCA_CCB_MSG    *p_rx_msg = NULL;
    UINT8           reject_code = MCA_RSP_NO_RESOURCE;
    BOOLEAN         send_rsp = FALSE;
    BOOLEAN         check_req = FALSE;
    UINT8           reject_opcode;

    MCA_TRACE_DEBUG ("mca_ccb_hdl_req status:%d", p_ccb->status);
    p_rx_msg = (tMCA_CCB_MSG *)p_pkt;
    p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    evt_data.hdr.op_code = *p++;
    BE_STREAM_TO_UINT16 (evt_data.hdr.mdl_id, p);
    reject_opcode = evt_data.hdr.op_code+1;

    MCA_TRACE_DEBUG ("received mdl id: %d ", evt_data.hdr.mdl_id);
    if (p_ccb->status == MCA_CCB_STAT_PENDING)
    {
        MCA_TRACE_DEBUG ("received req inpending state");
        /* allow abort in pending state */
        if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (evt_data.hdr.op_code == MCA_OP_MDL_ABORT_REQ))
        {
            reject_code = MCA_RSP_SUCCESS;
            send_rsp = TRUE;
            /* clear the pending status */
            p_ccb->status = MCA_CCB_STAT_NORM;
            if (p_ccb->p_tx_req && ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx))!= NULL))
            {
                mca_dcb_dealloc (p_dcb, NULL);
                mca_free_buf ((void **)&p_ccb->p_tx_req);
            }
        }
        else
            reject_code = MCA_RSP_BAD_OP;
    }
    else if (p_ccb->p_rx_msg)
    {
        MCA_TRACE_DEBUG ("still handling prev req");
        /* still holding previous message, reject this new one ?? */

    }
    else if (p_ccb->p_tx_req)
    {
        MCA_TRACE_DEBUG ("still waiting for a response ctrl_vpsm:0x%x", p_ccb->ctrl_vpsm);
        /* sent a request; waiting for response */
        if (p_ccb->ctrl_vpsm == 0)
        {
            MCA_TRACE_DEBUG ("local is ACP. accept the cmd from INT");
            /* local is acceptor, need to handle the request */
            check_req = TRUE;
            reject_code = MCA_RSP_SUCCESS;
            /* drop the previous request */
            if ((p_ccb->p_tx_req->op_code == MCA_OP_MDL_CREATE_REQ) &&
                ((p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx)) != NULL))
            {
                mca_dcb_dealloc(p_dcb, NULL);
            }
            mca_free_buf ((void **)&p_ccb->p_tx_req);
            mca_stop_timer(p_ccb);
        }
        else
        {
            /*  local is initiator, ignore the req */
            GKI_freebuf (p_pkt);
            return;
        }
    }
    else if (p_pkt->layer_specific != MCA_RSP_SUCCESS)
    {

        reject_code = (UINT8)p_pkt->layer_specific;
        if (((evt_data.hdr.op_code >= MCA_NUM_STANDARD_OPCODE) &&
            (evt_data.hdr.op_code < MCA_FIRST_SYNC_OP)) ||
            (evt_data.hdr.op_code > MCA_LAST_SYNC_OP))
        {
            /* invalid op code */
            reject_opcode = MCA_OP_ERROR_RSP;
            evt_data.hdr.mdl_id = 0;
        }
    }
    else
    {
        check_req = TRUE;
        reject_code = MCA_RSP_SUCCESS;
    }

    if (check_req)
    {
        if (reject_code == MCA_RSP_SUCCESS)
        {
            reject_code = MCA_RSP_BAD_MDL;
            if (MCA_IS_VALID_MDL_ID(evt_data.hdr.mdl_id) ||
                ((evt_data.hdr.mdl_id == MCA_ALL_MDL_ID) && (evt_data.hdr.op_code == MCA_OP_MDL_DELETE_REQ)))
            {
                reject_code = MCA_RSP_SUCCESS;
                /* mdl_id is valid according to the spec */
                switch (evt_data.hdr.op_code)
                {
                case MCA_OP_MDL_CREATE_REQ:
                    evt_data.create_ind.dep_id = *p++;
                    evt_data.create_ind.cfg = *p++;
                    p_rx_msg->mdep_id = evt_data.create_ind.dep_id;
                    if (!mca_is_valid_dep_id(p_ccb->p_rcb, p_rx_msg->mdep_id))
                    {
                        MCA_TRACE_ERROR ("not a valid local mdep id");
                        reject_code = MCA_RSP_BAD_MDEP;
                    }
                    else if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
                    {
                        MCA_TRACE_DEBUG ("the mdl_id is currently used in the CL(create)");
                        mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
                    }
                    else
                    {
                        /* check if this dep still have MDL available */
                        if (mca_dep_free_mdl(p_ccb, evt_data.create_ind.dep_id) == 0)
                        {
                            MCA_TRACE_ERROR ("the mdep is currently using max_mdl");
                            reject_code = MCA_RSP_MDEP_BUSY;
                        }
                    }
                    break;

                case MCA_OP_MDL_RECONNECT_REQ:
                    if (mca_ccb_uses_mdl_id(p_ccb, evt_data.hdr.mdl_id))
                    {
                        MCA_TRACE_ERROR ("the mdl_id is currently used in the CL(reconn)");
                        reject_code = MCA_RSP_MDL_BUSY;
                    }
                    break;

                case MCA_OP_MDL_ABORT_REQ:
                    reject_code = MCA_RSP_BAD_OP;
                    break;

                case MCA_OP_MDL_DELETE_REQ:
                    /* delete the associated mdl */
                    mca_dcb_close_by_mdl_id(p_ccb, evt_data.hdr.mdl_id);
                    send_rsp = TRUE;
                    break;
                }
            }
        }
    }

    if (((reject_code != MCA_RSP_SUCCESS) && (evt_data.hdr.op_code != MCA_OP_SYNC_INFO_IND))
        || send_rsp)
    {
        p_buf = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
        if (p_buf)
        {
            p_buf->offset = L2CAP_MIN_OFFSET;
            p = p_start = (UINT8*)(p_buf + 1) + L2CAP_MIN_OFFSET;
            *p++ = reject_opcode;
            *p++ = reject_code;
            UINT16_TO_BE_STREAM (p, evt_data.hdr.mdl_id);
            /*
            if (((*p_start) == MCA_OP_MDL_CREATE_RSP) && (reject_code == MCA_RSP_SUCCESS))
            {
                *p++ = evt_data.create_ind.cfg;
            }
            */

            p_buf->len = p - p_start;
            L2CA_DataWrite (p_ccb->lcid, p_buf);
        }
    }

    if (reject_code == MCA_RSP_SUCCESS)
    {
        /* use the received GKI buffer to store information to double check response API */
        p_rx_msg->op_code = evt_data.hdr.op_code;
        p_rx_msg->mdl_id = evt_data.hdr.mdl_id;
        p_ccb->p_rx_msg = p_rx_msg;
        if (send_rsp)
        {
            GKI_freebuf (p_pkt);
            p_ccb->p_rx_msg = NULL;
        }
        mca_ccb_report_event(p_ccb, evt_data.hdr.op_code, &evt_data);
    }
    else
        GKI_freebuf (p_pkt);
}
void *GKI_getpoolbuf (UINT8 pool_id)
#endif
{
    FREE_QUEUE_T  *Q;
    BUFFER_HDR_T  *p_hdr;
    tGKI_COM_CB *p_cb = &gki_cb.com;

    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
        return (NULL);

#if GKI_BUFFER_DEBUG
    LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
#endif
    /* Make sure the buffers aren't disturbed til finished with allocation */
    GKI_disable();

    Q = &p_cb->freeq[pool_id];
    if(Q->cur_cnt < Q->total)
    {
#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
        if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
            return NULL;
#endif

        if(Q->p_first == 0)
        {
            /* gki_alloc_free_queue() failed to alloc memory */
            GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
            return NULL;
        }

        p_hdr = Q->p_first;
        Q->p_first = p_hdr->p_next;

        if (!Q->p_first)
            Q->p_last = NULL;

        if(++Q->cur_cnt > Q->max_cnt)
            Q->max_cnt = Q->cur_cnt;

        GKI_enable();


        p_hdr->task_id = GKI_get_taskid();

        p_hdr->status  = BUF_STATUS_UNLINKED;
        p_hdr->p_next  = NULL;
        p_hdr->Type    = 0;

#if GKI_BUFFER_DEBUG
        LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);

        strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
        p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
        p_hdr->_line = _line_;
#endif
        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
    }

    /* If here, no buffers in the specified pool */
    GKI_enable();

#if GKI_BUFFER_DEBUG
    /* try for free buffers in public pools */
    return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
#else
    /* try for free buffers in public pools */
    return (GKI_getbuf(p_cb->freeq[pool_id].size));
#endif
}
Beispiel #5
0
/*******************************************************************************
**
** Function         gatt_process_read_by_type_rsp
**
** Description      This function is called to handle the read by type response.
**                  read by type can be used for discovery, or read by type or
**                  read characteristic value.
**
** Returns          void
**
*******************************************************************************/
void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
                                    UINT16 len, UINT8 *p_data)
{
    tGATT_DISC_RES      result;
    tGATT_DISC_VALUE    record_value;
    UINT8               *p = p_data, value_len, handle_len = 2;
    UINT16              handle = 0;

    /* discovery procedure and no callback function registered */
    if (((!p_clcb->p_reg) || (!p_clcb->p_reg->app_cb.p_disc_res_cb)) && (p_clcb->operation == GATTC_OPTYPE_DISCOVERY))
        return;

    STREAM_TO_UINT8(value_len, p);

    if ((value_len > (p_tcb->payload_size - 2)) || (value_len > (len-1))  )
    {
        /* this is an error case that server's response containing a value length which is larger than MTU-2
           or value_len > message total length -1 */
        GATT_TRACE_ERROR4("gatt_process_read_by_type_rsp: Discard response op_code=%d vale_len=%d > (MTU-2=%d or msg_len-1=%d)",
                          op_code, value_len, (p_tcb->payload_size - 2), (len-1));
        gatt_end_operation(p_clcb, GATT_ERROR, NULL);
        return;
    }

    if (op_code == GATT_RSP_READ_BY_GRP_TYPE)
        handle_len = 4;

    value_len -= handle_len; /* substract the handle pairs bytes */
    len -= 1;

    while (len >= (handle_len + value_len))
    {
        STREAM_TO_UINT16(handle, p);

        if (!GATT_HANDLE_IS_VALID(handle))
        {
            gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
            return;
        }

        memset(&result, 0, sizeof(tGATT_DISC_RES));
        memset(&record_value, 0, sizeof(tGATT_DISC_VALUE));

        result.handle = handle;
        result.type.len = 2;
        result.type.uu.uuid16 = disc_type_to_uuid[p_clcb->op_subtype];

        /* discover all services */
        if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY &&
            p_clcb->op_subtype == GATT_DISC_SRVC_ALL &&
            op_code == GATT_RSP_READ_BY_GRP_TYPE)
        {
            STREAM_TO_UINT16(handle, p);

            if (!GATT_HANDLE_IS_VALID(handle))
            {
                gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
                return;
            }
            else
            {
                record_value.group_value.e_handle = handle;
                if (!gatt_parse_uuid_from_cmd(&record_value.group_value.service_type, value_len, &p))
                {
                    GATT_TRACE_ERROR0("discover all service response parsing failure");
                    break;
                }
            }
        }
        /* discover included service */
        else if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->op_subtype == GATT_DISC_INC_SRVC)
        {
            STREAM_TO_UINT16(record_value.incl_service.s_handle, p);
            STREAM_TO_UINT16(record_value.incl_service.e_handle, p);

            if (!GATT_HANDLE_IS_VALID(record_value.incl_service.s_handle) ||
                !GATT_HANDLE_IS_VALID(record_value.incl_service.e_handle))
            {
                gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
                return;
            }

            if(value_len == 6)
            {
                STREAM_TO_UINT16(record_value.incl_service.service_type.uu.uuid16, p);
                record_value.incl_service.service_type.len = LEN_UUID_16;
            }
            else if (value_len == 4)
            {
                p_clcb->s_handle = record_value.incl_service.s_handle;
                p_clcb->read_uuid128.wait_for_read_rsp = TRUE;
                p_clcb->read_uuid128.next_disc_start_hdl = handle + 1;
                memcpy(&p_clcb->read_uuid128.result, &result, sizeof(result));
                memcpy(&p_clcb->read_uuid128.result.value, &record_value, sizeof (result.value));
                p_clcb->op_subtype |= 0x90;
                gatt_act_read(p_clcb, 0);
                return;
            }
            else
            {
               GATT_TRACE_ERROR1("gatt_process_read_by_type_rsp INCL_SRVC failed with invalid data value_len=%d", value_len);
               gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void *)p);
               return;
            }
        }
        /* read by type */
        else if (p_clcb->operation == GATTC_OPTYPE_READ && p_clcb->op_subtype == GATT_READ_BY_TYPE)
        {
            p_clcb->counter = len - 2;
            p_clcb->s_handle = handle;
            if ( p_clcb->counter == (p_clcb->p_tcb->payload_size -4))
            {
                p_clcb->op_subtype = GATT_READ_BY_HANDLE;
                if (!p_clcb->p_attr_buf)
                    p_clcb->p_attr_buf = (UINT8 *)GKI_getbuf(GATT_MAX_ATTR_LEN);
                if (p_clcb->p_attr_buf && p_clcb->counter <= GATT_MAX_ATTR_LEN)
                {
                    memcpy(p_clcb->p_attr_buf, p, p_clcb->counter);
                    gatt_act_read(p_clcb, p_clcb->counter);
                }
                else
                   gatt_end_operation(p_clcb, GATT_INTERNAL_ERROR, (void *)p);
            }
            else
            {
                 gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p);
            }
            return;
        }
        else /* discover characterisitic or read characteristic value */
        {
            STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
            STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
            if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle))
            {
                gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL);
                return;
            }
            gatt_parse_uuid_from_cmd(&record_value.dclr_value.char_uuid, (UINT16)(value_len - 3), &p);

            /* UUID not matching */
            if (!gatt_uuid_compare(record_value.dclr_value.char_uuid, p_clcb->uuid))
            {
                len -= (value_len + 2);
                continue; /* skip the result, and look for next one */
            }
            else if (p_clcb->operation == GATTC_OPTYPE_READ)
            /* UUID match for read characteristic value */
            {
                /* only read the first matching UUID characteristic value, and
                  discard the rest results */
                p_clcb->s_handle = record_value.dclr_value.val_handle;
                p_clcb->op_subtype |= 0x80;
                gatt_act_read(p_clcb, 0);
                return;
            }
        }
        len -= (value_len + handle_len);

        /* result is (handle, 16bits UUID) pairs */
        memcpy (&result.value, &record_value, sizeof (result.value));

        /* send callback if is discover procedure */
        if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->p_reg->app_cb.p_disc_res_cb)
            (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id, p_clcb->op_subtype, &result);
    }

    p_clcb->s_handle = (handle == 0) ? 0 : (handle + 1);

    if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
    {
        /* initiate another request */
        gatt_act_discovery(p_clcb) ;
    }
    else /* read characteristic value */
    {
        gatt_act_read(p_clcb, 0);
    }
}
Beispiel #6
0
/*******************************************************************************
**
** Function         bta_ag_mgmt_cback
**
** Description      RFCOMM management callback
**
**
** Returns          void
**
*******************************************************************************/
static void bta_ag_mgmt_cback(UINT32 code, UINT16 port_handle, UINT16 handle)
{
    tBTA_AG_RFC     *p_buf;
    tBTA_AG_SCB     *p_scb;
    UINT16          event;
    UINT8           i;
    BOOLEAN         found_handle = FALSE;

    APPL_TRACE_DEBUG("ag_mgmt_cback : code = %d, port_handle = %d, handle = %d",
                        code, port_handle, handle);

    if ((p_scb = bta_ag_scb_by_idx(handle)) != NULL)
    {
        /* ignore close event for port handles other than connected handle */
        if ((code != PORT_SUCCESS) && (port_handle != p_scb->conn_handle))
        {
            APPL_TRACE_DEBUG("ag_mgmt_cback ignoring handle:%d", port_handle);
            return;
        }

        if (code == PORT_SUCCESS)
        {
            if (p_scb->conn_handle)     /* Outgoing connection */
            {
                if (port_handle == p_scb->conn_handle)
                    found_handle = TRUE;
            }
            else                        /* Incoming connection */
            {
                for (i = 0; i < BTA_AG_NUM_IDX; i++)
                {
                    if (port_handle == p_scb->serv_handle[i])
                        found_handle = TRUE;
                }
            }

            if (!found_handle)
            {
                APPL_TRACE_ERROR ("bta_ag_mgmt_cback: PORT_SUCCESS, ignoring handle = %d", port_handle);
                return;
            }

            event = BTA_AG_RFC_OPEN_EVT;
        }
        /* distinguish server close events */
        else if (port_handle == p_scb->conn_handle)
        {
            event = BTA_AG_RFC_CLOSE_EVT;
        }
        else
        {
            event = BTA_AG_RFC_SRV_CLOSE_EVT;
        }

        if ((p_buf = (tBTA_AG_RFC *) GKI_getbuf(sizeof(tBTA_AG_RFC))) != NULL)
        {
            p_buf->hdr.event = event;
            p_buf->hdr.layer_specific = handle;
            p_buf->port_handle = port_handle;
            bta_sys_sendmsg(p_buf);
        }
    }
}
/*******************************************************************************
**
** Function         nfa_p2p_update_active_listen
**
** Description      Remove active listen mode temporarily or restore it
**
**
** Returns          None
**
*******************************************************************************/
static void nfa_p2p_update_active_listen (void)
{
    tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
    BT_HDR *p_msg;

    P2P_TRACE_DEBUG1 ("nfa_p2p_update_active_listen (): listen_tech_mask_to_restore:0x%x",
                       nfa_p2p_cb.listen_tech_mask_to_restore);

    /* if active listen mode was removed temporarily */
    if (nfa_p2p_cb.listen_tech_mask_to_restore)
    {
        /* restore listen technologies */
        nfa_p2p_cb.listen_tech_mask = nfa_p2p_cb.listen_tech_mask_to_restore;
        nfa_p2p_cb.listen_tech_mask_to_restore = 0;
        nfa_sys_stop_timer (&nfa_p2p_cb.active_listen_restore_timer);
    }
    else
    {
        /* start timer in case of no passive activation */
        nfa_p2p_cb.active_listen_restore_timer.p_cback = (TIMER_CBACK *)nfa_p2p_update_active_listen_timeout_cback;
        nfa_sys_start_timer (&nfa_p2p_cb.active_listen_restore_timer, 0, NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT);

        /* save listen techonologies */
        nfa_p2p_cb.listen_tech_mask_to_restore = nfa_p2p_cb.listen_tech_mask;

        /* remove active listen mode */
        nfa_p2p_cb.listen_tech_mask &= ~( NFA_TECHNOLOGY_MASK_A_ACTIVE|NFA_TECHNOLOGY_MASK_F_ACTIVE);
    }

    if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
    {
        nfa_dm_delete_rf_discover (nfa_p2p_cb.dm_disc_handle);
        nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
    }

    /* collect listen technologies with NFC-DEP protocol */
    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
        p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;

    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
        p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;

    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
        p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;

    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
        p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;

#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
    /*For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer. For LLCP DTA mode activate LLCP
     * Bypassing LLCP is handled in nfa_dm_poll_disc_cback*/
    if ((appl_dta_mode_flag == 1) && (nfa_dm_cb.eDtaMode == NFA_DTA_DEFAULT_MODE))
    {
        /* Configure listen technologies and protocols and register callback to NFA DM discovery */
        P2P_TRACE_DEBUG0 ("DTA mode1:Registering nfa_dm_poll_disc_cback to avoid LLCP in P2P ");
        nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover (p2p_listen_mask,
                                                            NFA_DM_DISC_HOST_ID_DH,
                                                            nfa_dm_poll_disc_cback_dta_wrapper);
    }
    else
#endif
    {
        /* Configure listen technologies and protocols and register callback to NFA DM discovery */
        nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover (p2p_listen_mask,
                                                            NFA_DM_DISC_HOST_ID_DH,
                                                            nfa_p2p_discovery_cback);
    }
    /* restart RF discovery to update RF technologies */
    if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof(BT_HDR))) != NULL)
    {
        p_msg->event = NFA_P2P_INT_RESTART_RF_DISC_EVT;
        nfa_sys_sendmsg (p_msg);
    }
}
Beispiel #8
0
/*******************************************************************************
**
** Function         AVDT_SendReport
**
** Description
**
**
**
** Returns
**
*******************************************************************************/
UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type,
                       tAVDT_REPORT_DATA *p_data)
{
    tAVDT_SCB       *p_scb;
    UINT16          result = AVDT_BAD_PARAMS;
    BT_HDR          *p_pkt;
    tAVDT_TC_TBL    *p_tbl;
    UINT8           *p, *plen, *pm1, *p_end;
#if AVDT_MULTIPLEXING == TRUE
    UINT8           *p_al = NULL, u;
#endif
    UINT32  ssrc;
    UINT16  len;

    /* map handle to scb && verify parameters */
    if (((p_scb = avdt_scb_by_hdl(handle)) != NULL)
            && (p_scb->p_ccb != NULL)
            && (((type == AVDT_RTCP_PT_SR) && (p_scb->cs.tsep == AVDT_TSEP_SRC)) ||
                ((type == AVDT_RTCP_PT_RR) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) ||
                (type == AVDT_RTCP_PT_SDES)) ) {
        result = AVDT_NO_RESOURCES;

        /* build SR - assume fit in one packet */
        p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb);
        if ((p_tbl->state == AVDT_AD_ST_OPEN) &&
                (p_pkt = (BT_HDR *)GKI_getbuf(p_tbl->peer_mtu)) != NULL) {
            p_pkt->offset = L2CAP_MIN_OFFSET;
            p = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
#if AVDT_MULTIPLEXING == TRUE
            if (p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX) {
                /* Adaptation Layer header later */
                p_al = p;
                p += 2;
            }
#endif
            pm1 = p;
            *p++ = AVDT_MEDIA_OCTET1 | 1;
            *p++ = type;
            /* save the location for length */
            plen = p;
            p += 2;
            ssrc = avdt_scb_gen_ssrc(p_scb);
            UINT32_TO_BE_STREAM(p, ssrc);

            switch (type) {
            case AVDT_RTCP_PT_SR:   /* Sender Report */
                *pm1 = AVDT_MEDIA_OCTET1;
                UINT32_TO_BE_STREAM(p, p_data->sr.ntp_sec);
                UINT32_TO_BE_STREAM(p, p_data->sr.ntp_frac);
                UINT32_TO_BE_STREAM(p, p_data->sr.rtp_time);
                UINT32_TO_BE_STREAM(p, p_data->sr.pkt_count);
                UINT32_TO_BE_STREAM(p, p_data->sr.octet_count);
                break;

            case AVDT_RTCP_PT_RR:   /* Receiver Report */
                *p++ = p_data->rr.frag_lost;
                AVDT_TRACE_API("packet_lost: %d\n", p_data->rr.packet_lost);
                p_data->rr.packet_lost &= 0xFFFFFF;
                AVDT_TRACE_API("packet_lost: %d\n", p_data->rr.packet_lost);
                UINT24_TO_BE_STREAM(p, p_data->rr.packet_lost);
                UINT32_TO_BE_STREAM(p, p_data->rr.seq_num_rcvd);
                UINT32_TO_BE_STREAM(p, p_data->rr.jitter);
                UINT32_TO_BE_STREAM(p, p_data->rr.lsr);
                UINT32_TO_BE_STREAM(p, p_data->rr.dlsr);
                break;

            case AVDT_RTCP_PT_SDES: /* Source Description */
                *p++ = AVDT_RTCP_SDES_CNAME;
                len = strlen((char *)p_data->cname);
                if (len > AVDT_MAX_CNAME_SIZE) {
                    len = AVDT_MAX_CNAME_SIZE;
                }
                *p++ = (UINT8)len;
                BCM_STRNCPY_S((char *)p, len + 1, (char *)p_data->cname, len + 1);
                p += len;
                break;
            }
            p_end = p;
            len = p - pm1 - 1;
            UINT16_TO_BE_STREAM(plen, len);

#if AVDT_MULTIPLEXING == TRUE
            if (p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX) {
                /* Adaptation Layer header */
                p = p_al;
                len++;
                UINT16_TO_BE_STREAM(p_al, len );
                /* TSID, no-fragment bit and coding of length(9-bit length field) */
                u = *p;
                *p = (p_scb->curr_cfg.mux_tsid_report << 3) | AVDT_ALH_LCODE_9BITM0;
                if (u) {
                    *p |= AVDT_ALH_LCODE_9BITM1;
                }
            }
#endif

            /* set the actual payload length */
            p_pkt->len = p_end - p;
            /* send the packet */
            if (L2CAP_DW_FAILED != avdt_ad_write_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, p_pkt)) {
                result = AVDT_SUCCESS;
            }
        }
    }

    return result;
}
Beispiel #9
0
/*******************************************************************************
**
** Function         bta_ag_do_disc
**
** Description      Do service discovery.
**
**
** Returns          void
**
*******************************************************************************/
void bta_ag_do_disc(tBTA_AG_SCB *p_scb, tBTA_SERVICE_MASK service)
{
    tSDP_UUID       uuid_list[2];
    UINT16          num_uuid = 1;
    UINT16          attr_list[4];
    UINT8           num_attr;
    BOOLEAN         db_inited = FALSE;

    /* HFP initiator; get proto list and features */
    if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_INT)
    {
        attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
        attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
        attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
        attr_list[3] = ATTR_ID_SUPPORTED_FEATURES;
        num_attr = 4;
        uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HF_HANDSFREE;
    }
    /* HFP acceptor; get features */
    else if (service & BTA_HFP_SERVICE_MASK && p_scb->role == BTA_AG_ACP)
    {
        attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
        attr_list[1] = ATTR_ID_BT_PROFILE_DESC_LIST;
        attr_list[2] = ATTR_ID_SUPPORTED_FEATURES;
        num_attr = 3;
        uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HF_HANDSFREE;
    }
    /* HSP initiator; get proto list */
    else if (service & BTA_HSP_SERVICE_MASK && p_scb->role == BTA_AG_INT)
    {
        attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
        attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
        attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
        attr_list[3] = ATTR_ID_REMOTE_AUDIO_VOLUME_CONTROL;
        num_attr = 4;

        uuid_list[0].uu.uuid16 = UUID_SERVCLASS_HEADSET;        /* Legacy from HSP v1.0 */
        if (p_scb->hsp_version >= HSP_VERSION_1_2)
        {
            uuid_list[1].uu.uuid16 = UUID_SERVCLASS_HEADSET_HS;
            num_uuid = 2;
        }
    }
    /* HSP acceptor; no discovery */
    else
    {
        return;
    }

    /* allocate buffer for sdp database */
    p_scb->p_disc_db = (tSDP_DISCOVERY_DB *) GKI_getbuf(BTA_AG_DISC_BUF_SIZE);

    if(p_scb->p_disc_db)
    {
        /* set up service discovery database; attr happens to be attr_list len */
        uuid_list[0].len = LEN_UUID_16;
        uuid_list[1].len = LEN_UUID_16;
        db_inited = SDP_InitDiscoveryDb(p_scb->p_disc_db, BTA_AG_DISC_BUF_SIZE, num_uuid,
                            uuid_list, num_attr, attr_list);
    }

    if(db_inited)
    {
        /*Service discovery not initiated */
        db_inited = SDP_ServiceSearchAttributeRequest(p_scb->peer_addr, p_scb->p_disc_db,
                                      bta_ag_sdp_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1]);
    }

    if(!db_inited)
    {
        /*free discover db */
        bta_ag_free_db(p_scb, NULL);
        /* sent failed event */
        bta_ag_sm_execute(p_scb, BTA_AG_DISC_FAIL_EVT, NULL);
    }

}
Beispiel #10
0
/*******************************************************************************
**
** Function         dis_c_cmpl_cback
**
** Description      Client operation complete callback.
**
** Returns          void
**
*******************************************************************************/
void dis_c_cmpl_cback (tSRVC_CLCB *p_clcb, tGATTC_OPTYPE op,
                              tGATT_STATUS status, tGATT_CL_COMPLETE *p_data)
{
    UINT16      read_type = dis_attr_uuid[dis_cb.dis_read_uuid_idx];
    UINT8       *pp = NULL, *p_str;
    UINT16      conn_id = p_clcb->conn_id;

    GATT_TRACE_EVENT ("dis_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x  \
                        read_type: 0x%04x", op, status, read_type);

    if (op != GATTC_OPTYPE_READ)
        return;

    if (p_data != NULL && status == GATT_SUCCESS)
    {
        pp = p_data->att_value.value;

        switch (read_type)
        {
            case GATT_UUID_SYSTEM_ID:
                GATT_TRACE_EVENT ("DIS_ATTR_SYS_ID_BIT");
                if (p_data->att_value.len == DIS_SYSTEM_ID_SIZE)
                {
                    p_clcb->dis_value.attr_mask |= DIS_ATTR_SYS_ID_BIT;
                    /* save system ID*/
                    STREAM_TO_UINT64 (p_clcb->dis_value.system_id, pp);
                }
                break;

            case GATT_UUID_PNP_ID:
                if (p_data->att_value.len == DIS_PNP_ID_SIZE)
                {
                    p_clcb->dis_value.attr_mask |= DIS_ATTR_PNP_ID_BIT;
                    STREAM_TO_UINT8 (p_clcb->dis_value.pnp_id.vendor_id_src, pp);
                    STREAM_TO_UINT16 (p_clcb->dis_value.pnp_id.vendor_id, pp);
                    STREAM_TO_UINT16 (p_clcb->dis_value.pnp_id.product_id, pp);
                    STREAM_TO_UINT16 (p_clcb->dis_value.pnp_id.product_version, pp);
                }
                break;

            case GATT_UUID_MODEL_NUMBER_STR:
            case GATT_UUID_SERIAL_NUMBER_STR:
            case GATT_UUID_FW_VERSION_STR:
            case GATT_UUID_HW_VERSION_STR:
            case GATT_UUID_SW_VERSION_STR:
            case GATT_UUID_MANU_NAME:
            case GATT_UUID_IEEE_DATA:
                p_str = p_clcb->dis_value.data_string[read_type - GATT_UUID_MODEL_NUMBER_STR];
                if (p_str != NULL)
                    GKI_freebuf(p_str);
                if ((p_str = (UINT8 *)GKI_getbuf((UINT16)(p_data->att_value.len + 1))) != NULL)
                {
                    p_clcb->dis_value.attr_mask |= dis_uuid_to_attr(read_type);
                    memcpy(p_str, p_data->att_value.value, p_data->att_value.len);
                    p_str[p_data->att_value.len] = 0;
                    p_clcb->dis_value.data_string[read_type - GATT_UUID_MODEL_NUMBER_STR] = p_str;
                }
                break;

            default:
                    break;

                break;
        }/* end switch */
    }/* end if */

    dis_cb.dis_read_uuid_idx ++;

    dis_gatt_c_read_dis_req(conn_id);
}