提交 1987fdc7 编写于 作者: J Johan Hedberg 提交者: Marcel Holtmann

Bluetooth: Make Set Connectable also update the LE advertising type

This patch updates the Set Connectable Management command to also update
the LE advertising type to either connectable or non-connectable
advertising. An extra helper function is needed for getting the right
advertising type since we can not only rely on the HCI_CONNECTABLE flag
but must also check for a pending Set Connectable command (in which case
the flag does not yet have its final value).
Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
上级 c6d887aa
...@@ -1072,6 +1072,25 @@ static void write_fast_connectable(struct hci_request *req, bool enable) ...@@ -1072,6 +1072,25 @@ static void write_fast_connectable(struct hci_request *req, bool enable)
hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type); hci_req_add(req, HCI_OP_WRITE_PAGE_SCAN_TYPE, 1, &type);
} }
static u8 get_adv_type(struct hci_dev *hdev)
{
struct pending_cmd *cmd;
bool connectable;
/* If there's a pending mgmt command the flag will not yet have
* it's final value, so check for this first.
*/
cmd = mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
if (cmd) {
struct mgmt_mode *cp = cmd->param;
connectable = !!cp->val;
} else {
connectable = test_bit(HCI_CONNECTABLE, &hdev->dev_flags);
}
return connectable ? LE_ADV_IND : LE_ADV_NONCONN_IND;
}
static void enable_advertising(struct hci_request *req) static void enable_advertising(struct hci_request *req)
{ {
struct hci_dev *hdev = req->hdev; struct hci_dev *hdev = req->hdev;
...@@ -1081,7 +1100,7 @@ static void enable_advertising(struct hci_request *req) ...@@ -1081,7 +1100,7 @@ static void enable_advertising(struct hci_request *req)
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
cp.min_interval = __constant_cpu_to_le16(0x0800); cp.min_interval = __constant_cpu_to_le16(0x0800);
cp.max_interval = __constant_cpu_to_le16(0x0800); cp.max_interval = __constant_cpu_to_le16(0x0800);
cp.type = LE_ADV_IND; cp.type = get_adv_type(hdev);
if (bacmp(&hdev->bdaddr, BDADDR_ANY)) if (bacmp(&hdev->bdaddr, BDADDR_ANY))
cp.own_address_type = ADDR_LE_DEV_PUBLIC; cp.own_address_type = ADDR_LE_DEV_PUBLIC;
else else
...@@ -1144,15 +1163,15 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -1144,15 +1163,15 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
struct mgmt_mode *cp = data; struct mgmt_mode *cp = data;
struct pending_cmd *cmd; struct pending_cmd *cmd;
struct hci_request req; struct hci_request req;
u8 scan, status; u8 scan;
int err; int err;
BT_DBG("request for %s", hdev->name); BT_DBG("request for %s", hdev->name);
status = mgmt_bredr_support(hdev); if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags) &&
if (status) !test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags))
return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
status); MGMT_STATUS_REJECTED);
if (cp->val != 0x00 && cp->val != 0x01) if (cp->val != 0x00 && cp->val != 0x01)
return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE,
...@@ -1223,6 +1242,12 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -1223,6 +1242,12 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
if (cp->val || test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags)) if (cp->val || test_bit(HCI_FAST_CONNECTABLE, &hdev->dev_flags))
write_fast_connectable(&req, false); write_fast_connectable(&req, false);
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags) &&
hci_conn_num(hdev, LE_LINK) == 0) {
disable_advertising(&req);
enable_advertising(&req);
}
err = hci_req_run(&req, set_connectable_complete); err = hci_req_run(&req, set_connectable_complete);
if (err < 0) { if (err < 0) {
mgmt_pending_remove(cmd); mgmt_pending_remove(cmd);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册