2017-12-21 16:47:15

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ 1/6] shared/btp: define gap device found flags as bit mask

This patch modifies gap device found flags to be bit masks as in other
defined flags groups in btp.
---
src/shared/btp.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/shared/btp.h b/src/shared/btp.h
index 5044de822..7b1f48817 100644
--- a/src/shared/btp.h
+++ b/src/shared/btp.h
@@ -241,9 +241,9 @@ struct btp_new_settings_ev {
uint32_t current_settings;
} __packed;

-#define BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI 0x00
-#define BTP_EV_GAP_DEVICE_FOUND_FLAG_AD 0x01
-#define BTP_EV_GAP_DEVICE_FOUND_FLAG_SR 0x02
+#define BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI 0x01
+#define BTP_EV_GAP_DEVICE_FOUND_FLAG_AD 0x02
+#define BTP_EV_GAP_DEVICE_FOUND_FLAG_SR 0x04

#define BTP_EV_GAP_DEVICE_FOUND 0x81
struct btp_device_found_ev {
--
2.13.6



2017-12-22 13:53:19

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: Re: [PATCH BlueZ 5/6] tools/btpclient: Add start, stop discovery commands

Hi,

2017-12-22 11:48 GMT+01:00 Szymon Janc <[email protected]>:
> On Thursday, 21 December 2017 17:47:19 CET Grzegorz Kolodziejczyk wrote:
>> This patch adds start and stop discovery command for btp client.
>> ---
>> tools/btpclient.c | 220
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2=
20
>> insertions(+)
>>
>> diff --git a/tools/btpclient.c b/tools/btpclient.c
>> index c0ad03b68..f4b930a51 100644
>> --- a/tools/btpclient.c
>> +++ b/tools/btpclient.c
>> @@ -122,6 +122,8 @@ static void btp_gap_read_commands(uint8_t index, con=
st
>> void *param, commands |=3D (1 << BTP_OP_GAP_SET_POWERED);
>> commands |=3D (1 << BTP_OP_GAP_SET_DISCOVERABLE);
>> commands |=3D (1 << BTP_OP_GAP_SET_BONDABLE);
>> + commands |=3D (1 << BTP_OP_GAP_START_DISCOVERY);
>> + commands |=3D (1 << BTP_OP_GAP_STOP_DISCOVERY);
>>
>> commands =3D L_CPU_TO_LE16(commands);
>>
>> @@ -399,6 +401,218 @@ failed:
>> btp_send_error(btp, BTP_GAP_SERVICE, index, status);
>> }
>>
>> +static void start_discovery_reply(struct l_dbus_proxy *proxy,
>> + struct l_dbus_message *res=
ult,
>> + void *user_data)
>> +{
>> + struct btp_adapter *adapter =3D find_adapter_by_proxy(proxy);
>> +
>> + if (!adapter) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROL=
LER,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + if (l_dbus_message_is_error(result)) {
>> + const char *name, *desc;
>> +
>> + l_dbus_message_get_error(result, &name, &desc);
>> + l_error("Failed to start discovery (%s), %s", name, desc);
>> +
>> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
>> + adapter->index, 0, NULL);
>> +}
>> +
>> +static void set_start_discovery_filter_setup(struct l_dbus_message
>> *message, + void *user=
_data)
>> +{
>> + uint8_t flags =3D L_PTR_TO_UINT(user_data);
>> + struct l_dbus_message_builder *builder;
>
> Add basic sanity check here for flags ie at least one of LE or BR should =
be
> set.
Ok
>
>> +
>> + builder =3D l_dbus_message_builder_new(message);
>> +
>> + l_dbus_message_builder_enter_array(builder, "{sv}");
>> + l_dbus_message_builder_enter_dict(builder, "sv");
>> +
>> + /* Be in observer mode or in general mode (default in Bluez) */
>> + if (flags & BTP_GAP_DISCOVERY_FLAG_OBSERVATION) {
>> + l_dbus_message_builder_append_basic(builder, 's', "Transpo=
rt");
>> + l_dbus_message_builder_enter_variant(builder, "s");
>> +
>> + if (flags & (BTP_GAP_DISCOVERY_FLAG_LE |
>> + BTP_GAP_DISCOVERY_FLAG_BRE=
DR))
>> + l_dbus_message_builder_append_basic(builder, 's',
>> + "a=
uto");
>> + else if (flags & BTP_GAP_DISCOVERY_FLAG_LE)
>> + l_dbus_message_builder_append_basic(builder, 's', =
"le");
>> + else if (flags & BTP_GAP_DISCOVERY_FLAG_BREDR)
>> + l_dbus_message_builder_append_basic(builder, 's',
>> + "bredr");
>> +
>> + l_dbus_message_builder_leave_variant(builder);
>> + }
>> +
>> + l_dbus_message_builder_leave_dict(builder);
>> + l_dbus_message_builder_leave_array(builder);
>> +
>> + /* TODO add passive, limited discovery */
>> + l_dbus_message_builder_finalize(builder);
>> + l_dbus_message_builder_destroy(builder);
>> +}
>> +
>> +static void set_start_discovery_filter_reply(struct l_dbus_proxy *proxy=
,
>> + struct l_dbus_message *res=
ult,
>> + void *user_data)
>> +{
>> + struct btp_adapter *adapter =3D find_adapter_by_proxy(proxy);
>> +
>> + if (!adapter) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROL=
LER,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + if (l_dbus_message_is_error(result)) {
>> + const char *name, *desc;
>> +
>> + l_dbus_message_get_error(result, &name, &desc);
>> + l_error("Failed to set discovery filter (%s), %s", name, d=
esc);
>> +
>> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + l_dbus_proxy_method_call(adapter->proxy, "StartDiscovery", NULL,
>> + start_discovery_reply, NULL, NULL)=
;
>> +}
>> +
>> +static void btp_gap_start_discovery(uint8_t index, const void *param,
>> + uint16_t length, void *user_data)
>> +{
>> + struct btp_adapter *adapter =3D find_adapter_by_index(index);
>> + const struct btp_gap_start_discovery_cp *cp =3D param;
>> + bool prop;
>> +
>> + if (!adapter) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, index,
>> + BTP_ERROR_INVALID_INDEX);
>> + return;
>> + }
>> +
>> + /* Adapter needs to be powered to start discovery */
>> + if (!l_dbus_proxy_get_property(adapter->proxy, "Powered", "b", &pr=
op) ||
>> + !p=
rop) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL=
);
>> + return;
>> + }
>> +
>> + l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
>> + set_start_discovery_filter_setup,
>> + set_start_discovery_filter_reply,
>
> nitpick: Name it set_discovery_filer_setup/reply.
Ok, I'll correct it
>
>> + L_UINT_TO_PTR(cp->flags), NULL);
>> +}
>> +
>> +static void set_stop_discovery_filter_setup(struct l_dbus_message *mess=
age,
>> + void *user_data)
>> +{
>> + struct l_dbus_message_builder *builder;
>> +
>> + builder =3D l_dbus_message_builder_new(message);
>> +
>> + /* Clear discovery filter setup */
>> + l_dbus_message_builder_enter_array(builder, "{sv}");
>> + l_dbus_message_builder_enter_dict(builder, "sv");
>> + l_dbus_message_builder_leave_dict(builder);
>> + l_dbus_message_builder_leave_array(builder);
>> + l_dbus_message_builder_finalize(builder);
>> + l_dbus_message_builder_destroy(builder);
>> +}
>> +
>> +static void set_stop_discovery_filter_reply(struct l_dbus_proxy *proxy,
>> + struct l_dbus_message *res=
ult,
>> + void *user_data)
>> +{
>> + struct btp_adapter *adapter =3D find_adapter_by_proxy(proxy);
>> +
>> + if (!adapter) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROL=
LER,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + if (l_dbus_message_is_error(result)) {
>> + const char *name, *desc;
>> +
>> + l_dbus_message_get_error(result, &name, &desc);
>> + l_error("Failed to set discovery filter (%s), %s", name, d=
esc);
>> +
>> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
>> + adapter->index, 0, NULL);
>> +}
>> +
>> +static void stop_discovery_reply(struct l_dbus_proxy *proxy,
>> + struct l_dbus_message *res=
ult,
>> + void *user_data)
>> +{
>> + struct btp_adapter *adapter =3D find_adapter_by_proxy(proxy);
>> +
>> + if (!adapter) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROL=
LER,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + if (l_dbus_message_is_error(result)) {
>> + const char *name;
>> +
>> + l_dbus_message_get_error(result, &name, NULL);
>> + l_error("Failed to stop discovery (%s)", name);
>> +
>> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
>> + BTP_ERROR_=
FAIL);
>> + return;
>> + }
>> +
>> + l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
>> + set_stop_discovery_filter_=
setup,
>> + set_stop_discovery_filter_=
reply,
>
> Name those clear_discovery_filter_setup/reply.
Ok, I'll correct it
>
>> + NULL, NULL);
>> +}
>> +
>> +static void btp_gap_stop_discovery(uint8_t index, const void *param,
>> + uint16_t length, void *user_data)
>> +{
>> + struct btp_adapter *adapter =3D find_adapter_by_index(index);
>> + bool prop;
>> +
>> + if (!adapter) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, index,
>> + BTP_ERROR_INVALID_INDEX);
>> + return;
>> + }
>> +
>> + /* Adapter needs to be powered to be able to remove devices */
>> + if (!l_dbus_proxy_get_property(adapter->proxy, "Powered", "b", &pr=
op) ||
>> + !p=
rop) {
>> + btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL=
);
>> + return;
>> + }
>> +
>> + l_dbus_proxy_method_call(adapter->proxy, "StopDiscovery", NULL,
>> + stop_discovery_reply, NULL, NULL);
>> +}
>> +
>> static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy)
>> {
>> struct btp_device_found_ev ev;
>> @@ -453,6 +667,12 @@ static void register_gap_service(void)
>>
>> btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_BONDABLE,
>> btp_gap_set_bondable, NULL, NULL);
>> +
>> + btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
>> + btp_gap_start_discovery, NULL, NUL=
L);
>> +
>> + btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
>> + btp_gap_stop_discovery, NULL, NULL=
);
>> }
>>
>> static void btp_core_read_commands(uint8_t index, const void *param,
>
>
> --
> pozdrawiam
> Szymon Janc

pozdrawiam,
Grzegorz Ko=C5=82odziejczyk

2017-12-22 13:51:43

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: Re: [PATCH BlueZ 4/6] tools/btpclient: Add device found event

Hi,

2017-12-22 11:48 GMT+01:00 Szymon Janc <[email protected]>:
> Hi Grzegorz,
>
> On Thursday, 21 December 2017 17:47:18 CET Grzegorz Kolodziejczyk wrote:
>> This patch adds device found event handler. It's called when rssi
>> property of device changes and new device interface is added.
>> ---
>> tools/btpclient.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 42 insertions(+)
>>
>> diff --git a/tools/btpclient.c b/tools/btpclient.c
>> index 095c5ea3e..c0ad03b68 100644
>> --- a/tools/btpclient.c
>> +++ b/tools/btpclient.c
>> @@ -399,6 +399,37 @@ failed:
>> btp_send_error(btp, BTP_GAP_SERVICE, index, status);
>> }
>>
>> +static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy)
>> +{
>> + struct btp_device_found_ev ev;
>> + const char *str;
>> +
>> + if (!l_dbus_proxy_get_property(proxy, "Address", "s", &str) ||
>> + (str2addr(str, ev.address) !=3D 6)=
)
>> + return;
>> +
>> + if (!l_dbus_proxy_get_property(proxy, "AddressType", "s", &str))
>> + return;
>> +
>> + ev.address_type =3D strcmp(str, "public") ? BTP_GAP_ADDR_RANDOM :
>> + BTP_GAP_ADDR_PUBLI=
C;
>> +
>> + if (!l_dbus_proxy_get_property(proxy, "RSSI", "n", &ev.rssi))
>
> "n" expects pointer to int16_t so you need to use local tmp for this.
> (this is due to no signed int8_t on D-Bus, only byte type)
Ok
>
>> + return;
>> +
>> + /* TODO Temporary set all flags */
>> + ev.flags =3D (BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI |
>> + BTP_EV_GAP_DEVICE_FOUND_FLAG_AD |
>> + BTP_EV_GAP_DEVICE_FOUND_FLAG_SR);
>> +
>> + /* TODO Add eir to device found event */
>> + ev.eir_len =3D 0;
>> +
>> + btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND,
>> + BTP_INDEX_NON_CONTROLLER,
>> + sizeof(ev) + ev.eir_len, &=
ev);
>> +}
>> +
>> static void register_gap_service(void)
>> {
>> btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_READ_SUPPORTED_COMMA=
NDS,
>> @@ -661,6 +692,8 @@ static void proxy_added(struct l_dbus_proxy *proxy, =
void
>> *user_data)
>>
>> l_queue_push_tail(adapter->devices, device);
>>
>> + btp_gap_device_found_ev(proxy);
>> +
>> return;
>> }
>>
>> @@ -782,6 +815,15 @@ static void property_changed(struct l_dbus_proxy
>> *proxy, const char *name, update_current_settings(adapter, new_settings)=
;
>>
>> return;
>> + } else if (!strcmp(interface, "org.bluez.Device1")) {
>> + if (!strcmp(name, "RSSI")) {
>> + uint16_t rssi;
>
> Should be int16_t.
Right, I've made typo
>
>> +
>> + if (!l_dbus_message_get_arguments(msg, "n", &rssi)=
)
>> + return;
>> +
>> + btp_gap_device_found_ev(proxy);
>> + }
>> }
>> }
>
>
> --
> pozdrawiam
> Szymon Janc


