@@ -80,6 +80,14 @@ struct msft_rp_le_set_advertisement_filter_enable {
8080 __u8 sub_opcode ;
8181} __packed ;
8282
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+
8391struct msft_monitor_advertisement_handle_data {
8492 __u8 msft_handle ;
8593 __u16 mgmt_handle ;
@@ -204,6 +212,30 @@ static struct msft_monitor_advertisement_handle_data *msft_find_handle_data
204212 return NULL ;
205213}
206214
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+
207239static void msft_le_monitor_advertisement_cb (struct hci_dev * hdev ,
208240 u8 status , u16 opcode ,
209241 struct sk_buff * skb )
@@ -294,6 +326,10 @@ static void msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev,
294326 if (monitor && !msft -> suspending )
295327 hci_free_adv_monitor (hdev , monitor );
296328
329+ /* Clear any monitored devices by this Adv Monitor */
330+ msft_monitor_device_del (hdev , handle_data -> mgmt_handle , NULL ,
331+ 0 );
332+
297333 list_del (& handle_data -> list );
298334 kfree (handle_data );
299335 }
@@ -557,6 +593,13 @@ void msft_do_close(struct hci_dev *hdev)
557593 list_del (& handle_data -> list );
558594 kfree (handle_data );
559595 }
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 );
560603}
561604
562605void msft_register (struct hci_dev * hdev )
@@ -590,10 +633,97 @@ void msft_unregister(struct hci_dev *hdev)
590633 kfree (msft );
591634}
592635
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+
593722void msft_vendor_evt (struct hci_dev * hdev , void * data , struct sk_buff * skb )
594723{
595724 struct msft_data * msft = hdev -> msft_data ;
596- u8 event ;
725+ u8 * evt_prefix ;
726+ u8 * evt ;
597727
598728 if (!msft )
599729 return ;
@@ -602,13 +732,12 @@ void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb)
602732 * matches, and otherwise just return.
603733 */
604734 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 )
606737 return ;
607738
608- if (memcmp (skb -> data , msft -> evt_prefix , msft -> evt_prefix_len ))
739+ if (memcmp (evt_prefix , msft -> evt_prefix , msft -> evt_prefix_len ))
609740 return ;
610-
611- skb_pull (skb , msft -> evt_prefix_len );
612741 }
613742
614743 /* 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)
617746 if (skb -> len < 1 )
618747 return ;
619748
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 ;
622759
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 );
624766}
625767
626768__u64 msft_get_features (struct hci_dev * hdev )
0 commit comments