From: Szymon Janc <szymon.janc@tieto.com>
To: Michael Janssen <jamuraa@chromium.org>
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: [PATCH BlueZ 2/4] core/advertising: Parse IncludeTXPower
Date: Mon, 13 Apr 2015 14:13:41 +0200 [thread overview]
Message-ID: <2942014.61BU9RGTfW@leonov> (raw)
In-Reply-To: <1428692768-31941-3-git-send-email-jamuraa@chromium.org>
Hi Michael,
On Friday 10 of April 2015 12:06:06 Michael Janssen wrote:
> Parse the IncludeTXPower property of the advertisement object, and
> pass the appropriate flag to MGMT if it is set.
>
> Uses MGMT Read Advertising Features Command to determine the maximum
> length allowed.
> ---
> src/advertising.c | 79
> +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74
> insertions(+), 5 deletions(-)
>
> diff --git a/src/advertising.c b/src/advertising.c
> index 2f8e539..8acd5b4 100644
> --- a/src/advertising.c
> +++ b/src/advertising.c
> @@ -46,6 +46,7 @@ struct btd_advertising {
> struct queue *ads;
> struct mgmt *mgmt;
> uint16_t mgmt_index;
> + uint8_t max_adv_len;
> };
>
> #define AD_TYPE_BROADCAST 0
> @@ -59,6 +60,7 @@ struct advertisement {
> GDBusProxy *proxy;
> DBusMessage *reg;
> uint8_t type; /* Advertising type */
> + bool include_tx_power;
> struct bt_ad *data;
> uint8_t instance;
> };
> @@ -361,6 +363,22 @@ fail:
> return false;
> }
>
> +static bool parse_advertising_include_tx_power(GDBusProxy *proxy,
> + bool *included)
> +{
> + DBusMessageIter iter;
> +
> + if (!g_dbus_proxy_get_property(proxy, "IncludeTXPower", &iter))
> + return true;
> +
> + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
> + return false;
> +
> + dbus_message_iter_get_basic(&iter, included);
Due to historical reasons dbus_bool_t is 4 bytes long (check dbus-types.h)
To be on a safe side I'd do:
dbus_bool_t b;
dbus_message_iter_get_basic(&iter, &b);
*included = b;
> +
> + return true;
> +}
> +
> static void add_advertising_callback(uint8_t status, uint16_t length,
> const void *param, void *user_data)
> {
> @@ -375,19 +393,44 @@ static void add_advertising_callback(uint8_t status,
> uint16_t length, ad->instance = rp->instance;
> }
>
> +static size_t calc_max_adv_len(struct advertisement *ad,
> + uint32_t flags)
nitpick: this should fit in single line
> +{
> + size_t max = ad->manager->max_adv_len;
> +
> + if (flags & MGMT_ADV_FLAG_TX_POWER)
> + max -= 3;
At least comment on where those 3/4 bytes came from.
> +
> + if (flags & (MGMT_ADV_FLAG_DISCOV | MGMT_ADV_FLAG_LIMITED_DISCOV |
> + MGMT_ADV_FLAG_MANAGED_FLAGS))
> + max -= 3;
> +
> + if (flags & MGMT_ADV_FLAG_APPEARANCE)
> + max -= 4;
> +
> + return max;
> +}
> +
> static DBusMessage *refresh_advertisement(struct advertisement *ad)
> {
> struct mgmt_cp_add_advertising *cp;
> uint8_t param_len;
> uint8_t *adv_data;
> size_t adv_data_len;
> + uint32_t flags = 0;
>
> DBG("Refreshing advertisement: %s", ad->path);
>
> + if (ad->type == AD_TYPE_PERIPHERAL)
> + flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;
> +
> + if (ad->include_tx_power)
> + flags |= MGMT_ADV_FLAG_TX_POWER;
> +
> adv_data = bt_ad_generate(ad->data, &adv_data_len);
>
> - if (!adv_data) {
> - error("Advertising data couldn't be generated.");
> + if (!adv_data || (adv_data_len > calc_max_adv_len(ad, flags))) {
> + error("Advertising data too long or couldn't be generated.");
>
> return g_dbus_create_error(ad->reg, ERROR_INTERFACE
> ".InvalidLength",
> @@ -406,9 +449,7 @@ static DBusMessage *refresh_advertisement(struct
> advertisement *ad) return btd_error_failed(ad->reg, "Failed");
> }
>
> - if (ad->type == AD_TYPE_PERIPHERAL)
> - cp->flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;
> -
> + cp->flags = flags;
> cp->instance = ad->instance;
> cp->adv_data_len = adv_data_len;
> memcpy(cp->data, adv_data, adv_data_len);
> @@ -457,6 +498,12 @@ static DBusMessage *parse_advertisement(struct
> advertisement *ad) goto fail;
> }
>
> + if (!parse_advertising_include_tx_power(ad->proxy,
> + &ad->include_tx_power)) {
> + error("Property \"IncludeTXPower\" failed to parse");
> + goto fail;
> + }
> +
> return refresh_advertisement(ad);
>
> fail:
> @@ -636,6 +683,20 @@ static void advertising_manager_destroy(void
> *user_data) free(manager);
> }
>
> +static void read_adv_features_callback(uint8_t status, uint16_t length,
> + const void *param, void *user_data)
> +{
> + struct btd_advertising *manager = user_data;
> + const struct mgmt_rp_read_adv_features *feat = param;
> +
> + if (status || !param) {
> + error("Failed to read advertising features");
I'd print status error here as well.
> + return;
> + }
Usually we check if daemon got enough bytes in response before accessing it:
if (length < sizeof(*rp)) {
error("Wrong size of read adv features response");
return;
}
> +
> + manager->max_adv_len = feat->max_adv_data_len;
> +}
> +
> static struct btd_advertising *
> advertising_manager_create(struct btd_adapter *adapter)
> {
> @@ -657,6 +718,14 @@ advertising_manager_create(struct btd_adapter *adapter)
>
> manager->mgmt_index = btd_adapter_get_index(adapter);
>
> + if (!mgmt_send(manager->mgmt, MGMT_OP_READ_ADV_FEATURES,
> + manager->mgmt_index, 0, NULL,
> + read_adv_features_callback, manager, NULL)) {
> + error("Cannot read advertising features, MGMT version too low");
I'm not sure if you get unsupported failure here since that needs to come from
kernel in response. So this error message doesn't seem right.
> + advertising_manager_destroy(manager);
> + return NULL;
> + }
> +
> if (!g_dbus_register_interface(btd_get_dbus_connection(),
> adapter_get_path(adapter),
> LE_ADVERTISING_MGR_IFACE,
--
BR
Szymon Janc
next prev parent reply other threads:[~2015-04-13 12:13 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-10 19:06 [PATCH BlueZ 0/4] Improvements to the LE Advertising API Michael Janssen
2015-04-10 19:06 ` [PATCH BlueZ 1/4] doc: Add IncludeTXPower to " Michael Janssen
2015-04-10 19:06 ` [PATCH BlueZ 2/4] core/advertising: Parse IncludeTXPower Michael Janssen
2015-04-13 12:13 ` Szymon Janc [this message]
2015-04-10 19:06 ` [PATCH BlueZ 3/4] core/advertising: Support more than one advertisement Michael Janssen
2015-04-10 19:06 ` [PATCH BlueZ 4/4] test: add IncludeTXPower to example-advertisement Michael Janssen
2015-04-13 13:38 ` [PATCH BlueZ 0/4] Improvements to the LE Advertising API Luiz Augusto von Dentz
2015-04-13 17:22 ` Michael Janssen
2015-04-13 18:16 ` Marcel Holtmann
2015-04-13 18:27 ` Michael Janssen
2015-04-14 18:18 ` Arman Uguray
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2942014.61BU9RGTfW@leonov \
--to=szymon.janc@tieto.com \
--cc=jamuraa@chromium.org \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox