From patchwork Wed Sep 16 23:25:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781133 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA6D6746 for ; Wed, 16 Sep 2020 23:25:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BED6D22208 for ; Wed, 16 Sep 2020 23:25:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="uwbghoe4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726718AbgIPXZ5 (ORCPT ); Wed, 16 Sep 2020 19:25:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726084AbgIPXZy (ORCPT ); Wed, 16 Sep 2020 19:25:54 -0400 Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A2B4C06174A for ; Wed, 16 Sep 2020 16:25:54 -0700 (PDT) Received: by mail-qv1-xf49.google.com with SMTP id a13so201676qvl.6 for ; Wed, 16 Sep 2020 16:25:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=+huwA4s3GAFhv45nHY4OvTaynBIxEfkWAWQB5QE2L54=; b=uwbghoe4ssspaSoLZHEcVPdKVJc3GC7g1/QIREF/6902DhbhPNUn3bqEfJvLn/RzPE Nhc4eT2WcHSlXATu1DbUD6rUWOX1K62UpRXVMQonKqMCIHhrDOwy+AEuXM1Gd/Dr+k6S D0L6SMAUd4eviI6EzdNQxtoTRaeIkLaFBI26vLaGC4cFqYVCbgNJxEWecm3aFHJvm1wp /HI3amMOSurMbOCXBlQGG4XIOAR9k1Ui3UtQd+CZbHYe/9/SujX4+ramnNZbTBottv1w tKGz0kinQ3pQuBmJAFqnLS2Ig7++ar3xbRo3CN/0p1KlCWpPr9UcKZFLcPT7avmtOgze 0OqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=+huwA4s3GAFhv45nHY4OvTaynBIxEfkWAWQB5QE2L54=; b=i1Z6f9Pj2OQbNupj6RgP/yEdsDTCH4xoiBJnHy/ufcn2ecqx0yJx26HC+E9Ez574Rg HzAzGMcKyBtjyLwX6tXdQL9cqF2RZUD+1utgLz1Gkbhx1R30OuD/m6VaM2k8KGOqHj7Y ZDFGLD/y2ssgpKDDzQVP49xoZ2ULgREBLGZLezwWF/XMiHtByyCZw3bt4G+vwcxfNolL TSXXKpDmx1x9dtq+kJtmHLnwUtf2ZcCvvdBFDrPul/x+GgTcA4nf+cGuS8DRf5JCIbM/ 2owf5bz1FWU+winCMjnbZHp4u35M4rQcQeTX1hOD71otCfAxA/foFk2MBoCgM1OFG7VV M+xA== X-Gm-Message-State: AOAM533oJnOUEsFuzKSQ7stJsOMcuiSOlrSebEb4pTP3i0jCmjlVzIrB z6u8jJd7Emfw7YHPSQj9wJ2OMFuhg81YAW2+6sst X-Google-Smtp-Source: ABdhPJwtDxkV5u7l6zrBENrrmQ6NvJBaNyScwtPPsc57GvJrU9AcqdvzPCeZfAKwaDYDSifsU8N6/Ba5GKvOkJKmpvW8 X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a0c:8246:: with SMTP id h64mr9715968qva.54.1600298753081; Wed, 16 Sep 2020 16:25:53 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:33 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.1.I50d9faa25e9da6e71d77c83c7d47a5b135e88799@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 01/10] advertising: Detect if extended advertising mgmt commands are supported From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org We need to know if kernel supports the new MGMT interface. To do so, we call MGMT_OP_READ_COMMANDS when our manager is created and check if the new commands are available. This will then be used to route our requests for new advertisements. The change is tested by manually verifying that the correct MGMT commands are used when the feature is and is not available in kernel. Reviewed-by: Sonny Sasaka --- src/advertising.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/advertising.c b/src/advertising.c index e5f25948d..172a83907 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -57,6 +57,7 @@ struct btd_adv_manager { uint8_t max_ads; uint32_t supported_flags; unsigned int instance_bitmap; + bool extended_add_cmds; }; #define AD_TYPE_BROADCAST 0 @@ -1407,6 +1408,51 @@ static void read_adv_features_callback(uint8_t status, uint16_t length, remove_advertising(manager, 0); } +static void read_commands_complete(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct btd_adv_manager *manager = user_data; + const struct mgmt_rp_read_commands *rp = param; + uint16_t num_commands, num_events; + size_t expected_len; + int i; + + if (status != MGMT_STATUS_SUCCESS) { + error("Failed to read supported commands: %s (0x%02x)", + mgmt_errstr(status), status); + return; + } + + if (length < sizeof(*rp)) { + error("Wrong size of read commands response"); + return; + } + + num_commands = btohs(rp->num_commands); + num_events = btohs(rp->num_events); + + expected_len = sizeof(*rp) + num_commands * sizeof(uint16_t) + + num_events * sizeof(uint16_t); + + if (length < expected_len) { + error("Too small reply for supported commands: (%u != %zu)", + length, expected_len); + return; + } + + for (i = 0; i < num_commands; i++) { + uint16_t op = get_le16(rp->opcodes + i); + + switch (op) { + case MGMT_OP_ADD_EXT_ADV_PARAMS: + manager->extended_add_cmds = true; + break; + default: + break; + } + } +} + static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, struct mgmt *mgmt) { @@ -1426,6 +1472,7 @@ static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, manager->mgmt_index = btd_adapter_get_index(adapter); manager->clients = queue_new(); manager->supported_flags = MGMT_ADV_FLAG_LOCAL_NAME; + manager->extended_add_cmds = false; if (!g_dbus_register_interface(btd_get_dbus_connection(), adapter_get_path(manager->adapter), @@ -1442,6 +1489,13 @@ static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, goto fail; } + /* Determine if kernel supports extended advertising add command. We + * don't care if this request fails, as we will fall back to legacy + * add_advertising by default + */ + mgmt_send(manager->mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, + NULL, read_commands_complete, manager, NULL); + return manager; fail: From patchwork Wed Sep 16 23:25:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781135 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9EA10746 for ; Wed, 16 Sep 2020 23:25:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 833CD22207 for ; Wed, 16 Sep 2020 23:25:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="fZ3CAxTf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726742AbgIPXZ5 (ORCPT ); Wed, 16 Sep 2020 19:25:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726731AbgIPXZ5 (ORCPT ); Wed, 16 Sep 2020 19:25:57 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37F9DC06174A for ; Wed, 16 Sep 2020 16:25:56 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id p13so409894ybe.4 for ; Wed, 16 Sep 2020 16:25:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=zx9Y03QWb8BNYfZ72/GnCJ0C/Svhms4y9N7CxG393LA=; b=fZ3CAxTfX2LjadVjg66T+bvLiW5pSHYoRjb1kbL1D6R4rTaXW8vM++LeGGpAYNWwaZ fFL9fnyDzCVNCQBp3jdE9NQwfe61d1QuQ4SMIIuh8MF5HGvGylgByzhEDbz5ABZCepor 5tZI7bbZlXipSUw/KT77E/ZxJQnciLqu/t0v6ZomN81YfhM5bUEkuGc6NGH+bt/Qp8B2 rL4Mei1UIA5D6JFmW7IFTv8cInLR/waqdze8np/B7OInc6E6gwNuFNRQO8PlAYIoVgiA oR+2LQUCZn7CuJI10FFA8gIW32BmC1ylcLFWzvq3WT7suttFLM8RsNph8LC8KMkgV/W+ 54bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=zx9Y03QWb8BNYfZ72/GnCJ0C/Svhms4y9N7CxG393LA=; b=A+dEL5n0/mmbOHxeuIMhwq489kX0nJKpTUTNS7W4d9mgAdJaT5fcBr2Jf9PU4ajm0g n5bQZ0AzJJt8NtHbB5nwV2WVD/5d5QshjvGlTa9Yg0gaPaYfHmMQVXqb8Hg7wHTvwsY7 MYeaN2GHQpDkQ3sRDPxlJS73JxRNxjz92xht6hsFPSSyVms7KgOf1qKWfP6KprX1NlIg DwRgTvKD0OOUFtOxU71t4FAaBm1C4MdgkhzalpPWSZBkrPNY1rNhGrJzOeuBF1O3eHI1 GONJM0/lq2YmlIuuVLW8sEBpuntn+bQM79lKCUCYfaPl7piSfz3Gox0xcrrEKACCvH59 VXkg== X-Gm-Message-State: AOAM531sz6piR+VYGy2CwmPLhv+AZsLND1WldtQe9ZEtkybmVD2+m4eD i/YWlZvro5GBSsrwbA4PO0vbd2g/8IycG2orAu7b X-Google-Smtp-Source: ABdhPJxhB4qjTqAAoBhxpCKngQTIbV+27jBJl34UL4gHdjhcBqywaNiZNm0vu5WtZD43Uw5bOmY/R5XyM5cRpsbA2FoM X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a25:6c05:: with SMTP id h5mr35164839ybc.433.1600298755450; Wed, 16 Sep 2020 16:25:55 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:34 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.2.Ic4a3667da774f5f34477d5168a68a9280657e2da@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 02/10] advertising: Parse intervals and tx power from adv From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This change adds parsers for the advertising intervals and tx power properties of the LEAdvertisement1 object. It validates that each field adheres to the 5.2 spec, and that min and max intervals are compatible with each other, i.e. that min interval is less than max interval. A note here for maintainers: The tx power that is sent in the hci parameter command is an int8_t, but as far as I can tell, there is no clean way to use a signed 8-bit integer in dbus. The dbus byte type seems incompatible with negative values in high-level languages (python) without awkward usage manipulation on the client side. For this reason, I chose to use an int16_t type for the tx power dbus field, which is then downcasted to the int8_t in bluetoothd, which at least makes the signed-ness of the type crystal clear to the dbus client that uses it. This change is manually verified by ensuring the intervals and tx power parameters are correctly parsed from the LEAdvertisement1 object, and that the parse fails if the parameters are incorrect or not compatible with each other. Reviewed-by: Sonny Sasaka --- src/advertising.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/advertising.c b/src/advertising.c index 172a83907..82ee87313 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -63,6 +63,11 @@ struct btd_adv_manager { #define AD_TYPE_BROADCAST 0 #define AD_TYPE_PERIPHERAL 1 +/* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2585 + * defines tx power value indicating no preference + */ +#define ADV_TX_POWER_NO_PREFERENCE 0x7F + struct btd_adv_client { struct btd_adv_manager *manager; char *owner; @@ -83,6 +88,9 @@ struct btd_adv_client { struct bt_ad *data; struct bt_ad *scan; uint8_t instance; + uint32_t min_interval; + uint32_t max_interval; + int8_t tx_power; }; struct dbus_obj_match { @@ -946,6 +954,74 @@ static bool parse_secondary(DBusMessageIter *iter, return false; } +static bool parse_min_interval(DBusMessageIter *iter, + struct btd_adv_client *client) +{ + if (!iter) + return false; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32) + return false; + + dbus_message_iter_get_basic(iter, &client->min_interval); + + /* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2584 + * defines acceptable interval range + */ + if (client->min_interval < 0x20 || client->min_interval > 0xFFFFFF) { + client->min_interval = 0; + return false; + } + + return true; +} + +static bool parse_max_interval(DBusMessageIter *iter, + struct btd_adv_client *client) +{ + if (!iter) + return false; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32) + return false; + + dbus_message_iter_get_basic(iter, &client->max_interval); + + /* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2584 + * defines acceptable interval range + */ + if (client->max_interval < 0x20 || client->max_interval > 0xFFFFFF) { + client->max_interval = 0; + return false; + } + + return true; +} + +static bool parse_tx_power(DBusMessageIter *iter, + struct btd_adv_client *client) +{ + int16_t val; + + if (!iter) + return false; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT16) + return false; + + dbus_message_iter_get_basic(iter, &val); + + /* BLUETOOTH SPECIFICATION Version 5.2 | Vol 4, Part E, page 2585 + * defines acceptable tx power range + */ + if (val < -127 || val > 20) + return false; + + client->tx_power = val; + + return true; +} + static struct adv_parser { const char *name; bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client); @@ -964,6 +1040,9 @@ static struct adv_parser { { "Discoverable", parse_discoverable }, { "DiscoverableTimeout", parse_discoverable_timeout }, { "SecondaryChannel", parse_secondary }, + { "MinInterval", parse_min_interval }, + { "MaxInterval", parse_max_interval }, + { "TxPower", parse_tx_power }, { }, }; @@ -1092,6 +1171,13 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client) goto fail; } + if (client->min_interval > client->max_interval) { + /* Min interval must not be bigger than max interval */ + error("MinInterval must be less than MaxInterval (%lu > %lu)", + client->min_interval, client->max_interval); + goto fail; + } + err = refresh_adv(client, add_adv_callback, &client->add_adv_id); if (!err) return NULL; @@ -1167,6 +1253,9 @@ static struct btd_adv_client *client_create(struct btd_adv_manager *manager, client->manager = manager; client->appearance = UINT16_MAX; + client->tx_power = ADV_TX_POWER_NO_PREFERENCE; + client->min_interval = 0; + client->max_interval = 0; return client; From patchwork Wed Sep 16 23:25:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781139 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 873B3139A for ; Wed, 16 Sep 2020 23:26:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6729222208 for ; Wed, 16 Sep 2020 23:26:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="NlwDYFKh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726802AbgIPX0C (ORCPT ); Wed, 16 Sep 2020 19:26:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726764AbgIPX0B (ORCPT ); Wed, 16 Sep 2020 19:26:01 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8EF0C06174A for ; Wed, 16 Sep 2020 16:26:00 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id a8so23009pjk.5 for ; Wed, 16 Sep 2020 16:26:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=TTQ8hdC1Cc1dBUroL41pt+qfr8CyeoljaFPSpZe/4mU=; b=NlwDYFKhuolBFJNLXWFmGNSpX4DSBAtdQPiYS8dshvz1nLboi9qVSSOU/dD09nhVVH SRmYxF+L7P2DR13+OM+rkx6Cd8UXwKwhiZ++Mp5xfMASZbz+4KIbm2zfmBBKYoOxb9eS MOXwZvv2l5Ixpt/xjqdrc2NEhYxZ5uKwkNXXS3Oxq0ecZdaDAj9og6VCgQoKjylbPRSa B+601J8XqV9pVdgcXpvg0AHBwvkSdJY2TfsCDO5Z+6dOICNuSG3posG8RtIZ53qlO2M5 iUYyj8ojR8ZeYzcRM6VWv+XDhDWV6C38xn+C41F7gK25pWsOz9BokBeLhxIDheZms8sa KcjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=TTQ8hdC1Cc1dBUroL41pt+qfr8CyeoljaFPSpZe/4mU=; b=VUX6S76jRnem7W2I7FyoSPIuECAdYkZIeesBeC7GYAUD4ja8fZRo4HnMvvC8LqxBUb 3mLaWF30GrEjROUxxGxAwyGx0asR4L1Jw9SER5s8xqOHGjvRgdWZfeON+tNFVcRSjfNu b9MJONsVTS9VKdvGXFZ7i0dBUlLjkZDlmnGIZlww+JSYIQV/o8+J1+qXoa6F/wmQSzU0 NB3DfDZLB0faR91Ej3uinMwVyLU0ciLYkTJG16gabRy41iQ4/5MnW4zsFHoIOcOqOYRn 0/zXAUGE44//1nJjZbnMvN5Dw30s9Br41B32fTkphlC6bDpory3ic/iyl/zgn1ZnSq17 3ucA== X-Gm-Message-State: AOAM533MJ9ZlDVsPVqYvXSpzTJAlTvTWH/06p6QntY0zF9bN3AcPalwu W2/sWEQl601bcCEBfA16X+Ov3m5zKLa9BA14IxJG X-Google-Smtp-Source: ABdhPJwfZWuiJoT8d8yXLdUrOupjdZbYfIHLw28sSAsHORF1HFKHe9SdYWF1+OpPQ1nuPBx4kbNXOzVttoteNlV+buuO X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a17:90a:db0f:: with SMTP id g15mr6002943pjv.145.1600298757562; Wed, 16 Sep 2020 16:25:57 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:35 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.3.Ia49df7ccded97ceb4ff1d1b0decc49d03d088a84@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 03/10] advertising: Use new mgmt interface for advertising add From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch allows bluetoothd to use the new extended advertising add mgmt interface if it is available. The new interface will be used by default, as it allows the client to set advertising intervals, and tx power if the controller and kernel support extended advertising. Each new registered advertisement will submit two requests to kernel; the first sets the advertising parameters for the advertising instance, and the second sets the advertising data and scan response for the instance. This change has been tested extensively on Hatch (extended advertising) and Kukui (no extended advertising) chromebooks. Manual tests do the following: - Configure advertisement with custom intervals, tx power with valid and invalid values and combinations - Ensure that with valid parameters, they are propagated and set in hci requests. With invalid parameters, ensure that the registration fails. Automatic tests verify 25 advertising usage scenarios involving single and multi-advertising registration, over-registration, parameter validation, etc. These tests don't test new intervals and tx power, but validate that the new MGMT interface does not regress compatibility in these 25 scenarios. Reviewed-by: Sonny Sasaka --- lib/mgmt.h | 31 +++++++ src/advertising.c | 208 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 224 insertions(+), 15 deletions(-) diff --git a/lib/mgmt.h b/lib/mgmt.h index 46d894ae9..9874be004 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -713,6 +713,37 @@ struct mgmt_rp_remove_adv_monitor { uint16_t monitor_handle; } __packed; +#define MGMT_ADV_PARAM_DURATION (1 << 0) +#define MGMT_ADV_PARAM_TIMEOUT (1 << 1) +#define MGMT_ADV_PARAM_INTERVALS (1 << 2) +#define MGMT_ADV_PARAM_TX_POWER (1 << 3) + +#define MGMT_OP_ADD_EXT_ADV_PARAMS 0x0054 +struct mgmt_cp_add_ext_adv_params { + uint8_t instance; + uint32_t flags; + uint16_t params; + uint16_t duration; + uint16_t timeout; + uint32_t min_interval; + uint32_t max_interval; + int8_t tx_power; +} __packed; +struct mgmt_rp_add_ext_adv_params { + uint8_t instance; +} __packed; + +#define MGMT_OP_ADD_EXT_ADV_DATA 0x0055 +struct mgmt_cp_add_ext_adv_data { + uint8_t instance; + uint8_t adv_data_len; + uint8_t scan_rsp_len; + uint8_t data[0]; +} __packed; +struct mgmt_rp_add_ext_adv_data { + uint8_t instance; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { uint16_t opcode; diff --git a/src/advertising.c b/src/advertising.c index 82ee87313..008ce0073 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -91,6 +91,7 @@ struct btd_adv_client { uint32_t min_interval; uint32_t max_interval; int8_t tx_power; + mgmt_request_func_t refresh_done_func; }; struct dbus_obj_match { @@ -797,19 +798,9 @@ static uint8_t *generate_scan_rsp(struct btd_adv_client *client, return bt_ad_generate(client->scan, len); } -static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func, - unsigned int *mgmt_id) +static int get_adv_flags(struct btd_adv_client *client) { - struct mgmt_cp_add_advertising *cp; - uint8_t param_len; - uint8_t *adv_data; - size_t adv_data_len; - uint8_t *scan_rsp; - size_t scan_rsp_len = -1; uint32_t flags = 0; - unsigned int mgmt_ret; - - DBG("Refreshing advertisement: %s", client->path); if (client->type == AD_TYPE_PERIPHERAL) { flags = MGMT_ADV_FLAG_CONNECTABLE; @@ -821,6 +812,26 @@ static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func, flags |= client->flags; + return flags; +} + +static int refresh_legacy_adv(struct btd_adv_client *client, + mgmt_request_func_t func, + unsigned int *mgmt_id) +{ + struct mgmt_cp_add_advertising *cp; + uint8_t param_len; + uint8_t *adv_data; + size_t adv_data_len; + uint8_t *scan_rsp; + size_t scan_rsp_len = -1; + uint32_t flags = 0; + unsigned int mgmt_ret; + + DBG("Refreshing advertisement: %s", client->path); + + flags = get_adv_flags(client); + adv_data = generate_adv_data(client, &flags, &adv_data_len); if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) { error("Advertising data too long or couldn't be generated."); @@ -873,6 +884,76 @@ static int refresh_adv(struct btd_adv_client *client, mgmt_request_func_t func, return 0; } +static void add_adv_params_callback(uint8_t status, uint16_t length, + const void *param, void *user_data); + +static int refresh_extended_adv(struct btd_adv_client *client, + mgmt_request_func_t func, unsigned int *mgmt_id) +{ + struct mgmt_cp_add_ext_adv_params cp; + uint32_t flags = 0; + uint16_t included_params = 0; + unsigned int mgmt_ret = 0; + + DBG("Refreshing advertisement parameters: %s", client->path); + + flags = get_adv_flags(client); + + memset(&cp, 0, sizeof(cp)); + cp.flags = htobl(flags); + cp.instance = client->instance; + + /* Not all advertising instances will use all possible parameters. The + * included_params bit field tells the kernel which parameters are + * relevant, and sensible defaults will be used for the rest + */ + + if (client->duration) { + cp.duration = client->duration; + included_params |= MGMT_ADV_PARAM_DURATION; + } + + if (client->min_interval && client->max_interval) { + cp.min_interval = client->min_interval; + cp.max_interval = client->max_interval; + included_params |= MGMT_ADV_PARAM_INTERVALS; + } + + if (client->tx_power != ADV_TX_POWER_NO_PREFERENCE) { + cp.tx_power = client->tx_power; + included_params |= MGMT_ADV_PARAM_TX_POWER; + } + + cp.params = included_params; + + mgmt_ret = mgmt_send(client->manager->mgmt, MGMT_OP_ADD_EXT_ADV_PARAMS, + client->manager->mgmt_index, sizeof(cp), &cp, + add_adv_params_callback, client, NULL); + + if (!mgmt_ret) { + error("Failed to request extended advertising parameters"); + return -EINVAL; + } + + /* Store callback, called after we set advertising data */ + client->refresh_done_func = func; + + if (mgmt_id) + *mgmt_id = mgmt_ret; + + + return 0; +} + +static int refresh_advertisement(struct btd_adv_client *client, + mgmt_request_func_t func, unsigned int *mgmt_id) +{ + if (client->manager->extended_add_cmds) + return refresh_extended_adv(client, func, mgmt_id); + + return refresh_legacy_adv(client, func, mgmt_id); +} + static gboolean client_discoverable_timeout(void *user_data) { struct btd_adv_client *client = user_data; @@ -883,7 +964,7 @@ static gboolean client_discoverable_timeout(void *user_data) bt_ad_clear_flags(client->data); - refresh_adv(client, NULL, NULL); + refresh_advertisement(client, NULL, NULL); return FALSE; } @@ -1057,7 +1138,8 @@ static void properties_changed(GDBusProxy *proxy, const char *name, continue; if (parser->func(iter, client)) { - refresh_adv(client, NULL, NULL); + refresh_advertisement(client, NULL, NULL); + break; } } @@ -1120,6 +1202,96 @@ done: add_client_complete(client, status); } +static void add_adv_params_callback(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct btd_adv_client *client = user_data; + const struct mgmt_rp_add_ext_adv_params *rp = param; + struct mgmt_cp_add_ext_adv_data *cp; + uint8_t param_len; + uint8_t *adv_data; + size_t adv_data_len; + uint8_t *scan_rsp; + size_t scan_rsp_len = -1; + uint32_t flags = 0; + unsigned int mgmt_ret; + + if (status) + goto fail; + + if (!param || length < sizeof(*rp)) { + status = MGMT_STATUS_FAILED; + goto fail; + } + + DBG("Refreshing advertisement data: %s", client->path); + + client->instance = rp->instance; + + flags = get_adv_flags(client); + + adv_data = generate_adv_data(client, &flags, &adv_data_len); + if (!adv_data || (adv_data_len > calc_max_adv_len(client, flags))) { + error("Advertising data too long or couldn't be generated."); + status = -EINVAL; + goto fail; + } + + scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len); + if (!scan_rsp && scan_rsp_len) { + error("Scan data couldn't be generated."); + free(adv_data); + status = -EINVAL; + goto fail; + } + + param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len + + scan_rsp_len; + + cp = malloc0(param_len); + if (!cp) { + error("Couldn't allocate for MGMT!"); + free(adv_data); + free(scan_rsp); + status = -EINVAL; + goto fail; + } + + cp->instance = client->instance; + cp->adv_data_len = adv_data_len; + cp->scan_rsp_len = scan_rsp_len; + memcpy(cp->data, adv_data, adv_data_len); + memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len); + + free(adv_data); + free(scan_rsp); + + /* Submit request to update instance data */ + mgmt_ret = mgmt_send(client->manager->mgmt, MGMT_OP_ADD_EXT_ADV_DATA, + client->manager->mgmt_index, param_len, cp, + client->refresh_done_func, client, NULL); + + /* Clear the callback */ + client->refresh_done_func = NULL; + + if (!mgmt_ret) { + error("Failed to add Advertising Data"); + free(cp); + status = -EINVAL; + goto fail; + } + + if (client->add_adv_id) + client->add_adv_id = mgmt_ret; + + free(cp); + return; + +fail: + /* Failure for any reason ends this advertising request */ + add_client_complete(client, status); +} + static DBusMessage *parse_advertisement(struct btd_adv_client *client) { struct adv_parser *parser; @@ -1178,7 +1350,9 @@ static DBusMessage *parse_advertisement(struct btd_adv_client *client) goto fail; } - err = refresh_adv(client, add_adv_callback, &client->add_adv_id); + err = refresh_advertisement(client, add_adv_callback, + &client->add_adv_id); + if (!err) return NULL; @@ -1257,6 +1431,8 @@ static struct btd_adv_client *client_create(struct btd_adv_manager *manager, client->min_interval = 0; client->max_interval = 0; + client->refresh_done_func = NULL; + return client; fail: @@ -1624,7 +1800,9 @@ void btd_adv_manager_destroy(struct btd_adv_manager *manager) static void manager_refresh(void *data, void *user_data) { - refresh_adv(data, user_data, NULL); + struct btd_adv_client *client = data; + + refresh_advertisement(client, user_data, NULL); } void btd_adv_manager_refresh(struct btd_adv_manager *manager) From patchwork Wed Sep 16 23:25:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781137 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 50848112E for ; Wed, 16 Sep 2020 23:26:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3244A22208 for ; Wed, 16 Sep 2020 23:26:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="OlVd74Vn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726788AbgIPX0B (ORCPT ); Wed, 16 Sep 2020 19:26:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726731AbgIPX0A (ORCPT ); Wed, 16 Sep 2020 19:26:00 -0400 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C24AC06174A for ; Wed, 16 Sep 2020 16:26:00 -0700 (PDT) Received: by mail-qk1-x749.google.com with SMTP id r128so99049qkc.9 for ; Wed, 16 Sep 2020 16:26:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=3Gv2h6Y33PNU5maObWHRnY34pFguxERvrCFOTuDaK1I=; b=OlVd74VnuAOjp0KkIozGsSyIwRgXhHSHBQ3Ru+dKUxnl1XvGpZppbQmdpNCn9Zpkyb 57hRTgzG/uws5apQjfgq6H0X5pMlBPSJQjZx2zOU80evDN+P4esfYI1VO3SzojX8Tn5O K4LigxjDz6CGEtj7kztPVUElFrVyggwJ0MTMlUYaoqXLByRyoBtLJfw9bGO3UU04uNBA 7UEXy3e2XND9DsCtg/5DakHbjqHhiKfnUibnD+McM4rGzpXRbltRrcraefZFJ48SaS7N Fd4upvA5tAd20VxKn1duFRhNYCWx/h0/VpnP/Tfajhxjwij+/ElG57RomCll3cjyMv29 Dkqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=3Gv2h6Y33PNU5maObWHRnY34pFguxERvrCFOTuDaK1I=; b=ZnxqfaOJTu0+f92Kn4dzRbubRj90OmUzjZ0tHV9ROsUrBGTOS7y+nJYn8X8ozCwham 9bbBhBeAFNInY7/P1QgJkMC8JV4RHlvgz0c1m4sN6Nb410+4ckgRINVsKHjEIdxh409c QYPnLSmRCQe4a8nhDYXOhfMo8k+o9SBeHBPvgfBtN+Ey7moMrXsgCaB7iGdyAXrNpEEu lumxcD3/1MzT7lZzpDBiNZ7iIQ5Ibe5PxDCWngoZMEbxRG8b4zIljFgFecD1d4jw8pgi ITrMj7AN/Br+60v2u5jCfdKVicxGzxQ5JkVTqxvxFJIUjpQNo79om+9ppfmewuvPHaH/ osmg== X-Gm-Message-State: AOAM532M8ez+cHKEE+G5wgzyIIYd1lqIUwZO6uYSJJsHT5nwVO1linJb 5SzAwfz/Cemxj+EpM/IKYufGroXxrgzaG26HXk+Q X-Google-Smtp-Source: ABdhPJy2cLkZ+qaqTzd2UONEmYJuM5szArdjhG3kchEo9ONpeVZCVd7vR8/hqmrsE9jP1S+nN0/jPmKaN4mTcGc2lGdT X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a0c:8c4c:: with SMTP id o12mr8977581qvb.46.1600298759734; Wed, 16 Sep 2020 16:25:59 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:36 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.4.Ia7689bc6f45cf6b8e13a95cd1da4f96fbfc3ac14@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 04/10] advertising: Catch tx power selected event and handle it From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org The new Tx Power Selected MGMT event will alert bluetoothd that an advertising instance has been assigned a tx power. This is intended to be used to then update the client of their instance's tx power. Towards this goal, this patch does the following: - When adv manager is created, register a handler for tx selected event - On callback, identify the relevant advertising instance, and call for a property set with the new value. If the client exposes this method, it will be called with the new value selected by the controller. To test, I modified the example-advertisement python script to implement the Set dbus method, and verified that it is called after advertisement registration on a device with extended advertising. Reviewed-by: Sonny Sasaka --- lib/mgmt.h | 6 ++++++ src/advertising.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/mgmt.h b/lib/mgmt.h index 9874be004..97f8dd9b4 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -1002,6 +1002,12 @@ struct mgmt_ev_controller_resume { uint8_t wake_reason; } __packed; +#define MGMT_EV_ADV_TX_POWER_SELECTED 0x002f +struct mgmt_ev_adv_tx_power_selected { + uint8_t instance; + int8_t tx_power; +} __packed; + static const char *mgmt_op[] = { "<0x0000>", "Read Version", diff --git a/src/advertising.c b/src/advertising.c index 008ce0073..0269c9224 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -113,6 +113,17 @@ static bool match_client(const void *a, const void *b) return true; } +static bool match_client_by_instance(const void *a, const void *b) +{ + const struct btd_adv_client *client = a; + const uint8_t *instance = b; + + if (client && client->instance == *instance) + return true; + + return false; +} + static void client_free(void *data) { struct btd_adv_client *client = data; @@ -1673,6 +1684,22 @@ static void read_adv_features_callback(uint8_t status, uint16_t length, remove_advertising(manager, 0); } +static void tx_power_selected(uint16_t index, uint16_t length, + const void *param, void *user_data) +{ + const struct mgmt_ev_adv_tx_power_selected *ev = param; + struct btd_adv_client *client; + struct btd_adv_manager *manager = user_data; + dbus_int16_t tx_power = ev->tx_power; + + client = queue_find(manager->clients, match_client_by_instance, + &ev->instance); + + if (client) + g_dbus_proxy_set_property_basic(client->proxy, "TxPower", + DBUS_TYPE_INT16, &tx_power, NULL, NULL, NULL); +} + static void read_commands_complete(uint8_t status, uint16_t length, const void *param, void *user_data) { @@ -1716,6 +1743,11 @@ static void read_commands_complete(uint8_t status, uint16_t length, break; } } + + if (manager->extended_add_cmds) + mgmt_register(manager->mgmt, MGMT_EV_ADV_TX_POWER_SELECTED, + manager->mgmt_index, tx_power_selected, + manager, NULL); } static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, From patchwork Wed Sep 16 23:25:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781141 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B7A35746 for ; Wed, 16 Sep 2020 23:26:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 988FE22208 for ; Wed, 16 Sep 2020 23:26:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="ZrQUzovl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726373AbgIPX0F (ORCPT ); Wed, 16 Sep 2020 19:26:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726764AbgIPX0C (ORCPT ); Wed, 16 Sep 2020 19:26:02 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61FB2C06174A for ; Wed, 16 Sep 2020 16:26:02 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id v3so386271yba.12 for ; Wed, 16 Sep 2020 16:26:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=RDn4qmzaK+DPbn7H086U+3kMev3mJs6C/TacCte6F1o=; b=ZrQUzovlfLclHjijnf3c0MwYzd7EtyV1jNyxR97xAwpM1zKcq5it0WwVwUtVoJWy7z 9ep4Ds97ODBev9BUViAomluXpjLP2Lxgf6DiIQ4BM74rp791inS5F9UiJFjMSWql7zkA C2SIgSFHjHPyYixcdOvjuGbA64IAkclxir89T0hMz/qahu8PDHj/2sereroYi2t8+02q +mA5PSRgktoyQzl6nKISOodxWGyrkYFlNQeBDe1bUC32r9oKlybxC4ryUeHXs6QNUha6 502M0jwfUStjmHCzVwf3yha/xRojV1Dgc37YbcUKy1GqLNpPakHN9UaOEkkWEIG3h/QK ahkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=RDn4qmzaK+DPbn7H086U+3kMev3mJs6C/TacCte6F1o=; b=AJLxK6B1kqxCKsc3Hn+F1sRpN8CW95NQFvMAYqb+8jrK9l0d1ymGO/gGJCVQeSaZEb zV2dTi+bTP7+OZf0iHtGL1KzXRdGLvIWgbPk49toq6PSfJG9qugAZdQ/pcGG9sMiHR26 nhWOwvzIQXBKn3/VTnc5axp8v3w/Obh+hwCYngSNrBgnzBGwNa/Uk38YRNBX7DmJukqQ 6NFtmhy858tZXgSOjtuSjbIUToI9DvaIzpufPDfee11aRx413u+JB2gElFs3Qlnw8U+X 7B7qGmB8UUgK0VsT53eIS/ACK4PfgvgW4S+4nMi9oqmT8N+0a/M6KtlDPfS38H7Py0bq v83A== X-Gm-Message-State: AOAM531G+crXUrsvA5gOT3GtZROli7yNS12FLEg8euj2XMHD2T7YBl64 KucNqXw/OQF1TJ+L+LbPFp93bKi/0pb6KIrhnLBq X-Google-Smtp-Source: ABdhPJxYBlMUSl2gGaVuCpcMYKztsQYUb9Ky1V8qms2lZouU442XpUqu67XjDaxG2BCMJZw/xTlCctN/RbMseeu1P7Va X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a25:3585:: with SMTP id c127mr8325177yba.374.1600298761623; Wed, 16 Sep 2020 16:26:01 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:37 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.5.I187f71748b9bd93f6bf97ec4a195216109c3ea06@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 05/10] advertising: Query LE TX range at manager initialization From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch calls the new MGMT command to get controller capabilities, and parses the min and max LE tx power range when the manager is initialized. This will be used to populate a client-facing dbus entry so that the client will know the advertising capabilities of the controller before registering an advertisement. This patch is tested by manually verifying the data is parsed correctly from the MGMT response. Reviewed-by: Sonny Sasaka --- lib/mgmt.h | 8 +++++++ src/advertising.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/lib/mgmt.h b/lib/mgmt.h index 97f8dd9b4..dbabb513f 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -744,6 +744,14 @@ struct mgmt_rp_add_ext_adv_data { uint8_t instance; } __packed; +#define MGMT_CAP_LE_TX_PWR_MIN 0x0001 +#define MGMT_CAP_LE_TX_PWR_MAX 0x0002 + +#define MGMT_OP_READ_CONTROLLER_CAP 0x0056 +struct mgmt_rp_read_controller_cap { + uint8_t capabilities[0]; /* mgmt_tlv */ +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { uint16_t opcode; diff --git a/src/advertising.c b/src/advertising.c index 0269c9224..02aa11934 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -58,6 +58,8 @@ struct btd_adv_manager { uint32_t supported_flags; unsigned int instance_bitmap; bool extended_add_cmds; + int8_t min_tx_power; + int8_t max_tx_power; }; #define AD_TYPE_BROADCAST 0 @@ -1750,6 +1752,54 @@ static void read_commands_complete(uint8_t status, uint16_t length, manager, NULL); } +static void read_controller_cap_complete(uint8_t status, uint16_t length, + const void *param, void *user_data) +{ + struct btd_adv_manager *manager = user_data; + const uint8_t *ptr = param; + uint16_t offset = 0; + + /* Both capabilities we care about are stored as int8_t. If we later + * want to track other types, this structure will need to change + */ + const struct { + struct mgmt_tlv entry; + int8_t value; + } __packed * cap; + + while (offset < length) { + /* Since TLV entries can have variable length, offset tracks how + * far into the member we are, so that cap is always pointing + * to the beginning of a valid struct + */ + cap = (void *)&ptr[offset]; + switch (cap->entry.type) { + case MGMT_CAP_LE_TX_PWR_MIN: + if (cap->entry.length != + sizeof(manager->min_tx_power)) { + error("TX power had unexpected length %d", + cap->entry.length); + break; + } + memcpy(&manager->min_tx_power, &cap->value, + cap->entry.length); + break; + case MGMT_CAP_LE_TX_PWR_MAX: + if (cap->entry.length != + sizeof(manager->min_tx_power)) { + error("TX power had unexpected length %d", + cap->entry.length); + break; + } + memcpy(&manager->max_tx_power, &cap->value, + cap->entry.length); + break; + } + + offset += sizeof(cap->entry) + cap->entry.length; + } +} + static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, struct mgmt *mgmt) { @@ -1770,6 +1820,8 @@ static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, manager->clients = queue_new(); manager->supported_flags = MGMT_ADV_FLAG_LOCAL_NAME; manager->extended_add_cmds = false; + manager->min_tx_power = ADV_TX_POWER_NO_PREFERENCE; + manager->max_tx_power = ADV_TX_POWER_NO_PREFERENCE; if (!g_dbus_register_interface(btd_get_dbus_connection(), adapter_get_path(manager->adapter), @@ -1793,6 +1845,13 @@ static struct btd_adv_manager *manager_create(struct btd_adapter *adapter, mgmt_send(manager->mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL, read_commands_complete, manager, NULL); + /* Query controller capabilities. This will be used to display valid + * advertising tx power range to the client. + */ + mgmt_send(manager->mgmt, MGMT_OP_READ_CONTROLLER_CAP, + manager->mgmt_index, 0, NULL, + read_controller_cap_complete, manager, NULL); + return manager; fail: From patchwork Wed Sep 16 23:25:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781143 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B85E3112E for ; Wed, 16 Sep 2020 23:26:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9BFEC2220B for ; Wed, 16 Sep 2020 23:26:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="NzopJ8vm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726764AbgIPX0F (ORCPT ); Wed, 16 Sep 2020 19:26:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726839AbgIPX0E (ORCPT ); Wed, 16 Sep 2020 19:26:04 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4724EC06174A for ; Wed, 16 Sep 2020 16:26:04 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id g189so389018ybg.9 for ; Wed, 16 Sep 2020 16:26:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=gLuLjClfnxVK5qrLMV6N0yEMaNbvlz3r2lsErbvwRmM=; b=NzopJ8vmUcd4umxiXHqIoXJOUPhjs8z6IyuvpxHLydN8ltvQqj3a87Mp6j+voWuEZB rmdxdQpPwMaD5wrPpxBiPiE6feJrgDwXN5X8toVCPHaYILmhlcIqE2VnkRIt29WhcLpq tMv+85aEeYzHRuvBhqoa5aUu27WENKif9S3VtYjx5Izj5qNYyQ1SWtZhhb6pwmMN+eeX rfVbM2rff7PH553UnIPI9LBCy4MfoGSPmsq13G7GT17tIYBxFEPP3tPd2ywq9/05z//c WZDkMZC6uJTYI2dwA+MsEkBQJu9PejNW0bPp3G3MMXMRZm3zTIYaNMhPgevxnhZQqirK J5GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=gLuLjClfnxVK5qrLMV6N0yEMaNbvlz3r2lsErbvwRmM=; b=dG3ErB+OVswD77+onlfnslDK28Q0bZai2NDPA0veAdRVoYGaAOlyoMh1Z0R9KwFmXK RC2Qyks7xMG0gh9nC4qIN831SJgVJ9HBZTRQr4ZT2qf/h6BesAq7SECY2IUaa3fXZxAQ EyX+6ZSt65kAgkX4WALYr1K7XCnYzxGbM81BVDlezHnID+nK1kNKERDHOGVOvUFF0YU9 vuufFymr15hacEqQLI9Lrx6+1KRgKBnsEn1A3ysYamT0II8nd4WA0uGuuXIF0RkUUR8J Bn/j2Lvc7N553Pt7Ewame4ZiG/SZBSLd/Kwq9h7hv3xLP0tKQIiRdP0fIqIoeguzLmhN mWvg== X-Gm-Message-State: AOAM533knfxD+QFUNHxvacQ4uX60TPNDbajF0P3mCDKpJhqQldzoVfPE hw/Kw1clAdVfLqFOpw/ZysSOlpfcKuArsE+DB7NR X-Google-Smtp-Source: ABdhPJwmQlIQLlRdgxNjGJru8bJiaFcDYpzwIOP1A9ZgkoFRWh5b6HAuz+FTESFXl/y6aBgVnvIbmLPg1224CDt0WkNm X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a25:ab2b:: with SMTP id u40mr41014451ybi.496.1600298763531; Wed, 16 Sep 2020 16:26:03 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:38 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.6.I4e536cf2c9b6c5571b4b3800dfb8338fce8e4421@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 06/10] advertising: Expose SupportedCapabilities for advertising From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org To help our advertising clients understand the device capabilities, this patch adds a SupportedCapabilities dbus endpoint for the advertising manager. The primary reason behind this is to provide the valid LE tx power range the controller supports (populated if controller supports BT5), so a client can know the valid power range before requesting a tx power for their advertisement. I also thought it would be useful to indicate the max advertising data length and scan response length in this endpoint, since some clients will find it useful to set their advertising data (currently experimental feature) or scan response data (possible future feature) directly. This patch has been tested on Hatch (BT5 support) and Kukui (No BT5 support) chromebooks to verify that the dbus endpoint contains the correct data. Reviewed-by: Sonny Sasaka --- lib/mgmt.h | 4 ++-- src/advertising.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/mgmt.h b/lib/mgmt.h index dbabb513f..5f752ecd5 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -744,8 +744,8 @@ struct mgmt_rp_add_ext_adv_data { uint8_t instance; } __packed; -#define MGMT_CAP_LE_TX_PWR_MIN 0x0001 -#define MGMT_CAP_LE_TX_PWR_MAX 0x0002 +#define MGMT_CAP_LE_TX_PWR_MIN 0x0000 +#define MGMT_CAP_LE_TX_PWR_MAX 0x0001 #define MGMT_OP_READ_CONTROLLER_CAP 0x0056 struct mgmt_rp_read_controller_cap { diff --git a/src/advertising.c b/src/advertising.c index 02aa11934..df7436b1d 100644 --- a/src/advertising.c +++ b/src/advertising.c @@ -1624,12 +1624,46 @@ static gboolean get_supported_secondary(const GDBusPropertyTable *property, return TRUE; } +static gboolean get_supported_cap(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct btd_adv_manager *manager = data; + DBusMessageIter dict; + int16_t min_tx_power = manager->min_tx_power; + int16_t max_tx_power = manager->max_tx_power; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + if (min_tx_power != ADV_TX_POWER_NO_PREFERENCE) + dict_append_entry(&dict, "MinTxPower", DBUS_TYPE_INT16, + &min_tx_power); + + if (max_tx_power != ADV_TX_POWER_NO_PREFERENCE) + dict_append_entry(&dict, "MaxTxPower", DBUS_TYPE_INT16, + &max_tx_power); + + dict_append_entry(&dict, "MaxAdvLen", DBUS_TYPE_BYTE, + &manager->max_adv_len); + dict_append_entry(&dict, "MaxScnRspLen", DBUS_TYPE_BYTE, + &manager->max_scan_rsp_len); + + dbus_message_iter_close_container(iter, &dict); + + return TRUE; +} + static const GDBusPropertyTable properties[] = { { "ActiveInstances", "y", get_active_instances, NULL, NULL }, { "SupportedInstances", "y", get_instances, NULL, NULL }, { "SupportedIncludes", "as", get_supported_includes, NULL, NULL }, { "SupportedSecondaryChannels", "as", get_supported_secondary, NULL, secondary_exits }, + { "SupportedCapabilities", "a{sv}", get_supported_cap, NULL, NULL}, { } }; From patchwork Wed Sep 16 23:25:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781145 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B9537112E for ; Wed, 16 Sep 2020 23:26:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 940CE2220B for ; Wed, 16 Sep 2020 23:26:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="VW18xMOT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726869AbgIPX0I (ORCPT ); Wed, 16 Sep 2020 19:26:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726839AbgIPX0G (ORCPT ); Wed, 16 Sep 2020 19:26:06 -0400 Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EEECC06174A for ; Wed, 16 Sep 2020 16:26:06 -0700 (PDT) Received: by mail-qv1-xf49.google.com with SMTP id k14so181141qvw.20 for ; Wed, 16 Sep 2020 16:26:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=E+m79sGOPfqC1NVoAVBQ73IS8QIMVn3x2pbxmIfIMJk=; b=VW18xMOTg2HToPZhkvfx/Eztw/EyvSeYj/TGQvKYaQeWKdNZ4ggf5GPWpS0K8XGomr jRurrCIiwLQV8sE7q88M+plybJ2YvsWNNN8p9jLwHY9xnSmHhCMGffWYecjDH4F5Ixuf 5LiWuD/YNatkZPOalPRqywjgzNJnX4iXykTYo1GcTjDv99F1F50xWx1nUy+tHuUhriIK TVV+iw77AphPRVhq8D1K1vjxj6Q6JxZhf40ATQOdkPoWiG6kdvR50o1EQqGPaxs5Qbl4 3NpioeE2UhZbEq5MwDyTfmIZvECb6vVOKvkPW/uruZYduZ40zq2Ya+zC1zea9Hu5fV/0 2rSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=E+m79sGOPfqC1NVoAVBQ73IS8QIMVn3x2pbxmIfIMJk=; b=pL2j+3OHfphjSuPIuKHxApFg3rW5aS6EK3GRcAM+nTFx9ZXE0B7fg+s4mR8QA2Eqj4 VkV50opuILAHbkTRXyxwcAJ8EaZeXxPX7H9tIiyA82kn6Qut+2oMFIYfEjAaaaJRUicb +bPm0fhkStG18x68iUYmV4HhVbP5TCLjZP2K4nz2S8NJd5kE4l/dFZBeRAxe8lJ9ogOZ Cc0dcIjTjsTQH6HBuXAKSqfjqZZgnfddE7NIDC6D379afYXArLjvsCqgnnGUJMpkHr/p yRkv3ENgiE6cHJ87r2UOA4uk4H6eIrOMx/eoJ2tqZwxT9ADCYk/moEsLC0NkBzr3q3D/ Bgsg== X-Gm-Message-State: AOAM530iktbXcU5rUbXs0/sYHY6a8yHUfRlwoTbgvFnfIJ7vzPx9JsbS wl0F5amCDW4MS6vOquJaAeMDm3yE/1DqTWBHOJtc X-Google-Smtp-Source: ABdhPJyTltNPH911TT2GP8+ZXBABtzTTh3lKKRDKpPP0t5fn88hR/viqqV3rNxXakZa/jVP0DVmHrEPRAkgwU3kcdUKz X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a0c:f2c1:: with SMTP id c1mr17616086qvm.30.1600298765472; Wed, 16 Sep 2020 16:26:05 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:39 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.7.Ic9eec7749b769aa5bf73a0d8e9a31be83f232f1c@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 07/10] client: Add SupportedCapabilities to bluetoothctl From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch adds the new "SupportedCapabilities" property to the bluetoothctl "show" view. The change is tested by verifying bluetoothctl shows the desired properties. Reviewed-by: Sonny Sasaka --- client/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.c b/client/main.c index 2b0243308..cb8ef54ad 100644 --- a/client/main.c +++ b/client/main.c @@ -954,6 +954,7 @@ static void cmd_show(int argc, char *argv[]) print_property(adapter->ad_proxy, "SupportedInstances"); print_property(adapter->ad_proxy, "SupportedIncludes"); print_property(adapter->ad_proxy, "SupportedSecondaryChannels"); + print_property(adapter->ad_proxy, "SupportedCapabilities"); } if (adapter->adv_monitor_proxy) { From patchwork Wed Sep 16 23:25:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781147 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9D978746 for ; Wed, 16 Sep 2020 23:26:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7E8D622208 for ; Wed, 16 Sep 2020 23:26:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="q/Ervwp0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726900AbgIPX0J (ORCPT ); Wed, 16 Sep 2020 19:26:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726839AbgIPX0I (ORCPT ); Wed, 16 Sep 2020 19:26:08 -0400 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12E5EC06174A for ; Wed, 16 Sep 2020 16:26:08 -0700 (PDT) Received: by mail-qt1-x849.google.com with SMTP id z27so134888qtu.3 for ; Wed, 16 Sep 2020 16:26:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=ga5rzsLM7wD43uaJwfTEAl0x1p4eifUEMxC6y8O/SMU=; b=q/Ervwp0jNtca48zrcoaWpfd4F8xuao5CHjO9/BmRPsXA0+6G7QSNuSjiPmUJtiCYc QzUpDmjk39UegKyJRMMbB2WwKMIm/alV9xerVwHInRR7t6vOJGOu+SLAOve9saZvWg1W j1vr3Nrw9QGLZ2CqX/nhsllo0NayCiLdWexjcWYMUcWHZf9+jwT4uNlneKsdY/5ka+0s 4tc2bBhLcqvBGTiBweL5sJGiUGYgWT0dH8tKc4mH//E07n9hyUI+XGP+RzGEYnlOxgtS BMi0+z4u8z2cjiNbSOk5EWvbxNITUecEd5AjC86kDYs8RxbLeA/1mKzbkyNLty4NPBq3 HIIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ga5rzsLM7wD43uaJwfTEAl0x1p4eifUEMxC6y8O/SMU=; b=JaNLI1eFTcenoj51gjrElXVC4JHs5eAChhRcC7FGnDzHogKrsLVF5U5oDPDEb/zAyV hYHk6W7VBMU1RDxAPelDgGCVyvzzyUNiogncJQ9SYzHDkkE3vfoBPqio3YqWakFTD8cN GOnkxqacNZ3A58XZiASjhh7vcZsWEbCA/3nDWVhafdX1azvBAW61PvMRkT/KjPVyEi0W n0qaCoG9AQQ1h7atLDA2iutILwdHxJr2yppKrz66L4O/oVvNY0QYqlmBL/QVpRMe6bEI no+2Z/QMIutqJjADcI8Xi9ej6G/ObwtH85cshA7C9L9zfty/UBcO/NgMer+3nBzIkfvN 3Tiw== X-Gm-Message-State: AOAM531iCpbXhcWOciawWWzYtpTE69AP7LJ8tCb6DJlH4z5+2AA5gEeT wlcYTaXvYAOp0prvJ4aUCAMB3Taj2vM4qeXn/UJg X-Google-Smtp-Source: ABdhPJwir1zZSyhC49bW+kWtVgrCuYOXxBihYJryBKw87eEoSYasYpHnLN0NgKSf9+jN3jcv/5zS0rLBTErc4cPpHUax X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a0c:f30f:: with SMTP id j15mr9497774qvl.51.1600298767278; Wed, 16 Sep 2020 16:26:07 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:40 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.8.I2884e6456c272dadb3d70a629674027f23b0393e@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 08/10] monitor: Add new MGMT adv commands and events to monitor From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This change adds the following to packet monitor: -Add Ext Adv Params command and response -Add Ext Adv Data command and response -Add Advertising Power Selected event This patch was manually tested by registering advertisements with various features and verifying in btmon log. Reviewed-by: Sonny Sasaka --- monitor/packet.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/monitor/packet.c b/monitor/packet.c index bef134095..5d1e6868e 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -11872,6 +11872,26 @@ static void mgmt_print_adv_flags(uint32_t flags) " (0x%8.8x)", mask); } +static const struct bitfield_data mgmt_adv_params_table[] = { + { 0, "Use Duration parameter" }, + { 1, "Use Timeout parameter" }, + { 2, "Use Interval parameters" }, + { 3, "Use TX Power parameter" }, + { } +}; + +static void mgmt_print_adv_params(uint16_t flags) +{ + uint32_t mask; + + print_field("Enabled parameters: 0x%4.4x", flags); + + mask = print_bitfield(2, flags, mgmt_adv_params_table); + if (mask) + print_text(COLOR_UNKNOWN_ADV_FLAG, " Unknown advertising param" + " (0x%8.8x)", mask); +} + static void mgmt_print_store_hint(uint8_t hint) { const char *str; @@ -13163,6 +13183,53 @@ static void mgmt_set_device_flags_rsp(const void *data, uint16_t size) mgmt_print_address(data, type); } +static void mgmt_add_ext_adv_params_cmd(const void *data, uint16_t size) +{ + uint8_t instance = get_u8(data); + uint32_t flags = get_le32(data + 1); + uint16_t params = get_le16(data + 5); + uint16_t duration = get_le16(data + 7); + uint16_t timeout = get_le16(data + 9); + uint32_t min_interval = get_le32(data + 11); + uint32_t max_interval = get_le32(data + 15); + int8_t tx_power = get_s8(data + 19); + + print_field("Instance: %u", instance); + mgmt_print_adv_flags(flags); + mgmt_print_adv_params(params); + print_field("Duration: %u", duration); + print_field("Timeout: %u", timeout); + print_ext_slot_625("Min advertising interval", &min_interval); + print_ext_slot_625("Max advertising interval", &max_interval); + print_power_level(tx_power, NULL); +} + +static void mgmt_add_ext_adv_params_rsp(const void *data, uint16_t size) +{ + uint8_t instance = get_u8(data); + + print_field("Instance: %u", instance); +} + +static void mgmt_add_ext_adv_data_cmd(const void *data, uint16_t size) +{ + uint8_t instance = get_u8(data); + uint8_t adv_data_len = get_u8(data + 1); + uint8_t scan_rsp_len = get_u8(data + 2); + + print_field("Instance: %u", instance); + print_field("Advertising data length: %u", adv_data_len); + print_eir(data + 3, adv_data_len, false); + print_field("Scan response length: %u", scan_rsp_len); + print_eir(data + 3 + adv_data_len, scan_rsp_len, false); +} + +static void mgmt_add_ext_adv_data_rsp(const void *data, uint16_t size) +{ + uint8_t instance = get_u8(data); + + print_field("Instance: %u", instance); +} struct mgmt_data { uint16_t opcode; @@ -13395,6 +13462,12 @@ static const struct mgmt_data mgmt_command_table[] = { { 0x0050, "Set Device Flags", mgmt_set_device_flags_cmd, 11, true, mgmt_set_device_flags_rsp, 7, true}, + { 0x0054, "Add Ext Adv Params", + mgmt_add_ext_adv_params_cmd, 20, false, + mgmt_add_ext_adv_params_rsp, 1, true }, + { 0x0055, "Add Ext Adv Data", + mgmt_add_ext_adv_data_cmd, 3, false, + mgmt_add_ext_adv_data_rsp, 1, true }, { } }; @@ -13847,6 +13920,15 @@ static void mgmt_controller_resume_evt(const void *data, uint16_t size) mgmt_print_address(data, addr_type); } +static void mgmt_adv_power_selected_evt(const void *data, uint16_t size) +{ + uint8_t instance = get_u8(data); + int8_t tx_power = get_s8(data + 1); + + print_field("Instance: %u", instance); + print_power_level(tx_power, NULL); +} + static const struct mgmt_data mgmt_event_table[] = { { 0x0001, "Command Complete", mgmt_command_complete_evt, 3, false }, @@ -13932,6 +14014,8 @@ static const struct mgmt_data mgmt_event_table[] = { mgmt_controller_suspend_evt, 1, true }, { 0x002e, "Controller Resumed", mgmt_controller_resume_evt, 8, true }, + { 0x002f, "Advertising Power Selected", + mgmt_adv_power_selected_evt, 2, true }, { } }; From patchwork Wed Sep 16 23:25:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781149 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 587DA746 for ; Wed, 16 Sep 2020 23:26:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 37BC922208 for ; Wed, 16 Sep 2020 23:26:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="pN44wtdd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726912AbgIPX0L (ORCPT ); Wed, 16 Sep 2020 19:26:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60222 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726839AbgIPX0K (ORCPT ); Wed, 16 Sep 2020 19:26:10 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13C7CC06174A for ; Wed, 16 Sep 2020 16:26:10 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id y6so389473ybi.11 for ; Wed, 16 Sep 2020 16:26:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=UdDPzO9OECkeo70fdtQdo6JOo5V7BHm0lOgDeLw00GE=; b=pN44wtddLVSWcWAfpjNRZ/C2EljFnOW8pU69igLU/NLa9aym0SV+Rem6pzEKPje3OJ xpdwI7soeGun/PR4AhLKidwOG2zqZZqwfPxAxbsv4xv86yQ2ahmv/Be9XwXwogaBkFf+ D3CyBPvvtYodl+wCVTbemhsMqqhOZJSYtbAf5RnAkCPi4rGHFyMvefSy5ZGhVkOgHj1A C/yGQ04AduvUdXPFEexAinn0wZX6XfK8SD3Es6x7X7DmJwsL2kSIfyN0GflWBkBzdN7I X5to0ES4z2N/NIQoJtNxT80OQ7K8cPc4kMDJISnXtQmj5ydXFbS54WMO/X+7TqgFhFV+ Es2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=UdDPzO9OECkeo70fdtQdo6JOo5V7BHm0lOgDeLw00GE=; b=GQlN2pDRiBrzSCZDcuRjGS+r0OGyqOK90MQajJVPRDBfjTjdo6mWyauvxWqmMNb+R0 XuwvITPpYudRNPraOgicOwBYavgnn3qLRYvEIVKifSdADFPIdcf6exm5VIleVcCTaoQn MLIwCmzTcV2inf8RDpo8rEm19IGhHObk10uOYlb77IoRvRvnSdEvfK/xUPEgnlzbkH9z uz7i1t3eQkkTYQpSpYIF15wtSaDNAa5PrdBcRdbgTyHms9KJU6eI/MNiOeabr3M+kN8T aYBD5JElCJ2os7FbCIHXrXtYa9/+8GKyOkq//W8YA5p2AiuT/ORvj4WyQbl5W2F3i6fu QyUA== X-Gm-Message-State: AOAM530TMItIwYQZtG7XdkwzRlmVSWcWPIf8SWh0mZ0xiRqyesXXUUuM tbJ0i47RYJTEBmwE+3xoUZo8f2xNdOd9MCXvqQSz X-Google-Smtp-Source: ABdhPJwVp1Y4v4huZ5Sz8BrFVkxmSlUInExt6o5RL0MqZ/4kJRxO+Azk05BT459om59z5PThbW7tjyEnvU77BuMW1lcq X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a25:a305:: with SMTP id d5mr11744783ybi.180.1600298769343; Wed, 16 Sep 2020 16:26:09 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:41 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.9.Ifaa96e71a871158e5d9d454073b2b6846eae339f@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 09/10] doc/advertising-api: update API with new interface From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This updates the advertising documentation to include the following features: LE Advertising Manager: - New SupportedCapabilities property LE Advertisement: - New min/max interval properties - New tx power property Reviewed-by: Sonny Sasaka --- doc/advertising-api.txt | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/doc/advertising-api.txt b/doc/advertising-api.txt index b0565eab2..3215a52f7 100644 --- a/doc/advertising-api.txt +++ b/doc/advertising-api.txt @@ -138,6 +138,33 @@ Properties string Type "2M" "Coded" + uint32 MinInterval + + Minimum advertising interval to be used by the + advertising set, in .625 millisecond slots. + Time = N * .625 ms, where N has range + [0x000020, 0xFFFFFF]. If the provided MinInterval is + larger than the provided MaxInterval, the registration + will return failure. + + uint32 MaxInterval + + Maximum advertising interval to be used by the + advertising set, in .625 millisecond slots. + Time = N * .625 ms, where N has range + [0x000020, 0xFFFFFF]. If the provided MinInterval is + larger than the provided MaxInterval, the registration + will return failure. + + int16 TxPower + + Requested transmission power of this advertising set. + The provided value is used only if the "CanSetTxPower" + feature is enabled on the Advertising Manager. The + provided value must be in range [-127 to +20], where + units are in dBm. + + LE Advertising Manager hierarchy ================================ @@ -209,3 +236,26 @@ Properties byte ActiveInstances Possible values: "1M" "2M" "Coded" + + dict SupportedCapabilities + + Enumerates Advertising-related controller capabilities + useful to the client. + + Possible Values: + + byte MaxAdvLen + + Max advertising data length + + byte MaxScnRspLen + + Max advertising scan response length + + int16 MinTxPower + + Min advertising tx power (dBm) + + int16 MaxTxPower + + Max advertising tx power (dBm) From patchwork Wed Sep 16 23:25:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Winkler X-Patchwork-Id: 11781151 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8C0EE112E for ; Wed, 16 Sep 2020 23:26:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5AC2622208 for ; Wed, 16 Sep 2020 23:26:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="INgXm6qm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726939AbgIPX0N (ORCPT ); Wed, 16 Sep 2020 19:26:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726839AbgIPX0M (ORCPT ); Wed, 16 Sep 2020 19:26:12 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AB20C06174A for ; Wed, 16 Sep 2020 16:26:12 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id q2so407089ybo.5 for ; Wed, 16 Sep 2020 16:26:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=69uV63sz9ZbKOkQ0qL0A6yR+4VihlUhYQyT6cjQqu5s=; b=INgXm6qmENLTljZ/eb/4QMJH3j5sljg/m2+ENI0fseJ+aOcC1NYbq7LnYyKTz3X/VQ hAH1eKlHmNu4A95rVVAKY/6ZiQnnmp6MyaQmop6veAxPUq4Atgsp1vXCYiLl5K9sKtMI IzHeE/vZt3Ea42wLT9EWowbCdu3TCEXyz75zmbzWgHxK8Jm5BO1t22A5ShPhWy9Wk7cp tt0aE0MuIBvRGS3S7ACUB4KEdaX+9qzZRxn/GSKqs8hj6HPhI4BwunRyTHtkwr5fc84s sq7klySqkIorlnxQ+IRCZLnpf0PuwxR3eeCA70ZEZ+GU46seX9D3KXF+YeFHu0TKzBQy AZWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=69uV63sz9ZbKOkQ0qL0A6yR+4VihlUhYQyT6cjQqu5s=; b=Q1B5xibDRG1tG33NcAM8LJlZz71zzBiZYZPo506j4idTDhbpwgYpmf8tLxcM3TO+OJ Ros5ym2FlS2erqyOvMYi7n8+Q5qdZFe6bukpE8Cke6ZdpO4Oi1fuGPqSmkUsQZCsnAbm SvJl3AigoEQk9UkED4id4harjxdC6YZt1nrTj9kKtKRiZL/u/Xu4zCZ78DeNuOAMNRww BPzbA/zxgM1ll4f/ulpOJ0nDkBpwzfgPAqkVv2Rr0E0n0YdHDy7JFKEmdkCrw0wrOo0s xpM7JnDLfVNa0oXIDq4kJOOb/DRC9ELO2KbQWKqD+e8UBHOp86gltUHaXkI3Pk8we2+N HorA== X-Gm-Message-State: AOAM530HbCaGmPMpB73Hc+EYKkPmxPw7oSTXMxAQ/0tUvi8PEs9j753A CgcDhzxn+mUNe3ITf3OIPKWCzBErL5dqjEj7Lu0p X-Google-Smtp-Source: ABdhPJz9oYOKtc754+4qBs/EXI5mjKSt7oGa0zLQAFtdOfuIpLWan3aTC1BoNVSDU75iqFFf1zIoDlRFadJgWXwOQDye X-Received: from danielwinkler-linux.mtv.corp.google.com ([2620:15c:202:201:f693:9fff:fef4:4e59]) (user=danielwinkler job=sendgmr) by 2002:a05:6902:6d4:: with SMTP id m20mr8276299ybt.118.1600298771472; Wed, 16 Sep 2020 16:26:11 -0700 (PDT) Date: Wed, 16 Sep 2020 16:25:42 -0700 In-Reply-To: <20200916232542.1584854-1-danielwinkler@google.com> Message-Id: <20200916162155.Bluez.10.If15d3d09724ded2bcc7240d29f6888f2ad12e723@changeid> Mime-Version: 1.0 References: <20200916232542.1584854-1-danielwinkler@google.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog Subject: [Bluez PATCH 10/10] doc/mgmt-api: Add new MGMT interfaces to mgmt-api From: Daniel Winkler To: luiz.dentz@gmail.com Cc: linux-bluetooth@vger.kernel.org, chromeos-bluetooth-upstreaming@chromium.org, Daniel Winkler , Sonny Sasaka Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch adds the following to mgmt-api: - Add Extended Advertising Parameters Command - Add Extended Advertising Data Command - Read Controller Capabilities Command - Advertisement Tx Power Selected Event Reviewed-by: Sonny Sasaka --- doc/mgmt-api.txt | 243 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt index ca0d38469..6e8914611 100644 --- a/doc/mgmt-api.txt +++ b/doc/mgmt-api.txt @@ -3574,6 +3574,235 @@ Remove Advertisement Monitor Command Busy +Add Extended Advertising Parameters Command +======================= + + Command Code: 0x0054 + Controller Index: + Command Parameters: Instance (1 Octet) + Flags (4 Octets) + Params (2 Octets) + Duration (2 Octets) + Timeout (2 Octets) + MinInterval (4 Octets) + MaxInterval (4 Octets) + TxPower (1 Octet) + Return Parameters: Instance (1 Octet) + + + This command is used to configure the parameters for Bluetooth Low + Energy advertising instance. This command is expected to be followed + by an Add Extended Advertising Data command to complete and enable + the advertising instance. + + Added advertising information with this command will not be visible + immediately if advertising is enabled via the Set Advertising + command. The usage of the Set Advertising command takes precedence + over this command. Instance information is stored and will be + advertised once advertising via Set Advertising has been disabled. + + The Instance identifier is a value between 1 and the number of + supported instances. The value 0 is reserved. + + With the Flags value the type of advertising is controlled and + the following flags are defined: + + 0 Switch into Connectable mode + 1 Advertise as Discoverable + 2 Advertise as Limited Discoverable + 3 Add Flags field to Adv_Data + 4 Add TX Power field to Adv_Data + 5 Add Appearance field to Scan_Rsp + 6 Add Local Name in Scan_Rsp + 7 Secondary Channel with LE 1M + 8 Secondary Channel with LE 2M + 9 Secondary Channel with LE Coded + + When the connectable flag is set, then the controller will use + undirected connectable advertising. The value of the connectable + setting can be overwritten this way. This is useful to switch a + controller into connectable mode only for LE operation. This is + similar to the mode 0x02 from the Set Advertising command. + + When the connectable flag is not set, then the controller will + use advertising based on the connectable setting. When using + non-connectable or scannable advertising, the controller will + be programmed with a non-resolvable random address. When the + system is connectable, then the identity address or resolvable + private address will be used. + + Using the connectable flag is useful for peripheral mode support + where BR/EDR (and/or LE) is controlled by Add Device. This allows + making the peripheral connectable without having to interfere + with the global connectable setting. + + Secondary channel flags can be used to advertise in secondary + channel with the corresponding PHYs. These flag bits are mutually + exclusive and setting multiple will result in Invalid Parameter + error. Choosing either LE 1M or LE 2M will result in using + extended advertising on the primary channel with LE 1M and the + respectively LE 1M or LE 2M on the secondary channel. Choosing + LE Coded will result in using extended advertising on the primary + and secondary channels with LE Coded. Choosing none of these flags + will result in legacy advertising. + + To allow future parameters to be optionally extended in this structure, + the Params member is used to specify which of the structure fields were + purposefully set by the caller. Unspecified parameters will be given + sensible defaults by the kernel before the advertisement is registered. + The Params bit field uses the following bit to parameter relationship: + + 0 The Duration parameter should be used + 1 The Timeout parameter should be used + 2 The Interval parameters should be used + 3 The Tx Power parameter should be used + + The Duration parameter configures the length of an Instance. The + value is in seconds. The default is 2 seconds. + + If only one advertising Instance has been added, then the Duration + value will be ignored. It only applies for the case where multiple + Instances are configured. In that case every Instance will be + available for the Duration time and after that it switches to + the next one. This is a simple round-robin based approach. + + The Timeout parameter configures the life-time of an Instance. In + case the value 0 is used it indicates no expiration time. If a + timeout value is provided, then the advertising Instance will be + automatically removed when the timeout passes. The value for the + timeout is in seconds. Powering down a controller will invalidate + all advertising Instances and it is not possible to add a new + Instance with a timeout when the controller is powered down. + + When a Timeout is provided, then the Duration subtracts from + the actual Timeout value of that Instance. For example an Instance + with Timeout of 5 and Duration of 2 will be scheduled exactly 3 + times, twice with 2 seconds and once with one second. Other + Instances have no influence on the Timeout. + + MinInterval and MaxInterval define the minimum and maximum advertising + intervals, with units as number of .625ms advertising slots. The Max + interval is expected to be greater than or equal to the Min interval, + and both must have values in the range [0x000020, 0xFFFFFF]. If either + condition is not met, the registration will fail. + + The provided Tx Power parameter will only be used if the controller + supports it, which can be determined by the presence of the + CanSetTxPower member of the Read Advertising Features command. + + The acceptable range for requested Tx Power is defined in the spec + (Version 5.2 | Vol 4, Part E, page 2585) to be [-127, +20] dBm, and the + controller will select a power value up to the requested one. The + transmission power selected by the controller is not guaranteed + to match the requested one, but the caller can determine the power + chosen by the controller by listening for the Tx Power Selected MGMT + event that follows this command. If the requested Tx Power is outside + the valid range, the registration will fail. + + Re-adding an already existing instance (i.e. issuing the Add Extended + Advertising Parameters command with an Instance identifier of an + existing instance) will update that instance's configuration. + + An instance being added or changed while another instance is + being advertised will not be visible immediately but only when + the new/changed instance is being scheduled by the round robin + advertising algorithm. + + Changes to an instance that is currently being advertised will + cancel that instance and switch to the next instance. The changes + will be visible the next time the instance is scheduled for + advertising. In case a single instance is active, this means + that changes will be visible right away. + + LE must already be enabled, and the controller must be powered, + otherwise a "rejected" status will be returned. + + This command generates a Command Complete event on success or a + Command Status event on failure. + + Possible errors: Failed + Rejected + Not Supported + Invalid Parameters + Busy + + +Add Extended Advertising Data Command +======================= + + Command Code: 0x0055 + Controller Index: + Command Parameters: Instance (1 Octet) + Advertising Data Length (1 Octet) + Scan Response Length (1 Octet) + Advertising Data (0-255 Octets) + Scan Response (0-255 Octets) + Return Parameters: Instance (1 Octet) + + The Add Extended Advertising Data command is used to update the + advertising data of an existing advertising instance known to the + kernel. It is expected to be called after an Add Extended Advertising + Parameters command, as part of the advertisement registration + process. + + If extended advertising is available, this call will initiate HCI + commands to set the instance's advertising data, set scan response + data, and then enable the instance. If extended advertising is + unavailable, the advertising instance structure maintained in kernel + will have its advertising data and scan response updated, and the + instance will either be scheduled immediately or left in the queue + for later advertisement as part of round-robin advertisement rotation + in software. + + If Scan_Rsp_Len is zero and the flags defined in Add Extended + Advertising Parameters command do not have connectable flag set and + the global connectable setting is off, then non-connectable + advertising is used. If Scan_Rsp_Len is larger than zero and + connectable flag is not set and the global advertising is off, + then scannable advertising is used. This small difference is + supported to provide less air traffic for devices implementing + broadcaster role. + + If the Instance provided does not match a known instance, or if the + provided advertising data or scan response are in an unrecognized + format, an "Invalid Parameters" status will be returned. + + If a "Set LE" or Advertising command is still in progress, a "Busy" + status will be returned. + + If the controller is not powered, a "rejected" status will be returned. + + This command generates a Command Complete event on success or a + Command Status event on failure. + + Possible errors: Failed + Rejected + Invalid Parameters + Busy + + +Read Controller Capabilities Command +==================================== + + Command Code: 0x0056 + Controller Index: + Command Parameters: + Return Parameters: Parameter1 { + Capability_Tag (2 Octet) + Value_Length (1 Octet) + Value (0-255 Octets) + } + Parameter2 { } + ... + + This command is used to read a list of controller capabilities. + + Currently defined Capability_Tag values are: + + 0x0000 Minimum Supported LE Tx Power (dBm) + 0x0001 Maximum Supported LE Tx Power (dBm) + + Command Complete Event ====================== @@ -4577,3 +4806,17 @@ Advertisement Monitor Removed Event The event will only be sent to management sockets other than the one through which the command was sent. + + +Advertisement Tx Power Selected Event +=================================== + + Event Code: 0x002f + Controller Index: + Event Parameters: Instance (1 Octet) + TxPower (1 Octet) + + This event indicates that the controller selected a transmission + power for an advertising instance. The event is emitted on platforms + that support extended advertising after an Add Extended Advertising + Parameters command is submitted. \ No newline at end of file