pozdrawiam,
Grzegorz Ko=C5=82odziejczyk

2017-12-22 13:50:32

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: Re: [PATCH BlueZ 3/6] tools/btpclient: Add advertising proxy to adapter

Hi,

2017-12-22 11:48 GMT+01:00 Szymon Janc <[email protected]>:
> Hi Grzegorz,
>
> On Thursday, 21 December 2017 17:47:17 CET Grzegorz Kolodziejczyk wrote:
>> Advertising manager proxy is required to handle advertise related
>> operations in adapter context.
>> ---
>> tools/btpclient.c | 12 ++++++++++++
>> 1 file changed, 12 insertions(+)
>>
>> diff --git a/tools/btpclient.c b/tools/btpclient.c
>> index 27e5a498e..095c5ea3e 100644
>> --- a/tools/btpclient.c
>> +++ b/tools/btpclient.c
>> @@ -36,6 +36,7 @@
>>
>> struct btp_adapter {
>> struct l_dbus_proxy *proxy;
>> + struct l_dbus_proxy *ad_proxy;
>> uint8_t index;
>> uint32_t supported_settings;
>> uint32_t current_settings;
>> @@ -659,6 +660,17 @@ static void proxy_added(struct l_dbus_proxy *proxy,
>> void *user_data) device->proxy =3D proxy;
>>
>> l_queue_push_tail(adapter->devices, device);
>> +
>> + return;
>> + }
>> +
>> + if (!strcmp(interface, "org.bluez.LEAdvertisingManager1")) {
>> + struct btp_adapter *adapter;
>> +
>> + adapter =3D find_adapter_by_path(path);
>
> This may return NULL if we failed to add proxy of adapter or due to inval=
id
> message. Please check that.
OK
>
>> +
>> + adapter->ad_proxy =3D proxy;
>> +
>> return;
>> }
>> }
>
>
> --
> pozdrawiam
> Szymon Janc

