This patch adds the option [--discovery=g|l] to lescan command. Use
this option to enable the general or limited discovery procedure.
If discovery option is not given scanning will display all results
ignoring the AD flags.
---
tools/hcitool.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/tools/hcitool.c b/tools/hcitool.c
index d7a82cc..cb7d181 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -49,6 +49,10 @@
/* Unofficial value, might still change */
#define LE_LINK 0x03
+#define FLAGS_AD_TYPE 0x01
+#define FLAGS_LIMITED_MODE_BIT 0x01
+#define FLAGS_GENERAL_MODE_BIT 0x02
+
#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1)
static void usage(void);
@@ -2287,7 +2291,62 @@ static void cmd_clock(int dev_id, int argc, char **argv)
hci_close_dev(dd);
}
-static int print_advertising_devices(int dd)
+static int read_flags(uint8_t *flags, const uint8_t *data, size_t size)
+{
+ unsigned int offset;
+
+ if (!flags || !data)
+ return -EINVAL;
+
+ offset = 0;
+ while (offset < size) {
+ uint8_t len = data[offset];
+ uint8_t type = data[offset + 1];
+
+ /* Check if it is the end of the significant part */
+ if (len == 0)
+ break;
+
+ if (type == FLAGS_AD_TYPE) {
+ *flags = data[offset + 2];
+ return 0;
+ }
+
+ offset += 1 + len;
+ }
+
+ return -ENOENT;
+}
+
+static int check_report_filter(uint8_t procedure, le_advertising_info *info)
+{
+ uint8_t flags;
+
+ /* If no discovery procedure is set, all reports are treat as valid */
+ if (procedure == 0)
+ return 1;
+
+ /* Read flags AD type value from the advertising report if it exists */
+ if (read_flags(&flags, info->data, info->length))
+ return 0;
+
+ switch (procedure) {
+ case 'l': /* Limited Discovery Procedure */
+ if (flags & FLAGS_LIMITED_MODE_BIT)
+ return 1;
+ break;
+ case 'g': /* General Discovery Procedure */
+ if (flags & (FLAGS_LIMITED_MODE_BIT | FLAGS_GENERAL_MODE_BIT))
+ return 1;
+ break;
+ default:
+ fprintf(stderr, "Unknown discovery procedure\n");
+ }
+
+ return 0;
+}
+
+static int print_advertising_devices(int dd, uint8_t filter_type)
{
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr;
struct hci_filter nf, of;
@@ -2334,8 +2393,10 @@ static int print_advertising_devices(int dd)
/* Ignoring multiple reports */
info = (le_advertising_info *) (meta->data + 1);
- ba2str(&info->bdaddr, addr);
- printf("%s\n", addr);
+ if (check_report_filter(filter_type, info)) {
+ ba2str(&info->bdaddr, addr);
+ printf("%s\n", addr);
+ }
}
done:
@@ -2351,19 +2412,23 @@ static struct option lescan_options[] = {
{ "help", 0, 0, 'h' },
{ "privacy", 0, 0, 'p' },
{ "passive", 0, 0, 'P' },
+ { "discovery", 1, 0, 'd' },
{ 0, 0, 0, 0 }
};
static const char *lescan_help =
"Usage:\n"
"\tlescan [--privacy] enable privacy\n"
- "\tlescan [--passive] set scan type passive (default active)\n";
+ "\tlescan [--passive] set scan type passive (default active)\n"
+ "\tlescan [--discovery=g|l] enable general or limited discovery"
+ "procedure\n";
static void cmd_lescan(int dev_id, int argc, char **argv)
{
int err, opt, dd;
uint8_t own_type = 0x00;
uint8_t scan_type = 0x01;
+ uint8_t filter_type = 0;
for_each_opt(opt, lescan_options, NULL) {
switch (opt) {
@@ -2373,6 +2438,13 @@ static void cmd_lescan(int dev_id, int argc, char **argv)
case 'P':
scan_type = 0x00; /* Passive */
break;
+ case 'd':
+ filter_type = optarg[0];
+ if (filter_type != 'g' && filter_type != 'l') {
+ fprintf(stderr, "Unknown discovery procedure\n");
+ exit(1);
+ }
+ break;
default:
printf("%s", lescan_help);
return;
@@ -2404,7 +2476,7 @@ static void cmd_lescan(int dev_id, int argc, char **argv)
printf("LE Scan ...\n");
- err = print_advertising_devices(dd);
+ err = print_advertising_devices(dd, filter_type);
if (err < 0) {
perror("Could not receive advertising events");
exit(1);
--
1.7.1
Hi,
On Thu, Feb 24, 2011, Anderson Lizardo wrote:
> On Wed, Feb 23, 2011 at 11:54 PM, Johan Hedberg <[email protected]> wrote:
> > Hi Andr?,
> >
> > On Wed, Feb 23, 2011, Andre Guedes wrote:
> >> + ? ? "\tlescan [--discovery=g|l] enable general or limited discovery"
> >
> > To make this consistent with the other options please default to general
> > and have a --limited switch to enable limited discovery.
>
> Note that there are actually three modes:
>
> 1) the default one, when no parameters are given: do not filter
> anything, useful for debugging (this is what is currently done)
> 2) limited discovery
> 3) general discovery
>
> limited/general are done according to the procedure description on the spec.
Ok, then the patch makes sense. It has now been pushed upstream.
Johan
Hi Johan,
On Wed, Feb 23, 2011 at 11:54 PM, Johan Hedberg <[email protected]> wrote:
> Hi Andr?,
>
> On Wed, Feb 23, 2011, Andre Guedes wrote:
>> + ? ? "\tlescan [--discovery=g|l] enable general or limited discovery"
>
> To make this consistent with the other options please default to general
> and have a --limited switch to enable limited discovery.
Note that there are actually three modes:
1) the default one, when no parameters are given: do not filter
anything, useful for debugging (this is what is currently done)
2) limited discovery
3) general discovery
limited/general are done according to the procedure description on the spec.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
Hi Andr?,
On Wed, Feb 23, 2011, Andre Guedes wrote:
> + "\tlescan [--discovery=g|l] enable general or limited discovery"
To make this consistent with the other options please default to general
and have a --limited switch to enable limited discovery.
Johan