summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2019-02-12 12:00:08 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2019-02-13 17:09:13 +0200
commit32232aba539b1218d8706f5681a302877fe8891b (patch)
tree2fc9ab2fc7813b6dfabe8907a09584729516387f /client
parent183d47c1760107fbe3958c3f7d63cc17cef745ae (diff)
downloadbluez-32232aba539b1218d8706f5681a302877fe8891b.tar.gz
client: Proxy calls to ReadValue and WriteValue
This uses the proxies created by clone command to forward the requests to the cloned services.
Diffstat (limited to 'client')
-rw-r--r--client/gatt.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/client/gatt.c b/client/gatt.c
index 6728b1c33..7e2011a1f 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -672,6 +672,7 @@ static void write_reply(DBusMessage *message, void *user_data)
}
struct write_attribute_data {
+ DBusMessage *msg;
struct iovec iov;
char *type;
uint16_t offset;
@@ -1908,6 +1909,95 @@ static bool is_device_trusted(const char *path)
return trusted;
}
+struct read_attribute_data {
+ DBusMessage *msg;
+ uint16_t offset;
+};
+
+static void proxy_read_reply(DBusMessage *message, void *user_data)
+{
+ struct read_attribute_data *data = user_data;
+ DBusConnection *conn = bt_shell_get_env("DBUS_CONNECTION");
+ DBusError error;
+ DBusMessageIter iter, array;
+ DBusMessage *reply;
+ uint8_t *value;
+ int len;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ bt_shell_printf("Failed to read: %s\n", error.name);
+ dbus_error_free(&error);
+ g_dbus_send_error(conn, data->msg, error.name, "%s",
+ error.message);
+ goto done;
+ }
+
+ dbus_message_iter_init(message, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+ bt_shell_printf("Invalid response to read\n");
+ g_dbus_send_error(conn, data->msg,
+ "org.bluez.Error.InvalidArguments", NULL);
+ goto done;
+ }
+
+ dbus_message_iter_recurse(&iter, &array);
+ dbus_message_iter_get_fixed_array(&array, &value, &len);
+
+ if (len < 0) {
+ bt_shell_printf("Unable to parse value\n");
+ g_dbus_send_error(conn, data->msg,
+ "org.bluez.Error.InvalidArguments", NULL);
+ }
+
+ reply = read_value(data->msg, value, len);
+
+ g_dbus_send_message(conn, reply);
+
+done:
+ dbus_message_unref(data->msg);
+ free(data);
+}
+
+static void proxy_read_setup(DBusMessageIter *iter, void *user_data)
+{
+ DBusMessageIter dict;
+ struct read_attribute_data *data = user_data;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &dict);
+
+ g_dbus_dict_append_entry(&dict, "offset", DBUS_TYPE_UINT16,
+ &data->offset);
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static DBusMessage *proxy_read_value(struct GDBusProxy *proxy, DBusMessage *msg,
+ uint16_t offset)
+{
+ struct read_attribute_data *data;
+
+ data = new0(struct read_attribute_data, 1);
+ data->msg = dbus_message_ref(msg);
+ data->offset = offset;
+
+ if (g_dbus_proxy_method_call(proxy, "ReadValue", proxy_read_setup,
+ proxy_read_reply, data, NULL))
+ return NULL;
+
+ bt_shell_printf("Failed to read\n");
+
+ return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
+ NULL);
+}
+
static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
@@ -1927,6 +2017,10 @@ static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg,
bt_shell_printf("ReadValue: %s offset %u link %s\n",
path_to_address(device), offset, link);
+ if (chrc->proxy) {
+ return proxy_read_value(chrc->proxy, msg, offset);
+ }
+
if (!is_device_trusted(device) && chrc->authorization_req) {
struct authorize_attribute_data *aad;
@@ -2047,6 +2141,49 @@ error:
g_free(aad);
}
+static void proxy_write_reply(DBusMessage *message, void *user_data)
+{
+ struct write_attribute_data *data = user_data;
+ DBusConnection *conn = bt_shell_get_env("DBUS_CONNECTION");
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message)) {
+ bt_shell_printf("Failed to write: %s\n", error.name);
+ g_dbus_send_error(conn, data->msg, error.name, "%s",
+ error.message);
+ } else
+ g_dbus_send_reply(conn, data->msg, DBUS_TYPE_INVALID);
+
+ dbus_message_unref(data->msg);
+ free(data);
+}
+
+static DBusMessage *proxy_write_value(struct GDBusProxy *proxy,
+ DBusMessage *msg, uint8_t *value,
+ int value_len, uint16_t offset)
+{
+ struct write_attribute_data *data;
+
+
+ data = new0(struct write_attribute_data, 1);
+ data->msg = dbus_message_ref(msg);
+ data->iov.iov_base = (void *) value;
+ data->iov.iov_len = value_len;
+ data->offset = offset;
+
+ if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup,
+ proxy_write_reply, data, NULL))
+ return NULL;
+
+
+ bt_shell_printf("Failed to write\n");
+
+ return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
+ NULL);
+}
+
static DBusMessage *chrc_write_value(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
@@ -2070,6 +2207,10 @@ static DBusMessage *chrc_write_value(DBusConnection *conn, DBusMessage *msg,
return g_dbus_create_error(msg,
"org.bluez.Error.InvalidArguments", NULL);
+ if (chrc->proxy)
+ return proxy_write_value(chrc->proxy, msg, value, value_len,
+ offset);
+
if (!is_device_trusted(device) && chrc->authorization_req) {
struct authorize_attribute_data *aad;