pozdrawiam
Grzegorz Ko=C5=82odziejczyk

2017-12-22 13:49:59

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: Re: [PATCH BlueZ 2/6] tools/btpclient: Move string to address conversion to helper

Hi,

2017-12-22 11:48 GMT+01:00 Szymon Janc <[email protected]>:
> Hi Grzegorz,
>
> On Thursday, 21 December 2017 17:47:16 CET Grzegorz Kolodziejczyk wrote:
>> This patch makes local helper with string to address conversion.
>> ---
>> tools/btpclient.c | 10 +++++++---
>> 1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/btpclient.c b/tools/btpclient.c
>> index 9ea624995..27e5a498e 100644
>> --- a/tools/btpclient.c
>> +++ b/tools/btpclient.c
>> @@ -52,6 +52,12 @@ static struct btp *btp;
>>
>> static bool gap_service_registered;
>>
>> +static inline uint8_t str2addr(const char *str, uint8_t *addr)
>
> Just static, no need for inline in .c file.
> Also make this return bool and verify sscanf return value in helper.
OK
>
>> +{
>> + return sscanf(str,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[5], &addr=
[4],
>> + &addr[3], &addr[2], &addr[1], &add=
r[0]);
>> +}
>> +
>> static struct btp_adapter *find_adapter_by_proxy(struct l_dbus_proxy
>> *proxy) {
>> const struct l_queue_entry *entry;
>> @@ -171,9 +177,7 @@ static void btp_gap_read_info(uint8_t index, const v=
oid
>> *param, uint16_t length, if (!l_dbus_proxy_get_property(adapter->proxy,
>> "Address", "s", &str)) goto failed;
>>
>> - if (sscanf(str,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
>> - &rp.address[5], &rp.address[4], &rp.address[3],
>> - &rp.address[2], &rp.address[1], &rp.address[0]) !=
=3D 6)
>> + if (str2addr(str, rp.address) !=3D 6)
>> goto failed;
>>
>> if (!l_dbus_proxy_get_property(adapter->proxy, "Name", "s", &str))=
{
>
>
> --
> pozdrawiam
> Szymon Janc

pozdrawiam,
Grzegorz Ko=C5=82odziejczyk

2017-12-22 10:49:45

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH BlueZ 1/6] shared/btp: define gap device found flags as bit mask

Hi Grzegorz,

On Thursday, 21 December 2017 17:47:15 CET Grzegorz Kolodziejczyk wrote:
> This patch modifies gap device found flags to be bit masks as in other
> defined flags groups in btp.
> ---
> src/shared/btp.h | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/src/shared/btp.h b/src/shared/btp.h
> index 5044de822..7b1f48817 100644
> --- a/src/shared/btp.h
> +++ b/src/shared/btp.h
> @@ -241,9 +241,9 @@ struct btp_new_settings_ev {
> uint32_t current_settings;
> } __packed;
>
> -#define BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI 0x00
> -#define BTP_EV_GAP_DEVICE_FOUND_FLAG_AD 0x01
> -#define BTP_EV_GAP_DEVICE_FOUND_FLAG_SR 0x02
> +#define BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI 0x01
> +#define BTP_EV_GAP_DEVICE_FOUND_FLAG_AD 0x02
> +#define BTP_EV_GAP_DEVICE_FOUND_FLAG_SR 0x04
>
> #define BTP_EV_GAP_DEVICE_FOUND 0x81
> struct btp_device_found_ev {

This patch is now applied, thanks.

--
pozdrawiam
Szymon Janc

2017-12-22 10:48:27

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH BlueZ 3/6] tools/btpclient: Add advertising proxy to adapter

Hi Grzegorz,

On Thursday, 21 December 2017 17:47:17 CET Grzegorz Kolodziejczyk wrote:
> Advertising manager proxy is required to handle advertise related
> operations in adapter context.
> ---
> tools/btpclient.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/tools/btpclient.c b/tools/btpclient.c
> index 27e5a498e..095c5ea3e 100644
> --- a/tools/btpclient.c
> +++ b/tools/btpclient.c
> @@ -36,6 +36,7 @@
>
> struct btp_adapter {
> struct l_dbus_proxy *proxy;
> + struct l_dbus_proxy *ad_proxy;
> uint8_t index;
> uint32_t supported_settings;
> uint32_t current_settings;
> @@ -659,6 +660,17 @@ static void proxy_added(struct l_dbus_proxy *proxy,
> void *user_data) device->proxy = proxy;
>
> l_queue_push_tail(adapter->devices, device);
> +
> + return;
> + }
> +
> + if (!strcmp(interface, "org.bluez.LEAdvertisingManager1")) {
> + struct btp_adapter *adapter;
> +
> + adapter = find_adapter_by_path(path);

This may return NULL if we failed to add proxy of adapter or due to invalid
message. Please check that.

> +
> + adapter->ad_proxy = proxy;
> +
> return;
> }
> }


--
pozdrawiam
Szymon Janc

2017-12-22 10:48:28

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH BlueZ 2/6] tools/btpclient: Move string to address conversion to helper

