Skip to content

Commit b338d91

Browse files
bgixVudentz
authored andcommitted
Bluetooth: Implement support for Mesh
The patch adds state bits, storage and HCI command chains for sending and receiving Bluetooth Mesh advertising packets, and delivery to requesting user space processes. It specifically creates 4 new MGMT commands and 2 new MGMT events: MGMT_OP_SET_MESH_RECEIVER - Sets passive scan parameters and a list of AD Types which will trigger Mesh Packet Received events MGMT_OP_MESH_READ_FEATURES - Returns information on how many outbound Mesh packets can be simultaneously queued, and what the currently queued handles are. MGMT_OP_MESH_SEND - Command to queue a specific outbound Mesh packet, with the number of times it should be sent, and the BD Addr to use. Discrete advertisments are added to the ADV Instance list. MGMT_OP_MESH_SEND_CANCEL - Command to cancel a prior outbound message request. MGMT_EV_MESH_DEVICE_FOUND - Event to deliver entire received Mesh Advertisement packet, along with timing information. MGMT_EV_MESH_PACKET_CMPLT - Event to indicate that an outbound packet is no longer queued for delivery. Signed-off-by: Brian Gix <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent fd3f106 commit b338d91

File tree

11 files changed

+760
-46
lines changed

11 files changed

+760
-46
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ static inline bool iso_enabled(void)
627627

628628
int mgmt_init(void);
629629
void mgmt_exit(void);
630+
void mgmt_cleanup(struct sock *sk);
630631

631632
void bt_sock_reclassify_lock(struct sock *sk, int proto);
632633

include/net/bluetooth/hci.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ enum {
354354
HCI_LE_SIMULTANEOUS_ROLES,
355355
HCI_CMD_DRAIN_WORKQUEUE,
356356

357+
HCI_MESH,
358+
HCI_MESH_SENDING,
359+
357360
__HCI_NUM_FLAGS,
358361
};
359362

include/net/bluetooth/hci_core.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ struct adv_info {
238238
bool enabled;
239239
bool pending;
240240
bool periodic;
241+
__u8 mesh;
241242
__u8 instance;
242243
__u32 flags;
243244
__u16 timeout;
@@ -372,6 +373,8 @@ struct hci_dev {
372373
__u8 le_resolv_list_size;
373374
__u8 le_num_of_adv_sets;
374375
__u8 le_states[8];
376+
__u8 mesh_ad_types[16];
377+
__u8 mesh_send_ref;
375378
__u8 commands[64];
376379
__u8 hci_ver;
377380
__u16 hci_rev;
@@ -511,6 +514,7 @@ struct hci_dev {
511514
struct list_head cmd_sync_work_list;
512515
struct mutex cmd_sync_work_lock;
513516
struct work_struct cmd_sync_cancel_work;
517+
struct work_struct reenable_adv_work;
514518

515519
__u16 discov_timeout;
516520
struct delayed_work discov_off;
@@ -561,6 +565,7 @@ struct hci_dev {
561565

562566
struct hci_conn_hash conn_hash;
563567

568+
struct list_head mesh_pending;
564569
struct list_head mgmt_pending;
565570
struct list_head reject_list;
566571
struct list_head accept_list;
@@ -614,6 +619,8 @@ struct hci_dev {
614619
struct delayed_work rpa_expired;
615620
bdaddr_t rpa;
616621

622+
struct delayed_work mesh_send_done;
623+
617624
enum {
618625
INTERLEAVE_SCAN_NONE,
619626
INTERLEAVE_SCAN_NO_FILTER,
@@ -1576,7 +1583,8 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
15761583
u32 flags, u16 adv_data_len, u8 *adv_data,
15771584
u16 scan_rsp_len, u8 *scan_rsp_data,
15781585
u16 timeout, u16 duration, s8 tx_power,
1579-
u32 min_interval, u32 max_interval);
1586+
u32 min_interval, u32 max_interval,
1587+
u8 mesh_handle);
15801588
struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
15811589
u32 flags, u8 data_len, u8 *data,
15821590
u32 min_interval, u32 max_interval);
@@ -1997,6 +2005,9 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
19972005
#define DISCOV_LE_FAST_ADV_INT_MAX 0x00F0 /* 150 msec */
19982006
#define DISCOV_LE_PER_ADV_INT_MIN 0x00A0 /* 200 msec */
19992007
#define DISCOV_LE_PER_ADV_INT_MAX 0x00A0 /* 200 msec */
2008+
#define DISCOV_LE_ADV_MESH_MIN 0x00A0 /* 100 msec */
2009+
#define DISCOV_LE_ADV_MESH_MAX 0x00A0 /* 100 msec */
2010+
#define INTERVAL_TO_MS(x) (((x) * 10) / 0x10)
20002011

20012012
#define NAME_RESOLVE_DURATION msecs_to_jiffies(10240) /* 10.24 sec */
20022013

@@ -2048,7 +2059,8 @@ void mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status);
20482059
void mgmt_stop_discovery_complete(struct hci_dev *hdev, u8 status);
20492060
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
20502061
u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
2051-
u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len);
2062+
u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len,
2063+
u64 instant);
20522064
void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
20532065
u8 addr_type, s8 rssi, u8 *name, u8 name_len);
20542066
void mgmt_discovering(struct hci_dev *hdev, u8 discovering);

