diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 81 |
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 */ |
485 | static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | 485 | static 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 */ |
509 | static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) | 514 | static 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 */ | ||
898 | static 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 | |||
868 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 915 | void 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); |