2020-06-05 05:15:55

by Tedd Ho-Jeong An

[permalink] [raw]
Subject: [PATCH 1/2] btp: Update connect event structure

From: Tedd Ho-Jeong An <[email protected]>

This patch updates the connect event struct to align withe the btp spec.

Opcode 0x82 - Device Connected event
Controller Index: <controller id>
Event parameters: Address_Type (1 octet)
Address (6 octets)
Connection Interval (2 octets)
Connection Latency (2 octets)
Supervision Timeout (2 octets)

This event indicates that a device was connected.
---
src/shared/btp.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/src/shared/btp.h b/src/shared/btp.h
index f0ac3a1ee..cc71a71df 100644
--- a/src/shared/btp.h
+++ b/src/shared/btp.h
@@ -259,6 +259,9 @@ struct btp_device_found_ev {
struct btp_gap_device_connected_ev {
uint8_t address_type;
bdaddr_t address;
+ uint16_t connection_interval;
+ uint16_t connection_latency;
+ uint16_t supervision_timeout;
} __packed;

#define BTP_EV_GAP_DEVICE_DISCONNECTED 0x83
--
2.25.4


2020-06-05 05:15:55

by Tedd Ho-Jeong An

[permalink] [raw]
Subject: [PATCH 2/2] tools/btpclient: Use mgmt api for limited discovery

From: Tedd Ho-Jeong An <[email protected]>

There are a few test cases for limited discovery in GAP qualification
test suite. But the d-bus API doesn't support it and the only way to
start the limited discovery is using the management API.

This patch adds support for limited discovery by using management API.
---
tools/btpclient.c | 193 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 186 insertions(+), 7 deletions(-)

diff --git a/tools/btpclient.c b/tools/btpclient.c
index f9c693056..bc70a196f 100644
--- a/tools/btpclient.c
+++ b/tools/btpclient.c
@@ -36,6 +36,10 @@
#include "lib/bluetooth.h"
#include "src/shared/btp.h"

+/* For BT_MGMT API */
+#include "lib/mgmt.h"
+#include "src/shared/mgmt.h"
+
#define AD_PATH "/org/bluez/advertising"
#define AG_PATH "/org/bluez/agent"
#define AD_IFACE "org.bluez.LEAdvertisement1"
@@ -77,6 +81,14 @@ static struct btp *btp;

static bool gap_service_registered;

+/* For BT_MGMT API */
+static struct mgmt *mgmt = NULL;
+static uint16_t mgmt_index = MGMT_INDEX_NONE;
+
+static uint32_t mgmt_flags;
+
+#define MGMT_OPS_DISCOVERY 0x01
+
struct ad_data {
uint8_t data[25];
uint8_t len;
@@ -1403,6 +1415,88 @@ static void set_discovery_filter_reply(struct l_dbus_proxy *proxy,
start_discovery_reply, NULL, NULL);
}

+#define SCAN_TYPE_BREDR (1 << BDADDR_BREDR)
+#define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))
+#define SCAN_TYPE_DUAL (SCAN_TYPE_BREDR | SCAN_TYPE_LE)
+
+struct discovery_flags {
+ uint8_t flags;
+};
+
+static int btp_mgmt_start_limited_discovery(uint8_t flags)
+{
+ struct mgmt_cp_start_discovery cp;
+ uint8_t type = SCAN_TYPE_DUAL;
+
+ memset(&cp, 0, sizeof(cp));
+
+ if (flags & (BTP_GAP_DISCOVERY_FLAG_LE |
+ BTP_GAP_DISCOVERY_FLAG_BREDR)) {
+ type = SCAN_TYPE_DUAL;
+ } else if (flags & BTP_GAP_DISCOVERY_FLAG_LE) {
+ type &= ~SCAN_TYPE_BREDR;
+ type |= SCAN_TYPE_LE;
+ } else if (flags & BTP_GAP_DISCOVERY_FLAG_BREDR) {
+ type |= SCAN_TYPE_BREDR;
+ type &= ~SCAN_TYPE_LE;
+ }
+ cp.type = type;
+
+ return mgmt_send(mgmt, MGMT_OP_START_LIMITED_DISCOVERY, mgmt_index,
+ sizeof(cp), &cp, NULL, NULL, NULL);
+}
+
+static void btp_mgmt_discovering_destroy(void *user_data)
+{
+ l_free(user_data);
+}
+
+static void btp_mgmt_discovering_cb(uint16_t index, uint16_t len,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_discovering *ev = param;
+ struct discovery_flags *df = user_data;
+
+ if (len < sizeof(*ev)) {
+ l_error("Too short (%u bytes) discovering event", len);
+ return;
+ }
+
+ l_info("MGMT: discovering %s", ev->discovering ? "on" : "off");
+
+ /* Start new discovery */
+ if (ev->discovering == 0 && (mgmt_flags & MGMT_OPS_DISCOVERY))
+ btp_mgmt_start_limited_discovery(df->flags);
+}
+
+static void btp_mgmt_setup_limited_discovery(uint8_t index, uint8_t flags)
+{
+ int ret;
+ struct discovery_flags *df;
+
+ /* Saves the flags so it can be used to start new discovery */
+ df = l_new(struct discovery_flags, 1);
+ df->flags = flags;
+
+ /* Register event for discovering */
+ mgmt_register(mgmt, MGMT_EV_DISCOVERING, mgmt_index,
+ btp_mgmt_discovering_cb, df,
+ btp_mgmt_discovering_destroy);
+
+ ret = btp_mgmt_start_limited_discovery(flags);
+ if (ret == 0) {
+ l_error("Unable to send start_discovery cmd");
+ btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL);
+ return;
+ }
+
+ /* Set flag that mgmt interface is used for scanning */
+ mgmt_flags |= MGMT_OPS_DISCOVERY;
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_START_DISCOVERY,
+ index, 0, NULL);
+}
+
static void btp_gap_start_discovery(uint8_t index, const void *param,
uint16_t length, void *user_data)
{
@@ -1423,10 +1517,17 @@ static void btp_gap_start_discovery(uint8_t index, const void *param,
return;
}

- l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
- set_discovery_filter_setup,
- set_discovery_filter_reply,
- L_UINT_TO_PTR(cp->flags), NULL);
+ /* Use BT MGMT interface to start limited discovery procedure since
+ * it is not supported by D-BUS API
+ */
+ if (cp->flags & BTP_GAP_DISCOVERY_FLAG_LIMITED)
+ btp_mgmt_setup_limited_discovery(index, cp->flags);
+ else {
+ l_dbus_proxy_method_call(adapter->proxy, "SetDiscoveryFilter",
+ set_discovery_filter_setup,
+ set_discovery_filter_reply,
+ L_UINT_TO_PTR(cp->flags), NULL);
+ }
}

