ESP_GATTC_CONNECT_EVT = 40, /*!< When the ble physical connection is set up, the event comes */
ESP_GATTC_DISCONNECT_EVT = 41, /*!< When the ble physical connection disconnected, the event comes */
ESP_GATTC_READ_MUTIPLE_EVT = 42, /*!< When the ble characteristic or descriptor mutiple complete, the event comes */
+ ESP_GATTC_QUEUE_FULL_EVT = 43, /*!< When the gattc command queue full, the event comes */
} esp_gattc_cb_event_t;
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
} disconnect; /*!< Gatt client callback param of ESP_GATTC_DISCONNECT_EVT */
+ /**
+ * @brief ESP_GATTC_QUEUE_FULL_EVT
+ */
+ struct gattc_queue_full_evt_param {
+ esp_gatt_status_t status; /*!< Operation status */
+ uint16_t conn_id; /*!< Connection id */
+ bool is_full; /*!< The gattc command queue is full or not */
+ } queue_full; /*!< Gatt client callback param of ESP_GATTC_QUEUE_FULL_EVT */
+
} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */
/**
if (p_data != NULL) {
/* execute pending operation of link block still present */
if (l2cu_find_lcb_by_bd_addr(p_clcb->p_srcb->server_bda, BT_TRANSPORT_LE) != NULL) {
- if (p_data->hdr.event == BTA_GATTC_API_WRITE_EVT) {
- APPL_TRACE_ERROR("%s(), p_data = %d", __func__, p_data->api_write.p_value[0]);
- }
// The data to be sent to the gattc state machine for processing
if(bta_gattc_sm_execute(p_clcb, p_data->hdr.event, p_data)) {
list_remove(p_clcb->p_cmd_list, (void *)p_data);
}
+
+ if (p_clcb->is_full) {
+ tBTA_GATTC cb_data = {0};
+ p_clcb->is_full = FALSE;
+ cb_data.status = GATT_SUCCESS;
+ cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
+ cb_data.queue_full.is_full = FALSE;
+ if (p_clcb->p_rcb->p_cback != NULL) {
+ ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
+ }
+ }
}
}
}
return p_tcb;
}
-static void bta_gattc_remove_prepare_write_in_queue(tBTA_GATTC_CLCB *p_clcb)
+static BOOLEAN bta_gattc_has_prepare_command_in_queue(tBTA_GATTC_CLCB *p_clcb)
{
assert(p_clcb != NULL);
if (cmd_data != NULL && ((cmd_data->hdr.event == BTA_GATTC_API_WRITE_EVT &&
cmd_data->api_write.write_type == BTA_GATTC_WRITE_PREPARE) ||
cmd_data->hdr.event == BTA_GATTC_API_EXEC_EVT)) {
- // remove the prepare write command in the command queue
- list_remove(p_clcb->p_cmd_list, (void *)cmd_data);
+ return TRUE;
}
}
- return;
+ return FALSE;
}
/*******************************************************************************
**
*******************************************************************************/
BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
{
+ tBTA_GATTC cb_data = {0};
if (p_clcb->p_q_cmd == NULL) {
p_clcb->p_q_cmd = p_data;
return TRUE;
} else if (p_data->hdr.event == BTA_GATTC_API_WRITE_EVT &&
p_data->api_write.write_type == BTA_GATTC_WRITE_PREPARE &&
- p_data->api_write.handle == p_clcb->p_q_cmd->api_write.handle) {
- bta_gattc_remove_prepare_write_in_queue (p_clcb);
- tBTA_GATTC cb_data = {0};
+ p_data->api_write.handle == p_clcb->p_q_cmd->api_write.handle &&
+ bta_gattc_has_prepare_command_in_queue(p_clcb)) {
cb_data.write.status = BTA_GATT_CONGESTED;
cb_data.write.handle = p_data->api_write.handle;
cb_data.write.conn_id = p_clcb->bta_conn_id;
/* write complete, callback */
- ( *p_clcb->p_rcb->p_cback)(p_data->hdr.event, (tBTA_GATTC *)&cb_data);
+ if (p_clcb->p_rcb->p_cback != NULL) {
+ ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_PREP_WRITE_EVT, (tBTA_GATTC *)&cb_data);
+ }
return FALSE;
}
else if (p_clcb->p_cmd_list) {
UINT16 len = 0;
tBTA_GATTC_DATA *cmd_data = NULL;
+
if (list_length(p_clcb->p_cmd_list) >= GATTC_COMMAND_QUEUE_SIZE_MAX) {
+
APPL_TRACE_ERROR("%s(), the gattc command queue is full.", __func__);
+ cb_data.status = GATT_BUSY;
+ cb_data.queue_full.conn_id = p_clcb->bta_conn_id;
+ cb_data.queue_full.is_full = TRUE;
+ p_clcb->is_full = TRUE;
+ if (p_clcb->p_rcb->p_cback != NULL) {
+ ( *p_clcb->p_rcb->p_cback)(BTA_GATTC_QUEUE_FULL_EVT, (tBTA_GATTC *)&cb_data);
+ }
return FALSE;
}
#define BTA_GATTC_CONNECT_EVT 35 /* GATTC CONNECT event */
#define BTA_GATTC_DISCONNECT_EVT 36 /* GATTC DISCONNECT event */
#define BTA_GATTC_READ_MUTIPLE_EVT 37 /* GATTC Read mutiple event */
+#define BTA_GATTC_QUEUE_FULL_EVT 38 /* GATTC queue full event */
typedef UINT8 tBTA_GATTC_EVT;
BOOLEAN congested; /* congestion indicator */
} tBTA_GATTC_CONGEST;
+typedef struct {
+ tBTA_GATT_STATUS status;
+ UINT16 conn_id;
+ BOOLEAN is_full;
+} tBTA_GATTC_QUEUE_FULL;
+
typedef struct {
tBTA_GATT_STATUS status;
tBTA_GATTC_IF client_if;
BD_ADDR remote_bda; /* service change event */
tBTA_GATTC_CFG_MTU cfg_mtu; /* configure MTU operation */
tBTA_GATTC_CONGEST congest;
+ tBTA_GATTC_QUEUE_FULL queue_full;
} tBTA_GATTC;
/* GATTC enable callback function */
tBTA_GATTC_SERV *p_srcb; /* server cache CB */
tBTA_GATTC_DATA *p_q_cmd; /* command in queue waiting for execution */
list_t *p_cmd_list; /* The list to store the command to be sent */
+ BOOLEAN is_full; /* The gattc command queue is full or not */
#define BTA_GATTC_NO_SCHEDULE 0
#define BTA_GATTC_DISC_WAITING 0x01
#define BTA_GATTC_REQ_WAITING 0x10
btc_gattc_cb_to_app(ESP_GATTC_SRVC_CHG_EVT, ESP_GATT_IF_NONE, ¶m);
break;
}
+ case BTA_GATTC_QUEUE_FULL_EVT: {
+ tBTA_GATTC_QUEUE_FULL *queue_full = &arg->queue_full;
+ gattc_if = BTC_GATT_GET_GATT_IF(queue_full->conn_id);
+ param.queue_full.conn_id = BTC_GATT_GET_CONN_ID(queue_full->conn_id);
+ param.queue_full.status = arg->status;
+ param.queue_full.is_full = queue_full->is_full;
+ btc_gattc_cb_to_app(ESP_GATTC_QUEUE_FULL_EVT, gattc_if, ¶m);
+ break;
+ }
default:
LOG_DEBUG("%s: Unhandled event (%d)!", __FUNCTION__, msg->act);
break;