diff options
author | Grzegorz Kolodziejczyk <grzegorz.kolodziejczyk@codecoup.pl> | 2018-03-20 15:05:19 +0100 |
---|---|---|
committer | Szymon Janc <szymon.janc@codecoup.pl> | 2018-03-21 11:25:52 +0100 |
commit | d3f155e4588b0a2f7fa08594b0f1d2da7506e3be (patch) | |
tree | f82c110d13e36b7a054e8baf05f299e15207003e /client/gatt.c | |
parent | bc6facb0cfcfa3098b57f93919b69e7ffb204f04 (diff) | |
download | bluez-d3f155e4588b0a2f7fa08594b0f1d2da7506e3be.tar.gz |
client: Add authorization request handling for attribute operations
This patch adds optional authorization request for reading, writing of
gatt database attributes.
Diffstat (limited to 'client/gatt.c')
-rw-r--r-- | client/gatt.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/client/gatt.c b/client/gatt.c index 3fa490b1a..930a64699 100644 --- a/client/gatt.c +++ b/client/gatt.c @@ -75,6 +75,8 @@ struct chrc { uint16_t mtu; struct io *write_io; struct io *notify_io; + bool authorization_req; + bool authorized; }; struct service { @@ -91,6 +93,7 @@ static GList *characteristics; static GList *descriptors; static GList *managers; static GList *uuids; +static DBusMessage *pending_message = NULL; struct pipe_io { GDBusProxy *proxy; @@ -1462,17 +1465,81 @@ static DBusMessage *read_value(DBusMessage *msg, uint8_t *value, return reply; } +struct authorize_attribute_data { + DBusConnection *conn; + void *attribute; + uint16_t offset; +}; + +static void authorize_read_response(const char *input, void *user_data) +{ + struct authorize_attribute_data *aad = user_data; + struct chrc *chrc = aad->attribute; + DBusMessage *reply; + char *err; + + if (!strcmp(input, "no")) { + err = "org.bluez.Error.NotAuthorized"; + + goto error; + } + + if (aad->offset > chrc->value_len) { + err = "org.bluez.Error.InvalidOffset"; + + goto error; + } + + reply = read_value(pending_message, &chrc->value[aad->offset], + chrc->value_len - aad->offset); + + chrc->authorized = true; + + g_dbus_send_message(aad->conn, reply); + + g_free(aad); + + return; + +error: + g_dbus_send_error(aad->conn, pending_message, err, NULL); + g_free(aad); +} + static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct chrc *chrc = user_data; DBusMessageIter iter; uint16_t offset = 0; + char *str; dbus_message_iter_init(msg, &iter); parse_offset(&iter, &offset); + if (chrc->authorization_req && offset == 0) + chrc->authorized = false; + + if (chrc->authorization_req && !chrc->authorized) { + struct authorize_attribute_data *aad; + + aad = g_new0(struct authorize_attribute_data, 1); + aad->conn = conn; + aad->attribute = chrc; + aad->offset = offset; + + str = g_strdup_printf("Authorize attribute(%s) read (yes/no):", + chrc->path); + + bt_shell_prompt_input("gatt", str, authorize_read_response, + aad); + + pending_message = dbus_message_ref(msg); + + return NULL; + } + if (offset > chrc->value_len) return g_dbus_create_error(msg, "org.bluez.Error.InvalidOffset", NULL); @@ -1493,14 +1560,74 @@ static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len) return 0; } +static void authorize_write_response(const char *input, void *user_data) +{ + struct authorize_attribute_data *aad = user_data; + struct chrc *chrc = aad->attribute; + DBusMessageIter iter; + DBusMessage *reply; + char *err; + + dbus_message_iter_init(pending_message, &iter); + + if (!strcmp(input, "no")) { + err = "org.bluez.Error.NotAuthorized"; + + goto error; + } + + chrc->authorized = true; + + if (parse_value_arg(&iter, &chrc->value, &chrc->value_len)) { + err = "org.bluez.Error.InvalidArguments"; + + goto error; + } + + bt_shell_printf("[" COLORED_CHG "] Attribute %s written" , chrc->path); + + g_dbus_emit_property_changed(aad->conn, chrc->path, CHRC_INTERFACE, + "Value"); + + reply = g_dbus_create_reply(pending_message, DBUS_TYPE_INVALID); + g_dbus_send_message(aad->conn, reply); + + g_free(aad); + + return; + +error: + g_dbus_send_error(aad->conn, pending_message, err, NULL); + g_free(aad); +} + static DBusMessage *chrc_write_value(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct chrc *chrc = user_data; DBusMessageIter iter; + char *str; dbus_message_iter_init(msg, &iter); + if (chrc->authorization_req && !chrc->authorized) { + struct authorize_attribute_data *aad; + + aad = g_new0(struct authorize_attribute_data, 1); + aad->conn = conn; + aad->attribute = chrc; + + str = g_strdup_printf("Authorize attribute(%s) write (yes/no):", + chrc->path); + + bt_shell_prompt_input("gatt", str, authorize_write_response, + aad); + + pending_message = dbus_message_ref(msg); + + return NULL; + } + if (parse_value_arg(&iter, &chrc->value, &chrc->value_len)) return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments", @@ -1763,6 +1890,7 @@ void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy, chrc->uuid = g_strdup(argv[1]); chrc->path = g_strdup_printf("%s/chrc%p", service->path, chrc); chrc->flags = g_strsplit(argv[2], ",", -1); + chrc->authorization_req = argc > 3 ? true : false; if (g_dbus_register_interface(conn, chrc->path, CHRC_INTERFACE, chrc_methods, NULL, chrc_properties, |