Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <brian.gix@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Brian Gix and committed by
Luiz Augusto von Dentz
b338d917 fd3f1066

+760 -46
+1
include/net/bluetooth/bluetooth.h
··· 627 627 628 628 int mgmt_init(void); 629 629 void mgmt_exit(void); 630 + void mgmt_cleanup(struct sock *sk); 630 631 631 632 void bt_sock_reclassify_lock(struct sock *sk, int proto); 632 633
+3
include/net/bluetooth/hci.h
··· 354 354 HCI_LE_SIMULTANEOUS_ROLES, 355 355 HCI_CMD_DRAIN_WORKQUEUE, 356 356 357 + HCI_MESH, 358 + HCI_MESH_SENDING, 359 + 357 360 __HCI_NUM_FLAGS, 358 361 }; 359 362
+14 -2
include/net/bluetooth/hci_core.h
··· 238 238 bool enabled; 239 239 bool pending; 240 240 bool periodic; 241 + __u8 mesh; 241 242 __u8 instance; 242 243 __u32 flags; 243 244 __u16 timeout; ··· 373 372 __u8 le_resolv_list_size; 374 373 __u8 le_num_of_adv_sets; 375 374 __u8 le_states[8]; 375 + __u8 mesh_ad_types[16]; 376 + __u8 mesh_send_ref; 376 377 __u8 commands[64]; 377 378 __u8 hci_ver; 378 379 __u16 hci_rev; ··· 514 511 struct list_head cmd_sync_work_list; 515 512 struct mutex cmd_sync_work_lock; 516 513 struct work_struct cmd_sync_cancel_work; 514 + struct work_struct reenable_adv_work; 517 515 518 516 __u16 discov_timeout; 519 517 struct delayed_work discov_off; ··· 565 561 566 562 struct hci_conn_hash conn_hash; 567 563 564 + struct list_head mesh_pending; 568 565 struct list_head mgmt_pending; 569 566 struct list_head reject_list; 570 567 struct list_head accept_list; ··· 618 613 __u32 rpa_timeout; 619 614 struct delayed_work rpa_expired; 620 615 bdaddr_t rpa; 616 + 617 + struct delayed_work mesh_send_done; 621 618 622 619 enum { 623 620 INTERLEAVE_SCAN_NONE, ··· 1583 1576 u32 flags, u16 adv_data_len, u8 *adv_data, 1584 1577 u16 scan_rsp_len, u8 *scan_rsp_data, 1585 1578 u16 timeout, u16 duration, s8 tx_power, 1586 - u32 min_interval, u32 max_interval); 1579 + u32 min_interval, u32 max_interval, 1580 + u8 mesh_handle); 1587 1581 struct adv_info *hci_add_per_instance(struct hci_dev *hdev, u8 instance, 1588 1582 u32 flags, u8 data_len, u8 *data, 1589 1583 u32 min_interval, u32 max_interval); ··· 2005 1997 #define DISCOV_LE_FAST_ADV_INT_MAX 0x00F0 /* 150 msec */ 2006 1998 #define DISCOV_LE_PER_ADV_INT_MIN 0x00A0 /* 200 msec */ 2007 1999 #define DISCOV_LE_PER_ADV_INT_MAX 0x00A0 /* 200 msec */ 2000 + #define DISCOV_LE_ADV_MESH_MIN 0x00A0 /* 100 msec */ 2001 + #define DISCOV_LE_ADV_MESH_MAX 0x00A0 /* 100 msec */ 2002 + #define INTERVAL_TO_MS(x) (((x) * 10) / 0x10) 2008 2003 2009 2004 #define NAME_RESOLVE_DURATION msecs_to_jiffies(10240) /* 10.24 sec */ 2010 2005 ··· 2059 2048 void mgmt_stop_discovery_complete(struct hci_dev *hdev, u8 status); 2060 2049 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 2061 2050 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 2062 - u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); 2051 + u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, 2052 + u64 instant); 2063 2053 void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 2064 2054 u8 addr_type, s8 rssi, u8 *name, u8 name_len); 2065 2055 void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
+52
include/net/bluetooth/mgmt.h
··· 837 837 struct mgmt_adv_pattern patterns[]; 838 838 } __packed; 839 839 #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 840 876 841 877 #define MGMT_EV_CMD_COMPLETE 0x0001 842 878 struct mgmt_ev_cmd_complete { ··· 1155 1119 struct mgmt_ev_adv_monitor_device_lost { 1156 1120 __le16 monitor_handle; 1157 1121 struct mgmt_addr_info addr; 1122 + } __packed; 1123 + 1124 + #define MGMT_EV_MESH_DEVICE_FOUND 0x0031 1125 + struct mgmt_ev_mesh_device_found { 1126 + struct mgmt_addr_info addr; 1127 + __s8 rssi; 1128 + __le64 instant; 1129 + __le32 flags; 1130 + __le16 eir_len; 1131 + __u8 eir[]; 1132 + } __packed; 1133 + 1134 + 1135 + #define MGMT_EV_MESH_PACKET_CMPLT 0x0032 1136 + struct mgmt_ev_mesh_pkt_cmplt { 1137 + __u8 handle; 1158 1138 } __packed;
+10 -3
net/bluetooth/hci_core.c
··· 1706 1706 u32 flags, u16 adv_data_len, u8 *adv_data, 1707 1707 u16 scan_rsp_len, u8 *scan_rsp_data, 1708 1708 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) 1710 1711 { 1711 1712 struct adv_info *adv; 1712 1713 ··· 1718 1717 memset(adv->per_adv_data, 0, sizeof(adv->per_adv_data)); 1719 1718 } else { 1720 1719 if (hdev->adv_instance_cnt >= hdev->le_num_of_adv_sets || 1721 - instance < 1 || instance > hdev->le_num_of_adv_sets) 1720 + instance < 1 || instance > hdev->le_num_of_adv_sets + 1) 1722 1721 return ERR_PTR(-EOVERFLOW); 1723 1722 1724 1723 adv = kzalloc(sizeof(*adv), GFP_KERNEL); ··· 1735 1734 adv->min_interval = min_interval; 1736 1735 adv->max_interval = max_interval; 1737 1736 adv->tx_power = tx_power; 1737 + /* Defining a mesh_handle changes the timing units to ms, 1738 + * rather than seconds, and ties the instance to the requested 1739 + * mesh_tx queue. 1740 + */ 1741 + adv->mesh = mesh_handle; 1738 1742 1739 1743 hci_set_adv_instance_data(hdev, instance, adv_data_len, adv_data, 1740 1744 scan_rsp_len, scan_rsp_data); ··· 1768 1762 1769 1763 adv = hci_add_adv_instance(hdev, instance, flags, 0, NULL, 0, NULL, 1770 1764 0, 0, HCI_ADV_TX_POWER_NO_PREFERENCE, 1771 - min_interval, max_interval); 1765 + min_interval, max_interval, 0); 1772 1766 if (IS_ERR(adv)) 1773 1767 return adv; 1774 1768 ··· 2492 2486 mutex_init(&hdev->lock); 2493 2487 mutex_init(&hdev->req_lock); 2494 2488 2489 + INIT_LIST_HEAD(&hdev->mesh_pending); 2495 2490 INIT_LIST_HEAD(&hdev->mgmt_pending); 2496 2491 INIT_LIST_HEAD(&hdev->reject_list); 2497 2492 INIT_LIST_HEAD(&hdev->accept_list);
+38 -23
net/bluetooth/hci_event.c
··· 1756 1756 hci_dev_set_flag(hdev, HCI_LE_SCAN); 1757 1757 if (hdev->le_scan_type == LE_SCAN_ACTIVE) 1758 1758 clear_pending_adv_report(hdev); 1759 + if (hci_dev_test_flag(hdev, HCI_MESH)) 1760 + hci_discovery_set_state(hdev, DISCOVERY_FINDING); 1759 1761 break; 1760 1762 1761 1763 case LE_SCAN_DISABLE: ··· 1772 1770 d->last_adv_addr_type, NULL, 1773 1771 d->last_adv_rssi, d->last_adv_flags, 1774 1772 d->last_adv_data, 1775 - d->last_adv_data_len, NULL, 0); 1773 + d->last_adv_data_len, NULL, 0, 0); 1776 1774 } 1777 1775 1778 1776 /* Cancel this timer so that we don't try to disable scanning ··· 1788 1786 */ 1789 1787 if (hci_dev_test_and_clear_flag(hdev, HCI_LE_SCAN_INTERRUPTED)) 1790 1788 hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 1789 + else if (!hci_dev_test_flag(hdev, HCI_LE_ADV) && 1790 + hdev->discovery.state == DISCOVERY_FINDING) 1791 + queue_work(hdev->workqueue, &hdev->reenable_adv_work); 1791 1792 1792 1793 break; 1793 1794 ··· 3117 3112 3118 3113 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 3119 3114 info->dev_class, HCI_RSSI_INVALID, 3120 - flags, NULL, 0, NULL, 0); 3115 + flags, NULL, 0, NULL, 0, 0); 3121 3116 } 3122 3117 3123 3118 hci_dev_unlock(hdev); ··· 4832 4827 4833 4828 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4834 4829 info->dev_class, info->rssi, 4835 - flags, NULL, 0, NULL, 0); 4830 + flags, NULL, 0, NULL, 0, 0); 4836 4831 } 4837 4832 } else if (skb->len == array_size(ev->num, 4838 4833 sizeof(struct inquiry_info_rssi))) { ··· 4863 4858 4864 4859 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 4865 4860 info->dev_class, info->rssi, 4866 - flags, NULL, 0, NULL, 0); 4861 + flags, NULL, 0, NULL, 0, 0); 4867 4862 } 4868 4863 } else { 4869 4864 bt_dev_err(hdev, "Malformed HCI Event: 0x%2.2x", ··· 5119 5114 5120 5115 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00, 5121 5116 info->dev_class, info->rssi, 5122 - flags, info->data, eir_len, NULL, 0); 5117 + flags, info->data, eir_len, NULL, 0, 0); 5123 5118 } 5124 5119 5125 5120 hci_dev_unlock(hdev); ··· 6175 6170 static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, 6176 6171 u8 bdaddr_type, bdaddr_t *direct_addr, 6177 6172 u8 direct_addr_type, s8 rssi, u8 *data, u8 len, 6178 - bool ext_adv) 6173 + bool ext_adv, bool ctl_time, u64 instant) 6179 6174 { 6180 6175 struct discovery_state *d = &hdev->discovery; 6181 6176 struct smp_irk *irk; ··· 6223 6218 * important to see if the address is matching the local 6224 6219 * controller address. 6225 6220 */ 6226 - if (direct_addr) { 6221 + if (!hci_dev_test_flag(hdev, HCI_MESH) && direct_addr) { 6227 6222 direct_addr_type = ev_bdaddr_type(hdev, direct_addr_type, 6228 6223 &bdaddr_resolved); 6229 6224 ··· 6271 6266 conn->le_adv_data_len = len; 6272 6267 } 6273 6268 6269 + if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 6270 + flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 6271 + else 6272 + flags = 0; 6273 + 6274 + /* All scan results should be sent up for Mesh systems */ 6275 + if (hci_dev_test_flag(hdev, HCI_MESH)) { 6276 + mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6277 + rssi, flags, data, len, NULL, 0, instant); 6278 + return; 6279 + } 6280 + 6274 6281 /* Passive scanning shouldn't trigger any device found events, 6275 6282 * except for devices marked as CONN_REPORT for which we do send 6276 6283 * device found events, or advertisement monitoring requested. ··· 6296 6279 idr_is_empty(&hdev->adv_monitors_idr)) 6297 6280 return; 6298 6281 6299 - if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) 6300 - flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 6301 - else 6302 - flags = 0; 6303 6282 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6304 - rssi, flags, data, len, NULL, 0); 6283 + rssi, flags, data, len, NULL, 0, 0); 6305 6284 return; 6306 6285 } 6307 6286 ··· 6316 6303 * and just sends a scan response event, then it is marked as 6317 6304 * not connectable as well. 6318 6305 */ 6319 - if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND || 6320 - type == LE_ADV_SCAN_RSP) 6306 + if (type == LE_ADV_SCAN_RSP) 6321 6307 flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; 6322 - else 6323 - flags = 0; 6324 6308 6325 6309 /* If there's nothing pending either store the data from this 6326 6310 * event or send an immediate device found event if the data ··· 6334 6324 } 6335 6325 6336 6326 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6337 - rssi, flags, data, len, NULL, 0); 6327 + rssi, flags, data, len, NULL, 0, 0); 6338 6328 return; 6339 6329 } 6340 6330 ··· 6353 6343 d->last_adv_addr_type, NULL, 6354 6344 d->last_adv_rssi, d->last_adv_flags, 6355 6345 d->last_adv_data, 6356 - d->last_adv_data_len, NULL, 0); 6346 + d->last_adv_data_len, NULL, 0, 0); 6357 6347 6358 6348 /* If the new report will trigger a SCAN_REQ store it for 6359 6349 * later merging. ··· 6370 6360 */ 6371 6361 clear_pending_adv_report(hdev); 6372 6362 mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL, 6373 - rssi, flags, data, len, NULL, 0); 6363 + rssi, flags, data, len, NULL, 0, 0); 6374 6364 return; 6375 6365 } 6376 6366 ··· 6380 6370 */ 6381 6371 mgmt_device_found(hdev, &d->last_adv_addr, LE_LINK, 6382 6372 d->last_adv_addr_type, NULL, rssi, d->last_adv_flags, 6383 - d->last_adv_data, d->last_adv_data_len, data, len); 6373 + d->last_adv_data, d->last_adv_data_len, data, len, 0); 6384 6374 clear_pending_adv_report(hdev); 6385 6375 } 6386 6376 ··· 6388 6378 struct sk_buff *skb) 6389 6379 { 6390 6380 struct hci_ev_le_advertising_report *ev = data; 6381 + u64 instant = jiffies; 6391 6382 6392 6383 if (!ev->num) 6393 6384 return; ··· 6413 6402 rssi = info->data[info->length]; 6414 6403 process_adv_report(hdev, info->type, &info->bdaddr, 6415 6404 info->bdaddr_type, NULL, 0, rssi, 6416 - info->data, info->length, false); 6405 + info->data, info->length, false, 6406 + false, instant); 6417 6407 } else { 6418 6408 bt_dev_err(hdev, "Dropping invalid advertising data"); 6419 6409 } ··· 6471 6459 struct sk_buff *skb) 6472 6460 { 6473 6461 struct hci_ev_le_ext_adv_report *ev = data; 6462 + u64 instant = jiffies; 6474 6463 6475 6464 if (!ev->num) 6476 6465 return; ··· 6498 6485 process_adv_report(hdev, legacy_evt_type, &info->bdaddr, 6499 6486 info->bdaddr_type, NULL, 0, 6500 6487 info->rssi, info->data, info->length, 6501 - !(evt_type & LE_EXT_ADV_LEGACY_PDU)); 6488 + !(evt_type & LE_EXT_ADV_LEGACY_PDU), 6489 + false, instant); 6502 6490 } 6503 6491 } 6504 6492 ··· 6722 6708 struct sk_buff *skb) 6723 6709 { 6724 6710 struct hci_ev_le_direct_adv_report *ev = data; 6711 + u64 instant = jiffies; 6725 6712 int i; 6726 6713 6727 6714 if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_DIRECT_ADV_REPORT, ··· 6740 6725 process_adv_report(hdev, info->type, &info->bdaddr, 6741 6726 info->bdaddr_type, &info->direct_addr, 6742 6727 info->direct_addr_type, info->rssi, NULL, 0, 6743 - false); 6728 + false, false, instant); 6744 6729 } 6745 6730 6746 6731 hci_dev_unlock(hdev);
+1
net/bluetooth/hci_sock.c
··· 2065 2065 2066 2066 static void hci_sock_destruct(struct sock *sk) 2067 2067 { 2068 + mgmt_cleanup(sk); 2068 2069 skb_queue_purge(&sk->sk_receive_queue); 2069 2070 skb_queue_purge(&sk->sk_write_queue); 2070 2071 }
+77 -10
net/bluetooth/hci_sync.c
··· 246 246 skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk); 247 247 if (IS_ERR(skb)) { 248 248 bt_dev_err(hdev, "Opcode 0x%4x failed: %ld", opcode, 249 - PTR_ERR(skb)); 249 + PTR_ERR(skb)); 250 250 return PTR_ERR(skb); 251 251 } 252 252 ··· 465 465 hci_dev_unlock(hdev); 466 466 } 467 467 468 + static int reenable_adv_sync(struct hci_dev *hdev, void *data) 469 + { 470 + bt_dev_dbg(hdev, ""); 471 + 472 + if (!hci_dev_test_flag(hdev, HCI_ADVERTISING) && 473 + list_empty(&hdev->adv_instances)) 474 + return 0; 475 + 476 + if (hdev->cur_adv_instance) { 477 + return hci_schedule_adv_instance_sync(hdev, 478 + hdev->cur_adv_instance, 479 + true); 480 + } else { 481 + if (ext_adv_capable(hdev)) { 482 + hci_start_ext_adv_sync(hdev, 0x00); 483 + } else { 484 + hci_update_adv_data_sync(hdev, 0x00); 485 + hci_update_scan_rsp_data_sync(hdev, 0x00); 486 + hci_enable_advertising_sync(hdev); 487 + } 488 + } 489 + 490 + return 0; 491 + } 492 + 493 + static void reenable_adv(struct work_struct *work) 494 + { 495 + struct hci_dev *hdev = container_of(work, struct hci_dev, 496 + reenable_adv_work); 497 + int status; 498 + 499 + bt_dev_dbg(hdev, ""); 500 + 501 + hci_dev_lock(hdev); 502 + 503 + status = hci_cmd_sync_queue(hdev, reenable_adv_sync, NULL, NULL); 504 + if (status) 505 + bt_dev_err(hdev, "failed to reenable ADV: %d", status); 506 + 507 + hci_dev_unlock(hdev); 508 + } 509 + 468 510 static void cancel_adv_timeout(struct hci_dev *hdev) 469 511 { 470 512 if (hdev->adv_instance_timeout) { ··· 629 587 mutex_init(&hdev->cmd_sync_work_lock); 630 588 631 589 INIT_WORK(&hdev->cmd_sync_cancel_work, hci_cmd_sync_cancel_work); 590 + INIT_WORK(&hdev->reenable_adv_work, reenable_adv); 632 591 INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable); 633 592 INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart); 634 593 INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire); ··· 640 597 struct hci_cmd_sync_work_entry *entry, *tmp; 641 598 642 599 cancel_work_sync(&hdev->cmd_sync_work); 600 + cancel_work_sync(&hdev->reenable_adv_work); 643 601 644 602 list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) { 645 603 if (entry->destroy) ··· 1790 1746 static int hci_clear_adv_sync(struct hci_dev *hdev, struct sock *sk, bool force) 1791 1747 { 1792 1748 struct adv_info *adv, *n; 1749 + int err = 0; 1793 1750 1794 1751 if (ext_adv_capable(hdev)) 1795 1752 /* Remove all existing sets */ 1796 - return hci_clear_adv_sets_sync(hdev, sk); 1753 + err = hci_clear_adv_sets_sync(hdev, sk); 1754 + if (ext_adv_capable(hdev)) 1755 + return err; 1797 1756 1798 1757 /* This is safe as long as there is no command send while the lock is 1799 1758 * held. ··· 1824 1777 static int hci_remove_adv_sync(struct hci_dev *hdev, u8 instance, 1825 1778 struct sock *sk) 1826 1779 { 1827 - int err; 1780 + int err = 0; 1828 1781 1829 1782 /* If we use extended advertising, instance has to be removed first. */ 1830 1783 if (ext_adv_capable(hdev)) 1831 - return hci_remove_ext_adv_instance_sync(hdev, instance, sk); 1784 + err = hci_remove_ext_adv_instance_sync(hdev, instance, sk); 1785 + if (ext_adv_capable(hdev)) 1786 + return err; 1832 1787 1833 1788 /* This is safe as long as there is no command send while the lock is 1834 1789 * held. ··· 1929 1880 int hci_disable_advertising_sync(struct hci_dev *hdev) 1930 1881 { 1931 1882 u8 enable = 0x00; 1883 + int err = 0; 1932 1884 1933 1885 /* If controller is not advertising we are done. */ 1934 1886 if (!hci_dev_test_flag(hdev, HCI_LE_ADV)) 1935 1887 return 0; 1936 1888 1937 1889 if (ext_adv_capable(hdev)) 1938 - return hci_disable_ext_adv_instance_sync(hdev, 0x00); 1890 + err = hci_disable_ext_adv_instance_sync(hdev, 0x00); 1891 + if (ext_adv_capable(hdev)) 1892 + return err; 1939 1893 1940 1894 return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_ENABLE, 1941 1895 sizeof(enable), &enable, HCI_CMD_TIMEOUT); ··· 1951 1899 1952 1900 memset(&cp, 0, sizeof(cp)); 1953 1901 cp.enable = val; 1954 - cp.filter_dup = filter_dup; 1902 + 1903 + if (hci_dev_test_flag(hdev, HCI_MESH)) 1904 + cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE; 1905 + else 1906 + cp.filter_dup = filter_dup; 1955 1907 1956 1908 return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_ENABLE, 1957 1909 sizeof(cp), &cp, HCI_CMD_TIMEOUT); ··· 1971 1915 1972 1916 memset(&cp, 0, sizeof(cp)); 1973 1917 cp.enable = val; 1974 - cp.filter_dup = filter_dup; 1918 + 1919 + if (val && hci_dev_test_flag(hdev, HCI_MESH)) 1920 + cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE; 1921 + else 1922 + cp.filter_dup = filter_dup; 1975 1923 1976 1924 return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_SCAN_ENABLE, 1977 1925 sizeof(cp), &cp, HCI_CMD_TIMEOUT); ··· 2614 2554 u8 own_addr_type; 2615 2555 u8 filter_policy; 2616 2556 u16 window, interval; 2557 + u8 filter_dups = LE_SCAN_FILTER_DUP_ENABLE; 2617 2558 int err; 2618 2559 2619 2560 if (hdev->scanning_paused) { ··· 2677 2616 interval = hdev->le_scan_interval; 2678 2617 } 2679 2618 2619 + /* Disable all filtering for Mesh */ 2620 + if (hci_dev_test_flag(hdev, HCI_MESH)) { 2621 + filter_policy = 0; 2622 + filter_dups = LE_SCAN_FILTER_DUP_DISABLE; 2623 + } 2624 + 2680 2625 bt_dev_dbg(hdev, "LE passive scan with acceptlist = %d", filter_policy); 2681 2626 2682 2627 return hci_start_scan_sync(hdev, LE_SCAN_PASSIVE, interval, window, 2683 - own_addr_type, filter_policy, 2684 - LE_SCAN_FILTER_DUP_ENABLE); 2628 + own_addr_type, filter_policy, filter_dups); 2685 2629 } 2686 2630 2687 2631 /* This function controls the passive scanning based on hdev->pend_le_conns ··· 2736 2670 bt_dev_dbg(hdev, "ADV monitoring is %s", 2737 2671 hci_is_adv_monitoring(hdev) ? "on" : "off"); 2738 2672 2739 - if (list_empty(&hdev->pend_le_conns) && 2673 + if (!hci_dev_test_flag(hdev, HCI_MESH) && 2674 + list_empty(&hdev->pend_le_conns) && 2740 2675 list_empty(&hdev->pend_le_reports) && 2741 2676 !hci_is_adv_monitoring(hdev) && 2742 2677 !hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
+472 -8
net/bluetooth/mgmt.c
··· 129 129 MGMT_OP_ADD_EXT_ADV_PARAMS, 130 130 MGMT_OP_ADD_EXT_ADV_DATA, 131 131 MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, 132 + MGMT_OP_SET_MESH_RECEIVER, 133 + MGMT_OP_MESH_READ_FEATURES, 134 + MGMT_OP_MESH_SEND, 135 + MGMT_OP_MESH_SEND_CANCEL, 132 136 }; 133 137 134 138 static const u16 mgmt_events[] = { ··· 1052 1048 hci_dev_unlock(hdev); 1053 1049 } 1054 1050 1051 + static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev); 1052 + 1053 + static void mesh_send_complete(struct hci_dev *hdev, 1054 + struct mgmt_mesh_tx *mesh_tx, bool silent) 1055 + { 1056 + u8 handle = mesh_tx->handle; 1057 + 1058 + if (!silent) 1059 + mgmt_event(MGMT_EV_MESH_PACKET_CMPLT, hdev, &handle, 1060 + sizeof(handle), NULL); 1061 + 1062 + mgmt_mesh_remove(mesh_tx); 1063 + } 1064 + 1065 + static int mesh_send_done_sync(struct hci_dev *hdev, void *data) 1066 + { 1067 + struct mgmt_mesh_tx *mesh_tx; 1068 + 1069 + hci_dev_clear_flag(hdev, HCI_MESH_SENDING); 1070 + hci_disable_advertising_sync(hdev); 1071 + mesh_tx = mgmt_mesh_next(hdev, NULL); 1072 + 1073 + if (mesh_tx) 1074 + mesh_send_complete(hdev, mesh_tx, false); 1075 + 1076 + return 0; 1077 + } 1078 + 1079 + static int mesh_send_sync(struct hci_dev *hdev, void *data); 1080 + static void mesh_send_start_complete(struct hci_dev *hdev, void *data, int err); 1081 + static void mesh_next(struct hci_dev *hdev, void *data, int err) 1082 + { 1083 + struct mgmt_mesh_tx *mesh_tx = mgmt_mesh_next(hdev, NULL); 1084 + 1085 + if (!mesh_tx) 1086 + return; 1087 + 1088 + err = hci_cmd_sync_queue(hdev, mesh_send_sync, mesh_tx, 1089 + mesh_send_start_complete); 1090 + 1091 + if (err < 0) 1092 + mesh_send_complete(hdev, mesh_tx, false); 1093 + else 1094 + hci_dev_set_flag(hdev, HCI_MESH_SENDING); 1095 + } 1096 + 1097 + static void mesh_send_done(struct work_struct *work) 1098 + { 1099 + struct hci_dev *hdev = container_of(work, struct hci_dev, 1100 + mesh_send_done.work); 1101 + 1102 + if (!hci_dev_test_flag(hdev, HCI_MESH_SENDING)) 1103 + return; 1104 + 1105 + hci_cmd_sync_queue(hdev, mesh_send_done_sync, NULL, mesh_next); 1106 + } 1107 + 1055 1108 static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev) 1056 1109 { 1057 1110 if (hci_dev_test_and_set_flag(hdev, HCI_MGMT)) ··· 1119 1058 INIT_DELAYED_WORK(&hdev->discov_off, discov_off); 1120 1059 INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off); 1121 1060 INIT_DELAYED_WORK(&hdev->rpa_expired, rpa_expired); 1061 + INIT_DELAYED_WORK(&hdev->mesh_send_done, mesh_send_done); 1122 1062 1123 1063 /* Non-mgmt controlled devices get this bit set 1124 1064 * implicitly so that pairing works for them, however ··· 2153 2091 hci_update_passive_scan(hdev); 2154 2092 } 2155 2093 2094 + return err; 2095 + } 2096 + 2097 + static void set_mesh_complete(struct hci_dev *hdev, void *data, int err) 2098 + { 2099 + struct mgmt_pending_cmd *cmd = data; 2100 + u8 status = mgmt_status(err); 2101 + struct sock *sk = cmd->sk; 2102 + 2103 + if (status) { 2104 + mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, 2105 + cmd_status_rsp, &status); 2106 + return; 2107 + } 2108 + 2109 + mgmt_pending_remove(cmd); 2110 + mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 0, NULL, 0); 2111 + } 2112 + 2113 + static int set_mesh_sync(struct hci_dev *hdev, void *data) 2114 + { 2115 + struct mgmt_pending_cmd *cmd = data; 2116 + struct mgmt_cp_set_mesh *cp = cmd->param; 2117 + size_t len = cmd->param_len; 2118 + 2119 + memset(hdev->mesh_ad_types, 0, sizeof(hdev->mesh_ad_types)); 2120 + 2121 + if (cp->enable) 2122 + hci_dev_set_flag(hdev, HCI_MESH); 2123 + else 2124 + hci_dev_clear_flag(hdev, HCI_MESH); 2125 + 2126 + len -= sizeof(*cp); 2127 + 2128 + /* If filters don't fit, forward all adv pkts */ 2129 + if (len <= sizeof(hdev->mesh_ad_types)) 2130 + memcpy(hdev->mesh_ad_types, cp->ad_types, len); 2131 + 2132 + hci_update_passive_scan_sync(hdev); 2133 + return 0; 2134 + } 2135 + 2136 + static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 2137 + { 2138 + struct mgmt_cp_set_mesh *cp = data; 2139 + struct mgmt_pending_cmd *cmd; 2140 + int err = 0; 2141 + 2142 + bt_dev_dbg(hdev, "sock %p", sk); 2143 + 2144 + if (!lmp_le_capable(hdev)) 2145 + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 2146 + MGMT_STATUS_NOT_SUPPORTED); 2147 + 2148 + if (cp->enable != 0x00 && cp->enable != 0x01) 2149 + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 2150 + MGMT_STATUS_INVALID_PARAMS); 2151 + 2152 + hci_dev_lock(hdev); 2153 + 2154 + cmd = mgmt_pending_add(sk, MGMT_OP_SET_MESH_RECEIVER, hdev, data, len); 2155 + if (!cmd) 2156 + err = -ENOMEM; 2157 + else 2158 + err = hci_cmd_sync_queue(hdev, set_mesh_sync, cmd, 2159 + set_mesh_complete); 2160 + 2161 + if (err < 0) { 2162 + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER, 2163 + MGMT_STATUS_FAILED); 2164 + 2165 + if (cmd) 2166 + mgmt_pending_remove(cmd); 2167 + } 2168 + 2169 + hci_dev_unlock(hdev); 2170 + return err; 2171 + } 2172 + 2173 + static void mesh_send_start_complete(struct hci_dev *hdev, void *data, int err) 2174 + { 2175 + struct mgmt_mesh_tx *mesh_tx = data; 2176 + struct mgmt_cp_mesh_send *send = (void *)mesh_tx->param; 2177 + unsigned long mesh_send_interval; 2178 + u8 mgmt_err = mgmt_status(err); 2179 + 2180 + /* Report any errors here, but don't report completion */ 2181 + 2182 + if (mgmt_err) { 2183 + hci_dev_clear_flag(hdev, HCI_MESH_SENDING); 2184 + /* Send Complete Error Code for handle */ 2185 + mesh_send_complete(hdev, mesh_tx, false); 2186 + return; 2187 + } 2188 + 2189 + mesh_send_interval = msecs_to_jiffies((send->cnt) * 25); 2190 + queue_delayed_work(hdev->req_workqueue, &hdev->mesh_send_done, 2191 + mesh_send_interval); 2192 + } 2193 + 2194 + static int mesh_send_sync(struct hci_dev *hdev, void *data) 2195 + { 2196 + struct mgmt_mesh_tx *mesh_tx = data; 2197 + struct mgmt_cp_mesh_send *send = (void *)mesh_tx->param; 2198 + struct adv_info *adv, *next_instance; 2199 + u8 instance = hdev->le_num_of_adv_sets + 1; 2200 + u16 timeout, duration; 2201 + int err = 0; 2202 + 2203 + if (hdev->le_num_of_adv_sets <= hdev->adv_instance_cnt) 2204 + return MGMT_STATUS_BUSY; 2205 + 2206 + timeout = 1000; 2207 + duration = send->cnt * INTERVAL_TO_MS(hdev->le_adv_max_interval); 2208 + adv = hci_add_adv_instance(hdev, instance, 0, 2209 + send->adv_data_len, send->adv_data, 2210 + 0, NULL, 2211 + timeout, duration, 2212 + HCI_ADV_TX_POWER_NO_PREFERENCE, 2213 + hdev->le_adv_min_interval, 2214 + hdev->le_adv_max_interval, 2215 + mesh_tx->handle); 2216 + 2217 + if (!IS_ERR(adv)) 2218 + mesh_tx->instance = instance; 2219 + else 2220 + err = PTR_ERR(adv); 2221 + 2222 + if (hdev->cur_adv_instance == instance) { 2223 + /* If the currently advertised instance is being changed then 2224 + * cancel the current advertising and schedule the next 2225 + * instance. If there is only one instance then the overridden 2226 + * advertising data will be visible right away. 2227 + */ 2228 + cancel_adv_timeout(hdev); 2229 + 2230 + next_instance = hci_get_next_instance(hdev, instance); 2231 + if (next_instance) 2232 + instance = next_instance->instance; 2233 + else 2234 + instance = 0; 2235 + } else if (hdev->adv_instance_timeout) { 2236 + /* Immediately advertise the new instance if no other, or 2237 + * let it go naturally from queue if ADV is already happening 2238 + */ 2239 + instance = 0; 2240 + } 2241 + 2242 + if (instance) 2243 + return hci_schedule_adv_instance_sync(hdev, instance, true); 2244 + 2245 + return err; 2246 + } 2247 + 2248 + static void send_count(struct mgmt_mesh_tx *mesh_tx, void *data) 2249 + { 2250 + struct mgmt_rp_mesh_read_features *rp = data; 2251 + 2252 + if (rp->used_handles >= rp->max_handles) 2253 + return; 2254 + 2255 + rp->handles[rp->used_handles++] = mesh_tx->handle; 2256 + } 2257 + 2258 + static int mesh_features(struct sock *sk, struct hci_dev *hdev, 2259 + void *data, u16 len) 2260 + { 2261 + struct mgmt_rp_mesh_read_features rp; 2262 + 2263 + if (!lmp_le_capable(hdev)) 2264 + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_READ_FEATURES, 2265 + MGMT_STATUS_NOT_SUPPORTED); 2266 + 2267 + memset(&rp, 0, sizeof(rp)); 2268 + rp.index = cpu_to_le16(hdev->id); 2269 + if (hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 2270 + rp.max_handles = MESH_HANDLES_MAX; 2271 + 2272 + hci_dev_lock(hdev); 2273 + 2274 + if (rp.max_handles) 2275 + mgmt_mesh_foreach(hdev, send_count, &rp, sk); 2276 + 2277 + mgmt_cmd_complete(sk, hdev->id, MGMT_OP_MESH_READ_FEATURES, 0, &rp, 2278 + rp.used_handles + sizeof(rp) - MESH_HANDLES_MAX); 2279 + 2280 + hci_dev_unlock(hdev); 2281 + return 0; 2282 + } 2283 + 2284 + static int send_cancel(struct hci_dev *hdev, void *data) 2285 + { 2286 + struct mgmt_pending_cmd *cmd = data; 2287 + struct mgmt_cp_mesh_send_cancel *cancel = (void *)cmd->param; 2288 + struct mgmt_mesh_tx *mesh_tx; 2289 + 2290 + if (!cancel->handle) { 2291 + do { 2292 + mesh_tx = mgmt_mesh_next(hdev, cmd->sk); 2293 + 2294 + if (mesh_tx) 2295 + mesh_send_complete(hdev, mesh_tx, false); 2296 + } while (mesh_tx); 2297 + } else { 2298 + mesh_tx = mgmt_mesh_find(hdev, cancel->handle); 2299 + 2300 + if (mesh_tx && mesh_tx->sk == cmd->sk) 2301 + mesh_send_complete(hdev, mesh_tx, false); 2302 + } 2303 + 2304 + mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL, 2305 + 0, NULL, 0); 2306 + mgmt_pending_free(cmd); 2307 + 2308 + return 0; 2309 + } 2310 + 2311 + static int mesh_send_cancel(struct sock *sk, struct hci_dev *hdev, 2312 + void *data, u16 len) 2313 + { 2314 + struct mgmt_pending_cmd *cmd; 2315 + int err; 2316 + 2317 + if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) 2318 + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL, 2319 + MGMT_STATUS_REJECTED); 2320 + 2321 + hci_dev_lock(hdev); 2322 + cmd = mgmt_pending_new(sk, MGMT_OP_MESH_SEND_CANCEL, hdev, data, len); 2323 + if (!cmd) 2324 + err = -ENOMEM; 2325 + else 2326 + err = hci_cmd_sync_queue(hdev, send_cancel, cmd, NULL); 2327 + 2328 + if (err < 0) { 2329 + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL, 2330 + MGMT_STATUS_FAILED); 2331 + 2332 + if (cmd) 2333 + mgmt_pending_free(cmd); 2334 + } 2335 + 2336 + hci_dev_unlock(hdev); 2337 + return err; 2338 + } 2339 + 2340 + static int mesh_send(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) 2341 + { 2342 + struct mgmt_mesh_tx *mesh_tx; 2343 + struct mgmt_cp_mesh_send *send = data; 2344 + struct mgmt_rp_mesh_read_features rp; 2345 + bool sending; 2346 + int err = 0; 2347 + 2348 + if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED) || 2349 + len <= MGMT_MESH_SEND_SIZE || 2350 + len > (MGMT_MESH_SEND_SIZE + 31)) 2351 + return mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_SEND, 2352 + MGMT_STATUS_REJECTED); 2353 + 2354 + hci_dev_lock(hdev); 2355 + 2356 + memset(&rp, 0, sizeof(rp)); 2357 + rp.max_handles = MESH_HANDLES_MAX; 2358 + 2359 + mgmt_mesh_foreach(hdev, send_count, &rp, sk); 2360 + 2361 + if (rp.max_handles <= rp.used_handles) { 2362 + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_SEND, 2363 + MGMT_STATUS_BUSY); 2364 + goto done; 2365 + } 2366 + 2367 + sending = hci_dev_test_flag(hdev, HCI_MESH_SENDING); 2368 + mesh_tx = mgmt_mesh_add(sk, hdev, send, len); 2369 + 2370 + if (!mesh_tx) 2371 + err = -ENOMEM; 2372 + else if (!sending) 2373 + err = hci_cmd_sync_queue(hdev, mesh_send_sync, mesh_tx, 2374 + mesh_send_start_complete); 2375 + 2376 + if (err < 0) { 2377 + bt_dev_err(hdev, "Send Mesh Failed %d", err); 2378 + err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_SEND, 2379 + MGMT_STATUS_FAILED); 2380 + 2381 + if (mesh_tx) { 2382 + if (sending) 2383 + mgmt_mesh_remove(mesh_tx); 2384 + } 2385 + } else { 2386 + hci_dev_set_flag(hdev, HCI_MESH_SENDING); 2387 + 2388 + mgmt_cmd_complete(sk, hdev->id, MGMT_OP_MESH_SEND, 0, 2389 + &mesh_tx->handle, 1); 2390 + } 2391 + 2392 + done: 2393 + hci_dev_unlock(hdev); 2156 2394 return err; 2157 2395 } 2158 2396 ··· 6355 5993 if (!hdev_is_powered(hdev) || 6356 5994 (val == hci_dev_test_flag(hdev, HCI_ADVERTISING) && 6357 5995 (cp->val == 0x02) == hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) || 5996 + hci_dev_test_flag(hdev, HCI_MESH) || 6358 5997 hci_conn_num(hdev, LE_LINK) > 0 || 6359 5998 (hci_dev_test_flag(hdev, HCI_LE_SCAN) && 6360 5999 hdev->le_scan_type == LE_SCAN_ACTIVE)) { ··· 8284 7921 /* In extended adv TX_POWER returned from Set Adv Param 8285 7922 * will be always valid. 8286 7923 */ 8287 - if ((hdev->adv_tx_power != HCI_TX_POWER_INVALID) || 8288 - ext_adv_capable(hdev)) 7924 + if (hdev->adv_tx_power != HCI_TX_POWER_INVALID || ext_adv_capable(hdev)) 8289 7925 flags |= MGMT_ADV_FLAG_TX_POWER; 8290 7926 8291 7927 if (ext_adv_capable(hdev)) { ··· 8337 7975 8338 7976 instance = rp->instance; 8339 7977 list_for_each_entry(adv_instance, &hdev->adv_instances, list) { 8340 - *instance = adv_instance->instance; 8341 - instance++; 7978 + /* Only instances 1-le_num_of_adv_sets are externally visible */ 7979 + if (adv_instance->instance <= hdev->adv_instance_cnt) { 7980 + *instance = adv_instance->instance; 7981 + instance++; 7982 + } else { 7983 + rp->num_instances--; 7984 + rp_len--; 7985 + } 8342 7986 } 8343 7987 8344 7988 hci_dev_unlock(hdev); ··· 8606 8238 timeout, duration, 8607 8239 HCI_ADV_TX_POWER_NO_PREFERENCE, 8608 8240 hdev->le_adv_min_interval, 8609 - hdev->le_adv_max_interval); 8241 + hdev->le_adv_max_interval, 0); 8610 8242 if (IS_ERR(adv)) { 8611 8243 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, 8612 8244 MGMT_STATUS_FAILED); ··· 8810 8442 /* Create advertising instance with no advertising or response data */ 8811 8443 adv = hci_add_adv_instance(hdev, cp->instance, flags, 0, NULL, 0, NULL, 8812 8444 timeout, duration, tx_power, min_interval, 8813 - max_interval); 8445 + max_interval, 0); 8814 8446 8815 8447 if (IS_ERR(adv)) { 8816 8448 err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS, ··· 9256 8888 { add_ext_adv_data, MGMT_ADD_EXT_ADV_DATA_SIZE, 9257 8889 HCI_MGMT_VAR_LEN }, 9258 8890 { add_adv_patterns_monitor_rssi, 9259 - MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE, 8891 + MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE }, 8892 + { set_mesh, MGMT_SET_MESH_RECEIVER_SIZE, 9260 8893 HCI_MGMT_VAR_LEN }, 8894 + { mesh_features, MGMT_MESH_READ_FEATURES_SIZE }, 8895 + { mesh_send, MGMT_MESH_SEND_SIZE, 8896 + HCI_MGMT_VAR_LEN }, 8897 + { mesh_send_cancel, MGMT_MESH_SEND_CANCEL_SIZE }, 9261 8898 }; 9262 8899 9263 8900 void mgmt_index_added(struct hci_dev *hdev) ··· 10202 9829 kfree_skb(skb); 10203 9830 } 10204 9831 9832 + static void mesh_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, 9833 + u8 addr_type, s8 rssi, u32 flags, u8 *eir, 9834 + u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, 9835 + u64 instant) 9836 + { 9837 + struct sk_buff *skb; 9838 + struct mgmt_ev_mesh_device_found *ev; 9839 + int i, j; 9840 + 9841 + if (!hdev->mesh_ad_types[0]) 9842 + goto accepted; 9843 + 9844 + /* Scan for requested AD types */ 9845 + if (eir_len > 0) { 9846 + for (i = 0; i + 1 < eir_len; i += eir[i] + 1) { 9847 + for (j = 0; j < sizeof(hdev->mesh_ad_types); j++) { 9848 + if (!hdev->mesh_ad_types[j]) 9849 + break; 9850 + 9851 + if (hdev->mesh_ad_types[j] == eir[i + 1]) 9852 + goto accepted; 9853 + } 9854 + } 9855 + } 9856 + 9857 + if (scan_rsp_len > 0) { 9858 + for (i = 0; i + 1 < scan_rsp_len; i += scan_rsp[i] + 1) { 9859 + for (j = 0; j < sizeof(hdev->mesh_ad_types); j++) { 9860 + if (!hdev->mesh_ad_types[j]) 9861 + break; 9862 + 9863 + if (hdev->mesh_ad_types[j] == scan_rsp[i + 1]) 9864 + goto accepted; 9865 + } 9866 + } 9867 + } 9868 + 9869 + return; 9870 + 9871 + accepted: 9872 + skb = mgmt_alloc_skb(hdev, MGMT_EV_MESH_DEVICE_FOUND, 9873 + sizeof(*ev) + eir_len + scan_rsp_len); 9874 + if (!skb) 9875 + return; 9876 + 9877 + ev = skb_put(skb, sizeof(*ev)); 9878 + 9879 + bacpy(&ev->addr.bdaddr, bdaddr); 9880 + ev->addr.type = link_to_bdaddr(LE_LINK, addr_type); 9881 + ev->rssi = rssi; 9882 + ev->flags = cpu_to_le32(flags); 9883 + ev->instant = cpu_to_le64(instant); 9884 + 9885 + if (eir_len > 0) 9886 + /* Copy EIR or advertising data into event */ 9887 + skb_put_data(skb, eir, eir_len); 9888 + 9889 + if (scan_rsp_len > 0) 9890 + /* Append scan response data to event */ 9891 + skb_put_data(skb, scan_rsp, scan_rsp_len); 9892 + 9893 + ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len); 9894 + 9895 + mgmt_event_skb(skb, NULL); 9896 + } 9897 + 10205 9898 void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 10206 9899 u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 10207 - u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len) 9900 + u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, 9901 + u64 instant) 10208 9902 { 10209 9903 struct sk_buff *skb; 10210 9904 struct mgmt_ev_device_found *ev; 10211 9905 bool report_device = hci_discovery_active(hdev); 9906 + 9907 + if (hci_dev_test_flag(hdev, HCI_MESH) && link_type == LE_LINK) 9908 + mesh_device_found(hdev, bdaddr, addr_type, rssi, flags, 9909 + eir, eir_len, scan_rsp, scan_rsp_len, 9910 + instant); 10212 9911 10213 9912 /* Don't send events for a non-kernel initiated discovery. With 10214 9913 * LE one exception is if we have pend_le_reports > 0 in which ··· 10439 9994 void mgmt_exit(void) 10440 9995 { 10441 9996 hci_mgmt_chan_unregister(&chan); 9997 + } 9998 + 9999 + void mgmt_cleanup(struct sock *sk) 10000 + { 10001 + struct mgmt_mesh_tx *mesh_tx; 10002 + struct hci_dev *hdev; 10003 + 10004 + read_lock(&hci_dev_list_lock); 10005 + 10006 + list_for_each_entry(hdev, &hci_dev_list, list) { 10007 + do { 10008 + mesh_tx = mgmt_mesh_next(hdev, sk); 10009 + 10010 + if (mesh_tx) 10011 + mesh_send_complete(hdev, mesh_tx, true); 10012 + } while (mesh_tx); 10013 + } 10014 + 10015 + read_unlock(&hci_dev_list_lock); 10442 10016 }
+74
net/bluetooth/mgmt_util.c
··· 314 314 list_del(&cmd->list); 315 315 mgmt_pending_free(cmd); 316 316 } 317 + 318 + void mgmt_mesh_foreach(struct hci_dev *hdev, 319 + void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data), 320 + void *data, struct sock *sk) 321 + { 322 + struct mgmt_mesh_tx *mesh_tx, *tmp; 323 + 324 + list_for_each_entry_safe(mesh_tx, tmp, &hdev->mgmt_pending, list) { 325 + if (!sk || mesh_tx->sk == sk) 326 + cb(mesh_tx, data); 327 + } 328 + } 329 + 330 + struct mgmt_mesh_tx *mgmt_mesh_next(struct hci_dev *hdev, struct sock *sk) 331 + { 332 + struct mgmt_mesh_tx *mesh_tx; 333 + 334 + if (list_empty(&hdev->mesh_pending)) 335 + return NULL; 336 + 337 + list_for_each_entry(mesh_tx, &hdev->mesh_pending, list) { 338 + if (!sk || mesh_tx->sk == sk) 339 + return mesh_tx; 340 + } 341 + 342 + return NULL; 343 + } 344 + 345 + struct mgmt_mesh_tx *mgmt_mesh_find(struct hci_dev *hdev, u8 handle) 346 + { 347 + struct mgmt_mesh_tx *mesh_tx; 348 + 349 + if (list_empty(&hdev->mesh_pending)) 350 + return NULL; 351 + 352 + list_for_each_entry(mesh_tx, &hdev->mesh_pending, list) { 353 + if (mesh_tx->handle == handle) 354 + return mesh_tx; 355 + } 356 + 357 + return NULL; 358 + } 359 + 360 + struct mgmt_mesh_tx *mgmt_mesh_add(struct sock *sk, struct hci_dev *hdev, 361 + void *data, u16 len) 362 + { 363 + struct mgmt_mesh_tx *mesh_tx; 364 + 365 + mesh_tx = kzalloc(sizeof(*mesh_tx), GFP_KERNEL); 366 + if (!mesh_tx) 367 + return NULL; 368 + 369 + hdev->mesh_send_ref++; 370 + if (!hdev->mesh_send_ref) 371 + hdev->mesh_send_ref++; 372 + 373 + mesh_tx->handle = hdev->mesh_send_ref; 374 + mesh_tx->index = hdev->id; 375 + memcpy(mesh_tx->param, data, len); 376 + mesh_tx->param_len = len; 377 + mesh_tx->sk = sk; 378 + sock_hold(sk); 379 + 380 + list_add_tail(&mesh_tx->list, &hdev->mesh_pending); 381 + 382 + return mesh_tx; 383 + } 384 + 385 + void mgmt_mesh_remove(struct mgmt_mesh_tx *mesh_tx) 386 + { 387 + list_del(&mesh_tx->list); 388 + sock_put(mesh_tx->sk); 389 + kfree(mesh_tx); 390 + }
+18
net/bluetooth/mgmt_util.h
··· 20 20 SOFTWARE IS DISCLAIMED. 21 21 */ 22 22 23 + struct mgmt_mesh_tx { 24 + struct list_head list; 25 + int index; 26 + size_t param_len; 27 + struct sock *sk; 28 + u8 handle; 29 + u8 instance; 30 + u8 param[sizeof(struct mgmt_cp_mesh_send) + 29]; 31 + }; 32 + 23 33 struct mgmt_pending_cmd { 24 34 struct list_head list; 25 35 u16 opcode; ··· 69 59 void *data, u16 len); 70 60 void mgmt_pending_free(struct mgmt_pending_cmd *cmd); 71 61 void mgmt_pending_remove(struct mgmt_pending_cmd *cmd); 62 + void mgmt_mesh_foreach(struct hci_dev *hdev, 63 + void (*cb)(struct mgmt_mesh_tx *mesh_tx, void *data), 64 + void *data, struct sock *sk); 65 + struct mgmt_mesh_tx *mgmt_mesh_find(struct hci_dev *hdev, u8 handle); 66 + struct mgmt_mesh_tx *mgmt_mesh_next(struct hci_dev *hdev, struct sock *sk); 67 + struct mgmt_mesh_tx *mgmt_mesh_add(struct sock *sk, struct hci_dev *hdev, 68 + void *data, u16 len); 69 + void mgmt_mesh_remove(struct mgmt_mesh_tx *mesh_tx);