void avct_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
void avct_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested);
void avct_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
+static void avct_on_l2cap_error(uint16_t lcid, uint16_t result);
/* L2CAP callback function structure */
-const tL2CAP_APPL_INFO avct_l2c_appl = {avct_l2c_connect_ind_cback,
- avct_l2c_connect_cfm_cback,
- avct_l2c_config_ind_cback,
- avct_l2c_config_cfm_cback,
- avct_l2c_disconnect_ind_cback,
- avct_l2c_data_ind_cback,
- avct_l2c_congestion_ind_cback,
- NULL,
- /* tL2CA_TX_COMPLETE_CB */};
+const tL2CAP_APPL_INFO avct_l2c_appl = {
+ avct_l2c_connect_ind_cback, avct_l2c_connect_cfm_cback,
+ avct_l2c_config_ind_cback, avct_l2c_config_cfm_cback,
+ avct_l2c_disconnect_ind_cback, avct_l2c_data_ind_cback,
+ avct_l2c_congestion_ind_cback, NULL,
+ avct_on_l2cap_error,
+};
/*******************************************************************************
*
void avct_l2c_br_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
void avct_l2c_br_congestion_ind_cback(uint16_t lcid, bool is_congested);
void avct_l2c_br_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
+void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result);
/* L2CAP callback function structure */
-const tL2CAP_APPL_INFO avct_l2c_br_appl = {avct_l2c_br_connect_ind_cback,
- avct_l2c_br_connect_cfm_cback,
- avct_l2c_br_config_ind_cback,
- avct_l2c_br_config_cfm_cback,
- avct_l2c_br_disconnect_ind_cback,
- avct_l2c_br_data_ind_cback,
- avct_l2c_br_congestion_ind_cback,
- NULL,
- /* tL2CA_TX_COMPLETE_CB */};
+const tL2CAP_APPL_INFO avct_l2c_br_appl = {
+ avct_l2c_br_connect_ind_cback, avct_l2c_br_connect_cfm_cback,
+ avct_l2c_br_config_ind_cback, avct_l2c_br_config_cfm_cback,
+ avct_l2c_br_disconnect_ind_cback, avct_l2c_br_data_ind_cback,
+ avct_l2c_br_congestion_ind_cback, NULL,
+ avct_br_on_l2cap_error,
+};
/*******************************************************************************
*
void avdt_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
void avdt_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested);
void avdt_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
+static void avdt_on_l2cap_error(uint16_t lcid, uint16_t result);
/* L2CAP callback function structure */
-const tL2CAP_APPL_INFO avdt_l2c_appl = {avdt_l2c_connect_ind_cback,
- avdt_l2c_connect_cfm_cback,
- avdt_l2c_config_ind_cback,
- avdt_l2c_config_cfm_cback,
- avdt_l2c_disconnect_ind_cback,
- avdt_l2c_data_ind_cback,
- avdt_l2c_congestion_ind_cback,
- NULL,
- /* tL2CA_TX_COMPLETE_CB */};
+const tL2CAP_APPL_INFO avdt_l2c_appl = {
+ avdt_l2c_connect_ind_cback, avdt_l2c_connect_cfm_cback,
+ avdt_l2c_config_ind_cback, avdt_l2c_config_cfm_cback,
+ avdt_l2c_disconnect_ind_cback, avdt_l2c_data_ind_cback,
+ avdt_l2c_congestion_ind_cback, NULL,
+ avdt_on_l2cap_error,
+};
/*******************************************************************************
*
static void bnep_disconnect_ind(uint16_t l2cap_cid, bool ack_needed);
static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg);
static void bnep_congestion_ind(uint16_t lcid, bool is_congested);
-
+static void bnep_on_l2cap_error(uint16_t l2cap_cid, uint16_t result);
/*******************************************************************************
*
* Function bnep_register_with_l2cap
bnep_cb.reg_info.pL2CA_DisconnectInd_Cb = bnep_disconnect_ind;
bnep_cb.reg_info.pL2CA_DataInd_Cb = bnep_data_ind;
bnep_cb.reg_info.pL2CA_CongestionStatus_Cb = bnep_congestion_ind;
+ bnep_cb.reg_info.pL2CA_Error_Cb = bnep_on_l2cap_error;
/* Now, register with L2CAP */
if (!L2CA_Register2(BT_PSM_BNEP, bnep_cb.reg_info, false /* enable_snoop */,
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_on_l2cap_error(uint16_t l2cap_cid, uint16_t result);
static tGAP_CCB* gap_find_ccb_by_cid(uint16_t cid);
static tGAP_CCB* gap_find_ccb_by_handle(uint16_t handle);
static tGAP_CCB* gap_allocate_ccb(void);
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_Error_Cb = gap_on_l2cap_error;
}
/*******************************************************************************
static void gatt_l2cif_data_ind_cback(uint16_t l2cap_cid, BT_HDR* p_msg);
static void gatt_send_conn_cback(tGATT_TCB* p_tcb);
static void gatt_l2cif_congest_cback(uint16_t cid, bool congested);
-
-static const tL2CAP_APPL_INFO dyn_info = {gatt_l2cif_connect_ind_cback,
- gatt_l2cif_connect_cfm_cback,
- gatt_l2cif_config_ind_cback,
- gatt_l2cif_config_cfm_cback,
- gatt_l2cif_disconnect_ind_cback,
- gatt_l2cif_data_ind_cback,
- gatt_l2cif_congest_cback,
- NULL};
+static void gatt_on_l2cap_error(uint16_t lcid, uint16_t result);
+
+static const tL2CAP_APPL_INFO dyn_info = {
+ gatt_l2cif_connect_ind_cback,
+ gatt_l2cif_connect_cfm_cback,
+ gatt_l2cif_config_ind_cback,
+ gatt_l2cif_config_cfm_cback,
+ gatt_l2cif_disconnect_ind_cback,
+ gatt_l2cif_data_ind_cback,
+ gatt_l2cif_congest_cback,
+ NULL,
+ gatt_on_l2cap_error,
+};
tGATT_CB gatt_cb;
static void hidd_l2cif_disconnect(uint16_t cid);
static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg);
static void hidd_l2cif_cong_ind(uint16_t cid, bool congested);
-
+static void hidd_on_l2cap_error(uint16_t lcid, uint16_t result);
static const tL2CAP_APPL_INFO dev_reg_info = {
hidd_l2cif_connect_ind, hidd_l2cif_connect_cfm,
hidd_l2cif_config_ind, hidd_l2cif_config_cfm,
hidd_l2cif_disconnect_ind, hidd_l2cif_data_ind,
- hidd_l2cif_cong_ind, NULL};
+ hidd_l2cif_cong_ind, NULL,
+ hidd_on_l2cap_error,
+};
/*******************************************************************************
*
static void hidh_l2cif_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg);
static void hidh_l2cif_disconnect(uint16_t l2cap_cid);
static void hidh_l2cif_cong_ind(uint16_t l2cap_cid, bool congested);
+static void hidh_on_l2cap_error(uint16_t l2cap_cid, uint16_t result);
static const tL2CAP_APPL_INFO hst_reg_info = {
hidh_l2cif_connect_ind, hidh_l2cif_connect_cfm,
hidh_l2cif_config_ind, hidh_l2cif_config_cfm,
hidh_l2cif_disconnect_ind, hidh_l2cif_data_ind,
hidh_l2cif_cong_ind, NULL,
- /* tL2CA_TX_COMPLETE_CB */};
+ hidh_on_l2cap_error,
+};
/*******************************************************************************
*
/* Connection confirmation callback prototype. Parameters are
* Local CID
- * Result - 0 = connected, non-zero means failure reason
+ * Result - 0 = connected
+ * If there is an error, tL2CA_ERROR_CB is invoked
*/
typedef void(tL2CA_CONNECT_CFM_CB)(uint16_t, uint16_t);
/* Configuration confirm callback prototype. Parameters are
* Local CID assigned to the connection
- * Config result (L2CA_CONN_OK, ...)
+ * Config result (L2CA_CONN_OK)
+ * If there is an error, tL2CA_ERROR_CB is invoked
*/
typedef void(tL2CA_CONFIG_CFM_CB)(uint16_t, uint16_t);
*/
typedef void(tL2CA_TX_COMPLETE_CB)(uint16_t, uint16_t);
+/*
+ * Notify the user when the remote send error result on ConnectRsp or ConfigRsp
+ * The parameters are:
+ * Local CID
+ * Error type (L2CAP_CONN_OTHER_ERROR for ConnectRsp,
+ * L2CAP_CFG_FAILED_NO_REASON for ConfigRsp)
+ */
+typedef void(tL2CA_ERROR_CB)(uint16_t, uint16_t);
+
/* Define the structure that applications use to register with
* L2CAP. This structure includes callback functions. All functions
* MUST be provided, with the exception of the "connect pending"
tL2CA_DATA_IND_CB* pL2CA_DataInd_Cb;
tL2CA_CONGESTION_STATUS_CB* pL2CA_CongestionStatus_Cb;
tL2CA_TX_COMPLETE_CB* pL2CA_TxComplete_Cb;
+ tL2CA_ERROR_CB* pL2CA_Error_Cb;
} tL2CAP_APPL_INFO;
/* Define the structure that applications use to create or accept
#define L2CAP_CONN_NO_PSM 2
#define L2CAP_CONN_SECURITY_BLOCK 3
#define L2CAP_CONN_NO_RESOURCES 4
+#define L2CAP_CONN_OTHER_ERROR 5
#define L2CAP_CONN_TIMEOUT 0xEEEE
/* Add a couple of our own for internal use */
#define L2CAP_CONN_NO_LINK 255
#define L2CAP_CFG_UNKNOWN_OPTIONS 3
#define L2CAP_CFG_PENDING 4
+static_assert(L2CAP_CONN_OTHER_ERROR != L2CAP_CFG_FAILED_NO_REASON,
+ "Different error code should be provided for Connect error and "
+ "Config error");
+
/* Define the L2CAP configuration option types
*/
#define L2CAP_CFG_TYPE_MTU 0x01
p_l2c->pL2CA_DataInd_Cb = RFCOMM_BufDataInd;
p_l2c->pL2CA_CongestionStatus_Cb = RFCOMM_CongestionStatusInd;
p_l2c->pL2CA_TxComplete_Cb = NULL;
+ p_l2c->pL2CA_Error_Cb = rfc_on_l2cap_error;
L2CA_Register(BT_PSM_RFCOMM, rfc_cb.rfc.reg_info, true /* enable_snoop */,
nullptr, L2CAP_MTU_SIZE, 0);
static void sdp_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg);
static void sdp_connect_cfm(uint16_t l2cap_cid, uint16_t result);
+static void sdp_on_l2cap_error(uint16_t l2cap_cid, uint16_t result);
/*******************************************************************************
*
sdp_cb.reg_info.pL2CA_ConfigCfm_Cb = sdp_config_cfm;
sdp_cb.reg_info.pL2CA_DisconnectInd_Cb = sdp_disconnect_ind;
sdp_cb.reg_info.pL2CA_DataInd_Cb = sdp_data_ind;
+ sdp_cb.reg_info.pL2CA_Error_Cb = sdp_on_l2cap_error;
/* Now, register with L2CAP */
if (!L2CA_Register2(SDP_PSM, sdp_cb.reg_info, true /* enable_snoop */,