Diff between 05f3aab743f097d1f8f10de77201e579e29d110a and 3e17f888c840270472ec618b3c3b27472288669c

Changed Files

File Additions Deletions Status
emulator/bthost.c +32 -0 modified

Full Patch

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 9302333..b00f8f2 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -184,6 +184,8 @@ struct l2conn {
 	uint16_t scid;
 	uint16_t dcid;
 	uint16_t psm;
+	uint16_t rx_credits;
+	uint16_t tx_credits;
 	enum l2cap_mode mode;
 	uint16_t data_len;
 	uint16_t recv_len;
@@ -2459,6 +2461,8 @@ static bool l2cap_le_conn_req(struct bthost *bthost, struct btconn *conn,
 							le16_to_cpu(req->scid),
 							le16_to_cpu(psm));
 		l2conn->mode = L2CAP_MODE_LE_CRED;
+		l2conn->rx_credits = le16_to_cpu(rsp.credits);
+		l2conn->tx_credits = le16_to_cpu(req->credits);
 
 		if (cb_data && l2conn->psm == cb_data->psm && cb_data->func)
 			cb_data->func(conn->handle, l2conn->dcid,
@@ -2476,10 +2480,13 @@ static bool l2cap_le_conn_rsp(struct bthost *bthost, struct btconn *conn,
 
 	if (len < sizeof(*rsp))
 		return false;
+
 	/* TODO add L2CAP connection before with proper PSM */
 	l2conn = bthost_add_l2cap_conn(bthost, conn, 0,
 						le16_to_cpu(rsp->dcid), 0);
 	l2conn->mode = L2CAP_MODE_LE_CRED;
+	l2conn->rx_credits = 1;
+	l2conn->tx_credits = le16_to_cpu(rsp->credits);
 
 	return true;
 }
@@ -2544,12 +2551,32 @@ static bool l2cap_ecred_conn_rsp(struct bthost *bthost, struct btconn *conn,
 		l2conn = bthost_add_l2cap_conn(bthost, conn, 0,
 				      le16_to_cpu(rsp->scid[i]), 0);
 		l2conn->mode = L2CAP_MODE_LE_ENH_CRED;
+		l2conn->tx_credits = rsp->pdu->credits;
+		l2conn->rx_credits = 1;
 	}
 
 
 	return true;
 }
 
+static bool l2cap_le_flowctl_creds(struct bthost *bthost, struct btconn *conn,
+				uint8_t ident, const void *data, uint16_t len)
+{
+	const struct bt_l2cap_pdu_le_flowctl_creds *ind = data;
+	struct l2conn *l2conn;
+
+	if (len < sizeof(*ind))
+		return false;
+
+	l2conn = btconn_find_l2cap_conn_by_dcid(conn, ind->cid);
+	if (!l2conn)
+		return true;
+
+	l2conn->tx_credits += ind->credits;
+
+	return true;
+}
+
 static bool l2cap_le_rsp(uint8_t code)
 {
 	switch (code) {
@@ -2624,6 +2651,11 @@ static void l2cap_le_sig(struct bthost *bthost, struct btconn *conn,
 						data + sizeof(*hdr), hdr_len);
 		break;
 
+	case BT_L2CAP_PDU_LE_FLOWCTL_CREDS:
+		ret = l2cap_le_flowctl_creds(bthost, conn, hdr->ident,
+						data + sizeof(*hdr), hdr_len);
+		break;
+
 	default:
 		bthost_debug(bthost, "Unknown L2CAP code 0x%02x", hdr->code);
 		ret = false;