static void gap_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg);
static void gap_congestion_ind(uint16_t lcid, bool is_congested);
static void gap_tx_complete_ind(uint16_t l2cap_cid, uint16_t sdu_sent);
+static void gap_credits_received_cb(uint16_t l2cap_cid,
+ uint16_t credits_received,
+ uint16_t credit_count);
static tGAP_CCB* gap_find_ccb_by_cid(uint16_t cid);
static tGAP_CCB* gap_find_ccb_by_handle(uint16_t handle);
conn.reg_info.pL2CA_DataInd_Cb = gap_data_ind;
conn.reg_info.pL2CA_CongestionStatus_Cb = gap_congestion_ind;
conn.reg_info.pL2CA_TxComplete_Cb = gap_tx_complete_ind;
+ conn.reg_info.pL2CA_CreditsReceived_Cb = gap_credits_received_cb;
}
/*******************************************************************************
mutex_global_unlock();
- DVLOG(1) << StringPrintf("GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
- p_ccb->rx_queue_size, *p_len);
+ DVLOG(1) << StringPrintf(
+ "GAP_ConnReadData - rx_queue_size left=%d, *p_len=%d",
+ p_ccb->rx_queue_size, *p_len);
return (BT_PASS);
}
} else
rc = GAP_INVALID_HANDLE;
- DVLOG(1) << StringPrintf("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d", rc,
- *p_rx_queue_count);
+ DVLOG(1) << StringPrintf("GAP_GetRxQueueCnt - rc = 0x%04x, rx_queue_count=%d",
+ rc, *p_rx_queue_count);
return (rc);
}
if ((p_ccb->con_state == GAP_CCB_STATE_CONNECTED) && (sdu_sent == 0xFFFF)) {
DVLOG(1) << StringPrintf("%s: GAP_EVT_TX_EMPTY", __func__);
- p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_TX_EMPTY);
+ p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_TX_EMPTY, nullptr);
}
}
+void gap_credits_received_cb(uint16_t l2cap_cid, uint16_t credits_received,
+ uint16_t credit_count) {
+ tGAP_CCB* p_ccb = gap_find_ccb_by_cid(l2cap_cid);
+ if (!p_ccb) return;
+
+ tGAP_CB_DATA data{.coc_credits = {.credits_received = credits_received,
+ .credit_count = credit_count}};
+ p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_LE_COC_CREDITS, &data);
+}
+
/*******************************************************************************
*
* Function gap_connect_ind
}
DVLOG(1) << StringPrintf("GAP_CONN - Rcvd L2CAP conn ind, CID: 0x%x",
- p_ccb->connection_id);
+ p_ccb->connection_id);
/* Send a Configuration Request. */
if (p_ccb->transport == BT_TRANSPORT_BR_EDR)
if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) {
p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
- p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
+ p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_OPENED, nullptr);
}
}
} else {
/* Tell the user if he has a callback */
if (p_ccb->p_callback)
- (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
+ (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED, nullptr);
gap_release_ccb(p_ccb);
}
gap_checks_con_flags(p_ccb);
} else {
- p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
+ p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED, nullptr);
gap_release_ccb(p_ccb);
}
}
if (ack_needed) L2CA_DISCONNECT_RSP(l2cap_cid);
- p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
+ p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED, nullptr);
gap_release_ccb(p_ccb);
}
p_ccb->rx_queue_size, p_msg->len);
*/
- p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
+ p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL, nullptr);
} else {
osi_free(p_msg);
}
******************************************************************************/
static void gap_congestion_ind(uint16_t lcid, bool is_congested) {
DVLOG(1) << StringPrintf("GAP_CONN - Rcvd L2CAP Is Congested (%d), CID: 0x%x",
- is_congested, lcid);
+ is_congested, lcid);
tGAP_CCB* p_ccb = gap_find_ccb_by_cid(lcid); /* Find CCB based on CID */
if (!p_ccb) return;
p_ccb->is_congested = is_congested;
- p_ccb->p_callback(p_ccb->gap_handle, (is_congested)
- ? GAP_EVT_CONN_CONGESTED
- : GAP_EVT_CONN_UNCONGESTED);
+ p_ccb->p_callback(
+ p_ccb->gap_handle,
+ (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED,
+ nullptr);
gap_try_write_queued_data(p_ccb);
}
if ((p_ccb_local->con_state != GAP_CCB_STATE_IDLE) &&
(p_ccb_local->psm == p_ccb->psm)) {
DVLOG(1) << __func__ << " : " << +p_ccb_local->psm
- << " PSM is still in use, do not deregister";
+ << " PSM is still in use, do not deregister";
return;
}
}
#define GAP_EVT_CONN_CONGESTED 0x0103
#define GAP_EVT_CONN_UNCONGESTED 0x0104
#define GAP_EVT_TX_EMPTY 0x0105
+#define GAP_EVT_LE_COC_CREDITS 0x0106
/* Values for 'chan_mode_mask' field */
/* GAP_ConnOpen() - optional channels to negotiate */
#define GAP_PREFER_CONN_SP_TOUT 2000
#endif
+struct tGAP_COC_CREDITS {
+ uint16_t gap_handle;
+ uint16_t credits_received;
+ uint16_t credit_count;
+};
+
+union tGAP_CB_DATA {
+ tGAP_COC_CREDITS coc_credits;
+};
+
/*****************************************************************************
* Type Definitions
****************************************************************************/
/*
* Callback function for connection services
*/
-typedef void(tGAP_CONN_CALLBACK)(uint16_t gap_handle, uint16_t event);
+typedef void(tGAP_CONN_CALLBACK)(uint16_t gap_handle, uint16_t event,
+ tGAP_CB_DATA* data);
/*
* Define the callback function prototypes. Parameters are specific