Skip to content

Commit c4960ec

Browse files
Michał Narajowskiholtmann
authored andcommitted
Bluetooth: Add support for appearance in scan rsp
This patch enables prepending appearance value to scan response data. It also adds support for setting appearance value through mgmt command. If currently advertised instance has apperance flag set it is expired immediately. Signed-off-by: Michał Narajowski <[email protected]> Signed-off-by: Szymon Janc <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 7c295c4 commit c4960ec

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ struct hci_dev {
211211
__u8 dev_name[HCI_MAX_NAME_LENGTH];
212212
__u8 short_name[HCI_MAX_SHORT_NAME_LENGTH];
213213
__u8 eir[HCI_MAX_EIR_LENGTH];
214+
__u16 appearance;
214215
__u8 dev_class[3];
215216
__u8 major_class;
216217
__u8 minor_class;

include/net/bluetooth/mgmt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,12 @@ struct mgmt_rp_read_ext_info {
598598
__u8 eir[0];
599599
} __packed;
600600

601+
#define MGMT_OP_SET_APPEARANCE 0x0043
602+
struct mgmt_cp_set_appearance {
603+
__u16 appearance;
604+
} __packed;
605+
#define MGMT_SET_APPEARANCE_SIZE 2
606+
601607
#define MGMT_EV_CMD_COMPLETE 0x0001
602608
struct mgmt_ev_cmd_complete {
603609
__le16 opcode;

net/bluetooth/hci_request.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,14 @@ static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
10151015

10161016
instance_flags = adv_instance->flags;
10171017

1018+
if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) {
1019+
ptr[0] = 3;
1020+
ptr[1] = EIR_APPEARANCE;
1021+
put_unaligned_le16(hdev->appearance, ptr + 2);
1022+
scan_rsp_len += 4;
1023+
ptr += 4;
1024+
}
1025+
10181026
memcpy(ptr, adv_instance->scan_rsp_data,
10191027
adv_instance->scan_rsp_len);
10201028

net/bluetooth/mgmt.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static const u16 mgmt_commands[] = {
105105
MGMT_OP_GET_ADV_SIZE_INFO,
106106
MGMT_OP_START_LIMITED_DISCOVERY,
107107
MGMT_OP_READ_EXT_INFO,
108+
MGMT_OP_SET_APPEARANCE,
108109
};
109110

110111
static const u16 mgmt_events[] = {
@@ -3143,6 +3144,34 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
31433144
return err;
31443145
}
31453146

3147+
static int set_appearance(struct sock *sk, struct hci_dev *hdev, void *data,
3148+
u16 len)
3149+
{
3150+
struct mgmt_cp_set_appearance *cp = data;
3151+
u16 apperance;
3152+
int err;
3153+
3154+
BT_DBG("");
3155+
3156+
apperance = le16_to_cpu(cp->appearance);
3157+
3158+
hci_dev_lock(hdev);
3159+
3160+
if (hdev->appearance != apperance) {
3161+
hdev->appearance = apperance;
3162+
3163+
if (hci_dev_test_flag(hdev, HCI_LE_ADV))
3164+
adv_expire(hdev, MGMT_ADV_FLAG_APPEARANCE);
3165+
}
3166+
3167+
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_APPEARANCE, 0, NULL,
3168+
0);
3169+
3170+
hci_dev_unlock(hdev);
3171+
3172+
return err;
3173+
}
3174+
31463175
static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
31473176
u16 opcode, struct sk_buff *skb)
31483177
{
@@ -5918,6 +5947,7 @@ static u32 get_supported_adv_flags(struct hci_dev *hdev)
59185947
flags |= MGMT_ADV_FLAG_DISCOV;
59195948
flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
59205949
flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
5950+
flags |= MGMT_ADV_FLAG_APPEARANCE;
59215951
flags |= MGMT_ADV_FLAG_LOCAL_NAME;
59225952

59235953
if (hdev->adv_tx_power != HCI_TX_POWER_INVALID)
@@ -5999,6 +6029,9 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
59996029
/* at least 1 byte of name should fit in */
60006030
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
60016031
max_len -= 3;
6032+
6033+
if (adv_flags & MGMT_ADV_FLAG_APPEARANCE)
6034+
max_len -= 4;
60026035
}
60036036

60046037
if (len > max_len)
@@ -6335,6 +6368,9 @@ static u8 tlv_data_max_len(u32 adv_flags, bool is_adv_data)
63356368
/* at least 1 byte of name should fit in */
63366369
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
63376370
max_len -= 3;
6371+
6372+
if (adv_flags & (MGMT_ADV_FLAG_APPEARANCE))
6373+
max_len -= 4;
63386374
}
63396375

63406376
return max_len;
@@ -6470,6 +6506,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
64706506
{ start_limited_discovery, MGMT_START_DISCOVERY_SIZE },
64716507
{ read_ext_controller_info,MGMT_READ_EXT_INFO_SIZE,
64726508
HCI_MGMT_UNTRUSTED },
6509+
{ set_appearance, MGMT_SET_APPEARANCE_SIZE },
64736510
};
64746511

64756512
void mgmt_index_added(struct hci_dev *hdev)

0 commit comments

Comments
 (0)