2019-07-06 15:39:57

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: [PATCH BlueZ v4 0/1] Add --io command line argument

Continuing the refactoring started in 12b984d1d, this patch adds --io
option to bluetooth-meshd, so that the user is able to select mesh-io
implementation.

Compared to v3, this moves option parsing from main into mesh-io-api.

Michał Lowas-Rzechonek (1):
mesh: Added --io option

mesh/main.c | 48 +++++++++++++++++++++++++++---------------
mesh/mesh-io-api.h | 2 ++
mesh/mesh-io-generic.c | 30 ++++++++++++++++++++++++++
mesh/mesh-io.c | 9 ++++++--
mesh/mesh-io.h | 2 +-
mesh/mesh.c | 4 ++--
mesh/mesh.h | 2 +-
7 files changed, 74 insertions(+), 23 deletions(-)

--
2.22.0


2019-07-06 15:40:30

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: [PATCH BlueZ v4 1/1] mesh: Added --io option

This allows specifying io type and options when invoking the daemon.

By default, meshd runs with MESH_IO_TYPE_GENERIC and tries to attach to
the first available HCI interface.

Option "--index=<n>" is now just a shortcut for "--io=generic:<n>"
---
mesh/main.c | 48 +++++++++++++++++++++++++++---------------
mesh/mesh-io-api.h | 2 ++
mesh/mesh-io-generic.c | 30 ++++++++++++++++++++++++++
mesh/mesh-io.c | 9 ++++++--
mesh/mesh-io.h | 2 +-
mesh/mesh.c | 4 ++--
mesh/mesh.h | 2 +-
7 files changed, 74 insertions(+), 23 deletions(-)

diff --git a/mesh/main.c b/mesh/main.c
index 262e3da48..7adb0c2d2 100644
--- a/mesh/main.c
+++ b/mesh/main.c
@@ -39,6 +39,7 @@

