2014-06-25 15:49:57

by Jakub Tyszkowski

[permalink] [raw]
Subject: [RFC 1/5] android/mcap: Change PIXIT value

Handling single data channel will simplify mcaptest tool.
This can be changed later when mcaptest will be improved.
---
android/pixit-mcap.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/pixit-mcap.txt b/android/pixit-mcap.txt
index ee67a1a..81cc6dc 100644
--- a/android/pixit-mcap.txt
+++ b/android/pixit-mcap.txt
@@ -11,7 +11,7 @@ Parameter Name Value
-------------------------------------------------------------------------------
TSPX_bd_addr_iut 112233445566 (*&)
TSPX_delete_link_key FALSE
-TSPX_MCAP_DC_max 2
+TSPX_MCAP_DC_max 1
TSPX_MCAP_l2cap_psm_control 1003
TSPX_MCAP_l2cap_psm_control_B
TSPX_MCAP_l2cap_psm_data 1005
--
2.0.0



2014-06-26 07:04:08

by Jakub Tyszkowski

[permalink] [raw]
Subject: Re: [RFC 2/5] tools/mcaptest: Add skeleton for mcap test tool

Hi Johan,

On 06/25/2014 09:47 PM, Johan Hedberg wrote:
> Hi Jakub,
>
> On Wed, Jun 25, 2014, Jakub Tyszkowski wrote:
>> +tools_mcaptest_SOURCES = tools/mcaptest.c \
>> + src/log.c btio/btio.c \
>> + android/mcap-lib.h android/mcap-lib.c
>
> I don't think we want to have tools/* depending on anything in
> android/*. Ideally the tool should depend on a nice library in
> src/shared (which we don't have) or in the worst case on
> profiles/health or then it should be moved to android/ from tools/.
>
> Johan
>

Sure. I'll move it to android/ then.

Jakub

2014-06-25 19:47:16

by Johan Hedberg

[permalink] [raw]
Subject: Re: [RFC 2/5] tools/mcaptest: Add skeleton for mcap test tool

Hi Jakub,

On Wed, Jun 25, 2014, Jakub Tyszkowski wrote:
> +tools_mcaptest_SOURCES = tools/mcaptest.c \
> + src/log.c btio/btio.c \
> + android/mcap-lib.h android/mcap-lib.c

I don't think we want to have tools/* depending on anything in
android/*. Ideally the tool should depend on a nice library in
src/shared (which we don't have) or in the worst case on
profiles/health or then it should be moved to android/ from tools/.

Johan

2014-06-25 15:49:59

by Jakub Tyszkowski

[permalink] [raw]
Subject: [RFC 3/5] tools/mcaptest: Support connect

This triggers the connection.
---
tools/mcaptest.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 3 deletions(-)

diff --git a/tools/mcaptest.c b/tools/mcaptest.c
index cc2d9cd..2793b9f 100644
--- a/tools/mcaptest.c
+++ b/tools/mcaptest.c
@@ -50,8 +50,10 @@ static GMainLoop *mloop;
static int ccpsm = 0x1003, dcpsm = 0x1005;

static struct mcap_instance *mcap = NULL;
+static struct mcap_mdl *mdl = NULL;
+static uint16_t mdlid;

-int control_mode = MODE_LISTEN;
+static int control_mode = MODE_LISTEN;

static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
{
@@ -67,8 +69,9 @@ static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)

static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
{
- /* TODO */
printf("MCL disconnected\n");
+
+ g_main_loop_quit(mloop);
}

static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
@@ -77,6 +80,50 @@ static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
printf("MCL uncached unsupported\n");
}

