提交 de73115a 编写于 作者: C Claudio Takahasi 提交者: Gustavo F. Padovan

Bluetooth: Add connection parameter update response

Implements L2CAP Connection Parameter Update Response defined in
the Bluetooth Core Specification, Volume 3, Part A, section 4.21.
Address the LE Connection Parameter Procedure initiated by the slave.

Connection Interval Minimum and Maximum have the same range: 6 to
3200. Time = N * 1.25ms. Minimum shall be less or equal to Maximum.
The Slave Latency field shall have a value in the range of 0 to
((connSupervisionTimeout / connIntervalMax) - 1). Latency field shall
be less than 500. connSupervisionTimeout = Timeout Multiplier * 10 ms.
Multiplier field shall have a value in the range of 10 to 3200.
Signed-off-by: NClaudio Takahasi <claudio.takahasi@openbossa.org>
Signed-off-by: NGustavo F. Padovan <padovan@profusion.mobi>
上级 3300d9a9
...@@ -261,6 +261,21 @@ struct l2cap_info_rsp { ...@@ -261,6 +261,21 @@ struct l2cap_info_rsp {
#define L2CAP_IR_SUCCESS 0x0000 #define L2CAP_IR_SUCCESS 0x0000
#define L2CAP_IR_NOTSUPP 0x0001 #define L2CAP_IR_NOTSUPP 0x0001
struct l2cap_conn_param_update_req {
__le16 min;
__le16 max;
__le16 latency;
__le16 to_multiplier;
} __packed;
struct l2cap_conn_param_update_rsp {
__le16 result;
} __packed;
/* Connection Parameters result */
#define L2CAP_CONN_PARAM_ACCEPTED 0x0000
#define L2CAP_CONN_PARAM_REJECTED 0x0001
/* ----- L2CAP connections ----- */ /* ----- L2CAP connections ----- */
struct l2cap_chan_list { struct l2cap_chan_list {
struct sock *head; struct sock *head;
......
...@@ -2501,6 +2501,63 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm ...@@ -2501,6 +2501,63 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
return 0; return 0;
} }
static int inline l2cap_check_conn_param(u16 min, u16 max, u16 latency,
u16 to_multiplier)
{
u16 max_latency;
if (min > max || min < 6 || max > 3200)
return -EINVAL;
if (to_multiplier < 10 || to_multiplier > 3200)
return -EINVAL;
if (max >= to_multiplier * 8)
return -EINVAL;
max_latency = (to_multiplier * 8 / max) - 1;
if (latency > 499 || latency > max_latency)
return -EINVAL;
return 0;
}
static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u8 *data)
{
struct hci_conn *hcon = conn->hcon;
struct l2cap_conn_param_update_req *req;
struct l2cap_conn_param_update_rsp rsp;
u16 min, max, latency, to_multiplier, cmd_len;
if (!(hcon->link_mode & HCI_LM_MASTER))
return -EINVAL;
cmd_len = __le16_to_cpu(cmd->len);
if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
return -EPROTO;
req = (struct l2cap_conn_param_update_req *) data;
min = __le16_to_cpu(req->min);
max = __le16_to_cpu(req->max);
latency = __le16_to_cpu(req->latency);
to_multiplier = __le16_to_cpu(req->to_multiplier);
BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
min, max, latency, to_multiplier);
memset(&rsp, 0, sizeof(rsp));
if (l2cap_check_conn_param(min, max, latency, to_multiplier))
rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
else
rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
sizeof(rsp), &rsp);
return 0;
}
static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{ {
...@@ -2567,7 +2624,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, ...@@ -2567,7 +2624,7 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
return 0; return 0;
case L2CAP_CONN_PARAM_UPDATE_REQ: case L2CAP_CONN_PARAM_UPDATE_REQ:
return -EINVAL; return l2cap_conn_param_update_req(conn, cmd, data);
case L2CAP_CONN_PARAM_UPDATE_RSP: case L2CAP_CONN_PARAM_UPDATE_RSP:
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册