include/net/bluetooth/mgmt.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,42 @@ struct mgmt_cp_add_adv_patterns_monitor_rssi {
837837
struct mgmt_adv_pattern patterns[];
838838
} __packed;
839839
#define MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE 8
840+
#define MGMT_OP_SET_MESH_RECEIVER 0x0057
841+
struct mgmt_cp_set_mesh {
842+
__u8 enable;
843+
__le16 window;
844+
__le16 period;
845+
__u8 num_ad_types;
846+
__u8 ad_types[];
847+
} __packed;
848+
#define MGMT_SET_MESH_RECEIVER_SIZE 6
849+
850+
#define MGMT_OP_MESH_READ_FEATURES 0x0058
851+
#define MGMT_MESH_READ_FEATURES_SIZE 0
852+
#define MESH_HANDLES_MAX 3
853+
struct mgmt_rp_mesh_read_features {
854+
__le16 index;
855+
__u8 max_handles;
856+
__u8 used_handles;
857+
__u8 handles[MESH_HANDLES_MAX];
858+
} __packed;
859+
860+
#define MGMT_OP_MESH_SEND 0x0059
861+
struct mgmt_cp_mesh_send {
862+
struct mgmt_addr_info addr;
863+
__le64 instant;
864+
__le16 delay;
865+
__u8 cnt;
866+
__u8 adv_data_len;
867+
__u8 adv_data[];
868+
} __packed;
869+
#define MGMT_MESH_SEND_SIZE 19
870+
871+
#define MGMT_OP_MESH_SEND_CANCEL 0x005A
872+
struct mgmt_cp_mesh_send_cancel {
873+
__u8 handle;
874+
} __packed;
875+
#define MGMT_MESH_SEND_CANCEL_SIZE 1
840876

841877
#define MGMT_EV_CMD_COMPLETE 0x0001
842878
struct mgmt_ev_cmd_complete {
@@ -1120,3 +1156,19 @@ struct mgmt_ev_adv_monitor_device_lost {
11201156
__le16 monitor_handle;
11211157
struct mgmt_addr_info addr;
11221158
} __packed;
1159+
1160+
#define MGMT_EV_MESH_DEVICE_FOUND 0x0031
1161+
struct mgmt_ev_mesh_device_found {
1162+
struct mgmt_addr_info addr;
1163+
__s8 rssi;
1164+
__le64 instant;
1165+
__le32 flags;
1166+
__le16 eir_len;
1167+
__u8 eir[];
1168+
} __packed;
1169+
1170+
1171+
#define MGMT_EV_MESH_PACKET_CMPLT 0x0032
1172+
struct mgmt_ev_mesh_pkt_cmplt {
1173+
__u8 handle;
1174+
} __packed;

net/bluetooth/hci_core.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,8 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
17061706
u32 flags, u16 adv_data_len, u8 *adv_data,
17071707
u16 scan_rsp_len, u8 *scan_rsp_data,
17081708
u16 timeout, u16 duration, s8 tx_power,
1709-
u32 min_interval, u32 max_interval)
1709+
u32 min_interval, u32 max_interval,
1710+
u8 mesh_handle)
17101711
{
17111712
struct adv_info *adv;
17121713

@@ -1717,7 +1718,7 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
17171718
memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data));
17181719
} else {
17191720
if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets ||
1720-
instance < 1 || instance > hdev->le_num_of_adv_sets)
1721+
instance < 1 || instance > hdev->le_num_of_adv_sets + 1)
17211722
return ERR_PTR(-EOVERFLOW);
17221723

17231724
adv = kzalloc(sizeof(*adv), GFP_KERNEL);
@@ -1734,6 +1735,11 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance,
17341735
adv->min_interval = min_interval;
17351736
adv->max_interval = max_interval;
17361737
adv->tx_power = tx_power;
1738+
/* Defining a mesh_handle changes the timing units to ms,
1739+
* rather than seconds, and ties the instance to the requested
1740+
* mesh_tx queue.
1741+
*/
1742+
adv->mesh = mesh_handle;
17371743

17381744
hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data,
17391745
scan_rsp_len, scan_rsp_data);
@@ -1762,7 +1768,7 @@ struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance,
17621768

17631769
adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL,
17641770
0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE,
1765-
min_interval, max_interval);
1771+
min_interval, max_interval, 0);
17661772
if (IS_ERR(adv))
17671773
return adv;
17681774

@@ -2486,6 +2492,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24862492
mutex_init(&hdev->lock);
24872493
mutex_init(&hdev->req_lock);
24882494

2495+
INIT_LIST_HEAD(&hdev->mesh_pending);
24892496
INIT_LIST_HEAD(&hdev->mgmt_pending);
24902497
INIT_LIST_HEAD(&hdev->reject_list);
24912498
INIT_LIST_HEAD(&hdev->accept_list);

0 commit comments

Comments
 (0)