+static void connect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data)
+{
+ mdlid = mcap_mdl_get_mdlid(mdl);
+
+ printf("MDL %d connected\n", mdlid);
+}
+
+static void create_mdl_cb(struct mcap_mdl *mcap_mdl, uint8_t type, GError *gerr,
+ gpointer data)
+{
+ GError *err = NULL;
+
+ if (gerr) {
+ printf("MDL error: %s\n", gerr->message);
+
+ exit(1);
+ }
+
+ mdl = mcap_mdl_ref(mcap_mdl);
+
+ if (!mcap_connect_mdl(mdl, L2CAP_MODE_ERTM, dcpsm, connect_mdl_cb, NULL,
+ NULL, &err)) {
+ printf("Error connecting to mdl: %s\n", err->message);
+ g_error_free(err);
+ }
+}
+
+static void create_mcl_cb(struct mcap_mcl *mcl, GError *err, gpointer data)
+{
+ GError *gerr = NULL;
+
+ if (err) {
+ printf("Could not connect MCL: %s\n", err->message);
+
+ exit(1);
+ }
+
+ mcap_create_mdl(mcl, 1, 0, create_mdl_cb, NULL, NULL, &gerr);
+ if (gerr) {
+ printf("Could not connect MDL: %s\n", gerr->message);
+ g_error_free(gerr);
+ }
+}
+
static void usage(void)
{
printf("mcaptest - MCAP testing ver %s\n", VERSION);
@@ -98,12 +145,12 @@ static struct option main_options[] = {
{ "data_ch", 1, 0, 'D' },
{ 0, 0, 0, 0 }
};
-
int main(int argc, char *argv[])
{
GError *err = NULL;
bdaddr_t src, dst;
int opt;
+ char bdastr[18];

hci_devba(0, &src);
bacpy(&dst, BDADDR_ANY);
@@ -165,6 +212,20 @@ int main(int argc, char *argv[])

switch (control_mode) {
case MODE_CONNECT:
+ ba2str(&dst, bdastr);
+ printf("Connecting to %s\n", bdastr);
+
+ mcap_create_mcl(mcap, &dst, ccpsm, create_mcl_cb, NULL, NULL,
+ &err);
+
+ if (err) {
+ printf("MCAP create error %s\n", err->message);
+ g_error_free(err);
+
+ exit(1);
+ }
+
+ break;
case MODE_NONE:
default:
goto done;
--
2.0.0


2014-06-25 15:49:58

by Jakub Tyszkowski

[permalink] [raw]
Subject: [RFC 2/5] tools/mcaptest: Add skeleton for mcap test tool

This adds skeleton for simple tool for testing mcap library. As mcap-lib
uses bt_io, this tool works in daemon-like mode, by utilizing Glib's main
loop.
---
.gitignore | 1 +
Makefile.tools | 7 ++-
tools/mcaptest.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 191 insertions(+), 1 deletion(-)
create mode 100644 tools/mcaptest.c

diff --git a/.gitignore b/.gitignore
index 2e08c21..cc6dc6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,6 +74,7 @@ tools/btinfo
tools/3dsp
tools/obexctl
tools/gatt-service
+tools/mcaptest
test/sap_client.pyc
test/bluezutils.pyc
unit/test-ringbuf
diff --git a/Makefile.tools b/Makefile.tools
index c24bdf7..402c290 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -278,7 +278,7 @@ noinst_PROGRAMS += tools/bdaddr tools/avinfo tools/avtest \
tools/btmgmt tools/btinfo tools/btattach \
tools/btsnoop tools/btproxy tools/btiotest \
tools/mpris-player tools/cltest tools/seq2bseq \
- tools/hex2hcd tools/ibeacon
+ tools/hex2hcd tools/ibeacon tools/mcaptest

tools_bdaddr_SOURCES = tools/bdaddr.c src/oui.h src/oui.c
tools_bdaddr_LDADD = lib/libbluetooth-internal.la @UDEV_LIBS@
@@ -344,6 +344,11 @@ tools_ibeacon_SOURCES = tools/ibeacon.c monitor/bt.h \
src/shared/queue.h src/shared/queue.c \
src/shared/ringbuf.h src/shared/ringbuf.c

+tools_mcaptest_SOURCES = tools/mcaptest.c \
+ src/log.c btio/btio.c \
+ android/mcap-lib.h android/mcap-lib.c
+tools_mcaptest_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
EXTRA_DIST += tools/bdaddr.1
endif

diff --git a/tools/mcaptest.c b/tools/mcaptest.c
new file mode 100644
index 0000000..cc2d9cd
--- /dev/null
+++ b/tools/mcaptest.c
@@ -0,0 +1,184 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Intel Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+#include <glib.h>
+
+#include "btio/btio.h"
+#include "lib/l2cap.h"
+#include "android/mcap-lib.h"
+
+enum {
+ MODE_NONE,
+ MODE_CONNECT,
+ MODE_LISTEN,
+};
+
+static GMainLoop *mloop;
+
+static int ccpsm = 0x1003, dcpsm = 0x1005;
+
+static struct mcap_instance *mcap = NULL;
+
+int control_mode = MODE_LISTEN;
+
+static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
+{
+ /* TODO */
+ printf("MCL connected unsupported\n");
+}
+
+static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
+{
+ /* TODO */
+ printf("MCL reconnected unsupported\n");
+}
+
+static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
+{
+ /* TODO */
+ printf("MCL disconnected\n");
+}
+
+static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
+{
+ /* TODO */
+ printf("MCL uncached unsupported\n");
+}
+
+static void usage(void)
+{
+ printf("mcaptest - MCAP testing ver %s\n", VERSION);
+ printf("Usage:\n"
+ "\tmcaptest <mode> [options]\n");
+ printf("Modes:\n"
+ "\t-c connect <dst_addr> (than wait for disconnect)\n");
+ printf("Options:\n"
+ "\t-i <hcidev> HCI device\n"
+ "\t-C <control_ch> Control channel PSM\n"
+ "\t-D <data_ch> Data channel PSM\n");
+}
+
+static struct option main_options[] = {
+ { "help", 0, 0, 'h' },
+ { "device", 1, 0, 'i' },
+ { "connect", 1, 0, 'c' },
+ { "control_ch", 1, 0, 'C' },
+ { "data_ch", 1, 0, 'D' },
+ { 0, 0, 0, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ GError *err = NULL;
+ bdaddr_t src, dst;
+ int opt;
+
+ hci_devba(0, &src);
+ bacpy(&dst, BDADDR_ANY);
+
+ mloop = g_main_loop_new(NULL, FALSE);
+ if (!mloop) {
+ printf("Cannot create main loop\n");
+
+ exit(1);
+ }
+
+ while ((opt = getopt_long(argc, argv, "+i:c:C:D:h",
+ main_options, NULL)) != EOF) {
+ switch (opt) {
+ case 'i':
+ if (!strncmp(optarg, "hci", 3))
+ hci_devba(atoi(optarg + 3), &src);
+ else
+ str2ba(optarg, &src);
+
+ break;
+
+ case 'c':
+ control_mode = MODE_CONNECT;
+ str2ba(optarg, &dst);
+
+ break;
+
+ case 'C':
+ ccpsm = atoi(optarg);
+
+ break;
+
+ case 'D':
+ dcpsm = atoi(optarg);
+
+ break;
+
+ case 'h':
+ default:
+ usage();
+ exit(0);
+ }
+ }
+
+ mcap = mcap_create_instance(&src, BT_IO_SEC_MEDIUM, 0, 0,
+ mcl_connected, mcl_reconnected,
+ mcl_disconnected, mcl_uncached,
+ NULL, /* CSP is not used right now */
+ NULL, &err);
+
+ if (!mcap) {
+ printf("MCAP instance creation failed %s\n",
+ err->message);
+ g_error_free(err);
+
+ exit(1);
+ }
+
+ switch (control_mode) {
+ case MODE_CONNECT:
+ case MODE_NONE:
+ default:
+ goto done;
+ }
+
+ g_main_loop_run(mloop);
+
+done:
+ printf("Done\n");
+
+ if (mcap)
+ mcap_instance_unref(mcap);
+
+ g_main_loop_unref(mloop);
+
+ return 0;
+}
--
2.0.0


2014-06-25 15:50:01

by Jakub Tyszkowski

[permalink] [raw]
Subject: [RFC 5/5] android/mcap: Update PTS results

---
android/pts-mcap.txt | 46 +++++++++++++++++++++++++---------------------
1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/android/pts-mcap.txt b/android/pts-mcap.txt
index 9a77839..84aabab 100644
--- a/android/pts-mcap.txt
+++ b/android/pts-mcap.txt
@@ -10,20 +10,24 @@ FAIL test failed
INC test is inconclusive
N/A test is disabled due to PICS setup

+<PTS addr> PTS address
+<cpsm> Control PSM as defined by TSPX_MCAP_l2cap_psm_control
+<dpsm> Data PSM as defined by TSPX_MCAP_l2cap_psm_data
+
-------------------------------------------------------------------------------
Test Name Result Notes
-------------------------------------------------------------------------------
-TC_MCAP_CE_BV_01_C INC
-TC_MCAP_CE_BV_02_C INC
-TC_MCAP_CE_BV_03_C INC
-TC_MCAP_CE_BV_04_C INC
+TC_MCAP_CE_BV_01_C PASS mcaptest -C <cpsm> -D <dpsm> -dc <PTS addr>
+TC_MCAP_CE_BV_02_C PASS mcaptest -C <cpsm> -D <dpsm>
+TC_MCAP_CE_BV_03_C PASS mcaptest -C <cpsm> -D <dpsm> -c <PTS addr>
+TC_MCAP_CE_BV_04_C PASS mcaptest -C <cpsm> -D <dpsm> -d
TC_MCAP_CM_ABT_BV_01_C N/A
-TC_MCAP_CM_ABT_BV_02_C INC
+TC_MCAP_CM_ABT_BV_02_C PASS mcaptest -C <cpsm> -D <dpsm> -d
TC_MCAP_CM_ABT_BV_03_C N/A
TC_MCAP_CM_DEL_BV_01_C N/A
-TC_MCAP_CM_DEL_BV_02_C INC
+TC_MCAP_CM_DEL_BV_02_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_CM_DEL_BV_02_C N/A
-TC_MCAP_CM_DEL_BV_04_C INC
+TC_MCAP_CM_DEL_BV_04_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_CM_DIS_BV_01_C INC
TC_MCAP_CM_DIS_BV_02_C INC
TC_MCAP_CM_DIS_BV_03_C INC
@@ -47,31 +51,31 @@ TC_MCAP_CS_R_BV_01_I N/A
TC_MCAP_CS_R_BV_02_I N/A
TC_MCAP_CS_R_BV_03_C N/A
TC_MCAP_CS_T_BV_04_C N/A
-TC_MCAP_ERR_BI_01_C INC
+TC_MCAP_ERR_BI_01_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_ERR_BI_02_C INC
-TC_MCAP_ERR_BI_03_C INC
+TC_MCAP_ERR_BI_03_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_ERR_BI_04_C INC
-TC_MCAP_ERR_BI_05_C INC
+TC_MCAP_ERR_BI_05_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_ERR_BI_06_C INC
TC_MCAP_ERR_BI_07_C INC
TC_MCAP_ERR_BI_08_C INC
-TC_MCAP_ERR_BI_09_C INC
-TC_MCAP_ERR_BI_10_C INC
+TC_MCAP_ERR_BI_09_C PASS mcaptest -C <cpsm> -D <dpsm>
+TC_MCAP_ERR_BI_10_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_ERR_BI_11_C INC
TC_MCAP_ERR_BI_12_C INC
-TC_MCAP_ERR_BI_13_C INC
-TC_MCAP_ERR_BI_14_C INC
+TC_MCAP_ERR_BI_13_C PASS mcaptest -C <cpsm> -D <dpsm>
+TC_MCAP_ERR_BI_14_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_ERR_BI_15_C INC
TC_MCAP_ERR_BI_16_C INC
TC_MCAP_ERR_BI_17_C INC
TC_MCAP_ERR_BI_18_C INC
-TC_MCAP_ERR_BI_19_C INC
+TC_MCAP_ERR_BI_19_C PASS mcaptest -C <cpsm> -D <dpsm>
TC_MCAP_ERR_BI_20_C INC
-TC_MCAP_INV_BI_01_C INC
+TC_MCAP_INV_BI_01_C PASS mcaptest -C <cpsm> -D <dpsm> -dc <PTS addr>
TC_MCAP_INV_BI_02_C INC
-TC_MCAP_INV_BI_03_C INC
-TC_MCAP_INV_BI_04_C INC
-TC_MCAP_INV_BI_05_C INC
-TC_MCAP_INV_BI_06_C INC
-TC_MCAP_INV_BI_07_C INC
+TC_MCAP_INV_BI_03_C PASS mcaptest -C <cpsm> -D <dpsm> -dc <PTS addr>
+TC_MCAP_INV_BI_04_C PASS mcaptest -C <cpsm> -D <dpsm> -c <PTS addr>
+TC_MCAP_INV_BI_05_C PASS mcaptest -C <cpsm> -D <dpsm>
+TC_MCAP_INV_BI_06_C PASS mcaptest -C <cpsm> -D <dpsm>
+TC_MCAP_INV_BI_07_C PASS mcaptest -C <cpsm> -D <dpsm>
-------------------------------------------------------------------------------
--
2.0.0


2014-06-25 15:50:00

by Jakub Tyszkowski

[permalink] [raw]
Subject: [RFC 4/5] tools/mcaptest: Support incomming connections

This adds support for handling incomming Control Link (MCL) and Data
Link (MDL) connections. This also adds support for aborting MDL and
reconnecting.
---
tools/mcaptest.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 150 insertions(+), 18 deletions(-)

diff --git a/tools/mcaptest.c b/tools/mcaptest.c
index 2793b9f..72b2246 100644
--- a/tools/mcaptest.c
+++ b/tools/mcaptest.c
@@ -54,11 +54,50 @@ static struct mcap_mdl *mdl = NULL;
static uint16_t mdlid;

static int control_mode = MODE_LISTEN;
+static int data_mode = MODE_LISTEN;
+static int reconnect_mdl_mode = MODE_LISTEN;

-static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
+static gboolean abort_mdl = FALSE;
+
+static struct mcap_mcl *mcl = NULL;
+
+static void hdp_mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data) {
+ /* TODO */
+ printf("%s\n", __func__);
+}
+
+static void hdp_mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data)
+{
+ /* TODO */
+ printf("%s\n", __func__);
+}
+
+static void hdp_mcap_mdl_deleted_cb(struct mcap_mdl *mdl, void *data)
{
/* TODO */
- printf("MCL connected unsupported\n");
+ printf("%s\n", __func__);
+}
+
+static void hdp_mcap_mdl_aborted_cb(struct mcap_mdl *mdl, void *data)
+{
+ /* TODO */
+ printf("%s\n", __func__);
+}
+
+static uint8_t hdp_mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
+ uint16_t mdlid, uint8_t *conf, void *data)
+{
+ printf("%s\n", __func__);
+
+ return MCAP_SUCCESS;
+}
+
+static uint8_t hdp_mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data)
+{
+ /* TODO */
+ printf("%s\n", __func__);
+
+ return MCAP_SUCCESS;
}

