Ejemplo n.º 1
0
/*******************************************************************************
**
** Function         gatt_send_queue_write_cancel
**
** Description      send queue write cancel
**
** Returns          void.
**
*******************************************************************************/
void gatt_send_queue_write_cancel (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, tGATT_EXEC_FLAG flag)
{
    UINT8       rt ;

    GATT_TRACE_DEBUG("gatt_send_queue_write_cancel ");

    rt = attp_send_cl_msg(p_tcb, p_clcb->clcb_idx, GATT_REQ_EXEC_WRITE, (tGATT_CL_MSG *)&flag);

    if (rt != GATT_SUCCESS) {
        gatt_end_operation(p_clcb, rt, NULL);
    }
}
Ejemplo n.º 2
0
/*******************************************************************************
**
** Function         gatt_act_discovery
**
** Description      GATT discovery operation.
**
** Returns          void.
**
*******************************************************************************/
void gatt_act_discovery(tGATT_CLCB *p_clcb)
{
    UINT8       op_code = disc_type_to_att_opcode[p_clcb->op_subtype];
    tGATT_CL_MSG   cl_req;
    tGATT_STATUS    st;

    if (p_clcb->s_handle <= p_clcb->e_handle && p_clcb->s_handle != 0)
    {
        memset(&cl_req, 0, sizeof(tGATT_CL_MSG));

        cl_req.browse.s_handle = p_clcb->s_handle;
        cl_req.browse.e_handle = p_clcb->e_handle;

        if (disc_type_to_uuid[p_clcb->op_subtype] != 0)
        {
            cl_req.browse.uuid.len = 2;
            cl_req.browse.uuid.uu.uuid16 = disc_type_to_uuid[p_clcb->op_subtype];
        }

        if (p_clcb->op_subtype == GATT_DISC_SRVC_BY_UUID) /* fill in the FindByTypeValue request info*/
        {
            cl_req.find_type_value.uuid.len = 2;
            cl_req.find_type_value.uuid.uu.uuid16 = disc_type_to_uuid[p_clcb->op_subtype];
            cl_req.find_type_value.s_handle = p_clcb->s_handle;
            cl_req.find_type_value.e_handle = p_clcb->e_handle;
            cl_req.find_type_value.value_len = p_clcb->uuid.len;
            /* if service type is 32 bits UUID, convert it now */
            if (p_clcb->uuid.len == LEN_UUID_32)
            {
                cl_req.find_type_value.value_len = LEN_UUID_128;
                gatt_convert_uuid32_to_uuid128(cl_req.find_type_value.value, p_clcb->uuid.uu.uuid32);
            }
            else
            memcpy (cl_req.find_type_value.value,  &p_clcb->uuid.uu, p_clcb->uuid.len);
        }

        st = attp_send_cl_msg(p_clcb->p_tcb, p_clcb->clcb_idx, op_code, &cl_req);

        if (st !=  GATT_SUCCESS && st != GATT_CMD_STARTED)
        {
            gatt_end_operation(p_clcb, GATT_ERROR, NULL);
        }
    }
    else /* end of handle range */
        gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
}
/*******************************************************************************
**
** Function         gatt_act_discovery
**
** Description      GATT discovery operation.
**
** Returns          void.
**
*******************************************************************************/
void gatt_act_discovery(tGATT_CLCB *p_clcb)
{
    UINT8       op_code = disc_type_to_att_opcode[p_clcb->op_subtype];
    tGATT_CL_MSG   cl_req;

    if (p_clcb->s_handle <= p_clcb->e_handle && p_clcb->s_handle != 0)
    {
        memset(&cl_req, 0, sizeof(tGATT_CL_MSG));

        cl_req.browse.s_handle = p_clcb->s_handle;
        cl_req.browse.e_handle = p_clcb->e_handle;

        if (disc_type_to_uuid[p_clcb->op_subtype] != 0)
        {
            cl_req.browse.uuid.len = 2;
            cl_req.browse.uuid.uu.uuid16 = disc_type_to_uuid[p_clcb->op_subtype];
        }

        if (p_clcb->op_subtype == GATT_DISC_SRVC_BY_UUID) /* fill in the FindByTypeValue request info*/
        {
            cl_req.find_type_value.uuid.len = 2;
            cl_req.find_type_value.uuid.uu.uuid16 = disc_type_to_uuid[p_clcb->op_subtype];
            cl_req.find_type_value.s_handle = p_clcb->s_handle;
            cl_req.find_type_value.e_handle = p_clcb->e_handle;
            cl_req.find_type_value.value_len = p_clcb->uuid.len;
            memcpy (cl_req.find_type_value.value,  &p_clcb->uuid.uu, p_clcb->uuid.len);
        }

        if (attp_send_cl_msg(p_clcb->p_tcb, p_clcb->clcb_idx, op_code, &cl_req) !=  GATT_SUCCESS)
        {
            gatt_end_operation(p_clcb, GATT_ERROR, NULL);
        }
    }
    else /* end of handle range */
        gatt_end_operation(p_clcb, GATT_SUCCESS, NULL);
}
Ejemplo n.º 4
0
/*******************************************************************************
**
** Function         gatt_process_notification
**
** Description      This function is called to handle the handle value indication
**                  or handle value notification.
**
**
** Returns          void
**
*******************************************************************************/
void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code,
                               UINT16 len, UINT8 *p_data)
{
    tGATT_VALUE     value = {0};
    tGATT_REG       *p_reg;
    UINT16          conn_id;
    tGATT_STATUS    encrypt_status;
    UINT8           *p = p_data, i,
                     event = (op_code == GATT_HANDLE_VALUE_NOTIF) ? GATTC_OPTYPE_NOTIFICATION : GATTC_OPTYPE_INDICATION;

    GATT_TRACE_DEBUG("gatt_process_notification ");

    if (len < GATT_NOTIFICATION_MIN_LEN) {
        GATT_TRACE_ERROR("illegal notification PDU length, discard");
        return;
    }

    STREAM_TO_UINT16 (value.handle, p);
    value.len = len - 2;
    memcpy (value.value, p, value.len);

    if (!GATT_HANDLE_IS_VALID(value.handle)) {
        /* illegal handle, send ack now */
        if (op_code == GATT_HANDLE_VALUE_IND) {
            attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL);
        }
        return;
    }

    if (event == GATTC_OPTYPE_INDICATION) {
        if (p_tcb->ind_count) {
            /* this is an error case that receiving an indication but we
               still has an indication not being acked yet.
               For now, just log the error reset the counter.
               Later we need to disconnect the link unconditionally.
            */
            GATT_TRACE_ERROR("gatt_process_notification rcv Ind. but ind_count=%d (will reset ind_count)",  p_tcb->ind_count);
        }
        p_tcb->ind_count = 0;
    }

    /* should notify all registered client with the handle value notificaion/indication
       Note: need to do the indication count and start timer first then do callback
     */

    for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
        if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb && (event == GATTC_OPTYPE_INDICATION)) {
            p_tcb->ind_count++;
        }
    }

    if (event == GATTC_OPTYPE_INDICATION) {
        /* start a timer for app confirmation */
        if (p_tcb->ind_count > 0) {
            gatt_start_ind_ack_timer(p_tcb);
        } else { /* no app to indicate, or invalid handle */
            attp_send_cl_msg(p_tcb, 0, GATT_HANDLE_VALUE_CONF, NULL);
        }
    }

    encrypt_status = gatt_get_link_encrypt_status(p_tcb);
    for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
        if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) {
            conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
            (*p_reg->app_cb.p_cmpl_cb) (conn_id, event, encrypt_status, (tGATT_CL_COMPLETE *)&value);
        }
    }

}
Ejemplo n.º 5
0
/*******************************************************************************
**
** Function         gatt_act_read
**
** Description      GATT read operation.
**
** Returns          void.
**
*******************************************************************************/
void gatt_act_read (tGATT_CLCB *p_clcb, UINT16 offset)
{
    tGATT_TCB  *p_tcb = p_clcb->p_tcb;
    UINT8   rt = GATT_INTERNAL_ERROR;
    tGATT_CL_MSG  msg;
    UINT8        op_code = 0;

    memset (&msg, 0, sizeof(tGATT_CL_MSG));

    switch (p_clcb->op_subtype) {
    case GATT_READ_CHAR_VALUE:
    case GATT_READ_BY_TYPE:
        op_code = GATT_REQ_READ_BY_TYPE;
        msg.browse.s_handle = p_clcb->s_handle;
        msg.browse.e_handle = p_clcb->e_handle;
        if (p_clcb->op_subtype == GATT_READ_BY_TYPE) {
            memcpy(&msg.browse.uuid, &p_clcb->uuid, sizeof(tBT_UUID));
        } else {
            msg.browse.uuid.len = LEN_UUID_16;
            msg.browse.uuid.uu.uuid16 = GATT_UUID_CHAR_DECLARE;
        }
        break;

    case GATT_READ_CHAR_VALUE_HDL:
    case GATT_READ_BY_HANDLE:
        if (!p_clcb->counter) {
            op_code = GATT_REQ_READ;
            msg.handle = p_clcb->s_handle;
        } else {
            if (!p_clcb->first_read_blob_after_read) {
                p_clcb->first_read_blob_after_read = TRUE;
            } else {
                p_clcb->first_read_blob_after_read = FALSE;
            }

            GATT_TRACE_DEBUG("gatt_act_read first_read_blob_after_read=%d",
                             p_clcb->first_read_blob_after_read);
            op_code = GATT_REQ_READ_BLOB;
            msg.read_blob.offset = offset;
            msg.read_blob.handle = p_clcb->s_handle;
        }
        p_clcb->op_subtype &= ~ 0x80;
        break;

    case GATT_READ_PARTIAL:
        op_code = GATT_REQ_READ_BLOB;
        msg.read_blob.handle = p_clcb->s_handle;
        msg.read_blob.offset = offset;
        break;

    case GATT_READ_MULTIPLE:
        op_code = GATT_REQ_READ_MULTI;
        memcpy (&msg.read_multi, p_clcb->p_attr_buf, sizeof(tGATT_READ_MULTI));
        break;

    case GATT_READ_INC_SRV_UUID128:
        op_code = GATT_REQ_READ;
        msg.handle = p_clcb->s_handle;
        p_clcb->op_subtype &= ~ 0x90;
        break;

    default:
        GATT_TRACE_ERROR("Unknown read type: %d", p_clcb->op_subtype);
        break;
    }

    if (op_code != 0) {
        rt = attp_send_cl_msg(p_tcb, p_clcb->clcb_idx, op_code, &msg);
    }

    if ( op_code == 0 || (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED)) {
        gatt_end_operation(p_clcb, rt, NULL);
    }
}