Hi Grzegorz,

On Thursday, 21 December 2017 17:47:16 CET Grzegorz Kolodziejczyk wrote:
> This patch makes local helper with string to address conversion.
> ---
> tools/btpclient.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/tools/btpclient.c b/tools/btpclient.c
> index 9ea624995..27e5a498e 100644
> --- a/tools/btpclient.c
> +++ b/tools/btpclient.c
> @@ -52,6 +52,12 @@ static struct btp *btp;
>
> static bool gap_service_registered;
>
> +static inline uint8_t str2addr(const char *str, uint8_t *addr)

Just static, no need for inline in .c file.
Also make this return bool and verify sscanf return value in helper.

> +{
> + return sscanf(str,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[5], &addr[4],
> + &addr[3], &addr[2], &addr[1], &addr[0]);
> +}
> +
> static struct btp_adapter *find_adapter_by_proxy(struct l_dbus_proxy
> *proxy) {
> const struct l_queue_entry *entry;
> @@ -171,9 +177,7 @@ static void btp_gap_read_info(uint8_t index, const void
> *param, uint16_t length, if (!l_dbus_proxy_get_property(adapter->proxy,
> "Address", "s", &str)) goto failed;
>
> - if (sscanf(str,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
> - &rp.address[5], &rp.address[4], &rp.address[3],
> - &rp.address[2], &rp.address[1], &rp.address[0]) != 6)
> + if (str2addr(str, rp.address) != 6)
> goto failed;
>
> if (!l_dbus_proxy_get_property(adapter->proxy, "Name", "s", &str)) {


--
pozdrawiam
Szymon Janc

2017-12-22 10:48:26

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH BlueZ 5/6] tools/btpclient: Add start, stop discovery commands

On Thursday, 21 December 2017 17:47:19 CET Grzegorz Kolodziejczyk wrote:
> This patch adds start and stop discovery command for btp client.
> ---
> tools/btpclient.c | 220
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220
> insertions(+)
>
> diff --git a/tools/btpclient.c b/tools/btpclient.c
> index c0ad03b68..f4b930a51 100644
> --- a/tools/btpclient.c
> +++ b/tools/btpclient.c
> @@ -122,6 +122,8 @@ static void btp_gap_read_commands(uint8_t index, const
> void *param, commands |= (1 << BTP_OP_GAP_SET_POWERED);
> commands |= (1 << BTP_OP_GAP_SET_DISCOVERABLE);
> commands |= (1 << BTP_OP_GAP_SET_BONDABLE);
> + commands |= (1 << BTP_OP_GAP_START_DISCOVERY);
> + commands |= (1 << BTP_OP_GAP_STOP_DISCOVERY);
>
> commands = L_CPU_TO_LE16(commands);
>
> @@ -399,6 +401,218 @@ failed:
> btp_send_error(btp, BTP_GAP_SERVICE, index, status);
> }
>
> +static void start_discovery_reply(struct l_dbus_proxy *proxy,
> + struct l_dbus_message *result,
> + void *user_data)
> +{
> + struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
> +
> + if (!adapter) {
> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + if (l_dbus_message_is_error(result)) {
> + const char *name, *desc;
> +
> + l_dbus_message_get_error(result, &name, &desc);
> + l_error("Failed to start discovery (%s), %s", name, desc);
> +
> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
> + adapter->index, 0, NULL);
> +}
> +
> +static void set_start_discovery_filter_setup(struct l_dbus_message
> *message, + void *user_data)
> +{
> + uint8_t flags = L_PTR_TO_UINT(user_data);
> + struct l_dbus_message_builder *builder;

Add basic sanity check here for flags ie at least one of LE or BR should be
set.

> +
> + builder = l_dbus_message_builder_new(message);
> +
> + l_dbus_message_builder_enter_array(builder, "{sv}");
> + l_dbus_message_builder_enter_dict(builder, "sv");
> +
> + /* Be in observer mode or in general mode (default in Bluez) */
> + if (flags & BTP_GAP_DISCOVERY_FLAG_OBSERVATION) {
> + l_dbus_message_builder_append_basic(builder, 's', "Transport");
> + l_dbus_message_builder_enter_variant(builder, "s");
> +
> + if (flags & (BTP_GAP_DISCOVERY_FLAG_LE |
> + BTP_GAP_DISCOVERY_FLAG_BREDR))
> + l_dbus_message_builder_append_basic(builder, 's',
> + "auto");
> + else if (flags & BTP_GAP_DISCOVERY_FLAG_LE)
> + l_dbus_message_builder_append_basic(builder, 's', "le");
> + else if (flags & BTP_GAP_DISCOVERY_FLAG_BREDR)
> + l_dbus_message_builder_append_basic(builder, 's',
> + "bredr");
> +
> + l_dbus_message_builder_leave_variant(builder);
> + }
> +
> + l_dbus_message_builder_leave_dict(builder);
> + l_dbus_message_builder_leave_array(builder);
> +
> + /* TODO add passive, limited discovery */
> + l_dbus_message_builder_finalize(builder);
> + l_dbus_message_builder_destroy(builder);
> +}
> +
> +static void set_start_discovery_filter_reply(struct l_dbus_proxy *proxy,
> + struct l_dbus_message *result,
> + void *user_data)
> +{
> + struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
> +
> + if (!adapter) {
> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + if (l_dbus_message_is_error(result)) {
> + const char *name, *desc;
> +
> + l_dbus_message_get_error(result, &name, &desc);
> + l_error("Failed to set discovery filter (%s), %s", name, desc);
> +
> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + l_dbus_proxy_method_call(adapter->proxy, "StartDiscovery", NULL,
> + start_discovery_reply, NULL, NULL);
> +}
> +
> +static void btp_gap_start_discovery(uint8_t index, const void *param,
> + uint16_t length, void *user_data)
> +{
> + struct btp_adapter *adapter = find_adapter_by_index(index);
> + const struct btp_gap_start_discovery_cp *cp = param;
> + bool prop;
> +
> + if (!adapter) {
> + btp_send_error(btp, BTP_GAP_SERVICE, index,
> + BTP_ERROR_INVALID_INDEX);
> + return;
> + }
> +
> + /* Adapter needs to be powered to start discovery */
> + if (!l_dbus_proxy_get_property(adapter->proxy, "Powered", "b", &prop) ||
> + !prop) {
> + btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL);
> + return;
> + }
> +
> + l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
> + set_start_discovery_filter_setup,
> + set_start_discovery_filter_reply,

nitpick: Name it set_discovery_filer_setup/reply.

> + L_UINT_TO_PTR(cp->flags), NULL);
> +}
> +
> +static void set_stop_discovery_filter_setup(struct l_dbus_message *message,
> + void *user_data)
> +{
> + struct l_dbus_message_builder *builder;
> +
> + builder = l_dbus_message_builder_new(message);
> +
> + /* Clear discovery filter setup */
> + l_dbus_message_builder_enter_array(builder, "{sv}");
> + l_dbus_message_builder_enter_dict(builder, "sv");
> + l_dbus_message_builder_leave_dict(builder);
> + l_dbus_message_builder_leave_array(builder);
> + l_dbus_message_builder_finalize(builder);
> + l_dbus_message_builder_destroy(builder);
> +}
> +
> +static void set_stop_discovery_filter_reply(struct l_dbus_proxy *proxy,
> + struct l_dbus_message *result,
> + void *user_data)
> +{
> + struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
> +
> + if (!adapter) {
> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + if (l_dbus_message_is_error(result)) {
> + const char *name, *desc;
> +
> + l_dbus_message_get_error(result, &name, &desc);
> + l_error("Failed to set discovery filter (%s), %s", name, desc);
> +
> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
> + adapter->index, 0, NULL);
> +}
> +
> +static void stop_discovery_reply(struct l_dbus_proxy *proxy,
> + struct l_dbus_message *result,
> + void *user_data)
> +{
> + struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
> +
> + if (!adapter) {
> + btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + if (l_dbus_message_is_error(result)) {
> + const char *name;
> +
> + l_dbus_message_get_error(result, &name, NULL);
> + l_error("Failed to stop discovery (%s)", name);
> +
> + btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
> + BTP_ERROR_FAIL);
> + return;
> + }
> +
> + l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
> + set_stop_discovery_filter_setup,
> + set_stop_discovery_filter_reply,

Name those clear_discovery_filter_setup/reply.

> + NULL, NULL);
> +}
> +
> +static void btp_gap_stop_discovery(uint8_t index, const void *param,
> + uint16_t length, void *user_data)
> +{
> + struct btp_adapter *adapter = find_adapter_by_index(index);
> + bool prop;
> +
> + if (!adapter) {
> + btp_send_error(btp, BTP_GAP_SERVICE, index,
> + BTP_ERROR_INVALID_INDEX);
> + return;
> + }
> +
> + /* Adapter needs to be powered to be able to remove devices */
> + if (!l_dbus_proxy_get_property(adapter->proxy, "Powered", "b", &prop) ||
> + !prop) {
> + btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL);
> + return;
> + }
> +
> + l_dbus_proxy_method_call(adapter->proxy, "StopDiscovery", NULL,
> + stop_discovery_reply, NULL, NULL);
> +}
> +
> static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy)
> {
> struct btp_device_found_ev ev;
> @@ -453,6 +667,12 @@ static void register_gap_service(void)
>
> btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_BONDABLE,
> btp_gap_set_bondable, NULL, NULL);
> +
> + btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
> + btp_gap_start_discovery, NULL, NULL);
> +
> + btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
> + btp_gap_stop_discovery, NULL, NULL);
> }
>
> static void btp_core_read_commands(uint8_t index, const void *param,


--
pozdrawiam
Szymon Janc

2017-12-22 10:48:27

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH BlueZ 4/6] tools/btpclient: Add device found event