static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
@@ -87,6 +126,31 @@ static void connect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data)
printf("MDL %d connected\n", mdlid);
}

+static void mdl_reconnect_cb(struct mcap_mdl *mdl, GError *err, gpointer data)
+{
+ printf("%s\n", __func__);
+}
+
+static void trigger_mdl_action(int mode);
+
+static void mdl_abort_cb(GError *err, gpointer data)
+{
+ GError *gerr = NULL;
+
+ printf("%s\n", __func__);
+
+ if (reconnect_mdl_mode == MODE_CONNECT) {
+ mcap_reconnect_mdl(mdl, mdl_reconnect_cb, NULL, NULL, &gerr);
+
+ if (gerr) {
+ printf("Could not connect MDL: %s\n", gerr->message);
+ g_error_free(gerr);
+ }
+ } else if (reconnect_mdl_mode == MODE_LISTEN) {
+ trigger_mdl_action(MODE_LISTEN);
+ }
+}
+
static void create_mdl_cb(struct mcap_mdl *mcap_mdl, uint8_t type, GError *gerr,
gpointer data)
{
@@ -95,42 +159,88 @@ static void create_mdl_cb(struct mcap_mdl *mcap_mdl, uint8_t type, GError *gerr,
if (gerr) {
printf("MDL error: %s\n", gerr->message);

- exit(1);
+ return;
}

mdl = mcap_mdl_ref(mcap_mdl);

- if (!mcap_connect_mdl(mdl, L2CAP_MODE_ERTM, dcpsm, connect_mdl_cb, NULL,
- NULL, &err)) {
+ if (abort_mdl) {
+ mcap_mdl_abort(mcap_mdl, mdl_abort_cb, NULL, NULL, &err);
+ if (err) {
+ printf("MDL abort error: %s\n", err->message);
+
+ g_error_free(err);
+ }
+
+ return;
+ }
+
+ if (!mcap_connect_mdl(mdl, L2CAP_MODE_ERTM, dcpsm,
+ connect_mdl_cb, NULL, NULL, &err)) {
printf("Error connecting to mdl: %s\n", err->message);
g_error_free(err);
}
}

-static void create_mcl_cb(struct mcap_mcl *mcl, GError *err, gpointer data)
+static void trigger_mdl_action(int mode)
{
GError *gerr = NULL;
+ gboolean ret;
+
+ if (mode == MODE_LISTEN) {
+ ret = mcap_mcl_set_cb(mcl, NULL, &gerr,
+ MCAP_MDL_CB_CONNECTED, hdp_mcap_mdl_connected_cb,
+ MCAP_MDL_CB_CLOSED, hdp_mcap_mdl_closed_cb,
+ MCAP_MDL_CB_DELETED, hdp_mcap_mdl_deleted_cb,
+ MCAP_MDL_CB_ABORTED, hdp_mcap_mdl_aborted_cb,
+ MCAP_MDL_CB_REMOTE_CONN_REQ, hdp_mcap_mdl_conn_req_cb,
+ MCAP_MDL_CB_REMOTE_RECONN_REQ,
+ hdp_mcap_mdl_reconn_req_cb, MCAP_MDL_CB_INVALID);
+
+ if (!ret && gerr) {
+ printf("MCL cannot handle connection %s\n",
+ gerr->message);
+ g_error_free(gerr);
+ }
+ } else if (mode == MODE_CONNECT) {
+ mcap_create_mdl(mcl, 1, 0, create_mdl_cb, NULL, NULL, &gerr);
+ if (gerr) {
+ printf("Could not connect MDL: %s\n", gerr->message);
+ g_error_free(gerr);
+ }
+ }
+}
+
+static void mcl_connected(struct mcap_mcl *mcap_mcl, gpointer data)
+{
+ printf("%s\n", __func__);

+ mcl = mcap_mcl_ref(mcap_mcl);
+ trigger_mdl_action(data_mode);
+}
+
+static void create_mcl_cb(struct mcap_mcl *mcap_mcl, GError *err, gpointer data)
+{
if (err) {
printf("Could not connect MCL: %s\n", err->message);

exit(1);
}

- mcap_create_mdl(mcl, 1, 0, create_mdl_cb, NULL, NULL, &gerr);
- if (gerr) {
- printf("Could not connect MDL: %s\n", gerr->message);
- g_error_free(gerr);
- }
+ mcl = mcap_mcl_ref(mcap_mcl);
+ trigger_mdl_action(data_mode);
}
-
static void usage(void)
{
printf("mcaptest - MCAP testing ver %s\n", VERSION);
printf("Usage:\n"
- "\tmcaptest <mode> [options]\n");
- printf("Modes:\n"
- "\t-c connect <dst_addr> (than wait for disconnect)\n");
+ "\tmcaptest <control_mode> <data_mode> [options]\n");
+ printf("Control Link Mode:\n"
+ "\t-c connect <dst_addr>\n");
+ printf("Data Link Mode:\n"
+ "\t-d connect\n"
+ "\t-a abort MDL connection\n"
+ "\t-r reconnect MDL after abort\n");
printf("Options:\n"
"\t-i <hcidev> HCI device\n"
"\t-C <control_ch> Control channel PSM\n"
@@ -140,7 +250,10 @@ static void usage(void)
static struct option main_options[] = {
{ "help", 0, 0, 'h' },
{ "device", 1, 0, 'i' },
- { "connect", 1, 0, 'c' },
+ { "connect_cl", 1, 0, 'c' },
+ { "connect_cl", 0, 0, 'a' },
+ { "connect_cl", 0, 0, 'r' },
+ { "connect_dl", 0, 0, 'd' },
{ "control_ch", 1, 0, 'C' },
{ "data_ch", 1, 0, 'D' },
{ 0, 0, 0, 0 }
@@ -162,7 +275,7 @@ int main(int argc, char *argv[])
exit(1);
}

- while ((opt = getopt_long(argc, argv, "+i:c:C:D:h",
+ while ((opt = getopt_long(argc, argv, "+i:c:C:D:hdar",
main_options, NULL)) != EOF) {
switch (opt) {
case 'i':
@@ -173,12 +286,27 @@ int main(int argc, char *argv[])

break;

+ case 'a':
+ abort_mdl = TRUE;
+
+ break;
+
+ case 'r':
+ reconnect_mdl_mode = MODE_CONNECT;
+
+ break;
+
case 'c':
control_mode = MODE_CONNECT;
str2ba(optarg, &dst);

break;

+ case 'd':
+ data_mode = MODE_CONNECT;
+
+ break;
+
case 'C':
ccpsm = atoi(optarg);

@@ -196,7 +324,7 @@ int main(int argc, char *argv[])
}
}

- mcap = mcap_create_instance(&src, BT_IO_SEC_MEDIUM, 0, 0,
+ mcap = mcap_create_instance(&src, BT_IO_SEC_MEDIUM, ccpsm, dcpsm,
mcl_connected, mcl_reconnected,
mcl_disconnected, mcl_uncached,
NULL, /* CSP is not used right now */
@@ -226,6 +354,10 @@ int main(int argc, char *argv[])
}

break;
+ case MODE_LISTEN:
+ printf("Listening for control channel connection\n");
+
+ break;
case MODE_NONE:
default:
goto done;
--
2.0.0