diff options
-rw-r--r-- | include/net/bluetooth/hci.h | 9 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 55 |
2 files changed, 51 insertions, 13 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 6f0706f4af68..cd075f197983 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -453,6 +453,15 @@ struct inquiry_info_with_rssi { | |||
453 | __u16 clock_offset; | 453 | __u16 clock_offset; |
454 | __s8 rssi; | 454 | __s8 rssi; |
455 | } __attribute__ ((packed)); | 455 | } __attribute__ ((packed)); |
456 | struct inquiry_info_with_rssi_and_pscan_mode { | ||
457 | bdaddr_t bdaddr; | ||
458 | __u8 pscan_rep_mode; | ||
459 | __u8 pscan_period_mode; | ||
460 | __u8 pscan_mode; | ||
461 | __u8 dev_class[3]; | ||
462 | __u16 clock_offset; | ||
463 | __s8 rssi; | ||
464 | } __attribute__ ((packed)); | ||
456 | 465 | ||
457 | #define HCI_EV_CONN_COMPLETE 0x03 | 466 | #define HCI_EV_CONN_COMPLETE 0x03 |
458 | struct hci_ev_conn_complete { | 467 | struct hci_ev_conn_complete { |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 46367bd129c3..632f7a9c2bcb 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 | ||