2011-02-23 21:16:28

by Andre Guedes

[permalink] [raw]
Subject: [PATCH] hcitool: add discovery procedure to lescan command

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



2011-02-24 20:40:07

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH] hcitool: add discovery procedure to lescan command

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

2011-02-24 11:32:35

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [PATCH] hcitool: add discovery procedure to lescan command

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

2011-02-24 02:54:37

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH] hcitool: add discovery procedure to lescan command

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