* [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode
@ 2018-02-26 15:53 Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 01/14] shared/shell: Add bt_shell_{noninteractive_}quit Luiz Augusto von Dentz
` (13 more replies)
0 siblings, 14 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds functionally to bt_shell to properly handle non-interactive
mode making all command line tools handle commands given as argument:
>./bluetoothctl power on
[CHG] Controller B8:8A:60:D8:17:D7 Class: 0x002c010c
Changing power on succeded
While on non-interactive mode readline will not be used and only the
command line arguments will be processed, in addition to that there
is now bt_shell_noninteractive_quit which shall be used by the command
handler to quit when it is done with the command execution.
Luiz Augusto von Dentz (14):
shared/shell: Add bt_shell_{noninteractive_}quit
shared/shell: Fix not reseting optind
shared/shell: Fix timeout parameter
shared/shell: Do not quit immediatelly on noninteractive mode
shared/shell: Fix not handling sort options
shared/shell: Disable bt_shell_prompt_input in noninteractive mode
shared/shell: Disable readline while in noninteractive mode
sharead/mainloop-glib: Fix mainloop_exit*
shared/mainloop-glib: Fix calling g_main_loop_quit with NULL
shared/shell: Allow executing submenu commands
client: Call bt_shell_noninteractive_quit when done with command
shared/shell: Add bt_shell_usage
shared/shell: Fix parsing of mandatory arguments
tools/btmgmt: Port to use bt_shell
client/advertising.c | 84 ++-
client/gatt.c | 113 ++--
client/main.c | 153 +++--
src/shared/mainloop-glib.c | 5 +
src/shared/shell.c | 130 +++-
src/shared/shell.h | 4 +
tools/btmgmt.c | 1560 ++++++++++++++++----------------------------
7 files changed, 905 insertions(+), 1144 deletions(-)
--
2.14.3
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH BlueZ 01/14] shared/shell: Add bt_shell_{noninteractive_}quit
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 02/14] shared/shell: Fix not reseting optind Luiz Augusto von Dentz
` (12 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
The functions can be used to tell the shell to stop running.
---
src/shared/shell.c | 16 ++++++++++++++++
src/shared/shell.h | 3 +++
2 files changed, 19 insertions(+)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index 6cc797cdb..9ecb4c7be 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -866,6 +866,22 @@ void bt_shell_run(void)
data.init = false;
}
+void bt_shell_quit(int status)
+{
+ if (status == EXIT_SUCCESS)
+ mainloop_exit_success();
+ else
+ mainloop_exit_failure();
+}
+
+void bt_shell_noninteractive_quit(int status)
+{
+ if (!data.mode || data.timeout)
+ return;
+
+ bt_shell_quit(status);
+}
+
bool bt_shell_set_menu(const struct bt_shell_menu *menu)
{
if (!menu)
diff --git a/src/shared/shell.h b/src/shared/shell.h
index 359629896..10747c955 100644
--- a/src/shared/shell.h
+++ b/src/shared/shell.h
@@ -68,6 +68,9 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt);
void bt_shell_run(void);
+void bt_shell_quit(int status);
+void bt_shell_noninteractive_quit(int status);
+
bool bt_shell_set_menu(const struct bt_shell_menu *menu);
bool bt_shell_add_submenu(const struct bt_shell_menu *menu);
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 02/14] shared/shell: Fix not reseting optind
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 01/14] shared/shell: Add bt_shell_{noninteractive_}quit Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 03/14] shared/shell: Fix timeout parameter Luiz Augusto von Dentz
` (11 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Not reseting optind may crash the tool if getopt and variants are
called a second time.
---
src/shared/shell.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index 9ecb4c7be..0653c0ea1 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -817,6 +817,7 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
data.argc = argc - optind;
data.argv = argv + optind;
+ optind = 0;
data.mode = (data.argc > 0);
if (data.mode)
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 03/14] shared/shell: Fix timeout parameter
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 01/14] shared/shell: Add bt_shell_{noninteractive_}quit Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 02/14] shared/shell: Fix not reseting optind Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 04/14] shared/shell: Do not quit immediatelly on noninteractive mode Luiz Augusto von Dentz
` (10 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fix help message and add proper optstr modifier so both -t/--timeout
work properly.
---
src/shared/shell.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index 0653c0ea1..e82307d6f 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -768,7 +768,7 @@ static void usage(int argc, char **argv, const struct bt_shell_opt *opt)
for (i = 0; opt && opt->options[i].name; i++)
printf("\t--%s \t%s\n", opt->options[i].name, opt->help[i]);
- printf("\t--timeout \t\tTimeout in seconds for non-interactive mode\n"
+ printf("\t--timeout \tTimeout in seconds for non-interactive mode\n"
"\t--version \tDisplay version\n"
"\t--help \t\tDisplay help\n");
}
@@ -787,9 +787,9 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
if (opt) {
memcpy(options + offset, opt->options,
sizeof(struct option) * opt->optno);
- snprintf(optstr, sizeof(optstr), "+hv%s", opt->optstr);
+ snprintf(optstr, sizeof(optstr), "+hvt:%s", opt->optstr);
} else
- snprintf(optstr, sizeof(optstr), "+hv");
+ snprintf(optstr, sizeof(optstr), "+hvt:");
while ((c = getopt_long(argc, argv, optstr, options, &index)) != -1) {
switch (c) {
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 04/14] shared/shell: Do not quit immediatelly on noninteractive mode
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (2 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 03/14] shared/shell: Fix timeout parameter Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 05/14] shared/shell: Fix not handling sort options Luiz Augusto von Dentz
` (9 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
The command handler shall be able to tell when it is done by calling
bt_shell_noninteractive_quit.
---
src/shared/shell.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index e82307d6f..eae4ffbdd 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -951,10 +951,7 @@ bool bt_shell_attach(int fd)
if (data.mode) {
shell_exec(data.argc, data.argv);
- if (!data.timeout) {
- bt_shell_detach();
- mainloop_quit();
- } else
+ if (data.timeout)
timeout_add(data.timeout * 1000, shell_quit, NULL,
NULL);
}
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 05/14] shared/shell: Fix not handling sort options
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (3 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 04/14] shared/shell: Do not quit immediatelly on noninteractive mode Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 06/14] shared/shell: Disable bt_shell_prompt_input in noninteractive mode Luiz Augusto von Dentz
` (8 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
getopt_long index is only valid for long options.
---
src/shared/shell.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index eae4ffbdd..7f726c2dd 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -775,7 +775,7 @@ static void usage(int argc, char **argv, const struct bt_shell_opt *opt)
void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
{
- int c, index = 0;
+ int c, index = -1;
struct option options[256];
char optstr[256];
size_t offset;
@@ -805,6 +805,13 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
data.timeout = atoi(optarg);
break;
default:
+ if (index < 0) {
+ for (index = 0; options[index].val; index++) {
+ if (c == options[index].val)
+ break;
+ }
+ }
+
if (c != opt->options[index - offset].val) {
usage(argc, argv, opt);
exit(EXIT_SUCCESS);
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 06/14] shared/shell: Disable bt_shell_prompt_input in noninteractive mode
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (4 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 05/14] shared/shell: Fix not handling sort options Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 07/14] shared/shell: Disable readline while " Luiz Augusto von Dentz
` (7 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Only the input given as argument shall be processed, all the rest shall
be ignored.
---
src/shared/shell.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index 7f726c2dd..bf07d034f 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -417,6 +417,9 @@ void bt_shell_hexdump(const unsigned char *buf, size_t len)
void bt_shell_prompt_input(const char *label, const char *msg,
bt_shell_prompt_input_func func, void *user_data)
{
+ if (!data.init || data.mode)
+ return;
+
/* Normal use should not prompt for user input to the value a second
* time before it releases the prompt, but we take a safe action. */
if (data.saved_prompt)
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 07/14] shared/shell: Disable readline while in noninteractive mode
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (5 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 06/14] shared/shell: Disable bt_shell_prompt_input in noninteractive mode Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 08/14] sharead/mainloop-glib: Fix mainloop_exit* Luiz Augusto von Dentz
` (6 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
User shall not be able to interact with the shell while in
noninteractive mode.
---
src/shared/shell.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index bf07d034f..b5556a288 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -381,6 +381,13 @@ void bt_shell_printf(const char *fmt, ...)
if (!data.input)
return;
+ if (data.mode) {
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ return;
+ }
+
save_input = !RL_ISSTATE(RL_STATE_DONE);
if (save_input) {
@@ -683,7 +690,7 @@ static bool signal_read(struct io *io, void *user_data)
switch (si.ssi_signo) {
case SIGINT:
- if (data.input) {
+ if (data.input && !data.mode) {
rl_replace_line("", 0);
rl_crlf();
rl_on_new_line();
@@ -701,8 +708,10 @@ static bool signal_read(struct io *io, void *user_data)
/* fall through */
case SIGTERM:
if (!terminated) {
- rl_replace_line("", 0);
- rl_crlf();
+ if (!data.mode) {
+ rl_replace_line("", 0);
+ rl_crlf();
+ }
mainloop_quit();
}
@@ -745,6 +754,9 @@ static struct io *setup_signalfd(void)
static void rl_init(void)
{
+ if (data.mode)
+ return;
+
setlinebuf(stdout);
rl_attempted_completion_function = shell_completion;
@@ -842,6 +854,9 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
static void rl_cleanup(void)
{
+ if (data.mode)
+ return;
+
rl_message("");
rl_callback_handler_remove();
}
@@ -953,7 +968,9 @@ bool bt_shell_attach(int fd)
io = io_new(fd);
- io_set_read_handler(io, input_read, NULL, NULL);
+ if (!data.mode)
+ io_set_read_handler(io, input_read, NULL, NULL);
+
io_set_disconnect_handler(io, io_hup, NULL, NULL);
data.input = io;
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 08/14] sharead/mainloop-glib: Fix mainloop_exit*
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (6 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 07/14] shared/shell: Disable readline while " Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 09/14] shared/mainloop-glib: Fix calling g_main_loop_quit with NULL Luiz Augusto von Dentz
` (5 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
These function shall cause the mainloop to quit.
---
src/shared/mainloop-glib.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/shared/mainloop-glib.c b/src/shared/mainloop-glib.c
index 14d43207a..1bbac5d11 100644
--- a/src/shared/mainloop-glib.c
+++ b/src/shared/mainloop-glib.c
@@ -53,11 +53,13 @@ void mainloop_quit(void)
void mainloop_exit_success(void)
{
exit_status = EXIT_SUCCESS;
+ mainloop_quit();
}
void mainloop_exit_failure(void)
{
exit_status = EXIT_FAILURE;
+ mainloop_quit();
}
int mainloop_run(void)
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 09/14] shared/mainloop-glib: Fix calling g_main_loop_quit with NULL
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (7 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 08/14] sharead/mainloop-glib: Fix mainloop_exit* Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 10/14] shared/shell: Allow executing submenu commands Luiz Augusto von Dentz
` (4 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This produces warnings such as:
(process:5122): GLib-CRITICAL **: g_main_loop_quit: assertion 'loop != NULL' failed
---
src/shared/mainloop-glib.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/shared/mainloop-glib.c b/src/shared/mainloop-glib.c
index 1bbac5d11..8436969bb 100644
--- a/src/shared/mainloop-glib.c
+++ b/src/shared/mainloop-glib.c
@@ -47,6 +47,9 @@ void mainloop_init(void)
void mainloop_quit(void)
{
+ if (!main_loop)
+ return;
+
g_main_loop_quit(main_loop);
}
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 10/14] shared/shell: Allow executing submenu commands
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (8 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 09/14] shared/mainloop-glib: Fix calling g_main_loop_quit with NULL Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 11/14] client: Call bt_shell_noninteractive_quit when done with command Luiz Augusto von Dentz
` (3 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This makes it possible to execute submenu commands directly from the
main menu by using the format <submenu>.<command>:
[bluetooth]# advertise.uuids 0x1820
[bluetooth]# advertise.name blah
[bluetooth]# advertise on
Advertising object registered
UUID: Internet Protocol Support(0x1820)
Tx Power: off
LocalName: blah
Apperance: off
---
src/shared/shell.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index b5556a288..cd46532fe 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -356,6 +356,34 @@ static int menu_exec(const struct bt_shell_menu_entry *entry,
return -ENOENT;
}
+static int submenu_exec(int argc, char *argv[])
+{
+ char *name;
+ int len, tlen;
+ const struct bt_shell_menu *submenu;
+
+ if (data.menu != data.main)
+ return -ENOENT;
+
+ name = strchr(argv[0], '.');
+ if (!name)
+ return -ENOENT;
+
+ tlen = strlen(argv[0]);
+ len = name - argv[0];
+ name[0] = '\0';
+
+ submenu = find_menu(argv[0]);
+ if (!submenu)
+ return -ENOENT;
+
+ /* Replace submenu.command with command */
+ memmove(argv[0], argv[0] + len + 1, tlen - len - 1);
+ memset(argv[0] + tlen - len - 1, 0, len + 1);
+
+ return menu_exec(submenu->entries, argc, argv);
+}
+
static void shell_exec(int argc, char *argv[])
{
if (!data.menu || !argv[0])
@@ -363,10 +391,12 @@ static void shell_exec(int argc, char *argv[])
if (menu_exec(default_menu, argc, argv) == -ENOENT) {
if (menu_exec(data.menu->entries, argc, argv) == -ENOENT) {
- print_text(COLOR_HIGHLIGHT,
+ if (submenu_exec(argc, argv) == -ENOENT) {
+ print_text(COLOR_HIGHLIGHT,
"Invalid command in menu %s: %s",
data.menu->name , argv[0]);
- shell_print_help();
+ shell_print_help();
+ }
}
}
}
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 11/14] client: Call bt_shell_noninteractive_quit when done with command
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (9 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 10/14] shared/shell: Allow executing submenu commands Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 12/14] shared/shell: Add bt_shell_usage Luiz Augusto von Dentz
` (2 subsequent siblings)
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This ensures that the commands don't stay hanging since bt_shell no
longer quits immediatelly after executing a command.
---
client/advertising.c | 84 +++++++++++++++++++---------
client/gatt.c | 113 ++++++++++++++++++++++++-------------
client/main.c | 153 ++++++++++++++++++++++++++++++++++-----------------
3 files changed, 235 insertions(+), 115 deletions(-)
diff --git a/client/advertising.c b/client/advertising.c
index 3cfc318ba..2be96483a 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -190,6 +190,7 @@ static void register_reply(DBusMessage *message, void *user_data)
ad.registered = true;
bt_shell_printf("Advertising object registered\n");
print_ad();
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
} else {
bt_shell_printf("Failed to register advertisement: %s\n", error.name);
dbus_error_free(&error);
@@ -197,6 +198,7 @@ static void register_reply(DBusMessage *message, void *user_data)
if (g_dbus_unregister_interface(conn, AD_PATH,
AD_IFACE) == FALSE)
bt_shell_printf("Failed to unregister advertising object\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -441,7 +443,7 @@ void ad_register(DBusConnection *conn, GDBusProxy *manager, const char *type)
{
if (ad.registered) {
bt_shell_printf("Advertisement is already registered\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
g_free(ad.type);
@@ -450,14 +452,14 @@ void ad_register(DBusConnection *conn, GDBusProxy *manager, const char *type)
if (g_dbus_register_interface(conn, AD_PATH, AD_IFACE, ad_methods,
NULL, ad_props, NULL, NULL) == FALSE) {
bt_shell_printf("Failed to register advertising object\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (g_dbus_proxy_method_call(manager, "RegisterAdvertisement",
register_setup, register_reply,
conn, NULL) == FALSE) {
bt_shell_printf("Failed to register advertising\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -481,10 +483,12 @@ static void unregister_reply(DBusMessage *message, void *user_data)
if (g_dbus_unregister_interface(conn, AD_PATH,
AD_IFACE) == FALSE)
bt_shell_printf("Failed to unregister advertising object\n");
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
} else {
bt_shell_printf("Failed to unregister advertisement: %s\n",
error.name);
dbus_error_free(&error);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -494,7 +498,7 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager)
ad_release(conn);
if (!ad.registered)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
g_free(ad.type);
ad.type = NULL;
@@ -503,7 +507,7 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager)
unregister_setup, unregister_reply,
conn, NULL) == FALSE) {
bt_shell_printf("Failed to unregister advertisement method\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -518,7 +522,7 @@ void ad_advertise_uuids(DBusConnection *conn, int argc, char *argv[])
{
if (argc < 2 || !strlen(argv[1])) {
print_ad_uuids();
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
ad_clear_uuids();
@@ -526,27 +530,33 @@ void ad_advertise_uuids(DBusConnection *conn, int argc, char *argv[])
ad.uuids = g_strdupv(&argv[1]);
if (!ad.uuids) {
bt_shell_printf("Failed to parse input\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ad.uuids_len = g_strv_length(ad.uuids);
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "ServiceUUIDs");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_disable_uuids(DBusConnection *conn)
{
if (!ad.uuids)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad_clear_uuids();
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "ServiceUUIDs");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void ad_clear_service(void)
{
g_free(ad.service.uuid);
memset(&ad.service, 0, sizeof(ad.service));
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_service(DBusConnection *conn, int argc, char *argv[])
@@ -560,7 +570,7 @@ void ad_advertise_service(DBusConnection *conn, int argc, char *argv[])
bt_shell_hexdump(ad.service.data.data,
ad.service.data.len);
}
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
ad_clear_service();
@@ -590,20 +600,26 @@ void ad_advertise_service(DBusConnection *conn, int argc, char *argv[])
}
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "ServiceData");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_disable_service(DBusConnection *conn)
{
if (!ad.service.uuid)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad_clear_service();
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "ServiceData");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void ad_clear_manufacturer(void)
{
memset(&ad.manufacturer, 0, sizeof(ad.manufacturer));
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
@@ -621,7 +637,7 @@ void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
ad.manufacturer.data.len);
}
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
ad_clear_manufacturer();
@@ -629,7 +645,7 @@ void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
val = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT16_MAX) {
bt_shell_printf("Invalid manufacture id\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ad.manufacturer.id = val;
@@ -639,14 +655,14 @@ void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
if (i >= G_N_ELEMENTS(data->data)) {
bt_shell_printf("Too much data\n");
ad_clear_manufacturer();
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
val = strtol(argv[i], &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
bt_shell_printf("Invalid value at index %d\n", i);
ad_clear_manufacturer();
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
data->data[data->len] = val;
@@ -655,23 +671,27 @@ void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE,
"ManufacturerData");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_disable_manufacturer(DBusConnection *conn)
{
if (!ad.manufacturer.id && !ad.manufacturer.data.len)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad_clear_manufacturer();
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE,
"ManufacturerData");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_tx_power(DBusConnection *conn, dbus_bool_t *value)
{
if (!value) {
bt_shell_printf("Tx Power: %s\n", ad.tx_power ? "on" : "off");
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
if (ad.tx_power == *value)
@@ -680,12 +700,14 @@ void ad_advertise_tx_power(DBusConnection *conn, dbus_bool_t *value)
ad.tx_power = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Includes");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_name(DBusConnection *conn, bool value)
{
if (ad.name == value)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad.name = value;
@@ -695,6 +717,8 @@ void ad_advertise_name(DBusConnection *conn, bool value)
}
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Includes");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_local_name(DBusConnection *conn, const char *name)
@@ -705,7 +729,7 @@ void ad_advertise_local_name(DBusConnection *conn, const char *name)
else
bt_shell_printf("Name: %s\n", ad.name ? "on" : "off");
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
if (ad.local_name && !strcmp(name, ad.local_name))
@@ -715,12 +739,14 @@ void ad_advertise_local_name(DBusConnection *conn, const char *name)
ad.local_name = strdup(name);
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "LocalName");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_appearance(DBusConnection *conn, bool value)
{
if (ad.appearance == value)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad.appearance = value;
@@ -728,6 +754,8 @@ void ad_advertise_appearance(DBusConnection *conn, bool value)
ad.local_appearance = UINT16_MAX;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Includes");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_local_appearance(DBusConnection *conn, long int *value)
@@ -741,15 +769,17 @@ void ad_advertise_local_appearance(DBusConnection *conn, long int *value)
bt_shell_printf("Apperance: %s\n",
ad.appearance ? "on" : "off");
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
if (ad.local_appearance == *value)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad.local_appearance = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Appearance");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_duration(DBusConnection *conn, long int *value)
@@ -757,15 +787,17 @@ void ad_advertise_duration(DBusConnection *conn, long int *value)
if (!value) {
if (ad.duration)
bt_shell_printf("Duration: %u sec\n", ad.duration);
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
if (ad.duration == *value)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad.duration = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Duration");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void ad_advertise_timeout(DBusConnection *conn, long int *value)
@@ -773,13 +805,15 @@ void ad_advertise_timeout(DBusConnection *conn, long int *value)
if (!value) {
if (ad.timeout)
bt_shell_printf("Timeout: %u sec\n", ad.timeout);
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
if (ad.timeout == *value)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
ad.timeout = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Timeout");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
diff --git a/client/gatt.c b/client/gatt.c
index b640b6eb9..91cfb019f 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -367,6 +367,7 @@ static void list_attributes(const char *path, GList *source)
void gatt_list_attributes(const char *path)
{
list_attributes(path, services);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static GDBusProxy *select_attribute(const char *path)
@@ -488,14 +489,14 @@ static void read_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to read: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
dbus_message_iter_init(message, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
bt_shell_printf("Invalid response to read\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
dbus_message_iter_recurse(&iter, &array);
@@ -503,10 +504,12 @@ static void read_reply(DBusMessage *message, void *user_data)
if (len < 0) {
bt_shell_printf("Unable to parse value\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_hexdump(value, len);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void read_setup(DBusMessageIter *iter, void *user_data)
@@ -528,7 +531,7 @@ static void read_attribute(GDBusProxy *proxy)
if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup, read_reply,
NULL, NULL) == FALSE) {
bt_shell_printf("Failed to read\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Attempting to read %s\n", g_dbus_proxy_get_path(proxy));
@@ -547,6 +550,7 @@ void gatt_read_attribute(GDBusProxy *proxy)
bt_shell_printf("Unable to read attribute %s\n",
g_dbus_proxy_get_path(proxy));
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void write_reply(DBusMessage *message, void *user_data)
@@ -558,8 +562,10 @@ static void write_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to write: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void write_setup(DBusMessageIter *iter, void *user_data)
@@ -598,13 +604,13 @@ static void write_attribute(GDBusProxy *proxy, char *arg)
if (i >= G_N_ELEMENTS(value)) {
bt_shell_printf("Too much data\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
val = strtol(entry, &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
bt_shell_printf("Invalid value at index %d\n", i);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
value[i] = val;
@@ -619,7 +625,7 @@ static void write_attribute(GDBusProxy *proxy, char *arg)
io_get_fd(write_io.io));
if (io_send(write_io.io, &iov, 1) < 0) {
bt_shell_printf("Failed to write: %s", strerror(errno));
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
return;
}
@@ -627,7 +633,7 @@ static void write_attribute(GDBusProxy *proxy, char *arg)
if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup,
write_reply, &iov, NULL) == FALSE) {
bt_shell_printf("Failed to write\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Attempting to write %s\n", g_dbus_proxy_get_path(proxy));
@@ -646,6 +652,8 @@ void gatt_write_attribute(GDBusProxy *proxy, const char *arg)
bt_shell_printf("Unable to write attribute %s\n",
g_dbus_proxy_get_path(proxy));
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static bool pipe_read(struct io *io, void *user_data)
@@ -729,7 +737,7 @@ static void acquire_write_reply(DBusMessage *message, void *user_data)
bt_shell_printf("Failed to acquire write: %s\n", error.name);
dbus_error_free(&error);
write_io.proxy = NULL;
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (write_io.io)
@@ -739,12 +747,13 @@ static void acquire_write_reply(DBusMessage *message, void *user_data)
DBUS_TYPE_UINT16, &write_io.mtu,
DBUS_TYPE_INVALID) == false)) {
bt_shell_printf("Invalid AcquireWrite response\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("AcquireWrite success: fd %d MTU %u\n", fd, write_io.mtu);
write_io.io = pipe_io_new(fd, NULL);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void acquire_setup(DBusMessageIter *iter, void *user_data)
@@ -769,13 +778,13 @@ void gatt_acquire_write(GDBusProxy *proxy, const char *arg)
if (strcmp(iface, "org.bluez.GattCharacteristic1")) {
bt_shell_printf("Unable to acquire write: %s not a characteristic\n",
g_dbus_proxy_get_path(proxy));
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (g_dbus_proxy_method_call(proxy, "AcquireWrite", acquire_setup,
acquire_write_reply, NULL, NULL) == FALSE) {
bt_shell_printf("Failed to AcquireWrite\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
write_io.proxy = proxy;
@@ -785,10 +794,12 @@ void gatt_release_write(GDBusProxy *proxy, const char *arg)
{
if (proxy != write_io.proxy || !write_io.io) {
bt_shell_printf("Write not acquired\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
write_io_destroy();
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void acquire_notify_reply(DBusMessage *message, void *user_data)
@@ -802,7 +813,7 @@ static void acquire_notify_reply(DBusMessage *message, void *user_data)
bt_shell_printf("Failed to acquire notify: %s\n", error.name);
dbus_error_free(&error);
write_io.proxy = NULL;
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (notify_io.io) {
@@ -816,12 +827,14 @@ static void acquire_notify_reply(DBusMessage *message, void *user_data)
DBUS_TYPE_UINT16, ¬ify_io.mtu,
DBUS_TYPE_INVALID) == false)) {
bt_shell_printf("Invalid AcquireNotify response\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("AcquireNotify success: fd %d MTU %u\n", fd, notify_io.mtu);
notify_io.io = pipe_io_new(fd, NULL);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void gatt_acquire_notify(GDBusProxy *proxy, const char *arg)
@@ -832,13 +845,13 @@ void gatt_acquire_notify(GDBusProxy *proxy, const char *arg)
if (strcmp(iface, "org.bluez.GattCharacteristic1")) {
bt_shell_printf("Unable to acquire notify: %s not a characteristic\n",
g_dbus_proxy_get_path(proxy));
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (g_dbus_proxy_method_call(proxy, "AcquireNotify", acquire_setup,
acquire_notify_reply, NULL, NULL) == FALSE) {
bt_shell_printf("Failed to AcquireNotify\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
notify_io.proxy = proxy;
@@ -848,10 +861,12 @@ void gatt_release_notify(GDBusProxy *proxy, const char *arg)
{
if (proxy != notify_io.proxy || !notify_io.io) {
bt_shell_printf("Notify not acquired\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
notify_io_destroy();
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void notify_reply(DBusMessage *message, void *user_data)
@@ -865,10 +880,12 @@ static void notify_reply(DBusMessage *message, void *user_data)
bt_shell_printf("Failed to %s notify: %s\n",
enable ? "start" : "stop", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Notify %s\n", enable == TRUE ? "started" : "stopped");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void notify_attribute(GDBusProxy *proxy, bool enable)
@@ -883,8 +900,10 @@ static void notify_attribute(GDBusProxy *proxy, bool enable)
if (g_dbus_proxy_method_call(proxy, method, NULL, notify_reply,
GUINT_TO_POINTER(enable), NULL) == FALSE) {
bt_shell_printf("Failed to %s notify\n", enable ? "start" : "stop");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void gatt_notify_attribute(GDBusProxy *proxy, bool enable)
@@ -899,6 +918,8 @@ void gatt_notify_attribute(GDBusProxy *proxy, bool enable)
bt_shell_printf("Unable to notify attribute %s\n",
g_dbus_proxy_get_path(proxy));
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void register_app_setup(DBusMessageIter *iter, void *user_data)
@@ -927,10 +948,12 @@ static void register_app_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to register application: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Application registered\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
void gatt_add_manager(GDBusProxy *proxy)
@@ -997,7 +1020,7 @@ void gatt_register_app(DBusConnection *conn, GDBusProxy *proxy,
l = g_list_find_custom(managers, proxy, match_proxy);
if (!l) {
bt_shell_printf("Unable to find GattManager proxy\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
for (i = 0; i < argc; i++)
@@ -1009,7 +1032,7 @@ void gatt_register_app(DBusConnection *conn, GDBusProxy *proxy,
NULL, properties, NULL,
NULL) == FALSE) {
bt_shell_printf("Failed to register application object\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1019,7 +1042,7 @@ void gatt_register_app(DBusConnection *conn, GDBusProxy *proxy,
NULL) == FALSE) {
bt_shell_printf("Failed register application\n");
g_dbus_unregister_interface(conn, APP_PATH, PROFILE_INTERFACE);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1033,18 +1056,20 @@ static void unregister_app_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to unregister application: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Application unregistered\n");
if (!uuids)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
g_list_free_full(uuids, g_free);
uuids = NULL;
g_dbus_unregister_interface(conn, APP_PATH, PROFILE_INTERFACE);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void unregister_app_setup(DBusMessageIter *iter, void *user_data)
@@ -1061,7 +1086,7 @@ void gatt_unregister_app(DBusConnection *conn, GDBusProxy *proxy)
l = g_list_find_custom(managers, proxy, match_proxy);
if (!l) {
bt_shell_printf("Unable to find GattManager proxy\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (g_dbus_proxy_method_call(l->data, "UnregisterApplication",
@@ -1069,7 +1094,7 @@ void gatt_unregister_app(DBusConnection *conn, GDBusProxy *proxy)
unregister_app_reply, conn,
NULL) == FALSE) {
bt_shell_printf("Failed unregister profile\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1190,7 +1215,7 @@ void gatt_register_service(DBusConnection *conn, GDBusProxy *proxy,
service_free) == FALSE) {
bt_shell_printf("Failed to register service object\n");
service_free(service);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print_service(service, COLORED_NEW);
@@ -1199,6 +1224,8 @@ void gatt_register_service(DBusConnection *conn, GDBusProxy *proxy,
bt_shell_prompt_input(service->path, "Primary (yes/no):", service_set_primary,
service);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct service *service_find(const char *pattern)
@@ -1228,7 +1255,7 @@ void gatt_unregister_service(DBusConnection *conn, GDBusProxy *proxy,
service = service_find(argv[1]);
if (!service) {
bt_shell_printf("Failed to unregister service object\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
local_services = g_list_remove(local_services, service);
@@ -1237,6 +1264,8 @@ void gatt_unregister_service(DBusConnection *conn, GDBusProxy *proxy,
g_dbus_unregister_interface(service->conn, service->path,
SERVICE_INTERFACE);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static gboolean chrc_get_uuid(const GDBusPropertyTable *property,
@@ -1672,7 +1701,7 @@ void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy,
if (!local_services) {
bt_shell_printf("No service registered\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
service = g_list_last(local_services)->data;
@@ -1688,7 +1717,7 @@ void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy,
chrc, chrc_free) == FALSE) {
bt_shell_printf("Failed to register characteristic object\n");
chrc_free(chrc);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
service->chrcs = g_list_append(service->chrcs, chrc);
@@ -1696,6 +1725,8 @@ void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy,
print_chrc(chrc, COLORED_NEW);
bt_shell_prompt_input(chrc->path, "Enter value:", chrc_set_value, chrc);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct chrc *chrc_find(const char *pattern)
@@ -1731,12 +1762,14 @@ void gatt_unregister_chrc(DBusConnection *conn, GDBusProxy *proxy,
chrc = chrc_find(argv[1]);
if (!chrc) {
bt_shell_printf("Failed to unregister characteristic object\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
chrc->service->chrcs = g_list_remove(chrc->service->chrcs, chrc);
chrc_unregister(chrc);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static DBusMessage *desc_read_value(DBusConnection *conn, DBusMessage *msg,
@@ -1859,14 +1892,14 @@ void gatt_register_desc(DBusConnection *conn, GDBusProxy *proxy,
if (!local_services) {
bt_shell_printf("No service registered\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
service = g_list_last(local_services)->data;
if (!service->chrcs) {
bt_shell_printf("No characteristic registered\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
desc = g_new0(struct desc, 1);
@@ -1880,7 +1913,7 @@ void gatt_register_desc(DBusConnection *conn, GDBusProxy *proxy,
desc, desc_free) == FALSE) {
bt_shell_printf("Failed to register descriptor object\n");
desc_free(desc);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
desc->chrc->descs = g_list_append(desc->chrc->descs, desc);
@@ -1888,6 +1921,8 @@ void gatt_register_desc(DBusConnection *conn, GDBusProxy *proxy,
print_desc(desc, COLORED_NEW);
bt_shell_prompt_input(desc->path, "Enter value:", desc_set_value, desc);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct desc *desc_find(const char *pattern)
@@ -1928,10 +1963,12 @@ void gatt_unregister_desc(DBusConnection *conn, GDBusProxy *proxy,
desc = desc_find(argv[1]);
if (!desc) {
bt_shell_printf("Failed to unregister descriptor object\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
desc->chrc->descs = g_list_remove(desc->chrc->descs, desc);
desc_unregister(desc);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
diff --git a/client/main.c b/client/main.c
index 962f3383b..85c1889fd 100644
--- a/client/main.c
+++ b/client/main.c
@@ -827,6 +827,8 @@ static void cmd_list(int argc, char *argv[])
struct adapter *adapter = list->data;
print_adapter(adapter->proxy, NULL);
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_show(int argc, char *argv[])
@@ -852,7 +854,7 @@ static void cmd_show(int argc, char *argv[])
}
if (g_dbus_proxy_get_property(proxy, "Address", &iter) == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
dbus_message_iter_get_basic(&iter, &address);
@@ -875,6 +877,8 @@ static void cmd_show(int argc, char *argv[])
print_uuids(proxy);
print_property(proxy, "Modalias");
print_property(proxy, "Discovering");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_select(int argc, char *argv[])
@@ -884,14 +888,16 @@ static void cmd_select(int argc, char *argv[])
adapter = find_ctrl_by_address(ctrl_list, argv[1]);
if (!adapter) {
bt_shell_printf("Controller %s not available\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (default_ctrl && default_ctrl->proxy == adapter->proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default_ctrl = adapter;
print_adapter(adapter->proxy, NULL);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_devices(int argc, char *argv[])
@@ -899,13 +905,15 @@ static void cmd_devices(int argc, char *argv[])
GList *ll;
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
for (ll = g_list_first(default_ctrl->devices);
ll; ll = g_list_next(ll)) {
GDBusProxy *proxy = ll->data;
print_device(proxy, NULL);
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_paired_devices(int argc, char *argv[])
@@ -913,7 +921,7 @@ static void cmd_paired_devices(int argc, char *argv[])
GList *ll;
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
for (ll = g_list_first(default_ctrl->devices);
ll; ll = g_list_next(ll)) {
@@ -930,16 +938,21 @@ static void cmd_paired_devices(int argc, char *argv[])
print_device(proxy, NULL);
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void generic_callback(const DBusError *error, void *user_data)
{
char *str = user_data;
- if (dbus_error_is_set(error))
+ if (dbus_error_is_set(error)) {
bt_shell_printf("Failed to set %s: %s\n", str, error->name);
- else
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ } else {
bt_shell_printf("Changing %s succeeded\n", str);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+ }
}
static void cmd_system_alias(int argc, char *argv[])
@@ -1016,6 +1029,8 @@ static void cmd_pairable(int argc, char *argv[])
return;
g_free(str);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_discoverable(int argc, char *argv[])
@@ -1038,6 +1053,8 @@ static void cmd_discoverable(int argc, char *argv[])
return;
g_free(str);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_agent(int argc, char *argv[])
@@ -1047,7 +1064,7 @@ static void cmd_agent(int argc, char *argv[])
if (!parse_argument(argc, argv, agent_arguments, "capability",
&enable, &capability))
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (enable == TRUE) {
g_free(auto_register_agent);
@@ -1067,6 +1084,8 @@ static void cmd_agent(int argc, char *argv[])
else
bt_shell_printf("Agent registration disabled\n");
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_default_agent(int argc, char *argv[])
@@ -1085,10 +1104,11 @@ static void start_discovery_reply(DBusMessage *message, void *user_data)
bt_shell_printf("Failed to %s discovery: %s\n",
enable == TRUE ? "start" : "stop", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
- bt_shell_printf("Discovery %s\n", enable == TRUE ? "started" : "stopped");
+ bt_shell_printf("Discovery %s\n", enable ? "started" : "stopped");
+ /* Leave the discovery running even on noninteractive mode */
}
static void append_variant(DBusMessageIter *iter, int type, void *val)
@@ -1235,12 +1255,14 @@ static void set_discovery_filter_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("SetDiscoveryFilter failed: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
filter.set = true;
bt_shell_printf("SetDiscoveryFilter success\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void set_discovery_filter(void)
@@ -1252,7 +1274,7 @@ static void set_discovery_filter(void)
set_discovery_filter_setup, set_discovery_filter_reply,
&filter, NULL) == FALSE) {
bt_shell_printf("Failed to set discovery filter\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
filter.set = true;
@@ -1280,7 +1302,7 @@ static void cmd_scan(int argc, char *argv[])
GUINT_TO_POINTER(enable), NULL) == FALSE) {
bt_shell_printf("Failed to %s discovery\n",
enable == TRUE ? "start" : "stop");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1305,7 +1327,7 @@ static void cmd_scan_filter_uuids(int argc, char *argv[])
filter.uuids = g_strdupv(&argv[1]);
if (!filter.uuids) {
bt_shell_printf("Failed to parse input\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
filter.uuids_len = g_strv_length(filter.uuids);
@@ -1515,10 +1537,10 @@ static void cmd_info(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (g_dbus_proxy_get_property(proxy, "Address", &iter) == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
dbus_message_iter_get_basic(&iter, &address);
@@ -1548,6 +1570,8 @@ static void cmd_info(int argc, char *argv[])
print_property(proxy, "ServiceData");
print_property(proxy, "RSSI");
print_property(proxy, "TxPower");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void pair_reply(DBusMessage *message, void *user_data)
@@ -1559,10 +1583,12 @@ static void pair_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to pair: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Pairing successful\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_pair(int argc, char *argv[])
@@ -1571,12 +1597,12 @@ static void cmd_pair(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (g_dbus_proxy_method_call(proxy, "Pair", NULL, pair_reply,
NULL, NULL) == FALSE) {
bt_shell_printf("Failed to pair\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Attempting to pair with %s\n", argv[1]);
@@ -1590,7 +1616,7 @@ static void cmd_trust(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
trusted = TRUE;
@@ -1602,6 +1628,8 @@ static void cmd_trust(int argc, char *argv[])
return;
g_free(str);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_untrust(int argc, char *argv[])
@@ -1612,7 +1640,7 @@ static void cmd_untrust(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
trusted = FALSE;
@@ -1624,6 +1652,8 @@ static void cmd_untrust(int argc, char *argv[])
return;
g_free(str);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_block(int argc, char *argv[])
@@ -1634,7 +1664,7 @@ static void cmd_block(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
blocked = TRUE;
@@ -1646,6 +1676,8 @@ static void cmd_block(int argc, char *argv[])
return;
g_free(str);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_unblock(int argc, char *argv[])
@@ -1656,7 +1688,7 @@ static void cmd_unblock(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
blocked = FALSE;
@@ -1668,6 +1700,8 @@ static void cmd_unblock(int argc, char *argv[])
return;
g_free(str);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void remove_device_reply(DBusMessage *message, void *user_data)
@@ -1679,10 +1713,11 @@ static void remove_device_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to remove device: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Device has been removed\n");
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void remove_device_setup(DBusMessageIter *iter, void *user_data)
@@ -1707,6 +1742,7 @@ static void remove_device(GDBusProxy *proxy)
path, g_free) == FALSE) {
bt_shell_printf("Failed to remove device\n");
g_free(path);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1748,12 +1784,13 @@ static void connect_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to connect: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Connection successful\n");
set_default_device(proxy, NULL);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_connect(int argc, char *argv[])
@@ -1766,13 +1803,13 @@ static void cmd_connect(int argc, char *argv[])
proxy = find_proxy_by_address(default_ctrl->devices, argv[1]);
if (!proxy) {
bt_shell_printf("Device %s not available\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (g_dbus_proxy_method_call(proxy, "Connect", NULL, connect_reply,
proxy, NULL) == FALSE) {
bt_shell_printf("Failed to connect\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Attempting to connect to %s\n", argv[1]);
@@ -1788,7 +1825,7 @@ static void disconn_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == TRUE) {
bt_shell_printf("Failed to disconnect: %s\n", error.name);
dbus_error_free(&error);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Successful disconnected\n");
@@ -1797,6 +1834,8 @@ static void disconn_reply(DBusMessage *message, void *user_data)
return;
set_default_device(NULL, NULL);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_disconn(int argc, char *argv[])
@@ -1810,7 +1849,7 @@ static void cmd_disconn(int argc, char *argv[])
if (g_dbus_proxy_method_call(proxy, "Disconnect", NULL, disconn_reply,
proxy, NULL) == FALSE) {
bt_shell_printf("Failed to disconnect\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (argc < 2 || strlen(argv[1]) == 0) {
@@ -1831,9 +1870,11 @@ static void cmd_list_attributes(int argc, char *argv[])
proxy = find_device(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_list_attributes(g_dbus_proxy_get_path(proxy));
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_set_alias(int argc, char *argv[])
@@ -1853,6 +1894,8 @@ static void cmd_set_alias(int argc, char *argv[])
return;
g_free(name);
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static void cmd_select_attribute(int argc, char *argv[])
@@ -1865,8 +1908,12 @@ static void cmd_select_attribute(int argc, char *argv[])
}
proxy = gatt_select_attribute(default_attr, argv[1]);
- if (proxy)
+ if (proxy) {
set_default_attribute(proxy);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
static struct GDBusProxy *find_attribute(int argc, char *argv[])
@@ -1897,10 +1944,10 @@ static void cmd_attribute_info(int argc, char *argv[])
proxy = find_attribute(argc, argv);
if (!proxy)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (g_dbus_proxy_get_property(proxy, "UUID", &iter) == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
dbus_message_iter_get_basic(&iter, &uuid);
@@ -1932,13 +1979,15 @@ static void cmd_attribute_info(int argc, char *argv[])
print_property(proxy, "Characteristic");
print_property(proxy, "Value");
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_read(int argc, char *argv[])
{
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_read_attribute(default_attr);
@@ -1948,7 +1997,7 @@ static void cmd_write(int argc, char *argv[])
{
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_write_attribute(default_attr, argv[1]);
@@ -1958,7 +2007,7 @@ static void cmd_acquire_write(int argc, char *argv[])
{
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_acquire_write(default_attr, argv[1]);
@@ -1968,7 +2017,7 @@ static void cmd_release_write(int argc, char *argv[])
{
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_release_write(default_attr, argv[1]);
@@ -1978,7 +2027,7 @@ static void cmd_acquire_notify(int argc, char *argv[])
{
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_acquire_notify(default_attr, argv[1]);
@@ -1988,7 +2037,7 @@ static void cmd_release_notify(int argc, char *argv[])
{
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_release_notify(default_attr, argv[1]);
@@ -2003,7 +2052,7 @@ static void cmd_notify(int argc, char *argv[])
if (!default_attr) {
bt_shell_printf("No attribute selected\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
gatt_notify_attribute(default_attr, enable ? true : false);
@@ -2012,7 +2061,7 @@ static void cmd_notify(int argc, char *argv[])
static void cmd_register_app(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_register_app(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2020,7 +2069,7 @@ static void cmd_register_app(int argc, char *argv[])
static void cmd_unregister_app(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_unregister_app(dbus_conn, default_ctrl->proxy);
}
@@ -2028,7 +2077,7 @@ static void cmd_unregister_app(int argc, char *argv[])
static void cmd_register_service(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_register_service(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2036,7 +2085,7 @@ static void cmd_register_service(int argc, char *argv[])
static void cmd_unregister_service(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_unregister_service(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2044,7 +2093,7 @@ static void cmd_unregister_service(int argc, char *argv[])
static void cmd_register_characteristic(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_register_chrc(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2052,7 +2101,7 @@ static void cmd_register_characteristic(int argc, char *argv[])
static void cmd_unregister_characteristic(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_unregister_chrc(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2060,7 +2109,7 @@ static void cmd_unregister_characteristic(int argc, char *argv[])
static void cmd_register_descriptor(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_register_desc(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2068,7 +2117,7 @@ static void cmd_register_descriptor(int argc, char *argv[])
static void cmd_unregister_descriptor(int argc, char *argv[])
{
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
gatt_unregister_desc(dbus_conn, default_ctrl->proxy, argc, argv);
}
@@ -2184,7 +2233,7 @@ static void cmd_advertise(int argc, char *argv[])
if (!default_ctrl || !default_ctrl->ad_proxy) {
bt_shell_printf("LEAdvertisingManager not found\n");
- return;
+ bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (enable == TRUE)
@@ -2271,7 +2320,7 @@ static void cmd_advertise_appearance(int argc, char *argv[])
value = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
bt_shell_printf("Invalid argument\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ad_advertise_local_appearance(dbus_conn, &value);
@@ -2290,7 +2339,7 @@ static void cmd_advertise_duration(int argc, char *argv[])
value = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
bt_shell_printf("Invalid argument\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ad_advertise_duration(dbus_conn, &value);
@@ -2309,7 +2358,7 @@ static void cmd_advertise_timeout(int argc, char *argv[])
value = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
bt_shell_printf("Invalid argument\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ad_advertise_timeout(dbus_conn, &value);
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 12/14] shared/shell: Add bt_shell_usage
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (10 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 11/14] client: Call bt_shell_noninteractive_quit when done with command Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 13/14] shared/shell: Fix parsing of mandatory arguments Luiz Augusto von Dentz
2018-02-28 16:09 ` [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
bt_shell_usage can be used to print the usage of the current command
in execution.
---
src/shared/shell.c | 14 ++++++++++++++
src/shared/shell.h | 1 +
2 files changed, 15 insertions(+)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index cd46532fe..c90d28a9f 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -76,6 +76,7 @@ static struct {
const struct bt_shell_menu *menu;
const struct bt_shell_menu *main;
struct queue *submenus;
+ const struct bt_shell_menu_entry *exec;
struct queue *envs;
} data;
@@ -325,9 +326,13 @@ optional:
wordfree(&w);
exec:
+ data.exec = entry;
+
if (entry->func)
entry->func(argc, argv);
+ data.exec = NULL;
+
return 0;
fail:
@@ -451,6 +456,15 @@ void bt_shell_hexdump(const unsigned char *buf, size_t len)
util_hexdump(' ', buf, len, print_string, NULL);
}
+void bt_shell_usage()
+{
+ if (!data.exec)
+ return;
+
+ bt_shell_printf("Usage: %s %s\n", data.exec->cmd,
+ data.exec->arg ? data.exec->arg : "");
+}
+
void bt_shell_prompt_input(const char *label, const char *msg,
bt_shell_prompt_input_func func, void *user_data)
{
diff --git a/src/shared/shell.h b/src/shared/shell.h
index 10747c955..33c31f35b 100644
--- a/src/shared/shell.h
+++ b/src/shared/shell.h
@@ -82,6 +82,7 @@ void bt_shell_set_prompt(const char *string);
void bt_shell_printf(const char *fmt,
...) __attribute__((format(printf, 1, 2)));
void bt_shell_hexdump(const unsigned char *buf, size_t len);
+void bt_shell_usage(void);
void bt_shell_prompt_input(const char *label, const char *msg,
bt_shell_prompt_input_func func, void *user_data);
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH BlueZ 13/14] shared/shell: Fix parsing of mandatory arguments
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (11 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 12/14] shared/shell: Add bt_shell_usage Luiz Augusto von Dentz
@ 2018-02-26 15:53 ` Luiz Augusto von Dentz
2018-02-28 16:09 ` [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-26 15:53 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
In certain cases the arguments may no start with the mandatory commands
such as when the command handler expects getopt arguments first.
---
src/shared/shell.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/shared/shell.c b/src/shared/shell.c
index c90d28a9f..9ae5af79e 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -291,11 +291,22 @@ static int cmd_exec(const struct bt_shell_menu_entry *entry,
}
len = man - entry->arg;
- man = strndup(entry->arg, len + 1);
+ if (entry->arg[0] == '<')
+ man = strndup(entry->arg, len + 1);
+ else {
+ /* Find where mandatory arguments start */
+ opt = strrchr(entry->arg, '<');
+ /* Skip if mandatory arguments are not in the right format */
+ if (!opt || opt > man) {
+ opt = strdup(entry->arg);
+ goto optional;
+ }
+ man = strndup(opt, man - opt + 1);
+ }
if (parse_args(man, &w, "<>", flags) < 0) {
print_text(COLOR_HIGHLIGHT,
- "Unable to parse mandatory command arguments");
+ "Unable to parse mandatory command arguments: %s", man );
return -EINVAL;
}
@@ -312,7 +323,7 @@ static int cmd_exec(const struct bt_shell_menu_entry *entry,
optional:
if (parse_args(opt, &w, "[]", flags) < 0) {
print_text(COLOR_HIGHLIGHT,
- "Unable to parse optional command arguments");
+ "Unable to parse optional command arguments: %s", opt);
return -EINVAL;
}
--
2.14.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
` (12 preceding siblings ...)
2018-02-26 15:53 ` [PATCH BlueZ 13/14] shared/shell: Fix parsing of mandatory arguments Luiz Augusto von Dentz
@ 2018-02-28 16:09 ` Luiz Augusto von Dentz
13 siblings, 0 replies; 15+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-28 16:09 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
Hi,
On Mon, Feb 26, 2018 at 5:53 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds functionally to bt_shell to properly handle non-interactive
> mode making all command line tools handle commands given as argument:
>
>>./bluetoothctl power on
> [CHG] Controller B8:8A:60:D8:17:D7 Class: 0x002c010c
> Changing power on succeded
>
> While on non-interactive mode readline will not be used and only the
> command line arguments will be processed, in addition to that there
> is now bt_shell_noninteractive_quit which shall be used by the command
> handler to quit when it is done with the command execution.
>
> Luiz Augusto von Dentz (14):
> shared/shell: Add bt_shell_{noninteractive_}quit
> shared/shell: Fix not reseting optind
> shared/shell: Fix timeout parameter
> shared/shell: Do not quit immediatelly on noninteractive mode
> shared/shell: Fix not handling sort options
> shared/shell: Disable bt_shell_prompt_input in noninteractive mode
> shared/shell: Disable readline while in noninteractive mode
> sharead/mainloop-glib: Fix mainloop_exit*
> shared/mainloop-glib: Fix calling g_main_loop_quit with NULL
> shared/shell: Allow executing submenu commands
> client: Call bt_shell_noninteractive_quit when done with command
> shared/shell: Add bt_shell_usage
> shared/shell: Fix parsing of mandatory arguments
> tools/btmgmt: Port to use bt_shell
>
> client/advertising.c | 84 ++-
> client/gatt.c | 113 ++--
> client/main.c | 153 +++--
> src/shared/mainloop-glib.c | 5 +
> src/shared/shell.c | 130 +++-
> src/shared/shell.h | 4 +
> tools/btmgmt.c | 1560 ++++++++++++++++----------------------------
> 7 files changed, 905 insertions(+), 1144 deletions(-)
Applied.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2018-02-28 16:09 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-26 15:53 [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 01/14] shared/shell: Add bt_shell_{noninteractive_}quit Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 02/14] shared/shell: Fix not reseting optind Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 03/14] shared/shell: Fix timeout parameter Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 04/14] shared/shell: Do not quit immediatelly on noninteractive mode Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 05/14] shared/shell: Fix not handling sort options Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 06/14] shared/shell: Disable bt_shell_prompt_input in noninteractive mode Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 07/14] shared/shell: Disable readline while " Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 08/14] sharead/mainloop-glib: Fix mainloop_exit* Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 09/14] shared/mainloop-glib: Fix calling g_main_loop_quit with NULL Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 10/14] shared/shell: Allow executing submenu commands Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 11/14] client: Call bt_shell_noninteractive_quit when done with command Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 12/14] shared/shell: Add bt_shell_usage Luiz Augusto von Dentz
2018-02-26 15:53 ` [PATCH BlueZ 13/14] shared/shell: Fix parsing of mandatory arguments Luiz Augusto von Dentz
2018-02-28 16:09 ` [PATCH BlueZ 00/14] shared/shell: Add proper support for non-interactive mode Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).