[PATCHv2 1/4] gatt: Add new characteristic functionality

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It will attach characteristic declaration and value, and return value
handle. It is needed to pass service handle to which this characteristic
will be added. If there is not enough free handles in service, 0 will be
returned.
---
 src/shared/gatt-db.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/shared/gatt-db.h |  15 ++++++++
 2 files changed, 116 insertions(+)

diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index a211cda..38c9612 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -28,10 +28,14 @@
 #include "src/shared/queue.h"
 #include "src/shared/gatt-db.h"
 
+#define MAX_CHAR_DECL_VALUE_LEN 19
+
 static const bt_uuid_t primary_service_uuid = { .type = BT_UUID16,
 					.value.u16 = GATT_PRIM_SVC_UUID };
 static const bt_uuid_t secondary_service_uuid = { .type = BT_UUID16,
 					.value.u16 = GATT_SND_SVC_UUID };
+static const bt_uuid_t characteristic_uuid = { .type = BT_UUID16,
+					.value.u16 = GATT_CHARAC_UUID };
 
 struct gatt_db {
 	uint16_t next_handle;
@@ -43,6 +47,10 @@ struct gatt_db_attribute {
 	bt_uuid_t uuid;
 	uint16_t val_len;
 	uint8_t value[0];
+	uint8_t permissions;
+	gatt_db_read_t read_func;
+	gatt_db_write_t write_func;
+	void *user_data;
 };
 
 struct gatt_db_service {
@@ -191,3 +199,96 @@ bool gatt_db_remove_service(struct gatt_db *db, uint16_t handle)
 
 	return true;
 }
+
+static uint16_t get_attribute_index(struct gatt_db_service *service,
+							int end_offset)
+{
+	int i = 0;
+
+	/* Here we look for first free attribute index with given offset */
+	while (i < (service->num_handles - end_offset) &&
+						service->attributes[i])
+		i++;
+
+	return i == (service->num_handles - end_offset) ? 0 : i;
+}
+
+static uint16_t get_handle_at_index(struct gatt_db_service *service,
+								int index)
+{
+	return service->attributes[index]->handle;
+}
+
+static uint16_t update_attribute_handle(struct gatt_db_service *service,
+								int index)
+{
+	uint16_t previous_handle;
+
+	/* We call this function with index > 0, because index 0 is reserved
+	 * for service declaration, and is set in add_service()
+	 */
+	previous_handle = service->attributes[index - 1]->handle;
+	service->attributes[index]->handle = previous_handle + 1;
+
+	return service->attributes[index]->handle;
+}
+
+static void set_attribute_data(struct gatt_db_attribute *attribute,
+						gatt_db_read_t read_func,
+						gatt_db_write_t write_func,
+						uint8_t permissions,
+						void *user_data)
+{
+	attribute->permissions = permissions;
+	attribute->read_func = read_func;
+	attribute->write_func = write_func;
+	attribute->user_data = user_data;
+}
+
+uint16_t gatt_db_add_characteristic(struct gatt_db *db, uint16_t handle,
+						const bt_uuid_t *uuid,
+						uint8_t permissions,
+						uint8_t properties,
+						gatt_db_read_t read_func,
+						gatt_db_write_t write_func,
+						void *user_data)
+{
+	uint8_t value[MAX_CHAR_DECL_VALUE_LEN];
+	struct gatt_db_service *service;
+	uint16_t len = 0;
+	int i;
+
+	service = queue_find(db->services, match_service_by_handle,
+							INT_TO_PTR(handle));
+	if (!service)
+		return 0;
+
+	i = get_attribute_index(service, 1);
+	if (!i)
+		return 0;
+
+	value[0] = properties;
+	len += sizeof(properties);
+	/* We set handle of characteristic value, which will be added next */
+	put_le16(get_handle_at_index(service, i - 1) + 2, &value[1]);
+	len += sizeof(uint16_t);
+	len += uuid_to_le(uuid, &value[3]);
+
+	service->attributes[i] = new_attribute(&characteristic_uuid, value,
+									len);
+	if (!service->attributes[i])
+		return 0;
+
+	update_attribute_handle(service, i++);
+
+	service->attributes[i] = new_attribute(uuid, NULL, 0);
+	if (!service->attributes[i]) {
+		free(service->attributes[i - 1]);
+		return 0;
+	}
+
+	set_attribute_data(service->attributes[i], read_func, write_func,
+							permissions, user_data);
+
+	return update_attribute_handle(service, i);
+}
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index b014b17..cfc4947 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -29,3 +29,18 @@ void gatt_db_destroy(struct gatt_db *db);
 uint16_t gatt_db_add_service(struct gatt_db *db, const bt_uuid_t *uuid,
 					bool primary, uint16_t num_handles);
 bool gatt_db_remove_service(struct gatt_db *db, uint16_t handle);
+
+typedef void (*gatt_db_read_t) (uint16_t handle, const bdaddr_t *bdaddr,
+				uint16_t request_id, void *user_data);
+
+typedef void (*gatt_db_write_t)  (uint16_t handle, const bdaddr_t *bdaddr,
+				uint16_t request_id, const uint8_t *value,
+								size_t len);
+
+uint16_t gatt_db_add_characteristic(struct gatt_db *db, uint16_t handle,
+						const bt_uuid_t *uuid,
+						uint8_t permissions,
+						uint8_t properties,
+						gatt_db_read_t read_func,
+						gatt_db_write_t write_func,
+						void *user_data);
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux