Diff between 822f082063c1992b1d235b0bb998a6c448dd5923 and 1ebfc68ff53ea5ed5cb424df151bf413c7ffe9be

Changed Files

File Additions Deletions Status
client/gatt.c +52 -94 modified
client/main.c +7 -2 modified

Full Patch

diff --git a/client/gatt.c b/client/gatt.c
index 3e70f36..d37a6f5 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -80,6 +80,7 @@ struct chrc {
 	struct io *write_io;
 	struct io *notify_io;
 	bool authorization_req;
+	bool authorized;
 };
 
 struct service {
@@ -1608,8 +1609,7 @@ static const char *path_to_address(const char *path)
 }
 
 static int parse_options(DBusMessageIter *iter, uint16_t *offset, uint16_t *mtu,
-						char **device, char **link,
-						bool *prep_authorize)
+						char **device, char **link)
 {
 	DBusMessageIter dict;
 
@@ -1650,12 +1650,6 @@ static int parse_options(DBusMessageIter *iter, uint16_t *offset, uint16_t *mtu,
 				return -EINVAL;
 			if (link)
 				dbus_message_iter_get_basic(&value, link);
-		} else if (strcasecmp(key, "prepare-authorize") == 0) {
-			if (var != DBUS_TYPE_BOOLEAN)
-				return -EINVAL;
-			if (prep_authorize)
-				dbus_message_iter_get_basic(&value,
-								prep_authorize);
 		}
 
 		dbus_message_iter_next(&dict);
@@ -1709,6 +1703,8 @@ static void authorize_read_response(const char *input, void *user_data)
 	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);
@@ -1731,15 +1727,18 @@ static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg,
 
 	dbus_message_iter_init(msg, &iter);
 
-	if (parse_options(&iter, &offset, NULL, &device, &link, NULL))
+	if (parse_options(&iter, &offset, NULL, &device, &link))
 		return g_dbus_create_error(msg,
 					"org.bluez.Error.InvalidArguments",
 					NULL);
 
 	bt_shell_printf("ReadValue: %s offset %u link %s\n",
-					path_to_address(device), offset, link);
+			path_to_address(device), offset, link);
+
+	if (chrc->authorization_req && offset == 0)
+		chrc->authorized = false;
 
-	if (chrc->authorization_req) {
+	if (chrc->authorization_req && !chrc->authorized) {
 		struct authorize_attribute_data *aad;
 
 		aad = g_new0(struct authorize_attribute_data, 1);
@@ -1766,31 +1765,33 @@ static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg,
 	return read_value(msg, &chrc->value[offset], chrc->value_len - offset);
 }
 
-static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len)
+static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len,
+								int max_len)
 {
 	DBusMessageIter array;
+	uint16_t offset = 0;
+	uint8_t *read_value;
+	int read_len;
 
 	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
 		return -EINVAL;
 
 	dbus_message_iter_recurse(iter, &array);
-	dbus_message_iter_get_fixed_array(&array, value, len);
+	dbus_message_iter_get_fixed_array(&array, &read_value, &read_len);
 
-	return 0;
-}
+	dbus_message_iter_next(iter);
+	if (parse_options(iter, &offset, NULL, NULL, NULL))
+		return -EINVAL;
 
-static int write_value(int *dst_len, uint8_t **dst_value, uint8_t *src_val,
-				int src_len, uint16_t offset, uint16_t max_len)
-{
-	if ((offset + src_len) > max_len)
+	if ((offset + read_len) > max_len)
 		return -EOVERFLOW;
 
-	if ((offset + src_len) != *dst_len) {
-		*dst_len = offset + src_len;
-		*dst_value = g_realloc(*dst_value, *dst_len);
+	if ((offset + read_len) > *len) {
+		*len = offset + read_len;
+		*value = g_realloc(*value, *len);
 	}
 
-	memcpy(*dst_value + offset, src_val, src_len);
+	memcpy(*value + offset, read_value, read_len);
 
 	return 0;
 }
@@ -1799,26 +1800,12 @@ static void authorize_write_response(const char *input, void *user_data)
 {
 	struct authorize_attribute_data *aad = user_data;
 	struct chrc *chrc = aad->attribute;
-	bool prep_authorize = false;
 	DBusMessageIter iter;
 	DBusMessage *reply;
-	int value_len;
-	uint8_t *value;
 	char *err;
+	int errsv;
 
 	dbus_message_iter_init(pending_message, &iter);
-	if (parse_value_arg(&iter, &value, &value_len)) {
-		err = "org.bluez.Error.InvalidArguments";
-
-		goto error;
-	}
-
-	dbus_message_iter_next(&iter);
-	if (parse_options(&iter, NULL, NULL, NULL, NULL, &prep_authorize)) {
-		err = "org.bluez.Error.InvalidArguments";
-
-		goto error;
-	}
 
 	if (!strcmp(input, "no")) {
 		err = "org.bluez.Error.NotAuthorized";
@@ -1826,17 +1813,15 @@ static void authorize_write_response(const char *input, void *user_data)
 		goto error;
 	}
 
-	/* Authorization check of prepare writes */
-	if (prep_authorize) {
-		reply = g_dbus_create_reply(pending_message, DBUS_TYPE_INVALID);
-		g_dbus_send_message(aad->conn, reply);
-		g_free(aad);
+	chrc->authorized = true;
 
-		return;
-	}
+	errsv = parse_value_arg(&iter, &chrc->value, &chrc->value_len,
+							chrc->max_val_len);
+	if (errsv == -EINVAL) {
+		err = "org.bluez.Error.InvalidArguments";
 
-	if (write_value(&chrc->value_len, &chrc->value, value, value_len,
-					aad->offset, chrc->max_val_len)) {
+		goto error;
+	} else if (errsv == -EOVERFLOW) {
 		err = "org.bluez.Error.InvalidValueLength";
 
 		goto error;
@@ -1863,31 +1848,18 @@ static DBusMessage *chrc_write_value(DBusConnection *conn, DBusMessage *msg,
 							void *user_data)
 {
 	struct chrc *chrc = user_data;
-	uint16_t offset = 0;
-	bool prep_authorize = false;
 	DBusMessageIter iter;
-	int value_len;
-	uint8_t *value;
 	char *str;
+	int errsv;
 
 	dbus_message_iter_init(msg, &iter);
 
-	if (parse_value_arg(&iter, &value, &value_len))
-		return g_dbus_create_error(msg,
-				"org.bluez.Error.InvalidArguments", NULL);
-
-	dbus_message_iter_next(&iter);
-	if (parse_options(&iter, &offset, NULL, NULL, NULL, &prep_authorize))
-		return g_dbus_create_error(msg,
-				"org.bluez.Error.InvalidArguments", NULL);
-
-	if (chrc->authorization_req) {
+	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) write (yes/no):",
 								chrc->path);
@@ -1901,14 +1873,15 @@ static DBusMessage *chrc_write_value(DBusConnection *conn, DBusMessage *msg,
 		return NULL;
 	}
 
-	/* Authorization check of prepare writes */
-	if (prep_authorize)
-		return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-
-	if (write_value(&chrc->value_len, &chrc->value, value, value_len,
-						offset, chrc->max_val_len))
+	errsv = parse_value_arg(&iter, &chrc->value, &chrc->value_len,
+							chrc->max_val_len);
+	if (errsv == -EINVAL) {
+		return g_dbus_create_error(msg,
+				"org.bluez.Error.InvalidArguments", NULL);
+	} else if (errsv == -EOVERFLOW) {
 		return g_dbus_create_error(msg,
 				"org.bluez.Error.InvalidValueLength", NULL);
+	}
 
 	bt_shell_printf("[" COLORED_CHG "] Attribute %s written" , chrc->path);
 
@@ -1970,7 +1943,7 @@ static DBusMessage *chrc_acquire_write(DBusConnection *conn, DBusMessage *msg,
 					"org.bluez.Error.NotPermitted",
 					NULL);
 
-	if (parse_options(&iter, NULL, &chrc->mtu, &device, &link, NULL))
+	if (parse_options(&iter, NULL, &chrc->mtu, &device, &link))
 		return g_dbus_create_error(msg,
 					"org.bluez.Error.InvalidArguments",
 					NULL);
@@ -2002,7 +1975,7 @@ static DBusMessage *chrc_acquire_notify(DBusConnection *conn, DBusMessage *msg,
 					"org.bluez.Error.NotPermitted",
 					NULL);
 
-	if (parse_options(&iter, NULL, &chrc->mtu, &device, &link, NULL))
+	if (parse_options(&iter, NULL, &chrc->mtu, &device, &link))
 		return g_dbus_create_error(msg,
 					"org.bluez.Error.InvalidArguments",
 					NULL);
@@ -2128,18 +2101,6 @@ static void chrc_set_value(const char *input, void *user_data)
 	chrc->max_val_len = chrc->value_len;
 }
 
-static gboolean attr_authorization_flag_exists(char **flags)
-{
-	int i;
-
-	for (i = 0; flags[i]; i++) {
-		if (!strcmp("authorize", flags[i]))
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
 void gatt_register_chrc(DBusConnection *conn, GDBusProxy *proxy,
 					int argc, char *argv[])
 {
@@ -2158,7 +2119,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 = attr_authorization_flag_exists(chrc->flags);
+	chrc->authorization_req = argc > 3 ? true : false;
 
 	if (g_dbus_register_interface(conn, chrc->path, CHRC_INTERFACE,
 					chrc_methods, NULL, chrc_properties,
@@ -2230,7 +2191,7 @@ static DBusMessage *desc_read_value(DBusConnection *conn, DBusMessage *msg,
 
 	dbus_message_iter_init(msg, &iter);
 
-	if (parse_options(&iter, &offset, NULL, &device, &link, NULL))
+	if (parse_options(&iter, &offset, NULL, &device, &link))
 		return g_dbus_create_error(msg,
 					"org.bluez.Error.InvalidArguments",
 					NULL);
@@ -2252,24 +2213,21 @@ static DBusMessage *desc_write_value(DBusConnection *conn, DBusMessage *msg,
 	DBusMessageIter iter;
 	uint16_t offset = 0;
 	char *device = NULL, *link = NULL;
-	int value_len;
-	uint8_t *value;
 
 	dbus_message_iter_init(msg, &iter);
 
-	if (parse_value_arg(&iter, &value, &value_len))
+	if (parse_value_arg(&iter, &desc->value, &desc->value_len,
+							desc->max_val_len))
 		return g_dbus_create_error(msg,
-				"org.bluez.Error.InvalidArguments", NULL);
+					"org.bluez.Error.InvalidArguments",
+					NULL);
 
 	dbus_message_iter_next(&iter);
-	if (parse_options(&iter, &offset, NULL, &device, &link, NULL))
-		return g_dbus_create_error(msg,
-				"org.bluez.Error.InvalidArguments", NULL);
 
-	if (write_value(&desc->value_len, &desc->value, value,
-					value_len, offset, desc->max_val_len))
+	if (parse_options(&iter, &offset, NULL, &device, &link))
 		return g_dbus_create_error(msg,
-				"org.bluez.Error.InvalidValueLength", NULL);
+					"org.bluez.Error.InvalidArguments",
+					NULL);
 
 	bt_shell_printf("WriteValue: %s offset %u link %s\n",
 			path_to_address(device), offset, link);
diff --git a/client/main.c b/client/main.c
index 87323d8..180f841 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2036,6 +2036,11 @@ static void cmd_register_characteristic(int argc, char *argv[])
 	if (check_default_ctrl() == FALSE)
 		return bt_shell_noninteractive_quit(EXIT_FAILURE);
 
+	if (argc > 3 && strcmp(argv[3], "authorize")) {
+		bt_shell_printf("Invalid authorize argument\n");
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
 	gatt_register_chrc(dbus_conn, default_ctrl->proxy, argc, argv);
 }
 
@@ -2512,8 +2517,8 @@ static const struct bt_shell_menu gatt_menu = {
 			cmd_unregister_includes,
 				 "Unregister Included service." },
 	{ "register-characteristic", "<UUID> <Flags=read,write,notify...> "
-					, cmd_register_characteristic,
-					"Register application characteristic" },
+				"[authorize]", cmd_register_characteristic,
+				"Register application characteristic" },
 	{ "unregister-characteristic", "<UUID/object>",
 				cmd_unregister_characteristic,
 				"Unregister application characteristic" },