Lines 39-44
Link Here
|
39 |
#include <errno.h> |
39 |
#include <errno.h> |
40 |
#include <netgraph/ng_message.h> |
40 |
#include <netgraph/ng_message.h> |
41 |
#include <errno.h> |
41 |
#include <errno.h> |
|
|
42 |
#include <stdbool.h> |
42 |
#include <stdio.h> |
43 |
#include <stdio.h> |
43 |
#include <stdlib.h> |
44 |
#include <stdlib.h> |
44 |
#include <string.h> |
45 |
#include <string.h> |
Lines 60-65
Link Here
|
60 |
static int le_set_advertising_enable(int s, int argc, char *argv[]); |
61 |
static int le_set_advertising_enable(int s, int argc, char *argv[]); |
61 |
static int le_set_advertising_param(int s, int argc, char *argv[]); |
62 |
static int le_set_advertising_param(int s, int argc, char *argv[]); |
62 |
static int le_read_advertising_channel_tx_power(int s, int argc, char *argv[]); |
63 |
static int le_read_advertising_channel_tx_power(int s, int argc, char *argv[]); |
|
|
64 |
static int le_scan(int s, int argc, char *argv[]); |
65 |
static void handle_le_event(ng_hci_event_pkt_t* e, bool verbose); |
63 |
|
66 |
|
64 |
static int |
67 |
static int |
65 |
le_set_scan_param(int s, int argc, char *argv[]) |
68 |
le_set_scan_param(int s, int argc, char *argv[]) |
Lines 613-618
Link Here
|
613 |
return (OK); |
616 |
return (OK); |
614 |
} |
617 |
} |
615 |
|
618 |
|
|
|
619 |
static int |
620 |
le_scan(int s, int argc, char *argv[]) |
621 |
{ |
622 |
int n, bufsize, scancount, numscans; |
623 |
bool verbose; |
624 |
uint8_t active = 0; |
625 |
char ch; |
626 |
|
627 |
char b[512]; |
628 |
ng_hci_event_pkt_t *e = (ng_hci_event_pkt_t *) b; |
629 |
|
630 |
ng_hci_le_set_scan_parameters_cp scan_param_cp; |
631 |
ng_hci_le_set_scan_parameters_rp scan_param_rp; |
632 |
|
633 |
ng_hci_le_set_scan_enable_cp scan_enable_cp; |
634 |
ng_hci_le_set_scan_enable_rp scan_enable_rp; |
635 |
|
636 |
optreset = 1; |
637 |
optind = 0; |
638 |
verbose = false; |
639 |
numscans = 1; |
640 |
|
641 |
while ((ch = getopt(argc, argv , "an:v")) != -1) { |
642 |
switch(ch) { |
643 |
case 'a': |
644 |
active = 1; |
645 |
break; |
646 |
case 'n': |
647 |
numscans = (uint8_t)strtol(optarg, NULL, 10); |
648 |
break; |
649 |
case 'v': |
650 |
verbose = true; |
651 |
break; |
652 |
} |
653 |
} |
654 |
|
655 |
scan_param_cp.le_scan_type = active; |
656 |
scan_param_cp.le_scan_interval = (uint16_t)(100/0.625); |
657 |
scan_param_cp.le_scan_window = (uint16_t)(50/0.625); |
658 |
/* Address type public */ |
659 |
scan_param_cp.own_address_type = 0; |
660 |
/* 'All' filter policy */ |
661 |
scan_param_cp.scanning_filter_policy = 0; |
662 |
n = sizeof(scan_param_rp); |
663 |
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, |
664 |
NG_HCI_OCF_LE_SET_SCAN_PARAMETERS), |
665 |
(void *)&scan_param_cp, sizeof(scan_param_cp), |
666 |
(void *)&scan_param_rp, &n) == ERROR) |
667 |
return (ERROR); |
668 |
|
669 |
if (scan_param_rp.status != 0x00) { |
670 |
fprintf(stdout, "LE_Set_Scan_Parameters failed. Status: %s [%#02x]\n", |
671 |
hci_status2str(scan_param_rp.status), |
672 |
scan_param_rp.status); |
673 |
return (FAILED); |
674 |
} |
675 |
|
676 |
/* Enable scanning */ |
677 |
n = sizeof(scan_enable_rp); |
678 |
scan_enable_cp.le_scan_enable = 1; |
679 |
scan_enable_cp.filter_duplicates = 1; |
680 |
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, |
681 |
NG_HCI_OCF_LE_SET_SCAN_ENABLE), |
682 |
(void *)&scan_enable_cp, sizeof(scan_enable_cp), |
683 |
(void *)&scan_enable_rp, &n) == ERROR) |
684 |
return (ERROR); |
685 |
|
686 |
if (scan_enable_rp.status != 0x00) { |
687 |
fprintf(stdout, "LE_Scan_Enable enable failed. Status: %s [%#02x]\n", |
688 |
hci_status2str(scan_enable_rp.status), |
689 |
scan_enable_rp.status); |
690 |
return (FAILED); |
691 |
} |
692 |
/* Set event mask */ |
693 |
set_event_mask(s, NG_HCI_EVENT_MASK_DEFAULT | |
694 |
NG_HCI_EVENT_MASK_LE); |
695 |
set_le_event_mask(s, NG_HCI_LE_EVENT_MASK_ALL); |
696 |
|
697 |
|
698 |
scancount = 0; |
699 |
while (scancount < numscans) { |
700 |
/* wait for scan events */ |
701 |
bufsize = sizeof(b); |
702 |
if (hci_recv(s, b, &bufsize) == ERROR) { |
703 |
return (ERROR); |
704 |
} |
705 |
|
706 |
if (bufsize < sizeof(*e)) { |
707 |
errno = EIO; |
708 |
return (ERROR); |
709 |
} |
710 |
scancount++; |
711 |
if (e->event == NG_HCI_EVENT_LE) { |
712 |
fprintf(stdout, "Scan %d\n", scancount); |
713 |
handle_le_event(e, verbose); |
714 |
} |
715 |
} |
716 |
|
717 |
fprintf(stdout, "Scan complete\n"); |
718 |
/* Clear event mask */ |
719 |
set_event_mask(s, NG_HCI_EVENT_MASK_DEFAULT); |
720 |
|
721 |
|
722 |
/* Disable scanning */ |
723 |
n = sizeof(scan_enable_rp); |
724 |
scan_enable_cp.le_scan_enable = 0; |
725 |
if (hci_request(s, NG_HCI_OPCODE(NG_HCI_OGF_LE, |
726 |
NG_HCI_OCF_LE_SET_SCAN_ENABLE), |
727 |
(void *)&scan_enable_cp, sizeof(scan_enable_cp), |
728 |
(void *)&scan_enable_rp, &n) == ERROR) |
729 |
return (ERROR); |
730 |
|
731 |
if (scan_enable_rp.status != 0x00) { |
732 |
fprintf(stdout, "LE_Scan_Enable disable failed. Status: %s [%#02x]\n", |
733 |
hci_status2str(scan_enable_rp.status), |
734 |
scan_enable_rp.status); |
735 |
return (FAILED); |
736 |
} |
737 |
|
738 |
return (OK); |
739 |
} |
740 |
|
741 |
static void handle_le_event(ng_hci_event_pkt_t* e, bool verbose) |
742 |
{ |
743 |
int rc; |
744 |
ng_hci_le_ep *leer = |
745 |
(ng_hci_le_ep *)(e + 1); |
746 |
ng_hci_le_advertising_report_ep *advrep = |
747 |
(ng_hci_le_advertising_report_ep *)(leer + 1); |
748 |
ng_hci_le_advreport *reports = |
749 |
(ng_hci_le_advreport *)(advrep + 1); |
750 |
|
751 |
if (leer->subevent_code == NG_HCI_LEEV_ADVREP) { |
752 |
fprintf(stdout, "Scan result, num_reports: %d\n", |
753 |
advrep->num_reports); |
754 |
for(rc = 0; rc < advrep->num_reports; rc++) { |
755 |
uint8_t length = (uint8_t)reports[rc].length_data; |
756 |
fprintf(stdout, "\tBD_ADDR %s \n", |
757 |
hci_bdaddr2str(&reports[rc].bdaddr)); |
758 |
fprintf(stdout, "\tAddress type: %s\n", |
759 |
hci_addrtype2str(reports[rc].addr_type)); |
760 |
if (length > 0 && verbose) { |
761 |
dump_adv_data(length, reports[rc].data); |
762 |
print_adv_data(length, reports[rc].data); |
763 |
} |
764 |
} |
765 |
} |
766 |
} |
767 |
|
616 |
struct hci_command le_commands[] = { |
768 |
struct hci_command le_commands[] = { |
617 |
{ |
769 |
{ |
618 |
"le_enable", |
770 |
"le_enable", |
Lines 685-688
Link Here
|
685 |
"Read the maximum size of ACL and ISO data packets", |
837 |
"Read the maximum size of ACL and ISO data packets", |
686 |
&le_read_buffer_size |
838 |
&le_read_buffer_size |
687 |
}, |
839 |
}, |
|
|
840 |
{ |
841 |
"le_scan", |
842 |
"le_scan [-a] [-v] [-n number_of_scans]\n" |
843 |
"Do an LE scan", |
844 |
&le_scan |
845 |
}, |
688 |
}; |
846 |
}; |