aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c81
1 files changed, 66 insertions, 15 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 46367bd129c3..d6da0939216d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -484,14 +484,18 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
484/* Inquiry Result */ 484/* Inquiry Result */
485static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) 485static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
486{ 486{
487 struct inquiry_data data;
487 struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1); 488 struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1);
488 int num_rsp = *((__u8 *) skb->data); 489 int num_rsp = *((__u8 *) skb->data);
489 490
490 BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 491 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
491 492
493 if (!num_rsp)
494 return;
495
492 hci_dev_lock(hdev); 496 hci_dev_lock(hdev);
497
493 for (; num_rsp; num_rsp--) { 498 for (; num_rsp; num_rsp--) {
494 struct inquiry_data data;
495 bacpy(&data.bdaddr, &info->bdaddr); 499 bacpy(&data.bdaddr, &info->bdaddr);
496 data.pscan_rep_mode = info->pscan_rep_mode; 500 data.pscan_rep_mode = info->pscan_rep_mode;
497 data.pscan_period_mode = info->pscan_period_mode; 501 data.pscan_period_mode = info->pscan_period_mode;
@@ -502,30 +506,55 @@ static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *
502 info++; 506 info++;
503 hci_inquiry_cache_update(hdev, &data); 507 hci_inquiry_cache_update(hdev, &data);
504 } 508 }
509
505 hci_dev_unlock(hdev); 510 hci_dev_unlock(hdev);
506} 511}
507 512
508/* Inquiry Result With RSSI */ 513/* Inquiry Result With RSSI */
509static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) 514static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
510{ 515{
511 struct inquiry_info_with_rssi *info = (struct inquiry_info_with_rssi *) (skb->data + 1); 516 struct inquiry_data data;
512 int num_rsp = *((__u8 *) skb->data); 517 int num_rsp = *((__u8 *) skb->data);
513 518
514 BT_DBG("%s num_rsp %d", hdev->name, num_rsp); 519 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
515 520
521 if (!num_rsp)
522 return;
523
516 hci_dev_lock(hdev); 524 hci_dev_lock(hdev);
517 for (; num_rsp; num_rsp--) { 525
518 struct inquiry_data data; 526 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
519 bacpy(&data.bdaddr, &info->bdaddr); 527 struct inquiry_info_with_rssi_and_pscan_mode *info =
520 data.pscan_rep_mode = info->pscan_rep_mode; 528 (struct inquiry_info_with_rssi_and_pscan_mode *) (skb->data + 1);
521 data.pscan_period_mode = info->pscan_period_mode; 529
522 data.pscan_mode = 0x00; 530 for (; num_rsp; num_rsp--) {
523 memcpy(data.dev_class, info->dev_class, 3); 531 bacpy(&data.bdaddr, &info->bdaddr);
524 data.clock_offset = info->clock_offset; 532 data.pscan_rep_mode = info->pscan_rep_mode;
525 data.rssi = info->rssi; 533 data.pscan_period_mode = info->pscan_period_mode;
526 info++; 534 data.pscan_mode = info->pscan_mode;
527 hci_inquiry_cache_update(hdev, &data); 535 memcpy(data.dev_class, info->dev_class, 3);
536 data.clock_offset = info->clock_offset;
537 data.rssi = info->rssi;
538 info++;
539 hci_inquiry_cache_update(hdev, &data);
540 }
541 } else {
542 struct inquiry_info_with_rssi *info =
543 (struct inquiry_info_with_rssi *) (skb->data + 1);
544
545 for (; num_rsp; num_rsp--) {
546 bacpy(&data.bdaddr, &info->bdaddr);
547 data.pscan_rep_mode = info->pscan_rep_mode;
548 data.pscan_period_mode = info->pscan_period_mode;
549 data.pscan_mode = 0x00;
550 memcpy(data.dev_class, info->dev_class, 3);
551 data.clock_offset = info->clock_offset;
552 data.rssi = info->rssi;
553 info++;
554 hci_inquiry_cache_update(hdev, &data);
555 }
528 } 556 }
557
529 hci_dev_unlock(hdev); 558 hci_dev_unlock(hdev);
530} 559}
531 560
@@ -865,6 +894,24 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
865 hci_dev_unlock(hdev); 894 hci_dev_unlock(hdev);
866} 895}
867 896
897/* Page Scan Repetition Mode */
898static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
899{
900 struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
901 struct inquiry_entry *ie;
902
903 BT_DBG("%s", hdev->name);
904
905 hci_dev_lock(hdev);
906
907 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
908 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
909 ie->timestamp = jiffies;
910 }
911
912 hci_dev_unlock(hdev);
913}
914
868void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 915void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
869{ 916{
870 struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; 917 struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
@@ -937,6 +984,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
937 hci_clock_offset_evt(hdev, skb); 984 hci_clock_offset_evt(hdev, skb);
938 break; 985 break;
939 986
987 case HCI_EV_PSCAN_REP_MODE:
988 hci_pscan_rep_mode_evt(hdev, skb);
989 break;
990
940 case HCI_EV_CMD_STATUS: 991 case HCI_EV_CMD_STATUS:
941 cs = (struct hci_ev_cmd_status *) skb->data; 992 cs = (struct hci_ev_cmd_status *) skb->data;
942 skb_pull(skb, sizeof(cs)); 993 skb_pull(skb, sizeof(cs));
@@ -1036,9 +1087,9 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
1036 memcpy(ev->data, data, dlen); 1087 memcpy(ev->data, data, dlen);
1037 1088
1038 bt_cb(skb)->incoming = 1; 1089 bt_cb(skb)->incoming = 1;
1039 do_gettimeofday(&skb->stamp); 1090 __net_timestamp(skb);
1040 1091
1041 skb->pkt_type = HCI_EVENT_PKT; 1092 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
1042 skb->dev = (void *) hdev; 1093 skb->dev = (void *) hdev;
1043 hci_send_to_sock(hdev, skb); 1094 hci_send_to_sock(hdev, skb);
1044 kfree_skb(skb); 1095 kfree_skb(skb);