static void clear_discovery_filter_setup(struct l_dbus_message *message,
@@ -1501,6 +1602,29 @@ static void stop_discovery_reply(struct l_dbus_proxy *proxy,
NULL, NULL);
}

+static void btp_mgmt_stop_discovery(uint8_t index)
+{
+ struct mgmt_cp_stop_discovery cp;
+ int ret;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.type = SCAN_TYPE_DUAL;
+
+ ret = mgmt_send(mgmt, MGMT_OP_STOP_DISCOVERY, mgmt_index, sizeof(cp),
+ &cp, NULL, NULL, NULL);
+ if (ret == 0) {
+ l_error("Unable to send stop_discovery cmd");
+ btp_send_error(btp, BTP_GAP_SERVICE, index, BTP_ERROR_FAIL);
+ return;
+ }
+
+ /* Clear flag that mgmt interface is used for scanning */
+ mgmt_flags &= ~MGMT_OPS_DISCOVERY;
+
+ btp_send(btp, BTP_GAP_SERVICE, BTP_OP_GAP_STOP_DISCOVERY,
+ index, 0, NULL);
+}
+
static void btp_gap_stop_discovery(uint8_t index, const void *param,
uint16_t length, void *user_data)
{
@@ -1520,8 +1644,14 @@ static void btp_gap_stop_discovery(uint8_t index, const void *param,
return;
}

- l_dbus_proxy_method_call(adapter->proxy, "StopDiscovery", NULL,
- stop_discovery_reply, NULL, NULL);
+ /* If the discovery procedure is started by BT MGMT API for limited
+ * discovering, it should be stopped by mgmt API.
+ */
+ if (mgmt_flags & MGMT_OPS_DISCOVERY)
+ btp_mgmt_stop_discovery(index);
+ else
+ l_dbus_proxy_method_call(adapter->proxy, "StopDiscovery", NULL,
+ stop_discovery_reply, NULL, NULL);
}

static void connect_reply(struct l_dbus_proxy *proxy,
@@ -3140,6 +3270,7 @@ static void usage(void)
l_info("\tbtpclient [options]");
l_info("options:\n"
"\t-s, --socket <socket> Socket to use for BTP\n"
+ "\t-i, --index <id> Specify the adapter index\n"
"\t-q, --quiet Don't emit any logs\n"
"\t-v, --version Show version\n"
"\t-h, --help Show help options");
@@ -3147,12 +3278,52 @@ static void usage(void)

static const struct option options[] = {
{ "socket", 1, 0, 's' },
+ { "index", 1, 0, 'i' },
{ "quiet", 0, 0, 'q' },
{ "version", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
};

+static void set_index(const char *arg)
+{
+ /* Use default index 0 */
+ if (!arg || !strcmp(arg, "none") || !strcmp(arg, "any") ||
+ !strcmp(arg, "all"))
+ mgmt_index = MGMT_INDEX_NONE;
+ else if(strlen(arg) > 3 && !strncasecmp(arg, "hci", 3))
+ mgmt_index = atoi(&arg[3]);
+ else
+ mgmt_index = atoi(arg);
+}
+
+static int btp_mgmt_init(const char *index_opt)
+{
+ mgmt = mgmt_new_default();
+ if (!mgmt) {
+ l_info("Unable to open mgmt_socket\n");
+ return EXIT_FAILURE;
+ }
+
+ if (index_opt)
+ set_index(index_opt);
+
+ if (mgmt_index == MGMT_INDEX_NONE)
+ mgmt_index = 0;
+
+ return EXIT_SUCCESS;
+}
+
+static void btp_mgmt_release()
+{
+ l_error("MGMT: Release all management resources");
+ mgmt_cancel_all(mgmt);
+ mgmt_unregister_all(mgmt);
+ mgmt_unref(mgmt);
+}
+
+static const char *index_opt;
+
int main(int argc, char *argv[])
{
struct l_dbus_client *client;
@@ -3160,7 +3331,7 @@ int main(int argc, char *argv[])

l_log_set_stderr();

- while ((opt = getopt_long(argc, argv, "+hs:vq", options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "+hs:vqi:", options, NULL)) != -1) {
switch (opt) {
case 's':
socket_path = l_strdup(optarg);
@@ -3173,6 +3344,9 @@ int main(int argc, char *argv[])
case 'v':
l_info("%s", VERSION);
return EXIT_SUCCESS;
+ case 'i':
+ index_opt = l_strdup(optarg);
+ break;
case 'h':
default:
usage();
@@ -3189,6 +3363,10 @@ int main(int argc, char *argv[])
if (!l_main_init())
return EXIT_FAILURE;

+ if (btp_mgmt_init(index_opt)) {
+ l_error("Unable to initialize the management interface");
+ return EXIT_FAILURE;
+ }

adapters = l_queue_new();

@@ -3210,6 +3388,7 @@ int main(int argc, char *argv[])
l_dbus_client_destroy(client);
l_dbus_destroy(dbus);
btp_cleanup(btp);
+ btp_mgmt_release();

l_queue_destroy(adapters, (l_queue_destroy_func_t)btp_adapter_free);

--
2.25.4

2020-06-05 05:36:56

by bluez.test.bot

[permalink] [raw]
Subject: RE: [1/2] btp: Update connect event structure


This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While we are preparing for reviewing the patches, we found the following
issue/warning.

Test Result:
checkgitlint Failed

Outputs:
6: B3 Line contains hard tab characters (\t): " Controller Index: <controller id>"
7: B3 Line contains hard tab characters (\t): " Event parameters: Address_Type (1 octet)"
8: B3 Line contains hard tab characters (\t): " Address (6 octets)"
9: B3 Line contains hard tab characters (\t): " Connection Interval (2 octets)"
10: B3 Line contains hard tab characters (\t): " Connection Latency (2 octets)"
11: B3 Line contains hard tab characters (\t): " Supervision Timeout (2 octets)"



---
Regards,
Linux Bluetooth

2020-06-05 05:36:56

by bluez.test.bot

[permalink] [raw]
Subject: RE: [2/2] tools/btpclient: Use mgmt api for limited discovery


This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
While we are preparing for reviewing the patches, we found the following
issue/warning.

Test Result:
checkpatch Failed

Outputs:
ERROR:INITIALISED_STATIC: do not initialise statics to NULL
#32: FILE: tools/btpclient.c:85:
+static struct mgmt *mgmt = NULL;

ERROR:SPACING: space required before the open parenthesis '('
#225: FILE: tools/btpclient.c:3294:
+ else if(strlen(arg) > 3 && !strncasecmp(arg, "hci", 3))

ERROR:FUNCTION_WITHOUT_ARGS: Bad function definition - void btp_mgmt_release() should probably be void btp_mgmt_release(void)
#248: FILE: tools/btpclient.c:3317:
+static void btp_mgmt_release()

WARNING:LONG_LINE: line over 80 characters
#266: FILE: tools/btpclient.c:3334:
+ while ((opt = getopt_long(argc, argv, "+hs:vqi:", options, NULL)) != -1) {

- total: 3 errors, 1 warnings, 271 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

Your patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPLIT_STRING

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.



---
Regards,
Linux Bluetooth