diff --git a/client/advertising.c b/client/advertising.c
index 56093f3..f51f713 100644
--- a/client/advertising.c
+++ b/client/advertising.c
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
-#include <readline/readline.h>
+#include <string.h>
#include <wordexp.h>
#include "gdbus/gdbus.h"
-#include "display.h"
+#include "src/shared/shell.h"
#include "advertising.h"
#define AD_PATH "/org/bluez/advertising"
static DBusMessage *release_advertising(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- rl_printf("Advertising released\n");
+ bt_shell_printf("Advertising released\n");
ad_release(conn);
if (dbus_set_error_from_message(&error, message) == FALSE) {
ad.registered = true;
- rl_printf("Advertising object registered\n");
+ bt_shell_printf("Advertising object registered\n");
} else {
- rl_printf("Failed to register advertisement: %s\n", error.name);
+ bt_shell_printf("Failed to register advertisement: %s\n", error.name);
dbus_error_free(&error);
if (g_dbus_unregister_interface(conn, AD_PATH,
AD_IFACE) == FALSE)
- rl_printf("Failed to unregister advertising object\n");
+ bt_shell_printf("Failed to unregister advertising object\n");
}
}
void ad_register(DBusConnection *conn, GDBusProxy *manager, const char *type)
{
if (ad.registered) {
- rl_printf("Advertisement is already registered\n");
+ bt_shell_printf("Advertisement is already registered\n");
return;
}
if (g_dbus_register_interface(conn, AD_PATH, AD_IFACE, ad_methods,
NULL, ad_props, NULL, NULL) == FALSE) {
- rl_printf("Failed to register advertising object\n");
+ bt_shell_printf("Failed to register advertising object\n");
return;
}
if (g_dbus_proxy_method_call(manager, "RegisterAdvertisement",
register_setup, register_reply,
conn, NULL) == FALSE) {
- rl_printf("Failed to register advertising\n");
+ bt_shell_printf("Failed to register advertising\n");
return;
}
}
if (dbus_set_error_from_message(&error, message) == FALSE) {
ad.registered = false;
- rl_printf("Advertising object unregistered\n");
+ bt_shell_printf("Advertising object unregistered\n");
if (g_dbus_unregister_interface(conn, AD_PATH,
AD_IFACE) == FALSE)
- rl_printf("Failed to unregister advertising object\n");
+ bt_shell_printf("Failed to unregister advertising object\n");
} else {
- rl_printf("Failed to unregister advertisement: %s\n",
+ bt_shell_printf("Failed to unregister advertisement: %s\n",
error.name);
dbus_error_free(&error);
}
if (g_dbus_proxy_method_call(manager, "UnregisterAdvertisement",
unregister_setup, unregister_reply,
conn, NULL) == FALSE) {
- rl_printf("Failed to unregister advertisement method\n");
+ bt_shell_printf("Failed to unregister advertisement method\n");
return;
}
}
ad.uuids = g_strsplit(arg, " ", -1);
if (!ad.uuids) {
- rl_printf("Failed to parse input\n");
+ bt_shell_printf("Failed to parse input\n");
return;
}
struct ad_data *data;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
char *endptr = NULL;
if (i >= G_N_ELEMENTS(data->data)) {
- rl_printf("Too much data\n");
+ bt_shell_printf("Too much data\n");
ad_clear_service();
goto done;
}
val = strtol(w.we_wordv[i], &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
- rl_printf("Invalid value at index %d\n", i);
+ bt_shell_printf("Invalid value at index %d\n", i);
ad_clear_service();
goto done;
}
struct ad_data *data;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
val = strtol(w.we_wordv[0], &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT16_MAX) {
- rl_printf("Invalid manufacture id\n");
+ bt_shell_printf("Invalid manufacture id\n");
goto done;
}
for (i = 1; i < w.we_wordc; i++) {
if (i >= G_N_ELEMENTS(data->data)) {
- rl_printf("Too much data\n");
+ bt_shell_printf("Too much data\n");
ad_clear_manufacturer();
goto done;
}
val = strtol(w.we_wordv[i], &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
- rl_printf("Invalid value at index %d\n", i);
+ bt_shell_printf("Invalid value at index %d\n", i);
ad_clear_manufacturer();
goto done;
}
diff --git a/client/agent.c b/client/agent.c
index dedd6ab..e8ca4dd 100644
--- a/client/agent.c
+++ b/client/agent.c
#include <stdio.h>
#include <stdlib.h>
-#include <readline/readline.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include "src/shared/shell.h"
#include "gdbus/gdbus.h"
-#include "display.h"
#include "agent.h"
#define AGENT_PATH "/org/bluez/agent"
if (!pending_message)
return;
- rl_release_prompt("");
+ bt_shell_release_prompt("");
}
dbus_bool_t agent_completion(void)
static DBusMessage *release_agent(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- rl_printf("Agent released\n");
+ bt_shell_printf("Agent released\n");
agent_release(conn);
{
const char *device;
- rl_printf("Request PIN code\n");
+ bt_shell_printf("Request PIN code\n");
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_INVALID);
- rl_prompt_input("agent", "Enter PIN code:", pincode_response, conn);
+ bt_shell_prompt_input("agent", "Enter PIN code:", pincode_response,
+ conn);
pending_message = dbus_message_ref(msg);
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_STRING, &pincode, DBUS_TYPE_INVALID);
- rl_printf(AGENT_PROMPT "PIN code: %s\n", pincode);
+ bt_shell_printf(AGENT_PROMPT "PIN code: %s\n", pincode);
return dbus_message_new_method_return(msg);
}
{
const char *device;
- rl_printf("Request passkey\n");
+ bt_shell_printf("Request passkey\n");
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_INVALID);
- rl_prompt_input("agent", "Enter passkey (number in 0-999999):",
- passkey_response, conn);
+ bt_shell_prompt_input("agent", "Enter passkey (number in 0-999999):",
+ passkey_response, conn);
pending_message = dbus_message_ref(msg);
if (entered > strlen(passkey_full))
entered = strlen(passkey_full);
- rl_printf(AGENT_PROMPT "Passkey: "
+ bt_shell_printf(AGENT_PROMPT "Passkey: "
COLOR_BOLDGRAY "%.*s" COLOR_BOLDWHITE "%s\n" COLOR_OFF,
entered, passkey_full, passkey_full + entered);
dbus_uint32_t passkey;
char *str;
- rl_printf("Request confirmation\n");
+ bt_shell_printf("Request confirmation\n");
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID);
str = g_strdup_printf("Confirm passkey %06u (yes/no):", passkey);
- rl_prompt_input("agent", str, confirm_response, conn);
+ bt_shell_prompt_input("agent", str, confirm_response, conn);
g_free(str);
pending_message = dbus_message_ref(msg);
{
const char *device;
- rl_printf("Request authorization\n");
+ bt_shell_printf("Request authorization\n");
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_INVALID);
- rl_prompt_input("agent", "Accept pairing (yes/no):", confirm_response,
- conn);
+ bt_shell_prompt_input("agent", "Accept pairing (yes/no):",
+ confirm_response, conn);
pending_message = dbus_message_ref(msg);
const char *device, *uuid;
char *str;
- rl_printf("Authorize service\n");
+ bt_shell_printf("Authorize service\n");
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device,
DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID);
str = g_strdup_printf("Authorize service %s (yes/no):", uuid);
- rl_prompt_input("agent", str, confirm_response, conn);
+ bt_shell_prompt_input("agent", str, confirm_response, conn);
g_free(str);
pending_message = dbus_message_ref(msg);
static DBusMessage *cancel_request(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
- rl_printf("Request canceled\n");
+ bt_shell_printf("Request canceled\n");
agent_release_prompt();
dbus_message_unref(pending_message);
if (dbus_set_error_from_message(&error, message) == FALSE) {
agent_registered = TRUE;
- rl_printf("Agent registered\n");
+ bt_shell_printf("Agent registered\n");
} else {
- rl_printf("Failed to register agent: %s\n", error.name);
+ bt_shell_printf("Failed to register agent: %s\n", error.name);
dbus_error_free(&error);
if (g_dbus_unregister_interface(conn, AGENT_PATH,
AGENT_INTERFACE) == FALSE)
- rl_printf("Failed to unregister agent object\n");
+ bt_shell_printf("Failed to unregister agent object\n");
}
}
{
if (agent_registered == TRUE) {
- rl_printf("Agent is already registered\n");
+ bt_shell_printf("Agent is already registered\n");
return;
}
if (g_dbus_register_interface(conn, AGENT_PATH,
AGENT_INTERFACE, methods,
NULL, NULL, NULL, NULL) == FALSE) {
- rl_printf("Failed to register agent object\n");
+ bt_shell_printf("Failed to register agent object\n");
return;
}
register_agent_setup,
register_agent_reply,
conn, NULL) == FALSE) {
- rl_printf("Failed to call register agent method\n");
+ bt_shell_printf("Failed to call register agent method\n");
return;
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == FALSE) {
- rl_printf("Agent unregistered\n");
+ bt_shell_printf("Agent unregistered\n");
agent_release(conn);
} else {
- rl_printf("Failed to unregister agent: %s\n", error.name);
+ bt_shell_printf("Failed to unregister agent: %s\n", error.name);
dbus_error_free(&error);
}
}
void agent_unregister(DBusConnection *conn, GDBusProxy *manager)
{
if (agent_registered == FALSE) {
- rl_printf("No agent is registered\n");
+ bt_shell_printf("No agent is registered\n");
return;
}
if (!manager) {
- rl_printf("Agent unregistered\n");
+ bt_shell_printf("Agent unregistered\n");
agent_release(conn);
return;
}
unregister_agent_setup,
unregister_agent_reply,
conn, NULL) == FALSE) {
- rl_printf("Failed to call unregister agent method\n");
+ bt_shell_printf("Failed to call unregister agent method\n");
return;
}
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to request default agent: %s\n", error.name);
+ bt_shell_printf("Failed to request default agent: %s\n",
+ error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Default agent request successful\n");
+ bt_shell_printf("Default agent request successful\n");
}
void agent_default(DBusConnection *conn, GDBusProxy *manager)
{
if (agent_registered == FALSE) {
- rl_printf("No agent is registered\n");
+ bt_shell_printf("No agent is registered\n");
return;
}
request_default_setup,
request_default_reply,
NULL, NULL) == FALSE) {
- rl_printf("Failed to call request default agent method\n");
+ bt_shell_printf("Failed to call RequestDefaultAgent method\n");
return;
}
}
diff --git a/client/gatt.c b/client/gatt.c
index 93aec92..ed0e71a 100644
--- a/client/gatt.c
+++ b/client/gatt.c
#include <sys/uio.h>
#include <wordexp.h>
#include <fcntl.h>
+#include <string.h>
-#include <readline/readline.h>
-#include <readline/history.h>
#include <glib.h>
#include "src/shared/queue.h"
#include "src/shared/io.h"
+#include "src/shared/shell.h"
#include "gdbus/gdbus.h"
#include "monitor/uuid.h"
-#include "display.h"
#include "gatt.h"
#define APP_PATH "/org/bluez/app"
text = uuidstr_to_str(service->uuid);
if (!text)
- rl_printf("%s%s%s%s Service\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%s%s Service\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
"Secondary",
service->path, service->uuid);
else
- rl_printf("%s%s%s%s Service\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%s%s Service\n\t%s\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
text = uuidstr_to_str(chrc->uuid);
if (!text)
- rl_printf("%s%s%sCharacteristic\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sCharacteristic\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
chrc->path, chrc->uuid);
else
- rl_printf("%s%s%sCharacteristic\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sCharacteristic\n\t%s\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
text = uuidstr_to_str(desc->uuid);
if (!text)
- rl_printf("%s%s%sDescriptor\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sDescriptor\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
desc->path, desc->uuid);
else
- rl_printf("%s%s%sDescriptor\n\t%s\n\t%s\n\t%s\n",
+ bt_shell_printf("%s%s%sDescriptor\n\t%s\n\t%s\n\t%s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to read: %s\n", error.name);
+ bt_shell_printf("Failed to read: %s\n", error.name);
dbus_error_free(&error);
return;
}
dbus_message_iter_init(message, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
- rl_printf("Invalid response to read\n");
+ bt_shell_printf("Invalid response to read\n");
return;
}
dbus_message_iter_get_fixed_array(&array, &value, &len);
if (len < 0) {
- rl_printf("Unable to parse value\n");
+ bt_shell_printf("Unable to parse value\n");
return;
}
- rl_hexdump(value, len);
+ bt_shell_hexdump(value, len);
}
static void read_setup(DBusMessageIter *iter, void *user_data)
{
if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup, read_reply,
NULL, NULL) == FALSE) {
- rl_printf("Failed to read\n");
+ bt_shell_printf("Failed to read\n");
return;
}
- rl_printf("Attempting to read %s\n", g_dbus_proxy_get_path(proxy));
+ bt_shell_printf("Attempting to read %s\n", g_dbus_proxy_get_path(proxy));
}
void gatt_read_attribute(GDBusProxy *proxy)
return;
}
- rl_printf("Unable to read attribute %s\n",
+ bt_shell_printf("Unable to read attribute %s\n",
g_dbus_proxy_get_path(proxy));
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to write: %s\n", error.name);
+ bt_shell_printf("Failed to write: %s\n", error.name);
dbus_error_free(&error);
return;
}
continue;
if (i >= G_N_ELEMENTS(value)) {
- rl_printf("Too much data\n");
+ bt_shell_printf("Too much data\n");
return;
}
val = strtol(entry, &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
- rl_printf("Invalid value at index %d\n", i);
+ bt_shell_printf("Invalid value at index %d\n", i);
return;
}
/* Write using the fd if it has been acquired and fit the MTU */
if (proxy == write_io.proxy && (write_io.io && write_io.mtu >= i)) {
- rl_printf("Attempting to write fd %d\n",
+ bt_shell_printf("Attempting to write fd %d\n",
io_get_fd(write_io.io));
if (io_send(write_io.io, &iov, 1) < 0) {
- rl_printf("Failed to write: %s", strerror(errno));
+ bt_shell_printf("Failed to write: %s", strerror(errno));
return;
}
return;
if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup,
write_reply, &iov, NULL) == FALSE) {
- rl_printf("Failed to write\n");
+ bt_shell_printf("Failed to write\n");
return;
}
- rl_printf("Attempting to write %s\n", g_dbus_proxy_get_path(proxy));
+ bt_shell_printf("Attempting to write %s\n", g_dbus_proxy_get_path(proxy));
}
void gatt_write_attribute(GDBusProxy *proxy, const char *arg)
return;
}
- rl_printf("Unable to write attribute %s\n",
+ bt_shell_printf("Unable to write attribute %s\n",
g_dbus_proxy_get_path(proxy));
}
return false;
if (chrc)
- rl_printf("[" COLORED_CHG "] Attribute %s written:\n",
+ bt_shell_printf("[" COLORED_CHG "] Attribute %s written:\n",
chrc->path);
else
- rl_printf("[" COLORED_CHG "] %s Notification:\n",
+ bt_shell_printf("[" COLORED_CHG "] %s Notification:\n",
g_dbus_proxy_get_path(notify_io.proxy));
- rl_hexdump(buf, bytes_read);
+ bt_shell_hexdump(buf, bytes_read);
return true;
}
struct chrc *chrc = user_data;
if (chrc) {
- rl_printf("Attribute %s Write pipe closed\n", chrc->path);
+ bt_shell_printf("Attribute %s Write pipe closed\n", chrc->path);
if (chrc->write_io) {
io_destroy(chrc->write_io);
chrc->write_io = NULL;
return false;
}
- rl_printf("%s closed\n", io == notify_io.io ? "Notify" : "Write");
+ bt_shell_printf("%s closed\n", io == notify_io.io ? "Notify" : "Write");
if (io == notify_io.io)
notify_io_destroy();
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to acquire write: %s\n", error.name);
+ bt_shell_printf("Failed to acquire write: %s\n", error.name);
dbus_error_free(&error);
write_io.proxy = NULL;
return;
if ((dbus_message_get_args(message, NULL, DBUS_TYPE_UNIX_FD, &fd,
DBUS_TYPE_UINT16, &write_io.mtu,
DBUS_TYPE_INVALID) == false)) {
- rl_printf("Invalid AcquireWrite response\n");
+ bt_shell_printf("Invalid AcquireWrite response\n");
return;
}
- rl_printf("AcquireWrite success: fd %d MTU %u\n", fd, write_io.mtu);
+ bt_shell_printf("AcquireWrite success: fd %d MTU %u\n", fd, write_io.mtu);
write_io.io = pipe_io_new(fd, NULL);
}
iface = g_dbus_proxy_get_interface(proxy);
if (strcmp(iface, "org.bluez.GattCharacteristic1")) {
- rl_printf("Unable to acquire write: %s not a characteristic\n",
+ bt_shell_printf("Unable to acquire write: %s not a characteristic\n",
g_dbus_proxy_get_path(proxy));
return;
}
if (g_dbus_proxy_method_call(proxy, "AcquireWrite", acquire_setup,
acquire_write_reply, NULL, NULL) == FALSE) {
- rl_printf("Failed to AcquireWrite\n");
+ bt_shell_printf("Failed to AcquireWrite\n");
return;
}
void gatt_release_write(GDBusProxy *proxy, const char *arg)
{
if (proxy != write_io.proxy || !write_io.io) {
- rl_printf("Write not acquired\n");
+ bt_shell_printf("Write not acquired\n");
return;
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to acquire notify: %s\n", error.name);
+ bt_shell_printf("Failed to acquire notify: %s\n", error.name);
dbus_error_free(&error);
write_io.proxy = NULL;
return;
if ((dbus_message_get_args(message, NULL, DBUS_TYPE_UNIX_FD, &fd,
DBUS_TYPE_UINT16, ¬ify_io.mtu,
DBUS_TYPE_INVALID) == false)) {
- rl_printf("Invalid AcquireNotify response\n");
+ bt_shell_printf("Invalid AcquireNotify response\n");
return;
}
- rl_printf("AcquireNotify success: fd %d MTU %u\n", fd, notify_io.mtu);
+ bt_shell_printf("AcquireNotify success: fd %d MTU %u\n", fd, notify_io.mtu);
notify_io.io = pipe_io_new(fd, NULL);
}
iface = g_dbus_proxy_get_interface(proxy);
if (strcmp(iface, "org.bluez.GattCharacteristic1")) {
- rl_printf("Unable to acquire notify: %s not a characteristic\n",
+ bt_shell_printf("Unable to acquire notify: %s not a characteristic\n",
g_dbus_proxy_get_path(proxy));
return;
}
if (g_dbus_proxy_method_call(proxy, "AcquireNotify", acquire_setup,
acquire_notify_reply, NULL, NULL) == FALSE) {
- rl_printf("Failed to AcquireNotify\n");
+ bt_shell_printf("Failed to AcquireNotify\n");
return;
}
void gatt_release_notify(GDBusProxy *proxy, const char *arg)
{
if (proxy != notify_io.proxy || !notify_io.io) {
- rl_printf("Notify not acquired\n");
+ bt_shell_printf("Notify not acquired\n");
return;
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to %s notify: %s\n",
+ bt_shell_printf("Failed to %s notify: %s\n",
enable ? "start" : "stop", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Notify %s\n", enable == TRUE ? "started" : "stopped");
+ bt_shell_printf("Notify %s\n", enable == TRUE ? "started" : "stopped");
}
static void notify_attribute(GDBusProxy *proxy, bool enable)
if (g_dbus_proxy_method_call(proxy, method, NULL, notify_reply,
GUINT_TO_POINTER(enable), NULL) == FALSE) {
- rl_printf("Failed to %s notify\n", enable ? "start" : "stop");
+ bt_shell_printf("Failed to %s notify\n", enable ? "start" : "stop");
return;
}
}
return;
}
- rl_printf("Unable to notify attribute %s\n",
+ bt_shell_printf("Unable to notify attribute %s\n",
g_dbus_proxy_get_path(proxy));
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to register application: %s\n", error.name);
+ bt_shell_printf("Failed to register application: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Application registered\n");
+ bt_shell_printf("Application registered\n");
}
void gatt_add_manager(GDBusProxy *proxy)
l = g_list_find_custom(managers, proxy, match_proxy);
if (!l) {
- rl_printf("Unable to find GattManager proxy\n");
+ bt_shell_printf("Unable to find GattManager proxy\n");
return;
}
PROFILE_INTERFACE, methods,
NULL, properties, NULL,
NULL) == FALSE) {
- rl_printf("Failed to register application object\n");
+ bt_shell_printf("Failed to register application object\n");
return;
}
}
register_app_setup,
register_app_reply, w,
NULL) == FALSE) {
- rl_printf("Failed register application\n");
+ bt_shell_printf("Failed register application\n");
g_dbus_unregister_interface(conn, APP_PATH, PROFILE_INTERFACE);
return;
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to unregister application: %s\n", error.name);
+ bt_shell_printf("Failed to unregister application: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Application unregistered\n");
+ bt_shell_printf("Application unregistered\n");
if (!uuids)
return;
l = g_list_find_custom(managers, proxy, match_proxy);
if (!l) {
- rl_printf("Unable to find GattManager proxy\n");
+ bt_shell_printf("Unable to find GattManager proxy\n");
return;
}
unregister_app_setup,
unregister_app_reply, conn,
NULL) == FALSE) {
- rl_printf("Failed unregister profile\n");
+ bt_shell_printf("Failed unregister profile\n");
return;
}
}
else if (!strcmp(input, "no")) {
service->primary = false;
} else {
- rl_printf("Invalid option: %s\n", input);
+ bt_shell_printf("Invalid option: %s\n", input);
local_services = g_list_remove(local_services, service);
print_service(service, COLORED_DEL);
g_dbus_unregister_interface(service->conn, service->path,
SERVICE_INTERFACE, NULL, NULL,
service_properties, service,
service_free) == FALSE) {
- rl_printf("Failed to register service object\n");
+ bt_shell_printf("Failed to register service object\n");
service_free(service);
return;
}
local_services = g_list_append(local_services, service);
- rl_prompt_input(service->path, "Primary (yes/no):", service_set_primary,
+ bt_shell_prompt_input(service->path, "Primary (yes/no):", service_set_primary,
service);
}
service = service_find(w->we_wordv[0]);
if (!service) {
- rl_printf("Failed to unregister service object\n");
+ bt_shell_printf("Failed to unregister service object\n");
return;
}
"org.bluez.Error.InvalidArguments",
NULL);
- rl_printf("[" COLORED_CHG "] Attribute %s written" , chrc->path);
+ bt_shell_printf("[" COLORED_CHG "] Attribute %s written" , chrc->path);
g_dbus_emit_property_changed(conn, chrc->path, CHRC_INTERFACE, "Value");
else
chrc->notify_io = io;
- rl_printf("[" COLORED_CHG "] Attribute %s %s pipe acquired\n",
+ bt_shell_printf("[" COLORED_CHG "] Attribute %s %s pipe acquired\n",
chrc->path, dir ? "Write" : "Notify");
return reply;
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
chrc->notifying = true;
- rl_printf("[" COLORED_CHG "] Attribute %s notifications enabled",
+ bt_shell_printf("[" COLORED_CHG "] Attribute %s notifications enabled",
chrc->path);
g_dbus_emit_property_changed(conn, chrc->path, CHRC_INTERFACE,
"Notifying");
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
chrc->notifying = false;
- rl_printf("[" COLORED_CHG "] Attribute %s notifications disabled",
+ bt_shell_printf("[" COLORED_CHG "] Attribute %s notifications disabled",
chrc->path);
g_dbus_emit_property_changed(conn, chrc->path, CHRC_INTERFACE,
"Notifying");
{
struct chrc *chrc = user_data;
- rl_printf("Attribute %s indication confirm received", chrc->path);
+ bt_shell_printf("Attribute %s indication confirm received", chrc->path);
return dbus_message_new_method_return(msg);
}
continue;
if (i >= G_N_ELEMENTS(value)) {
- rl_printf("Too much data\n");
+ bt_shell_printf("Too much data\n");
return NULL;
}
val = strtol(entry, &endptr, 0);
if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
- rl_printf("Invalid value at index %d\n", i);
+ bt_shell_printf("Invalid value at index %d\n", i);
return NULL;
}
struct chrc *chrc;
if (!local_services) {
- rl_printf("No service registered\n");
+ bt_shell_printf("No service registered\n");
return;
}
if (g_dbus_register_interface(conn, chrc->path, CHRC_INTERFACE,
chrc_methods, NULL, chrc_properties,
chrc, chrc_free) == FALSE) {
- rl_printf("Failed to register characteristic object\n");
+ bt_shell_printf("Failed to register characteristic object\n");
chrc_free(chrc);
return;
}
print_chrc(chrc, COLORED_NEW);
- rl_prompt_input(chrc->path, "Enter value:", chrc_set_value, chrc);
+ bt_shell_prompt_input(chrc->path, "Enter value:", chrc_set_value, chrc);
}
static struct chrc *chrc_find(const char *pattern)
chrc = chrc_find(w->we_wordv[0]);
if (!chrc) {
- rl_printf("Failed to unregister characteristic object\n");
+ bt_shell_printf("Failed to unregister characteristic object\n");
return;
}
"org.bluez.Error.InvalidArguments",
NULL);
- rl_printf("[" COLORED_CHG "] Attribute %s written" , desc->path);
+ bt_shell_printf("[" COLORED_CHG "] Attribute %s written" , desc->path);
g_dbus_emit_property_changed(conn, desc->path, CHRC_INTERFACE, "Value");
struct desc *desc;
if (!local_services) {
- rl_printf("No service registered\n");
+ bt_shell_printf("No service registered\n");
return;
}
service = g_list_last(local_services)->data;
if (!service->chrcs) {
- rl_printf("No characteristic registered\n");
+ bt_shell_printf("No characteristic registered\n");
return;
}
if (g_dbus_register_interface(conn, desc->path, DESC_INTERFACE,
desc_methods, NULL, desc_properties,
desc, desc_free) == FALSE) {
- rl_printf("Failed to register descriptor object\n");
+ bt_shell_printf("Failed to register descriptor object\n");
desc_free(desc);
return;
}
print_desc(desc, COLORED_NEW);
- rl_prompt_input(desc->path, "Enter value:", desc_set_value, desc);
+ bt_shell_prompt_input(desc->path, "Enter value:", desc_set_value, desc);
}
static struct desc *desc_find(const char *pattern)
desc = desc_find(w->we_wordv[0]);
if (!desc) {
- rl_printf("Failed to unregister descriptor object\n");
+ bt_shell_printf("Failed to unregister descriptor object\n");
return;
}
diff --git a/client/main.c b/client/main.c
index 37a411b..034c500 100644
--- a/client/main.c
+++ b/client/main.c
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
-#include <signal.h>
-#include <sys/signalfd.h>
#include <wordexp.h>
-#include <readline/readline.h>
-#include <readline/history.h>
#include <glib.h>
+#include "src/shared/shell.h"
#include "src/shared/util.h"
#include "gdbus/gdbus.h"
#include "monitor/uuid.h"
#include "agent.h"
-#include "display.h"
#include "gatt.h"
#include "advertising.h"
#define PROMPT_ON COLOR_BLUE "[bluetooth]" COLOR_OFF "# "
#define PROMPT_OFF "Waiting to connect to bluetoothd..."
-static GMainLoop *main_loop;
static DBusConnection *dbus_conn;
static GDBusProxy *agent_manager;
static GDBusProxy *default_attr;
static GList *ctrl_list;
-static guint input = 0;
-
static const char *mode_arguments[] = {
"on",
"off",
printf("Leaking proxy %p\n", data);
}
-static gboolean input_handler(GIOChannel *channel, GIOCondition condition,
- gpointer user_data)
-{
- if (condition & G_IO_IN) {
- rl_callback_read_char();
- return TRUE;
- }
-
- if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
- g_main_loop_quit(main_loop);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static guint setup_standard_input(void)
+static void setup_standard_input(void)
{
- GIOChannel *channel;
- guint source;
-
- channel = g_io_channel_unix_new(fileno(stdin));
-
- source = g_io_add_watch(channel,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- input_handler, NULL);
-
- g_io_channel_unref(channel);
-
- return source;
+ bt_shell_attach(fileno(stdin));
}
static void connect_handler(DBusConnection *connection, void *user_data)
{
- rl_set_prompt(PROMPT_ON);
- printf("\r");
- rl_on_new_line();
- rl_redisplay();
+ bt_shell_set_prompt(PROMPT_ON);
}
static void disconnect_handler(DBusConnection *connection, void *user_data)
{
- if (input > 0) {
- g_source_remove(input);
- input = 0;
- }
+ bt_shell_detach();
- rl_set_prompt(PROMPT_OFF);
- printf("\r");
- rl_on_new_line();
- rl_redisplay();
+ bt_shell_set_prompt(PROMPT_OFF);
g_list_free_full(ctrl_list, proxy_leak);
ctrl_list = NULL;
else
name = "<unknown>";
- rl_printf("%s%s%sController %s %s %s\n",
+ bt_shell_printf("%s%s%sController %s %s %s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
else
name = "<unknown>";
- rl_printf("%s%s%sDevice %s %s\n",
+ bt_shell_printf("%s%s%sDevice %s %s\n",
description ? "[" : "",
description ? : "",
description ? "] " : "",
if (len <= 0)
return;
- rl_printf("%s%s:\n", label, name);
- rl_hexdump((void *)valbool, len * sizeof(*valbool));
+ bt_shell_printf("%s%s:\n", label, name);
+ bt_shell_printf((void *)valbool, len * sizeof(*valbool));
break;
case DBUS_TYPE_UINT32:
if (len <= 0)
return;
- rl_printf("%s%s:\n", label, name);
- rl_hexdump((void *)valu32, len * sizeof(*valu32));
+ bt_shell_printf("%s%s:\n", label, name);
+ bt_shell_printf((void *)valu32, len * sizeof(*valu32));
break;
case DBUS_TYPE_UINT16:
if (len <= 0)
return;
- rl_printf("%s%s:\n", label, name);
- rl_hexdump((void *)valu16, len * sizeof(*valu16));
+ bt_shell_printf("%s%s:\n", label, name);
+ bt_shell_printf((void *)valu16, len * sizeof(*valu16));
break;
case DBUS_TYPE_INT16:
if (len <= 0)
return;
- rl_printf("%s%s:\n", label, name);
- rl_hexdump((void *)vals16, len * sizeof(*vals16));
+ bt_shell_printf("%s%s:\n", label, name);
+ bt_shell_printf((void *)vals16, len * sizeof(*vals16));
break;
case DBUS_TYPE_BYTE:
if (len <= 0)
return;
- rl_printf("%s%s:\n", label, name);
- rl_hexdump((void *)byte, len * sizeof(*byte));
+ bt_shell_printf("%s%s:\n", label, name);
+ bt_shell_printf((void *)byte, len * sizeof(*byte));
break;
default:
char *entry;
if (iter == NULL) {
- rl_printf("%s%s is nil\n", label, name);
+ bt_shell_printf("%s%s is nil\n", label, name);
return;
}
switch (dbus_message_iter_get_arg_type(iter)) {
case DBUS_TYPE_INVALID:
- rl_printf("%s%s is invalid\n", label, name);
+ bt_shell_printf("%s%s is invalid\n", label, name);
break;
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
dbus_message_iter_get_basic(iter, &valstr);
- rl_printf("%s%s: %s\n", label, name, valstr);
+ bt_shell_printf("%s%s: %s\n", label, name, valstr);
break;
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic(iter, &valbool);
- rl_printf("%s%s: %s\n", label, name,
+ bt_shell_printf("%s%s: %s\n", label, name,
valbool == TRUE ? "yes" : "no");
break;
case DBUS_TYPE_UINT32:
dbus_message_iter_get_basic(iter, &valu32);
- rl_printf("%s%s: 0x%08x\n", label, name, valu32);
+ bt_shell_printf("%s%s: 0x%08x\n", label, name, valu32);
break;
case DBUS_TYPE_UINT16:
dbus_message_iter_get_basic(iter, &valu16);
- rl_printf("%s%s: 0x%04x\n", label, name, valu16);
+ bt_shell_printf("%s%s: 0x%04x\n", label, name, valu16);
break;
case DBUS_TYPE_INT16:
dbus_message_iter_get_basic(iter, &vals16);
- rl_printf("%s%s: %d\n", label, name, vals16);
+ bt_shell_printf("%s%s: %d\n", label, name, vals16);
break;
case DBUS_TYPE_BYTE:
dbus_message_iter_get_basic(iter, &byte);
- rl_printf("%s%s: 0x%02x\n", label, name, byte);
+ bt_shell_printf("%s%s: 0x%02x\n", label, name, byte);
break;
case DBUS_TYPE_VARIANT:
dbus_message_iter_recurse(iter, &subiter);
g_free(entry);
break;
default:
- rl_printf("%s%s has unsupported type\n", label, name);
+ bt_shell_printf("%s%s has unsupported type\n", label, name);
break;
}
}
n = sizeof(str) - 1;
}
- rl_printf("\tUUID: %s%*c(%s)\n",
+ bt_shell_printf("\tUUID: %s%*c(%s)\n",
str, 26 - n, ' ', uuid);
} else
- rl_printf("\tUUID: %*c(%s)\n", 26, ' ', uuid);
+ bt_shell_printf("\tUUID: %*c(%s)\n", 26, ' ', uuid);
dbus_message_iter_next(&value);
}
attribute ? attribute + strlen(path) : "");
done:
- rl_set_prompt(desc ? desc : PROMPT_ON);
- printf("\r");
- rl_on_new_line();
+ bt_shell_set_prompt(desc ? desc : PROMPT_ON);
g_free(desc);
}
static void message_handler(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- rl_printf("[SIGNAL] %s.%s\n", dbus_message_get_interface(message),
+ bt_shell_printf("[SIGNAL] %s.%s\n", dbus_message_get_interface(message),
dbus_message_get_member(message));
}
static gboolean check_default_ctrl(void)
{
if (!default_ctrl) {
- rl_printf("No default controller available\n");
+ bt_shell_printf("No default controller available\n");
return FALSE;
}
if (!arg || !strlen(arg)) {
if (msg)
- rl_printf("Missing on/off/%s argument\n", msg);
+ bt_shell_printf("Missing on/off/%s argument\n", msg);
else
- rl_printf("Missing on/off argument\n");
+ bt_shell_printf("Missing on/off argument\n");
return FALSE;
}
}
}
- rl_printf("Invalid argument %s\n", arg);
+ bt_shell_printf("Invalid argument %s\n", arg);
return FALSE;
}
} else {
adapter = find_ctrl_by_address(ctrl_list, arg);
if (!adapter) {
- rl_printf("Controller %s not available\n", arg);
+ bt_shell_printf("Controller %s not available\n", arg);
return;
}
proxy = adapter->proxy;
return;
dbus_message_iter_get_basic(&iter, &address);
- rl_printf("Controller %s\n", address);
+ bt_shell_printf("Controller %s\n", address);
print_property(proxy, "Name");
print_property(proxy, "Alias");
struct adapter *adapter;
if (!arg || !strlen(arg)) {
- rl_printf("Missing controller address argument\n");
+ bt_shell_printf("Missing controller address argument\n");
return;
}
adapter = find_ctrl_by_address(ctrl_list, arg);
if (!adapter) {
- rl_printf("Controller %s not available\n", arg);
+ bt_shell_printf("Controller %s not available\n", arg);
return;
}
char *str = user_data;
if (dbus_error_is_set(error))
- rl_printf("Failed to set %s: %s\n", str, error->name);
+ bt_shell_printf("Failed to set %s: %s\n", str, error->name);
else
- rl_printf("Changing %s succeeded\n", str);
+ bt_shell_printf("Changing %s succeeded\n", str);
}
static void cmd_system_alias(const char *arg)
char *name;
if (!arg || !strlen(arg)) {
- rl_printf("Missing name argument\n");
+ bt_shell_printf("Missing name argument\n");
return;
}
agent_register(dbus_conn, agent_manager,
auto_register_agent);
else
- rl_printf("Agent registration enabled\n");
+ bt_shell_printf("Agent registration enabled\n");
} else {
g_free(auto_register_agent);
auto_register_agent = NULL;
if (agent_manager)
agent_unregister(dbus_conn, agent_manager);
else
- rl_printf("Agent registration disabled\n");
+ bt_shell_printf("Agent registration disabled\n");
}
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to %s discovery: %s\n",
+ bt_shell_printf("Failed to %s discovery: %s\n",
enable == TRUE ? "start" : "stop", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Discovery %s\n", enable == TRUE ? "started" : "stopped");
+ bt_shell_printf("Discovery %s\n", enable == TRUE ? "started" : "stopped");
}
static void cmd_scan(const char *arg)
if (g_dbus_proxy_method_call(default_ctrl->proxy, method,
NULL, start_discovery_reply,
GUINT_TO_POINTER(enable), NULL) == FALSE) {
- rl_printf("Failed to %s discovery\n",
+ bt_shell_printf("Failed to %s discovery\n",
enable == TRUE ? "start" : "stop");
return;
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("SetDiscoveryFilter failed: %s\n", error.name);
+ bt_shell_printf("SetDiscoveryFilter failed: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("SetDiscoveryFilter success\n");
+ bt_shell_printf("SetDiscoveryFilter success\n");
}
static gint filtered_scan_rssi = DISTANCE_VAL_INVALID;
if (g_dbus_proxy_method_call(default_ctrl->proxy, "SetDiscoveryFilter",
set_discovery_filter_setup, set_discovery_filter_reply,
&args, NULL) == FALSE) {
- rl_printf("Failed to set discovery filter\n");
+ bt_shell_printf("Failed to set discovery filter\n");
return;
}
}
filtered_scan_uuids = g_strsplit(arg, " ", -1);
if (!filtered_scan_uuids) {
- rl_printf("Failed to parse input\n");
+ bt_shell_printf("Failed to parse input\n");
return;
}
else if (!strcmp(arg, "off"))
filtered_scan_duplicate_data = false;
else {
- rl_printf("Invalid option: %s\n", arg);
+ bt_shell_printf("Invalid option: %s\n", arg);
return;
}
if (g_dbus_proxy_method_call(default_ctrl->proxy, "SetDiscoveryFilter",
clear_discovery_filter_setup, set_discovery_filter_reply,
NULL, NULL) == FALSE) {
- rl_printf("Failed to clear discovery filter\n");
+ bt_shell_printf("Failed to clear discovery filter\n");
}
}
if (!arg || !strlen(arg)) {
if (default_dev)
return default_dev;
- rl_printf("Missing device address argument\n");
+ bt_shell_printf("Missing device address argument\n");
return NULL;
}
proxy = find_proxy_by_address(default_ctrl->devices, arg);
if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ bt_shell_printf("Device %s not available\n", arg);
return NULL;
}
return;
dbus_message_iter_get_basic(&iter, &address);
- rl_printf("Device %s\n", address);
+ bt_shell_printf("Device %s\n", address);
print_property(proxy, "Name");
print_property(proxy, "Alias");
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to pair: %s\n", error.name);
+ bt_shell_printf("Failed to pair: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Pairing successful\n");
+ bt_shell_printf("Pairing successful\n");
}
static void cmd_pair(const char *arg)
if (g_dbus_proxy_method_call(proxy, "Pair", NULL, pair_reply,
NULL, NULL) == FALSE) {
- rl_printf("Failed to pair\n");
+ bt_shell_printf("Failed to pair\n");
return;
}
- rl_printf("Attempting to pair with %s\n", arg);
+ bt_shell_printf("Attempting to pair with %s\n", arg);
}
static void cmd_trust(const char *arg)
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to remove device: %s\n", error.name);
+ bt_shell_printf("Failed to remove device: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Device has been removed\n");
+ bt_shell_printf("Device has been removed\n");
}
static void remove_device_setup(DBusMessageIter *iter, void *user_data)
remove_device_setup,
remove_device_reply,
path, g_free) == FALSE) {
- rl_printf("Failed to remove device\n");
+ bt_shell_printf("Failed to remove device\n");
g_free(path);
}
}
GDBusProxy *proxy;
if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
+ bt_shell_printf("Missing device address argument\n");
return;
}
proxy = find_proxy_by_address(default_ctrl->devices, arg);
if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ bt_shell_printf("Device %s not available\n", arg);
return;
}
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to connect: %s\n", error.name);
+ bt_shell_printf("Failed to connect: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Connection successful\n");
+ bt_shell_printf("Connection successful\n");
set_default_device(proxy, NULL);
}
GDBusProxy *proxy;
if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
+ bt_shell_printf("Missing device address argument\n");
return;
}
proxy = find_proxy_by_address(default_ctrl->devices, arg);
if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ bt_shell_printf("Device %s not available\n", arg);
return;
}
if (g_dbus_proxy_method_call(proxy, "Connect", NULL, connect_reply,
proxy, NULL) == FALSE) {
- rl_printf("Failed to connect\n");
+ bt_shell_printf("Failed to connect\n");
return;
}
- rl_printf("Attempting to connect to %s\n", arg);
+ bt_shell_printf("Attempting to connect to %s\n", arg);
}
static void disconn_reply(DBusMessage *message, void *user_data)
dbus_error_init(&error);
if (dbus_set_error_from_message(&error, message) == TRUE) {
- rl_printf("Failed to disconnect: %s\n", error.name);
+ bt_shell_printf("Failed to disconnect: %s\n", error.name);
dbus_error_free(&error);
return;
}
- rl_printf("Successful disconnected\n");
+ bt_shell_printf("Successful disconnected\n");
if (proxy != default_dev)
return;
if (g_dbus_proxy_method_call(proxy, "Disconnect", NULL, disconn_reply,
proxy, NULL) == FALSE) {
- rl_printf("Failed to disconnect\n");
+ bt_shell_printf("Failed to disconnect\n");
return;
}
if (strlen(arg) == 0) {
if (g_dbus_proxy_get_property(proxy, "Address", &iter) == TRUE)
dbus_message_iter_get_basic(&iter, &arg);
}
- rl_printf("Attempting to disconnect from %s\n", arg);
+ bt_shell_printf("Attempting to disconnect from %s\n", arg);
}
static void cmd_list_attributes(const char *arg)
char *name;
if (!arg || !strlen(arg)) {
- rl_printf("Missing name argument\n");
+ bt_shell_printf("Missing name argument\n");
return;
}
if (!default_dev) {
- rl_printf("No device connected\n");
+ bt_shell_printf("No device connected\n");
return;
}
GDBusProxy *proxy;
if (!arg || !strlen(arg)) {
- rl_printf("Missing attribute argument\n");
+ bt_shell_printf("Missing attribute argument\n");
return;
}
if (!default_dev) {
- rl_printf("No device connected\n");
+ bt_shell_printf("No device connected\n");
return;
}
if (!arg || !strlen(arg)) {
if (default_attr)
return default_attr;
- rl_printf("Missing attribute argument\n");
+ bt_shell_printf("Missing attribute argument\n");
return NULL;
}
proxy = gatt_select_attribute(default_attr, arg);
if (!proxy) {
- rl_printf("Attribute %s not available\n", arg);
+ bt_shell_printf("Attribute %s not available\n", arg);
return NULL;
}
iface = g_dbus_proxy_get_interface(proxy);
if (!strcmp(iface, "org.bluez.GattService1")) {
- rl_printf("Service - %s\n", text);
+ bt_shell_printf("Service - %s\n", text);
print_property(proxy, "UUID");
print_property(proxy, "Primary");
print_property(proxy, "Characteristics");
print_property(proxy, "Includes");
} else if (!strcmp(iface, "org.bluez.GattCharacteristic1")) {
- rl_printf("Characteristic - %s\n", text);
+ bt_shell_printf("Characteristic - %s\n", text);
print_property(proxy, "UUID");
print_property(proxy, "Service");
print_property(proxy, "Flags");
print_property(proxy, "Descriptors");
} else if (!strcmp(iface, "org.bluez.GattDescriptor1")) {
- rl_printf("Descriptor - %s\n", text);
+ bt_shell_printf("Descriptor - %s\n", text);
print_property(proxy, "UUID");
print_property(proxy, "Characteristic");
static void cmd_read(const char *arg)
{
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
static void cmd_write(const char *arg)
{
if (!arg || !strlen(arg)) {
- rl_printf("Missing data argument\n");
+ bt_shell_printf("Missing data argument\n");
return;
}
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
static void cmd_acquire_write(const char *arg)
{
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
static void cmd_release_write(const char *arg)
{
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
static void cmd_acquire_notify(const char *arg)
{
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
static void cmd_release_notify(const char *arg)
{
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
return;
if (!default_attr) {
- rl_printf("No attribute selected\n");
+ bt_shell_printf("No attribute selected\n");
return;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
if (w.we_wordc == 0) {
- rl_printf("Missing argument\n");
+ bt_shell_printf("Missing argument\n");
goto done;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
if (w.we_wordc == 0) {
- rl_printf("Missing argument\n");
+ bt_shell_printf("Missing argument\n");
goto done;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
if (w.we_wordc < 2) {
- rl_printf("Missing arguments\n");
+ bt_shell_printf("Missing arguments\n");
goto done;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
if (w.we_wordc < 1) {
- rl_printf("Missing arguments\n");
+ bt_shell_printf("Missing arguments\n");
goto done;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
if (w.we_wordc < 2) {
- rl_printf("Missing arguments\n");
+ bt_shell_printf("Missing arguments\n");
goto done;
}
return;
if (wordexp(arg, &w, WRDE_NOCMD)) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
if (w.we_wordc < 1) {
- rl_printf("Missing arguments\n");
+ bt_shell_printf("Missing arguments\n");
goto done;
}
wordfree(&w);
}
-static void cmd_version(const char *arg)
-{
- rl_printf("Version %s\n", VERSION);
-}
-
-static void cmd_quit(const char *arg)
-{
- g_main_loop_quit(main_loop);
-}
-
-static void cmd_help(const char *arg);
-
static char *generic_generator(const char *text, int state,
GList *source, const char *property)
{
return;
if (!default_ctrl || !default_ctrl->ad_proxy) {
- rl_printf("LEAdvertisingManager not found\n");
+ bt_shell_printf("LEAdvertisingManager not found\n");
return;
}
static void cmd_set_advertise_name(const char *arg)
{
if (arg == NULL || strlen(arg) == 0) {
- rl_printf("Missing on/off argument\n");
+ bt_shell_printf("Missing on/off argument\n");
return;
}
char *endptr = NULL;
if (arg == NULL || strlen(arg) == 0) {
- rl_printf("Missing value argument\n");
+ bt_shell_printf("Missing value argument\n");
return;
}
value = strtol(arg, &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
char *endptr = NULL;
if (arg == NULL || strlen(arg) == 0) {
- rl_printf("Missing value argument\n");
+ bt_shell_printf("Missing value argument\n");
return;
}
value = strtol(arg, &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
char *endptr = NULL;
if (arg == NULL || strlen(arg) == 0) {
- rl_printf("Missing value argument\n");
+ bt_shell_printf("Missing value argument\n");
return;
}
value = strtol(arg, &endptr, 0);
if (!endptr || *endptr != '\0' || value > UINT16_MAX) {
- rl_printf("Invalid argument\n");
+ bt_shell_printf("Invalid argument\n");
return;
}
ad_advertise_timeout(dbus_conn, value);
}
-static const struct {
- const char *cmd;
- const char *arg;
- void (*func) (const char *arg);
- const char *desc;
- char * (*gen) (const char *text, int state);
- void (*disp) (char **matches, int num_matches, int max_length);
-} cmd_table[] = {
+static const struct bt_shell_menu_entry cmd_table[] = {
{ "list", NULL, cmd_list, "List available controllers" },
{ "show", "[ctrl]", cmd_show, "Controller information",
ctrl_generator },
{ "unregister-descriptor", "<UUID/object>",
cmd_unregister_descriptor,
"Unregister application descriptor" },
- { "version", NULL, cmd_version, "Display version" },
- { "quit", NULL, cmd_quit, "Quit program" },
- { "exit", NULL, cmd_quit, "Quit program" },
- { "help", NULL, cmd_help,
- "Display help about this program" },
{ }
};
-static char *cmd_generator(const char *text, int state)
-{
- static int index, len;
- const char *cmd;
-
- if (!state) {
- index = 0;
- len = strlen(text);
- }
-
- while ((cmd = cmd_table[index].cmd)) {
- index++;
-
- 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 (agent_completion() == TRUE) {
- rl_attempted_completion_over = 1;
- return NULL;
- }
-
- if (start > 0) {
- int i;
- char *input_cmd;
-
- input_cmd = g_strndup(rl_line_buffer, start -1);
- for (i = 0; cmd_table[i].cmd; i++) {
- if (strcmp(cmd_table[i].cmd, input_cmd))
- continue;
-
- if (!cmd_table[i].gen)
- continue;
-
- rl_completion_display_matches_hook = cmd_table[i].disp;
- matches = rl_completion_matches(text, cmd_table[i].gen);
- break;
- }
- g_free(input_cmd);
- } else {
- rl_completion_display_matches_hook = NULL;
- matches = rl_completion_matches(text, cmd_generator);
- }
-
- if (!matches)
- rl_attempted_completion_over = 1;
-
- return matches;
-}
-
-static void rl_handler(char *input)
-{
- char *cmd, *arg;
- int i;
-
- if (!input) {
- rl_insert_text("quit");
- rl_redisplay();
- rl_crlf();
- g_main_loop_quit(main_loop);
- return;
- }
-
- if (!strlen(input))
- goto done;
-
- if (!rl_release_prompt(input))
- goto done;
-
- if (history_search(input, -1))
- add_history(input);
-
- cmd = strtok_r(input, " ", &arg);
- if (!cmd)
- goto done;
-
- if (arg) {
- int len = strlen(arg);
- if (len > 0 && arg[len - 1] == ' ')
- arg[len - 1] = '\0';
- }
-
- for (i = 0; cmd_table[i].cmd; i++) {
- if (strcmp(cmd, cmd_table[i].cmd))
- continue;
-
- if (cmd_table[i].func) {
- cmd_table[i].func(arg);
- goto done;
- }
- }
-
- printf("Invalid command\n");
-done:
- free(input);
-}
-
-static void cmd_help(const char *arg)
-{
- int i;
-
- printf("Available commands:\n");
-
- for (i = 0; cmd_table[i].cmd; i++) {
- if ((int)strlen(cmd_table[i].arg? : "") <=
- (int)(25 - strlen(cmd_table[i].cmd)))
- printf(" %s %-*s %s\n", cmd_table[i].cmd,
- (int)(25 - strlen(cmd_table[i].cmd)),
- cmd_table[i].arg ? : "",
- cmd_table[i].desc ? : "");
- else
- printf(" %s %-s\n" " %s %-25s %s\n",
- cmd_table[i].cmd,
- cmd_table[i].arg ? : "",
- "", "",
- cmd_table[i].desc ? : "");
- }
-}
-
-static gboolean signal_handler(GIOChannel *channel, GIOCondition condition,
- gpointer user_data)
-{
- static bool terminated = false;
- struct signalfd_siginfo si;
- ssize_t result;
- int fd;
-
- if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
- g_main_loop_quit(main_loop);
- return FALSE;
- }
-
- fd = g_io_channel_unix_get_fd(channel);
-
- result = read(fd, &si, sizeof(si));
- if (result != sizeof(si))
- return FALSE;
-
- switch (si.ssi_signo) {
- case SIGINT:
- if (input) {
- rl_replace_line("", 0);
- rl_crlf();
- rl_on_new_line();
- rl_redisplay();
- break;
- }
-
- /*
- * If input was not yet setup up that means signal was received
- * while daemon was not yet running. Since user is not able
- * to terminate client by CTRL-D or typing exit treat this as
- * exit and fall through.
- */
-
- /* fall through */
- case SIGTERM:
- if (!terminated) {
- rl_replace_line("", 0);
- rl_crlf();
- g_main_loop_quit(main_loop);
- }
-
- terminated = true;
- break;
- }
-
- return TRUE;
-}
-
-static guint setup_signalfd(void)
-{
- GIOChannel *channel;
- guint source;
- sigset_t mask;
- int fd;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGINT);
- sigaddset(&mask, SIGTERM);
-
- if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
- perror("Failed to set signal mask");
- return 0;
- }
-
- fd = signalfd(-1, &mask, 0);
- if (fd < 0) {
- perror("Failed to create signal descriptor");
- return 0;
- }
-
- channel = g_io_channel_unix_new(fd);
-
- g_io_channel_set_close_on_unref(channel, TRUE);
- g_io_channel_set_encoding(channel, NULL, NULL);
- g_io_channel_set_buffered(channel, FALSE);
-
- source = g_io_add_watch(channel,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- signal_handler, NULL);
-
- g_io_channel_unref(channel);
-
- return source;
-}
-
-static gboolean option_version = FALSE;
-
static gboolean parse_agent(const char *key, const char *value,
gpointer user_data, GError **error)
{
}
static GOptionEntry options[] = {
- { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
- "Show version information and exit" },
{ "agent", 'a', 0, G_OPTION_ARG_CALLBACK, parse_agent,
"Register agent handler", "CAPABILITY" },
{ NULL },
static void client_ready(GDBusClient *client, void *user_data)
{
- if (!input)
- input = setup_standard_input();
+ setup_standard_input();
}
int main(int argc, char *argv[])
GOptionContext *context;
GError *error = NULL;
GDBusClient *client;
- guint signal;
auto_register_agent = g_strdup("");
g_option_context_free(context);
- if (option_version == TRUE) {
- printf("%s\n", VERSION);
- exit(0);
- }
+ bt_shell_init(&argc, &argv);
+ bt_shell_set_menu(cmd_table);
+ bt_shell_set_prompt(PROMPT_OFF);
- main_loop = g_main_loop_new(NULL, FALSE);
dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
g_dbus_attach_object_manager(dbus_conn);
- setlinebuf(stdout);
- rl_attempted_completion_function = cmd_completion;
-
- rl_erase_empty_line = 1;
- rl_callback_handler_install(NULL, rl_handler);
-
- rl_set_prompt(PROMPT_OFF);
- rl_redisplay();
-
- signal = setup_signalfd();
client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
g_dbus_client_set_connect_watch(client, connect_handler, NULL);
g_dbus_client_set_ready_watch(client, client_ready, NULL);
- g_main_loop_run(main_loop);
+ bt_shell_run();
g_dbus_client_unref(client);
- g_source_remove(signal);
- if (input > 0)
- g_source_remove(input);
-
- rl_message("");
- rl_callback_handler_remove();
dbus_connection_unref(dbus_conn);
- g_main_loop_unref(main_loop);
g_list_free_full(ctrl_list, proxy_leak);