Пример #1
0
/*******************************************************************************
**
** Function         gatt_send_conn_cback
**
** Description      Callback used to notify layer above about a connection.
**
**
** Returns          void
**
*******************************************************************************/
static void gatt_send_conn_cback(tGATT_TCB *p_tcb)
{
    UINT8               i;
    tGATT_REG           *p_reg;
    tGATT_BG_CONN_DEV   *p_bg_dev=NULL;
    UINT16              conn_id;

    p_bg_dev = gatt_find_bg_dev(p_tcb->peer_bda);

    /* notifying all applications for the connection up event */
    for (i = 0,  p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++)
    {
        if (p_reg->in_use)
        {
            if (p_bg_dev && gatt_is_bg_dev_for_app(p_bg_dev, p_reg->gatt_if))
                gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, TRUE, TRUE);

            if (p_reg->app_cb.p_conn_cb)
            {
                conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
                (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
                                          TRUE, 0, p_tcb->transport);
            }
        }
    }


    if (gatt_num_apps_hold_link(p_tcb) &&  p_tcb->att_lcid == L2CAP_ATT_CID )
    {
        /* disable idle timeout if one or more clients are holding the link disable the idle timer */
        GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
    }
}
Пример #2
0
/*******************************************************************************
**
** Function         gatt_channel_congestion
**
** Description      This function is called to process the congestion callback
**                  from lcb
**
** Returns          void
**
*******************************************************************************/
static void gatt_channel_congestion(tGATT_TCB *p_tcb, BOOLEAN congested)
{
    UINT8 i = 0;
    tGATT_REG *p_reg=NULL;
    UINT16 conn_id;

    /* if uncongested, check to see if there is any more pending data */
    if (p_tcb != NULL && congested == FALSE)
    {
        gatt_cl_send_next_cmd_inq(p_tcb);
    }
    /* notifying all applications for the connection up event */
    for (i = 0, p_reg = gatt_cb.cl_rcb ; i < GATT_MAX_APPS; i++, p_reg++)
    {
        if (p_reg->in_use)
        {
            if (p_reg->app_cb.p_congestion_cb)
            {
                conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
                (*p_reg->app_cb.p_congestion_cb)(conn_id, congested);
            }
        }
    }
}
Пример #3
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);
        }
    }

}