Bluetooth: Connection Parameter Update Procedure
This patch adds support for LE Connection Parameters Request Link Layer control procedure introduced in Core spec 4.1. This procedure allows a Peripheral or Central to update the Link Layer connection parameters of an established connection. Regarding the acceptance of connection parameters, the LL procedure follows the same approach of L2CAP procedure (see l2cap_conn_param_ update_req function). We accept any connection parameters values as long as they are within the valid range. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:

committed by
Marcel Holtmann

parent
396e04f4bb
commit
8e75b46a4f
@@ -4382,6 +4382,52 @@ not_found:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
|
||||
u8 reason)
|
||||
{
|
||||
struct hci_cp_le_conn_param_req_neg_reply cp;
|
||||
|
||||
cp.handle = cpu_to_le16(handle);
|
||||
cp.reason = reason;
|
||||
|
||||
hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, sizeof(cp),
|
||||
&cp);
|
||||
}
|
||||
|
||||
static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct hci_ev_le_remote_conn_param_req *ev = (void *) skb->data;
|
||||
struct hci_cp_le_conn_param_req_reply cp;
|
||||
struct hci_conn *hcon;
|
||||
u16 handle, min, max, latency, timeout;
|
||||
|
||||
handle = le16_to_cpu(ev->handle);
|
||||
min = le16_to_cpu(ev->interval_min);
|
||||
max = le16_to_cpu(ev->interval_max);
|
||||
latency = le16_to_cpu(ev->latency);
|
||||
timeout = le16_to_cpu(ev->timeout);
|
||||
|
||||
hcon = hci_conn_hash_lookup_handle(hdev, handle);
|
||||
if (!hcon || hcon->state != BT_CONNECTED)
|
||||
return send_conn_param_neg_reply(hdev, handle,
|
||||
HCI_ERROR_UNKNOWN_CONN_ID);
|
||||
|
||||
if (hci_check_conn_params(min, max, latency, timeout))
|
||||
return send_conn_param_neg_reply(hdev, handle,
|
||||
HCI_ERROR_INVALID_LL_PARAMS);
|
||||
|
||||
cp.handle = ev->handle;
|
||||
cp.interval_min = ev->interval_min;
|
||||
cp.interval_max = ev->interval_max;
|
||||
cp.latency = ev->latency;
|
||||
cp.timeout = ev->timeout;
|
||||
cp.min_ce_len = 0;
|
||||
cp.max_ce_len = 0;
|
||||
|
||||
hci_send_cmd(hdev, HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(cp), &cp);
|
||||
}
|
||||
|
||||
static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_ev_le_meta *le_ev = (void *) skb->data;
|
||||
@@ -4405,6 +4451,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
hci_le_ltk_request_evt(hdev, skb);
|
||||
break;
|
||||
|
||||
case HCI_EV_LE_REMOTE_CONN_PARAM_REQ:
|
||||
hci_le_remote_conn_param_req_evt(hdev, skb);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user