summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPyun DoHyun <dh79.pyun@samsung.com>2018-05-18 03:01:11 +0000
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>2018-05-18 03:01:11 +0000
commitfd8e51badb18555cc2ff5980844af5cef087e43c (patch)
tree675d3baff345d8a0b3929d6f2e8fc288d805d506
parent709dda0ace16b10d164c84899c7489986e42b454 (diff)
parentc5f8c8712d47efc3903ba2a04af2299388ccf46e (diff)
downloadbluez-fd8e51badb18555cc2ff5980844af5cef087e43c.tar.gz
bluez-fd8e51badb18555cc2ff5980844af5cef087e43c.tar.bz2
bluez-fd8e51badb18555cc2ff5980844af5cef087e43c.zip
Merge "Import meshctl & bt-shell related apis and fixes" into tizen
-rwxr-xr-xMakefile.am9
-rwxr-xr-xMakefile.tools32
-rw-r--r--client/advertising.c164
-rwxr-xr-xclient/advertising.h8
-rwxr-xr-xclient/gatt.c57
-rw-r--r--client/main.c88
-rwxr-xr-xgdbus/client.c177
-rwxr-xr-xgdbus/gdbus.h13
-rw-r--r--mesh/config-client.c547
-rw-r--r--mesh/config-server.c3
-rw-r--r--mesh/gatt.c16
-rw-r--r--mesh/main.c246
-rw-r--r--mesh/node.c24
-rw-r--r--mesh/node.h2
-rw-r--r--mesh/onoff-model.c30
-rw-r--r--mesh/prov-db.c89
-rw-r--r--mesh/prov-db.h2
-rw-r--r--src/adapter.c6
-rw-r--r--src/device.c25
-rwxr-xr-xsrc/shared/ecc.c101
-rwxr-xr-xsrc/shared/ecc.h27
-rw-r--r--src/shared/mainloop-glib.c117
-rwxr-xr-xsrc/shared/mainloop.c4
-rwxr-xr-xsrc/shared/queue.c5
-rw-r--r--src/shared/shell.c530
-rw-r--r--src/shared/shell.h9
-rwxr-xr-xsrc/shared/util.c45
-rwxr-xr-xsrc/shared/util.h3
-rwxr-xr-xtools/bluetooth-player.c98
-rwxr-xr-xtools/btmgmt.c1532
-rwxr-xr-xtools/obexctl.c212
-rwxr-xr-xunit/test-ecc.c39
32 files changed, 2413 insertions, 1847 deletions
diff --git a/Makefile.am b/Makefile.am
index b2c6b87b..f07ef83b 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,11 +119,16 @@ shared_sources = src/shared/io.h src/shared/timeout.h \
src/shared/gatt-server.h src/shared/gatt-server.c \
src/shared/gatt-db.h src/shared/gatt-db.c \
src/shared/gap.h src/shared/gap.c \
- src/shared/tty.h src/shared/shell.c src/shared/shell.h
+ src/shared/tty.h
+
+if READLINE
+shared_sources += src/shared/shell.c src/shared/shell.h
+endif
src_libshared_glib_la_SOURCES = $(shared_sources) \
src/shared/io-glib.c \
- src/shared/timeout-glib.c
+ src/shared/timeout-glib.c \
+ src/shared/mainloop-glib.c
src_libshared_mainloop_la_SOURCES = $(shared_sources) \
src/shared/io-mainloop.c \
diff --git a/Makefile.tools b/Makefile.tools
index ae448d2b..08e1efaf 100755
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -17,24 +17,26 @@ if MESH
bin_PROGRAMS += mesh/meshctl
mesh_meshctl_SOURCES = mesh/main.c \
- mesh/mesh-net.h \
- mesh/node.h mesh/node.c \
- mesh/gatt.h mesh/gatt.c \
- mesh/crypto.h mesh/crypto.c \
- mesh/keys.h \
- mesh/net.h mesh/net.c \
- mesh/prov.h mesh/prov.c \
- mesh/util.h mesh/util.c \
- mesh/agent.h mesh/agent.c \
- mesh/prov-db.h mesh/prov-db.c \
- mesh/config-model.h mesh/config-client.c \
- mesh/config-server.c \
- mesh/onoff-model.h mesh/onoff-model.c
+ mesh/mesh-net.h \
+ mesh/node.h mesh/node.c \
+ mesh/gatt.h mesh/gatt.c \
+ mesh/crypto.h mesh/crypto.c \
+ mesh/keys.h \
+ mesh/net.h mesh/net.c \
+ mesh/prov.h mesh/prov.c \
+ mesh/util.h mesh/util.c \
+ mesh/agent.h mesh/agent.c \
+ mesh/prov-db.h mesh/prov-db.c \
+ mesh/config-model.h mesh/config-client.c \
+ mesh/config-server.c \
+ mesh/onoff-model.h mesh/onoff-model.c
mesh_meshctl_LDADD = gdbus/libgdbus-internal.la src/libshared-glib.la \
- lib/libbluetooth-internal.la \
- @GLIB_LIBS@ @DBUS_LIBS@ -ljson-c -lreadline
+ lib/libbluetooth-internal.la \
+ @GLIB_LIBS@ @DBUS_LIBS@ -ljson-c -lreadline
endif
+EXTRA_DIST += mesh/local_node.json mesh/prov_db.json
+
if MONITOR
bin_PROGRAMS += monitor/btmon
diff --git a/client/advertising.c b/client/advertising.c
index 5ca45998..9b1df12d 100644
--- a/client/advertising.c
+++ b/client/advertising.c
@@ -32,6 +32,7 @@
#include <string.h>
#include "gdbus/gdbus.h"
+#include "src/shared/util.h"
#include "src/shared/shell.h"
#include "advertising.h"
@@ -107,6 +108,77 @@ static void register_setup(DBusMessageIter *iter, void *user_data)
dbus_message_iter_close_container(iter, &dict);
}
+static void print_uuid(const char *uuid)
+{
+ const char *text;
+
+ text = bt_uuidstr_to_str(uuid);
+ if (text) {
+ char str[26];
+ unsigned int n;
+
+ str[sizeof(str) - 1] = '\0';
+
+ n = snprintf(str, sizeof(str), "%s", text);
+ if (n > sizeof(str) - 1) {
+ str[sizeof(str) - 2] = '.';
+ str[sizeof(str) - 3] = '.';
+ if (str[sizeof(str) - 4] == ' ')
+ str[sizeof(str) - 4] = '.';
+
+ n = sizeof(str) - 1;
+ }
+
+ bt_shell_printf("UUID: %s(%s)\n", str, uuid);
+ } else
+ bt_shell_printf("UUID: (%s)\n", uuid);
+}
+
+static void print_ad_uuids(void)
+{
+ char **uuid;
+
+ for (uuid = ad.uuids; uuid && *uuid; uuid++)
+ print_uuid(*uuid);
+}
+
+static void print_ad(void)
+{
+ print_ad_uuids();
+
+ if (ad.service.uuid) {
+ print_uuid(ad.service.uuid);
+ bt_shell_hexdump(ad.service.data.data, ad.service.data.len);
+ }
+
+ if (ad.manufacturer.data.len) {
+ bt_shell_printf("Manufacturer: %u\n", ad.manufacturer.id);
+ bt_shell_hexdump(ad.manufacturer.data.data,
+ ad.manufacturer.data.len);
+ }
+
+ bt_shell_printf("Tx Power: %s\n", ad.tx_power ? "on" : "off");
+
+ if (ad.local_name)
+ bt_shell_printf("LocalName: %s\n", ad.local_name);
+ else
+ bt_shell_printf("Name: %s\n", ad.name ? "on" : "off");
+
+ if (ad.local_appearance != UINT16_MAX)
+ bt_shell_printf("Appearance: %s (0x%04x)\n",
+ bt_appear_to_str(ad.local_appearance),
+ ad.local_appearance);
+ else
+ bt_shell_printf("Apperance: %s\n",
+ ad.appearance ? "on" : "off");
+
+ if (ad.duration)
+ bt_shell_printf("Duration: %u sec\n", ad.duration);
+
+ if (ad.timeout)
+ bt_shell_printf("Timeout: %u sec\n", ad.timeout);
+}
+
static void register_reply(DBusMessage *message, void *user_data)
{
DBusConnection *conn = user_data;
@@ -117,6 +189,7 @@ static void register_reply(DBusMessage *message, void *user_data)
if (dbus_set_error_from_message(&error, message) == FALSE) {
ad.registered = true;
bt_shell_printf("Advertising object registered\n");
+ print_ad();
} else {
bt_shell_printf("Failed to register advertisement: %s\n", error.name);
dbus_error_free(&error);
@@ -436,13 +509,15 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager)
void ad_advertise_uuids(DBusConnection *conn, int argc, char *argv[])
{
+ if (argc < 2 || !strlen(argv[1])) {
+ print_ad_uuids();
+ return;
+ }
+
g_strfreev(ad.uuids);
ad.uuids = NULL;
ad.uuids_len = 0;
- if (argc < 2 || !strlen(argv[1]))
- return;
-
ad.uuids = g_strdupv(&argv[1]);
if (!ad.uuids) {
bt_shell_printf("Failed to parse input\n");
@@ -465,15 +540,16 @@ void ad_advertise_service(DBusConnection *conn, int argc, char *argv[])
unsigned int i;
struct ad_data *data;
- ad_clear_service();
-
- if (argc < 2)
+ if (argc < 2 || !strlen(argv[1])) {
+ print_uuid(ad.service.uuid);
+ bt_shell_hexdump(ad.service.data.data, ad.service.data.len);
return;
+ }
ad.service.uuid = g_strdup(argv[1]);
data = &ad.service.data;
- for (i = 1; i < (unsigned int) argc; i++) {
+ for (i = 2; i < (unsigned int) argc; i++) {
long int val;
char *endptr = NULL;
@@ -509,10 +585,18 @@ void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
long int val;
struct ad_data *data;
- ad_clear_manufacturer();
+ if (argc < 2 || !strlen(argv[1])) {
+ if (ad.manufacturer.data.len) {
+ bt_shell_printf("Manufacturer: %u\n",
+ ad.manufacturer.id);
+ bt_shell_hexdump(ad.manufacturer.data.data,
+ ad.manufacturer.data.len);
+ }
- if (argc < 2)
return;
+ }
+
+ ad_clear_manufacturer();
val = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT16_MAX) {
@@ -545,12 +629,17 @@ void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[])
"ManufacturerData");
}
-void ad_advertise_tx_power(DBusConnection *conn, bool value)
+void ad_advertise_tx_power(DBusConnection *conn, dbus_bool_t *value)
{
- if (ad.tx_power == value)
+ if (!value) {
+ bt_shell_printf("Tx Power: %s\n", ad.tx_power ? "on" : "off");
+ return;
+ }
+
+ if (ad.tx_power == *value)
return;
- ad.tx_power = value;
+ ad.tx_power = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Includes");
}
@@ -572,6 +661,15 @@ void ad_advertise_name(DBusConnection *conn, bool value)
void ad_advertise_local_name(DBusConnection *conn, const char *name)
{
+ if (!name) {
+ if (ad.local_name)
+ bt_shell_printf("LocalName: %s\n", ad.local_name);
+ else
+ bt_shell_printf("Name: %s\n", ad.name ? "on" : "off");
+
+ return;
+ }
+
if (ad.local_name && !strcmp(name, ad.local_name))
return;
@@ -594,32 +692,56 @@ void ad_advertise_appearance(DBusConnection *conn, bool value)
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Includes");
}
-void ad_advertise_local_appearance(DBusConnection *conn, uint16_t value)
+void ad_advertise_local_appearance(DBusConnection *conn, long int *value)
{
- if (ad.local_appearance == value)
+ if (!value) {
+ if (ad.local_appearance != UINT16_MAX)
+ bt_shell_printf("Appearance: %s (0x%04x)\n",
+ bt_appear_to_str(ad.local_appearance),
+ ad.local_appearance);
+ else
+ bt_shell_printf("Apperance: %s\n",
+ ad.appearance ? "on" : "off");
+
return;
+ }
- ad.local_appearance = value;
+ if (ad.local_appearance == *value)
+ return;
+
+ ad.local_appearance = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Appearance");
}
-void ad_advertise_duration(DBusConnection *conn, uint16_t value)
+void ad_advertise_duration(DBusConnection *conn, long int *value)
{
- if (ad.duration == value)
+ if (!value) {
+ if (ad.duration)
+ bt_shell_printf("Duration: %u sec\n", ad.duration);
+ return;
+ }
+
+ if (ad.duration == *value)
return;
- ad.duration = value;
+ ad.duration = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Duration");
}
-void ad_advertise_timeout(DBusConnection *conn, uint16_t value)
+void ad_advertise_timeout(DBusConnection *conn, long int *value)
{
- if (ad.timeout == value)
+ if (!value) {
+ if (ad.timeout)
+ bt_shell_printf("Timeout: %u sec\n", ad.timeout);
+ return;
+ }
+
+ if (ad.timeout == *value)
return;
- ad.timeout = value;
+ ad.timeout = *value;
g_dbus_emit_property_changed(conn, AD_PATH, AD_IFACE, "Timeout");
}
diff --git a/client/advertising.h b/client/advertising.h
index d7472e1a..13e07643 100755
--- a/client/advertising.h
+++ b/client/advertising.h
@@ -27,10 +27,10 @@ void ad_unregister(DBusConnection *conn, GDBusProxy *manager);
void ad_advertise_uuids(DBusConnection *conn, int argc, char *argv[]);
void ad_advertise_service(DBusConnection *conn, int argc, char *argv[]);
void ad_advertise_manufacturer(DBusConnection *conn, int argc, char *argv[]);
-void ad_advertise_tx_power(DBusConnection *conn, bool value);
+void ad_advertise_tx_power(DBusConnection *conn, dbus_bool_t *value);
void ad_advertise_name(DBusConnection *conn, bool value);
void ad_advertise_appearance(DBusConnection *conn, bool value);
void ad_advertise_local_name(DBusConnection *conn, const char *name);
-void ad_advertise_local_appearance(DBusConnection *conn, uint16_t value);
-void ad_advertise_duration(DBusConnection *conn, uint16_t value);
-void ad_advertise_timeout(DBusConnection *conn, uint16_t value);
+void ad_advertise_local_appearance(DBusConnection *conn, long int *value);
+void ad_advertise_duration(DBusConnection *conn, long int *value);
+void ad_advertise_timeout(DBusConnection *conn, long int *value);
diff --git a/client/gatt.c b/client/gatt.c
index 224a78a1..4d51e053 100755
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -206,25 +206,16 @@ static void print_characteristic(GDBusProxy *proxy, const char *description)
static gboolean chrc_is_child(GDBusProxy *characteristic)
{
- GList *l;
DBusMessageIter iter;
- const char *service, *path;
+ const char *service;
if (!g_dbus_proxy_get_property(characteristic, "Service", &iter))
return FALSE;
dbus_message_iter_get_basic(&iter, &service);
- for (l = services; l; l = g_list_next(l)) {
- GDBusProxy *proxy = l->data;
-
- path = g_dbus_proxy_get_path(proxy);
-
- if (!strcmp(path, service))
- return TRUE;
- }
-
- return FALSE;
+ return g_dbus_proxy_lookup(services, NULL, service,
+ "org.bluez.GattService1") != NULL;
}
void gatt_add_characteristic(GDBusProxy *proxy)
@@ -378,33 +369,22 @@ void gatt_list_attributes(const char *path)
list_attributes(path, services);
}
-static GDBusProxy *select_proxy(const char *path, GList *source)
-{
- GList *l;
-
- for (l = source; l; l = g_list_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static GDBusProxy *select_attribute(const char *path)
{
GDBusProxy *proxy;
- proxy = select_proxy(path, services);
+ proxy = g_dbus_proxy_lookup(services, NULL, path,
+ "org.bluez.GattService1");
if (proxy)
return proxy;
- proxy = select_proxy(path, characteristics);
+ proxy = g_dbus_proxy_lookup(characteristics, NULL, path,
+ "org.bluez.GattCharacteristic1");
if (proxy)
return proxy;
- return select_proxy(path, descriptors);
+ return g_dbus_proxy_lookup(descriptors, NULL, path,
+ "org.bluez.GattDescriptor1");
}
static GDBusProxy *select_proxy_by_uuid(GDBusProxy *parent, const char *uuid,
@@ -465,28 +445,13 @@ GDBusProxy *gatt_select_attribute(GDBusProxy *parent, const char *arg)
static char *attribute_generator(const char *text, int state, GList *source)
{
- static int index, len;
- GList *list;
+ static int index;
if (!state) {
index = 0;
- len = strlen(text);
}
- for (list = g_list_nth(source, index); list;
- list = g_list_next(list)) {
- GDBusProxy *proxy = list->data;
- const char *path;
-
- index++;
-
- path = g_dbus_proxy_get_path(proxy);
-
- if (!strncmp(path, text, len))
- return strdup(path);
- }
-
- return NULL;
+ return g_dbus_proxy_path_lookup(source, &index, text);
}
char *gatt_attribute_generator(const char *text, int state)
diff --git a/client/main.c b/client/main.c
index 17a92fda..1a0a7c1e 100644
--- a/client/main.c
+++ b/client/main.c
@@ -392,9 +392,8 @@ static gboolean device_is_child(GDBusProxy *device, GDBusProxy *master)
static gboolean service_is_child(GDBusProxy *service)
{
- GList *l;
DBusMessageIter iter;
- const char *device, *path;
+ const char *device;
if (g_dbus_proxy_get_property(service, "Device", &iter) == FALSE)
return FALSE;
@@ -404,16 +403,8 @@ static gboolean service_is_child(GDBusProxy *service)
if (!default_ctrl)
return FALSE;
- for (l = default_ctrl->devices; l; l = g_list_next(l)) {
- struct GDBusProxy *proxy = l->data;
-
- path = g_dbus_proxy_get_path(proxy);
-
- if (!strcmp(path, device))
- return TRUE;
- }
-
- return FALSE;
+ return g_dbus_proxy_lookup(default_ctrl->devices, NULL, device,
+ "org.bluez.Device1") != NULL;
}
static struct adapter *find_parent(GDBusProxy *device)
@@ -2206,33 +2197,43 @@ static char *ad_generator(const char *text, int state)
return argument_generator(text, state, ad_arguments);
}
-static void cmd_set_advertise_uuids(int argc, char *argv[])
+static void cmd_advertise_uuids(int argc, char *argv[])
{
ad_advertise_uuids(dbus_conn, argc, argv);
}
-static void cmd_set_advertise_service(int argc, char *argv[])
+static void cmd_advertise_service(int argc, char *argv[])
{
ad_advertise_service(dbus_conn, argc, argv);
}
-static void cmd_set_advertise_manufacturer(int argc, char *argv[])
+static void cmd_advertise_manufacturer(int argc, char *argv[])
{
ad_advertise_manufacturer(dbus_conn, argc, argv);
}
-static void cmd_set_advertise_tx_power(int argc, char *argv[])
+static void cmd_advertise_tx_power(int argc, char *argv[])
{
dbus_bool_t powered;
+ if (argc < 2) {
+ ad_advertise_tx_power(dbus_conn, NULL);
+ return;
+ }
+
if (!parse_argument(argc, argv, NULL, NULL, &powered, NULL))
return;
- ad_advertise_tx_power(dbus_conn, powered);
+ ad_advertise_tx_power(dbus_conn, &powered);
}
-static void cmd_set_advertise_name(int argc, char *argv[])
+static void cmd_advertise_name(int argc, char *argv[])
{
+ if (argc < 2) {
+ ad_advertise_local_name(dbus_conn, NULL);
+ return;
+ }
+
if (strcmp(argv[1], "on") == 0 || strcmp(argv[1], "yes") == 0) {
ad_advertise_name(dbus_conn, true);
return;
@@ -2246,11 +2247,16 @@ static void cmd_set_advertise_name(int argc, char *argv[])
ad_advertise_local_name(dbus_conn, argv[1]);
}
-static void cmd_set_advertise_appearance(int argc, char *argv[])
+static void cmd_advertise_appearance(int argc, char *argv[])
{
long int value;
char *endptr = NULL;
+ if (argc < 2) {
+ ad_advertise_local_appearance(dbus_conn, NULL);
+ return;
+ }
+
if (strcmp(argv[1], "on") == 0 || strcmp(argv[1], "yes") == 0) {
ad_advertise_appearance(dbus_conn, true);
return;
@@ -2267,59 +2273,69 @@ static void cmd_set_advertise_appearance(int argc, char *argv[])
return;
}
- ad_advertise_local_appearance(dbus_conn, value);
+ ad_advertise_local_appearance(dbus_conn, &value);
}
-static void cmd_set_advertise_duration(int argc, char *argv[])
+static void cmd_advertise_duration(int argc, char *argv[])
{
long int value;
char *endptr = NULL;
+ if (argc < 2) {
+ ad_advertise_duration(dbus_conn, NULL);
+ return;
+ }
+
value = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
bt_shell_printf("Invalid argument\n");
return;
}
- ad_advertise_duration(dbus_conn, value);
+ ad_advertise_duration(dbus_conn, &value);
}
-static void cmd_set_advertise_timeout(int argc, char *argv[])
+static void cmd_advertise_timeout(int argc, char *argv[])
{
long int value;
char *endptr = NULL;
+ if (argc < 2) {
+ ad_advertise_timeout(dbus_conn, NULL);
+ return;
+ }
+
value = strtol(argv[1], &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
bt_shell_printf("Invalid argument\n");
return;
}
- ad_advertise_timeout(dbus_conn, value);
+ ad_advertise_timeout(dbus_conn, &value);
}
static const struct bt_shell_menu advertise_menu = {
.name = "advertise",
.desc = "Advertise Options Submenu",
.entries = {
- { "set-uuids", "[uuid1 uuid2 ...]",
- cmd_set_advertise_uuids, "Set advertise uuids" },
- { "set-service", "[uuid] [data=xx xx ...]", cmd_set_advertise_service,
+ { "uuids", "[uuid1 uuid2 ...]", cmd_advertise_uuids,
+ "Set advertise uuids" },
+ { "service", "[uuid] [data=xx xx ...]", cmd_advertise_service,
"Set advertise service data" },
- { "set-manufacturer", "[id] [data=xx xx ...]",
- cmd_set_advertise_manufacturer,
+ { "manufacturer", "[id] [data=xx xx ...]",
+ cmd_advertise_manufacturer,
"Set advertise manufacturer data" },
- { "set-tx-power", "<on/off>", cmd_set_advertise_tx_power,
+ { "tx-power", "[on/off]", cmd_advertise_tx_power,
"Enable/disable TX power to be advertised",
mode_generator },
- { "set-name", "<on/off/name>", cmd_set_advertise_name,
+ { "name", "[on/off/name]", cmd_advertise_name,
"Enable/disable local name to be advertised" },
- { "set-appearance", "<value>", cmd_set_advertise_appearance,
+ { "appearance", "[value]", cmd_advertise_appearance,
"Set custom appearance to be advertised" },
- { "set-duration", "<seconds>", cmd_set_advertise_duration,
- "Set advertise duration" },
- { "set-timeout", "<seconds>", cmd_set_advertise_timeout,
- "Set advertise timeout" },
+ { "duration", "[seconds]", cmd_advertise_duration,
+ "Set/Get advertise duration" },
+ { "timeout", "[seconds]", cmd_advertise_timeout,
+ "Set/Get advertise timeout" },
{ } },
};
diff --git a/gdbus/client.c b/gdbus/client.c
index ab405969..dd5d2eb5 100755
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -26,6 +26,7 @@
#endif
#include <stdio.h>
+#include <string.h>
#include <glib.h>
#include <dbus/dbus.h>
@@ -126,6 +127,99 @@ static gboolean modify_match(DBusConnection *conn, const char *member,
return TRUE;
}
+static void append_variant(DBusMessageIter *iter, int type, const void *val)
+{
+ DBusMessageIter value;
+ char sig[2] = { type, '\0' };
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
+
+ dbus_message_iter_append_basic(&value, type, val);
+
+ dbus_message_iter_close_container(iter, &value);
+}
+
+static void append_array_variant(DBusMessageIter *iter, int type, void *val,
+ int n_elements)
+{
+ DBusMessageIter variant, array;
+ char type_sig[2] = { type, '\0' };
+ char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+ array_sig, &variant);
+
+ dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
+ type_sig, &array);
+
+ if (dbus_type_is_fixed(type) == TRUE) {
+ dbus_message_iter_append_fixed_array(&array, type, val,
+ n_elements);
+ } else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
+ const char ***str_array = val;
+ int i;
+
+ for (i = 0; i < n_elements; i++)
+ dbus_message_iter_append_basic(&array, type,
+ &((*str_array)[i]));
+ }
+
+ dbus_message_iter_close_container(&variant, &array);
+
+ dbus_message_iter_close_container(iter, &variant);
+}
+
+static void dict_append_basic(DBusMessageIter *dict, int key_type,
+ const void *key, int type, void *val)
+{
+ DBusMessageIter entry;
+
+ if (type == DBUS_TYPE_STRING) {
+ const char *str = *((const char **) val);
+ if (str == NULL)
+ return;
+ }
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, key_type, key);
+
+ append_variant(&entry, type, val);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+void g_dbus_dict_append_entry(DBusMessageIter *dict,
+ const char *key, int type, void *val)
+{
+ dict_append_basic(dict, DBUS_TYPE_STRING, &key, type, val);
+}
+
+void g_dbus_dict_append_basic_array(DBusMessageIter *dict, int key_type,
+ const void *key, int type, void *val,
+ int n_elements)
+{
+ DBusMessageIter entry;
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, key_type, key);
+
+ append_array_variant(&entry, type, val, n_elements);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+void g_dbus_dict_append_array(DBusMessageIter *dict,
+ const char *key, int type, void *val,
+ int n_elements)
+{
+ g_dbus_dict_append_basic_array(dict, DBUS_TYPE_STRING, &key, type, val,
+ n_elements);
+}
+
static void iter_append_iter(DBusMessageIter *base, DBusMessageIter *iter)
{
int type;
@@ -352,22 +446,49 @@ static void get_all_properties(GDBusProxy *proxy)
dbus_message_unref(msg);
}
-static GDBusProxy *proxy_lookup(GList *list, const char *path,
+GDBusProxy *g_dbus_proxy_lookup(GList *list, int *index, const char *path,
const char *interface)
{
GList *l;
- for (l = g_list_first(list); l; l = g_list_next(l)) {
+ if (!interface)
+ return NULL;
+
+ for (l = g_list_nth(list, index ? *index : 0); l; l = g_list_next(l)) {
GDBusProxy *proxy = l->data;
+ const char *proxy_iface = g_dbus_proxy_get_interface(proxy);
+ const char *proxy_path = g_dbus_proxy_get_path(proxy);
- if (g_str_equal(proxy->interface, interface) == TRUE &&
- g_str_equal(proxy->obj_path, path) == TRUE)
+ if (index)
+ (*index)++;
+
+ if (g_str_equal(proxy_iface, interface) == TRUE &&
+ g_str_equal(proxy_path, path) == TRUE)
return proxy;
}
return NULL;
}
+char *g_dbus_proxy_path_lookup(GList *list, int *index, const char *path)
+{
+ int len = strlen(path);
+ GList *l;
+
+ for (l = g_list_nth(list, index ? *index : 0); l; l = g_list_next(l)) {
+ GDBusProxy *proxy = l->data;
+ const char *proxy_path = g_dbus_proxy_get_path(proxy);
+
+ if (index)
+ (*index)++;
+
+ if (!strncasecmp(proxy_path, path, len))
+ return strdup(proxy_path);
+ }
+
+ return NULL;
+}
+
static gboolean properties_changed(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
@@ -519,7 +640,8 @@ GDBusProxy *g_dbus_proxy_new(GDBusClient *client, const char *path,
if (client == NULL)
return NULL;
- proxy = proxy_lookup(client->proxy_list, path, interface);
+ proxy = g_dbus_proxy_lookup(client->proxy_list, NULL,
+ path, interface);
if (proxy)
return g_dbus_proxy_ref(proxy);
@@ -725,9 +847,8 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
struct set_property_data *data;
GDBusClient *client;
DBusMessage *msg;
- DBusMessageIter iter, variant;
+ DBusMessageIter iter;
DBusPendingCall *call;
- char type_as_str[2];
if (proxy == NULL || name == NULL || value == NULL)
return FALSE;
@@ -754,18 +875,12 @@ gboolean g_dbus_proxy_set_property_basic(GDBusProxy *proxy,
return FALSE;
}
- type_as_str[0] = (char) type;
- type_as_str[1] = '\0';
-
dbus_message_iter_init_append(msg, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
&proxy->interface);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
- type_as_str, &variant);
- dbus_message_iter_append_basic(&variant, type, value);
- dbus_message_iter_close_container(&iter, &variant);
+ append_variant(&iter, type, value);
if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, -1) == FALSE) {
@@ -790,10 +905,8 @@ gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
struct set_property_data *data;
GDBusClient *client;
DBusMessage *msg;
- DBusMessageIter iter, variant, array;
+ DBusMessageIter iter;
DBusPendingCall *call;
- char array_sig[3];
- char type_sig[2];
if (!proxy || !name || !value)
return FALSE;
@@ -822,37 +935,12 @@ gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
return FALSE;
}
- array_sig[0] = DBUS_TYPE_ARRAY;
- array_sig[1] = (char) type;
- array_sig[2] = '\0';
-
- type_sig[0] = (char) type;
- type_sig[1] = '\0';
-
dbus_message_iter_init_append(msg, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
&proxy->interface);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
- array_sig, &variant);
-
- dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
- type_sig, &array);
-
- if (dbus_type_is_fixed(type))
- dbus_message_iter_append_fixed_array(&array, type, &value,
- size);
- else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
- const char **str = (const char **) value;
- size_t i;
-
- for (i = 0; i < size; i++)
- dbus_message_iter_append_basic(&array, type, &str[i]);
- }
-
- dbus_message_iter_close_container(&variant, &array);
- dbus_message_iter_close_container(&iter, &variant);
+ append_array_variant(&iter, type, &value, size);
if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, -1) == FALSE) {
@@ -992,7 +1080,8 @@ static void parse_properties(GDBusClient *client, const char *path,
if (g_str_equal(interface, DBUS_INTERFACE_PROPERTIES) == TRUE)
return;
- proxy = proxy_lookup(client->proxy_list, path, interface);
+ proxy = g_dbus_proxy_lookup(client->proxy_list, NULL,
+ path, interface);
if (proxy && !proxy->pending) {
update_properties(proxy, iter, FALSE);
return;
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index e40dd44b..df66e794 100755
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -345,6 +345,10 @@ const char *g_dbus_proxy_get_interface(GDBusProxy *proxy);
gboolean g_dbus_proxy_get_property(GDBusProxy *proxy, const char *name,
DBusMessageIter *iter);
+GDBusProxy *g_dbus_proxy_lookup(GList *list, int *index, const char *path,
+ const char *interface);
+char *g_dbus_proxy_path_lookup(GList *list, int *index, const char *path);
+
gboolean g_dbus_proxy_refresh_property(GDBusProxy *proxy, const char *name);
typedef void (* GDBusResultFunction) (const DBusError *error, void *user_data);
@@ -359,6 +363,15 @@ gboolean g_dbus_proxy_set_property_array(GDBusProxy *proxy,
size_t size, GDBusResultFunction function,
void *user_data, GDBusDestroyFunction destroy);
+void g_dbus_dict_append_entry(DBusMessageIter *dict,
+ const char *key, int type, void *val);
+void g_dbus_dict_append_basic_array(DBusMessageIter *dict, int key_type,
+ const void *key, int type, void *val,
+ int n_elements);
+void g_dbus_dict_append_array(DBusMessageIter *dict,
+ const char *key, int type, void *val,
+ int n_elements);
+
typedef void (* GDBusSetupFunction) (DBusMessageIter *iter, void *user_data);
typedef void (* GDBusReturnFunction) (DBusMessage *message, void *user_data);
diff --git a/mesh/config-client.c b/mesh/config-client.c
index f280441c..b6b02ef9 100644
--- a/mesh/config-client.c
+++ b/mesh/config-client.c
@@ -49,6 +49,23 @@
#define MIN_COMPOSITION_LEN 16
+static uint32_t print_mod_id(uint8_t *data, bool vid)
+{
+ uint32_t mod_id;
+
+ if (!vid) {
+ mod_id = get_le16(data);
+ bt_shell_printf("Model Id\t%4.4x\n", mod_id);
+ mod_id = 0xffff0000 | mod_id;
+ } else {
+ mod_id = get_le16(data + 2);
+ bt_shell_printf("Model Id\t%4.4x %4.4x\n",
+ get_le16(data), mod_id);
+ mod_id = get_le16(data) << 16 | mod_id;
+ }
+ return mod_id;
+}
+
static bool client_msg_recvd(uint16_t src, uint8_t *data,
uint16_t len, void *user_data)
{
@@ -101,12 +118,13 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
if (len != 4)
break;
- bt_shell_printf("Node %4.4x AppKey Status %s\n", src,
+ bt_shell_printf("Node %4.4x AppKey status %s\n", src,
mesh_status_str(data[0]));
net_idx = get_le16(data + 1) & 0xfff;
app_idx = get_le16(data + 2) >> 4;
- bt_shell_printf("\tNetKey %3.3x, AppKey %3.3x\n", net_idx, app_idx);
+ bt_shell_printf("NetKey\t%3.3x\n", net_idx);
+ bt_shell_printf("AppKey\t%3.3x\n", app_idx);
if (data[0] != MESH_STATUS_SUCCESS &&
data[0] != MESH_STATUS_IDX_ALREADY_STORED &&
@@ -119,7 +137,7 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
if (len != 3)
break;
- bt_shell_printf("Node %4.4x NetKey Status %s\n", src,
+ bt_shell_printf("Node %4.4x NetKey status %s\n", src,
mesh_status_str(data[0]));
net_idx = get_le16(data + 1) & 0xfff;
@@ -136,23 +154,16 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
if (len != 7 && len != 9)
break;
- bt_shell_printf("Node %4.4x Model App Status %s\n", src,
+ bt_shell_printf("Node %4.4x Model App status %s\n", src,
mesh_status_str(data[0]));
addr = get_le16(data + 1);
app_idx = get_le16(data + 3);
- bt_shell_printf("\tElement %4.4x AppIdx %3.3x\n ", addr, app_idx);
-
- if (len == 7) {
- mod_id = get_le16(data + 5);
- bt_shell_printf("ModelId %4.4x\n", mod_id);
- mod_id = 0xffff0000 | mod_id;
- } else {
- mod_id = get_le16(data + 7);
- bt_shell_printf("ModelId %4.4x %4.4x\n", get_le16(data + 5),
- mod_id);
- mod_id = get_le16(data + 5) << 16 | mod_id;
- }
+ bt_shell_printf("Element Addr\t%4.4x\n", addr);
+
+ mod_id = print_mod_id(data + 5, (len == 9) ? true : false);
+
+ bt_shell_printf("AppIdx\t\t%3.3x\n ", app_idx);
if (data[0] == MESH_STATUS_SUCCESS &&
node_add_binding(node, addr - src, mod_id, app_idx))
@@ -162,24 +173,31 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
case OP_NODE_IDENTITY_STATUS:
if (len != 4)
return true;
- bt_shell_printf("Network index 0x%04x has "
- "Node Identity state 0x%02x %s\n",
+ bt_shell_printf("Network index 0x%04x "
+ "Node Identity state 0x%02x status %s\n",
get_le16(data + 1), data[3],
mesh_status_str(data[0]));
break;
+ case OP_CONFIG_BEACON_STATUS:
+ if (len != 1)
+ return true;
+ bt_shell_printf("Node %4.4x Config Beacon Status 0x%02x\n",
+ src, data[0]);
+ break;
+
case OP_CONFIG_RELAY_STATUS:
if (len != 2)
return true;
- bt_shell_printf("Node %4.4x Relay state: 0x%02x"
- " count: %d steps: %d\n",
+ bt_shell_printf("Node %4.4x Relay state 0x%02x"
+ " count %d steps %d\n",
src, data[0], data[1]>>5, data[1] & 0x1f);
break;
case OP_CONFIG_PROXY_STATUS:
if (len != 1)
return true;
- bt_shell_printf("Node %4.4x Proxy state: 0x%02x\n",
+ bt_shell_printf("Node %4.4x Proxy state 0x%02x\n",
src, data[0]);
break;
@@ -195,45 +213,42 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
if (len != 12 && len != 14)
return true;
- bt_shell_printf("\nSet publication for node %4.4x status: %s\n",
- src, data[0] == MESH_STATUS_SUCCESS ?
- "Success" : mesh_status_str(data[0]));
+ bt_shell_printf("\nNode %4.4x Publication status %s\n",
+ src, mesh_status_str(data[0]));
if (data[0] != MESH_STATUS_SUCCESS)
return true;
ele_addr = get_le16(data + 1);
- mod_id = get_le16(data + 10);
- if (len == 14)
- mod_id = (mod_id << 16) | get_le16(data + 12);
- else
- mod_id |= 0xffff0000;
+
+ bt_shell_printf("Element Addr\t%04x\n", ele_addr);
+
+ mod_id = print_mod_id(data + 10, (len == 14) ? true : false);
pub.u.addr16 = get_le16(data + 3);
pub.app_idx = get_le16(data + 5);
pub.ttl = data[7];
pub.period = data[8];
n = (data[8] & 0x3f);
- bt_shell_printf("Publication address: 0x%04x\n", pub.u.addr16);
+ bt_shell_printf("Pub Addr\t%04x\n", pub.u.addr16);
switch (data[8] >> 6) {
case 0:
- bt_shell_printf("Period: %d ms\n", n * 100);
+ bt_shell_printf("Period\t\t%d ms\n", n * 100);
break;
case 2:
n *= 10;
/* fall through */
case 1:
- bt_shell_printf("Period: %d sec\n", n);
+ bt_shell_printf("Period\t\t%d sec\n", n);
break;
case 3:
- bt_shell_printf("Period: %d min\n", n * 10);
+ bt_shell_printf("Period\t\t%d min\n", n * 10);
break;
}
pub.retransmit = data[9];
- bt_shell_printf("Retransmit count: %d\n", data[9] >> 5);
- bt_shell_printf("Retransmit Interval Steps: %d\n",
- data[9] & 0x1f);
+ bt_shell_printf("Rexmit count\t%d\n", data[9] >> 5);
+ bt_shell_printf("Rexmit steps\t%d\n", data[9] & 0x1f);
ele_idx = ele_addr - node_get_primary(node);
@@ -248,75 +263,102 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
/* Per Mesh Profile 4.3.2.19 */
case OP_CONFIG_MODEL_SUB_STATUS:
- bt_shell_printf("\nSubscription changed"
- " for node %4.4x status: %s\n", src,
- data[0] == MESH_STATUS_SUCCESS ? "Success" :
- mesh_status_str(data[0]));
+ bt_shell_printf("\nNode %4.4x Subscription status %s\n",
+ src, mesh_status_str(data[0]));
if (data[0] != MESH_STATUS_SUCCESS)
return true;
- bt_shell_printf("Element Addr:\t%4.4x\n", get_le16(data + 1));
- bt_shell_printf("Subscr Addr:\t%4.4x\n", get_le16(data + 3));
- bt_shell_printf("Model ID:\t%4.4x\n", get_le16(data + 5));
- break;
+ ele_addr = get_le16(data + 1);
+ addr = get_le16(data + 3);
+ ele_idx = ele_addr - node_get_primary(node);
+
+ bt_shell_printf("Element Addr\t%4.4x\n", ele_addr);
+
+ mod_id = print_mod_id(data + 5, (len == 9) ? true : false);
- /* TODO */
- /* Save subscription info in database */
+ bt_shell_printf("Subscr Addr\t%4.4x\n", addr);
+
+ /* Save subscriptions in node and database */
+ if (node_add_subscription(node, ele_idx, mod_id, addr))
+ prov_db_add_subscription(node, ele_idx, mod_id, addr);
+ break;
/* Per Mesh Profile 4.3.2.27 */
case OP_CONFIG_MODEL_SUB_LIST:
- bt_shell_printf("\nSubscription list for node %4.4x "
- "length: %u status: %s\n", src, len,
- data[0] == MESH_STATUS_SUCCESS ? "Success" :
- mesh_status_str(data[0]));
+ bt_shell_printf("\nNode %4.4x Subscription List status %s\n",
+ src, mesh_status_str(data[0]));
if (data[0] != MESH_STATUS_SUCCESS)
return true;
- bt_shell_printf("Element Addr:\t%4.4x\n", get_le16(data + 1));
- bt_shell_printf("Model ID:\t%4.4x\n", get_le16(data + 3));
+ bt_shell_printf("Element Addr\t%4.4x\n", get_le16(data + 1));
+ bt_shell_printf("Model ID\t%4.4x\n", get_le16(data + 3));
for (i = 5; i < len; i += 2)
- bt_shell_printf("Subscr Addr:\t%4.4x\n",
+ bt_shell_printf("Subscr Addr\t%4.4x\n",
get_le16(data + i));
break;
/* Per Mesh Profile 4.3.2.50 */
case OP_MODEL_APP_LIST:
- bt_shell_printf("\nModel App Key list for node %4.4x "
- "length: %u status: %s\n", src, len,
- data[0] == MESH_STATUS_SUCCESS ? "Success" :
- mesh_status_str(data[0]));
+ bt_shell_printf("\nNode %4.4x Model AppIdx "
+ "status %s\n", src,
+ mesh_status_str(data[0]));
if (data[0] != MESH_STATUS_SUCCESS)
return true;
- bt_shell_printf("Element Addr:\t%4.4x\n", get_le16(data + 1));
- bt_shell_printf("Model ID:\t%4.4x\n", get_le16(data + 3));
+ bt_shell_printf("Element Addr\t%4.4x\n", get_le16(data + 1));
+ bt_shell_printf("Model ID\t%4.4x\n", get_le16(data + 3));
for (i = 5; i < len; i += 2)
- bt_shell_printf("Model App Key:\t%4.4x\n",
+ bt_shell_printf("Model AppIdx\t%4.4x\n",
get_le16(data + i));
break;
/* Per Mesh Profile 4.3.2.63 */
case OP_CONFIG_HEARTBEAT_PUB_STATUS:
- bt_shell_printf("\nSet heartbeat for node %4.4x status: %s\n",
- src,
- data[0] == MESH_STATUS_SUCCESS ? "Success" :
- mesh_status_str(data[0]));
+ bt_shell_printf("\nNode %4.4x Heartbeat publish status %s\n",
+ src, mesh_status_str(data[0]));
+
+ if (data[0] != MESH_STATUS_SUCCESS)
+ return true;
+
+ bt_shell_printf("Destination\t%4.4x\n", get_le16(data + 1));
+ bt_shell_printf("Count\t\t%2.2x\n", data[3]);
+ bt_shell_printf("Period\t\t%2.2x\n", data[4]);
+ bt_shell_printf("TTL\t\t%2.2x\n", data[5]);
+ bt_shell_printf("Features\t%4.4x\n", get_le16(data + 6));
+ bt_shell_printf("Net_Idx\t%4.4x\n", get_le16(data + 8));
+ break;
+
+ /* Per Mesh Profile 4.3.2.66 */
+ case OP_CONFIG_HEARTBEAT_SUB_STATUS:
+ bt_shell_printf("\nNode %4.4x Heartbeat subscribe status %s\n",
+ src, mesh_status_str(data[0]));
if (data[0] != MESH_STATUS_SUCCESS)
return true;
- bt_shell_printf("Destination:\t%4.4x\n", get_le16(data + 1));
- bt_shell_printf("Count:\t\t%2.2x\n", data[3]);
- bt_shell_printf("Period:\t\t%2.2x\n", data[4]);
- bt_shell_printf("TTL:\t\t%2.2x\n", data[5]);
- bt_shell_printf("Features:\t%4.4x\n", get_le16(data + 6));
- bt_shell_printf("Net_Idx:\t%4.4x\n", get_le16(data + 8));
+ bt_shell_printf("Source\t\t%4.4x\n", get_le16(data + 1));
+ bt_shell_printf("Destination\t%4.4x\n", get_le16(data + 3));
+ bt_shell_printf("Period\t\t%2.2x\n", data[5]);
+ bt_shell_printf("Count\t\t%2.2x\n", data[6]);
+ bt_shell_printf("Min Hops\t%2.2x\n", data[7]);
+ bt_shell_printf("Max Hops\t%2.2x\n", data[8]);
+ break;
+
+ /* Per Mesh Profile 4.3.2.54 */
+ case OP_NODE_RESET_STATUS:
+ bt_shell_printf("Node %4.4x reset status %s\n",
+ src, mesh_status_str(data[0]));
+
+ net_release_address(node_get_primary(node),
+ (node_get_num_elements(node)));
+ /* TODO: Remove node info from database */
+ node_free(node);
break;
}
@@ -351,7 +393,7 @@ static uint32_t read_input_parameters(int argc, char *argv[])
return i;
}
-static void cmd_set_node(int argc, char *argv[])
+static void cmd_node_set(int argc, char *argv[])
{
uint32_t dst;
char *end;
@@ -361,10 +403,12 @@ static void cmd_set_node(int argc, char *argv[])
bt_shell_printf("Bad unicast address %s: "
"expected format 4 digit hex\n", argv[1]);
target = UNASSIGNED_ADDRESS;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
} else {
bt_shell_printf("Configuring node %4.4x\n", dst);
target = dst;
set_menu_prompt("config", argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
}
@@ -395,17 +439,21 @@ static void cmd_default(uint32_t opcode)
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(opcode, msg);
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send command (opcode 0x%x)\n",
opcode);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_get_composition(int argc, char *argv[])
+static void cmd_composition_get(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[32];
@@ -413,21 +461,25 @@ static void cmd_get_composition(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
node = node_find_by_addr(target);
if (!node)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
n = mesh_opcode_set(OP_DEV_COMP_GET, msg);
/* By default, use page 0 */
msg[n++] = (read_input_parameters(argc, argv) == 1) ? parms[0] : 0;
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"GET NODE COMPOSITION\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_net_key(int argc, char *argv[], uint32_t opcode)
@@ -440,20 +492,20 @@ static void cmd_net_key(int argc, char *argv[], uint32_t opcode)
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(opcode, msg);
if (read_input_parameters(argc, argv) != 1) {
bt_shell_printf("Bad arguments %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
node = node_find_by_addr(target);
if (!node) {
bt_shell_printf("Node %4.4x\n not found", target);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
net_idx = parms[0];
@@ -462,9 +514,9 @@ static void cmd_net_key(int argc, char *argv[], uint32_t opcode)
key = keys_net_key_get(net_idx, true);
if (!key) {
- bt_shell_printf("Network key with index %4.4x not found\n",
+ bt_shell_printf("NetKey with index %4.4x not found\n",
net_idx);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
put_le16(net_idx, &msg[n]);
@@ -477,7 +529,7 @@ static void cmd_net_key(int argc, char *argv[], uint32_t opcode)
if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"%s NET KEY\"\n",
opcode == OP_NETKEY_ADD ? "ADD" : "DEL");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (opcode != OP_NETKEY_DELETE) {
@@ -490,14 +542,15 @@ static void cmd_net_key(int argc, char *argv[], uint32_t opcode)
"netKeys");
}
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_add_net_key(int argc, char *argv[])
+static void cmd_netkey_add(int argc, char *argv[])
{
cmd_net_key(argc, argv, OP_NETKEY_ADD);
}
-static void cmd_del_net_key(int argc, char *argv[])
+static void cmd_netkey_del(int argc, char *argv[])
{
cmd_net_key(argc, argv, OP_NETKEY_DELETE);
}
@@ -513,18 +566,18 @@ static void cmd_app_key(int argc, char *argv[], uint32_t opcode)
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (read_input_parameters(argc, argv) != 1) {
bt_shell_printf("Bad arguments %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
node = node_find_by_addr(target);
if (!node) {
bt_shell_printf("Node %4.4x\n not found", target);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(opcode, msg);
@@ -532,8 +585,8 @@ static void cmd_app_key(int argc, char *argv[], uint32_t opcode)
app_idx = parms[0];
net_idx = keys_app_key_get_bound(app_idx);
if (net_idx == NET_IDX_INVALID) {
- bt_shell_printf("App key with index %4.4x not found\n", app_idx);
- return;
+ bt_shell_printf("AppKey with index %4.4x not found\n", app_idx);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
msg[n++] = net_idx & 0xf;
@@ -544,7 +597,7 @@ static void cmd_app_key(int argc, char *argv[], uint32_t opcode)
if (opcode != OP_APPKEY_DELETE) {
key = keys_app_key_get(app_idx, true);
if (!key) {
- bt_shell_printf("App key %4.4x not found\n", net_idx);
+ bt_shell_printf("AppKey %4.4x not found\n", net_idx);
return;
}
@@ -555,7 +608,7 @@ static void cmd_app_key(int argc, char *argv[], uint32_t opcode)
if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"ADD %s KEY\"\n",
opcode == OP_APPKEY_ADD ? "ADD" : "DEL");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (opcode != OP_APPKEY_DELETE) {
@@ -567,14 +620,16 @@ static void cmd_app_key(int argc, char *argv[], uint32_t opcode)
prov_db_node_keys(node, node_get_app_keys(node),
"appKeys");
}
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_add_app_key(int argc, char *argv[])
+static void cmd_appkey_add(int argc, char *argv[])
{
cmd_app_key(argc, argv, OP_APPKEY_ADD);
}
-static void cmd_del_app_key(int argc, char *argv[])
+static void cmd_appkey_del(int argc, char *argv[])
{
cmd_app_key(argc, argv, OP_APPKEY_DELETE);
}
@@ -590,7 +645,8 @@ static bool verify_config_target(uint32_t dst)
node = node_find_by_addr(dst);
if (!node) {
- bt_shell_printf("Node with unicast address %4.4x unknown\n", dst);
+ bt_shell_printf("Node with unicast address %4.4x unknown\n",
+ dst);
return false;
}
@@ -609,12 +665,12 @@ static void cmd_bind(int argc, char *argv[])
int parm_cnt;
if (!verify_config_target(target))
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 3 && parm_cnt != 4) {
bt_shell_printf("Bad arguments\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_MODEL_APP_BIND, msg);
@@ -632,118 +688,169 @@ static void cmd_bind(int argc, char *argv[])
n += 2;
}
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"MODEL APP BIND\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_set_ident(int argc, char *argv[])
+static void cmd_beacon_set(int argc, char *argv[])
{
uint16_t n;
- uint8_t msg[2 + 3 + 4];
+ uint8_t msg[2 + 1];
int parm_cnt;
if (!verify_config_target(target))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+
+ n = mesh_opcode_set(OP_CONFIG_BEACON_SET, msg);
+
+ parm_cnt = read_input_parameters(argc, argv);
+ if (parm_cnt != 1) {
+ bt_shell_printf("bad arguments\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ msg[n++] = parms[0];
+
+ if (!config_send(msg, n)) {
+ bt_shell_printf("Failed to send \"SET BEACON\"\n");
return;
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_beacon_get(int argc, char *argv[])
+{
+ cmd_default(OP_CONFIG_BEACON_GET);
+}
+
+static void cmd_ident_set(int argc, char *argv[])
+{
+ uint16_t n;
+ uint8_t msg[2 + 3 + 4];
+ int parm_cnt;
+
+ if (!verify_config_target(target))
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
n = mesh_opcode_set(OP_NODE_IDENTITY_SET, msg);
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 2) {
bt_shell_printf("bad arguments\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
put_le16(parms[0], msg + n);
n += 2;
msg[n++] = parms[1];
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"SET IDENTITY\"\n");
+ return;
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_get_ident(int argc, char *argv[])
+static void cmd_ident_get(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[2 + 2 + 4];
int parm_cnt;
if (!verify_config_target(target))
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
n = mesh_opcode_set(OP_NODE_IDENTITY_GET, msg);
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 1) {
bt_shell_printf("bad arguments\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
put_le16(parms[0], msg + n);
n += 2;
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"GET IDENTITY\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_set_proxy(int argc, char *argv[])
+static void cmd_proxy_set(int argc, char *argv[])
{
uint16_t n;
- uint8_t msg[2 + 1 + 4];
+ uint8_t msg[2 + 1];
int parm_cnt;
if (!verify_config_target(target))
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
n = mesh_opcode_set(OP_CONFIG_PROXY_SET, msg);
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 1) {
bt_shell_printf("bad arguments");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
msg[n++] = parms[0];
- msg[n++] = parms[1];
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"SET PROXY\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_get_proxy(int argc, char *argv[])
+static void cmd_proxy_get(int argc, char *argv[])
{
cmd_default(OP_CONFIG_PROXY_GET);
}
-static void cmd_set_relay(int argc, char *argv[])
+static void cmd_relay_set(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[2 + 2 + 4];
int parm_cnt;
if (!verify_config_target(target))
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
n = mesh_opcode_set(OP_CONFIG_RELAY_SET, msg);
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 3) {
bt_shell_printf("bad arguments\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
msg[n++] = parms[0];
msg[n++] = (parms[1] << 5) | parms[2];
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"SET RELAY\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_get_relay(int argc, char *argv[])
+static void cmd_relay_get(int argc, char *argv[])
{
cmd_default(OP_CONFIG_RELAY_GET);
}
-static void cmd_set_ttl(int argc, char *argv[])
+static void cmd_ttl_set(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[32];
@@ -752,7 +859,7 @@ static void cmd_set_ttl(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_CONFIG_DEFAULT_TTL_SET, msg);
@@ -765,25 +872,29 @@ static void cmd_set_ttl(int argc, char *argv[])
msg[n++] = ttl;
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"SET_DEFAULT TTL\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_set_pub(int argc, char *argv[])
+static void cmd_pub_set(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[32];
int parm_cnt;
if (!verify_config_target(target))
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
n = mesh_opcode_set(OP_CONFIG_MODEL_PUB_SET, msg);
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 6 && parm_cnt != 7) {
bt_shell_printf("Bad arguments\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
put_le16(parms[0], msg + n);
@@ -791,7 +902,7 @@ static void cmd_set_pub(int argc, char *argv[])
/* Publish address */
put_le16(parms[1], msg + n);
n += 2;
- /* App key index + credential (set to 0) */
+ /* AppKey index + credential (set to 0) */
put_le16(parms[2], msg + n);
n += 2;
/* TTL */
@@ -810,11 +921,15 @@ static void cmd_set_pub(int argc, char *argv[])
n += 2;
}
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"SET MODEL PUBLICATION\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_get_pub(int argc, char *argv[])
+static void cmd_pub_get(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[32];
@@ -822,7 +937,7 @@ static void cmd_get_pub(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_CONFIG_MODEL_PUB_GET, msg);
@@ -830,7 +945,7 @@ static void cmd_get_pub(int argc, char *argv[])
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 2 && parm_cnt != 3) {
bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
/* Element Address */
@@ -846,8 +961,12 @@ static void cmd_get_pub(int argc, char *argv[])
n += 2;
}
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"GET MODEL PUBLICATION\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_sub_add(int argc, char *argv[])
@@ -858,7 +977,7 @@ static void cmd_sub_add(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_CONFIG_MODEL_SUB_ADD, msg);
@@ -866,7 +985,7 @@ static void cmd_sub_add(int argc, char *argv[])
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 3) {
bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
/* Per Mesh Profile 4.3.2.19 */
@@ -880,8 +999,12 @@ static void cmd_sub_add(int argc, char *argv[])
put_le16(parms[2], msg + n);
n += 2;
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"ADD SUBSCRIPTION\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_sub_get(int argc, char *argv[])
@@ -892,7 +1015,7 @@ static void cmd_sub_get(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_CONFIG_MODEL_SUB_GET, msg);
@@ -900,7 +1023,7 @@ static void cmd_sub_get(int argc, char *argv[])
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 2) {
bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
/* Per Mesh Profile 4.3.2.27 */
@@ -911,11 +1034,15 @@ static void cmd_sub_get(int argc, char *argv[])
put_le16(parms[1], msg + n);
n += 2;
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"GET SUB GET\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_get_app(int argc, char *argv[])
+static void cmd_mod_appidx_get(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[32];
@@ -923,7 +1050,7 @@ static void cmd_get_app(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_MODEL_APP_GET, msg);
@@ -931,7 +1058,7 @@ static void cmd_get_app(int argc, char *argv[])
parm_cnt = read_input_parameters(argc, argv);
if (parm_cnt != 2) {
bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
/* Per Mesh Profile 4.3.2.49 */
@@ -942,11 +1069,15 @@ static void cmd_get_app(int argc, char *argv[])
put_le16(parms[1], msg + n);
n += 2;
- if (!config_send(msg, n))
+ if (!config_send(msg, n)) {
bt_shell_printf("Failed to send \"GET APP GET\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_set_hb(int argc, char *argv[])
+static void cmd_hb_pub_set(int argc, char *argv[])
{
uint16_t n;
uint8_t msg[32];
@@ -954,15 +1085,15 @@ static void cmd_set_hb(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_CONFIG_HEARTBEAT_PUB_SET, msg);
parm_cnt = read_input_parameters(argc, argv);
- if (parm_cnt != 5) {
+ if (parm_cnt != 6) {
bt_shell_printf("Bad arguments: %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
/* Per Mesh Profile 4.3.2.62 */
@@ -974,72 +1105,140 @@ static void cmd_set_hb(int argc, char *argv[])
/* Period Log */
msg[n++] = parms[2];
/* Heartbeat TTL */
- msg[n++] = DEFAULT_TTL;
+ msg[n++] = parms[3];
/* Features */
- put_le16(parms[3], msg + n);
+ put_le16(parms[4], msg + n);
n += 2;
/* NetKey Index */
- put_le16(parms[4], msg + n);
+ put_le16(parms[5], msg + n);
n += 2;
- if (!config_send(msg, n))
- bt_shell_printf("Failed to send \"SET HEARTBEAT PUBLICATION\"\n");
+ if (!config_send(msg, n)) {
+ bt_shell_printf("Failed to send \"SET HEARTBEAT PUBLISH\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_hb_pub_get(int argc, char *argv[])
+{
+ cmd_default(OP_CONFIG_HEARTBEAT_PUB_GET);
}
-static void cmd_get_ttl(int argc, char *argv[])
+static void cmd_hb_sub_set(int argc, char *argv[])
+{
+ uint16_t n;
+ uint8_t msg[32];
+ int parm_cnt;
+
+ if (IS_UNASSIGNED(target)) {
+ bt_shell_printf("Destination not set\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ n = mesh_opcode_set(OP_CONFIG_HEARTBEAT_SUB_SET, msg);
+
+ parm_cnt = read_input_parameters(argc, argv);
+ if (parm_cnt != 3) {
+ bt_shell_printf("Bad arguments: %s\n", argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ /* Per Mesh Profile 4.3.2.65 */
+ /* Source address */
+ put_le16(parms[0], msg + n);
+ n += 2;
+ /* Destination address */
+ put_le16(parms[1], msg + n);
+ n += 2;
+ /* Period log */
+ msg[n++] = parms[2];
+
+ if (!config_send(msg, n)) {
+ bt_shell_printf("Failed to send \"SET HEARTBEAT SUBSCRIBE\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_hb_sub_get(int argc, char *argv[])
+{
+ cmd_default(OP_CONFIG_HEARTBEAT_SUB_GET);
+}
+
+static void cmd_ttl_get(int argc, char *argv[])
{
cmd_default(OP_CONFIG_DEFAULT_TTL_GET);
}
+static void cmd_node_reset(int argc, char *argv[])
+{
+ cmd_default(OP_NODE_RESET);
+}
+
static const struct bt_shell_menu cfg_menu = {
.name = "config",
.desc = "Configuration Model Submenu",
.entries = {
- {"target", "<unicast>", cmd_set_node,
+ {"target", "<unicast>", cmd_node_set,
"Set target node to configure"},
- {"composition-get", "[page_num]", cmd_get_composition,
- "Get Composition Data"},
- {"netkey-add", "<net_idx>", cmd_add_net_key,
+ {"composition-get", "[page_num]", cmd_composition_get,
+ "Get composition data"},
+ {"netkey-add", "<net_idx>", cmd_netkey_add,
"Add network key"},
- {"netkey-del", "<net_idx>", cmd_del_net_key,
+ {"netkey-del", "<net_idx>", cmd_netkey_del,
"Delete network key"},
- {"appkey-add", "<app_idx>", cmd_add_app_key,
+ {"appkey-add", "<app_idx>", cmd_appkey_add,
"Add application key"},
- {"appkey-del", "<app_idx>", cmd_del_app_key,
+ {"appkey-del", "<app_idx>", cmd_appkey_del,
"Delete application key"},
{"bind", "<ele_idx> <app_idx> <mod_id> [cid]",
cmd_bind, "Bind app key to a model"},
- {"ttl-set", "<ttl>", cmd_set_ttl,
+ {"mod-appidx-get", "<ele_addr> <model id>",
+ cmd_mod_appidx_get, "Get model app_idx"},
+ {"ttl-set", "<ttl>", cmd_ttl_set,
"Set default TTL"},
- {"ttl-get", NULL, cmd_get_ttl,
+ {"ttl-get", NULL, cmd_ttl_get,
"Get default TTL"},
{"pub-set", "<ele_addr> <pub_addr> <app_idx> "
"<per (step|res)> <re-xmt (cnt|per)> <mod id> "
"[cid]",
- cmd_set_pub, "\n\t\t\t\t\t\t Set publication"},
- {"pub-get", "<ele_addr> <model>", cmd_get_pub,
+ cmd_pub_set, "\n\t\t\t\t\t\t Set publication"},
+ {"pub-get", "<ele_addr> <model>", cmd_pub_get,
"Get publication"},
- {"proxy-set", "<proxy>", cmd_set_proxy,
+ {"proxy-set", "<proxy>", cmd_proxy_set,
"Set proxy state"},
- {"proxy-get", NULL, cmd_get_proxy,
+ {"proxy-get", NULL, cmd_proxy_get,
"Get proxy state"},
- {"ident-set", "<net_idx> <state>", cmd_set_ident,
+ {"ident-set", "<net_idx> <state>", cmd_ident_set,
"Set node identity state"},
- {"ident-get", "<net_idx>", cmd_get_ident,
+ {"ident-get", "<net_idx>", cmd_ident_get,
"Get node identity state"},
+ {"beacon-set", "<state>", cmd_beacon_set,
+ "Set node identity state"},
+ {"beacon-get", NULL, cmd_beacon_get,
+ "Get node beacon state"},
{"relay-set", "<relay> <rexmt count> <rexmt steps>",
- cmd_set_relay,
+ cmd_relay_set,
"Set relay"},
- {"relay-get", NULL, cmd_get_relay,
+ {"relay-get", NULL, cmd_relay_get,
"Get relay"},
- {"hb-pub-set", "<pub_addr> <count> <period> <features> <net_idx>",
- cmd_set_hb, "Set heartbeati publish"},
+ {"hb-pub-set", "<pub_addr> <count> <period> <ttl> <features> <net_idx>",
+ cmd_hb_pub_set, "Set heartbeat publish"},
+ {"hb-pub-get", NULL, cmd_hb_pub_get,
+ "Get heartbeat publish"},
+ {"hb-sub-set", "<src_addr> <dst_addr> <period>",
+ cmd_hb_sub_set, "Set heartbeat subscribe"},
+ {"hb-sub-get", NULL, cmd_hb_sub_get,
+ "Get heartbeat subscribe"},
{"sub-add", "<ele_addr> <sub_addr> <model id>",
- cmd_sub_add, "Subscription add"},
+ cmd_sub_add, "Add subscription"},
{"sub-get", "<ele_addr> <model id>",
- cmd_sub_get, "Subscription get"},
- {"app-get", "<ele_addr> <model id>",
- cmd_get_app, "Get App Keys"},
+ cmd_sub_get, "Get subscription"},
+ {"node-reset", NULL, cmd_node_reset,
+ "Reset a node and remove it from network"},
{} },
};
@@ -1048,7 +1247,7 @@ void config_client_get_composition(uint32_t dst)
uint32_t tmp = target;
target = dst;
- cmd_get_composition(0, NULL);
+ cmd_composition_get(0, NULL);
target = tmp;
}
diff --git a/mesh/config-server.c b/mesh/config-server.c
index 10fead6e..2d657637 100644
--- a/mesh/config-server.c
+++ b/mesh/config-server.c
@@ -129,7 +129,8 @@ static bool server_msg_recvd(uint16_t src, uint8_t *data,
pub.retransmit = data[8];
bt_shell_printf("Retransmit count: %d\n", data[8] >> 5);
- bt_shell_printf("Retransmit Interval Steps: %d\n", data[8] & 0x1f);
+ bt_shell_printf("Retransmit Interval Steps: %d\n",
+ data[8] & 0x1f);
ele_idx = ele_addr - node_get_primary(node);
diff --git a/mesh/gatt.c b/mesh/gatt.c
index 9116a9de..693577a3 100644
--- a/mesh/gatt.c
+++ b/mesh/gatt.c
@@ -383,7 +383,7 @@ static bool pipe_read(struct io *io, bool prov, void *user_data)
uint8_t buf[512];
uint8_t *res;
int fd = io_get_fd(io);
- ssize_t len;
+ ssize_t len, len_sar;
if (io != notify_io)
return true;
@@ -393,14 +393,14 @@ static bool pipe_read(struct io *io, bool prov, void *user_data)
break;
res = buf;
- mesh_gatt_sar(&res, len);
-
- if (prov)
- prov_data_ready(node, res, len);
- else
- net_data_ready(res, len);
+ len_sar = mesh_gatt_sar(&res, len);
+ if (len_sar) {
+ if (prov)
+ prov_data_ready(node, res, len_sar);
+ else
+ net_data_ready(res, len_sar);
+ }
}
-
return true;
}
diff --git a/mesh/main.c b/mesh/main.c
index b5ec4bcd..3e1484f6 100644
--- a/mesh/main.c
+++ b/mesh/main.c
@@ -637,12 +637,14 @@ static void connect_reply(DBusMessage *message, void *user_data)
bt_shell_printf("Failed to connect: %s\n", error.name);
dbus_error_free(&error);
set_connected_device(NULL);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_printf("Connection successful\n");
set_connected_device(proxy);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void update_device_info(GDBusProxy *proxy)
@@ -921,8 +923,10 @@ static GDBusProxy *get_characteristic(GDBusProxy *device, const char *char_uuid)
for (l = char_list; l; l = l->next) {
if (mesh_gatt_is_child(l->data, service, "Service") &&
char_is_mesh(l->data, char_uuid)) {
- bt_shell_printf("Found matching char: path %s, uuid %s\n",
- g_dbus_proxy_get_path(l->data), char_uuid);
+ bt_shell_printf("Found matching char: path %s,"
+ " uuid %s\n",
+ g_dbus_proxy_get_path(l->data),
+ char_uuid);
return l->data;
}
}
@@ -945,7 +949,6 @@ static void mesh_session_setup(GDBusProxy *proxy)
data_out_notify(connection.data_out, true, notify_prov_out_cb);
} else if (connection.type != CONN_TYPE_INVALID){
-
connection.data_in = get_characteristic(proxy,
MESH_PROXY_DATA_IN_UUID_STR);
if (!connection.data_in)
@@ -982,13 +985,15 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
} else if (!strcmp(interface, "org.bluez.GattService1") &&
service_is_mesh(proxy, NULL)) {
- bt_shell_printf("Service added %s\n", g_dbus_proxy_get_path(proxy));
+ bt_shell_printf("Service added %s\n",
+ g_dbus_proxy_get_path(proxy));
service_list = g_list_append(service_list, proxy);
} else if (!strcmp(interface, "org.bluez.GattCharacteristic1") &&
char_is_mesh(proxy, NULL)) {
- bt_shell_printf("Char added %s:\n", g_dbus_proxy_get_path(proxy));
+ bt_shell_printf("Char added %s:\n",
+ g_dbus_proxy_get_path(proxy));
char_list = g_list_append(char_list, proxy);
}
@@ -1005,10 +1010,13 @@ 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 == TRUE ? "started" : "stopped");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct mesh_device *find_device_by_proxy(GList *source,
@@ -1193,8 +1201,10 @@ static void property_changed(GDBusProxy *proxy, const char *name,
if (connected && connection.device == NULL)
set_connected_device(proxy);
else if (!connected &&
- connection.device == proxy)
+ connection.device == proxy) {
+ net_session_close(connection.data_in);
set_connected_device(NULL);
+ }
} else if ((strcmp(name, "Alias") == 0) &&
connection.device == proxy) {
/* Re-generate prompt */
@@ -1206,8 +1216,8 @@ static void property_changed(GDBusProxy *proxy, const char *name,
dbus_message_iter_get_basic(iter, &resolved);
- bt_shell_printf("Services resolved %s\n", resolved ?
- "yes" : "no");
+ bt_shell_printf("Services resolved %s\n",
+ resolved ? "yes" : "no");
if (resolved)
mesh_session_setup(connection.device);
@@ -1306,6 +1316,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[])
@@ -1318,7 +1330,7 @@ static void cmd_show(int argc, char *argv[])
if (argc < 2 || !strlen(argv[1])) {
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
proxy = default_ctrl->proxy;
} else {
@@ -1326,13 +1338,13 @@ static void cmd_show(int argc, char *argv[])
if (!adapter) {
bt_shell_printf("Controller %s not available\n",
argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
proxy = adapter->proxy;
}
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);
bt_shell_printf("Controller %s\n", address);
@@ -1345,6 +1357,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[])
@@ -1354,26 +1368,31 @@ 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);
forget_mesh_devices();
default_ctrl = adapter;
print_adapter(adapter->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_power(int argc, char *argv[])
@@ -1382,10 +1401,10 @@ static void cmd_power(int argc, char *argv[])
char *str;
if (parse_argument_on_off(argc, argv, &powered) == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
str = g_strdup_printf("power %s", powered == TRUE ? "on" : "off");
@@ -1395,93 +1414,8 @@ static void cmd_power(int argc, char *argv[])
return;
g_free(str);
-}
-
-static void append_variant(DBusMessageIter *iter, int type, void *val)
-{
- DBusMessageIter value;
- char sig[2] = { type, '\0' };
- dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
-
- dbus_message_iter_append_basic(&value, type, val);
-
- dbus_message_iter_close_container(iter, &value);
-}
-
-static void append_array_variant(DBusMessageIter *iter, int type, void *val,
- int n_elements)
-{
- DBusMessageIter variant, array;
- char type_sig[2] = { type, '\0' };
- char array_sig[3] = { DBUS_TYPE_ARRAY, type, '\0' };
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
- array_sig, &variant);
-
- dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
- type_sig, &array);
-
- if (dbus_type_is_fixed(type) == TRUE) {
- dbus_message_iter_append_fixed_array(&array, type, val,
- n_elements);
- } else if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
- const char ***str_array = val;
- int i;
-
- for (i = 0; i < n_elements; i++)
- dbus_message_iter_append_basic(&array, type,
- &((*str_array)[i]));
- }
-
- dbus_message_iter_close_container(&variant, &array);
-
- dbus_message_iter_close_container(iter, &variant);
-}
-
-static void dict_append_entry(DBusMessageIter *dict, const char *key,
- int type, void *val)
-{
- DBusMessageIter entry;
-
- if (type == DBUS_TYPE_STRING) {
- const char *str = *((const char **) val);
-
- if (str == NULL)
- return;
- }
-
- dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
-
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
-
- append_variant(&entry, type, val);
-
- dbus_message_iter_close_container(dict, &entry);
-}
-
-static void dict_append_basic_array(DBusMessageIter *dict, int key_type,
- const void *key, int type, void *val,
- int n_elements)
-{
- DBusMessageIter entry;
-
- dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
-
- dbus_message_iter_append_basic(&entry, key_type, key);
-
- append_array_variant(&entry, type, val, n_elements);
-
- dbus_message_iter_close_container(dict, &entry);
-}
-
-static void dict_append_array(DBusMessageIter *dict, const char *key, int type,
- void *val, int n_elements)
-{
- dict_append_basic_array(dict, DBUS_TYPE_STRING, &key, type, val,
- n_elements);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
#define DISTANCE_VAL_INVALID 0x7FFF
@@ -1506,21 +1440,24 @@ static void set_discovery_filter_setup(DBusMessageIter *iter, void *user_data)
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
- dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &args->uuids,
+ g_dbus_dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING,
+ &args->uuids,
args->uuids_len);
if (args->pathloss != DISTANCE_VAL_INVALID)
- dict_append_entry(&dict, "Pathloss", DBUS_TYPE_UINT16,
+ g_dbus_dict_append_entry(&dict, "Pathloss", DBUS_TYPE_UINT16,
&args->pathloss);
if (args->rssi != DISTANCE_VAL_INVALID)
- dict_append_entry(&dict, "RSSI", DBUS_TYPE_INT16, &args->rssi);
+ g_dbus_dict_append_entry(&dict, "RSSI", DBUS_TYPE_INT16,
+ &args->rssi);
if (args->transport != NULL)
- dict_append_entry(&dict, "Transport", DBUS_TYPE_STRING,
+ g_dbus_dict_append_entry(&dict, "Transport", DBUS_TYPE_STRING,
&args->transport);
if (args->duplicate)
- dict_append_entry(&dict, "DuplicateData", DBUS_TYPE_BOOLEAN,
+ g_dbus_dict_append_entry(&dict, "DuplicateData",
+ DBUS_TYPE_BOOLEAN,
&args->duplicate);
dbus_message_iter_close_container(iter, &dict);
@@ -1535,10 +1472,12 @@ 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);
}
bt_shell_printf("SetDiscoveryFilter success\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static gint filtered_scan_rssi = DISTANCE_VAL_INVALID;
@@ -1559,13 +1498,13 @@ static void set_scan_filter_commit(void)
args.duplicate = TRUE;
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (g_dbus_proxy_method_call(default_ctrl->proxy, "SetDiscoveryFilter",
set_discovery_filter_setup, set_discovery_filter_reply,
&args, NULL) == FALSE) {
bt_shell_printf("Failed to set discovery filter\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1581,7 +1520,7 @@ static void set_scan_filter_uuids(char *filters[])
filtered_scan_uuids = g_strdupv(filters);
if (!filtered_scan_uuids) {
bt_shell_printf("Failed to parse input\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
filtered_scan_uuids_len = g_strv_length(filtered_scan_uuids);
@@ -1597,10 +1536,10 @@ static void cmd_scan_unprovisioned(int argc, char *argv[])
const char *method;
if (parse_argument_on_off(argc, argv, &enable) == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
if (enable == TRUE) {
discover_mesh = false;
@@ -1615,6 +1554,7 @@ static void cmd_scan_unprovisioned(int argc, char *argv[])
GUINT_TO_POINTER(enable), NULL) == FALSE) {
bt_shell_printf("Failed to %s discovery\n",
enable == TRUE ? "start" : "stop");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1626,10 +1566,10 @@ static void cmd_info(int argc, char *argv[])
proxy = connection.device;
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);
bt_shell_printf("Device %s\n", address);
@@ -1648,6 +1588,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 const char *security2str(uint8_t level)
@@ -1675,13 +1617,15 @@ static void cmd_security(int argc, char *argv[])
level = strtol(argv[1], &end, 10);
if (end == argv[1] || !prov_set_sec_level(level)) {
bt_shell_printf("Invalid security level %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
done:
bt_shell_printf("Provision Security Level set to %u (%s)\n",
prov_get_sec_level(),
security2str(prov_get_sec_level()));
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_connect(int argc, char *argv[])
@@ -1689,7 +1633,7 @@ static void cmd_connect(int argc, char *argv[])
char *filters[] = { MESH_PROXY_SVC_UUID, NULL };
if (check_default_ctrl() == FALSE)
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
memset(&connection, 0, sizeof(connection));
@@ -1701,7 +1645,7 @@ static void cmd_connect(int argc, char *argv[])
if (end == argv[1]) {
connection.net_idx = NET_IDX_INVALID;
bt_shell_printf("Invalid network index %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (argc > 2)
@@ -1728,8 +1672,10 @@ static void cmd_connect(int argc, char *argv[])
if (g_dbus_proxy_method_call(default_ctrl->proxy,
"StartDiscovery", NULL, start_discovery_reply,
- GUINT_TO_POINTER(TRUE), NULL) == FALSE)
+ GUINT_TO_POINTER(TRUE), NULL) == FALSE) {
bt_shell_printf("Failed to start mesh proxy discovery\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
g_dbus_proxy_method_call(default_ctrl->proxy, "StartDiscovery",
NULL, NULL, NULL, NULL);
@@ -1747,7 +1693,7 @@ static void prov_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);
}
set_connected_device(NULL);
@@ -1762,8 +1708,10 @@ static void prov_disconn_reply(DBusMessage *message, void *user_data)
if (g_dbus_proxy_method_call(default_ctrl->proxy,
"StartDiscovery", NULL, start_discovery_reply,
- GUINT_TO_POINTER(TRUE), NULL) == FALSE)
+ GUINT_TO_POINTER(TRUE), NULL) == FALSE) {
bt_shell_printf("Failed to start mesh proxy discovery\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
}
@@ -1777,15 +1725,17 @@ 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("Successfully disconnected\n");
if (proxy != connection.device)
- return;
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
set_connected_device(NULL);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_disconn(int argc, char *argv[])
@@ -1797,6 +1747,8 @@ static void cmd_disconn(int argc, char *argv[])
}
disconnect_device(disconn_reply, connection.device);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void mesh_prov_done(void *user_data, int status)
@@ -1841,14 +1793,14 @@ static void cmd_start_prov(int argc, char *argv[])
bt_shell_printf("Device with UUID %s not found.\n", argv[1]);
bt_shell_printf("Stale services? Remove device and "
"re-discover\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
/* TODO: add command to remove a node from mesh, i.e., "unprovision" */
if (node_is_provisioned(node)) {
bt_shell_printf("Already provisioned with unicast %4.4x\n",
node_get_primary(node));
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
dev = find_device_by_uuid(default_ctrl->mesh_devices,
@@ -1856,7 +1808,7 @@ static void cmd_start_prov(int argc, char *argv[])
if (!dev || !dev->proxy) {
bt_shell_printf("Could not find device proxy\n");
memset(connection.dev_uuid, 0, 16);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
proxy = dev->proxy;
@@ -1871,7 +1823,7 @@ static void cmd_start_prov(int argc, char *argv[])
proxy, NULL) == FALSE) {
bt_shell_printf("Failed to connect ");
print_device(proxy, NULL);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
} else {
bt_shell_printf("Trying to connect ");
print_device(proxy, NULL);
@@ -1881,15 +1833,22 @@ static void cmd_start_prov(int argc, char *argv[])
static void cmd_print_mesh(int argc, char *argv[])
{
- if (!prov_db_show(mesh_prov_db_filename))
+ if (!prov_db_show(mesh_prov_db_filename)) {
bt_shell_printf("Unavailable\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_print_local(int argc, char *argv[])
{
- if (!prov_db_show(mesh_local_config_filename))
+ if (!prov_db_show(mesh_local_config_filename)) {
bt_shell_printf("Unavailable\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static const struct bt_shell_menu main_menu = {
@@ -1945,6 +1904,7 @@ static void client_ready(GDBusClient *client, void *user_data)
int main(int argc, char *argv[])
{
GDBusClient *client;
+ int status;
int len;
int extra;
@@ -1956,8 +1916,8 @@ int main(int argc, char *argv[])
bt_shell_printf("Local config directory not provided.\n");
mesh_config_dir = "";
} else {
- bt_shell_printf("Reading prov_db.json and local_node.json from %s\n",
- mesh_config_dir);
+ bt_shell_printf("Reading prov_db.json and local_node.json from"
+ " %s\n", mesh_config_dir);
}
len = strlen(mesh_config_dir);
@@ -1971,11 +1931,11 @@ int main(int argc, char *argv[])
mesh_local_config_filename = g_malloc(len + strlen("local_node.json")
+ 2);
if (!mesh_local_config_filename)
- exit(1);
+ goto fail;
mesh_prov_db_filename = g_malloc(len + strlen("prov_db.json") + 2);
if (!mesh_prov_db_filename) {
- exit(1);
+ goto fail;
}
sprintf(mesh_local_config_filename, "%s", mesh_config_dir);
@@ -1991,7 +1951,7 @@ int main(int argc, char *argv[])
if (!prov_db_read_local_node(mesh_local_config_filename, true)) {
g_printerr("Failed to parse local node configuration file %s\n",
mesh_local_config_filename);
- exit(1);
+ goto fail;
}
sprintf(mesh_prov_db_filename, "%s", mesh_config_dir);
@@ -2006,7 +1966,7 @@ int main(int argc, char *argv[])
if (!prov_db_read(mesh_prov_db_filename)) {
g_printerr("Failed to parse provisioning database file %s\n",
mesh_prov_db_filename);
- exit(1);
+ goto fail;
}
dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
@@ -2030,7 +1990,7 @@ int main(int argc, char *argv[])
if (!onoff_client_init(PRIMARY_ELEMENT_IDX))
g_printerr("Failed to initialize mesh generic On/Off client\n");
- bt_shell_run();
+ status = bt_shell_run();
g_dbus_client_unref(client);
@@ -2042,5 +2002,9 @@ int main(int argc, char *argv[])
g_list_free(service_list);
g_list_free_full(ctrl_list, proxy_leak);
- return 0;
+ return status;
+
+fail:
+ bt_shell_cleanup();
+ return EXIT_FAILURE;
}
diff --git a/mesh/node.c b/mesh/node.c
index 0a60e792..9ff74196 100644
--- a/mesh/node.c
+++ b/mesh/node.c
@@ -417,7 +417,7 @@ bool node_parse_composition(struct mesh_node *node, uint8_t *data, uint16_t len)
m = *data++;
v = *data++;
- len -= 4;
+ len -= 2;
while (len >= 2 && m--) {
mod_id = get_le16(data);
@@ -691,7 +691,7 @@ bool node_set_model(struct mesh_node *node, uint8_t ele_idx, uint32_t id)
l = g_list_find_custom(ele->models, GUINT_TO_POINTER(id),
match_model_id);
if (l)
- return false;
+ return true;
model = g_malloc0(sizeof(struct mesh_model));
if (!model)
@@ -757,7 +757,7 @@ bool node_add_binding(struct mesh_node *node, uint8_t ele_idx,
GList *l;
model = get_model(node, ele_idx, model_id);
- if(!model)
+ if (!model)
return false;
l = g_list_find(model->bindings, GUINT_TO_POINTER(app_idx));
@@ -771,7 +771,25 @@ bool node_add_binding(struct mesh_node *node, uint8_t ele_idx,
model->bindings = g_list_append(model->bindings,
GUINT_TO_POINTER(app_idx));
+ return true;
+}
+
+bool node_add_subscription(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t model_id, uint16_t addr)
+{
+ struct mesh_model *model;
+ GList *l;
+
+ model = get_model(node, ele_idx, model_id);
+ if (!model)
+ return false;
+
+ l = g_list_find(model->subscriptions, GUINT_TO_POINTER(addr));
+ if (l)
+ return false;
+ model->subscriptions = g_list_append(model->subscriptions,
+ GUINT_TO_POINTER(addr));
return true;
}
diff --git a/mesh/node.h b/mesh/node.h
index 1fab80a1..a5b5c752 100644
--- a/mesh/node.h
+++ b/mesh/node.h
@@ -111,6 +111,8 @@ bool node_set_composition(struct mesh_node *node,
struct mesh_node_composition *comp);
bool node_add_binding(struct mesh_node *node, uint8_t ele_idx,
uint32_t model_id, uint16_t app_idx);
+bool node_add_subscription(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t model_id, uint16_t addr);
uint8_t node_get_default_ttl(struct mesh_node *node);
bool node_set_default_ttl(struct mesh_node *node, uint8_t ttl);
bool node_set_sequence_number(struct mesh_node *node, uint32_t seq);
diff --git a/mesh/onoff-model.c b/mesh/onoff-model.c
index dbbe6970..49be089a 100644
--- a/mesh/onoff-model.c
+++ b/mesh/onoff-model.c
@@ -58,8 +58,8 @@ static int client_bind(uint16_t app_idx, int action)
return MESH_STATUS_INSUFF_RESOURCES;
} else {
onoff_app_idx = app_idx;
- bt_shell_printf("On/Off client model: new binding %4.4x\n",
- app_idx);
+ bt_shell_printf("On/Off client model: new binding"
+ " %4.4x\n", app_idx);
}
} else {
if (onoff_app_idx == app_idx)
@@ -101,8 +101,8 @@ static void print_remaining_time(uint8_t remaining_time)
break;
}
- bt_shell_printf("\n\t\tRemaining time: %d hrs %d mins %d secs %d msecs\n",
- hours, minutes, secs, msecs);
+ bt_shell_printf("\n\t\tRemaining time: %d hrs %d mins %d secs %d"
+ " msecs\n", hours, minutes, secs, msecs);
}
@@ -134,7 +134,8 @@ static bool client_msg_recvd(uint16_t src, uint8_t *data,
src, data[0] ? "ON" : "OFF");
if (len == 3) {
- bt_shell_printf(", target = %s", data[1] ? "ON" : "OFF");
+ bt_shell_printf(", target = %s",
+ data[1] ? "ON" : "OFF");
print_remaining_time(data[2]);
} else
bt_shell_printf("\n");
@@ -183,10 +184,12 @@ static void cmd_set_node(int argc, char *argv[])
bt_shell_printf("Bad unicast address %s: "
"expected format 4 digit hex\n", argv[1]);
target = UNASSIGNED_ADDRESS;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
} else {
bt_shell_printf("Controlling ON/OFF for node %4.4x\n", dst);
target = dst;
set_menu_prompt("on/off", argv[1]);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
}
@@ -212,7 +215,7 @@ static void cmd_get_status(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
node = node_find_by_addr(target);
@@ -222,8 +225,12 @@ static void cmd_get_status(int argc, char *argv[])
n = mesh_opcode_set(OP_GENERIC_ONOFF_GET, msg);
- if (!send_cmd(msg, n))
+ if (!send_cmd(msg, n)) {
bt_shell_printf("Failed to send \"GENERIC ON/OFF GET\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_set(int argc, char *argv[])
@@ -234,7 +241,7 @@ static void cmd_set(int argc, char *argv[])
if (IS_UNASSIGNED(target)) {
bt_shell_printf("Destination not set\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
node = node_find_by_addr(target);
@@ -245,16 +252,19 @@ static void cmd_set(int argc, char *argv[])
if ((read_input_parameters(argc, argv) != 1) &&
parms[0] != 0 && parms[0] != 1) {
bt_shell_printf("Bad arguments: Expecting \"0\" or \"1\"\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
n = mesh_opcode_set(OP_GENERIC_ONOFF_SET, msg);
msg[n++] = parms[0];
msg[n++] = trans_id++;
- if (!send_cmd(msg, n))
+ if (!send_cmd(msg, n)) {
bt_shell_printf("Failed to send \"GENERIC ON/OFF SET\"\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static const struct bt_shell_menu onoff_menu = {
diff --git a/mesh/prov-db.c b/mesh/prov-db.c
index 8a7b47f6..019b4e17 100644
--- a/mesh/prov-db.c
+++ b/mesh/prov-db.c
@@ -409,6 +409,36 @@ static json_object* find_configured_model(struct mesh_node *node, int ele_idx,
return NULL;
}
+static bool parse_subscriptions(struct mesh_node *node, int ele_idx,
+ uint32_t model_id, json_object *jsubscriptions)
+
+{
+ int cnt;
+ int i;
+ int addr;
+
+ cnt = json_object_array_length(jsubscriptions);
+
+ for (i = 0; i < cnt; ++i) {
+ char *str;
+ json_object *jsubscription;
+
+ jsubscription = json_object_array_get_idx(jsubscriptions, i);
+ if (!jsubscription)
+ return false;
+
+ str = (char *)json_object_get_string(jsubscription);
+
+ if (sscanf(str, "%04x", &addr) != 1)
+ return false;
+
+ if (!node_add_subscription(node, ele_idx, model_id, addr))
+ return false;
+ }
+
+ return true;
+}
+
static bool parse_configuration_models(struct mesh_node *node, int ele_idx,
json_object *jmodels)
{
@@ -441,11 +471,15 @@ static bool parse_configuration_models(struct mesh_node *node, int ele_idx,
model_id += 0xffff0000;
json_object_object_get_ex(jmodel, "bind", &jarray);
+
if (jarray && !parse_bindings(node, ele_idx, model_id, jarray))
return false;
- json_object_object_get_ex(jmodel, "publish", &jvalue);
+ json_object_object_get_ex(jmodel, "subscribe", &jarray);
+ if (jarray && !parse_subscriptions(node, ele_idx, model_id, jarray))
+ return false;
+ json_object_object_get_ex(jmodel, "publish", &jvalue);
if (jvalue && !parse_model_pub(node, ele_idx, model_id, jvalue))
return false;
}
@@ -653,7 +687,7 @@ bool prov_db_add_node_composition(struct mesh_node *node, uint8_t *data,
put_uint16(jcomp, "cid", comp->cid);
put_uint16(jcomp, "pid", comp->pid);
- put_uint16(jcomp, "vid", comp->pid);
+ put_uint16(jcomp, "vid", comp->vid);
put_uint16(jcomp, "crpl", comp->crpl);
jfeatures = json_object_new_object();
@@ -1070,14 +1104,13 @@ done:
bool prov_db_add_binding(struct mesh_node *node, uint8_t ele_idx,
uint32_t model_id, uint16_t app_idx)
{
- json_object *jmain;
+ bool local = (node == node_get_local_node());
+ json_object *jbindings = NULL;
json_object *jmodel;
json_object *jvalue;
- json_object *jbindings = NULL;
- bool local = (node == node_get_local_node());
+ json_object *jmain;
jmodel = get_jmodel_obj(node, ele_idx, model_id, &jmain);
-
if (!jmodel)
return false;
@@ -1098,6 +1131,34 @@ bool prov_db_add_binding(struct mesh_node *node, uint8_t ele_idx,
return true;
}
+bool prov_db_add_subscription(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t model_id, uint16_t addr)
+{
+ bool local = (node == node_get_local_node());
+ json_object *jsubscriptions = NULL;
+ json_object *jmodel;
+ json_object *jmain;
+
+ jmodel = get_jmodel_obj(node, ele_idx, model_id, &jmain);
+ if (!jmodel)
+ return false;
+
+ json_object_object_get_ex(jmodel, "subscribe", &jsubscriptions);
+
+ if (!jsubscriptions) {
+ jsubscriptions = json_object_new_array();
+ json_object_object_add(jmodel, "subscribe", jsubscriptions);
+ }
+
+ put_uint16_array_entry(jsubscriptions, addr);
+
+ prov_file_write(jmain, local);
+
+ json_object_put(jmain);
+
+ return true;
+}
+
bool prov_db_node_set_model_pub(struct mesh_node *node, uint8_t ele_idx,
uint32_t model_id,
struct mesh_publication *pub)
@@ -1225,6 +1286,7 @@ static bool parse_node_composition(struct mesh_node *node, json_object *jcomp)
{
json_object *jvalue;
json_object *jelements;
+ json_object *jfeatures;
json_bool enable;
char *str;
struct mesh_node_composition comp;
@@ -1244,7 +1306,7 @@ static bool parse_node_composition(struct mesh_node *node, json_object *jcomp)
str = (char *)json_object_get_string(jvalue);
- if (sscanf(str, "%04hx", &comp.vid) != 1)
+ if (sscanf(str, "%04hx", &comp.pid) != 1)
return false;
json_object_object_get_ex(jcomp, "vid", &jvalue);
@@ -1266,19 +1328,24 @@ static bool parse_node_composition(struct mesh_node *node, json_object *jcomp)
return false;
/* Extract features */
- json_object_object_get_ex(jcomp, "relay", &jvalue);
+
+ json_object_object_get_ex(jcomp, "features", &jfeatures);
+ if (!jfeatures)
+ return false;
+
+ json_object_object_get_ex(jfeatures, "relay", &jvalue);
enable = json_object_get_boolean(jvalue);
comp.relay = (enable) ? true : false;
- json_object_object_get_ex(jcomp, "proxy", &jvalue);
+ json_object_object_get_ex(jfeatures, "proxy", &jvalue);
enable = json_object_get_boolean(jvalue);
comp.proxy = (enable) ? true : false;
- json_object_object_get_ex(jcomp, "friend", &jvalue);
+ json_object_object_get_ex(jfeatures, "friend", &jvalue);
enable = json_object_get_boolean(jvalue);
comp.friend = (enable) ? true : false;
- json_object_object_get_ex(jcomp, "lowPower", &jvalue);
+ json_object_object_get_ex(jfeatures, "lowPower", &jvalue);
enable = json_object_get_boolean(jvalue);
comp.lpn = (enable) ? true : false;
diff --git a/mesh/prov-db.h b/mesh/prov-db.h
index b1e4c629..b8584a8c 100644
--- a/mesh/prov-db.h
+++ b/mesh/prov-db.h
@@ -30,6 +30,8 @@ bool prov_db_add_node_composition(struct mesh_node *node, uint8_t *data,
bool prov_db_node_keys(struct mesh_node *node, GList *idxs, const char *desc);
bool prov_db_add_binding(struct mesh_node *node, uint8_t ele_idx,
uint32_t model_id, uint16_t app_idx);
+bool prov_db_add_subscription(struct mesh_node *node, uint8_t ele_idx,
+ uint32_t model_id, uint16_t addr);
bool prov_db_node_set_ttl(struct mesh_node *node, uint8_t ttl);
bool prov_db_node_set_iv_seq(struct mesh_node *node, uint32_t iv, uint32_t seq);
bool prov_db_local_set_iv_index(uint32_t iv_index, bool update, bool prov);
diff --git a/src/adapter.c b/src/adapter.c
index a01f33c4..9c91a4fe 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1913,7 +1913,7 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
struct btd_adapter *adapter = user_data;
- struct watch_client *client = adapter->discovery_list->data;
+ struct watch_client *client;
const struct mgmt_cp_start_discovery *rp = param;
DBusMessage *reply;
@@ -1922,7 +1922,7 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
/* Is there are no clients the discovery must have been stopped while
* discovery command was pending.
*/
- if (!client) {
+ if (!adapter->discovery_list) {
struct mgmt_cp_stop_discovery cp;
if (status != MGMT_STATUS_SUCCESS)
@@ -1936,6 +1936,8 @@ static void start_discovery_complete(uint8_t status, uint16_t length,
return;
}
+ client = adapter->discovery_list->data;
+
if (length < sizeof(*rp)) {
btd_error(adapter->dev_id,
"Wrong size of start discovery return parameters");
diff --git a/src/device.c b/src/device.c
index 08a02348..544b06d1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2871,6 +2871,7 @@ static void browse_request_complete(struct browse_req *req, uint8_t type,
{
struct btd_device *dev = req->device;
DBusMessage *reply = NULL;
+ DBusMessage *msg;
if (req->type != type)
return;
@@ -2907,19 +2908,31 @@ static void browse_request_complete(struct browse_req *req, uint8_t type,
goto done;
}
- if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Connect"))
- reply = dev_connect(dbus_conn, req->msg, dev);
- else if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
+ /* if successfully resolved services we need to free browsing request
+ * before passing message back to connect functions, otherwise
+ * device->browse is set and "InProgress" error is returned instead
+ * of actually connecting services
+ */
+ msg = dbus_message_ref(req->msg);
+ browse_request_free(req);
+ req = NULL;
+
+ if (dbus_message_is_method_call(msg, DEVICE_INTERFACE, "Connect"))
+ reply = dev_connect(dbus_conn, msg, dev);
+ else if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
"ConnectProfile"))
- reply = connect_profile(dbus_conn, req->msg, dev);
+ reply = connect_profile(dbus_conn, msg, dev);
else
- reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
+ reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+ dbus_message_unref(msg);
done:
if (reply)
g_dbus_send_message(dbus_conn, reply);
- browse_request_free(req);
+ if (req)
+ browse_request_free(req);
}
static void device_set_svc_refreshed(struct btd_device *device, bool value)
diff --git a/src/shared/ecc.c b/src/shared/ecc.c
index 41be02b7..15f6b8a9 100755
--- a/src/shared/ecc.c
+++ b/src/shared/ecc.c
@@ -66,9 +66,13 @@ typedef struct {
#define CURVE_N_32 { 0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull, \
0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull }
+#define CURVE_B_32 { 0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull, \
+ 0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull }
+
static uint64_t curve_p[NUM_ECC_DIGITS] = CURVE_P_32;
static struct ecc_point curve_g = CURVE_G_32;
static uint64_t curve_n[NUM_ECC_DIGITS] = CURVE_N_32;
+static uint64_t curve_b[NUM_ECC_DIGITS] = CURVE_B_32;
static bool get_random_number(uint64_t *vli)
{
@@ -183,6 +187,19 @@ static int vli_cmp(const uint64_t *left, const uint64_t *right)
return 0;
}
+/* Constant-time comparison function - secure way to compare long integers */
+/* Returns one if left == right, zero otherwise. */
+static bool vli_equal(const uint64_t *left, const uint64_t *right)
+{
+ uint64_t diff = 0;
+ int i;
+
+ for (i = NUM_ECC_DIGITS - 1; i >= 0; --i)
+ diff |= (left[i] ^ right[i]);
+
+ return (diff == 0);
+}
+
/* Computes result = in << c, returning carry. Can modify in place
* (if result == in). 0 < shift < 64.
*/
@@ -770,6 +787,34 @@ static void ecc_point_mult(struct ecc_point *result,
vli_set(result->y, ry[0]);
}
+static bool ecc_valid_point(const struct ecc_point *point)
+{
+ uint64_t tmp1[NUM_ECC_DIGITS];
+ uint64_t tmp2[NUM_ECC_DIGITS];
+ uint64_t _3[NUM_ECC_DIGITS] = { 3 }; /* -a = 3 */
+
+ /* The point at infinity is invalid. */
+ if (ecc_point_is_zero(point))
+ return false;
+
+ /* x and y must be smaller than p. */
+ if (vli_cmp(curve_p, point->x) != 1 ||
+ vli_cmp(curve_p, point->y) != 1)
+ return false;
+
+ /* Computes result = y^2. */
+ vli_mod_square_fast(tmp1, point->y);
+
+ /* Computes result = x^3 + ax + b. result must not overlap x. */
+ vli_mod_square_fast(tmp2, point->x); /* r = x^2 */
+ vli_mod_sub(tmp2, tmp2, _3, curve_p); /* r = x^2 - 3 */
+ vli_mod_mult_fast(tmp2, tmp2, point->x); /* r = x^3 - 3x */
+ vli_mod_add(tmp2, tmp2, curve_b, curve_p); /* r = x^3 - 3x + b */
+
+ /* Make sure that y^2 == x^3 + ax + b */
+ return vli_equal(tmp1, tmp2);
+}
+
/* Little endian byte-array to native conversion */
static void ecc_bytes2native(const uint8_t bytes[ECC_BYTES],
uint64_t native[NUM_ECC_DIGITS])
@@ -811,33 +856,59 @@ static void ecc_native2bytes(const uint64_t native[NUM_ECC_DIGITS],
}
}
-bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32])
+bool ecc_make_public_key(const uint8_t private_key[32], uint8_t public_key[64])
{
struct ecc_point pk;
uint64_t priv[NUM_ECC_DIGITS];
- unsigned tries = 0;
- do {
- if (!get_random_number(priv) || (tries++ >= MAX_TRIES))
- return false;
+ ecc_bytes2native(private_key, priv);
- if (vli_is_zero(priv))
- continue;
+ if (vli_is_zero(priv))
+ return false;
- /* Make sure the private key is in the range [1, n-1]. */
- if (vli_cmp(curve_n, priv) != 1)
- continue;
+ /* Make sure the private key is in the range [1, n-1]. */
+ if (vli_cmp(curve_n, priv) != 1)
+ return false;
- ecc_point_mult(&pk, &curve_g, priv, NULL, vli_num_bits(priv));
- } while (ecc_point_is_zero(&pk));
+ ecc_point_mult(&pk, &curve_g, priv, NULL, vli_num_bits(priv));
+
+ if (ecc_point_is_zero(&pk))
+ return false;
- ecc_native2bytes(priv, private_key);
ecc_native2bytes(pk.x, public_key);
ecc_native2bytes(pk.y, &public_key[32]);
return true;
}
+bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32])
+{
+ uint64_t priv[NUM_ECC_DIGITS];
+ unsigned int tries = 0;
+ bool result = false;
+
+ for (tries = 0; !result && tries < MAX_TRIES; tries++) {
+ if (!get_random_number(priv))
+ continue;
+
+ ecc_native2bytes(priv, private_key);
+
+ result = ecc_make_public_key(private_key, public_key);
+ }
+
+ return result;
+}
+
+bool ecc_valid_public_key(const uint8_t public_key[64])
+{
+ struct ecc_point pk;
+
+ ecc_bytes2native(public_key, pk.x);
+ ecc_bytes2native(&public_key[32], pk.y);
+
+ return ecc_valid_point(&pk);
+}
+
bool ecdh_shared_secret(const uint8_t public_key[64],
const uint8_t private_key[32],
uint8_t secret[32])
@@ -851,6 +922,10 @@ bool ecdh_shared_secret(const uint8_t public_key[64],
ecc_bytes2native(public_key, pk.x);
ecc_bytes2native(&public_key[32], pk.y);
+
+ if (!ecc_valid_point(&pk))
+ return false;
+
ecc_bytes2native(private_key, priv);
ecc_point_mult(&product, &pk, priv, rand, vli_num_bits(priv));
diff --git a/src/shared/ecc.h b/src/shared/ecc.h
index e971375a..a88e735c 100755
--- a/src/shared/ecc.h
+++ b/src/shared/ecc.h
@@ -27,16 +27,37 @@
#include <stdbool.h>
#include <stdint.h>
+/* Create a public key from a private key.
+ *
+ * Outputs:
+ * private_key - Const private key
+ * public_key - Will be filled in with the public key.
+ *
+ * Returns true if the public key was generated successfully, false
+ * if an error occurred. The keys are with the LSB first.
+ */
+bool ecc_make_public_key(const uint8_t private_key[32], uint8_t public_key[64]);
+
/* Create a public/private key pair.
+ *
* Outputs:
* public_key - Will be filled in with the public key.
- * private_Key - Will be filled in with the private key.
+ * private_key - Will be filled in with the private key.
*
* Returns true if the key pair was generated successfully, false
- * if an error occurred. They keys are with the LSB first.
+ * if an error occurred. The keys are with the LSB first.
*/
bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32]);
+/* Check to see if a public key is valid.
+ *
+ * Inputs:
+ * public_key - The public key to check.
+ *
+ * Returns true if the public key is valid, false if it is invalid.
+*/
+bool ecc_valid_public_key(const uint8_t public_key[64]);
+
/* Compute a shared secret given your secret key and someone else's
* public key.
* Note: It is recommended that you hash the result of ecdh_shared_secret
@@ -44,7 +65,7 @@ bool ecc_make_key(uint8_t public_key[64], uint8_t private_key[32]);
*
* Inputs:
* public_key - The public key of the remote party.
- * private_Key - Your private key.
+ * private_key - Your private key.
*
* Outputs:
* secret - Will be filled in with the shared secret value.
diff --git a/src/shared/mainloop-glib.c b/src/shared/mainloop-glib.c
new file mode 100644
index 00000000..8436969b
--- /dev/null
+++ b/src/shared/mainloop-glib.c
@@ -0,0 +1,117 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <sys/signalfd.h>
+
+#include <glib.h>
+
+#include "mainloop.h"
+
+static GMainLoop *main_loop;
+static int exit_status;
+
+void mainloop_init(void)
+{
+ main_loop = g_main_loop_new(NULL, FALSE);
+}
+
+void mainloop_quit(void)
+{
+ if (!main_loop)
+ return;
+
+ g_main_loop_quit(main_loop);
+}
+
+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)
+{
+ if (!main_loop)
+ return -EINVAL;
+
+ g_main_loop_run(main_loop);
+
+ g_main_loop_unref(main_loop);
+ main_loop = NULL;
+
+ return exit_status;
+}
+
+int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback,
+ void *user_data, mainloop_destroy_func destroy)
+{
+ return -ENOSYS;
+}
+
+int mainloop_modify_fd(int fd, uint32_t events)
+{
+ return -ENOSYS;
+}
+
+int mainloop_remove_fd(int fd)
+{
+ return -ENOSYS;
+}
+
+int mainloop_add_timeout(unsigned int msec, mainloop_timeout_func callback,
+ void *user_data, mainloop_destroy_func destroy)
+{
+ return -ENOSYS;
+}
+
+int mainloop_modify_timeout(int fd, unsigned int msec)
+{
+ return -ENOSYS;
+}
+
+int mainloop_remove_timeout(int id)
+{
+ return -ENOSYS;
+}
+
+int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback,
+ void *user_data, mainloop_destroy_func destroy)
+{
+ return -ENOSYS;
+}
diff --git a/src/shared/mainloop.c b/src/shared/mainloop.c
index 09c46a79..e6ab9c43 100755
--- a/src/shared/mainloop.c
+++ b/src/shared/mainloop.c
@@ -42,7 +42,7 @@
static int epoll_fd;
static int epoll_terminate;
-static int exit_status;
+static int exit_status = EXIT_SUCCESS;
struct mainloop_data {
int fd;
@@ -141,8 +141,6 @@ int mainloop_run(void)
}
}
- exit_status = EXIT_SUCCESS;
-
while (!epoll_terminate) {
struct epoll_event events[MAX_EPOLL_EVENTS];
int n, nfds;
diff --git a/src/shared/queue.c b/src/shared/queue.c
index 5ddb8326..60df1114 100755
--- a/src/shared/queue.c
+++ b/src/shared/queue.c
@@ -280,9 +280,12 @@ void *queue_remove_if(struct queue *queue, queue_match_func_t function,
{
struct queue_entry *entry, *prev = NULL;
- if (!queue || !function)
+ if (!queue)
return NULL;
+ if (!function)
+ function = direct_match;
+
entry = queue->head;
while (entry) {
diff --git a/src/shared/shell.c b/src/shared/shell.c
index 6cdea1c7..e7f17e02 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -29,6 +29,7 @@
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <stdbool.h>
#include <signal.h>
#include <sys/signalfd.h>
@@ -37,8 +38,9 @@
#include <readline/readline.h>
#include <readline/history.h>
-#include <glib.h>
+#include "src/shared/mainloop.h"
+#include "src/shared/timeout.h"
#include "src/shared/io.h"
#include "src/shared/util.h"
#include "src/shared/queue.h"
@@ -54,9 +56,17 @@
printf(COLOR_BLUE "%s %-*s " COLOR_OFF "%s\n", \
cmd, (int)(CMD_LENGTH - strlen(cmd)), "", desc)
-static GMainLoop *main_loop;
+struct bt_shell_env {
+ char *name;
+ void *value;
+};
static struct {
+ bool init;
+ int argc;
+ char **argv;
+ bool mode;
+ int timeout;
struct io *input;
bool saved_prompt;
@@ -66,6 +76,9 @@ 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;
static void shell_print_menu(void);
@@ -73,19 +86,23 @@ static void shell_print_menu(void);
static void cmd_version(int argc, char *argv[])
{
bt_shell_printf("Version %s\n", VERSION);
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_quit(int argc, char *argv[])
{
- g_main_loop_quit(main_loop);
+ mainloop_quit();
}
static void cmd_help(int argc, char *argv[])
{
shell_print_menu();
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static const struct bt_shell_menu *find_menu(const char *name)
+static const struct bt_shell_menu *find_menu(const char *name, size_t len)
{
const struct queue_entry *entry;
@@ -93,8 +110,10 @@ static const struct bt_shell_menu *find_menu(const char *name)
entry = entry->next) {
struct bt_shell_menu *menu = entry->data;
- if (!strcmp(menu->name, name))
+ if (!strncmp(menu->name, name, len))
return menu;
+
+
}
return NULL;
@@ -131,18 +150,20 @@ static void cmd_menu(int argc, char *argv[])
if (argc < 2 || !strlen(argv[1])) {
bt_shell_printf("Missing name argument\n");
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
- menu = find_menu(argv[1]);
+ menu = find_menu(argv[1], strlen(argv[1]));
if (!menu) {
bt_shell_printf("Unable find menu with name: %s\n", argv[1]);
- return;
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bt_shell_set_menu(menu);
shell_print_menu();
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static bool cmd_menu_exists(const struct bt_shell_menu *menu)
@@ -177,6 +198,17 @@ static bool cmd_back_exists(const struct bt_shell_menu *menu)
return true;
}
+static void cmd_export(int argc, char *argv[])
+{
+ const struct queue_entry *entry;
+
+ for (entry = queue_get_entries(data.envs); entry; entry = entry->next) {
+ struct bt_shell_env *env = entry->data;
+
+ print_text(COLOR_HIGHLIGHT, "%s=%p", env->name, env->value);
+ }
+}
+
static const struct bt_shell_menu_entry default_menu[] = {
{ "back", NULL, cmd_back, "Return to main menu", NULL,
NULL, cmd_back_exists },
@@ -188,9 +220,20 @@ static const struct bt_shell_menu_entry default_menu[] = {
{ "exit", NULL, cmd_quit, "Quit program" },
{ "help", NULL, cmd_help,
"Display help about this program" },
+ { "export", NULL, cmd_export,
+ "Print evironment variables" },
{ }
};
+static void shell_print_help(void)
+{
+ print_text(COLOR_HIGHLIGHT,
+ "\n"
+ "Use \"help\" for a list of available commands in a menu.\n"
+ "Use \"menu <submenu>\" if you want to enter any submenu.\n"
+ "Use \"back\" if you want to return to menu main.");
+}
+
static void shell_print_menu(void)
{
const struct bt_shell_menu_entry *entry;
@@ -229,18 +272,18 @@ static int parse_args(char *arg, wordexp_t *w, char *del, int flags)
{
char *str;
- str = g_strdelimit(arg, del, '"');
+ str = strdelimit(arg, del, '"');
if (wordexp(str, w, flags)) {
- g_free(str);
+ free(str);
return -EINVAL;
}
- /* If argument ends with ,,, set we_offs bypass strict checks */
- if (w->we_wordc && g_str_has_suffix(w->we_wordv[w->we_wordc -1], "..."))
+ /* If argument ends with ... set we_offs bypass strict checks */
+ if (w->we_wordc && !strsuffix(w->we_wordv[w->we_wordc -1], "..."))
w->we_offs = 1;
- g_free(str);
+ free(str);
return 0;
}
@@ -269,16 +312,30 @@ 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 );
+ free(man);
return -EINVAL;
}
+ free(man);
+
/* Check if there are enough arguments */
- if ((unsigned) argc - 1 < w.we_wordc && !w.we_offs) {
+ if ((unsigned) argc - 1 < w.we_wordc) {
print_text(COLOR_HIGHLIGHT, "Missing %s argument",
w.we_wordv[argc - 1]);
goto fail;
@@ -290,10 +347,13 @@ 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);
+ free(opt);
return -EINVAL;
}
+ free(opt);
+
/* Check if there are too many arguments */
if ((unsigned) argc - 1 > w.we_wordc && !w.we_offs) {
print_text(COLOR_HIGHLIGHT, "Too many arguments: %d > %zu",
@@ -301,15 +361,21 @@ optional:
goto fail;
}
+ w.we_offs = 0;
wordfree(&w);
exec:
+ data.exec = entry;
+
if (entry->func)
entry->func(argc, argv);
+ data.exec = NULL;
+
return 0;
fail:
+ w.we_offs = 0;
wordfree(&w);
return -EINVAL;
}
@@ -335,15 +401,56 @@ static int menu_exec(const struct bt_shell_menu_entry *entry,
return -ENOENT;
}
-static void shell_exec(int argc, char *argv[])
+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], strlen(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 int shell_exec(int argc, char *argv[])
+{
+ int err;
+
if (!data.menu || !argv[0])
- return;
+ return -EINVAL;
- if (menu_exec(default_menu, argc, argv) == -ENOENT) {
- if (menu_exec(data.menu->entries, argc, argv) == -ENOENT)
- print_text(COLOR_HIGHLIGHT, "Invalid command");
+ err = menu_exec(default_menu, argc, argv);
+ if (err == -ENOENT) {
+ err = menu_exec(data.menu->entries, argc, argv);
+ if (err == -ENOENT) {
+ err = submenu_exec(argc, argv);
+ if (err == -ENOENT) {
+ print_text(COLOR_HIGHLIGHT,
+ "Invalid command in menu %s: %s",
+ data.menu->name , argv[0]);
+ shell_print_help();
+ }
+ }
}
+
+ return err;
}
void bt_shell_printf(const char *fmt, ...)
@@ -353,16 +460,25 @@ void bt_shell_printf(const char *fmt, ...)
char *saved_line;
int saved_point;
+ 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) {
saved_point = rl_point;
saved_line = rl_copy_text(0, rl_end);
- if (!data.saved_prompt) {
+ if (!data.saved_prompt)
rl_save_prompt();
- rl_replace_line("", 0);
- rl_redisplay();
- }
+ rl_replace_line("", 0);
+ rl_redisplay();
}
va_start(args, fmt);
@@ -379,61 +495,42 @@ void bt_shell_printf(const char *fmt, ...)
}
}
+static void print_string(const char *str, void *user_data)
+{
+ bt_shell_printf("%s\n", str);
+}
+
void bt_shell_hexdump(const unsigned char *buf, size_t len)
{
- static const char hexdigits[] = "0123456789abcdef";
- char str[68];
- size_t i;
+ util_hexdump(' ', buf, len, print_string, NULL);
+}
- if (!len)
+void bt_shell_usage()
+{
+ if (!data.exec)
return;
- str[0] = ' ';
-
- for (i = 0; i < len; i++) {
- str[((i % 16) * 3) + 1] = ' ';
- str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4];
- str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf];
- str[(i % 16) + 51] = isprint(buf[i]) ? buf[i] : '.';
-
- if ((i + 1) % 16 == 0) {
- str[49] = ' ';
- str[50] = ' ';
- str[67] = '\0';
- bt_shell_printf("%s\n", str);
- str[0] = ' ';
- }
- }
-
- if (i % 16 > 0) {
- size_t j;
- for (j = (i % 16); j < 16; j++) {
- str[(j * 3) + 1] = ' ';
- str[(j * 3) + 2] = ' ';
- str[(j * 3) + 3] = ' ';
- str[j + 51] = ' ';
- }
- str[49] = ' ';
- str[50] = ' ';
- str[67] = '\0';
- bt_shell_printf("%s\n", str);
- }
+ 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)
{
+ 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)
return;
- rl_save_prompt();
- rl_message(COLOR_RED "[%s]" COLOR_OFF " %s ", label, msg);
-
data.saved_prompt = true;
data.saved_func = func;
data.saved_user_data = user_data;
+
+ rl_save_prompt();
+ bt_shell_printf(COLOR_RED "[%s]" COLOR_OFF " %s ", label, msg);
}
int bt_shell_release_prompt(const char *input)
@@ -467,7 +564,7 @@ static void rl_handler(char *input)
rl_insert_text("quit");
rl_redisplay();
rl_crlf();
- g_main_loop_quit(main_loop);
+ mainloop_quit();
return;
}
@@ -521,12 +618,15 @@ static char *find_cmd(const char *text,
static char *cmd_generator(const char *text, int state)
{
static int index;
- static bool default_menu_enabled;
+ static bool default_menu_enabled, submenu_enabled;
+ static const struct bt_shell_menu *menu;
char *cmd;
if (!state) {
index = 0;
+ menu = NULL;
default_menu_enabled = true;
+ submenu_enabled = false;
}
if (default_menu_enabled) {
@@ -535,15 +635,124 @@ static char *cmd_generator(const char *text, int state)
return cmd;
} else {
index = 0;
+ menu = data.menu;
default_menu_enabled = false;
}
}
- return find_cmd(text, data.menu->entries, &index);
+ if (!submenu_enabled) {
+ cmd = find_cmd(text, menu->entries, &index);
+ if (cmd || menu != data.main)
+ return cmd;
+
+ cmd = strrchr(text, '.');
+ if (!cmd)
+ return NULL;
+
+ menu = find_menu(text, cmd - text);
+ if (!menu)
+ return NULL;
+
+ index = 0;
+ submenu_enabled = true;
+ }
+
+ cmd = find_cmd(text + strlen(menu->name) + 1, menu->entries, &index);
+ if (cmd) {
+ int err;
+ char *tmp;
+
+ err = asprintf(&tmp, "%s.%s", menu->name, cmd);
+
+ free(cmd);
+
+ if (err < 0)
+ return NULL;
+
+ cmd = tmp;
+ }
+
+ return cmd;
+}
+
+static wordexp_t args;
+
+static char *arg_generator(const char *text, int state)
+{
+ static unsigned int index, len;
+ const char *arg;
+
+ if (!state) {
+ index = 0;
+ len = strlen(text);
+ }
+
+ while (index < args.we_wordc) {
+ arg = args.we_wordv[index];
+ index++;
+
+ if (!strncmp(arg, text, len))
+ return strdup(arg);
+ }
+
+ return NULL;
+}
+
+static char **args_completion(const struct bt_shell_menu_entry *entry, int argc,
+ const char *text)
+{
+ char **matches = NULL;
+ char *str;
+ int index;
+
+ index = text[0] == '\0' ? argc - 1 : argc - 2;
+ if (index < 0)
+ return NULL;
+
+ if (!entry->arg)
+ goto end;
+
+ str = strdup(entry->arg);
+
+ if (parse_args(str, &args, "<>[]", WRDE_NOCMD))
+ goto done;
+
+ /* Check if argument is valid */
+ if ((unsigned) index > args.we_wordc - 1)
+ goto done;
+
+ /* Check if there are multiple values */
+ if (!strrchr(entry->arg, '/'))
+ goto done;
+
+ free(str);
+
+ /* Split values separated by / */
+ str = strdelimit(args.we_wordv[index], "/", ' ');
+
+ args.we_offs = 0;
+ wordfree(&args);
+
+ if (wordexp(str, &args, WRDE_NOCMD))
+ goto done;
+
+ rl_completion_display_matches_hook = NULL;
+ matches = rl_completion_matches(text, arg_generator);
+
+done:
+ free(str);
+end:
+ if (!matches && text[0] == '\0')
+ bt_shell_printf("Usage: %s %s\n", entry->cmd,
+ entry->arg ? entry->arg : "");
+
+ args.we_offs = 0;
+ wordfree(&args);
+ return matches;
}
static char **menu_completion(const struct bt_shell_menu_entry *entry,
- const char *text, char *input_cmd)
+ const char *text, int argc, char *input_cmd)
{
char **matches = NULL;
@@ -552,9 +761,7 @@ static char **menu_completion(const struct bt_shell_menu_entry *entry,
continue;
if (!entry->gen) {
- if (text[0] == '\0')
- bt_shell_printf("Usage: %s %s\n", entry->cmd,
- entry->arg ? entry->arg : "");
+ matches = args_completion(entry, argc, text);
break;
}
@@ -579,9 +786,11 @@ static char **shell_completion(const char *text, int start, int end)
if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))
return NULL;
- matches = menu_completion(default_menu, text, w.we_wordv[0]);
+ matches = menu_completion(default_menu, text, w.we_wordc,
+ w.we_wordv[0]);
if (!matches)
matches = menu_completion(data.menu->entries, text,
+ w.we_wordc,
w.we_wordv[0]);
wordfree(&w);
@@ -598,7 +807,7 @@ static char **shell_completion(const char *text, int start, int end)
static bool io_hup(struct io *io, void *user_data)
{
- g_main_loop_quit(main_loop);
+ mainloop_quit();
return false;
}
@@ -618,12 +827,12 @@ 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();
rl_redisplay();
- break;
+ return true;
}
/*
@@ -636,9 +845,11 @@ static bool signal_read(struct io *io, void *user_data)
/* fall through */
case SIGTERM:
if (!terminated) {
- rl_replace_line("", 0);
- rl_crlf();
- g_main_loop_quit(main_loop);
+ if (!data.mode) {
+ rl_replace_line("", 0);
+ rl_crlf();
+ }
+ mainloop_quit();
}
terminated = true;
@@ -680,6 +891,9 @@ static struct io *setup_signalfd(void)
static void rl_init(void)
{
+ if (data.mode)
+ return;
+
setlinebuf(stdout);
rl_attempted_completion_function = shell_completion;
@@ -690,6 +904,7 @@ static void rl_init(void)
static const struct option main_options[] = {
{ "version", no_argument, 0, 'v' },
{ "help", no_argument, 0, 'h' },
+ { "timeout", required_argument, 0, 't' },
};
static void usage(int argc, char **argv, const struct bt_shell_opt *opt)
@@ -705,13 +920,14 @@ 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--version \tDisplay version\n"
+ printf("\t--timeout \tTimeout in seconds for non-interactive mode\n"
+ "\t--version \tDisplay version\n"
"\t--help \t\tDisplay help\n");
}
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;
@@ -723,9 +939,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) {
@@ -737,7 +953,17 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
usage(argc, argv, opt);
exit(EXIT_SUCCESS);
return;
+ case 't':
+ 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);
@@ -746,36 +972,87 @@ void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt)
*opt->optarg[index - offset] = optarg;
}
+
+ index = -1;
}
- main_loop = g_main_loop_new(NULL, FALSE);
+ data.argc = argc - optind;
+ data.argv = argv + optind;
+ optind = 0;
+ data.mode = (data.argc > 0);
+
+ if (data.mode)
+ bt_shell_set_env("NON_INTERACTIVE", &data.mode);
+
+ mainloop_init();
rl_init();
+
+ data.init = true;
}
static void rl_cleanup(void)
{
+ if (data.mode)
+ return;
+
rl_message("");
rl_callback_handler_remove();
}
-void bt_shell_run(void)
+static void env_destroy(void *data)
+{
+ struct bt_shell_env *env = data;
+
+ free(env->name);
+ free(env);
+}
+
+int bt_shell_run(void)
{
struct io *signal;
+ int status;
signal = setup_signalfd();
- g_main_loop_run(main_loop);
+ status = mainloop_run();
+
+ io_destroy(signal);
+
+ bt_shell_cleanup();
+ return status;
+}
+
+void bt_shell_cleanup(void)
+{
bt_shell_release_prompt("");
bt_shell_detach();
- io_destroy(signal);
-
- g_main_loop_unref(main_loop);
- main_loop = NULL;
+ if (data.envs) {
+ queue_destroy(data.envs, env_destroy);
+ data.envs = NULL;
+ }
rl_cleanup();
+
+ 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)
@@ -806,13 +1083,11 @@ bool bt_shell_add_submenu(const struct bt_shell_menu *menu)
void bt_shell_set_prompt(const char *string)
{
- if (!main_loop)
+ if (!data.init || data.mode)
return;
rl_set_prompt(string);
- printf("\r");
- rl_on_new_line();
- rl_redisplay();
+ bt_shell_printf("\r");
}
static bool input_read(struct io *io, void *user_data)
@@ -821,6 +1096,13 @@ static bool input_read(struct io *io, void *user_data)
return true;
}
+static bool shell_quit(void *data)
+{
+ mainloop_quit();
+
+ return false;
+}
+
bool bt_shell_attach(int fd)
{
struct io *io;
@@ -831,11 +1113,24 @@ 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;
+ if (data.mode) {
+ if (shell_exec(data.argc, data.argv) < 0) {
+ bt_shell_noninteractive_quit(EXIT_FAILURE);
+ return true;
+ }
+
+ if (data.timeout)
+ timeout_add(data.timeout * 1000, shell_quit, NULL,
+ NULL);
+ }
+
return true;
}
@@ -849,3 +1144,52 @@ bool bt_shell_detach(void)
return true;
}
+
+static bool match_env(const void *data, const void *user_data)
+{
+ const struct bt_shell_env *env = data;
+ const char *name = user_data;
+
+ return !strcmp(env->name, name);
+}
+
+void bt_shell_set_env(const char *name, void *value)
+{
+ struct bt_shell_env *env;
+
+ if (!data.envs) {
+ if (!value)
+ return;
+ data.envs = queue_new();
+ goto done;
+ }
+
+ env = queue_remove_if(data.envs, match_env, (void *) name);
+ if (env)
+ env_destroy(env);
+
+ /* Don't create an env if value is not set */
+ if (!value)
+ return;
+
+done:
+ env = new0(struct bt_shell_env, 1);
+ env->name = strdup(name);
+ env->value = value;
+
+ queue_push_tail(data.envs, env);
+}
+
+void *bt_shell_get_env(const char *name)
+{
+ const struct bt_shell_env *env;
+
+ if (!data.envs)
+ return NULL;
+
+ env = queue_find(data.envs, match_env, name);
+ if (!env)
+ return NULL;
+
+ return env->value;
+}
diff --git a/src/shared/shell.h b/src/shared/shell.h
index 8b8b1f63..8b7cb7f3 100644
--- a/src/shared/shell.h
+++ b/src/shared/shell.h
@@ -66,7 +66,10 @@ struct bt_shell_opt {
void bt_shell_init(int argc, char **argv, const struct bt_shell_opt *opt);
-void bt_shell_run(void);
+int 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);
@@ -79,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);
@@ -87,4 +91,7 @@ int bt_shell_release_prompt(const char *input);
bool bt_shell_attach(int fd);
bool bt_shell_detach(void);
+void bt_shell_set_env(const char *name, void *value);
+void *bt_shell_get_env(const char *name);
+
void bt_shell_cleanup(void);
diff --git a/src/shared/util.c b/src/shared/util.c
index f6f265e5..43a81afa 100755
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -980,3 +980,48 @@ const char *bt_appear_to_str(uint16_t appearance)
return str;
}
+
+char *strdelimit(char *str, char *del, char c)
+{
+ char *dup;
+
+ if (!str)
+ return NULL;
+
+ dup = strdup(str);
+ if (dup[0] == '\0')
+ return dup;
+
+ while (del[0] != '\0') {
+ char *rep = dup;
+
+ while ((rep = strchr(rep, del[0])))
+ rep[0] = c;
+
+ del++;
+ }
+
+ return dup;
+}
+
+int strsuffix(const char *str, const char *suffix)
+{
+ int len;
+ int suffix_len;
+
+ if (!str || !suffix)
+ return -1;
+
+ if (str[0] == '\0' && suffix[0] != '\0')
+ return -1;
+
+ if (suffix[0] == '\0' && str[0] != '\0')
+ return -1;
+
+ len = strlen(str);
+ suffix_len = strlen(suffix);
+ if (len < suffix_len)
+ return -1;
+
+ return strncmp(str + len - suffix_len, suffix, suffix_len);
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 3f5f6dfb..604dc3be 100755
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -92,6 +92,9 @@ do { \
#define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
#define malloc0(n) (calloc((n), 1))
+char *strdelimit(char *str, char *del, char c);
+int strsuffix(const char *str, const char *suffix);
+
void *btd_malloc(size_t size);
typedef void (*util_debug_func_t)(const char *str, void *user_data);
diff --git a/tools/bluetooth-player.c b/tools/bluetooth-player.c
index b22de277..0ab8cab3 100755
--- a/tools/bluetooth-player.c
+++ b/tools/bluetooth-player.c
@@ -51,9 +51,9 @@
static DBusConnection *dbus_conn;
static GDBusProxy *default_player;
-static GSList *players = NULL;
-static GSList *folders = NULL;
-static GSList *items = NULL;
+static GList *players = NULL;
+static GList *folders = NULL;
+static GList *items = NULL;
static void connect_handler(DBusConnection *connection, void *user_data)
{
@@ -90,25 +90,12 @@ static void play_reply(DBusMessage *message, void *user_data)
bt_shell_printf("Play successful\n");
}
-static GDBusProxy *find_item(const char *path)
-{
- GSList *l;
-
- for (l = items; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void cmd_play_item(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_item(argv[1]);
+ proxy = g_dbus_proxy_lookup(items, NULL, argv[1],
+ BLUEZ_MEDIA_ITEM_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Item %s not available\n", argv[1]);
return;
@@ -460,28 +447,14 @@ static void print_player(GDBusProxy *proxy, const char *description)
static void cmd_list(int argc, char *arg[])
{
- GSList *l;
+ GList *l;
- for (l = players; l; l = g_slist_next(l)) {
+ for (l = players; l; l = g_list_next(l)) {
GDBusProxy *proxy = l->data;
print_player(proxy, NULL);
}
}
-static GDBusProxy *find_player(const char *path)
-{
- GSList *l;
-
- for (l = players; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void print_iter(const char *label, const char *name,
DBusMessageIter *iter)
{
@@ -557,25 +530,12 @@ static void print_property(GDBusProxy *proxy, const char *name)
print_iter("\t", name, &iter);
}
-static GDBusProxy *find_folder(const char *path)
-{
- GSList *l;
-
- for (l = folders; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void cmd_show_item(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_item(argv[1]);
+ proxy = g_dbus_proxy_lookup(items, NULL, argv[1],
+ BLUEZ_MEDIA_ITEM_INTERFACE);
if (!proxy) {
bt_shell_printf("Item %s not available\n", argv[1]);
return;
@@ -605,7 +565,8 @@ static void cmd_show(int argc, char *argv[])
proxy = default_player;
} else {
- proxy = find_player(argv[1]);
+ proxy = g_dbus_proxy_lookup(players, NULL, argv[1],
+ BLUEZ_MEDIA_PLAYER_INTERFACE);
if (!proxy) {
bt_shell_printf("Player %s not available\n", argv[1]);
return;
@@ -623,7 +584,9 @@ static void cmd_show(int argc, char *argv[])
print_property(proxy, "Position");
print_property(proxy, "Track");
- folder = find_folder(g_dbus_proxy_get_path(proxy));
+ folder = g_dbus_proxy_lookup(folders, NULL,
+ g_dbus_proxy_get_path(proxy),
+ BLUEZ_MEDIA_FOLDER_INTERFACE);
if (folder == NULL)
return;
@@ -637,7 +600,8 @@ static void cmd_show(int argc, char *argv[])
dbus_message_iter_get_basic(&iter, &path);
- item = find_item(path);
+ item = g_dbus_proxy_lookup(items, NULL, path,
+ BLUEZ_MEDIA_ITEM_INTERFACE);
if (item == NULL)
return;
@@ -650,7 +614,8 @@ static void cmd_select(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_player(argv[1]);
+ proxy = g_dbus_proxy_lookup(players, NULL, argv[1],
+ BLUEZ_MEDIA_PLAYER_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Player %s not available\n", argv[1]);
return;
@@ -697,7 +662,9 @@ static void cmd_change_folder(int argc, char *argv[])
if (check_default_player() == FALSE)
return;
- proxy = find_folder(g_dbus_proxy_get_path(default_player));
+ proxy = g_dbus_proxy_lookup(folders, NULL,
+ g_dbus_proxy_get_path(default_player),
+ BLUEZ_MEDIA_FOLDER_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Operation not supported\n");
return;
@@ -799,7 +766,9 @@ static void cmd_list_items(int argc, char *argv[])
if (check_default_player() == FALSE)
return;
- proxy = find_folder(g_dbus_proxy_get_path(default_player));
+ proxy = g_dbus_proxy_lookup(folders, NULL,
+ g_dbus_proxy_get_path(default_player),
+ BLUEZ_MEDIA_FOLDER_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Operation not supported\n");
return;
@@ -882,7 +851,9 @@ static void cmd_search(int argc, char *argv[])
if (check_default_player() == FALSE)
return;
- proxy = find_folder(g_dbus_proxy_get_path(default_player));
+ proxy = g_dbus_proxy_lookup(folders, NULL,
+ g_dbus_proxy_get_path(default_player),
+ BLUEZ_MEDIA_FOLDER_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Operation not supported\n");
return;
@@ -919,7 +890,8 @@ static void cmd_queue(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_item(argv[1]);
+ proxy = g_dbus_proxy_lookup(items, NULL, argv[1],
+ BLUEZ_MEDIA_ITEM_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Item %s not available\n", argv[1]);
return;
@@ -970,7 +942,7 @@ static const struct bt_shell_menu main_menu = {
static void player_added(GDBusProxy *proxy)
{
- players = g_slist_append(players, proxy);
+ players = g_list_append(players, proxy);
if (default_player == NULL)
default_player = proxy;
@@ -992,7 +964,7 @@ static void print_folder(GDBusProxy *proxy, const char *description)
static void folder_added(GDBusProxy *proxy)
{
- folders = g_slist_append(folders, proxy);
+ folders = g_list_append(folders, proxy);
print_folder(proxy, COLORED_NEW);
}
@@ -1017,7 +989,7 @@ static void print_item(GDBusProxy *proxy, const char *description)
static void item_added(GDBusProxy *proxy)
{
- items = g_slist_append(items, proxy);
+ items = g_list_append(items, proxy);
print_item(proxy, COLORED_NEW);
}
@@ -1043,19 +1015,19 @@ static void player_removed(GDBusProxy *proxy)
if (default_player == proxy)
default_player = NULL;
- players = g_slist_remove(players, proxy);
+ players = g_list_remove(players, proxy);
}
static void folder_removed(GDBusProxy *proxy)
{
- folders = g_slist_remove(folders, proxy);
+ folders = g_list_remove(folders, proxy);
print_folder(proxy, COLORED_DEL);
}
static void item_removed(GDBusProxy *proxy)
{
- items = g_slist_remove(items, proxy);
+ items = g_list_remove(items, proxy);
print_item(proxy, COLORED_DEL);
}
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 3911ba26..122c46d0 100755
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -40,9 +40,6 @@
#include <wordexp.h>
#include <ctype.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-
#include "lib/bluetooth.h"
#include "lib/hci.h"
#include "lib/hci_lib.h"
@@ -52,11 +49,11 @@
#include "src/uuid-helper.h"
#include "lib/mgmt.h"
-#include "client/display.h"
#include "src/shared/mainloop.h"
#include "src/shared/io.h"
#include "src/shared/util.h"
#include "src/shared/mgmt.h"
+#include "src/shared/shell.h"
#define SCAN_TYPE_BREDR (1 << BDADDR_BREDR)
#define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM))
@@ -67,10 +64,6 @@ static uint16_t mgmt_index = MGMT_INDEX_NONE;
static bool discovery = false;
static bool resolve_names = true;
-static bool interactive = false;
-
-static char *saved_prompt = NULL;
-static int saved_point = 0;
static struct {
uint16_t index;
@@ -80,6 +73,7 @@ static struct {
.index = MGMT_INDEX_NONE,
};
+
static int pending_index = 0;
#ifndef MIN
@@ -88,7 +82,7 @@ static int pending_index = 0;
#define PROMPT_ON COLOR_BLUE "[mgmt]" COLOR_OFF "# "
-static void set_index(char *arg)
+static void set_index(const char *arg)
{
if (!arg || !strcmp(arg, "none") || !strcmp(arg, "any") ||
!strcmp(arg, "all"))
@@ -110,38 +104,15 @@ static void update_prompt(uint16_t index)
snprintf(str, sizeof(str),
COLOR_BLUE "[hci%u]" COLOR_OFF "# ", index);
- if (saved_prompt) {
- free(saved_prompt);
- saved_prompt = strdup(str);
- return;
- }
-
- rl_set_prompt(str);
-}
-
-static void noninteractive_quit(int status)
-{
- if (interactive)
- return;
-
- if (status == EXIT_SUCCESS)
- mainloop_exit_success();
- else
- mainloop_exit_failure();
+ bt_shell_set_prompt(str);
}
#define print(fmt, arg...) do { \
- if (interactive) \
- rl_printf(fmt "\n", ## arg); \
- else \
- printf(fmt "\n", ## arg); \
+ bt_shell_printf(fmt "\n", ## arg); \
} while (0)
#define error(fmt, arg...) do { \
- if (interactive) \
- rl_printf(COLOR_RED fmt "\n" COLOR_OFF, ## arg); \
- else \
- fprintf(stderr, fmt "\n", ## arg); \
+ bt_shell_printf(COLOR_RED fmt "\n" COLOR_OFF, ## arg); \
} while (0)
static size_t hex2bin(const char *hexstr, uint8_t *buf, size_t buflen)
@@ -428,7 +399,7 @@ static void discovering(uint16_t index, uint16_t len, const void *param,
ev->discovering ? "on" : "off");
if (ev->discovering == 0 && discovery)
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void new_link_key(uint16_t index, uint16_t len, const void *param,
@@ -481,29 +452,6 @@ static void connected(uint16_t index, uint16_t len, const void *param,
typestr(ev->addr.type), eir_len);
}
-static void release_prompt(void)
-{
- if (!interactive)
- return;
-
- memset(&prompt, 0, sizeof(prompt));
- prompt.index = MGMT_INDEX_NONE;
-
- if (!saved_prompt)
- return;
-
- /* This will cause rl_expand_prompt to re-run over the last prompt,
- * but our prompt doesn't expand anyway.
- */
- rl_set_prompt(saved_prompt);
- rl_replace_line("", 0);
- rl_point = saved_point;
- rl_redisplay();
-
- free(saved_prompt);
- saved_prompt = NULL;
-}
-
static void disconnected(uint16_t index, uint16_t len, const void *param,
void *user_data)
{
@@ -516,9 +464,6 @@ static void disconnected(uint16_t index, uint16_t len, const void *param,
return;
}
- if (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
- release_prompt();
-
if (len < sizeof(*ev))
reason = MGMT_DEV_DISCONN_UNKNOWN;
else
@@ -557,9 +502,6 @@ static void auth_failed(uint16_t index, uint16_t len, const void *param,
return;
}
- if (!memcmp(&ev->addr, &prompt.addr, sizeof(ev->addr)))
- release_prompt();
-
ba2str(&ev->addr.bdaddr, addr);
print("hci%u %s auth failed with status 0x%02x (%s)",
index, addr, ev->status, mgmt_errstr(ev->status));
@@ -739,14 +681,13 @@ static void pin_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("PIN Code reply failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("PIN Reply successful");
}
-static int mgmt_pin_reply(struct mgmt *mgmt, uint16_t index,
- const struct mgmt_addr_info *addr,
+static int mgmt_pin_reply(uint16_t index, const struct mgmt_addr_info *addr,
const char *pin, size_t len)
{
struct mgmt_cp_pin_code_reply cp;
@@ -756,8 +697,8 @@ static int mgmt_pin_reply(struct mgmt *mgmt, uint16_t index,
cp.pin_len = len;
memcpy(cp.pin_code, pin, len);
- return mgmt_reply(mgmt, MGMT_OP_PIN_CODE_REPLY, index, sizeof(cp), &cp,
- pin_rsp, NULL, NULL);
+ return mgmt_reply(mgmt, MGMT_OP_PIN_CODE_REPLY, index,
+ sizeof(cp), &cp, pin_rsp, NULL, NULL);
}
static void pin_neg_rsp(uint8_t status, uint16_t len, const void *param,
@@ -766,14 +707,13 @@ static void pin_neg_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("PIN Neg reply failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("PIN Negative Reply successful");
}
-static int mgmt_pin_neg_reply(struct mgmt *mgmt, uint16_t index,
- const struct mgmt_addr_info *addr)
+static int mgmt_pin_neg_reply(uint16_t index, const struct mgmt_addr_info *addr)
{
struct mgmt_cp_pin_code_neg_reply cp;
@@ -790,14 +730,13 @@ static void confirm_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("User Confirm reply failed. status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("User Confirm Reply successful");
}
-static int mgmt_confirm_reply(struct mgmt *mgmt, uint16_t index,
- const struct mgmt_addr_info *addr)
+static int mgmt_confirm_reply(uint16_t index, const struct mgmt_addr_info *addr)
{
struct mgmt_cp_user_confirm_reply cp;
@@ -814,13 +753,13 @@ static void confirm_neg_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Confirm Neg reply failed. status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("User Confirm Negative Reply successful");
}
-static int mgmt_confirm_neg_reply(struct mgmt *mgmt, uint16_t index,
+static int mgmt_confirm_neg_reply(uint16_t index,
const struct mgmt_addr_info *addr)
{
struct mgmt_cp_user_confirm_reply cp;
@@ -838,15 +777,14 @@ static void passkey_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("User Passkey reply failed. status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("User Passkey Reply successful");
}
-static int mgmt_passkey_reply(struct mgmt *mgmt, uint16_t index,
- const struct mgmt_addr_info *addr,
- uint32_t passkey)
+static int mgmt_passkey_reply(uint16_t index, const struct mgmt_addr_info *addr,
+ uint32_t passkey)
{
struct mgmt_cp_user_passkey_reply cp;
@@ -864,13 +802,13 @@ static void passkey_neg_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Passkey Neg reply failed. status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("User Passkey Negative Reply successful");
}
-static int mgmt_passkey_neg_reply(struct mgmt *mgmt, uint16_t index,
+static int mgmt_passkey_neg_reply(uint16_t index,
const struct mgmt_addr_info *addr)
{
struct mgmt_cp_user_passkey_reply cp;
@@ -882,85 +820,40 @@ static int mgmt_passkey_neg_reply(struct mgmt *mgmt, uint16_t index,
sizeof(cp), &cp, passkey_neg_rsp, NULL, NULL);
}
-static bool prompt_input(const char *input)
+static void prompt_input(const char *input, void *user_data)
{
size_t len;
- if (!prompt.req)
- return false;
-
len = strlen(input);
switch (prompt.req) {
case MGMT_EV_PIN_CODE_REQUEST:
if (len)
- mgmt_pin_reply(mgmt, prompt.index, &prompt.addr,
- input, len);
+ mgmt_pin_reply(prompt.index, &prompt.addr, input, len);
else
- mgmt_pin_neg_reply(mgmt, prompt.index, &prompt.addr);
+ mgmt_pin_neg_reply(prompt.index, &prompt.addr);
break;
case MGMT_EV_USER_PASSKEY_REQUEST:
if (strlen(input) > 0)
- mgmt_passkey_reply(mgmt, prompt.index, &prompt.addr,
+ mgmt_passkey_reply(prompt.index, &prompt.addr,
atoi(input));
else
- mgmt_passkey_neg_reply(mgmt, prompt.index,
+ mgmt_passkey_neg_reply(prompt.index,
&prompt.addr);
break;
case MGMT_EV_USER_CONFIRM_REQUEST:
if (input[0] == 'y' || input[0] == 'Y')
- mgmt_confirm_reply(mgmt, prompt.index, &prompt.addr);
+ mgmt_confirm_reply(prompt.index, &prompt.addr);
else
- mgmt_confirm_neg_reply(mgmt, prompt.index,
- &prompt.addr);
+ mgmt_confirm_neg_reply(prompt.index, &prompt.addr);
break;
}
-
- release_prompt();
-
- return true;
-}
-
-static void interactive_prompt(const char *msg)
-{
- if (saved_prompt)
- return;
-
- saved_prompt = strdup(rl_prompt);
- if (!saved_prompt)
- return;
-
- saved_point = rl_point;
-
- rl_set_prompt("");
- rl_redisplay();
-
- rl_set_prompt(msg);
-
- rl_replace_line("", 0);
- rl_redisplay();
-}
-
-static size_t get_input(char *buf, size_t buf_len)
-{
- size_t len;
-
- if (!fgets(buf, buf_len, stdin))
- return 0;
-
- len = strlen(buf);
-
- /* Remove trailing white-space */
- while (len && isspace(buf[len - 1]))
- buf[--len] = '\0';
-
- return len;
}
static void ask(uint16_t index, uint16_t req, const struct mgmt_addr_info *addr,
const char *fmt, ...)
{
- char msg[256], buf[18];
+ char msg[256];
va_list ap;
int off;
@@ -975,18 +868,7 @@ static void ask(uint16_t index, uint16_t req, const struct mgmt_addr_info *addr,
snprintf(msg + off, sizeof(msg) - off, " %s ",
COLOR_BOLDGRAY ">>" COLOR_OFF);
- if (interactive) {
- interactive_prompt(msg);
- va_end(ap);
- return;
- }
-
- printf("%s", msg);
- fflush(stdout);
-
- memset(buf, 0, sizeof(buf));
- get_input(buf, sizeof(buf));
- prompt_input(buf);
+ bt_shell_prompt_input("", msg, prompt_input, NULL);
}
static void request_pin(uint16_t index, uint16_t len, const void *param,
@@ -1137,18 +1019,15 @@ static void version_rsp(uint8_t status, uint16_t len, const void *param,
get_le16(&rp->revision));
done:
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_usage(char *cmd);
-
-static void cmd_version(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_version(int argc, char **argv)
{
if (mgmt_send(mgmt, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE,
0, NULL, version_rsp, NULL, NULL) == 0) {
error("Unable to send read_version cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1199,16 +1078,16 @@ static void commands_rsp(uint8_t status, uint16_t len, const void *param,
}
done:
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_commands(struct mgmt *mgmt, uint16_t index, int argc,
+static void cmd_commands(int argc,
char **argv)
{
if (mgmt_send(mgmt, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE,
0, NULL, commands_rsp, NULL, NULL) == 0) {
error("Unable to send read_commands cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1246,7 +1125,7 @@ done:
if (pending_index > 0)
return;
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1259,12 +1138,12 @@ static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Reading index list failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small index list reply (%u bytes)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count = le16_to_cpu(rp->num_controllers);
@@ -1272,7 +1151,7 @@ static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
error("Index count (%u) doesn't match reply length (%u)",
count, len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Unconfigured index list with %u item%s",
@@ -1284,33 +1163,33 @@ static void unconf_index_rsp(uint8_t status, uint16_t len, const void *param,
if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, index, 0, NULL,
config_info_rsp, UINT_TO_PTR(index), NULL)) {
error("Unable to send read_config_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
pending_index++;
}
if (!count)
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_config(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_config(int argc, char **argv)
{
- if (index == MGMT_INDEX_NONE) {
+ if (mgmt_index == MGMT_INDEX_NONE) {
if (!mgmt_send(mgmt, MGMT_OP_READ_UNCONF_INDEX_LIST,
MGMT_INDEX_NONE, 0, NULL,
unconf_index_rsp, mgmt, NULL)) {
error("Unable to send unconf_index_list cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
return;
}
- if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, index, 0, NULL,
+ if (!mgmt_send(mgmt, MGMT_OP_READ_CONFIG_INFO, mgmt_index, 0, NULL,
config_info_rsp, UINT_TO_PTR(index), NULL)) {
error("Unable to send read_config_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1346,7 +1225,7 @@ done:
if (pending_index > 0)
return;
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void info_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1400,7 +1279,7 @@ done:
if (pending_index > 0)
return;
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void ext_info_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1450,7 +1329,7 @@ done:
if (pending_index > 0)
return;
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void index_rsp(uint8_t status, uint16_t len, const void *param,
@@ -1464,12 +1343,12 @@ static void index_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Reading index list failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small index list reply (%u bytes)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count = le16_to_cpu(rp->num_controllers);
@@ -1477,7 +1356,7 @@ static void index_rsp(uint8_t status, uint16_t len, const void *param,
if (len < sizeof(*rp) + count * sizeof(uint16_t)) {
error("Index count (%u) doesn't match reply length (%u)",
count, len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Index list with %u item%s", count, count != 1 ? "s" : "");
@@ -1488,33 +1367,33 @@ static void index_rsp(uint8_t status, uint16_t len, const void *param,
if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
info_rsp, UINT_TO_PTR(index), NULL)) {
error("Unable to send read_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
pending_index++;
}
if (!count)
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_info(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_info(int argc, char **argv)
{
- if (index == MGMT_INDEX_NONE) {
+ if (mgmt_index == MGMT_INDEX_NONE) {
if (!mgmt_send(mgmt, MGMT_OP_READ_INDEX_LIST,
MGMT_INDEX_NONE, 0, NULL,
index_rsp, mgmt, NULL)) {
error("Unable to send index_list cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
return;
}
- if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL, info_rsp,
- UINT_TO_PTR(index), NULL)) {
+ if (!mgmt_send(mgmt, MGMT_OP_READ_INFO, mgmt_index, 0, NULL, info_rsp,
+ UINT_TO_PTR(mgmt_index), NULL)) {
error("Unable to send read_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1528,12 +1407,12 @@ static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Reading ext index list failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small ext index list reply (%u bytes)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count = get_le16(&rp->num_controllers);
@@ -1541,7 +1420,7 @@ static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
if (len < sizeof(*rp) + count * (sizeof(uint16_t) + sizeof(uint8_t))) {
error("Index count (%u) doesn't match reply length (%u)",
count, len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Extended index list with %u item%s",
@@ -1561,7 +1440,7 @@ static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
index, 0, NULL, ext_info_rsp,
UINT_TO_PTR(index), NULL)) {
error("Unable to send read_ext_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
pending_index++;
break;
@@ -1572,7 +1451,7 @@ static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
index, 0, NULL, config_info_rsp,
UINT_TO_PTR(index), NULL)) {
error("Unable to send read_config cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
pending_index++;
break;
@@ -1589,17 +1468,17 @@ static void ext_index_rsp(uint8_t status, uint16_t len, const void *param,
print("");
if (!count)
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_extinfo(struct mgmt *mgmt, uint16_t index,
+static void cmd_extinfo(
int argc, char **argv)
{
if (!mgmt_send(mgmt, MGMT_OP_READ_EXT_INDEX_LIST,
MGMT_INDEX_NONE, 0, NULL,
ext_index_rsp, UINT_TO_PTR(index), NULL)) {
error("Unable to send ext_index_list cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1610,7 +1489,7 @@ static void auto_power_enable_rsp(uint8_t status, uint16_t len,
print("Successfully enabled controller with index %u", index);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void auto_power_info_rsp(uint8_t status, uint16_t len,
@@ -1624,7 +1503,7 @@ static void auto_power_info_rsp(uint8_t status, uint16_t len,
if (status) {
error("Reading info failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
supported_settings = le32_to_cpu(rp->supported_settings);
@@ -1653,13 +1532,13 @@ static void auto_power_info_rsp(uint8_t status, uint16_t len,
NULL, NULL, NULL);
if (current_settings & MGMT_SETTING_POWERED)
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
if (!mgmt_send(mgmt, MGMT_OP_SET_POWERED, index, sizeof(val), &val,
auto_power_enable_rsp,
UINT_TO_PTR(index), NULL)) {
error("Unable to send set powerd cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1677,7 +1556,7 @@ static void auto_power_index_evt(uint16_t index, uint16_t len,
auto_power_info_rsp,
UINT_TO_PTR(index), NULL)) {
error("Unable to send read info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1692,7 +1571,7 @@ static void auto_power_index_rsp(uint8_t status, uint16_t len,
if (status) {
error("Reading index list failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count = le16_to_cpu(rp->num_controllers);
@@ -1716,13 +1595,15 @@ static void auto_power_index_rsp(uint8_t status, uint16_t len,
auto_power_info_rsp,
UINT_TO_PTR(index), NULL)) {
error("Unable to send read info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_auto_power(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_auto_power(int argc, char **argv)
{
+ int index;
+
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -1730,7 +1611,7 @@ static void cmd_auto_power(struct mgmt *mgmt, uint16_t index,
auto_power_index_rsp,
UINT_TO_PTR(index), NULL)) {
error("Unable to send read index list cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1795,16 +1676,11 @@ static void setting_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
settings2str(get_le32(rp)));
done:
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static bool parse_setting(int argc, char **argv, uint8_t *val)
{
- if (argc < 2) {
- cmd_usage(argv[0]);
- return false;
- }
-
if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
*val = 1;
else if (strcasecmp(argv[1], "off") == 0)
@@ -1814,37 +1690,33 @@ static bool parse_setting(int argc, char **argv, uint8_t *val)
return true;
}
-static void cmd_setting(struct mgmt *mgmt, uint16_t index, uint16_t op,
- int argc, char **argv)
+static void cmd_setting(uint16_t op, int argc, char **argv)
{
+ int index;
uint8_t val;
if (parse_setting(argc, argv, &val) == false)
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (send_cmd(mgmt, op, index, sizeof(val), &val, setting_rsp) == 0) {
error("Unable to send %s cmd", mgmt_opstr(op));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_power(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_power(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_POWERED, argc, argv);
+ cmd_setting(MGMT_OP_SET_POWERED, argc, argv);
}
-static void cmd_discov(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_discov(int argc, char **argv)
{
struct mgmt_cp_set_discoverable cp;
-
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
+ uint16_t index;
memset(&cp, 0, sizeof(cp));
@@ -1860,53 +1732,46 @@ static void cmd_discov(struct mgmt *mgmt, uint16_t index, int argc,
if (argc > 2)
cp.timeout = htobs(atoi(argv[2]));
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (send_cmd(mgmt, MGMT_OP_SET_DISCOVERABLE, index, sizeof(cp), &cp,
setting_rsp) == 0) {
error("Unable to send set_discoverable cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_connectable(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_connectable(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_CONNECTABLE, argc, argv);
+ cmd_setting(MGMT_OP_SET_CONNECTABLE, argc, argv);
}
-static void cmd_fast_conn(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_fast_conn(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_FAST_CONNECTABLE, argc, argv);
+ cmd_setting(MGMT_OP_SET_FAST_CONNECTABLE, argc, argv);
}
-static void cmd_bondable(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_bondable(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_BONDABLE, argc, argv);
+ cmd_setting(MGMT_OP_SET_BONDABLE, argc, argv);
}
-static void cmd_linksec(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_linksec(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_LINK_SECURITY, argc, argv);
+ cmd_setting(MGMT_OP_SET_LINK_SECURITY, argc, argv);
}
-static void cmd_ssp(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_ssp(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_SSP, argc, argv);
+ cmd_setting(MGMT_OP_SET_SSP, argc, argv);
}
-static void cmd_sc(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_sc(int argc, char **argv)
{
uint8_t val;
-
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
+ uint16_t index;
if (strcasecmp(argv[1], "on") == 0 || strcasecmp(argv[1], "yes") == 0)
val = 1;
@@ -1917,45 +1782,46 @@ static void cmd_sc(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
else
val = atoi(argv[1]);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (send_cmd(mgmt, MGMT_OP_SET_SECURE_CONN, index,
sizeof(val), &val, setting_rsp) == 0) {
error("Unable to send set_secure_conn cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_hs(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_hs(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_HS, argc, argv);
+ cmd_setting(MGMT_OP_SET_HS, argc, argv);
}
-static void cmd_le(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_le(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_LE, argc, argv);
+ cmd_setting(MGMT_OP_SET_LE, argc, argv);
}
-static void cmd_advertising(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_advertising(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_ADVERTISING, argc, argv);
+ cmd_setting(MGMT_OP_SET_ADVERTISING, argc, argv);
}
-static void cmd_bredr(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_bredr(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_BREDR, argc, argv);
+ cmd_setting(MGMT_OP_SET_BREDR, argc, argv);
}
-static void cmd_privacy(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_privacy(int argc, char **argv)
{
struct mgmt_cp_set_privacy cp;
+ uint16_t index;
if (parse_setting(argc, argv, &cp.privacy) == false)
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -1963,7 +1829,7 @@ static void cmd_privacy(struct mgmt *mgmt, uint16_t index, int argc,
if (hex2bin(argv[2], cp.irk,
sizeof(cp.irk)) != sizeof(cp.irk)) {
error("Invalid key format");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
} else {
int fd;
@@ -1971,13 +1837,13 @@ static void cmd_privacy(struct mgmt *mgmt, uint16_t index, int argc,
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
error("open(/dev/urandom): %s", strerror(errno));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (read(fd, cp.irk, sizeof(cp.irk)) != sizeof(cp.irk)) {
error("Reading from urandom failed");
close(fd);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
close(fd);
@@ -1986,7 +1852,7 @@ static void cmd_privacy(struct mgmt *mgmt, uint16_t index, int argc,
if (send_cmd(mgmt, MGMT_OP_SET_PRIVACY, index, sizeof(cp), &cp,
setting_rsp) == 0) {
error("Unable to send Set Privacy command");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -1998,39 +1864,36 @@ static void class_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
if (len == 0 && status != 0) {
error("%s failed, status 0x%02x (%s)",
mgmt_opstr(op), status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Unexpected %s len %u", mgmt_opstr(op), len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("%s succeeded. Class 0x%02x%02x%02x", mgmt_opstr(op),
rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_class(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_class(int argc, char **argv)
{
uint8_t class[2];
-
- if (argc < 3) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
+ uint16_t index;
class[0] = atoi(argv[1]);
class[1] = atoi(argv[2]);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (send_cmd(mgmt, MGMT_OP_SET_DEV_CLASS, index, sizeof(class), class,
class_rsp) == 0) {
error("Unable to send set_dev_class cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2043,12 +1906,12 @@ static void disconnect_rsp(uint8_t status, uint16_t len, const void *param,
if (len == 0 && status != 0) {
error("Disconnect failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Invalid disconnect response length (%u)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ba2str(&rp->addr.bdaddr, addr);
@@ -2059,7 +1922,7 @@ static void disconnect_rsp(uint8_t status, uint16_t len, const void *param,
error("Disconnecting %s failed with status 0x%02x (%s)",
addr, status, mgmt_errstr(status));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option disconnect_options[] = {
@@ -2068,13 +1931,12 @@ static struct option disconnect_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_disconnect(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_disconnect(int argc, char **argv)
{
struct mgmt_cp_disconnect cp;
uint8_t type = BDADDR_BREDR;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+t:h", disconnect_options,
NULL)) != -1) {
@@ -2083,13 +1945,13 @@ static void cmd_disconnect(struct mgmt *mgmt, uint16_t index, int argc,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2097,11 +1959,7 @@ static void cmd_disconnect(struct mgmt *mgmt, uint16_t index, int argc,
argv += optind;
optind = 0;
- if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2112,7 +1970,7 @@ static void cmd_disconnect(struct mgmt *mgmt, uint16_t index, int argc,
if (mgmt_send(mgmt, MGMT_OP_DISCONNECT, index, sizeof(cp), &cp,
disconnect_rsp, NULL, NULL) == 0) {
error("Unable to send disconnect cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2124,14 +1982,14 @@ static void con_rsp(uint8_t status, uint16_t len, const void *param,
if (len < sizeof(*rp)) {
error("Too small (%u bytes) get_connections rsp", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count = get_le16(&rp->conn_count);
if (len != sizeof(*rp) + count * sizeof(struct mgmt_addr_info)) {
error("Invalid get_connections length (count=%u, len=%u)",
count, len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
for (i = 0; i < count; i++) {
@@ -2142,18 +2000,21 @@ static void con_rsp(uint8_t status, uint16_t len, const void *param,
print("%s type %s", addr, typestr(rp->addr[i].type));
}
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_con(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_con(int argc, char **argv)
{
+ uint16_t index;
+
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (mgmt_send(mgmt, MGMT_OP_GET_CONNECTIONS, index, 0, NULL,
con_rsp, NULL, NULL) == 0) {
error("Unable to send get_connections cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2163,7 +2024,7 @@ static void find_service_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Start Service Discovery failed: status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Service discovery started");
@@ -2191,8 +2052,7 @@ static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
#define MAX_UUIDS 4
-static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_find_service(int argc, char **argv)
{
struct mgmt_cp_start_service_discovery *cp;
uint8_t buf[sizeof(*cp) + 16 * MAX_UUIDS];
@@ -2203,19 +2063,15 @@ static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
int8_t rssi;
uint16_t count;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
rssi = 127;
count = 0;
- if (argc == 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
while ((opt = getopt_long(argc, argv, "+lbu:r:h",
find_service_options, NULL)) != -1) {
switch (opt) {
@@ -2231,13 +2087,13 @@ static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
if (count == MAX_UUIDS) {
print("Max %u UUIDs supported", MAX_UUIDS);
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (bt_string2uuid(&uuid, optarg) < 0) {
print("Invalid UUID: %s", optarg);
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
cp = (void *) buf;
uuid_to_uuid128(&uuid128, &uuid);
@@ -2249,13 +2105,13 @@ static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
rssi = atoi(optarg);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2263,11 +2119,6 @@ static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
argv += optind;
optind = 0;
- if (argc > 0) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
cp = (void *) buf;
cp->type = type;
cp->rssi = rssi;
@@ -2277,7 +2128,7 @@ static void cmd_find_service(struct mgmt *mgmt, uint16_t index, int argc,
sizeof(*cp) + count * 16, cp,
find_service_rsp, NULL, NULL) == 0) {
error("Unable to send start_service_discovery cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2287,7 +2138,7 @@ static void find_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Unable to start discovery. status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Discovery started");
@@ -2302,14 +2153,15 @@ static struct option find_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_find(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_find(int argc, char **argv)
{
struct mgmt_cp_start_discovery cp;
uint8_t op = MGMT_OP_START_DISCOVERY;
uint8_t type = SCAN_TYPE_DUAL;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2328,13 +2180,13 @@ static void cmd_find(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
op = MGMT_OP_START_LIMITED_DISCOVERY;
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2348,7 +2200,7 @@ static void cmd_find(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (mgmt_send(mgmt, op, index, sizeof(cp), &cp, find_rsp,
NULL, NULL) == 0) {
error("Unable to send start_discovery cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2358,13 +2210,13 @@ static void stop_find_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Stop Discovery failed: status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
print("Discovery stopped");
discovery = false;
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option stop_find_options[] = {
@@ -2374,14 +2226,14 @@ static struct option stop_find_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_stop_find(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_stop_find(int argc, char **argv)
{
struct mgmt_cp_stop_discovery cp;
uint8_t type = SCAN_TYPE_DUAL;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2398,9 +2250,9 @@ static void cmd_stop_find(struct mgmt *mgmt, uint16_t index, int argc,
break;
case 'h':
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
}
@@ -2414,7 +2266,7 @@ static void cmd_stop_find(struct mgmt *mgmt, uint16_t index, int argc,
if (mgmt_send(mgmt, MGMT_OP_STOP_DISCOVERY, index, sizeof(cp), &cp,
stop_find_rsp, NULL, NULL) == 0) {
error("Unable to send stop_discovery cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2425,18 +2277,15 @@ static void name_rsp(uint8_t status, uint16_t len, const void *param,
error("Unable to set local name with status 0x%02x (%s)",
status, mgmt_errstr(status));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_name(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_name(int argc, char **argv)
{
struct mgmt_cp_set_local_name cp;
+ uint16_t index;
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2449,7 +2298,7 @@ static void cmd_name(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (mgmt_send(mgmt, MGMT_OP_SET_LOCAL_NAME, index, sizeof(cp), &cp,
name_rsp, NULL, NULL) == 0) {
error("Unable to send set_name cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2462,17 +2311,14 @@ static void pair_rsp(uint8_t status, uint16_t len, const void *param,
if (len == 0 && status != 0) {
error("Pairing failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Unexpected pair_rsp len %u", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
- if (!memcmp(&rp->addr, &prompt.addr, sizeof(rp->addr)))
- release_prompt();
-
ba2str(&rp->addr.bdaddr, addr);
if (status)
@@ -2482,7 +2328,7 @@ static void pair_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Paired with %s (%s)", addr, typestr(rp->addr.type));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option pair_options[] = {
@@ -2492,14 +2338,14 @@ static struct option pair_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_pair(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_pair(int argc, char **argv)
{
struct mgmt_cp_pair_device cp;
uint8_t cap = 0x01;
uint8_t type = BDADDR_BREDR;
char addr[18];
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+c:t:h", pair_options,
NULL)) != -1) {
@@ -2511,13 +2357,13 @@ static void cmd_pair(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2526,10 +2372,11 @@ static void cmd_pair(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2544,7 +2391,7 @@ static void cmd_pair(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (mgmt_send(mgmt, MGMT_OP_PAIR_DEVICE, index, sizeof(cp), &cp,
pair_rsp, NULL, NULL) == 0) {
error("Unable to send pair_device cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2557,12 +2404,12 @@ static void cancel_pair_rsp(uint8_t status, uint16_t len, const void *param,
if (len == 0 && status != 0) {
error("Cancel Pairing failed with 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Unexpected cancel_pair_rsp len %u", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ba2str(&rp->bdaddr, addr);
@@ -2574,7 +2421,7 @@ static void cancel_pair_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Pairing Cancelled with %s", addr);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option cancel_pair_options[] = {
@@ -2583,13 +2430,12 @@ static struct option cancel_pair_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_cancel_pair(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_cancel_pair(int argc, char **argv)
{
struct mgmt_addr_info cp;
uint8_t type = BDADDR_BREDR;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+t:h", cancel_pair_options,
NULL)) != -1) {
@@ -2598,13 +2444,13 @@ static void cmd_cancel_pair(struct mgmt *mgmt, uint16_t index, int argc,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2613,10 +2459,11 @@ static void cmd_cancel_pair(struct mgmt *mgmt, uint16_t index, int argc,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2627,7 +2474,7 @@ static void cmd_cancel_pair(struct mgmt *mgmt, uint16_t index, int argc,
if (mgmt_reply(mgmt, MGMT_OP_CANCEL_PAIR_DEVICE, index, sizeof(cp), &cp,
cancel_pair_rsp, NULL, NULL) == 0) {
error("Unable to send cancel_pair_device cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2640,12 +2487,12 @@ static void unpair_rsp(uint8_t status, uint16_t len, const void *param,
if (len == 0 && status != 0) {
error("Unpair device failed. status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Unexpected unpair_device_rsp len %u", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ba2str(&rp->addr.bdaddr, addr);
@@ -2656,7 +2503,7 @@ static void unpair_rsp(uint8_t status, uint16_t len, const void *param,
else
print("%s unpaired", addr);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option unpair_options[] = {
@@ -2665,13 +2512,12 @@ static struct option unpair_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_unpair(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_unpair(int argc, char **argv)
{
struct mgmt_cp_unpair_device cp;
uint8_t type = BDADDR_BREDR;
int opt;
- char *cmd = argv[0];
+ uint16_t index = mgmt_index;
while ((opt = getopt_long(argc, argv, "+t:h", unpair_options,
NULL)) != -1) {
@@ -2680,13 +2526,13 @@ static void cmd_unpair(struct mgmt *mgmt, uint16_t index, int argc,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2695,10 +2541,11 @@ static void cmd_unpair(struct mgmt *mgmt, uint16_t index, int argc,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2710,7 +2557,7 @@ static void cmd_unpair(struct mgmt *mgmt, uint16_t index, int argc,
if (mgmt_send(mgmt, MGMT_OP_UNPAIR_DEVICE, index, sizeof(cp), &cp,
unpair_rsp, NULL, NULL) == 0) {
error("Unable to send unpair_device cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2723,13 +2570,15 @@ static void keys_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Keys successfully loaded");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_keys(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_keys(int argc, char **argv)
{
struct mgmt_cp_load_link_keys cp;
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2738,7 +2587,7 @@ static void cmd_keys(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (mgmt_send(mgmt, MGMT_OP_LOAD_LINK_KEYS, index, sizeof(cp), &cp,
keys_rsp, NULL, NULL) == 0) {
error("Unable to send load_keys cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2751,13 +2600,15 @@ static void ltks_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Long term keys successfully loaded");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_ltks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_ltks(int argc, char **argv)
{
struct mgmt_cp_load_long_term_keys cp;
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2766,7 +2617,7 @@ static void cmd_ltks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (mgmt_send(mgmt, MGMT_OP_LOAD_LONG_TERM_KEYS, index, sizeof(cp), &cp,
ltks_rsp, NULL, NULL) == 0) {
error("Unable to send load_ltks cmd");
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
}
@@ -2779,7 +2630,7 @@ static void irks_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Identity Resolving Keys successfully loaded");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option irks_options[] = {
@@ -2791,15 +2642,16 @@ static struct option irks_options[] = {
#define MAX_IRKS 4
-static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_irks(int argc, char **argv)
{
struct mgmt_cp_load_irks *cp;
uint8_t buf[sizeof(*cp) + 23 * MAX_IRKS];
uint16_t count, local_index;
char path[PATH_MAX];
int opt;
- char *cmd = argv[0];
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2813,7 +2665,7 @@ static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (count >= MAX_IRKS) {
error("Number of IRKs exceeded");
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (strlen(optarg) > 3 &&
strncasecmp(optarg, "hci", 3) == 0)
@@ -2826,7 +2678,7 @@ static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (!load_identity(path, &cp->irks[count])) {
error("Unable to load identity");
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count++;
break;
@@ -2834,23 +2686,23 @@ static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (count >= MAX_IRKS) {
error("Number of IRKs exceeded");
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (!load_identity(optarg, &cp->irks[count])) {
error("Unable to load identities");
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
count++;
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2858,18 +2710,13 @@ static void cmd_irks(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
argv += optind;
optind = 0;
- if (argc > 0) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
cp->irk_count = cpu_to_le16(count);
if (mgmt_send(mgmt, MGMT_OP_LOAD_IRKS, index,
sizeof(*cp) + count * 23, cp,
irks_rsp, NULL, NULL) == 0) {
error("Unable to send load_irks cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2882,12 +2729,12 @@ static void block_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
if (len == 0 && status != 0) {
error("%s failed, status 0x%02x (%s)",
mgmt_opstr(op), status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Unexpected %s len %u", mgmt_opstr(op), len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ba2str(&rp->bdaddr, addr);
@@ -2899,7 +2746,7 @@ static void block_rsp(uint16_t op, uint16_t id, uint8_t status, uint16_t len,
else
print("%s %s succeeded", mgmt_opstr(op), addr);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option block_options[] = {
@@ -2908,12 +2755,12 @@ static struct option block_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_block(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_block(int argc, char **argv)
{
struct mgmt_cp_block_device cp;
uint8_t type = BDADDR_BREDR;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+t:h", block_options,
NULL)) != -1) {
@@ -2922,13 +2769,13 @@ static void cmd_block(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2937,10 +2784,11 @@ static void cmd_block(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2951,17 +2799,16 @@ static void cmd_block(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (send_cmd(mgmt, MGMT_OP_BLOCK_DEVICE, index, sizeof(cp), &cp,
block_rsp) == 0) {
error("Unable to send block_device cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_unblock(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_unblock(int argc, char **argv)
{
struct mgmt_cp_unblock_device cp;
uint8_t type = BDADDR_BREDR;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+t:h", block_options,
NULL)) != -1) {
@@ -2970,13 +2817,13 @@ static void cmd_unblock(struct mgmt *mgmt, uint16_t index, int argc,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -2985,10 +2832,11 @@ static void cmd_unblock(struct mgmt *mgmt, uint16_t index, int argc,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -2999,28 +2847,29 @@ static void cmd_unblock(struct mgmt *mgmt, uint16_t index, int argc,
if (send_cmd(mgmt, MGMT_OP_UNBLOCK_DEVICE, index, sizeof(cp), &cp,
block_rsp) == 0) {
error("Unable to send unblock_device cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_add_uuid(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_add_uuid(int argc, char **argv)
{
struct mgmt_cp_add_uuid cp;
uint128_t uint128;
uuid_t uuid, uuid128;
+ uint16_t index;
if (argc < 3) {
print("UUID and service hint needed");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (bt_string2uuid(&uuid, argv[1]) < 0) {
print("Invalid UUID: %s", argv[1]);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
memset(&cp, 0, sizeof(cp));
@@ -3034,28 +2883,29 @@ static void cmd_add_uuid(struct mgmt *mgmt, uint16_t index, int argc,
if (send_cmd(mgmt, MGMT_OP_ADD_UUID, index, sizeof(cp), &cp,
class_rsp) == 0) {
error("Unable to send add_uuid cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_remove_uuid(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_remove_uuid(int argc, char **argv)
{
struct mgmt_cp_remove_uuid cp;
uint128_t uint128;
uuid_t uuid, uuid128;
+ uint16_t index;
if (argc < 2) {
print("UUID needed");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (bt_string2uuid(&uuid, argv[1]) < 0) {
print("Invalid UUID: %s", argv[1]);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
memset(&cp, 0, sizeof(cp));
@@ -3067,17 +2917,16 @@ static void cmd_remove_uuid(struct mgmt *mgmt, uint16_t index, int argc,
if (send_cmd(mgmt, MGMT_OP_REMOVE_UUID, index, sizeof(cp), &cp,
class_rsp) == 0) {
error("Unable to send remove_uuid cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_clr_uuids(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_clr_uuids(int argc, char **argv)
{
char *uuid_any = "00000000-0000-0000-0000-000000000000";
char *rm_argv[] = { "rm-uuid", uuid_any, NULL };
- cmd_remove_uuid(mgmt, index, 2, rm_argv);
+ cmd_remove_uuid(2, rm_argv);
}
static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
@@ -3089,12 +2938,12 @@ static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Read Local OOB Data failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small (%u bytes) read_local_oob rsp", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
bin2hex(rp->hash192, 16, str, sizeof(str));
@@ -3104,7 +2953,7 @@ static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
print("Randomizer R with P-192: %s", str);
if (len < sizeof(*rp))
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
bin2hex(rp->hash256, 16, str, sizeof(str));
print("Hash C from P-256: %s", str);
@@ -3112,19 +2961,21 @@ static void local_oob_rsp(uint8_t status, uint16_t len, const void *param,
bin2hex(rp->rand256, 16, str, sizeof(str));
print("Randomizer R with P-256: %s", str);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_local_oob(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_local_oob(int argc, char **argv)
{
+ uint16_t index;
+
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (mgmt_send(mgmt, MGMT_OP_READ_LOCAL_OOB_DATA, index, 0, NULL,
local_oob_rsp, NULL, NULL) == 0) {
error("Unable to send read_local_oob cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3155,12 +3006,11 @@ static struct option remote_oob_opt[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_remote_oob(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_remote_oob(int argc, char **argv)
{
struct mgmt_cp_add_remote_oob_data cp;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
memset(&cp, 0, sizeof(cp));
cp.addr.type = BDADDR_BREDR;
@@ -3184,9 +3034,9 @@ static void cmd_remote_oob(struct mgmt *mgmt, uint16_t index,
hex2bin(optarg, cp.hash256, 16);
break;
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3195,10 +3045,11 @@ static void cmd_remote_oob(struct mgmt *mgmt, uint16_t index,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3210,7 +3061,7 @@ static void cmd_remote_oob(struct mgmt *mgmt, uint16_t index,
sizeof(cp), &cp, remote_oob_rsp,
NULL, NULL) == 0) {
error("Unable to send add_remote_oob cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3223,25 +3074,15 @@ static void did_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Device ID successfully set");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void did_usage(void)
-{
- cmd_usage("did");
- print(" possible source values: bluetooth, usb");
-}
-
-static void cmd_did(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_did(int argc, char **argv)
{
struct mgmt_cp_set_device_id cp;
uint16_t vendor, product, version , source;
int result;
-
- if (argc < 2) {
- did_usage();
- return noninteractive_quit(EXIT_FAILURE);
- }
+ uint16_t index;
result = sscanf(argv[1], "bluetooth:%4hx:%4hx:%4hx", &vendor, &product,
&version);
@@ -3257,10 +3098,9 @@ static void cmd_did(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
goto done;
}
- did_usage();
- return noninteractive_quit(EXIT_FAILURE);
-
+ return;
done:
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3272,7 +3112,7 @@ done:
if (mgmt_send(mgmt, MGMT_OP_SET_DEVICE_ID, index, sizeof(cp), &cp,
did_rsp, NULL, NULL) == 0) {
error("Unable to send set_device_id cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3285,19 +3125,15 @@ static void static_addr_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Static address successfully set");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_static_addr(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_static_addr(int argc, char **argv)
{
struct mgmt_cp_set_static_address cp;
+ uint16_t index;
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3306,7 +3142,7 @@ static void cmd_static_addr(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_SET_STATIC_ADDRESS, index, sizeof(cp), &cp,
static_addr_rsp, NULL, NULL) == 0) {
error("Unable to send set_static_address cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3318,31 +3154,27 @@ static void options_rsp(uint16_t op, uint16_t id, uint8_t status,
if (status != 0) {
error("%s for hci%u failed with status 0x%02x (%s)",
mgmt_opstr(op), id, status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small %s response (%u bytes)",
mgmt_opstr(op), len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("hci%u %s complete, options: %s", id, mgmt_opstr(op),
options2str(get_le32(rp)));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_public_addr(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_public_addr(int argc, char **argv)
{
struct mgmt_cp_set_public_address cp;
+ uint16_t index;
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3351,32 +3183,32 @@ static void cmd_public_addr(struct mgmt *mgmt, uint16_t index,
if (send_cmd(mgmt, MGMT_OP_SET_PUBLIC_ADDRESS, index, sizeof(cp), &cp,
options_rsp) == 0) {
error("Unable to send Set Public Address cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_ext_config(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_ext_config(int argc, char **argv)
{
struct mgmt_cp_set_external_config cp;
+ uint16_t index;
if (parse_setting(argc, argv, &cp.config) == false)
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (send_cmd(mgmt, MGMT_OP_SET_EXTERNAL_CONFIG, index, sizeof(cp), &cp,
options_rsp) == 0) {
error("Unable to send Set External Config cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_debug_keys(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_debug_keys(int argc, char **argv)
{
- cmd_setting(mgmt, index, MGMT_OP_SET_DEBUG_KEYS, argc, argv);
+ cmd_setting(MGMT_OP_SET_DEBUG_KEYS, argc, argv);
}
static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
@@ -3387,12 +3219,12 @@ static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
if (len == 0 && status != 0) {
error("Get Conn Info failed, status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Unexpected Get Conn Info len %u", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
ba2str(&rp->addr.bdaddr, addr);
@@ -3408,22 +3240,21 @@ static void conn_info_rsp(uint8_t status, uint16_t len, const void *param,
rp->rssi, rp->tx_power, rp->max_tx_power);
}
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option conn_info_options[] = {
- { "help", 0, 0, 'h' },
- { "type", 1, 0, 't' },
+ { "help", 0, 0, 'h' },
+ { "type", 1, 0, 't' },
{ 0, 0, 0, 0 }
};
-static void cmd_conn_info(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_conn_info(int argc, char **argv)
{
struct mgmt_cp_get_conn_info cp;
uint8_t type = BDADDR_BREDR;
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+t:h", conn_info_options,
NULL)) != -1) {
@@ -3432,13 +3263,13 @@ static void cmd_conn_info(struct mgmt *mgmt, uint16_t index,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3447,10 +3278,11 @@ static void cmd_conn_info(struct mgmt *mgmt, uint16_t index,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3461,7 +3293,7 @@ static void cmd_conn_info(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_GET_CONN_INFO, index, sizeof(cp), &cp,
conn_info_rsp, NULL, NULL) == 0) {
error("Unable to send get_conn_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3474,20 +3306,16 @@ static void io_cap_rsp(uint8_t status, uint16_t len, const void *param,
else
print("IO Capabilities successfully set");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_io_cap(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_io_cap(int argc, char **argv)
{
struct mgmt_cp_set_io_capability cp;
uint8_t cap;
+ uint16_t index;
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3498,7 +3326,7 @@ static void cmd_io_cap(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_SET_IO_CAPABILITY, index, sizeof(cp), &cp,
io_cap_rsp, NULL, NULL) == 0) {
error("Unable to send set-io-cap cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3511,19 +3339,15 @@ static void scan_params_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Scan parameters successfully set");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_scan_params(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_scan_params(int argc, char **argv)
{
struct mgmt_cp_set_scan_params cp;
+ uint16_t index;
- if (argc < 3) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3533,7 +3357,7 @@ static void cmd_scan_params(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_SET_SCAN_PARAMS, index, sizeof(cp), &cp,
scan_params_rsp, NULL, NULL) == 0) {
error("Unable to send set_scan_params cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3544,27 +3368,28 @@ static void clock_info_rsp(uint8_t status, uint16_t len, const void *param,
if (len < sizeof(*rp)) {
error("Unexpected Get Clock Info len %u", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (status) {
error("Get Clock Info failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Local Clock: %u", le32_to_cpu(rp->local_clock));
print("Piconet Clock: %u", le32_to_cpu(rp->piconet_clock));
print("Accurary: %u", le16_to_cpu(rp->accuracy));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_clock_info(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_clock_info(int argc, char **argv)
{
struct mgmt_cp_get_clock_info cp;
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3576,7 +3401,7 @@ static void cmd_clock_info(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_GET_CLOCK_INFO, index, sizeof(cp), &cp,
clock_info_rsp, NULL, NULL) == 0) {
error("Unable to send get_clock_info cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3586,7 +3411,7 @@ static void add_device_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0)
error("Add device failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option add_device_options[] = {
@@ -3596,15 +3421,14 @@ static struct option add_device_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_add_device(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_add_device(int argc, char **argv)
{
struct mgmt_cp_add_device cp;
uint8_t action = 0x00;
uint8_t type = BDADDR_BREDR;
char addr[18];
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+a:t:h", add_device_options,
NULL)) != -1) {
@@ -3616,13 +3440,13 @@ static void cmd_add_device(struct mgmt *mgmt, uint16_t index,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3631,10 +3455,11 @@ static void cmd_add_device(struct mgmt *mgmt, uint16_t index,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3649,7 +3474,7 @@ static void cmd_add_device(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_ADD_DEVICE, index, sizeof(cp), &cp,
add_device_rsp, NULL, NULL) == 0) {
error("Unable to send add device command");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3659,7 +3484,7 @@ static void remove_device_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0)
error("Remove device failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static struct option del_device_options[] = {
@@ -3668,14 +3493,13 @@ static struct option del_device_options[] = {
{ 0, 0, 0, 0 }
};
-static void cmd_del_device(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_del_device(int argc, char **argv)
{
struct mgmt_cp_remove_device cp;
uint8_t type = BDADDR_BREDR;
char addr[18];
int opt;
- char *cmd = argv[0];
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+t:h", del_device_options,
NULL)) != -1) {
@@ -3684,13 +3508,13 @@ static void cmd_del_device(struct mgmt *mgmt, uint16_t index,
type = strtol(optarg, NULL, 0);
break;
case 'h':
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
default:
- cmd_usage(cmd);
+ bt_shell_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3699,10 +3523,12 @@ static void cmd_del_device(struct mgmt *mgmt, uint16_t index,
optind = 0;
if (argc < 1) {
- cmd_usage(cmd);
- return noninteractive_quit(EXIT_FAILURE);
+ bt_shell_usage();
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3716,17 +3542,16 @@ static void cmd_del_device(struct mgmt *mgmt, uint16_t index,
if (mgmt_send(mgmt, MGMT_OP_REMOVE_DEVICE, index, sizeof(cp), &cp,
remove_device_rsp, NULL, NULL) == 0) {
error("Unable to send remove device command");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_clr_devices(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_clr_devices(int argc, char **argv)
{
char *bdaddr_any = "00:00:00:00:00:00";
char *rm_argv[] = { "del-device", bdaddr_any, NULL };
- cmd_del_device(mgmt, index, 2, rm_argv);
+ cmd_del_device(2, rm_argv);
}
static void local_oob_ext_rsp(uint8_t status, uint16_t len, const void *param,
@@ -3738,31 +3563,32 @@ static void local_oob_ext_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Read Local OOB Ext Data failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small (%u bytes) read_local_oob_ext rsp", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
eir_len = le16_to_cpu(rp->eir_len);
if (len != sizeof(*rp) + eir_len) {
error("local_oob_ext: expected %zu bytes, got %u bytes",
sizeof(*rp) + eir_len, len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print_eir(rp->eir, eir_len);
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_bredr_oob(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_bredr_oob(int argc, char **argv)
{
struct mgmt_cp_read_local_oob_ext_data cp;
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3772,15 +3598,16 @@ static void cmd_bredr_oob(struct mgmt *mgmt, uint16_t index,
index, sizeof(cp), &cp,
local_oob_ext_rsp, NULL, NULL)) {
error("Unable to send read_local_oob_ext cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_le_oob(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_le_oob(int argc, char **argv)
{
struct mgmt_cp_read_local_oob_ext_data cp;
+ uint16_t index;
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3790,7 +3617,7 @@ static void cmd_le_oob(struct mgmt *mgmt, uint16_t index,
index, sizeof(cp), &cp,
local_oob_ext_rsp, NULL, NULL)) {
error("Unable to send read_local_oob_ext cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3831,18 +3658,18 @@ static void adv_features_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Reading adv features failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small adv features reply (%u bytes)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp) + rp->num_instances * sizeof(uint8_t)) {
error("Instances count (%u) doesn't match reply length (%u)",
rp->num_instances, len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
supported_flags = le32_to_cpu(rp->supported_flags);
@@ -3854,19 +3681,21 @@ static void adv_features_rsp(uint8_t status, uint16_t len, const void *param,
print("Instances list with %u item%s", rp->num_instances,
rp->num_instances != 1 ? "s" : "");
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_advinfo(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_advinfo(int argc, char **argv)
{
+ uint16_t index;
+
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
if (!mgmt_send(mgmt, MGMT_OP_READ_ADV_FEATURES, index, 0, NULL,
adv_features_rsp, NULL, NULL)) {
error("Unable to send advertising features command");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3879,12 +3708,12 @@ static void adv_size_info_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Reading adv size info failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len < sizeof(*rp)) {
error("Too small adv size info reply (%u bytes)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
flags = le32_to_cpu(rp->flags);
@@ -3893,19 +3722,19 @@ static void adv_size_info_rsp(uint8_t status, uint16_t len, const void *param,
print("Max advertising data len: %u", rp->max_adv_data_len);
print("Max scan response data len: %u", rp->max_scan_rsp_len);
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void advsize_usage(void)
{
- cmd_usage("advsize");
+ bt_shell_usage();
print("Options:\n"
"\t -c, --connectable \"connectable\" flag\n"
"\t -g, --general-discov \"general-discoverable\" flag\n"
"\t -l, --limited-discov \"limited-discoverable\" flag\n"
"\t -m, --managed-flags \"managed-flags\" flag\n"
- "\t -p, --tx-power \"tx-power\" flag\n"\
- "\t -a, --appearance \"appearance\" flag\n"\
+ "\t -p, --tx-power \"tx-power\" flag\n"
+ "\t -a, --appearance \"appearance\" flag\n"
"\t -n, --local-name \"local-name\" flag");
}
@@ -3921,13 +3750,13 @@ static struct option advsize_options[] = {
{ 0, 0, 0, 0}
};
-static void cmd_advsize(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_advsize(int argc, char **argv)
{
struct mgmt_cp_get_adv_size_info cp;
uint8_t instance;
uint32_t flags = 0;
int opt;
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+cglmphna",
advsize_options, NULL)) != -1) {
@@ -3956,7 +3785,7 @@ static void cmd_advsize(struct mgmt *mgmt, uint16_t index,
default:
advsize_usage();
optind = 0;
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3966,11 +3795,12 @@ static void cmd_advsize(struct mgmt *mgmt, uint16_t index,
if (argc != 1) {
advsize_usage();
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
instance = strtol(argv[0], NULL, 0);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -3982,7 +3812,7 @@ static void cmd_advsize(struct mgmt *mgmt, uint16_t index,
if (!mgmt_send(mgmt, MGMT_OP_GET_ADV_SIZE_INFO, index, sizeof(cp), &cp,
adv_size_info_rsp, NULL, NULL)) {
error("Unable to send advertising size info command");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
@@ -3994,22 +3824,22 @@ static void add_adv_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Add Advertising failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Invalid Add Advertising response length (%u)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Instance added: %u", rp->instance);
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void add_adv_usage(void)
{
- cmd_usage("add-adv");
+ bt_shell_usage();
print("Options:\n"
"\t -u, --uuid <uuid> Service UUID\n"
"\t -d, --adv-data <data> Advertising Data bytes\n"
@@ -4084,8 +3914,7 @@ static bool parse_bytes(char *optarg, uint8_t **bytes, size_t *len)
#define MAX_AD_UUID_BYTES 32
-static void cmd_add_adv(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
+static void cmd_add_adv(int argc, char **argv)
{
struct mgmt_cp_add_advertising *cp = NULL;
int opt;
@@ -4101,6 +3930,7 @@ static void cmd_add_adv(struct mgmt *mgmt, uint16_t index,
bool success = false;
bool quit = true;
uint32_t flags = 0;
+ uint16_t index;
while ((opt = getopt_long(argc, argv, "+u:d:s:t:D:cglmphna",
add_adv_options, NULL)) != -1) {
@@ -4211,6 +4041,7 @@ static void cmd_add_adv(struct mgmt *mgmt, uint16_t index,
instance = strtol(argv[0], NULL, 0);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -4249,7 +4080,7 @@ done:
free(cp);
if (quit)
- noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
+ bt_shell_noninteractive_quit(success ? EXIT_SUCCESS : EXIT_FAILURE);
}
static void rm_adv_rsp(uint8_t status, uint16_t len, const void *param,
@@ -4260,31 +4091,28 @@ static void rm_adv_rsp(uint8_t status, uint16_t len, const void *param,
if (status != 0) {
error("Remove Advertising failed with status 0x%02x (%s)",
status, mgmt_errstr(status));
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
if (len != sizeof(*rp)) {
error("Invalid Remove Advertising response length (%u)", len);
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
print("Instance removed: %u", rp->instance);
- return noninteractive_quit(EXIT_SUCCESS);
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_rm_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_rm_adv(int argc, char **argv)
{
struct mgmt_cp_remove_advertising cp;
uint8_t instance;
-
- if (argc != 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
+ uint16_t index;
instance = strtol(argv[1], NULL, 0);
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -4295,16 +4123,16 @@ static void cmd_rm_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
if (!mgmt_send(mgmt, MGMT_OP_REMOVE_ADVERTISING, index, sizeof(cp), &cp,
rm_adv_rsp, NULL, NULL)) {
error("Unable to send \"Remove Advertising\" command");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-static void cmd_clr_adv(struct mgmt *mgmt, uint16_t index, int argc, char **argv)
+static void cmd_clr_adv(int argc, char **argv)
{
char *all_instances = "0";
char *rm_argv[] = { "rm-adv", all_instances, NULL };
- cmd_rm_adv(mgmt, index, 2, rm_argv);
+ cmd_rm_adv(2, rm_argv);
}
static void appearance_rsp(uint8_t status, uint16_t len, const void *param,
@@ -4316,19 +4144,15 @@ static void appearance_rsp(uint8_t status, uint16_t len, const void *param,
else
print("Appearance successfully set");
- noninteractive_quit(EXIT_SUCCESS);
+ bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
-static void cmd_appearance(struct mgmt *mgmt, uint16_t index, int argc,
- char **argv)
+static void cmd_appearance(int argc, char **argv)
{
struct mgmt_cp_set_appearance cp;
+ uint16_t index;
- if (argc < 2) {
- cmd_usage(argv[0]);
- return noninteractive_quit(EXIT_FAILURE);
- }
-
+ index = mgmt_index;
if (index == MGMT_INDEX_NONE)
index = 0;
@@ -4337,20 +4161,83 @@ static void cmd_appearance(struct mgmt *mgmt, uint16_t index, int argc,
if (mgmt_send(mgmt, MGMT_OP_SET_APPEARANCE, index, sizeof(cp), &cp,
appearance_rsp, NULL, NULL) == 0) {
error("Unable to send appearance cmd");
- return noninteractive_quit(EXIT_FAILURE);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
-struct cmd_info {
- char *cmd;
- const char *arg;
- void (*func)(struct mgmt *mgmt, uint16_t index, int argc, char **argv);
- char *doc;
- char * (*gen) (const char *text, int state);
- void (*disp) (char **matches, int num_matches, int max_length);
-};
+static void register_mgmt_callbacks(struct mgmt *mgmt, uint16_t index)
+{
+ mgmt_register(mgmt, MGMT_EV_CONTROLLER_ERROR, index, controller_error,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_INDEX_ADDED, index, index_added,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_INDEX_REMOVED, index, index_removed,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_NEW_SETTINGS, index, new_settings,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_DISCOVERING, index, discovering,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_NEW_LINK_KEY, index, new_link_key,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_DEVICE_CONNECTED, index, connected,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_DEVICE_DISCONNECTED, index, disconnected,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_CONNECT_FAILED, index, conn_failed,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_AUTH_FAILED, index, auth_failed,
+ NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED, index,
+ class_of_dev_changed, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_LOCAL_NAME_CHANGED, index,
+ local_name_changed, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_DEVICE_FOUND, index, device_found,
+ mgmt, NULL);
+ mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index, request_pin,
+ mgmt, NULL);
+ mgmt_register(mgmt, MGMT_EV_USER_CONFIRM_REQUEST, index, user_confirm,
+ mgmt, NULL);
+ mgmt_register(mgmt, MGMT_EV_USER_PASSKEY_REQUEST, index,
+ request_passkey, mgmt, NULL);
+ mgmt_register(mgmt, MGMT_EV_PASSKEY_NOTIFY, index,
+ passkey_notify, mgmt, NULL);
+ mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_ADDED, index,
+ unconf_index_added, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_REMOVED, index,
+ unconf_index_removed, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_NEW_CONFIG_OPTIONS, index,
+ new_config_options, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_EXT_INDEX_ADDED, index,
+ ext_index_added, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_EXT_INDEX_REMOVED, index,
+ ext_index_removed, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_LOCAL_OOB_DATA_UPDATED, index,
+ local_oob_data_updated, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_ADVERTISING_ADDED, index,
+ advertising_added, NULL, NULL);
+ mgmt_register(mgmt, MGMT_EV_ADVERTISING_REMOVED, index,
+ advertising_removed, NULL, NULL);
+}
+
+static void cmd_select(int argc, char **argv)
+{
+ mgmt_cancel_all(mgmt);
+ mgmt_unregister_all(mgmt);
-static struct cmd_info all_cmd[] = {
+ set_index(argv[1]);
+
+ register_mgmt_callbacks(mgmt, mgmt_index);
+
+ print("Selected index %u", mgmt_index);
+
+ update_prompt(mgmt_index);
+}
+
+static const struct bt_shell_menu main_menu = {
+ .name = "main",
+ .entries = {
+ { "select", "<index>",
+ cmd_select, "Select a different index" },
{ "version", NULL,
cmd_version, "Get the MGMT Version" },
{ "commands", NULL,
@@ -4473,363 +4360,45 @@ static struct cmd_info all_cmd[] = {
cmd_clr_adv, "Clear advertising instances" },
{ "appearance", "<appearance>",
cmd_appearance, "Set appearance" },
+ {} },
};
-static void cmd_quit(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
-{
- mainloop_exit_success();
-}
-
-static void register_mgmt_callbacks(struct mgmt *mgmt, uint16_t index)
-{
- mgmt_register(mgmt, MGMT_EV_CONTROLLER_ERROR, index, controller_error,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_INDEX_ADDED, index, index_added,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_INDEX_REMOVED, index, index_removed,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_NEW_SETTINGS, index, new_settings,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_DISCOVERING, index, discovering,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_NEW_LINK_KEY, index, new_link_key,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_DEVICE_CONNECTED, index, connected,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_DEVICE_DISCONNECTED, index, disconnected,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_CONNECT_FAILED, index, conn_failed,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_AUTH_FAILED, index, auth_failed,
- NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED, index,
- class_of_dev_changed, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_LOCAL_NAME_CHANGED, index,
- local_name_changed, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_DEVICE_FOUND, index, device_found,
- mgmt, NULL);
- mgmt_register(mgmt, MGMT_EV_PIN_CODE_REQUEST, index, request_pin,
- mgmt, NULL);
- mgmt_register(mgmt, MGMT_EV_USER_CONFIRM_REQUEST, index, user_confirm,
- mgmt, NULL);
- mgmt_register(mgmt, MGMT_EV_USER_PASSKEY_REQUEST, index,
- request_passkey, mgmt, NULL);
- mgmt_register(mgmt, MGMT_EV_PASSKEY_NOTIFY, index,
- passkey_notify, mgmt, NULL);
- mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_ADDED, index,
- unconf_index_added, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_UNCONF_INDEX_REMOVED, index,
- unconf_index_removed, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_NEW_CONFIG_OPTIONS, index,
- new_config_options, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_EXT_INDEX_ADDED, index,
- ext_index_added, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_EXT_INDEX_REMOVED, index,
- ext_index_removed, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_LOCAL_OOB_DATA_UPDATED, index,
- local_oob_data_updated, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_ADVERTISING_ADDED, index,
- advertising_added, NULL, NULL);
- mgmt_register(mgmt, MGMT_EV_ADVERTISING_REMOVED, index,
- advertising_removed, NULL, NULL);
-}
-
-static void cmd_select(struct mgmt *mgmt, uint16_t index,
- int argc, char **argv)
-{
- if (argc != 2) {
- cmd_usage(argv[0]);
- return;
- }
-
- mgmt_cancel_all(mgmt);
- mgmt_unregister_all(mgmt);
-
- set_index(argv[1]);
-
- register_mgmt_callbacks(mgmt, mgmt_index);
-
- print("Selected index %u", mgmt_index);
-
- update_prompt(mgmt_index);
-}
-
-static struct cmd_info interactive_cmd[] = {
- { "select", "<index>",
- cmd_select, "Select a different index" },
- { "quit", NULL,
- cmd_quit, "Exit program" },
- { "exit", NULL,
- cmd_quit, "Exit program" },
- { "help", NULL,
- NULL, "List supported commands" },
-};
-
-static char *cmd_generator(const char *text, int state)
-{
- static size_t i, j, len;
- const char *cmd;
-
- if (!state) {
- i = 0;
- j = 0;
- len = strlen(text);
- }
-
- while (i < NELEM(all_cmd)) {
- cmd = all_cmd[i++].cmd;
-
- if (!strncmp(cmd, text, len))
- return strdup(cmd);
- }
-
- while (j < NELEM(interactive_cmd)) {
- cmd = interactive_cmd[j++].cmd;
-
- if (!strncmp(cmd, text, len))
- return strdup(cmd);
- }
-
- return NULL;
-}
-
-static char **cmd_completion(const char *text, int start, int end)
-{
- char **matches = NULL;
-
- if (start > 0) {
- unsigned int i;
-
- for (i = 0; i < NELEM(all_cmd); i++) {
- struct cmd_info *c = &all_cmd[i];
-
- if (strncmp(c->cmd, rl_line_buffer, start - 1))
- continue;
-
- if (!c->gen)
- continue;
-
- rl_completion_display_matches_hook = c->disp;
- matches = rl_completion_matches(text, c->gen);
- break;
- }
- } else {
- rl_completion_display_matches_hook = NULL;
- matches = rl_completion_matches(text, cmd_generator);
- }
-
- if (!matches)
- rl_attempted_completion_over = 1;
-
- return matches;
-}
-
-static struct cmd_info *find_cmd(const char *cmd, struct cmd_info table[],
- size_t cmd_count)
-{
- size_t i;
-
- for (i = 0; i < cmd_count; i++) {
- if (!strcmp(table[i].cmd, cmd))
- return &table[i];
- }
-
- return NULL;
-}
-
-static void cmd_usage(char *cmd)
-{
- struct cmd_info *c;
-
- if (!cmd)
- return;
-
- c = find_cmd(cmd, all_cmd, NELEM(all_cmd));
- if (!c && interactive) {
- c = find_cmd(cmd, interactive_cmd, NELEM(interactive_cmd));
- if (!c)
- return;
- error("Usage: %s %s", cmd, c->arg ? : "");
- return;
- }
-
- if (!c)
- return;
-
- print("Usage: %s %s", cmd, c->arg ? : "");
-
-}
-
-static void rl_handler(char *input)
+static void mgmt_debug(const char *str, void *user_data)
{
- struct cmd_info *c;
- wordexp_t w;
- char *cmd, **argv;
- size_t argc, i;
-
- if (!input) {
- rl_insert_text("quit");
- rl_redisplay();
- rl_crlf();
- mainloop_quit();
- return;
- }
-
- if (!strlen(input))
- goto done;
-
- if (prompt_input(input))
- goto done;
-
- if (history_search(input, -1))
- add_history(input);
-
- if (wordexp(input, &w, WRDE_NOCMD))
- goto done;
-
- if (w.we_wordc == 0)
- goto free_we;
-
- cmd = w.we_wordv[0];
- argv = w.we_wordv;
- argc = w.we_wordc;
-
- c = find_cmd(cmd, all_cmd, NELEM(all_cmd));
- if (!c && interactive)
- c = find_cmd(cmd, interactive_cmd, NELEM(interactive_cmd));
-
- if (c && c->func) {
- c->func(mgmt, mgmt_index, argc, argv);
- goto free_we;
- }
-
- if (strcmp(cmd, "help")) {
- print("Invalid command");
- goto free_we;
- }
-
- print("Available commands:");
-
- for (i = 0; i < NELEM(all_cmd); i++) {
- c = &all_cmd[i];
- if ((int)strlen(c->arg ? : "") <=
- (int)(25 - strlen(c->cmd)))
- printf(" %s %-*s %s\n", c->cmd,
- (int)(25 - strlen(c->cmd)),
- c->arg ? : "",
- c->doc ? : "");
- else
- printf(" %s %-s\n" " %s %-25s %s\n",
- c->cmd,
- c->arg ? : "",
- "", "",
- c->doc ? : "");
- }
-
- if (!interactive)
- goto free_we;
-
- for (i = 0; i < NELEM(interactive_cmd); i++) {
- c = &interactive_cmd[i];
- if ((int)strlen(c->arg ? : "") <=
- (int)(25 - strlen(c->cmd)))
- printf(" %s %-*s %s\n", c->cmd,
- (int)(25 - strlen(c->cmd)),
- c->arg ? : "",
- c->doc ? : "");
- else
- printf(" %s %-s\n" " %s %-25s %s\n",
- c->cmd,
- c->arg ? : "",
- "", "",
- c->doc ? : "");
- }
+ const char *prefix = user_data;
-free_we:
- wordfree(&w);
-done:
- free(input);
+ print("%s%s", prefix, str);
}
-static void usage(void)
-{
- unsigned int i;
-
- printf("btmgmt ver %s\n", VERSION);
- printf("Usage:\n"
- "\tbtmgmt [options] <command> [command parameters]\n");
-
- printf("Options:\n"
- "\t--index <id>\tSpecify adapter index\n"
- "\t--verbose\tEnable extra logging\n"
- "\t--help\tDisplay help\n");
-
- printf("Commands:\n");
- for (i = 0; i < NELEM(all_cmd); i++)
- printf("\t%-15s\t%s\n", all_cmd[i].cmd, all_cmd[i].doc);
-
- printf("\n"
- "For more information on the usage of each command use:\n"
- "\tbtmgmt <command> --help\n" );
-}
+static const char *index_option;
static struct option main_options[] = {
{ "index", 1, 0, 'i' },
- { "verbose", 0, 0, 'v' },
- { "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
};
-static bool prompt_read(struct io *io, void *user_data)
-{
- rl_callback_read_char();
- return true;
-}
-
-static struct io *setup_stdin(void)
-{
- struct io *io;
-
- io = io_new(STDIN_FILENO);
- if (!io)
- return io;
-
- io_set_read_handler(io, prompt_read, NULL, NULL);
-
- return io;
-}
+static const char **optargs[] = {
+ &index_option
+};
-static void mgmt_debug(const char *str, void *user_data)
-{
- const char *prefix = user_data;
+static const char *help[] = {
+ "Specify adapter index\n"
+};
- print("%s%s", prefix, str);
-}
+static const struct bt_shell_opt opt = {
+ .options = main_options,
+ .optno = sizeof(main_options) / sizeof(struct option),
+ .optstr = "i:V",
+ .optarg = optargs,
+ .help = help,
+};
int main(int argc, char *argv[])
{
- struct io *input;
- int status, opt;
-
- while ((opt = getopt_long(argc, argv, "+hi:",
- main_options, NULL)) != -1) {
- switch (opt) {
- case 'i':
- set_index(optarg);
- break;
- case 'h':
- default:
- usage();
- return 0;
- }
- }
+ int status;
- argc -= optind;
- argv += optind;
- optind = 0;
-
- mainloop_init();
+ bt_shell_init(argc, argv, &opt);
+ bt_shell_set_menu(&main_menu);
mgmt = mgmt_new_default();
if (!mgmt) {
@@ -4840,47 +4409,14 @@ int main(int argc, char *argv[])
if (getenv("MGMT_DEBUG"))
mgmt_set_debug(mgmt, mgmt_debug, "mgmt: ", NULL);
- if (argc > 0) {
- struct cmd_info *c;
-
- c = find_cmd(argv[0], all_cmd, NELEM(all_cmd));
- if (!c) {
- fprintf(stderr, "Unknown command: %s\n", argv[0]);
- mgmt_unref(mgmt);
- return EXIT_FAILURE;
- }
-
- c->func(mgmt, mgmt_index, argc, argv);
- }
+ if (index_option)
+ set_index(index_option);
register_mgmt_callbacks(mgmt, mgmt_index);
- /* Interactive mode */
- if (!argc)
- input = setup_stdin();
- else
- input = NULL;
-
- if (input) {
- interactive = true;
-
- rl_attempted_completion_function = cmd_completion;
-
- rl_erase_empty_line = 1;
- rl_callback_handler_install(NULL, rl_handler);
-
- update_prompt(mgmt_index);
- rl_redisplay();
- }
-
- status = mainloop_run();
-
- if (input) {
- io_destroy(input);
-
- rl_message("");
- rl_callback_handler_remove();
- }
+ bt_shell_attach(fileno(stdin));
+ update_prompt(mgmt_index);
+ bt_shell_run();
mgmt_cancel_all(mgmt);
mgmt_unregister_all(mgmt);
diff --git a/tools/obexctl.c b/tools/obexctl.c
index 209442c0..d72f33e0 100755
--- a/tools/obexctl.c
+++ b/tools/obexctl.c
@@ -59,13 +59,13 @@
static DBusConnection *dbus_conn;
static GDBusProxy *default_session;
-static GSList *sessions = NULL;
-static GSList *opps = NULL;
-static GSList *ftps = NULL;
-static GSList *pbaps = NULL;
-static GSList *maps = NULL;
-static GSList *msgs = NULL;
-static GSList *transfers = NULL;
+static GList *sessions = NULL;
+static GList *opps = NULL;
+static GList *ftps = NULL;
+static GList *pbaps = NULL;
+static GList *maps = NULL;
+static GList *msgs = NULL;
+static GList *transfers = NULL;
static GDBusProxy *client = NULL;
struct transfer_data {
@@ -219,26 +219,13 @@ static void disconnect_setup(DBusMessageIter *iter, void *user_data)
dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
}
-static GDBusProxy *find_session(const char *path)
-{
- GSList *l;
-
- for (l = sessions; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void cmd_disconnect(int argc, char *argv[])
{
GDBusProxy *proxy;
if (argc > 1)
- proxy = find_session(argv[1]);
+ proxy = g_dbus_proxy_lookup(sessions, NULL, argv[1],
+ OBEX_SESSION_INTERFACE);
else
proxy = default_session;
@@ -285,9 +272,9 @@ static void print_proxy(GDBusProxy *proxy, const char *title,
static void cmd_list(int argc, char *arg[])
{
- GSList *l;
+ GList *l;
- for (l = sessions; l; l = g_slist_next(l)) {
+ for (l = sessions; l; l = g_list_next(l)) {
GDBusProxy *proxy = l->data;
print_proxy(proxy, "Session", NULL);
}
@@ -393,7 +380,8 @@ static void cmd_show(int argc, char *argv[])
proxy = default_session;
} else {
- proxy = find_session(argv[1]);
+ proxy = g_dbus_proxy_lookup(sessions, NULL, argv[1],
+ OBEX_SESSION_INTERFACE);
if (!proxy) {
bt_shell_printf("Session %s not available\n", argv[1]);
return;
@@ -430,7 +418,8 @@ static void cmd_select(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_session(argv[1]);
+ proxy = g_dbus_proxy_lookup(sessions, NULL, argv[1],
+ OBEX_SESSION_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Session %s not available\n", argv[1]);
return;
@@ -444,34 +433,6 @@ static void cmd_select(int argc, char *argv[])
print_proxy(proxy, "Session", NULL);
}
-static GDBusProxy *find_transfer(const char *path)
-{
- GSList *l;
-
- for (l = transfers; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
-static GDBusProxy *find_message(const char *path)
-{
- GSList *l;
-
- for (l = msgs; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void transfer_info(GDBusProxy *proxy, int argc, char *argv[])
{
bt_shell_printf("Transfer %s\n", g_dbus_proxy_get_path(proxy));
@@ -512,13 +473,14 @@ static void cmd_info(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_transfer(argv[1]);
+ proxy = g_dbus_proxy_lookup(transfers, NULL, argv[1],
+ OBEX_TRANSFER_INTERFACE);
if (proxy) {
transfer_info(proxy, argc, argv);
return;
}
- proxy = find_message(argv[1]);
+ proxy = g_dbus_proxy_lookup(msgs, NULL, argv[1], OBEX_MSG_INTERFACE);
if (proxy) {
message_info(proxy, argc, argv);
return;
@@ -546,7 +508,8 @@ static void cmd_cancel(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_transfer(argv[1]);
+ proxy = g_dbus_proxy_lookup(transfers, NULL, argv[1],
+ OBEX_TRANSFER_INTERFACE);
if (!proxy) {
bt_shell_printf("Transfer %s not available\n", argv[1]);
return;
@@ -581,7 +544,8 @@ static void cmd_suspend(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_transfer(argv[1]);
+ proxy = g_dbus_proxy_lookup(transfers, NULL, argv[1],
+ OBEX_TRANSFER_INTERFACE);
if (!proxy) {
bt_shell_printf("Transfer %s not available\n", argv[1]);
return;
@@ -616,7 +580,8 @@ static void cmd_resume(int argc, char *argv[])
{
GDBusProxy *proxy;
- proxy = find_transfer(argv[1]);
+ proxy = g_dbus_proxy_lookup(transfers, NULL, argv[1],
+ OBEX_TRANSFER_INTERFACE);
if (!proxy) {
bt_shell_printf("Transfer %s not available\n", argv[1]);
return;
@@ -632,34 +597,6 @@ static void cmd_resume(int argc, char *argv[])
g_dbus_proxy_get_path(proxy));
}
-static GDBusProxy *find_opp(const char *path)
-{
- GSList *l;
-
- for (l = opps; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
-static GDBusProxy *find_map(const char *path)
-{
- GSList *l;
-
- for (l = maps; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void print_dict_iter(DBusMessageIter *iter)
{
DBusMessageIter dict;
@@ -806,18 +743,19 @@ static void map_send(GDBusProxy *proxy, int argc, char *argv[])
static void cmd_send(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_opp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(opps, NULL, path, OBEX_OPP_INTERFACE);
if (proxy) {
opp_send(proxy, argc, argv);
return;
}
- proxy = find_map(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(maps, NULL, path, OBEX_MAP_INTERFACE);
if (proxy) {
map_send(proxy, argc, argv);
return;
@@ -828,12 +766,13 @@ static void cmd_send(int argc, char *argv[])
static void cmd_pull(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_opp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(opps, NULL, path, OBEX_OPP_INTERFACE);
if (proxy) {
opp_pull(proxy, argc, argv);
return;
@@ -913,34 +852,6 @@ static void setfolder_setup(DBusMessageIter *iter, void *user_data)
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &folder);
}
-static GDBusProxy *find_ftp(const char *path)
-{
- GSList *l;
-
- for (l = ftps; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
-static GDBusProxy *find_pbap(const char *path)
-{
- GSList *l;
-
- for (l = pbaps; l; l = g_slist_next(l)) {
- GDBusProxy *proxy = l->data;
-
- if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
- return proxy;
- }
-
- return NULL;
-}
-
static void ftp_cd(GDBusProxy *proxy, int argc, char *argv[])
{
if (g_dbus_proxy_method_call(proxy, "ChangeFolder", change_folder_setup,
@@ -979,24 +890,25 @@ static void map_cd(GDBusProxy *proxy, int argc, char *argv[])
static void cmd_cd(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_ftp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(ftps, NULL, path, OBEX_FTP_INTERFACE);
if (proxy) {
ftp_cd(proxy, argc, argv);
return;
}
- proxy = find_pbap(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(pbaps, NULL, path, OBEX_PBAP_INTERFACE);
if (proxy) {
pbap_cd(proxy, argc, argv);
return;
}
- proxy = find_map(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(maps, NULL, path, OBEX_MAP_INTERFACE);
if (proxy) {
map_cd(proxy, argc, argv);
return;
@@ -1326,24 +1238,25 @@ static void map_ls(GDBusProxy *proxy, int argc, char *argv[])
static void cmd_ls(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_ftp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(ftps, NULL, path, OBEX_FTP_INTERFACE);
if (proxy) {
ftp_ls(proxy, argc, argv);
return;
}
- proxy = find_pbap(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(pbaps, NULL, path, OBEX_PBAP_INTERFACE);
if (proxy) {
pbap_ls(proxy, argc, argv);
return;
}
- proxy = find_map(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(maps, NULL, path, OBEX_MAP_INTERFACE);
if (proxy) {
map_ls(proxy, argc, argv);
return;
@@ -1652,7 +1565,7 @@ static void map_cp(GDBusProxy *proxy, int argc, char *argv[])
{
GDBusProxy *obj;
- obj = find_message(argv[1]);
+ obj = g_dbus_proxy_lookup(msgs, NULL, argv[1], OBEX_MSG_INTERFACE);
if (obj == NULL) {
bt_shell_printf("Invalid message argument\n");
return;
@@ -1669,25 +1582,25 @@ static void map_cp(GDBusProxy *proxy, int argc, char *argv[])
static void cmd_cp(int argc, char *argv[])
{
-
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_ftp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(ftps, NULL, path, OBEX_FTP_INTERFACE);
if (proxy) {
ftp_cp(proxy, argc, argv);
return;
}
- proxy = find_pbap(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(pbaps, NULL, path, OBEX_PBAP_INTERFACE);
if (proxy) {
pbap_cp(proxy, argc, argv);
return;
}
- proxy = find_map(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(maps, NULL, path, OBEX_MAP_INTERFACE);
if (proxy) {
map_cp(proxy, argc, argv);
return;
@@ -1713,13 +1626,14 @@ static void move_file_reply(DBusMessage *message, void *user_data)
static void cmd_mv(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
struct cp_args *args;
if (!check_default_session())
return;
- proxy = find_ftp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(ftps, NULL, path, OBEX_FTP_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Command not supported\n");
return;
@@ -1783,7 +1697,7 @@ static void map_rm(GDBusProxy *proxy, int argc, char *argv[])
GDBusProxy *msg;
dbus_bool_t value = TRUE;
- msg = find_message(argv[1]);
+ msg = g_dbus_proxy_lookup(msgs, NULL, argv[1], OBEX_MSG_INTERFACE);
if (msg == NULL) {
bt_shell_printf("Invalid message argument\n");
return;
@@ -1801,18 +1715,19 @@ static void map_rm(GDBusProxy *proxy, int argc, char *argv[])
static void cmd_rm(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_ftp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(ftps, NULL, path, OBEX_FTP_INTERFACE);
if (proxy) {
ftp_rm(proxy, argc, argv);
return;
}
- proxy = find_map(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(maps, NULL, path, OBEX_MAP_INTERFACE);
if (proxy) {
map_rm(proxy, argc, argv);
return;
@@ -1845,12 +1760,13 @@ static void create_folder_setup(DBusMessageIter *iter, void *user_data)
static void cmd_mkdir(int argc, char *argv[])
{
+ const char *path = g_dbus_proxy_get_path(default_session);
GDBusProxy *proxy;
if (!check_default_session())
return;
- proxy = find_ftp(g_dbus_proxy_get_path(default_session));
+ proxy = g_dbus_proxy_lookup(ftps, NULL, path, OBEX_FTP_INTERFACE);
if (proxy == NULL) {
bt_shell_printf("Command not supported\n");
return;
@@ -1902,7 +1818,7 @@ static void client_added(GDBusProxy *proxy)
static void session_added(GDBusProxy *proxy)
{
- sessions = g_slist_append(sessions, proxy);
+ sessions = g_list_append(sessions, proxy);
if (default_session == NULL)
set_default_session(proxy);
@@ -1969,7 +1885,7 @@ static void transfer_added(GDBusProxy *proxy)
struct transfer_data *data;
DBusMessageIter iter;
- transfers = g_slist_append(transfers, proxy);
+ transfers = g_list_append(transfers, proxy);
print_proxy(proxy, "Transfer", COLORED_NEW);
@@ -1987,35 +1903,35 @@ static void transfer_added(GDBusProxy *proxy)
static void opp_added(GDBusProxy *proxy)
{
- opps = g_slist_append(opps, proxy);
+ opps = g_list_append(opps, proxy);
print_proxy(proxy, "ObjectPush", COLORED_NEW);
}
static void ftp_added(GDBusProxy *proxy)
{
- ftps = g_slist_append(ftps, proxy);
+ ftps = g_list_append(ftps, proxy);
print_proxy(proxy, "FileTransfer", COLORED_NEW);
}
static void pbap_added(GDBusProxy *proxy)
{
- pbaps = g_slist_append(pbaps, proxy);
+ pbaps = g_list_append(pbaps, proxy);
print_proxy(proxy, "PhonebookAccess", COLORED_NEW);
}
static void map_added(GDBusProxy *proxy)
{
- maps = g_slist_append(maps, proxy);
+ maps = g_list_append(maps, proxy);
print_proxy(proxy, "MessageAccess", COLORED_NEW);
}
static void msg_added(GDBusProxy *proxy)
{
- msgs = g_slist_append(msgs, proxy);
+ msgs = g_list_append(msgs, proxy);
print_proxy(proxy, "Message", COLORED_NEW);
}
@@ -2059,49 +1975,49 @@ static void session_removed(GDBusProxy *proxy)
if (default_session == proxy)
set_default_session(NULL);
- sessions = g_slist_remove(sessions, proxy);
+ sessions = g_list_remove(sessions, proxy);
}
static void transfer_removed(GDBusProxy *proxy)
{
print_proxy(proxy, "Transfer", COLORED_DEL);
- transfers = g_slist_remove(transfers, proxy);
+ transfers = g_list_remove(transfers, proxy);
}
static void opp_removed(GDBusProxy *proxy)
{
print_proxy(proxy, "ObjectPush", COLORED_DEL);
- opps = g_slist_remove(opps, proxy);
+ opps = g_list_remove(opps, proxy);
}
static void ftp_removed(GDBusProxy *proxy)
{
print_proxy(proxy, "FileTransfer", COLORED_DEL);
- ftps = g_slist_remove(ftps, proxy);
+ ftps = g_list_remove(ftps, proxy);
}
static void pbap_removed(GDBusProxy *proxy)
{
print_proxy(proxy, "PhonebookAccess", COLORED_DEL);
- pbaps = g_slist_remove(pbaps, proxy);
+ pbaps = g_list_remove(pbaps, proxy);
}
static void map_removed(GDBusProxy *proxy)
{
print_proxy(proxy, "MessageAccess", COLORED_DEL);
- maps = g_slist_remove(maps, proxy);
+ maps = g_list_remove(maps, proxy);
}
static void msg_removed(GDBusProxy *proxy)
{
print_proxy(proxy, "Message", COLORED_DEL);
- msgs = g_slist_remove(msgs, proxy);
+ msgs = g_list_remove(msgs, proxy);
}
static void proxy_removed(GDBusProxy *proxy, void *user_data)
diff --git a/unit/test-ecc.c b/unit/test-ecc.c
index 9b48d0b3..d9136814 100755
--- a/unit/test-ecc.c
+++ b/unit/test-ecc.c
@@ -94,7 +94,10 @@ static int test_sample(uint8_t priv_a[32], uint8_t priv_b[32],
uint8_t dhkey_a[32], dhkey_b[32];
int fails = 0;
+ memset(dhkey_a, 0, sizeof(dhkey_a));
ecdh_shared_secret(pub_b, priv_a, dhkey_a);
+
+ memset(dhkey_b, 0, sizeof(dhkey_b));
ecdh_shared_secret(pub_a, priv_b, dhkey_b);
if (g_test_verbose()) {
@@ -110,6 +113,7 @@ static int test_sample(uint8_t priv_a[32], uint8_t priv_b[32],
tester_debug("DHKey A matches :)");
}
+
if (memcmp(dhkey_b, dhkey, 32)) {
tester_debug("DHKey B doesn't match!");
fails++;
@@ -243,6 +247,39 @@ static void test_sample_3(const void *data)
tester_test_passed();
}
+static void test_invalid_pub(const void *data)
+{
+ uint8_t priv_a[32] = { 0xbd, 0x1a, 0x3c, 0xcd, 0xa6, 0xb8, 0x99, 0x58,
+ 0x99, 0xb7, 0x40, 0xeb, 0x7b, 0x60, 0xff, 0x4a,
+ 0x50, 0x3f, 0x10, 0xd2, 0xe3, 0xb3, 0xc9, 0x74,
+ 0x38, 0x5f, 0xc5, 0xa3, 0xd4, 0xf6, 0x49, 0x3f,
+ };
+ uint8_t pub_a[64] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc,
+ 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef,
+ 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
+ 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20,
+
+ 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74,
+ 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
+ 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63,
+ 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc,
+ };
+ uint8_t dhkey[32] = { 0x2d, 0xab, 0x00, 0x48, 0xcb, 0xb3, 0x7b, 0xda,
+ 0x55, 0x7b, 0x8b, 0x72, 0xa8, 0x57, 0x87, 0xc3,
+ 0x87, 0x27, 0x99, 0x32, 0xfc, 0x79, 0x5f, 0xae,
+ 0x7c, 0x1c, 0xf9, 0x49, 0xe6, 0xd7, 0xaa, 0x70,
+ };
+ int fails;
+
+ memset(pub_a + 32, 0x42, 32);
+
+ fails = test_sample(priv_a, priv_a, pub_a, pub_a, dhkey);
+
+ g_assert(fails >= 1);
+
+ tester_test_passed();
+}
+
int main(int argc, char *argv[])
{
tester_init(&argc, &argv);
@@ -253,5 +290,7 @@ int main(int argc, char *argv[])
tester_add("/ecdh/sample/2", NULL, NULL, test_sample_2, NULL);
tester_add("/ecdh/sample/3", NULL, NULL, test_sample_3, NULL);
+ tester_add("/ecdh/invalid", NULL, NULL, test_invalid_pub, NULL);
+
return tester_run();
}