Hi Grzegorz,

On Thursday, 21 December 2017 17:47:18 CET Grzegorz Kolodziejczyk wrote:
> This patch adds device found event handler. It's called when rssi
> property of device changes and new device interface is added.
> ---
> tools/btpclient.c | 42 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 42 insertions(+)
>
> diff --git a/tools/btpclient.c b/tools/btpclient.c
> index 095c5ea3e..c0ad03b68 100644
> --- a/tools/btpclient.c
> +++ b/tools/btpclient.c
> @@ -399,6 +399,37 @@ failed:
> btp_send_error(btp, BTP_GAP_SERVICE, index, status);
> }
>
> +static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy)
> +{
> + struct btp_device_found_ev ev;
> + const char *str;
> +
> + if (!l_dbus_proxy_get_property(proxy, "Address", "s", &str) ||
> + (str2addr(str, ev.address) != 6))
> + return;
> +
> + if (!l_dbus_proxy_get_property(proxy, "AddressType", "s", &str))
> + return;
> +
> + ev.address_type = strcmp(str, "public") ? BTP_GAP_ADDR_RANDOM :
> + BTP_GAP_ADDR_PUBLIC;
> +
> + if (!l_dbus_proxy_get_property(proxy, "RSSI", "n", &ev.rssi))

"n" expects pointer to int16_t so you need to use local tmp for this.
(this is due to no signed int8_t on D-Bus, only byte type)

> + return;
> +
> + /* TODO Temporary set all flags */
> + ev.flags = (BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI |
> + BTP_EV_GAP_DEVICE_FOUND_FLAG_AD |
> + BTP_EV_GAP_DEVICE_FOUND_FLAG_SR);
> +
> + /* TODO Add eir to device found event */
> + ev.eir_len = 0;
> +
> + btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND,
> + BTP_INDEX_NON_CONTROLLER,
> + sizeof(ev) + ev.eir_len, &ev);
> +}
> +
> static void register_gap_service(void)
> {
> btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_READ_SUPPORTED_COMMANDS,
> @@ -661,6 +692,8 @@ static void proxy_added(struct l_dbus_proxy *proxy, void
> *user_data)
>
> l_queue_push_tail(adapter->devices, device);
>
> + btp_gap_device_found_ev(proxy);
> +
> return;
> }
>
> @@ -782,6 +815,15 @@ static void property_changed(struct l_dbus_proxy
> *proxy, const char *name, update_current_settings(adapter, new_settings);
>
> return;
> + } else if (!strcmp(interface, "org.bluez.Device1")) {
> + if (!strcmp(name, "RSSI")) {
> + uint16_t rssi;

Should be int16_t.

> +
> + if (!l_dbus_message_get_arguments(msg, "n", &rssi))
> + return;
> +
> + btp_gap_device_found_ev(proxy);
> + }
> }
> }


