@@ -80,6 +80,14 @@ struct msft_rp_le_set_advertisement_filter_enable {
80
80
__u8 sub_opcode ;
81
81
} __packed ;
82
82
83
+ #define MSFT_EV_LE_MONITOR_DEVICE 0x02
84
+ struct msft_ev_le_monitor_device {
85
+ __u8 addr_type ;
86
+ bdaddr_t bdaddr ;
87
+ __u8 monitor_handle ;
88
+ __u8 monitor_state ;
89
+ } __packed ;
90
+
83
91
struct msft_monitor_advertisement_handle_data {
84
92
__u8 msft_handle ;
85
93
__u16 mgmt_handle ;
@@ -204,6 +212,30 @@ static struct msft_monitor_advertisement_handle_data *msft_find_handle_data
204
212
return NULL ;
205
213
}
206
214
215
+ /* This function requires the caller holds hdev->lock */
216
+ static int msft_monitor_device_del (struct hci_dev * hdev , __u16 mgmt_handle ,
217
+ bdaddr_t * bdaddr , __u8 addr_type )
218
+ {
219
+ struct monitored_device * dev , * tmp ;
220
+ int count = 0 ;
221
+
222
+ list_for_each_entry_safe (dev , tmp , & hdev -> monitored_devices , list ) {
223
+ /* mgmt_handle == 0 indicates remove all devices, whereas,
224
+ * bdaddr == NULL indicates remove all devices matching the
225
+ * mgmt_handle.
226
+ */
227
+ if ((!mgmt_handle || dev -> handle == mgmt_handle ) &&
228
+ (!bdaddr || (!bacmp (bdaddr , & dev -> bdaddr ) &&
229
+ addr_type == dev -> addr_type ))) {
230
+ list_del (& dev -> list );
231
+ kfree (dev );
232
+ count ++ ;
233
+ }
234
+ }
235
+
236
+ return count ;
237
+ }
238
+
207
239
static void msft_le_monitor_advertisement_cb (struct hci_dev * hdev ,
208
240
u8 status , u16 opcode ,
209
241
struct sk_buff * skb )
@@ -294,6 +326,10 @@ static void msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev,
294
326
if (monitor && !msft -> suspending )
295
327
hci_free_adv_monitor (hdev , monitor );
296
328
329
+ /* Clear any monitored devices by this Adv Monitor */
330
+ msft_monitor_device_del (hdev , handle_data -> mgmt_handle , NULL ,
331
+ 0 );
332
+
297
333
list_del (& handle_data -> list );
298
334
kfree (handle_data );
299
335
}
@@ -557,6 +593,13 @@ void msft_do_close(struct hci_dev *hdev)
557
593
list_del (& handle_data -> list );
558
594
kfree (handle_data );
559
595
}
596
+
597
+ hci_dev_lock (hdev );
598
+
599
+ /* Clear any devices that are being monitored */
600
+ msft_monitor_device_del (hdev , 0 , NULL , 0 );
601
+
602
+ hci_dev_unlock (hdev );
560
603
}
561
604
562
605
void msft_register (struct hci_dev * hdev )
@@ -590,10 +633,97 @@ void msft_unregister(struct hci_dev *hdev)
590
633
kfree (msft );
591
634
}
592
635
636
+ /* This function requires the caller holds hdev->lock */
637
+ static void msft_device_found (struct hci_dev * hdev , bdaddr_t * bdaddr ,
638
+ __u8 addr_type , __u16 mgmt_handle )
639
+ {
640
+ struct monitored_device * dev ;
641
+
642
+ dev = kmalloc (sizeof (* dev ), GFP_KERNEL );
643
+ if (!dev ) {
644
+ bt_dev_err (hdev , "MSFT vendor event %u: no memory" ,
645
+ MSFT_EV_LE_MONITOR_DEVICE );
646
+ return ;
647
+ }
648
+
649
+ bacpy (& dev -> bdaddr , bdaddr );
650
+ dev -> addr_type = addr_type ;
651
+ dev -> handle = mgmt_handle ;
652
+ dev -> notified = false;
653
+
654
+ INIT_LIST_HEAD (& dev -> list );
655
+ list_add (& dev -> list , & hdev -> monitored_devices );
656
+ }
657
+
658
+ /* This function requires the caller holds hdev->lock */
659
+ static void msft_device_lost (struct hci_dev * hdev , bdaddr_t * bdaddr ,
660
+ __u8 addr_type , __u16 mgmt_handle )
661
+ {
662
+ if (!msft_monitor_device_del (hdev , mgmt_handle , bdaddr , addr_type )) {
663
+ bt_dev_err (hdev , "MSFT vendor event %u: dev %pMR not in list" ,
664
+ MSFT_EV_LE_MONITOR_DEVICE , bdaddr );
665
+ }
666
+ }
667
+
668
+ static void * msft_skb_pull (struct hci_dev * hdev , struct sk_buff * skb ,
669
+ u8 ev , size_t len )
670
+ {
671
+ void * data ;
672
+
673
+ data = skb_pull_data (skb , len );
674
+ if (!data )
675
+ bt_dev_err (hdev , "Malformed MSFT vendor event: 0x%02x" , ev );
676
+
677
+ return data ;
678
+ }
679
+
680
+ /* This function requires the caller holds hdev->lock */
681
+ static void msft_monitor_device_evt (struct hci_dev * hdev , struct sk_buff * skb )
682
+ {
683
+ struct msft_ev_le_monitor_device * ev ;
684
+ struct msft_monitor_advertisement_handle_data * handle_data ;
685
+ u8 addr_type ;
686
+
687
+ ev = msft_skb_pull (hdev , skb , MSFT_EV_LE_MONITOR_DEVICE , sizeof (* ev ));
688
+ if (!ev )
689
+ return ;
690
+
691
+ bt_dev_dbg (hdev ,
692
+ "MSFT vendor event 0x%02x: handle 0x%04x state %d addr %pMR" ,
693
+ MSFT_EV_LE_MONITOR_DEVICE , ev -> monitor_handle ,
694
+ ev -> monitor_state , & ev -> bdaddr );
695
+
696
+ handle_data = msft_find_handle_data (hdev , ev -> monitor_handle , false);
697
+
698
+ switch (ev -> addr_type ) {
699
+ case ADDR_LE_DEV_PUBLIC :
700
+ addr_type = BDADDR_LE_PUBLIC ;
701
+ break ;
702
+
703
+ case ADDR_LE_DEV_RANDOM :
704
+ addr_type = BDADDR_LE_RANDOM ;
705
+ break ;
706
+
707
+ default :
708
+ bt_dev_err (hdev ,
709
+ "MSFT vendor event 0x%02x: unknown addr type 0x%02x" ,
710
+ MSFT_EV_LE_MONITOR_DEVICE , ev -> addr_type );
711
+ return ;
712
+ }
713
+
714
+ if (ev -> monitor_state )
715
+ msft_device_found (hdev , & ev -> bdaddr , addr_type ,
716
+ handle_data -> mgmt_handle );
717
+ else
718
+ msft_device_lost (hdev , & ev -> bdaddr , addr_type ,
719
+ handle_data -> mgmt_handle );
720
+ }
721
+
593
722
void msft_vendor_evt (struct hci_dev * hdev , void * data , struct sk_buff * skb )
594
723
{
595
724
struct msft_data * msft = hdev -> msft_data ;
596
- u8 event ;
725
+ u8 * evt_prefix ;
726
+ u8 * evt ;
597
727
598
728
if (!msft )
599
729
return ;
@@ -602,13 +732,12 @@ void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb)
602
732
* matches, and otherwise just return.
603
733
*/
604
734
if (msft -> evt_prefix_len > 0 ) {
605
- if (skb -> len < msft -> evt_prefix_len )
735
+ evt_prefix = msft_skb_pull (hdev , skb , 0 , msft -> evt_prefix_len );
736
+ if (!evt_prefix )
606
737
return ;
607
738
608
- if (memcmp (skb -> data , msft -> evt_prefix , msft -> evt_prefix_len ))
739
+ if (memcmp (evt_prefix , msft -> evt_prefix , msft -> evt_prefix_len ))
609
740
return ;
610
-
611
- skb_pull (skb , msft -> evt_prefix_len );
612
741
}
613
742
614
743
/* Every event starts at least with an event code and the rest of
@@ -617,10 +746,23 @@ void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb)
617
746
if (skb -> len < 1 )
618
747
return ;
619
748
620
- event = * skb -> data ;
621
- skb_pull (skb , 1 );
749
+ evt = msft_skb_pull (hdev , skb , 0 , sizeof (* evt ));
750
+ if (!evt )
751
+ return ;
752
+
753
+ hci_dev_lock (hdev );
754
+
755
+ switch (* evt ) {
756
+ case MSFT_EV_LE_MONITOR_DEVICE :
757
+ msft_monitor_device_evt (hdev , skb );
758
+ break ;
622
759
623
- bt_dev_dbg (hdev , "MSFT vendor event %u" , event );
760
+ default :
761
+ bt_dev_dbg (hdev , "MSFT vendor event 0x%02x" , * evt );
762
+ break ;
763
+ }
764
+
765
+ hci_dev_unlock (hdev );
624
766
}
625
767
626
768
__u64 msft_get_features (struct hci_dev * hdev )
0 commit comments