|
@@ -3104,6 +3104,45 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
|
|
|
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
|
|
|
+ void *data)
|
|
|
+{
|
|
|
+ struct l2cap_create_chan_req *req = data;
|
|
|
+ struct l2cap_create_chan_rsp rsp;
|
|
|
+ u16 psm, scid;
|
|
|
+
|
|
|
+ if (cmd_len != sizeof(*req))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ if (!enable_hs)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ psm = le16_to_cpu(req->psm);
|
|
|
+ scid = le16_to_cpu(req->scid);
|
|
|
+
|
|
|
+ BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id);
|
|
|
+
|
|
|
+ /* Placeholder: Always reject */
|
|
|
+ rsp.dcid = 0;
|
|
|
+ rsp.scid = cpu_to_le16(scid);
|
|
|
+ rsp.result = L2CAP_CR_NO_MEM;
|
|
|
+ rsp.status = L2CAP_CS_NO_INFO;
|
|
|
+
|
|
|
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
|
|
|
+ sizeof(rsp), &rsp);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
|
|
|
+ struct l2cap_cmd_hdr *cmd, void *data)
|
|
|
+{
|
|
|
+ BT_DBG("conn %p", conn);
|
|
|
+
|
|
|
+ return l2cap_connect_rsp(conn, cmd, data);
|
|
|
+}
|
|
|
+
|
|
|
static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency,
|
|
|
u16 to_multiplier)
|
|
|
{
|
|
@@ -3216,6 +3255,14 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
|
|
|
err = l2cap_information_rsp(conn, cmd, data);
|
|
|
break;
|
|
|
|
|
|
+ case L2CAP_CREATE_CHAN_REQ:
|
|
|
+ err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case L2CAP_CREATE_CHAN_RSP:
|
|
|
+ err = l2cap_create_channel_rsp(conn, cmd, data);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
|
|
|
err = -EINVAL;
|