Bluetooth: Support the "connectable mode" adv flag
This patch adds support for the "connectable mode" flag of the Add Advertising command. Signed-off-by: Arman Uguray <armansito@chromium.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
4950999621
commit
e7a685d316
|
@ -1013,11 +1013,8 @@ static void update_adv_data_for_instance(struct hci_request *req, u8 instance)
|
||||||
hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
|
hci_req_add(req, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_adv_data(struct hci_request *req)
|
static u8 get_current_adv_instance(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = req->hdev;
|
|
||||||
u8 instance;
|
|
||||||
|
|
||||||
/* The "Set Advertising" setting supersedes the "Add Advertising"
|
/* The "Set Advertising" setting supersedes the "Add Advertising"
|
||||||
* setting. Here we set the advertising data based on which
|
* setting. Here we set the advertising data based on which
|
||||||
* setting was set. When neither apply, default to the global settings,
|
* setting was set. When neither apply, default to the global settings,
|
||||||
|
@ -1025,9 +1022,54 @@ static void update_adv_data(struct hci_request *req)
|
||||||
*/
|
*/
|
||||||
if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
|
if (hci_dev_test_flag(hdev, HCI_ADVERTISING_INSTANCE) &&
|
||||||
!hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
!hci_dev_test_flag(hdev, HCI_ADVERTISING))
|
||||||
instance = 0x01;
|
return 0x01;
|
||||||
else
|
|
||||||
instance = 0x00;
|
return 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_connectable(struct hci_dev *hdev)
|
||||||
|
{
|
||||||
|
struct mgmt_pending_cmd *cmd;
|
||||||
|
|
||||||
|
/* If there's a pending mgmt command the flag will not yet have
|
||||||
|
* it's final value, so check for this first.
|
||||||
|
*/
|
||||||
|
cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
|
||||||
|
if (cmd) {
|
||||||
|
struct mgmt_mode *cp = cmd->param;
|
||||||
|
|
||||||
|
return cp->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
|
||||||
|
{
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
|
if (instance > 0x01)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (instance == 1)
|
||||||
|
return hdev->adv_instance.flags;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
/* For instance 0, assemble the flags from global settings */
|
||||||
|
if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE) ||
|
||||||
|
get_connectable(hdev))
|
||||||
|
flags |= MGMT_ADV_FLAG_CONNECTABLE;
|
||||||
|
|
||||||
|
/* TODO: Add the rest of the flags */
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_adv_data(struct hci_request *req)
|
||||||
|
{
|
||||||
|
struct hci_dev *hdev = req->hdev;
|
||||||
|
u8 instance = get_current_adv_instance(hdev);
|
||||||
|
|
||||||
update_adv_data_for_instance(req, instance);
|
update_adv_data_for_instance(req, instance);
|
||||||
}
|
}
|
||||||
|
@ -1159,22 +1201,6 @@ static void update_class(struct hci_request *req)
|
||||||
hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
|
hci_req_add(req, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_connectable(struct hci_dev *hdev)
|
|
||||||
{
|
|
||||||
struct mgmt_pending_cmd *cmd;
|
|
||||||
|
|
||||||
/* If there's a pending mgmt command the flag will not yet have
|
|
||||||
* it's final value, so check for this first.
|
|
||||||
*/
|
|
||||||
cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
|
|
||||||
if (cmd) {
|
|
||||||
struct mgmt_mode *cp = cmd->param;
|
|
||||||
return cp->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disable_advertising(struct hci_request *req)
|
static void disable_advertising(struct hci_request *req)
|
||||||
{
|
{
|
||||||
u8 enable = 0x00;
|
u8 enable = 0x00;
|
||||||
|
@ -1188,6 +1214,8 @@ static void enable_advertising(struct hci_request *req)
|
||||||
struct hci_cp_le_set_adv_param cp;
|
struct hci_cp_le_set_adv_param cp;
|
||||||
u8 own_addr_type, enable = 0x01;
|
u8 own_addr_type, enable = 0x01;
|
||||||
bool connectable;
|
bool connectable;
|
||||||
|
u8 instance;
|
||||||
|
u32 flags;
|
||||||
|
|
||||||
if (hci_conn_num(hdev, LE_LINK) > 0)
|
if (hci_conn_num(hdev, LE_LINK) > 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1202,10 +1230,9 @@ static void enable_advertising(struct hci_request *req)
|
||||||
*/
|
*/
|
||||||
hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
hci_dev_clear_flag(hdev, HCI_LE_ADV);
|
||||||
|
|
||||||
if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
|
instance = get_current_adv_instance(hdev);
|
||||||
connectable = true;
|
flags = get_adv_instance_flags(hdev, instance);
|
||||||
else
|
connectable = (flags & MGMT_ADV_FLAG_CONNECTABLE);
|
||||||
connectable = get_connectable(hdev);
|
|
||||||
|
|
||||||
/* Set require_privacy to true only when non-connectable
|
/* Set require_privacy to true only when non-connectable
|
||||||
* advertising is used. In that case it is fine to use a
|
* advertising is used. In that case it is fine to use a
|
||||||
|
@ -6623,10 +6650,8 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
|
||||||
flags = __le32_to_cpu(cp->flags);
|
flags = __le32_to_cpu(cp->flags);
|
||||||
timeout = __le16_to_cpu(cp->timeout);
|
timeout = __le16_to_cpu(cp->timeout);
|
||||||
|
|
||||||
/* The current implementation only supports adding one instance and
|
/* The current implementation only supports adding one instance */
|
||||||
* doesn't support flags.
|
if (cp->instance != 0x01)
|
||||||
*/
|
|
||||||
if (cp->instance != 0x01 || flags)
|
|
||||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
|
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
|
||||||
MGMT_STATUS_INVALID_PARAMS);
|
MGMT_STATUS_INVALID_PARAMS);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue