2011-01-06 03:52:37

by Sumit Kumar BAJPAI

[permalink] [raw]
Subject: [PATCH] HCI Commands for LE White List

Added HCI commands for LE White List support.
These LE White List Commands can be tested from
hcitool.


---
lib/hci.c | 107 +++++++++++++++++++++++++++++++
lib/hci_lib.h | 4 +
tools/hcitool.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 297 insertions(+), 0 deletions(-)
mode change 100644 => 100755 lib/hci.c
mode change 100644 => 100755 lib/hci_lib.h

diff --git a/lib/hci.c b/lib/hci.c
old mode 100644
new mode 100755
index 048fda4..5a0275c
--- a/lib/hci.c
+++ b/lib/hci.c
@@ -1291,6 +1291,113 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to)
return 0;
}

+int hci_le_add_to_white_list(int dd, bdaddr_t addr, uint8_t type)
+{
+ struct hci_request rq;
+ le_add_device_to_white_list_cp param_cp;
+ uint8_t status;
+
+ memset(&param_cp, 0, sizeof(param_cp));
+ param_cp.bdaddr_type = type;
+ param_cp.bdaddr= addr;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
+ rq.cparam = &param_cp;
+ rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(dd, &rq, 100) < 0)
+ return -1;
+
+ if (status) {
+ errno = EIO;
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_remove_from_white_list(int dd, bdaddr_t addr, uint8_t type)
+{
+ struct hci_request rq;
+ le_remove_device_from_white_list_cp param_cp;
+ uint8_t status;
+
+ memset(&param_cp, 0, sizeof(param_cp));
+ param_cp.bdaddr_type = type;
+ param_cp.bdaddr= addr;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
+ rq.cparam = &param_cp;
+ rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(dd, &rq, 100) < 0)
+ return -1;
+
+ if (status) {
+ errno = EIO;
+ return -1;
+ }
+
+ return 0;
+}
+
+int hci_le_read_white_list_size(int dd)
+{
+ struct hci_request rq;
+ le_read_white_list_size_rp param_cp;
+
+ memset(&param_cp, 0, sizeof(param_cp));
+ param_cp.size=0;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
+ rq.rparam = &param_cp;
+ rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
+
+ if (hci_send_req(dd, &rq, 100) < 0)
+ return -1;
+
+ if (param_cp.status) {
+ errno = EIO;
+ return -1;
+ }
+
+ printf("LE White list size= %d\n", param_cp.size);
+
+ return 0;
+}
+
+int hci_le_clear_white_list(int dd)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(dd, &rq, 100) < 0)
+ return -1;
+
+ if (status) {
+ errno = EIO;
+ return -1;
+ }
+
+ return 0;
+}
+
int hci_read_local_name(int dd, int len, char *name, int to)
{
read_local_name_rp rp;
diff --git a/lib/hci_lib.h b/lib/hci_lib.h
old mode 100644
new mode 100755
index b63a2a4..ed74dfc
--- a/lib/hci_lib.h
+++ b/lib/hci_lib.h
@@ -127,6 +127,10 @@ int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
uint16_t latency, uint16_t supervision_timeout,
uint16_t min_ce_length, uint16_t max_ce_length,
uint16_t *handle, int to);
+int hci_le_add_to_white_list(int dd, bdaddr_t addr, uint8_t type);
+int hci_le_remove_from_white_list(int dd, bdaddr_t addr, uint8_t type);
+int hci_le_read_white_list_size(int dd);
+int hci_le_clear_white_list(int dd);

int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);
int hci_get_route(bdaddr_t *bdaddr);
diff --git a/tools/hcitool.c b/tools/hcitool.c
index d50adaf..387c47c 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -2471,6 +2471,188 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
hci_close_dev(dd);
}