--
pozdrawiam
Szymon Janc

2017-12-21 16:47:20

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ 6/6] tools/btpclient: Add set connectable command

This patch adds set connectable command for btp client.
---
tools/btpclient.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 51 insertions(+), 13 deletions(-)

diff --git a/tools/btpclient.c b/tools/btpclient.c
index f4b930a51..f57550f66 100644
--- a/tools/btpclient.c
+++ b/tools/btpclient.c
@@ -120,6 +120,7 @@ static void btp_gap_read_commands(uint8_t index, const void *param,
commands |= (1 << BTP_OP_GAP_READ_COTROLLER_INFO);
commands |= (1 << BTP_OP_GAP_RESET);
commands |= (1 << BTP_OP_GAP_SET_POWERED);
+ commands |= (1 << BTP_OP_GAP_SET_CONNECTABLE);
commands |= (1 << BTP_OP_GAP_SET_DISCOVERABLE);
commands |= (1 << BTP_OP_GAP_SET_BONDABLE);
commands |= (1 << BTP_OP_GAP_START_DISCOVERY);
@@ -335,6 +336,53 @@ failed:
btp_send_error(btp, BTP_GAP_SERVICE, index, status);
}

+static void update_current_settings(struct btp_adapter *adapter,
+ uint32_t new_settings)
+{
+ struct btp_new_settings_ev ev;
+
+ adapter->current_settings = new_settings;
+
+ ev.current_settings = L_CPU_TO_LE32(adapter->current_settings);
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_NEW_SETTINGS, adapter->index,
+ sizeof(ev), &ev);
+}
+
+static void btp_gap_set_connectable(uint8_t index, const void *param,
+ uint16_t length, void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_index(index);
+ const struct btp_gap_set_connectable_cp *cp = param;
+ uint8_t status = BTP_ERROR_FAIL;
+ uint32_t new_settings;
+
+ if (length < sizeof(*cp))
+ goto failed;
+
+ if (!adapter) {
+ status = BTP_ERROR_INVALID_INDEX;
+ goto failed;
+ }
+
+ new_settings = adapter->current_settings;
+
+ if (cp->connectable)
+ new_settings |= 1 << BTP_GAP_SETTING_CONNECTABLE;
+ else
+ new_settings &= ~(1 << BTP_GAP_SETTING_CONNECTABLE);
+
+ update_current_settings(adapter, new_settings);
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_CONNECTABLE, index,
+ sizeof(new_settings), &new_settings);
+
+ return;
+
+failed:
+ btp_send_error(btp, BTP_GAP_SERVICE, index, status);
+}
+
static void btp_gap_set_discoverable(uint8_t index, const void *param,
uint16_t length, void *user_data)
{
@@ -662,6 +710,9 @@ static void register_gap_service(void)
btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_POWERED,
btp_gap_set_powered, NULL, NULL);

+ btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_CONNECTABLE,
+ btp_gap_set_connectable, NULL, NULL);
+
btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_DISCOVERABLE,
btp_gap_set_discoverable, NULL, NULL);

@@ -967,19 +1018,6 @@ static void proxy_removed(struct l_dbus_proxy *proxy, void *user_data)
}
}

-static void update_current_settings(struct btp_adapter *adapter,
- uint32_t new_settings)
-{
- struct btp_new_settings_ev ev;
-
- adapter->current_settings = new_settings;
-
- ev.current_settings = L_CPU_TO_LE32(adapter->current_settings);
-
- btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_NEW_SETTINGS, adapter->index,
- sizeof(ev), &ev);
-}
-
static void property_changed(struct l_dbus_proxy *proxy, const char *name,
struct l_dbus_message *msg, void *user_data)
{
--
2.13.6


2017-12-21 16:47:19

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ 5/6] tools/btpclient: Add start, stop discovery commands

This patch adds start and stop discovery command for btp client.
---
tools/btpclient.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 220 insertions(+)

