Linux bluetooth development
 help / color / mirror / Atom feed
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

  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