static const struct option main_options[] = {
{ "index", required_argument, NULL, 'i' },
+ { "io", required_argument, NULL, 'I' },
{ "config", optional_argument, NULL, 'c' },
{ "nodetach", no_argument, NULL, 'n' },
{ "debug", no_argument, NULL, 'd' },
@@ -49,16 +50,23 @@ static const struct option main_options[] = {

static void usage(void)
{
- l_info("");
- l_info("Usage:\n"
+ fprintf(stderr,
+ "Usage:\n"
"\tbluetooth-meshd [options]\n");
- l_info("Options:\n"
- "\t--index <hcinum> Use specified controller\n"
+ fprintf(stderr,
+ "Options:\n"
+ "\t--index <hcinum> Equivalent of `--io=generic:<hcinum>`\n"
+ "\t--io <io> Use specified io (default: generic)\n"
"\t--config Configuration directory\n"
"\t--nodetach Run in foreground\n"
"\t--debug Enable debug output\n"
"\t--dbus-debug Enable D-Bus debugging\n"
"\t--help Show %s information\n", __func__);
+ fprintf(stderr,
+ "io:\n"
+ "\tgeneric[:<index>]\n"
+ "\t\tUse generic HCI io on interface hci<index>, or the first\n"
+ "\t\tavailable one\n");
}

static void do_debug(const char *str, void *user_data)
@@ -114,7 +122,7 @@ int main(int argc, char *argv[])
bool dbus_debug = false;
struct l_dbus *dbus = NULL;
const char *config_dir = NULL;
- int index = MGMT_INDEX_NONE;
+ char *ioarg = NULL;

if (!l_main_init())
return -1;
@@ -123,7 +131,6 @@ int main(int argc, char *argv[])

for (;;) {
int opt;
- const char *str;

opt = getopt_long(argc, argv, "i:c:ndbh", main_options, NULL);
if (opt < 0)
@@ -131,18 +138,20 @@ int main(int argc, char *argv[])

switch (opt) {
case 'i':
- if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
- str = optarg + 3;
- else
- str = optarg;
- if (!isdigit(*str)) {
- l_error("Invalid controller index value");
- status = EXIT_FAILURE;
+ if (ioarg) {
+ l_error("Use either --index or --io, not both");
+ status = EXIT_SUCCESS;
goto done;
}
-
- index = atoi(str);
-
+ ioarg = l_strdup_printf("generic:%s", optarg);
+ break;
+ case 'I':
+ if (ioarg) {
+ l_error("Use either --index or --io, not both");
+ status = EXIT_SUCCESS;
+ goto done;
+ }
+ ioarg = l_strdup(optarg);
break;
case 'n':
detached = false;
@@ -167,8 +176,10 @@ int main(int argc, char *argv[])
}
}

+ if (!ioarg)
+ ioarg = l_strdup("generic");

- if (!mesh_init(config_dir, MESH_IO_TYPE_GENERIC, &index)) {
+ if (!mesh_init(config_dir, ioarg)) {
l_error("Failed to initialize mesh");
status = EXIT_FAILURE;
goto done;
@@ -198,6 +209,9 @@ int main(int argc, char *argv[])
status = l_main_run_with_signal(signal_handler, NULL);

done:
+ if (ioarg)
+ l_free(ioarg);
+
mesh_cleanup();
l_dbus_destroy(dbus);
l_main_exit();
diff --git a/mesh/mesh-io-api.h b/mesh/mesh-io-api.h
index 4cdf1f80a..b7807da53 100644
--- a/mesh/mesh-io-api.h
+++ b/mesh/mesh-io-api.h
@@ -19,6 +19,7 @@

struct mesh_io_private;

+typedef void *(*mesh_io_opts_t)(const char *optarg);
typedef bool (*mesh_io_init_t)(struct mesh_io *io, void *opts);
typedef bool (*mesh_io_destroy_t)(struct mesh_io *io);
typedef bool (*mesh_io_caps_t)(struct mesh_io *io, struct mesh_io_caps *caps);
@@ -35,6 +36,7 @@ typedef bool (*mesh_io_tx_cancel_t)(struct mesh_io *io, const uint8_t *pattern,
uint8_t len);

struct mesh_io_api {
+ mesh_io_opts_t opts;
mesh_io_init_t init;
mesh_io_destroy_t destroy;
mesh_io_caps_t caps;
diff --git a/mesh/mesh-io-generic.c b/mesh/mesh-io-generic.c
index 42aaa0947..47d0de247 100644
--- a/mesh/mesh-io-generic.c
+++ b/mesh/mesh-io-generic.c
@@ -312,6 +312,35 @@ static void read_info(int index, void *user_data)
hci_init(io);
}

+static void *dev_opts(const char *optarg)
+{
+ int *index = l_new(int, 1);
+
+ if (strstr(optarg, "generic") != optarg)
+ goto fail;
+
+ optarg += strlen("generic");
+ if (!*optarg) {
+ *index = MGMT_INDEX_NONE;
+ return index;
+ }
+
+ if (*optarg != ':')
+ goto fail;
+
+ optarg++;
+
+ if ((sscanf(optarg, "hci%d", index) != 1) &&
+ (sscanf(optarg, "%d", index) != 1)) {
+ goto fail;
+ }
+
+ return index;
+fail:
+ l_free(index);
+ return NULL;
+}
+
static bool dev_init(struct mesh_io *io, void *opts)
{
if (!io || io->pvt)
@@ -783,6 +812,7 @@ static bool filter_set(struct mesh_io *io,
}

const struct mesh_io_api mesh_io_generic = {
+ .opts = dev_opts,
.init = dev_init,
.destroy = dev_destroy,
.caps = dev_caps,
diff --git a/mesh/mesh-io.c b/mesh/mesh-io.c
index 62a8c0e2c..32acd9c2c 100644
--- a/mesh/mesh-io.c
+++ b/mesh/mesh-io.c
@@ -52,15 +52,20 @@ static bool match_by_type(const void *a, const void *b)
return io->type == type;
}

-struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts)
+struct mesh_io *mesh_io_new(const char *optarg)
{
const struct mesh_io_api *api = NULL;
+ enum mesh_io_type type = MESH_IO_TYPE_NONE;
struct mesh_io *io;
+ void *opts;
uint16_t i;

for (i = 0; i < L_ARRAY_SIZE(table); i++) {
- if (table[i].type == type) {
+ opts = table[i].api->opts(optarg);
+
+ if (opts) {
api = table[i].api;
+ type = table[i].type;
break;
}
}
diff --git a/mesh/mesh-io.h b/mesh/mesh-io.h
index 6585205c7..0c367acb7 100644
--- a/mesh/mesh-io.h
+++ b/mesh/mesh-io.h
@@ -80,7 +80,7 @@ typedef void (*mesh_io_recv_func_t)(void *user_data,
typedef void (*mesh_io_status_func_t)(void *user_data, int status,
uint8_t filter_id);

-struct mesh_io *mesh_io_new(enum mesh_io_type type, void *opts);
+struct mesh_io *mesh_io_new(const char *optarg);
void mesh_io_destroy(struct mesh_io *io);

bool mesh_io_get_caps(struct mesh_io *io, struct mesh_io_caps *caps);
diff --git a/mesh/mesh.c b/mesh/mesh.c
index 26acfd4dc..31295d9c6 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -136,7 +136,7 @@ void mesh_unreg_prov_rx(prov_rx_cb_t cb)
mesh_io_deregister_recv_cb(mesh.io, MESH_IO_FILTER_PROV);
}

-bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
+bool mesh_init(const char *config_dir, const char *optarg)
{
struct mesh_io_caps caps;

@@ -158,7 +158,7 @@ bool mesh_init(const char *config_dir, enum mesh_io_type type, void *opts)
if (!storage_load_nodes(config_dir))
return false;

- mesh.io = mesh_io_new(type, opts);
+ mesh.io = mesh_io_new(optarg);
if (!mesh.io)
return false;

diff --git a/mesh/mesh.h b/mesh/mesh.h
index 14b1fb517..4df0615fc 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -32,7 +32,7 @@ enum mesh_io_type;

typedef void (*prov_rx_cb_t)(void *user_data, const uint8_t *data,
uint16_t len);
-bool mesh_init(const char *in_config_name, enum mesh_io_type type, void *opts);
+bool mesh_init(const char *config_dir, const char *optarg);
void mesh_cleanup(void);
bool mesh_dbus_init(struct l_dbus *dbus);

--
2.22.0