diff --git a/tools/btpclient.c b/tools/btpclient.c
index c0ad03b68..f4b930a51 100644
--- a/tools/btpclient.c
+++ b/tools/btpclient.c
@@ -122,6 +122,8 @@ static void btp_gap_read_commands(uint8_t index, const void *param,
commands |= (1 << BTP_OP_GAP_SET_POWERED);
commands |= (1 << BTP_OP_GAP_SET_DISCOVERABLE);
commands |= (1 << BTP_OP_GAP_SET_BONDABLE);
+ commands |= (1 << BTP_OP_GAP_START_DISCOVERY);
+ commands |= (1 << BTP_OP_GAP_STOP_DISCOVERY);

commands = L_CPU_TO_LE16(commands);

@@ -399,6 +401,218 @@ failed:
btp_send_error(btp, BTP_GAP_SERVICE, index, status);
}

+static void start_discovery_reply(struct l_dbus_proxy *proxy,
+ struct l_dbus_message *result,
+ void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
+
+ if (!adapter) {
+ btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ if (l_dbus_message_is_error(result)) {
+ const char *name, *desc;
+
+ l_dbus_message_get_error(result, &name, &desc);
+ l_error("Failed to start discovery (%s), %s", name, desc);
+
+ btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
+ adapter->index, 0, NULL);
+}
+
+static void set_start_discovery_filter_setup(struct l_dbus_message *message,
+ void *user_data)
+{
+ uint8_t flags = L_PTR_TO_UINT(user_data);
+ struct l_dbus_message_builder *builder;
+
+ builder = l_dbus_message_builder_new(message);
+
+ l_dbus_message_builder_enter_array(builder, "{sv}");
+ l_dbus_message_builder_enter_dict(builder, "sv");
+
+ /* Be in observer mode or in general mode (default in Bluez) */
+ if (flags & BTP_GAP_DISCOVERY_FLAG_OBSERVATION) {
+ l_dbus_message_builder_append_basic(builder, 's', "Transport");
+ l_dbus_message_builder_enter_variant(builder, "s");
+
+ if (flags & (BTP_GAP_DISCOVERY_FLAG_LE |
+ BTP_GAP_DISCOVERY_FLAG_BREDR))
+ l_dbus_message_builder_append_basic(builder, 's',
+ "auto");
+ else if (flags & BTP_GAP_DISCOVERY_FLAG_LE)
+ l_dbus_message_builder_append_basic(builder, 's', "le");
+ else if (flags & BTP_GAP_DISCOVERY_FLAG_BREDR)
+ l_dbus_message_builder_append_basic(builder, 's',
+ "bredr");
+
+ l_dbus_message_builder_leave_variant(builder);
+ }
+
+ l_dbus_message_builder_leave_dict(builder);
+ l_dbus_message_builder_leave_array(builder);
+
+ /* TODO add passive, limited discovery */
+ l_dbus_message_builder_finalize(builder);
+ l_dbus_message_builder_destroy(builder);
+}
+
+static void set_start_discovery_filter_reply(struct l_dbus_proxy *proxy,
+ struct l_dbus_message *result,
+ void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
+
+ if (!adapter) {
+ btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ if (l_dbus_message_is_error(result)) {
+ const char *name, *desc;
+
+ l_dbus_message_get_error(result, &name, &desc);
+ l_error("Failed to set discovery filter (%s), %s", name, desc);
+
+ btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ l_dbus_proxy_method_call(adapter->proxy, "StartDiscovery", NULL,
+ start_discovery_reply, NULL, NULL);
+}
+
+static void btp_gap_start_discovery(uint8_t index, const void *param,
+ uint16_t length, void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_index(index);
+ const struct btp_gap_start_discovery_cp *cp = param;
+ bool prop;
+
+ if (!adapter) {
+ btp_send_error(btp, BTP_GAP_SERVICE, index,
+ BTP_ERROR_INVALID_INDEX);
+ return;
+ }
+
+ /* Adapter needs to be powered to start discovery */
+ if (!l_dbus_proxy_get_property(adapter->proxy, "Powered", "b", &prop) ||
+ !prop) {
+ btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL);
+ return;
+ }
+
+ l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
+ set_start_discovery_filter_setup,
+ set_start_discovery_filter_reply,
+ L_UINT_TO_PTR(cp->flags), NULL);
+}
+
+static void set_stop_discovery_filter_setup(struct l_dbus_message *message,
+ void *user_data)
+{
+ struct l_dbus_message_builder *builder;
+
+ builder = l_dbus_message_builder_new(message);
+
+ /* Clear discovery filter setup */
+ l_dbus_message_builder_enter_array(builder, "{sv}");
+ l_dbus_message_builder_enter_dict(builder, "sv");
+ l_dbus_message_builder_leave_dict(builder);
+ l_dbus_message_builder_leave_array(builder);
+ l_dbus_message_builder_finalize(builder);
+ l_dbus_message_builder_destroy(builder);
+}
+
+static void set_stop_discovery_filter_reply(struct l_dbus_proxy *proxy,
+ struct l_dbus_message *result,
+ void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
+
+ if (!adapter) {
+ btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ if (l_dbus_message_is_error(result)) {
+ const char *name, *desc;
+
+ l_dbus_message_get_error(result, &name, &desc);
+ l_error("Failed to set discovery filter (%s), %s", name, desc);
+
+ btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
+ adapter->index, 0, NULL);
+}
+
+static void stop_discovery_reply(struct l_dbus_proxy *proxy,
+ struct l_dbus_message *result,
+ void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_proxy(proxy);
+
+ if (!adapter) {
+ btp_send_error(btp, BTP_GAP_SERVICE, BTP_INDEX_NON_CONTROLLER,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ if (l_dbus_message_is_error(result)) {
+ const char *name;
+
+ l_dbus_message_get_error(result, &name, NULL);
+ l_error("Failed to stop discovery (%s)", name);
+
+ btp_send_error(btp, BTP_GAP_SERVICE, adapter->index,
+ BTP_ERROR_FAIL);
+ return;
+ }
+
+ l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
+ set_stop_discovery_filter_setup,
+ set_stop_discovery_filter_reply,
+ NULL, NULL);
+}
+
+static void btp_gap_stop_discovery(uint8_t index, const void *param,
+ uint16_t length, void *user_data)
+{
+ struct btp_adapter *adapter = find_adapter_by_index(index);
+ bool prop;
+
+ if (!adapter) {
+ btp_send_error(btp, BTP_GAP_SERVICE, index,
+ BTP_ERROR_INVALID_INDEX);
+ return;
+ }
+
+ /* Adapter needs to be powered to be able to remove devices */
+ if (!l_dbus_proxy_get_property(adapter->proxy, "Powered", "b", &prop) ||
+ !prop) {
+ btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL);
+ return;
+ }
+
+ l_dbus_proxy_method_call(adapter->proxy, "StopDiscovery", NULL,
+ stop_discovery_reply, NULL, NULL);
+}
+
static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy)
{
struct btp_device_found_ev ev;
@@ -453,6 +667,12 @@ static void register_gap_service(void)

btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_SET_BONDABLE,
btp_gap_set_bondable, NULL, NULL);
+
+ btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
+ btp_gap_start_discovery, NULL, NULL);
+
+ btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
+ btp_gap_stop_discovery, NULL, NULL);
}

