Applied On Thu, 2020-01-16 at 13:09 +0100, Michał Lowas-Rzechonek wrote: > This allows specifying io type and options when invoking the daemon. > > When no "-i" is passed, meshd still runs with MESH_IO_TYPE_GENERIC and > tries to attach to the first available HCI interface. > > Options "-i <n>" and "-i hci<n>" are just shortcuts for > "--io=generic:<n>" and "--io=generic:hci<n>", respectively. > --- > v4: Free the 'io' string immediately after parsing it with parse_io > > mesh/main.c | 89 +++++++++++++++++++++++++++++++++++++++++------------ > 1 file changed, 69 insertions(+), 20 deletions(-) > > diff --git a/mesh/main.c b/mesh/main.c > index 010edcf85..c6bf1ff41 100644 > --- a/mesh/main.c > +++ b/mesh/main.c > @@ -40,10 +40,11 @@ > > static const char *config_dir; > static const char *mesh_conf_fname; > -static int ctlr_index = MGMT_INDEX_NONE; > +static enum mesh_io_type io_type; > +static void *io_opts; > > 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' }, > @@ -54,16 +55,22 @@ 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--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" > + "\t([hci]<index> | generic[:[hci]<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) > @@ -100,8 +107,8 @@ static void request_name_callback(struct l_dbus *dbus, bool success, > return; > } > > - if (!mesh_init(config_dir, mesh_conf_fname, MESH_IO_TYPE_GENERIC, > - &ctlr_index, mesh_ready_callback, dbus)) { > + if (!mesh_init(config_dir, mesh_conf_fname, io_type, io_opts, > + mesh_ready_callback, dbus)) { > l_error("Failed to initialize mesh"); > l_main_quit(); > } > @@ -133,12 +140,45 @@ static void signal_handler(uint32_t signo, void *user_data) > terminated = true; > } > > +static bool parse_io(const char *optarg, enum mesh_io_type *type, void **opts) > +{ > + if (strstr(optarg, "generic") == optarg) { > + int *index = l_new(int, 1); > + > + *type = MESH_IO_TYPE_GENERIC; > + *opts = index; > + > + optarg += strlen("generic"); > + if (!*optarg) { > + *index = MGMT_INDEX_NONE; > + return true; > + } > + > + if (*optarg != ':') > + return false; > + > + optarg++; > + > + if (sscanf(optarg, "hci%d", index) == 1) > + return true; > + > + if (sscanf(optarg, "%d", index) == 1) > + return true; > + > + return false; > + } > + > + return false; > +} > + > int main(int argc, char *argv[]) > { > int status; > bool detached = true; > bool dbus_debug = false; > struct l_dbus *dbus = NULL; > + char *io = NULL; > + int hci_index; > > if (!l_main_init()) > return -1; > @@ -153,7 +193,6 @@ int main(int argc, char *argv[]) > > for (;;) { > int opt; > - const char *str; > > opt = getopt_long(argc, argv, "i:c:f:ndbh", main_options, NULL); > if (opt < 0) > @@ -161,18 +200,11 @@ int main(int argc, char *argv[]) > > switch (opt) { > case 'i': > - if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3)) > - str = optarg + 3; > + if (sscanf(optarg, "hci%d", &hci_index) == 1 || > + sscanf(optarg, "%d", &hci_index) == 1) > + io = l_strdup_printf("generic:%s", optarg); > else > - str = optarg; > - if (!isdigit(*str)) { > - l_error("Invalid controller index value"); > - status = EXIT_FAILURE; > - goto done; > - } > - > - ctlr_index = atoi(str); > - > + io = l_strdup(optarg); > break; > case 'n': > detached = false; > @@ -200,6 +232,17 @@ int main(int argc, char *argv[]) > } > } > > + if (!io) > + io = l_strdup_printf("generic"); > + > + if (!parse_io(io, &io_type, &io_opts)) { > + l_error("Invalid io: %s", io); > + status = EXIT_FAILURE; > + goto done; > + } > + > + l_free(io); > + io = NULL; > > if (!detached) > umask(0077); > @@ -225,6 +268,12 @@ int main(int argc, char *argv[]) > status = l_main_run_with_signal(signal_handler, NULL); > > done: > + if (io) > + l_free(io); > + > + if (io_opts) > + l_free(io_opts); > + > mesh_cleanup(); > l_dbus_destroy(dbus); > l_main_exit();