+static struct option leaddwl_options[] = {
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+static const char *leaddwl_help =
+ "Usage:\n"
+ "\tleaddwl <bdaddr>\n";
+
+static void cmd_leaddwl(int dev_id, int argc,char **argv)
+{
+ int err, opt, dd;
+ bdaddr_t bdaddr;
+ uint8_t bdaddr_type;
+
+ for_each_opt(opt, leaddwl_options, NULL) {
+ switch (opt) {
+ default:
+ printf("%s", leaddwl_help);
+ return;
+ }
+ }
+ helper_arg(1, 1, &argc, &argv, leaddwl_help);
+
+ if (dev_id < 0)
+ dev_id = hci_get_route(NULL);
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ perror("Could not open device");
+ exit(1);
+ }
+
+ str2ba(argv[1], &bdaddr);
+ bdaddr_type = 0x00;
+
+ err = hci_le_add_to_white_list(dd, bdaddr ,bdaddr_type);
+ if (err < 0) {
+ perror("Cant add to white list");
+ exit(1);
+ }
+ else {
+ printf("Device added to white list");
+ }
+
+ hci_close_dev(dd);
+
+}
+
+static struct option lermwl_options[] = {
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+static const char *lermwl_help =
+ "Usage:\n"
+ "\tlermwl <bdaddr>\n";
+
+static void cmd_lermwl(int dev_id, int argc,char **argv)
+{
+ int err, opt, dd;
+ bdaddr_t bdaddr;
+ uint8_t bdaddr_type;
+
+ for_each_opt(opt, lermwl_options, NULL) {
+ switch (opt) {
+ default:
+ printf("%s", lermwl_help);
+ return;
+ }
+ }
+ helper_arg(1, 1, &argc, &argv, lermwl_help);
+
+ if (dev_id < 0)
+ dev_id = hci_get_route(NULL);
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ perror("Could not open device");
+ exit(1);
+ }
+
+ str2ba(argv[1], &bdaddr);
+ bdaddr_type = 0x00;
+
+ err = hci_le_remove_from_white_list(dd, bdaddr ,bdaddr_type);
+ if (err < 0) {
+ perror("Cant remove from white list");
+ exit(1);
+ }
+ else {
+ printf("Device removed from white list");
+ }
+
+ hci_close_dev(dd);
+
+}
+
+static struct option lerdwlsz_options[] = {
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+static const char *lerdwlsz_help =
+ "Usage:\n"
+ "\tlerdwlsz\n";
+
+static void cmd_lerdwlsz(int dev_id, int argc,char **argv)
+{
+ int err,dd, opt;
+
+ for_each_opt(opt, lerdwlsz_options, NULL) {
+ switch (opt) {
+ default:
+ printf("%s", lerdwlsz_help);
+ return;
+ }
+ }
+ helper_arg(0, 0, &argc, &argv, lermwl_help);
+
+ if (dev_id < 0)
+ dev_id = hci_get_route(NULL);
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ perror("Could not open device");
+ exit(1);
+ }
+
+ err = hci_le_read_white_list_size(dd);
+ if (err < 0) {
+ perror("Cant read white list size");
+ exit(1);
+ }
+
+ hci_close_dev(dd);
+
+}
+
+
+static struct option leclrwl_options[] = {
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+static const char *leclrwl_help =
+ "Usage:\n"
+ "\tleclrwl\n";
+
+static void cmd_leclrwl(int dev_id, int argc,char **argv)
+{
+ int err,dd, opt;
+
+ for_each_opt(opt, leclrwl_options, NULL) {
+ switch (opt) {
+ default:
+ printf("%s", leclrwl_help);
+ return;
+ }
+ }
+ helper_arg(0, 0, &argc, &argv, leclrwl_help);
+
+ if (dev_id < 0)
+ dev_id = hci_get_route(NULL);
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ perror("Could not open device");
+ exit(1);
+ }
+
+ err = hci_le_clear_white_list(dd);
+ if (err < 0) {
+ perror("Cant clear white list");
+ exit(1);
+ }
+
+ hci_close_dev(dd);
+
+}
+
+
static struct option ledc_options[] = {
{ "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
@@ -2547,6 +2729,10 @@ static struct {
{ "clkoff", cmd_clkoff, "Read clock offset" },
{ "clock", cmd_clock, "Read local or remote clock" },
{ "lescan", cmd_lescan, "Start LE scan" },
+ { "leaddwl", cmd_leaddwl, "Add this device to white list" },
+ { "lermwl", cmd_lermwl, "Remove this device from white list" },
+ { "lerdwlsz", cmd_lerdwlsz, "Read white list size" },
+ { "leclrwl", cmd_leclrwl, "Clear white list" },
{ "lecc", cmd_lecc, "Create a LE Connection", },
{ "ledc", cmd_ledc, "Disconnect a LE Connection", },
{ NULL, NULL, 0 }
--
1.6.5




2011-01-24 09:56:04

by Sumit Kumar BAJPAI

[permalink] [raw]
Subject: RE: [PATCH] HCI Commands for LE White List

SGkgQ2xhdWRpbywgDQoNCg0KIA0KPiA8c25pcD4NCj4gDQo+ID4gSXMgdXNpbmcgYSBzZXBhcmF0
ZSB2YXJpYWJsZSBlcnIgZm9yIHJldHVybiB0eXBlIG9mIGEgZnVuY3Rpb24NCj4gcHJvYmxlbSBo
ZXJlPw0KPiBJIGRpZG4ndCB1bmRlcnN0YW5kIHlvdXIgcXVlc3Rpb24gaGVyZS4NCj4gaGNpXyog
ZnVuY3Rpb25zIHJldHVybiAwIG9uIHN1Y2Nlc3Mgb3IgLTEgb24gZmFpbHVyZS4gT24gZmFpbHVy
ZSBlcnJubw0KPiBjYW4gYmUgcmVhZCB0byBnZXQgdGhlIGVycm9yIG51bWJlci4NCj4gDQo+ID4g
SSBjb3VsZCBzZWUgc2FtZSBjb2Rpbmcgc3R5bGUgb2YgZGVmaW5pbmcgYSB2YXJpYWJsZSB0byBj
YXJyeSB0aGUNCj4gZXJyb3Igc3RhdHVzIGluIGhjaXRvb2wuYyBmdW5jdGlvbiBjbWRfbGVjYy4N
Cj4gPiBQbGVhc2UgY29uZmlybS4NCj4gVGhlIGNvZGluZyBzdHlsZSBpc3N1ZSBpcyB0aGUgaWYg
ZWxzZToNCj4gQXQgdGhpcyBwb2ludCAiZWxzZSIgaXMgbm90IG5lZWRlZDogdGhlcmUgaXMgYSAi
ZXhpdCgxKSIgaW5zaWRlIHRoZQ0KPiAiaWYiIGJsb2NrLiBCdXQgaWYgeW91IG5lZWQgZWxzZSB0
aGUgY29ycmVjdCBjb2Rpbmcgc3R5bGUgaXM6DQo+IC4uLg0KPiB9IGVsc2Ugew0KPiAuLi4NCj4g
DQo+IEluc3RlYWQgb2YNCj4gLi4uDQo+IH0NCj4gZWxzZSB7DQo+IC4uLg0KPiANCj4gPHNuaXA+
DQo+IA0KPiA+PiA+ICsgwqAgwqAgwqAgZXJyID0gaGNpX2xlX3JlbW92ZV9mcm9tX3doaXRlX2xp
c3QoZGQsIGJkYWRkcg0KPiAsYmRhZGRyX3R5cGUpOw0KPiA+PiA+ICsgwqAgwqAgwqAgaWYgKGVy
ciA8IDApIHsNCj4gPj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHBlcnJvcigiQ2FudCByZW1v
dmUgZnJvbSB3aGl0ZSBsaXN0Iik7DQo+ID4+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBleGl0
KDEpOw0KPiA+PiA+ICsgwqAgwqAgwqAgfQ0KPiA+PiA+ICsgwqAgwqAgwqAgwqBlbHNlIHsNCj4g
Pj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHByaW50ZigiRGV2aWNlIHJlbW92ZWQgZnJvbSB3
aGl0ZSBsaXN0Iik7DQo+ID4+ID4gKyDCoCDCoCDCoCB9DQo+ID4+ID4gKw0KPiA+PiA+ICsgwqAg
wqAgwqAgaGNpX2Nsb3NlX2RldihkZCk7DQo+ID4+IFNhbWUgY29kaW5nIHN0eWxlIGlzc3VlIGFu
ZCBjbG9zZSAiZGQiDQo+ID4+DQo+ID4NCj4gPg0KPiA+IE9rLiBHb29kIHBvaW50LiBCdXQgSSBj
b3VsZCBzdGlsbCBmaW5kIHByZW1hdHVyZSByZXR1cm5zIG9uIGVycm9yDQo+IGNvbmRpdGlvbnMg
dmlhIGV4aXRzIGF0IHNldmVyYWwgcGxhY2VzIGluIGhjaXRvb2wuYy4gQ2FuIEkgc3VibWl0IGEN
Cj4gc2VwYXJhdGUgcGF0Y2ggZm9yIHJlY3RpZnlpbmcgYWxsIHN1Y2ggZXJyb3IgY29uZGl0aW9u
cyB0b28/DQo+IA0KPiBzdXJlIQ0KPiANCg0KQXMgcGVyIHlvdXIgY29tbWVudHMsIEkgYW0gcG9z
dGluZyA0IHBhdGNoZXMgc2VwYXJhdGVseS4gDQo=

2011-01-17 17:27:43

by Claudio Takahasi

[permalink] [raw]
Subject: Re: [PATCH] HCI Commands for LE White List

Hi Sumit,

<snip>

> Is using a separate variable err for return type of a function problem here?
I didn't understand your question here.
hci_* functions return 0 on success or -1 on failure. On failure errno
can be read to get the error number.

> I could see same coding style of defining a variable to carry the error status in hcitool.c function cmd_lecc.
> Please confirm.
The coding style issue is the if else:
At this point "else" is not needed: there is a "exit(1)" inside the
"if" block. But if you need else the correct coding style is:
...
} else {
...

Instead of
...
}
else {
...

<snip>

>> > +       err = hci_le_remove_from_white_list(dd, bdaddr ,bdaddr_type);
>> > +       if (err < 0) {
>> > +               perror("Cant remove from white list");
>> > +               exit(1);
>> > +       }
>> > +        else {
>> > +               printf("Device removed from white list");
>> > +       }
>> > +
>> > +       hci_close_dev(dd);
>> Same coding style issue and close "dd"
>>
>
>
> Ok. Good point. But I could still find premature returns on error conditions via exits at several places in hcitool.c. Can I submit a separate patch for rectifying all such error conditions too?

sure!

Claudio

2011-01-12 08:21:26

by Sumit Kumar BAJPAI

[permalink] [raw]
Subject: RE: [PATCH] HCI Commands for LE White List

SGkgQ2xhdWRpbywNCg0KIA0KPiBDb3VsZCB5b3UgcGxlYXNlIHNwbGl0IHRoaXMgcGF0Y2ggaW50
byBtaW5vciBmdW5jdGlvbmFsIHBhdGNoZXM/DQpPay4gV291bGQgcmVzdWJtaXQgZm91ciBwYXRj
aGVzIG5vdy1vbmUgZWFjaCBmb3IgQWRkIERldmljZSwgUmVtb3ZlIERldmljZSwgQ2xlYXIgV2hp
dGUgTGlzdCBhbmQgUmVhZCBXaGl0ZSBMaXN0IHNpemUuDQoNCj4gDQo+IE9uIFRodSwgSmFuIDYs
IDIwMTEgYXQgMTI6NTIgQU0sIFN1bWl0IEt1bWFyIEJBSlBBSQ0KPiA8c3VtaXRrdW1hci5iYWpw
YWlAc3Rlcmljc3Nvbi5jb20+IHdyb3RlOg0KPiA+IEFkZGVkIEhDSSBjb21tYW5kcyBmb3IgTEUg
V2hpdGUgTGlzdCBzdXBwb3J0Lg0KPiA+IFRoZXNlIExFIFdoaXRlIExpc3QgQ29tbWFuZHMgY2Fu
IGJlIHRlc3RlZCBmcm9tDQo+ID4gaGNpdG9vbC4NCj4gPg0KPiA+DQo+ID4gLS0tDQo+ID4gwqBs
aWIvaGNpLmMgwqAgwqAgwqAgfCDCoDEwNyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
DQo+ID4gwqBsaWIvaGNpX2xpYi5oIMKgIHwgwqAgwqA0ICsNCj4gPiDCoHRvb2xzL2hjaXRvb2wu
YyB8IMKgMTg2DQo+ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysNCj4gPiDCoDMgZmlsZXMgY2hhbmdlZCwgMjk3IGluc2VydGlvbnMoKyksIDAg
ZGVsZXRpb25zKC0pDQo+ID4gwqBtb2RlIGNoYW5nZSAxMDA2NDQgPT4gMTAwNzU1IGxpYi9oY2ku
Yw0KPiA+IMKgbW9kZSBjaGFuZ2UgMTAwNjQ0ID0+IDEwMDc1NSBsaWIvaGNpX2xpYi5oDQo+ID4N
Cj4gPiBkaWZmIC0tZ2l0IGEvbGliL2hjaS5jIGIvbGliL2hjaS5jDQo+ID4gb2xkIG1vZGUgMTAw
NjQ0DQo+ID4gbmV3IG1vZGUgMTAwNzU1DQo+ID4gaW5kZXggMDQ4ZmRhNC4uNWEwMjc1Yw0KPiA+
IC0tLSBhL2xpYi9oY2kuYw0KPiA+ICsrKyBiL2xpYi9oY2kuYw0KPiA+IEBAIC0xMjkxLDYgKzEy
OTEsMTEzIEBAIGludCBoY2lfZGlzY29ubmVjdChpbnQgZGQsIHVpbnQxNl90IGhhbmRsZSwNCj4g
dWludDhfdCByZWFzb24sIGludCB0bykNCj4gPiDCoCDCoCDCoCDCoHJldHVybiAwOw0KPiA+IMKg
fQ0KPiA+DQo+ID4gK2ludCBoY2lfbGVfYWRkX3RvX3doaXRlX2xpc3QoaW50IGRkLCBiZGFkZHJf
dCBhZGRyLCB1aW50OF90IHR5cGUpDQo+IFVzZSBwb2ludGVyIGZvciBiZGFkZHJfdA0KPiBhZGRy
ZXNzIHR5cGVzIGhhdmUgZGVmaW5lZCB2YWx1ZXMgaW4gdGhlIEJUIHNwZWMsIGRlY2xhcmUgYW4g
ZW51bSBpbg0KPiBoY2kuaA0KPiANCk9rLg0KPiA+ICt7DQo+ID4gKyDCoCDCoCDCoCBzdHJ1Y3Qg
aGNpX3JlcXVlc3QgcnE7DQo+ID4gKyDCoCDCoCDCoCBsZV9hZGRfZGV2aWNlX3RvX3doaXRlX2xp
c3RfY3AgcGFyYW1fY3A7DQo+IEl0IHNlZW1zIHRoYXQgeW91IGNvcGllZCB0aGlzIGRlY2xhcmF0
aW9uIGZyb20gc2V0IHNjYW4gcGFyYW1ldGVycw0KPiBmdW5jdGlvbi4gVXNlIG9ubHkgImNwIiwg
aXQgaXMgc2hvcnQgZm9yIGNvbW1hbmQgcGFyYW1ldGVycy4NCj4gDQpPay4NCj4gPiArIMKgIMKg
IMKgIHVpbnQ4X3Qgc3RhdHVzOw0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIG1lbXNldCgmcGFyYW1f
Y3AsIDAsIHNpemVvZihwYXJhbV9jcCkpOw0KPiA+ICsgwqAgwqAgwqAgcGFyYW1fY3AuYmRhZGRy
X3R5cGUgPSB0eXBlOw0KPiA+ICsgwqAgwqAgwqAgcGFyYW1fY3AuYmRhZGRyPSBhZGRyOw0KPiA+
ICsNCj4gPiArIMKgIMKgIMKgIG1lbXNldCgmcnEsIDAsIHNpemVvZihycSkpOw0KPiA+ICsgwqAg
wqAgwqAgcnEub2dmID0gT0dGX0xFX0NUTDsNCj4gPiArIMKgIMKgIMKgIHJxLm9jZiA9IE9DRl9M
RV9BRERfREVWSUNFX1RPX1dISVRFX0xJU1Q7DQo+ID4gKyDCoCDCoCDCoCBycS5jcGFyYW0gPSAm
cGFyYW1fY3A7DQo+ID4gKyDCoCDCoCDCoCBycS5jbGVuID0gTEVfQUREX0RFVklDRV9UT19XSElU
RV9MSVNUX0NQX1NJWkU7DQo+ID4gKyDCoCDCoCDCoCBycS5ycGFyYW0gPSAmc3RhdHVzOw0KPiA+
ICsgwqAgwqAgwqAgcnEucmxlbiA9IDE7DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgaWYgKGhjaV9z
ZW5kX3JlcShkZCwgJnJxLCAxMDApIDwgMCkNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJl
dHVybiAtMTsNCj4gVXNlIDEwMDAsIHdlIGFyZSBub3RpY2luZyB0aW1lb3V0IG9uIHNvbWUgTEUg
aGFyZHdhcmVzLg0KT2suIGJ1dCB3b3VsZCByZWNvbW1lbmQgZGVmaW5pbmcgaXQgYXMgYSBtYWNy
byBzb21ld2hlcmUgaW4gaGNpLmggZm9yIGVhc3kgbWFuaXB1bGF0aW9uIGxhdGVyLiBXb3VsZCBy
ZS1zdWJtaXQgdGhlIHBhdGNoIHVzaW5nIDEwMDAgZm9yIG5vdy4NCg0KPiA+ICsNCj4gPiArIMKg
IMKgIMKgIGlmIChzdGF0dXMpIHsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVycm5vID0g
RUlPOw0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIC0xOw0KPiA+ICsgwqAgwqAg
wqAgfQ0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIHJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+
ICtpbnQgaGNpX2xlX3JlbW92ZV9mcm9tX3doaXRlX2xpc3QoaW50IGRkLCBiZGFkZHJfdCBhZGRy
LCB1aW50OF90DQo+IHR5cGUpDQo+ID4gK3sNCj4gU2FtZSBjb21tZW50IGFib3V0IGFkZHJlc3Mg
dHlwZSBhbmQgYmRhZGRyX3QgcG9pbnRlcg0KT2suDQo+IA0KPiA+ICsgwqAgwqAgwqAgc3RydWN0
IGhjaV9yZXF1ZXN0IHJxOw0KPiA+ICsgwqAgwqAgwqAgbGVfcmVtb3ZlX2RldmljZV9mcm9tX3do
aXRlX2xpc3RfY3AgcGFyYW1fY3A7DQo+IFNhbWUgY29tbWVudCBhYm91dCBwYXJhbV9jcDogcy9w
YXJhbV9jcC9jcA0KPiANCk9rLg0KDQo+ID4gKyDCoCDCoCDCoCB1aW50OF90IHN0YXR1czsNCj4g
PiArDQo+ID4gKyDCoCDCoCDCoCBtZW1zZXQoJnBhcmFtX2NwLCAwLCBzaXplb2YocGFyYW1fY3Ap
KTsNCj4gPiArIMKgIMKgIMKgIHBhcmFtX2NwLmJkYWRkcl90eXBlID0gdHlwZTsNCj4gPiArIMKg
IMKgIMKgIHBhcmFtX2NwLmJkYWRkcj0gYWRkcjsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBtZW1z
ZXQoJnJxLCAwLCBzaXplb2YocnEpKTsNCj4gPiArIMKgIMKgIMKgIHJxLm9nZiA9IE9HRl9MRV9D
VEw7DQo+ID4gKyDCoCDCoCDCoCBycS5vY2YgPSBPQ0ZfTEVfUkVNT1ZFX0RFVklDRV9GUk9NX1dI
SVRFX0xJU1Q7DQo+ID4gKyDCoCDCoCDCoCBycS5jcGFyYW0gPSAmcGFyYW1fY3A7DQo+ID4gKyDC
oCDCoCDCoCBycS5jbGVuID0gTEVfUkVNT1ZFX0RFVklDRV9GUk9NX1dISVRFX0xJU1RfQ1BfU0la
RTsNCj4gPiArIMKgIMKgIMKgIHJxLnJwYXJhbSA9ICZzdGF0dXM7DQo+ID4gKyDCoCDCoCDCoCBy
cS5ybGVuID0gMTsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBpZiAoaGNpX3NlbmRfcmVxKGRkLCAm
cnEsIDEwMCkgPCAwKQ0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIC0xOw0KPiBV
c2UgMTAwMA0KPiANCk9rLg0KDQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgaWYgKHN0YXR1cykgew0K
PiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZXJybm8gPSBFSU87DQo+ID4gKyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCByZXR1cm4gLTE7DQo+ID4gKyDCoCDCoCDCoCB9DQo+ID4gKw0KPiA+ICsgwqAg
wqAgwqAgcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK2ludCBoY2lfbGVfcmVhZF93aGl0
ZV9saXN0X3NpemUoaW50IGRkKQ0KPiA+ICt7DQo+ID4gKyDCoCDCoCDCoCBzdHJ1Y3QgaGNpX3Jl
cXVlc3QgcnE7DQo+ID4gKyDCoCDCoCDCoCBsZV9yZWFkX3doaXRlX2xpc3Rfc2l6ZV9ycCBwYXJh
bV9jcDsNCj4gUmVuYW1lIHBhcmFtX2NwIHRvIHJwDQo+IA0KT2suDQo+ID4gKw0KPiA+ICsgwqAg
wqAgwqAgbWVtc2V0KCZwYXJhbV9jcCwgMCwgc2l6ZW9mKHBhcmFtX2NwKSk7DQo+ID4gKyDCoCDC
oCDCoCBwYXJhbV9jcC5zaXplPTA7DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgbWVtc2V0KCZycSwg
MCwgc2l6ZW9mKHJxKSk7DQo+ID4gKyDCoCDCoCDCoCBycS5vZ2YgPSBPR0ZfTEVfQ1RMOw0KPiA+
ICsgwqAgwqAgwqAgcnEub2NmID0gT0NGX0xFX1JFQURfV0hJVEVfTElTVF9TSVpFOw0KPiA+ICsg
wqAgwqAgwqAgcnEucnBhcmFtID0gJnBhcmFtX2NwOw0KPiA+ICsgwqAgwqAgwqAgcnEucmxlbiA9
IExFX1JFQURfV0hJVEVfTElTVF9TSVpFX1JQX1NJWkU7DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAg
aWYgKGhjaV9zZW5kX3JlcShkZCwgJnJxLCAxMDApIDwgMCkNCj4gPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIHJldHVybiAtMTsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBpZiAocGFyYW1fY3Auc3Rh
dHVzKSB7DQo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBlcnJubyA9IEVJTzsNCj4gPiArIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybiAtMTsNCj4gPiArIMKgIMKgIMKgIH0NCj4gPiArDQo+
ID4gKyDCoCDCoCDCoCBwcmludGYoIkxFIFdoaXRlIGxpc3Qgc2l6ZT0gJWRcbiIsIHBhcmFtX2Nw
LnNpemUpOw0KPiBwcmludGY/IHRoZSBzaXplIHNob3VsZCBiZSByZXR1cm5lZCB0byB0aGUgY2Fs
bGVyLg0KPiBTdWdnZXN0aW9uOiBhZGQgYSBwb2ludGVyIGluIHRoZSBmdW5jdGlvbiBwYXJhbWV0
ZXJzDQo+IGlmIChzaXplKQ0KPiAgICAgKnNpemUgPSBwYXJhbV9jcC5zaXplOw0KPg0KWXVwLiBX
b3VsZCB0YWtlIGNhcmUgd2hpbGUgcmUtc3VibWl0dGluZyB0aGUgcGF0Y2hlcy4NCiANCj4gPiAr
DQo+ID4gKyDCoCDCoCDCoCByZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiAraW50IGhjaV9s
ZV9jbGVhcl93aGl0ZV9saXN0KGludCBkZCkNCj4gPiArew0KPiA+ICsgwqAgwqAgwqAgc3RydWN0
IGhjaV9yZXF1ZXN0IHJxOw0KPiA+ICsgwqAgwqAgwqAgdWludDhfdCBzdGF0dXM7DQo+ID4gKw0K
PiA+ICsgwqAgwqAgwqAgbWVtc2V0KCZycSwgMCwgc2l6ZW9mKHJxKSk7DQo+ID4gKyDCoCDCoCDC
oCBycS5vZ2YgPSBPR0ZfTEVfQ1RMOw0KPiA+ICsgwqAgwqAgwqAgcnEub2NmID0gT0NGX0xFX0NM
RUFSX1dISVRFX0xJU1Q7DQo+ID4gKyDCoCDCoCDCoCBycS5ycGFyYW0gPSAmc3RhdHVzOw0KPiA+
ICsgwqAgwqAgwqAgcnEucmxlbiA9IDE7DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgaWYgKGhjaV9z
ZW5kX3JlcShkZCwgJnJxLCAxMDApIDwgMCkNCj4gVXNlIDEwMDANCj4gDQpPay4NCg0KPiA+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIC0xOw0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIGlm
IChzdGF0dXMpIHsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVycm5vID0gRUlPOw0KPiA+
ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuIC0xOw0KPiA+ICsgwqAgwqAgwqAgfQ0KPiA+
ICsNCj4gPiArIMKgIMKgIMKgIHJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+IMKgaW50IGhj
aV9yZWFkX2xvY2FsX25hbWUoaW50IGRkLCBpbnQgbGVuLCBjaGFyICpuYW1lLCBpbnQgdG8pDQo+
ID4gwqB7DQo+ID4gwqAgwqAgwqAgwqByZWFkX2xvY2FsX25hbWVfcnAgcnA7DQo+ID4gZGlmZiAt
LWdpdCBhL2xpYi9oY2lfbGliLmggYi9saWIvaGNpX2xpYi5oDQo+ID4gb2xkIG1vZGUgMTAwNjQ0
DQo+ID4gbmV3IG1vZGUgMTAwNzU1DQo+ID4gaW5kZXggYjYzYTJhNC4uZWQ3NGRmYw0KPiA+IC0t
LSBhL2xpYi9oY2lfbGliLmgNCj4gPiArKysgYi9saWIvaGNpX2xpYi5oDQo+ID4gQEAgLTEyNyw2
ICsxMjcsMTAgQEAgaW50IGhjaV9sZV9jcmVhdGVfY29ubihpbnQgZGQsIHVpbnQxNl90DQo+IGlu
dGVydmFsLCB1aW50MTZfdCB3aW5kb3csDQo+ID4gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1aW50
MTZfdCBsYXRlbmN5LCB1aW50MTZfdCBzdXBlcnZpc2lvbl90aW1lb3V0LA0KPiA+IMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgdWludDE2X3QgbWluX2NlX2xlbmd0aCwgdWludDE2X3QgbWF4X2NlX2xl
bmd0aCwNCj4gPiDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVpbnQxNl90ICpoYW5kbGUsIGludCB0
byk7DQo+ID4gK2ludCBoY2lfbGVfYWRkX3RvX3doaXRlX2xpc3QoaW50IGRkLCBiZGFkZHJfdCBh
ZGRyLCB1aW50OF90IHR5cGUpOw0KPiA+ICtpbnQgaGNpX2xlX3JlbW92ZV9mcm9tX3doaXRlX2xp
c3QoaW50IGRkLCBiZGFkZHJfdCBhZGRyLCB1aW50OF90DQo+IHR5cGUpOw0KPiA+ICtpbnQgaGNp
X2xlX3JlYWRfd2hpdGVfbGlzdF9zaXplKGludCBkZCk7DQo+ID4gK2ludCBoY2lfbGVfY2xlYXJf
d2hpdGVfbGlzdChpbnQgZGQpOw0KPiA+DQo+ID4gwqBpbnQgaGNpX2Zvcl9lYWNoX2RldihpbnQg
ZmxhZywgaW50KCpmdW5jKShpbnQgZGQsIGludCBkZXZfaWQsIGxvbmcNCj4gYXJnKSwgbG9uZyBh
cmcpOw0KPiA+IMKgaW50IGhjaV9nZXRfcm91dGUoYmRhZGRyX3QgKmJkYWRkcik7DQo+ID4gZGlm
ZiAtLWdpdCBhL3Rvb2xzL2hjaXRvb2wuYyBiL3Rvb2xzL2hjaXRvb2wuYw0KPiA+IGluZGV4IGQ1
MGFkYWYuLjM4N2M0N2MgMTAwNjQ0DQo+ID4gLS0tIGEvdG9vbHMvaGNpdG9vbC5jDQo+ID4gKysr
IGIvdG9vbHMvaGNpdG9vbC5jDQo+ID4gQEAgLTI0NzEsNiArMjQ3MSwxODggQEAgc3RhdGljIHZv
aWQgY21kX2xlY2MoaW50IGRldl9pZCwgaW50IGFyZ2MsDQo+IGNoYXIgKiphcmd2KQ0KPiA+IMKg
IMKgIMKgIMKgaGNpX2Nsb3NlX2RldihkZCk7DQo+ID4gwqB9DQo+ID4NCj4gPiArc3RhdGljIHN0
cnVjdCBvcHRpb24gbGVhZGR3bF9vcHRpb25zW10gPSB7DQo+ID4gKyDCoCDCoCDCoCB7ICJoZWxw
IiwgwqAgwqAgwqAgMCwgMCwgJ2gnIH0sDQo+ID4gKyDCoCDCoCDCoCB7IDAsIDAsIDAsIDAgfQ0K
PiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IGNoYXIgKmxlYWRkd2xfaGVscCA9DQo+
ID4gKyDCoCDCoCDCoCAiVXNhZ2U6XG4iDQo+ID4gKyDCoCDCoCDCoCAiXHRsZWFkZHdsIDxiZGFk
ZHI+XG4iOw0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgY21kX2xlYWRkd2woaW50IGRldl9pZCwg
aW50IGFyZ2MsY2hhciAqKmFyZ3YpDQo+ID4gK3sNCj4gPiArIMKgIMKgIMKgIGludCBlcnIsIG9w
dCwgZGQ7DQo+ID4gKyDCoCDCoCDCoCBiZGFkZHJfdCBiZGFkZHI7DQo+ID4gKyDCoCDCoCDCoCB1
aW50OF90IGJkYWRkcl90eXBlOw0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIGZvcl9lYWNoX29wdChv
cHQsIGxlYWRkd2xfb3B0aW9ucywgTlVMTCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
c3dpdGNoIChvcHQpIHsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRlZmF1bHQ6DQo+ID4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcmludGYoIiVzIiwgbGVhZGR3bF9o
ZWxwKTsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJldHVybjsNCj4g
PiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0NCj4gPiArIMKgIMKgIMKgIH0NCj4gPiArIMKgIMKg
IMKgIGhlbHBlcl9hcmcoMSwgMSwgJmFyZ2MsICZhcmd2LCBsZWFkZHdsX2hlbHApOw0KPiA+ICsN
Cj4gPiArIMKgIMKgIMKgIGlmIChkZXZfaWQgPCAwKQ0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgZGV2X2lkID0gaGNpX2dldF9yb3V0ZShOVUxMKTsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBk
ZCA9IGhjaV9vcGVuX2RldihkZXZfaWQpOw0KPiA+ICsgwqAgwqAgwqAgaWYgKGRkIDwgMCkgew0K
PiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcGVycm9yKCJDb3VsZCBub3Qgb3BlbiBkZXZpY2Ui
KTsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGV4aXQoMSk7DQo+ID4gKyDCoCDCoCDCoCB9
DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgc3RyMmJhKGFyZ3ZbMV0sICZiZGFkZHIpOw0KPiA+ICsg
wqAgwqAgwqAgYmRhZGRyX3R5cGUgPSAweDAwOw0KPiBVc2UgZW51bQ0KPiANCk9rLiBXb3VsZCBk
ZWZpbmUgYW4gZW51bSBsZV9kZXZpY2VfYWRkcl90eXBlIGluIGhjaS5oLg0KDQo+ID4gKw0KPiA+
ICsgwqAgwqAgwqAgZXJyID0gaGNpX2xlX2FkZF90b193aGl0ZV9saXN0KGRkLCBiZGFkZHIgLGJk
YWRkcl90eXBlKTsNCj4gTWlzc2luZyBzcGFjZSBiZWZvcmUgYmRhZGRyX3R5cGUNCj4gDQo+ID4g
KyDCoCDCoCDCoCBpZiAoZXJyIDwgMCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcGVy
cm9yKCJDYW50IGFkZCB0byB3aGl0ZSBsaXN0Iik7DQo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCBleGl0KDEpOw0KPiA+ICsgwqAgwqAgwqAgfQ0KPiB3cm9uZyBjb2Rpbmcgc3R5bGUNCj4gDQpJ
cyB1c2luZyBhIHNlcGFyYXRlIHZhcmlhYmxlIGVyciBmb3IgcmV0dXJuIHR5cGUgb2YgYSBmdW5j
dGlvbiBwcm9ibGVtIGhlcmU/IA0KSSBjb3VsZCBzZWUgc2FtZSBjb2Rpbmcgc3R5bGUgb2YgZGVm
aW5pbmcgYSB2YXJpYWJsZSB0byBjYXJyeSB0aGUgZXJyb3Igc3RhdHVzIGluIGhjaXRvb2wuYyBm
dW5jdGlvbiBjbWRfbGVjYy4NClBsZWFzZSBjb25maXJtLiANCg0KPiA+ICsgwqAgwqAgwqAgZWxz
ZSB7DQo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcmludGYoIkRldmljZSBhZGRlZCB0byB3
aGl0ZSBsaXN0Iik7DQo+ID4gKyDCoCDCoCDCoCB9DQo+ICJ7IiBub3QgbmVjZXNzYXJ5DQo+IA0K
DQpPay4NCg0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIGhjaV9jbG9zZV9kZXYoZGQpOw0KPiBNb3Zl
IHRoaXMgbGluZSBhZnRlciAiaGNpX2xlX2FkZF90b193aGl0ZV9saXN0KCkiIGNhbGwsIG90aGVy
d2lzZSBkZA0KPiB3aWxsIG5vdCBiZSBjbG9zZWQgaWYgdGhlIGNtZCBmYWlscw0KPiANCj4gPiAr
DQo+IHJlbW92ZSBlbXB0eSBsaW5lDQoNCk9rLg0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMg
c3RydWN0IG9wdGlvbiBsZXJtd2xfb3B0aW9uc1tdID0gew0KPiA+ICsgwqAgwqAgwqAgeyAiaGVs
cCIsIMKgIMKgIMKgIDAsIDAsICdoJyB9LA0KPiA+ICsgwqAgwqAgwqAgeyAwLCAwLCAwLCAwIH0N
Cj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBjaGFyICpsZXJtd2xfaGVscCA9DQo+
ID4gKyDCoCDCoCDCoCAiVXNhZ2U6XG4iDQo+ID4gKyDCoCDCoCDCoCAiXHRsZXJtd2wgPGJkYWRk
cj5cbiI7DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBjbWRfbGVybXdsKGludCBkZXZfaWQsIGlu
dCBhcmdjLGNoYXIgKiphcmd2KQ0KPiA+ICt7DQo+ID4gKyDCoCDCoCDCoCBpbnQgZXJyLCBvcHQs
IGRkOw0KPiA+ICsgwqAgwqAgwqAgYmRhZGRyX3QgYmRhZGRyOw0KPiA+ICsgwqAgwqAgwqAgdWlu
dDhfdCBiZGFkZHJfdHlwZTsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBmb3JfZWFjaF9vcHQob3B0
LCBsZXJtd2xfb3B0aW9ucywgTlVMTCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3dp
dGNoIChvcHQpIHsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRlZmF1bHQ6DQo+ID4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcmludGYoIiVzIiwgbGVybXdsX2hlbHAp
Ow0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmV0dXJuOw0KPiA+ICsg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgfQ0KPiA+ICsgwqAgwqAgwqAgfQ0KPiA+ICsgwqAgwqAgwqAg
aGVscGVyX2FyZygxLCAxLCAmYXJnYywgJmFyZ3YsIGxlcm13bF9oZWxwKTsNCj4gPiArDQo+ID4g
KyDCoCDCoCDCoCBpZiAoZGV2X2lkIDwgMCkNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRl
dl9pZCA9IGhjaV9nZXRfcm91dGUoTlVMTCk7DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgZGQgPSBo
Y2lfb3Blbl9kZXYoZGV2X2lkKTsNCj4gPiArIMKgIMKgIMKgIGlmIChkZCA8IDApIHsNCj4gPiAr
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIHBlcnJvcigiQ291bGQgbm90IG9wZW4gZGV2aWNlIik7DQo+
ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBleGl0KDEpOw0KPiA+ICsgwqAgwqAgwqAgfQ0KPiA+
ICsNCj4gPiArIMKgIMKgIMKgIHN0cjJiYShhcmd2WzFdLCAmYmRhZGRyKTsNCj4gPiArIMKgIMKg
IMKgIGJkYWRkcl90eXBlID0gMHgwMDsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBlcnIgPSBoY2lf
bGVfcmVtb3ZlX2Zyb21fd2hpdGVfbGlzdChkZCwgYmRhZGRyICxiZGFkZHJfdHlwZSk7DQo+ID4g
KyDCoCDCoCDCoCBpZiAoZXJyIDwgMCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcGVy
cm9yKCJDYW50IHJlbW92ZSBmcm9tIHdoaXRlIGxpc3QiKTsNCj4gPiArIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIGV4aXQoMSk7DQo+ID4gKyDCoCDCoCDCoCB9DQo+ID4gKyDCoCDCoCDCoCDCoGVsc2Ug
ew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcHJpbnRmKCJEZXZpY2UgcmVtb3ZlZCBmcm9t
IHdoaXRlIGxpc3QiKTsNCj4gPiArIMKgIMKgIMKgIH0NCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBo
Y2lfY2xvc2VfZGV2KGRkKTsNCj4gU2FtZSBjb2Rpbmcgc3R5bGUgaXNzdWUgYW5kIGNsb3NlICJk
ZCINCj4gDQoNCg0KT2suIEdvb2QgcG9pbnQuIEJ1dCBJIGNvdWxkIHN0aWxsIGZpbmQgcHJlbWF0
dXJlIHJldHVybnMgb24gZXJyb3IgY29uZGl0aW9ucyB2aWEgZXhpdHMgYXQgc2V2ZXJhbCBwbGFj
ZXMgaW4gaGNpdG9vbC5jLiBDYW4gSSBzdWJtaXQgYSBzZXBhcmF0ZSBwYXRjaCBmb3IgcmVjdGlm
eWluZyBhbGwgc3VjaCBlcnJvciBjb25kaXRpb25zIHRvbz8NCg0KPiA+ICsNCj4gPiArfQ0KPiA+
ICsNCj4gPiArc3RhdGljIHN0cnVjdCBvcHRpb24gbGVyZHdsc3pfb3B0aW9uc1tdID0gew0KPiA+
ICsgwqAgwqAgwqAgeyAiaGVscCIsIMKgIMKgIMKgIDAsIDAsICdoJyB9LA0KPiA+ICsgwqAgwqAg
wqAgeyAwLCAwLCAwLCAwIH0NCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBjaGFy
ICpsZXJkd2xzel9oZWxwID0NCj4gPiArIMKgIMKgIMKgICJVc2FnZTpcbiINCj4gPiArIMKgIMKg
IMKgICJcdGxlcmR3bHN6XG4iOw0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgY21kX2xlcmR3bHN6
KGludCBkZXZfaWQsIGludCBhcmdjLGNoYXIgKiphcmd2KQ0KPiA+ICt7DQo+ID4gKyDCoCDCoCDC
oCBpbnQgZXJyLGRkLCBvcHQ7DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgZm9yX2VhY2hfb3B0KG9w
dCwgbGVyZHdsc3pfb3B0aW9ucywgTlVMTCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
c3dpdGNoIChvcHQpIHsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRlZmF1bHQ6DQo+ID4g
KyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcmludGYoIiVzIiwgbGVyZHdsc3pf
aGVscCk7DQo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCByZXR1cm47DQo+
ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCB9DQo+ID4gKyDCoCDCoCDCoCB9DQo+IEFkZCBlbXB0
eSBsaW5lIGhlcmUNCg0KT2suDQo+ID4gKyDCoCDCoCDCoCBoZWxwZXJfYXJnKDAsIDAsICZhcmdj
LCAmYXJndiwgbGVybXdsX2hlbHApOw0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIGlmIChkZXZfaWQg
PCAwKQ0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZGV2X2lkID0gaGNpX2dldF9yb3V0ZShO
VUxMKTsNCj4gPiArDQo+ID4gKyDCoCDCoCDCoCBkZCA9IGhjaV9vcGVuX2RldihkZXZfaWQpOw0K
PiA+ICsgwqAgwqAgwqAgaWYgKGRkIDwgMCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
cGVycm9yKCJDb3VsZCBub3Qgb3BlbiBkZXZpY2UiKTsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIGV4aXQoMSk7DQo+ID4gKyDCoCDCoCDCoCB9DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgZXJy
ID0gaGNpX2xlX3JlYWRfd2hpdGVfbGlzdF9zaXplKGRkKTsNCj4gPiArIMKgIMKgIMKgIGlmIChl
cnIgPCAwKSB7DQo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwZXJyb3IoIkNhbnQgcmVhZCB3
aGl0ZSBsaXN0IHNpemUiKTsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGV4aXQoMSk7DQo+
ID4gKyDCoCDCoCDCoCB9DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgaGNpX2Nsb3NlX2RldihkZCk7
DQo+IE1pc3NpbmcgY2xvc2UgZGQgaWYgdGhlIGNtZCBmYWlscw0KT2suDQo+IFJlbW92ZSBlbXB0
eSBsaW5lIGhlcmUNCk9rLg0KPiA+ICsNCj4gPiArfQ0KPiA+ICsNCj4gPiArDQo+IFJlbW92ZSBl
bXB0eSBsaW5lIGhlcmUNCk9rLg0KPiA+ICtzdGF0aWMgc3RydWN0IG9wdGlvbiBsZWNscndsX29w
dGlvbnNbXSA9IHsNCj4gPiArIMKgIMKgIMKgIHsgImhlbHAiLCDCoCDCoCDCoCAwLCAwLCAnaCcg
fSwNCj4gPiArIMKgIMKgIMKgIHsgMCwgMCwgMCwgMCB9DQo+ID4gK307DQo+ID4gKw0KPiA+ICtz
dGF0aWMgY29uc3QgY2hhciAqbGVjbHJ3bF9oZWxwID0NCj4gPiArIMKgIMKgIMKgICJVc2FnZTpc
biINCj4gPiArIMKgIMKgIMKgICJcdGxlY2xyd2xcbiI7DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9p
ZCBjbWRfbGVjbHJ3bChpbnQgZGV2X2lkLCBpbnQgYXJnYyxjaGFyICoqYXJndikNCj4gPiArew0K
PiA+ICsgwqAgwqAgwqAgaW50IGVycixkZCwgb3B0Ow0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIGZv
cl9lYWNoX29wdChvcHQsIGxlY2xyd2xfb3B0aW9ucywgTlVMTCkgew0KPiA+ICsgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgc3dpdGNoIChvcHQpIHsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRl
ZmF1bHQ6DQo+ID4gKyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBwcmludGYoIiVz
IiwgbGVjbHJ3bF9oZWxwKTsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IHJldHVybjsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIH0NCj4gPiArIMKgIMKgIMKgIH0N
Cj4gPiArIMKgIMKgIMKgIGhlbHBlcl9hcmcoMCwgMCwgJmFyZ2MsICZhcmd2LCBsZWNscndsX2hl
bHApOw0KPiA+ICsNCj4gPiArIMKgIMKgIMKgIGlmIChkZXZfaWQgPCAwKQ0KPiA+ICsgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgZGV2X2lkID0gaGNpX2dldF9yb3V0ZShOVUxMKTsNCj4gPiArDQo+ID4g
KyDCoCDCoCDCoCBkZCA9IGhjaV9vcGVuX2RldihkZXZfaWQpOw0KPiA+ICsgwqAgwqAgwqAgaWYg
KGRkIDwgMCkgew0KPiA+ICsgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcGVycm9yKCJDb3VsZCBub3Qg
b3BlbiBkZXZpY2UiKTsNCj4gPiArIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGV4aXQoMSk7DQo+ID4g
KyDCoCDCoCDCoCB9DQo+ID4gKw0KPiA+ICsgwqAgwqAgwqAgZXJyID0gaGNpX2xlX2NsZWFyX3do
aXRlX2xpc3QoZGQpOw0KPiA+ICsgwqAgwqAgwqAgaWYgKGVyciA8IDApIHsNCj4gPiArIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHBlcnJvcigiQ2FudCBjbGVhciB3aGl0ZSBsaXN0Iik7DQo+ID4gKyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCBleGl0KDEpOw0KPiA+ICsgwqAgwqAgwqAgfQ0KPiA+ICsNCj4g
PiArIMKgIMKgIMKgIGhjaV9jbG9zZV9kZXYoZGQpOw0KPiBNaXNzaW5nIGNsb3NlIGRkIHdoZW4g
dGhlIGNtZCBmYWlscw0KPiBSZW1vdmUgZW1wdHkgbGluZSBoZXJlDQo+IA0KT2suDQoNCj4gQ2xh
dWRpbw0KPiA+ICsNCj4gPiArfQ0KPiA+ICsNCj4gPiArDQo+IFJlbW92ZSBlbXB0eSBsaW5lIGhl
cmUNCg0KT2suDQo+ID4gwqBzdGF0aWMgc3RydWN0IG9wdGlvbiBsZWRjX29wdGlvbnNbXSA9IHsN
Cj4gPiDCoCDCoCDCoCDCoHsgImhlbHAiLCDCoCDCoCDCoCAwLCAwLCAnaCcgfSwNCj4gPiDCoCDC
oCDCoCDCoHsgMCwgMCwgMCwgMCB9DQo+ID4gQEAgLTI1NDcsNiArMjcyOSwxMCBAQCBzdGF0aWMg
c3RydWN0IHsNCj4gPiDCoCDCoCDCoCDCoHsgImNsa29mZiIsIGNtZF9jbGtvZmYsICJSZWFkIGNs
b2NrIG9mZnNldCINCj4gwqB9LA0KPiA+IMKgIMKgIMKgIMKgeyAiY2xvY2siLCDCoGNtZF9jbG9j
aywgwqAiUmVhZCBsb2NhbCBvciByZW1vdGUgY2xvY2siDQo+IH0sDQo+ID4gwqAgwqAgwqAgwqB7
ICJsZXNjYW4iLCBjbWRfbGVzY2FuLCAiU3RhcnQgTEUgc2NhbiINCj4gwqB9LA0KPiA+ICsgwqAg
wqAgwqAgeyAibGVhZGR3bCIsIGNtZF9sZWFkZHdsLCAiQWRkIHRoaXMgZGV2aWNlIHRvIHdoaXRl
IGxpc3QiDQo+IMKgIMKgIMKgfSwNCj4gPiArIMKgIMKgIMKgIHsgImxlcm13bCIsIGNtZF9sZXJt
d2wsICJSZW1vdmUgdGhpcyBkZXZpY2UgZnJvbSB3aGl0ZSBsaXN0Ig0KPiDCoCB9LA0KPiA+ICsg
wqAgwqAgwqAgeyAibGVyZHdsc3oiLCDCoGNtZF9sZXJkd2xzeiwgwqAiUmVhZCB3aGl0ZSBsaXN0
IHNpemUiDQo+IMKgIMKgIMKgIH0sDQo+ID4gKyDCoCDCoCDCoCB7ICJsZWNscndsIiwgwqAgY21k
X2xlY2xyd2wsIMKgICJDbGVhciB3aGl0ZSBsaXN0Ig0KPiDCoCDCoCDCoCB9LA0KPiA+IMKgIMKg
IMKgIMKgeyAibGVjYyIsIMKgIGNtZF9sZWNjLCDCoCAiQ3JlYXRlIGEgTEUgQ29ubmVjdGlvbiIs
DQo+IMKgfSwNCj4gPiDCoCDCoCDCoCDCoHsgImxlZGMiLCDCoCBjbWRfbGVkYywgwqAgIkRpc2Nv
bm5lY3QgYSBMRSBDb25uZWN0aW9uIiwNCj4gwqB9LA0KPiA+IMKgIMKgIMKgIMKgeyBOVUxMLCBO
VUxMLCAwIH0NCj4gPiAtLQ0KPiA+IDEuNi41DQo+ID4NCj4gPg0KPiA+IC0tDQo+ID4gVG8gdW5z
dWJzY3JpYmUgZnJvbSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUgInVuc3Vic2NyaWJlIGxpbnV4
LQ0KPiBibHVldG9vdGgiIGluDQo+ID4gdGhlIGJvZHkgb2YgYSBtZXNzYWdlIHRvIG1ham9yZG9t
b0B2Z2VyLmtlcm5lbC5vcmcNCj4gPiBNb3JlIG1ham9yZG9tbyBpbmZvIGF0IMKgaHR0cDovL3Zn
ZXIua2VybmVsLm9yZy9tYWpvcmRvbW8taW5mby5odG1sDQo+ID4NCg0KVGhhbmtzLCANClN1bWl0
Lg0K

2011-01-07 17:05:07

by Claudio Takahasi

[permalink] [raw]
Subject: Re: [PATCH] HCI Commands for LE White List

Hi Sumit,

Could you please split this patch into minor functional patches?

On Thu, Jan 6, 2011 at 12:52 AM, Sumit Kumar BAJPAI
<[email protected]> wrote:
> Added HCI commands for LE White List support.
> These LE White List Commands can be tested from
> hcitool.
>
>
> ---
>  lib/hci.c       |  107 +++++++++++++++++++++++++++++++
>  lib/hci_lib.h   |    4 +
>  tools/hcitool.c |  186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 297 insertions(+), 0 deletions(-)
>  mode change 100644 => 100755 lib/hci.c
>  mode change 100644 => 100755 lib/hci_lib.h
>
> diff --git a/lib/hci.c b/lib/hci.c
> old mode 100644
> new mode 100755
> index 048fda4..5a0275c
> --- a/lib/hci.c
> +++ b/lib/hci.c
> @@ -1291,6 +1291,113 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to)
>        return 0;
>  }
>
> +int hci_le_add_to_white_list(int dd, bdaddr_t addr, uint8_t type)
Use pointer for bdaddr_t
address types have defined values in the BT spec, declare an enum in hci.h

> +{
> +       struct hci_request rq;
> +       le_add_device_to_white_list_cp param_cp;
It seems that you copied this declaration from set scan parameters
function. Use only "cp", it is short for command parameters.

> +       uint8_t status;
> +
> +       memset(&param_cp, 0, sizeof(param_cp));
> +       param_cp.bdaddr_type = type;
> +       param_cp.bdaddr= addr;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
> +       rq.cparam = &param_cp;
> +       rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
> +       rq.rparam = &status;
> +       rq.rlen = 1;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
Use 1000, we are noticing timeout on some LE hardwares.

> +
> +       if (status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +int hci_le_remove_from_white_list(int dd, bdaddr_t addr, uint8_t type)
> +{
Same comment about address type and bdaddr_t pointer

> +       struct hci_request rq;
> +       le_remove_device_from_white_list_cp param_cp;
Same comment about param_cp: s/param_cp/cp

> +       uint8_t status;
> +
> +       memset(&param_cp, 0, sizeof(param_cp));
> +       param_cp.bdaddr_type = type;
> +       param_cp.bdaddr= addr;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
> +       rq.cparam = &param_cp;
> +       rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
> +       rq.rparam = &status;
> +       rq.rlen = 1;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
Use 1000

> +
> +       if (status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +int hci_le_read_white_list_size(int dd)
> +{
> +       struct hci_request rq;
> +       le_read_white_list_size_rp param_cp;
Rename param_cp to rp

> +
> +       memset(&param_cp, 0, sizeof(param_cp));
> +       param_cp.size=0;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
> +       rq.rparam = &param_cp;
> +       rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
> +
> +       if (param_cp.status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       printf("LE White list size= %d\n", param_cp.size);
printf? the size should be returned to the caller.
Suggestion: add a pointer in the function parameters
if (size)
*size = param_cp.size;

> +
> +       return 0;
> +}
> +
> +int hci_le_clear_white_list(int dd)
> +{
> +       struct hci_request rq;
> +       uint8_t status;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
> +       rq.rparam = &status;
> +       rq.rlen = 1;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
Use 1000

> +               return -1;
> +
> +       if (status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
>  int hci_read_local_name(int dd, int len, char *name, int to)
>  {
>        read_local_name_rp rp;
> diff --git a/lib/hci_lib.h b/lib/hci_lib.h
> old mode 100644
> new mode 100755
> index b63a2a4..ed74dfc
> --- a/lib/hci_lib.h
> +++ b/lib/hci_lib.h
> @@ -127,6 +127,10 @@ int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
>                uint16_t latency, uint16_t supervision_timeout,
>                uint16_t min_ce_length, uint16_t max_ce_length,
>                uint16_t *handle, int to);
> +int hci_le_add_to_white_list(int dd, bdaddr_t addr, uint8_t type);
> +int hci_le_remove_from_white_list(int dd, bdaddr_t addr, uint8_t type);
> +int hci_le_read_white_list_size(int dd);
> +int hci_le_clear_white_list(int dd);
>
>  int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);
>  int hci_get_route(bdaddr_t *bdaddr);
> diff --git a/tools/hcitool.c b/tools/hcitool.c
> index d50adaf..387c47c 100644
> --- a/tools/hcitool.c
> +++ b/tools/hcitool.c
> @@ -2471,6 +2471,188 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
>        hci_close_dev(dd);
>  }
>
> +static struct option leaddwl_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *leaddwl_help =
> +       "Usage:\n"
> +       "\tleaddwl <bdaddr>\n";
> +
> +static void cmd_leaddwl(int dev_id, int argc,char **argv)
> +{
> +       int err, opt, dd;
> +       bdaddr_t bdaddr;
> +       uint8_t bdaddr_type;
> +
> +       for_each_opt(opt, leaddwl_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", leaddwl_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(1, 1, &argc, &argv, leaddwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       str2ba(argv[1], &bdaddr);
> +       bdaddr_type = 0x00;
Use enum

> +
> +       err = hci_le_add_to_white_list(dd, bdaddr ,bdaddr_type);
Missing space before bdaddr_type

> +       if (err < 0) {
> +               perror("Cant add to white list");
> +               exit(1);
> +       }
wrong coding style

> +       else {
> +               printf("Device added to white list");
> +       }
"{" not necessary

> +
> +       hci_close_dev(dd);
Move this line after "hci_le_add_to_white_list()" call, otherwise dd
will not be closed if the cmd fails

> +
remove empty line
> +}
> +
> +static struct option lermwl_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *lermwl_help =
> +       "Usage:\n"
> +       "\tlermwl <bdaddr>\n";
> +
> +static void cmd_lermwl(int dev_id, int argc,char **argv)
> +{
> +       int err, opt, dd;
> +       bdaddr_t bdaddr;
> +       uint8_t bdaddr_type;
> +
> +       for_each_opt(opt, lermwl_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", lermwl_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(1, 1, &argc, &argv, lermwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       str2ba(argv[1], &bdaddr);
> +       bdaddr_type = 0x00;
> +
> +       err = hci_le_remove_from_white_list(dd, bdaddr ,bdaddr_type);
> +       if (err < 0) {
> +               perror("Cant remove from white list");
> +               exit(1);
> +       }
> +        else {
> +               printf("Device removed from white list");
> +       }
> +
> +       hci_close_dev(dd);
Same coding style issue and close "dd"

> +
> +}
> +
> +static struct option lerdwlsz_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *lerdwlsz_help =
> +       "Usage:\n"
> +       "\tlerdwlsz\n";
> +
> +static void cmd_lerdwlsz(int dev_id, int argc,char **argv)
> +{
> +       int err,dd, opt;
> +
> +       for_each_opt(opt, lerdwlsz_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", lerdwlsz_help);
> +                       return;
> +               }
> +       }
Add empty line here
> +       helper_arg(0, 0, &argc, &argv, lermwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       err = hci_le_read_white_list_size(dd);
> +       if (err < 0) {
> +               perror("Cant read white list size");
> +               exit(1);
> +       }
> +
> +       hci_close_dev(dd);
Missing close dd if the cmd fails
Remove empty line here
> +
> +}
> +
> +
Remove empty line here
> +static struct option leclrwl_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *leclrwl_help =
> +       "Usage:\n"
> +       "\tleclrwl\n";
> +
> +static void cmd_leclrwl(int dev_id, int argc,char **argv)
> +{
> +       int err,dd, opt;
> +
> +       for_each_opt(opt, leclrwl_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", leclrwl_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(0, 0, &argc, &argv, leclrwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       err = hci_le_clear_white_list(dd);
> +       if (err < 0) {
> +               perror("Cant clear white list");
> +               exit(1);
> +       }
> +
> +       hci_close_dev(dd);
Missing close dd when the cmd fails
Remove empty line here

Claudio
> +
> +}
> +
> +
Remove empty line here
>  static struct option ledc_options[] = {
>        { "help",       0, 0, 'h' },
>        { 0, 0, 0, 0 }
> @@ -2547,6 +2729,10 @@ static struct {
>        { "clkoff", cmd_clkoff, "Read clock offset"                    },
>        { "clock",  cmd_clock,  "Read local or remote clock"           },
>        { "lescan", cmd_lescan, "Start LE scan"                        },
> +       { "leaddwl", cmd_leaddwl, "Add this device to white list"          },
> +       { "lermwl", cmd_lermwl, "Remove this device from white list"   },
> +       { "lerdwlsz",  cmd_lerdwlsz,  "Read white list size"               },
> +       { "leclrwl",   cmd_leclrwl,   "Clear white list"                   },
>        { "lecc",   cmd_lecc,   "Create a LE Connection",              },
>        { "ledc",   cmd_ledc,   "Disconnect a LE Connection",          },
>        { NULL, NULL, 0 }
> --
> 1.6.5
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

2011-01-07 07:38:58

by Arun K. Singh

[permalink] [raw]
Subject: Re: [PATCH] HCI Commands for LE White List

Hi Claudio,


On Thu, Jan 6, 2011 at 9:22 AM, Sumit Kumar BAJPAI
<[email protected]> wrote:
>
> Added HCI commands for LE White List support.
> These LE White List Commands can be tested from
> hcitool.
>
>
> ---
>  lib/hci.c       |  107 +++++++++++++++++++++++++++++++
>  lib/hci_lib.h   |    4 +
>  tools/hcitool.c |  186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 297 insertions(+), 0 deletions(-)
>  mode change 100644 => 100755 lib/hci.c
>  mode change 100644 => 100755 lib/hci_lib.h
>
> diff --git a/lib/hci.c b/lib/hci.c
> old mode 100644
> new mode 100755
> index 048fda4..5a0275c
> --- a/lib/hci.c
> +++ b/lib/hci.c
> @@ -1291,6 +1291,113 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to)
>        return 0;
>  }
>
> +int hci_le_add_to_white_list(int dd, bdaddr_t addr, uint8_t type)
> +{
> +       struct hci_request rq;
> +       le_add_device_to_white_list_cp param_cp;
> +       uint8_t status;
> +
> +       memset(&param_cp, 0, sizeof(param_cp));
> +       param_cp.bdaddr_type = type;
> +       param_cp.bdaddr= addr;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
> +       rq.cparam = &param_cp;
> +       rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
> +       rq.rparam = &status;
> +       rq.rlen = 1;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
> +
> +       if (status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +int hci_le_remove_from_white_list(int dd, bdaddr_t addr, uint8_t type)
> +{
> +       struct hci_request rq;
> +       le_remove_device_from_white_list_cp param_cp;
> +       uint8_t status;
> +
> +       memset(&param_cp, 0, sizeof(param_cp));
> +       param_cp.bdaddr_type = type;
> +       param_cp.bdaddr= addr;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
> +       rq.cparam = &param_cp;
> +       rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
> +       rq.rparam = &status;
> +       rq.rlen = 1;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
> +
> +       if (status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +int hci_le_read_white_list_size(int dd)
> +{
> +       struct hci_request rq;
> +       le_read_white_list_size_rp param_cp;
> +
> +       memset(&param_cp, 0, sizeof(param_cp));
> +       param_cp.size=0;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
> +       rq.rparam = &param_cp;
> +       rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
> +
> +       if (param_cp.status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       printf("LE White list size= %d\n", param_cp.size);
> +
> +       return 0;
> +}
> +
> +int hci_le_clear_white_list(int dd)
> +{
> +       struct hci_request rq;
> +       uint8_t status;
> +
> +       memset(&rq, 0, sizeof(rq));
> +       rq.ogf = OGF_LE_CTL;
> +       rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
> +       rq.rparam = &status;
> +       rq.rlen = 1;
> +
> +       if (hci_send_req(dd, &rq, 100) < 0)
> +               return -1;
> +
> +       if (status) {
> +               errno = EIO;
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
>  int hci_read_local_name(int dd, int len, char *name, int to)
>  {
>        read_local_name_rp rp;
> diff --git a/lib/hci_lib.h b/lib/hci_lib.h
> old mode 100644
> new mode 100755
> index b63a2a4..ed74dfc
> --- a/lib/hci_lib.h
> +++ b/lib/hci_lib.h
> @@ -127,6 +127,10 @@ int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
>                uint16_t latency, uint16_t supervision_timeout,
>                uint16_t min_ce_length, uint16_t max_ce_length,
>                uint16_t *handle, int to);
> +int hci_le_add_to_white_list(int dd, bdaddr_t addr, uint8_t type);
> +int hci_le_remove_from_white_list(int dd, bdaddr_t addr, uint8_t type);
> +int hci_le_read_white_list_size(int dd);
> +int hci_le_clear_white_list(int dd);
>
>  int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);
>  int hci_get_route(bdaddr_t *bdaddr);
> diff --git a/tools/hcitool.c b/tools/hcitool.c
> index d50adaf..387c47c 100644
> --- a/tools/hcitool.c
> +++ b/tools/hcitool.c
> @@ -2471,6 +2471,188 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
>        hci_close_dev(dd);
>  }
>
> +static struct option leaddwl_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *leaddwl_help =
> +       "Usage:\n"
> +       "\tleaddwl <bdaddr>\n";
> +
> +static void cmd_leaddwl(int dev_id, int argc,char **argv)
> +{
> +       int err, opt, dd;
> +       bdaddr_t bdaddr;
> +       uint8_t bdaddr_type;
> +
> +       for_each_opt(opt, leaddwl_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", leaddwl_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(1, 1, &argc, &argv, leaddwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       str2ba(argv[1], &bdaddr);
> +       bdaddr_type = 0x00;
> +
> +       err = hci_le_add_to_white_list(dd, bdaddr ,bdaddr_type);
> +       if (err < 0) {
> +               perror("Cant add to white list");
> +               exit(1);
> +       }
> +       else {
> +               printf("Device added to white list");
> +       }
> +
> +       hci_close_dev(dd);
> +
> +}
> +
> +static struct option lermwl_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *lermwl_help =
> +       "Usage:\n"
> +       "\tlermwl <bdaddr>\n";
> +
> +static void cmd_lermwl(int dev_id, int argc,char **argv)
> +{
> +       int err, opt, dd;
> +       bdaddr_t bdaddr;
> +       uint8_t bdaddr_type;
> +
> +       for_each_opt(opt, lermwl_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", lermwl_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(1, 1, &argc, &argv, lermwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       str2ba(argv[1], &bdaddr);
> +       bdaddr_type = 0x00;
> +
> +       err = hci_le_remove_from_white_list(dd, bdaddr ,bdaddr_type);
> +       if (err < 0) {
> +               perror("Cant remove from white list");
> +               exit(1);
> +       }
> +        else {
> +               printf("Device removed from white list");
> +       }
> +
> +       hci_close_dev(dd);
> +
> +}
> +
> +static struct option lerdwlsz_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *lerdwlsz_help =
> +       "Usage:\n"
> +       "\tlerdwlsz\n";
> +
> +static void cmd_lerdwlsz(int dev_id, int argc,char **argv)
> +{
> +       int err,dd, opt;
> +
> +       for_each_opt(opt, lerdwlsz_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", lerdwlsz_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(0, 0, &argc, &argv, lermwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       err = hci_le_read_white_list_size(dd);
> +       if (err < 0) {
> +               perror("Cant read white list size");
> +               exit(1);
> +       }
> +
> +       hci_close_dev(dd);
> +
> +}
> +
> +
> +static struct option leclrwl_options[] = {
> +       { "help",       0, 0, 'h' },
> +       { 0, 0, 0, 0 }
> +};
> +
> +static const char *leclrwl_help =
> +       "Usage:\n"
> +       "\tleclrwl\n";
> +
> +static void cmd_leclrwl(int dev_id, int argc,char **argv)
> +{
> +       int err,dd, opt;
> +
> +       for_each_opt(opt, leclrwl_options, NULL) {
> +               switch (opt) {
> +               default:
> +                       printf("%s", leclrwl_help);
> +                       return;
> +               }
> +       }
> +       helper_arg(0, 0, &argc, &argv, leclrwl_help);
> +
> +       if (dev_id < 0)
> +               dev_id = hci_get_route(NULL);
> +
> +       dd = hci_open_dev(dev_id);
> +       if (dd < 0) {
> +               perror("Could not open device");
> +               exit(1);
> +       }
> +
> +       err = hci_le_clear_white_list(dd);
> +       if (err < 0) {
> +               perror("Cant clear white list");
> +               exit(1);
> +       }
> +
> +       hci_close_dev(dd);
> +
> +}
> +
> +
>  static struct option ledc_options[] = {
>        { "help",       0, 0, 'h' },
>        { 0, 0, 0, 0 }
> @@ -2547,6 +2729,10 @@ static struct {
>        { "clkoff", cmd_clkoff, "Read clock offset"                    },
>        { "clock",  cmd_clock,  "Read local or remote clock"           },
>        { "lescan", cmd_lescan, "Start LE scan"                        },
> +       { "leaddwl", cmd_leaddwl, "Add this device to white list"          },
> +       { "lermwl", cmd_lermwl, "Remove this device from white list"   },
> +       { "lerdwlsz",  cmd_lerdwlsz,  "Read white list size"               },
> +       { "leclrwl",   cmd_leclrwl,   "Clear white list"                   },
>        { "lecc",   cmd_lecc,   "Create a LE Connection",              },
>        { "ledc",   cmd_ledc,   "Disconnect a LE Connection",          },
>        { NULL, NULL, 0 }
> --
> 1.6.5
>

Did you get some time to review our patches?


Thanks,
Arun


>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html