static void btp_core_read_commands(uint8_t index, const void *param,
--
2.13.6


2017-12-21 16:47:18

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ 4/6] tools/btpclient: Add device found event

This patch adds device found event handler. It's called when rssi
property of device changes and new device interface is added.
---
tools/btpclient.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)

diff --git a/tools/btpclient.c b/tools/btpclient.c
index 095c5ea3e..c0ad03b68 100644
--- a/tools/btpclient.c
+++ b/tools/btpclient.c
@@ -399,6 +399,37 @@ failed:
btp_send_error(btp, BTP_GAP_SERVICE, index, status);
}

+static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy)
+{
+ struct btp_device_found_ev ev;
+ const char *str;
+
+ if (!l_dbus_proxy_get_property(proxy, "Address", "s", &str) ||
+ (str2addr(str, ev.address) != 6))
+ return;
+
+ if (!l_dbus_proxy_get_property(proxy, "AddressType", "s", &str))
+ return;
+
+ ev.address_type = strcmp(str, "public") ? BTP_GAP_ADDR_RANDOM :
+ BTP_GAP_ADDR_PUBLIC;
+
+ if (!l_dbus_proxy_get_property(proxy, "RSSI", "n", &ev.rssi))
+ return;
+
+ /* TODO Temporary set all flags */
+ ev.flags = (BTP_EV_GAP_DEVICE_FOUND_FLAG_RSSI |
+ BTP_EV_GAP_DEVICE_FOUND_FLAG_AD |
+ BTP_EV_GAP_DEVICE_FOUND_FLAG_SR);
+
+ /* TODO Add eir to device found event */
+ ev.eir_len = 0;
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND,
+ BTP_INDEX_NON_CONTROLLER,
+ sizeof(ev) + ev.eir_len, &ev);
+}
+
static void register_gap_service(void)
{
btp_register(btp, BTP_GAP_SERVICE, BTP_OP_GAP_READ_SUPPORTED_COMMANDS,
@@ -661,6 +692,8 @@ static void proxy_added(struct l_dbus_proxy *proxy, void *user_data)

l_queue_push_tail(adapter->devices, device);

+ btp_gap_device_found_ev(proxy);
+
return;
}

@@ -782,6 +815,15 @@ static void property_changed(struct l_dbus_proxy *proxy, const char *name,
update_current_settings(adapter, new_settings);

return;
+ } else if (!strcmp(interface, "org.bluez.Device1")) {
+ if (!strcmp(name, "RSSI")) {
+ uint16_t rssi;
+
+ if (!l_dbus_message_get_arguments(msg, "n", &rssi))
+ return;
+
+ btp_gap_device_found_ev(proxy);
+ }
}
}

--
2.13.6


2017-12-21 16:47:16

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ 2/6] tools/btpclient: Move string to address conversion to helper

This patch makes local helper with string to address conversion.
---
tools/btpclient.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/btpclient.c b/tools/btpclient.c
index 9ea624995..27e5a498e 100644
--- a/tools/btpclient.c
+++ b/tools/btpclient.c
@@ -52,6 +52,12 @@ static struct btp *btp;

static bool gap_service_registered;

+static inline uint8_t str2addr(const char *str, uint8_t *addr)
+{
+ return sscanf(str,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[5], &addr[4],
+ &addr[3], &addr[2], &addr[1], &addr[0]);
+}
+
static struct btp_adapter *find_adapter_by_proxy(struct l_dbus_proxy *proxy)
{
const struct l_queue_entry *entry;
@@ -171,9 +177,7 @@ static void btp_gap_read_info(uint8_t index, const void *param, uint16_t length,
if (!l_dbus_proxy_get_property(adapter->proxy, "Address", "s", &str))
goto failed;

- if (sscanf(str,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
- &rp.address[5], &rp.address[4], &rp.address[3],
- &rp.address[2], &rp.address[1], &rp.address[0]) != 6)
+ if (str2addr(str, rp.address) != 6)
goto failed;

if (!l_dbus_proxy_get_property(adapter->proxy, "Name", "s", &str)) {
--
2.13.6


2017-12-21 16:47:17

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ 3/6] tools/btpclient: Add advertising proxy to adapter

Advertising manager proxy is required to handle advertise related
operations in adapter context.
---
tools/btpclient.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/tools/btpclient.c b/tools/btpclient.c
index 27e5a498e..095c5ea3e 100644
--- a/tools/btpclient.c
+++ b/tools/btpclient.c
@@ -36,6 +36,7 @@

struct btp_adapter {
struct l_dbus_proxy *proxy;
+ struct l_dbus_proxy *ad_proxy;
uint8_t index;
uint32_t supported_settings;
uint32_t current_settings;
@@ -659,6 +660,17 @@ static void proxy_added(struct l_dbus_proxy *proxy, void *user_data)
device->proxy = proxy;

l_queue_push_tail(adapter->devices, device);
+
+ return;
+ }
+
+ if (!strcmp(interface, "org.bluez.LEAdvertisingManager1")) {
+ struct btp_adapter *adapter;
+
+ adapter = find_adapter_by_path(path);
+
+ adapter->ad_proxy = proxy;
+
return;
}
}
--
2.13.6