linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/10] Implement Generic battery and LE Battery client
@ 2012-09-20  8:27 chen.ganir
  2012-09-20  8:27 ` [PATCH v3 01/10] battery: Add generic device battery documentation chen.ganir
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

This patch set replaces previous patch sets which implemented the LE battery
GATT Client. This patch set implements a generic device battery D-Bus interface
that can be used to get remote device battery status using D-Bus. In addition,
This patch set also implements the GATT Battery client, which uses the generic
device battery to expose LE device battery status.

see doc/battery-api.txt and doc/device-api.txt for more information.

This is version 2 of the patch set, including multiple style and other comments
reported on the ML. This version is rebased on the latest code.

Chen Ganir (10):
  battery: Add generic device battery documentation
  battery: Implement Generic device battery
  battery: Add GATT Battery Client Service skeleton
  battery: Add client connection logic
  battery: Discover Characteristic Descriptors
  battery: Get Battery ID
  battery: Add Battery to device
  battery: Read Battery level characteristic
  battery: Add support for notifications
  battery: Support persistent battery level

 Makefile.am                |    9 +-
 doc/battery-api.txt        |   31 +++
 doc/device-api.txt         |    5 +
 lib/uuid.h                 |    3 +
 profiles/battery/battery.c |  594 ++++++++++++++++++++++++++++++++++++++++++++
 profiles/battery/battery.h |   24 ++
 profiles/battery/main.c    |   52 ++++
 profiles/battery/manager.c |   62 +++++
 profiles/battery/manager.h |   24 ++
 src/device.c               |  182 ++++++++++++++
 src/device.h               |   15 ++
 test/test-device           |   13 +
 12 files changed, 1012 insertions(+), 2 deletions(-)
 create mode 100644 doc/battery-api.txt
 create mode 100644 profiles/battery/battery.c
 create mode 100644 profiles/battery/battery.h
 create mode 100644 profiles/battery/main.c
 create mode 100644 profiles/battery/manager.c
 create mode 100644 profiles/battery/manager.h

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 01/10] battery: Add generic device battery documentation
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 02/10] battery: Implement Generic device battery chen.ganir
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Add documentation for the generic battery D-Bus interface.
---
 doc/battery-api.txt |   31 +++++++++++++++++++++++++++++++
 doc/device-api.txt  |    5 +++++
 2 files changed, 36 insertions(+)
 create mode 100644 doc/battery-api.txt

diff --git a/doc/battery-api.txt b/doc/battery-api.txt
new file mode 100644
index 0000000..7e1b94f
--- /dev/null
+++ b/doc/battery-api.txt
@@ -0,0 +1,31 @@
+BlueZ D-Bus Battery API description
+****************************************
+
+	Texas Instruments, Inc. <chen.ganir@ti.com>
+
+Device Battery hierarchy
+=====================================
+
+Service		org.bluez
+Interface	org.bluez.Battery
+Object path	[variable prefix]/{hci0,..}/dev_XX_XX_XX_XX_XX_XX/BATTYYYY
+YYYY is numeric value between 0 and 9999.
+
+Methods	dict GetProperties()
+
+			Returns all properties for the interface. See the
+			Properties section for the available properties.
+
+		void Refresh()
+
+			Refresh the batterty level. If the battery level changed, the
+			PropertyChanged signal will be sent with the new value.
+
+Signals		PropertyChanged(string name, variant value)
+
+			This signal indicates a changed value of the given
+			property.
+
+Properties	uint16 Level [readonly]
+
+			Battery level (0-100).
diff --git a/doc/device-api.txt b/doc/device-api.txt
index 1f0dc96..c98d539 100644
--- a/doc/device-api.txt
+++ b/doc/device-api.txt
@@ -179,3 +179,8 @@ Properties	string Address [readonly]
 			Note that this property can exhibit false-positives
 			in the case of Bluetooth 2.1 (or newer) devices that
 			have disabled Extended Inquiry Response support.
+
+		array{object} Batteries [readonly]
+
+			List of device battery object paths that represents the available
+			batteries on the remote device.
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 02/10] battery: Implement Generic device battery
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
  2012-09-20  8:27 ` [PATCH v3 01/10] battery: Add generic device battery documentation chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 03/10] battery: Add GATT Battery Client Service skeleton chen.ganir
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Add implementation for the generic battery in bluetooth device.
This patch adds new D-Bus interface for adding/removing/changing
peer device battery status, allowing management of remote device
batteries.
---
 src/device.c     |  182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/device.h     |   15 +++++
 test/test-device |   13 ++++
 3 files changed, 210 insertions(+)

diff --git a/src/device.c b/src/device.c
index 77215f1..2e3c738 100644
--- a/src/device.c
+++ b/src/device.c
@@ -167,6 +167,7 @@ struct btd_device {
 
 	gboolean	authorizing;
 	gint		ref;
+	GSList		*batteries;
 
 	GIOChannel      *att_io;
 	guint		cleanup_id;
@@ -179,6 +180,26 @@ static uint16_t uuid_list[] = {
 	0
 };
 
+struct btd_battery {
+	DBusConnection		*conn;
+	uint16_t		level;
+	char			*path;
+	struct btd_device	*device;
+	refresh_battery_cb	refresh;
+};
+
+static void battery_free(gpointer user_data)
+{
+	struct btd_battery *b = user_data;
+
+	g_dbus_unregister_interface(b->conn, b->path, BATTERY_INTERFACE);
+	dbus_connection_unref(b->conn);
+	btd_device_unref(b->device);
+	g_free(b->path);
+	g_free(b);
+
+}
+
 static void browse_request_free(struct browse_req *req)
 {
 	if (req->listener_id)
@@ -258,6 +279,7 @@ static void device_free(gpointer user_data)
 	g_slist_free_full(device->primaries, g_free);
 	g_slist_free_full(device->attios, g_free);
 	g_slist_free_full(device->attios_offline, g_free);
+	g_slist_free_full(device->batteries, battery_free);
 
 	attio_cleanup(device);
 
@@ -431,6 +453,15 @@ static DBusMessage *get_properties(DBusConnection *conn,
 	ptr = adapter_get_path(adapter);
 	dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
 
+	/* Batteries */
+	str = g_new0(char *, g_slist_length(device->batteries) + 1);
+	for (i = 0, l = device->batteries; l; l = l->next, i++) {
+		struct btd_battery *b = l->data;
+		str[i] = b->path;
+	}
+	dict_append_array(&dict, "Batteries", DBUS_TYPE_OBJECT_PATH, &str, i);
+	g_free(str);
+
 	dbus_message_iter_close_container(&iter, &dict);
 
 	return reply;
@@ -3224,3 +3255,154 @@ void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
 	device_set_version(device, product_ver);
 }
 
+static void batteries_changed(struct btd_device *device)
+{
+	DBusConnection *conn = get_dbus_connection();
+	char **batteries;
+	GSList *l;
+	int i;
+
+	batteries = g_new0(char *, g_slist_length(device->batteries) + 1);
+	for (i = 0, l = device->batteries; l; l = l->next, i++) {
+		struct btd_battery *batt = l->data;
+		batteries[i] = batt->path;
+	}
+
+	emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
+				     "Batteries", DBUS_TYPE_OBJECT_PATH,
+				     &batteries, i);
+
+	g_free(batteries);
+}
+
+static DBusMessage *refresh_batt_level(DBusConnection *conn,
+						  DBusMessage *msg, void *data)
+{
+	struct btd_battery *b = data;
+
+	if (!b->refresh)
+		return btd_error_not_supported(msg);
+
+	b->refresh(b);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *get_batt_properties(DBusConnection *conn,
+						  DBusMessage *msg, void *data)
+{
+	struct btd_battery *b = data;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	DBusMessage *reply;
+
+	reply = dbus_message_new_method_return(msg);
+	if (reply == NULL)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	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);
+
+	dict_append_entry(&dict, "Level", DBUS_TYPE_UINT16, &b->level);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	return reply;
+}
+
+static GDBusMethodTable battery_methods[] = {
+	{ GDBUS_METHOD("GetProperties",
+		NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
+		get_batt_properties) },
+	{ GDBUS_METHOD("Refresh",
+		NULL, NULL,
+		refresh_batt_level) },
+	{ }
+};
+
+static GDBusSignalTable battery_signals[] = {
+	{ GDBUS_SIGNAL("PropertyChanged",
+		GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+	{ }
+};
+
+struct btd_battery *btd_device_add_battery(struct btd_device *device)
+{
+	struct btd_battery *batt;
+	DBusConnection *conn = get_dbus_connection();
+
+	batt = g_new0(struct btd_battery, 1);
+	batt->path = g_strdup_printf("%s/BATT%04X", device->path,
+					     g_slist_length(device->batteries));
+	batt->conn = dbus_connection_ref(conn);
+
+	if (!g_dbus_register_interface(batt->conn, batt->path,
+			BATTERY_INTERFACE, battery_methods, battery_signals,
+			NULL, batt, NULL)) {
+		error("D-Bus register interface %s failed", BATTERY_INTERFACE);
+		dbus_connection_unref(batt->conn);
+		g_free(batt->path);
+		g_free(batt);
+		return NULL;
+	}
+
+	batt->device = btd_device_ref(device);
+	device->batteries = g_slist_append(device->batteries, batt);
+	batteries_changed(device);
+
+	return batt;
+}
+
+void btd_device_remove_battery(struct btd_battery *batt)
+{
+	struct btd_device *dev = batt->device;
+
+	dev->batteries = g_slist_remove(dev->batteries, batt);
+
+	battery_free(batt);
+
+	batteries_changed(dev);
+}
+
+gboolean btd_device_set_battery_opt(struct btd_battery *batt,
+						    battery_option_t opt1, ...)
+{
+	va_list args;
+	battery_option_t opt = opt1;
+	int level;
+
+	if (!batt)
+		return FALSE;
+
+	va_start(args, opt1);
+
+	while (opt != BATTERY_OPT_INVALID) {
+		switch (opt) {
+		case BATTERY_OPT_LEVEL:
+			level = va_arg(args, int);
+			if (level != batt->level) {
+				batt->level = level;
+				emit_property_changed(batt->conn, batt->path,
+						BATTERY_INTERFACE, "Level",
+						DBUS_TYPE_UINT16, &level);
+			}
+			break;
+		case BATTERY_OPT_REFRESH_FUNC:
+			batt->refresh = va_arg(args, refresh_battery_cb);
+			break;
+		default:
+			error("Unknown option %d", opt);
+			return FALSE;
+		}
+
+		opt = va_arg(args, int);
+	}
+
+	va_end(args);
+
+	return TRUE;
+}
diff --git a/src/device.h b/src/device.h
index 9426ef8..f1662ca 100644
--- a/src/device.h
+++ b/src/device.h
@@ -23,8 +23,10 @@
  */
 
 #define DEVICE_INTERFACE	"org.bluez.Device"
+#define BATTERY_INTERFACE      "org.bluez.Battery"
 
 struct btd_device;
+struct btd_battery;
 
 typedef enum {
 	AUTH_TYPE_PINCODE,
@@ -34,6 +36,14 @@ typedef enum {
 	AUTH_TYPE_NOTIFY_PINCODE,
 } auth_type_t;
 
+typedef void (*refresh_battery_cb) (struct btd_battery *batt);
+
+typedef enum {
+	BATTERY_OPT_INVALID = 0,
+	BATTERY_OPT_LEVEL,
+	BATTERY_OPT_REFRESH_FUNC,
+} battery_option_t;
+
 struct btd_device *device_create(DBusConnection *conn,
 					struct btd_adapter *adapter,
 					const char *address, uint8_t bdaddr_type);
@@ -127,3 +137,8 @@ int device_unblock(DBusConnection *conn, struct btd_device *device,
 void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
 			uint16_t vendor_id, uint16_t product_id,
 			uint16_t product_ver);
+
+struct btd_battery *btd_device_add_battery(struct btd_device *device);
+void btd_device_remove_battery(struct btd_battery *batt);
+gboolean btd_device_set_battery_opt(struct btd_battery *batt,
+						    battery_option_t opt1, ...);
diff --git a/test/test-device b/test/test-device
index 63a96d3..7edb7b8 100755
--- a/test/test-device
+++ b/test/test-device
@@ -37,6 +37,7 @@ if (len(args) < 1):
 	print("")
 	print("  list")
 	print("  services <address>")
+	print("  batteries <address>")
 	print("  create <address>")
 	print("  remove <address|path>")
 	print("  disconnect <address>")
@@ -205,5 +206,17 @@ if (args[0] == "services"):
 			print(path)
 	sys.exit(0)
 
+if (args[0] == "batteries"):
+	if (len(args) < 2):
+		print("Need address parameter")
+	else:
+		path = adapter.FindDevice(args[1])
+		device = dbus.Interface(bus.get_object("org.bluez", path),
+							"org.bluez.Device")
+		properties = device.GetProperties()
+		for path in properties["Batteries"]:
+			print(path)
+	sys.exit(0)
+
 print("Unknown command")
 sys.exit(1)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 03/10] battery: Add GATT Battery Client Service skeleton
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
  2012-09-20  8:27 ` [PATCH v3 01/10] battery: Add generic device battery documentation chen.ganir
  2012-09-20  8:27 ` [PATCH v3 02/10] battery: Implement Generic device battery chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 04/10] battery: Add client connection logic chen.ganir
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Add support for the Battery Service Gatt Client side. Implement
the basic skeleton.
---
 Makefile.am                |    9 ++++-
 lib/uuid.h                 |    2 +
 profiles/battery/battery.c |   89 ++++++++++++++++++++++++++++++++++++++++++++
 profiles/battery/battery.h |   24 ++++++++++++
 profiles/battery/main.c    |   52 ++++++++++++++++++++++++++
 profiles/battery/manager.c |   62 ++++++++++++++++++++++++++++++
 profiles/battery/manager.h |   24 ++++++++++++
 7 files changed, 260 insertions(+), 2 deletions(-)
 create mode 100644 profiles/battery/battery.c
 create mode 100644 profiles/battery/battery.h
 create mode 100644 profiles/battery/main.c
 create mode 100644 profiles/battery/manager.c
 create mode 100644 profiles/battery/manager.h

diff --git a/Makefile.am b/Makefile.am
index 372111a..21b5ebf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -211,7 +211,7 @@ endif
 
 if GATTMODULES
 builtin_modules += thermometer alert time gatt_example proximity deviceinfo \
-			gatt
+			gatt battery
 builtin_sources += profiles/thermometer/main.c \
 			profiles/thermometer/manager.h \
 			profiles/thermometer/manager.c \
@@ -240,7 +240,12 @@ builtin_sources += profiles/thermometer/main.c \
 			profiles/deviceinfo/deviceinfo.c \
 			profiles/gatt/main.c profiles/gatt/manager.h \
 			profiles/gatt/manager.c profiles/gatt/gas.h \
-			profiles/gatt/gas.c
+			profiles/gatt/gas.c \
+			profiles/battery/main.c \
+			profiles/battery/manager.c \
+			profiles/battery/manager.h \
+			profiles/battery/battery.c \
+			profiles/battery/battery.h
 endif
 
 builtin_modules += formfactor
diff --git a/lib/uuid.h b/lib/uuid.h
index aa6efdf..58ad0b3 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -56,6 +56,8 @@ extern "C" {
 #define PNPID_UUID		"00002a50-0000-1000-8000-00805f9b34fb"
 #define DEVICE_INFORMATION_UUID	"0000180a-0000-1000-8000-00805f9b34fb"
 
+#define BATTERY_SERVICE_UUID	"0000180f-0000-1000-8000-00805f9b34fb"
+
 #define GATT_UUID		"00001801-0000-1000-8000-00805f9b34fb"
 #define IMMEDIATE_ALERT_UUID	"00001802-0000-1000-8000-00805f9b34fb"
 #define LINK_LOSS_UUID		"00001803-0000-1000-8000-00805f9b34fb"
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
new file mode 100644
index 0000000..7702e39
--- /dev/null
+++ b/profiles/battery/battery.c
@@ -0,0 +1,89 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <bluetooth/uuid.h>
+#include <stdbool.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "battery.h"
+
+struct battery {
+	struct btd_device	*dev;		/* Device reference */
+};
+
+static GSList *servers;
+
+static gint cmp_device(gconstpointer a, gconstpointer b)
+{
+	const struct battery *batt = a;
+	const struct btd_device *dev = b;
+
+	if (dev == batt->dev)
+		return 0;
+
+	return -1;
+}
+
+static void battery_free(gpointer user_data)
+{
+	struct battery *batt = user_data;
+
+	btd_device_unref(batt->dev);
+	g_free(batt);
+}
+
+
+int battery_register(struct btd_device *device)
+{
+	struct battery *batt;
+
+	batt = g_new0(struct battery, 1);
+	batt->dev = btd_device_ref(device);
+
+	servers = g_slist_prepend(servers, batt);
+
+	return 0;
+}
+
+void battery_unregister(struct btd_device *device)
+{
+	struct battery *batt;
+	GSList *l;
+
+	l = g_slist_find_custom(servers, device, cmp_device);
+	if (l == NULL)
+		return;
+
+	batt = l->data;
+	servers = g_slist_remove(servers, batt);
+
+	battery_free(batt);
+}
diff --git a/profiles/battery/battery.h b/profiles/battery/battery.h
new file mode 100644
index 0000000..9933343
--- /dev/null
+++ b/profiles/battery/battery.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int battery_register(struct btd_device *device);
+void battery_unregister(struct btd_device *device);
diff --git a/profiles/battery/main.c b/profiles/battery/main.c
new file mode 100644
index 0000000..d4a23c9
--- /dev/null
+++ b/profiles/battery/main.c
@@ -0,0 +1,52 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+#include <glib.h>
+#include <errno.h>
+
+#include "hcid.h"
+#include "plugin.h"
+#include "manager.h"
+#include "log.h"
+
+static int battery_init(void)
+{
+	if (!main_opts.gatt_enabled) {
+		error("GATT is disabled");
+		return -ENOTSUP;
+	}
+
+	return battery_manager_init();
+}
+
+static void battery_exit(void)
+{
+	battery_manager_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(battery, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+						battery_init, battery_exit)
diff --git a/profiles/battery/manager.c b/profiles/battery/manager.c
new file mode 100644
index 0000000..9abb31a
--- /dev/null
+++ b/profiles/battery/manager.c
@@ -0,0 +1,62 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <glib.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+#include <stdbool.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "profile.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "battery.h"
+#include "manager.h"
+
+static int battery_driver_probe(struct btd_device *device, GSList *uuids)
+{
+	return battery_register(device);
+}
+
+static void battery_driver_remove(struct btd_device *device)
+{
+	battery_unregister(device);
+}
+
+static struct btd_profile battery_profile = {
+	.name		= "battery",
+	.remote_uuids	= BTD_UUIDS(BATTERY_SERVICE_UUID),
+	.device_probe	= battery_driver_probe,
+	.device_remove	= battery_driver_remove
+};
+
+int battery_manager_init(void)
+{
+	return btd_profile_register(&battery_profile);
+}
+
+void battery_manager_exit(void)
+{
+	btd_profile_unregister(&battery_profile);
+}
diff --git a/profiles/battery/manager.h b/profiles/battery/manager.h
new file mode 100644
index 0000000..b2c849f
--- /dev/null
+++ b/profiles/battery/manager.h
@@ -0,0 +1,24 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+int battery_manager_init(void);
+void battery_manager_exit(void);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 04/10] battery: Add client connection logic
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (2 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 03/10] battery: Add GATT Battery Client Service skeleton chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 05/10] battery: Discover Characteristic Descriptors chen.ganir
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Add connection logic to the Battery Plugin. When the driver is
loaded, it will request a connection to the remote device and
release the connection request when destroyed.
---
 profiles/battery/battery.c |   90 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 7702e39..5e52275 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -30,17 +30,28 @@
 
 #include "adapter.h"
 #include "device.h"
+#include "gattrib.h"
+#include "attio.h"
 #include "att.h"
 #include "gattrib.h"
 #include "gatt.h"
 #include "battery.h"
+#include "log.h"
 
 struct battery {
 	struct btd_device	*dev;		/* Device reference */
+	GAttrib			*attrib;	/* GATT connection */
+	guint			attioid;	/* Att watcher id */
+	struct att_range	*svc_range;	/* Battery range */
+	GSList			*chars;		/* Characteristics */
 };
 
 static GSList *servers;
 
+struct characteristic {
+	struct gatt_char	attr;		/* Characteristic */
+	struct battery		*batt;		/* Parent Battery Service */
+};
 static gint cmp_device(gconstpointer a, gconstpointer b)
 {
 	const struct battery *batt = a;
@@ -56,20 +67,99 @@ static void battery_free(gpointer user_data)
 {
 	struct battery *batt = user_data;
 
+	if (batt->chars != NULL)
+		g_slist_free_full(batt->chars, g_free);
+
+	if (batt->attioid > 0)
+		btd_device_remove_attio_callback(batt->dev, batt->attioid);
+
+	if (batt->attrib != NULL)
+		g_attrib_unref(batt->attrib);
+
 	btd_device_unref(batt->dev);
 	g_free(batt);
 }
 
+static void configure_battery_cb(GSList *characteristics, guint8 status,
+							gpointer user_data)
+{
+	struct battery *batt = user_data;
+	GSList *l;
+
+	if (status != 0) {
+		error("Discover Battery characteristics: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	for (l = characteristics; l; l = l->next) {
+		struct gatt_char *c = l->data;
+		struct characteristic *ch;
+
+		ch = g_new0(struct characteristic, 1);
+		ch->attr.handle = c->handle;
+		ch->attr.properties = c->properties;
+		ch->attr.value_handle = c->value_handle;
+		memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
+		ch->batt = batt;
+
+		batt->chars = g_slist_append(batt->chars, ch);
+	}
+}
+
+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+	struct battery *batt = user_data;
+
+	batt->attrib = g_attrib_ref(attrib);
+
+	if (batt->chars == NULL) {
+		gatt_discover_char(batt->attrib, batt->svc_range->start,
+					batt->svc_range->end, NULL,
+					configure_battery_cb, batt);
+	}
+}
+
+static void attio_disconnected_cb(gpointer user_data)
+{
+	struct battery *batt = user_data;
+
+	g_attrib_unref(batt->attrib);
+	batt->attrib = NULL;
+}
+
+static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct gatt_primary *prim = a;
+	const char *uuid = b;
+
+	return g_strcmp0(prim->uuid, uuid);
+}
 
 int battery_register(struct btd_device *device)
 {
 	struct battery *batt;
+	struct gatt_primary *prim;
+	GSList *primaries, *l;
+
+	primaries = btd_device_get_primaries(device);
+
+	l = g_slist_find_custom(primaries, BATTERY_SERVICE_UUID,
+							primary_uuid_cmp);
+	prim = l->data;
 
 	batt = g_new0(struct battery, 1);
 	batt->dev = btd_device_ref(device);
 
+	batt->svc_range = g_new0(struct att_range, 1);
+	batt->svc_range->start = prim->range.start;
+	batt->svc_range->end = prim->range.end;
+
 	servers = g_slist_prepend(servers, batt);
 
+	batt->attioid = btd_device_add_attio_callback(device,
+				attio_connected_cb, attio_disconnected_cb,
+				batt);
 	return 0;
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 05/10] battery: Discover Characteristic Descriptors
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (3 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 04/10] battery: Add client connection logic chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 06/10] battery: Get Battery ID chen.ganir
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Discover all characteristic descriptors, and build a descriptor
list. Presentation Format Descriptor and Client Characteristic
Configuration descriptors are searched.
---
 profiles/battery/battery.c |   73 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 72 insertions(+), 1 deletion(-)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 5e52275..dada15b 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -51,7 +51,15 @@ static GSList *servers;
 struct characteristic {
 	struct gatt_char	attr;		/* Characteristic */
 	struct battery		*batt;		/* Parent Battery Service */
+	GSList			*desc;		/* Descriptors */
 };
+
+struct descriptor {
+	struct characteristic	*ch;		/* Parent Characteristic */
+	uint16_t		handle;		/* Descriptor Handle */
+	bt_uuid_t		uuid;		/* UUID */
+};
+
 static gint cmp_device(gconstpointer a, gconstpointer b)
 {
 	const struct battery *batt = a;
@@ -63,12 +71,21 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
 	return -1;
 }
 
+static void char_free(gpointer user_data)
+{
+	struct characteristic *c = user_data;
+
+	g_slist_free_full(c->desc, g_free);
+
+	g_free(c);
+}
+
 static void battery_free(gpointer user_data)
 {
 	struct battery *batt = user_data;
 
 	if (batt->chars != NULL)
-		g_slist_free_full(batt->chars, g_free);
+		g_slist_free_full(batt->chars, char_free);
 
 	if (batt->attioid > 0)
 		btd_device_remove_attio_callback(batt->dev, batt->attioid);
@@ -77,9 +94,48 @@ static void battery_free(gpointer user_data)
 		g_attrib_unref(batt->attrib);
 
 	btd_device_unref(batt->dev);
+	g_free(batt->svc_range);
 	g_free(batt);
 }
 
+static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct characteristic *ch = user_data;
+	struct att_data_list *list;
+	uint8_t format;
+	int i;
+
+	if (status != 0) {
+		error("Discover all characteristic descriptors failed [%s]: %s",
+					ch->attr.uuid, att_ecode2str(status));
+		return;
+	}
+
+	list = dec_find_info_resp(pdu, len, &format);
+	if (list == NULL)
+		return;
+
+	for (i = 0; i < list->num; i++) {
+		struct descriptor *desc;
+		uint8_t *value;
+
+		value = list->data[i];
+		desc = g_new0(struct descriptor, 1);
+		desc->handle = att_get_u16(value);
+		desc->ch = ch;
+
+		if (format == 0x01)
+			desc->uuid = att_get_uuid16(&value[2]);
+		else
+			desc->uuid = att_get_uuid128(&value[2]);
+
+		ch->desc = g_slist_append(ch->desc, desc);
+	}
+
+	att_data_list_free(list);
+}
+
 static void configure_battery_cb(GSList *characteristics, guint8 status,
 							gpointer user_data)
 {
@@ -95,6 +151,7 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 	for (l = characteristics; l; l = l->next) {
 		struct gatt_char *c = l->data;
 		struct characteristic *ch;
+		uint16_t start, end;
 
 		ch = g_new0(struct characteristic, 1);
 		ch->attr.handle = c->handle;
@@ -104,6 +161,20 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 		ch->batt = batt;
 
 		batt->chars = g_slist_append(batt->chars, ch);
+
+		start = c->value_handle + 1;
+
+		if (l->next != NULL) {
+			struct gatt_char *c = l->next->data;
+			if (start == c->handle)
+				continue;
+			end = c->handle - 1;
+		} else if (c->value_handle != batt->svc_range->end)
+			end = batt->svc_range->end;
+		else
+			continue;
+
+		gatt_find_info(batt->attrib, start, end, discover_desc_cb, ch);
 	}
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 06/10] battery: Get Battery ID
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (4 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 05/10] battery: Discover Characteristic Descriptors chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20 10:46   ` Anderson Lizardo
  2012-09-20  8:27 ` [PATCH v3 07/10] battery: Add Battery to device chen.ganir
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Read the battery level format characteristic descriptor to get the
unique namespace and description values.
---
 lib/uuid.h                 |    1 +
 profiles/battery/battery.c |   98 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 77 insertions(+), 22 deletions(-)

diff --git a/lib/uuid.h b/lib/uuid.h
index 58ad0b3..5c1b3ff 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -57,6 +57,7 @@ extern "C" {
 #define DEVICE_INFORMATION_UUID	"0000180a-0000-1000-8000-00805f9b34fb"
 
 #define BATTERY_SERVICE_UUID	"0000180f-0000-1000-8000-00805f9b34fb"
+#define BATTERY_LEVEL_UUID	"00002a19-0000-1000-8000-00805f9b34fb"
 
 #define GATT_UUID		"00001801-0000-1000-8000-00805f9b34fb"
 #define IMMEDIATE_ALERT_UUID	"00001802-0000-1000-8000-00805f9b34fb"
diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index dada15b..a3a1bb0 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -52,6 +52,8 @@ struct characteristic {
 	struct gatt_char	attr;		/* Characteristic */
 	struct battery		*batt;		/* Parent Battery Service */
 	GSList			*desc;		/* Descriptors */
+	uint8_t			ns;		/* Battery Namespace */
+	uint16_t		description;	/* Battery description */
 };
 
 struct descriptor {
@@ -98,6 +100,53 @@ static void battery_free(gpointer user_data)
 	g_free(batt);
 }
 
+static void batterylevel_presentation_format_desc_cb(guint8 status,
+						const guint8 *pdu, guint16 len,
+						gpointer user_data)
+{
+	struct descriptor *desc = user_data;
+	uint8_t value[ATT_MAX_MTU];
+	int vlen;
+
+	if (status != 0) {
+		error("Presentation Format desc read failed: %s",
+							att_ecode2str(status));
+		return;
+	}
+
+	vlen = dec_read_resp(pdu, len, value, sizeof(value));
+	if (vlen < 0) {
+		error("Presentation Format desc read failed: Protocol error");
+		return;
+	}
+
+	if (vlen < 7) {
+		error("Presentation Format desc read failed: Invalid range");
+		return;
+	}
+
+	desc->ch->ns = value[4];
+	desc->ch->description = att_get_u16(&value[5]);
+}
+
+static void process_batterylevel_desc(struct descriptor *desc)
+{
+	struct characteristic *ch = desc->ch;
+	char uuidstr[MAX_LEN_UUID_STR];
+	bt_uuid_t btuuid;
+
+	bt_uuid16_create(&btuuid, GATT_CHARAC_FMT_UUID);
+
+	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0) {
+		gatt_read_char(ch->batt->attrib, desc->handle, 0,
+				batterylevel_presentation_format_desc_cb, desc);
+		return;
+	}
+
+	bt_uuid_to_string(&desc->uuid, uuidstr, MAX_LEN_UUID_STR);
+	DBG("Ignored descriptor %s characteristic %s", uuidstr,	ch->attr.uuid);
+}
+
 static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
 							gpointer user_data)
 {
@@ -131,6 +180,7 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
 			desc->uuid = att_get_uuid128(&value[2]);
 
 		ch->desc = g_slist_append(ch->desc, desc);
+		process_batterylevel_desc(desc);
 	}
 
 	att_data_list_free(list);
@@ -150,31 +200,35 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 
 	for (l = characteristics; l; l = l->next) {
 		struct gatt_char *c = l->data;
-		struct characteristic *ch;
-		uint16_t start, end;
-
-		ch = g_new0(struct characteristic, 1);
-		ch->attr.handle = c->handle;
-		ch->attr.properties = c->properties;
-		ch->attr.value_handle = c->value_handle;
-		memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
-		ch->batt = batt;
 
-		batt->chars = g_slist_append(batt->chars, ch);
-
-		start = c->value_handle + 1;
-
-		if (l->next != NULL) {
-			struct gatt_char *c = l->next->data;
-			if (start == c->handle)
+		if (g_strcmp0(c->uuid, BATTERY_LEVEL_UUID) == 0) {
+			struct characteristic *ch;
+			uint16_t start, end;
+
+			ch = g_new0(struct characteristic, 1);
+			ch->attr.handle = c->handle;
+			ch->attr.properties = c->properties;
+			ch->attr.value_handle = c->value_handle;
+			memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
+			ch->batt = batt;
+
+			batt->chars = g_slist_append(batt->chars, ch);
+
+			start = c->value_handle + 1;
+
+			if (l->next != NULL) {
+				struct gatt_char *c = l->next->data;
+				if (start == c->handle)
+					continue;
+				end = c->handle - 1;
+			} else if (c->value_handle != batt->svc_range->end)
+				end = batt->svc_range->end;
+			else
 				continue;
-			end = c->handle - 1;
-		} else if (c->value_handle != batt->svc_range->end)
-			end = batt->svc_range->end;
-		else
-			continue;
 
-		gatt_find_info(batt->attrib, start, end, discover_desc_cb, ch);
+			gatt_find_info(batt->attrib, start, end,
+							discover_desc_cb, ch);
+		}
 	}
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 07/10] battery: Add Battery to device
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (5 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 06/10] battery: Get Battery ID chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 08/10] battery: Read Battery level characteristic chen.ganir
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Add/Remove battery from device
---
 profiles/battery/battery.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index a3a1bb0..6a6635b 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -49,6 +49,7 @@ struct battery {
 static GSList *servers;
 
 struct characteristic {
+	struct btd_battery	*devbatt;	/* device_battery pointer */
 	struct gatt_char	attr;		/* Characteristic */
 	struct battery		*batt;		/* Parent Battery Service */
 	GSList			*desc;		/* Descriptors */
@@ -79,6 +80,8 @@ static void char_free(gpointer user_data)
 
 	g_slist_free_full(c->desc, g_free);
 
+	btd_device_remove_battery(c->devbatt);
+
 	g_free(c);
 }
 
@@ -216,6 +219,8 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 
 			start = c->value_handle + 1;
 
+			ch->devbatt = btd_device_add_battery(ch->batt->dev);
+
 			if (l->next != NULL) {
 				struct gatt_char *c = l->next->data;
 				if (start == c->handle)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 08/10] battery: Read Battery level characteristic
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (6 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 07/10] battery: Add Battery to device chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20  8:27 ` [PATCH v3 09/10] battery: Add support for notifications chen.ganir
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Implement support for reading the battery level characteristic on
connection establishment.
---
 profiles/battery/battery.c |   86 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 6a6635b..d681e2d 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -55,6 +55,7 @@ struct characteristic {
 	GSList			*desc;		/* Descriptors */
 	uint8_t			ns;		/* Battery Namespace */
 	uint16_t		description;	/* Battery description */
+	uint8_t			level;		/* Battery level */
 };
 
 struct descriptor {
@@ -103,6 +104,78 @@ static void battery_free(gpointer user_data)
 	g_free(batt);
 }
 
+static void read_batterylevel_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct characteristic *ch = user_data;
+	uint8_t value[ATT_MAX_MTU];
+	int vlen;
+
+	if (status != 0) {
+		error("Failed to read Battery Level:%s", att_ecode2str(status));
+		return;
+	}
+
+	vlen = dec_read_resp(pdu, len, value, sizeof(value));
+	if (vlen < 0) {
+		error("Failed to read Battery Level: Protocol error");
+		return;
+	}
+
+	if (vlen != 1) {
+		error("Failed to read Battery Level: Wrong pdu len");
+		return;
+	}
+
+	ch->level = value[0];
+	btd_device_set_battery_opt(ch->devbatt, BATTERY_OPT_LEVEL, ch->level,
+						BATTERY_OPT_INVALID);
+}
+
+static void process_batteryservice_char(struct characteristic *ch)
+{
+	if (g_strcmp0(ch->attr.uuid, BATTERY_LEVEL_UUID) == 0) {
+		gatt_read_char(ch->batt->attrib, ch->attr.value_handle, 0,
+						read_batterylevel_cb, ch);
+	}
+}
+
+static gint device_battery_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct characteristic *ch = a;
+	const struct btd_battery *batt = b;
+
+	if (batt == ch->devbatt)
+		return 0;
+
+	return -1;
+}
+
+static struct characteristic *find_battery_char(struct btd_battery *db)
+{
+	GSList *l, *b;
+
+	for (l = servers; l != NULL; l = g_slist_next(l)) {
+		struct battery *batt = l->data;
+
+		b = g_slist_find_custom(batt->chars, db, device_battery_cmp);
+		if (b)
+			return b->data;
+	}
+
+	return NULL;
+}
+
+static void batterylevel_refresh_cb(struct btd_battery *batt)
+{
+	struct characteristic *ch;
+
+	ch = find_battery_char(batt);
+
+	if (ch)
+		process_batteryservice_char(ch);
+}
+
 static void batterylevel_presentation_format_desc_cb(guint8 status,
 						const guint8 *pdu, guint16 len,
 						gpointer user_data)
@@ -219,8 +292,15 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 
 			start = c->value_handle + 1;
 
+			process_batteryservice_char(ch);
+
 			ch->devbatt = btd_device_add_battery(ch->batt->dev);
 
+			btd_device_set_battery_opt(ch->devbatt,
+						   BATTERY_OPT_REFRESH_FUNC,
+						   batterylevel_refresh_cb,
+						   BATTERY_OPT_INVALID);
+
 			if (l->next != NULL) {
 				struct gatt_char *c = l->next->data;
 				if (start == c->handle)
@@ -247,6 +327,12 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 		gatt_discover_char(batt->attrib, batt->svc_range->start,
 					batt->svc_range->end, NULL,
 					configure_battery_cb, batt);
+	} else {
+		GSList *l;
+		for (l = batt->chars; l; l = l->next) {
+			struct characteristic *c = l->data;
+			process_batteryservice_char(c);
+		}
 	}
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 09/10] battery: Add support for notifications
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (7 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 08/10] battery: Read Battery level characteristic chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20 10:54   ` Anderson Lizardo
  2012-09-20  8:27 ` [PATCH v3 10/10] battery: Support persistent battery level chen.ganir
  2012-09-20 10:56 ` [PATCH v3 00/10] Implement Generic battery and LE Battery client Anderson Lizardo
  10 siblings, 1 reply; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Add support for emitting PropertyChanged when a battery level
characteristic notification is sent from the peer device.
---
 profiles/battery/battery.c |   98 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 2 deletions(-)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index d681e2d..fce7724 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -43,6 +43,7 @@ struct battery {
 	GAttrib			*attrib;	/* GATT connection */
 	guint			attioid;	/* Att watcher id */
 	struct att_range	*svc_range;	/* Battery range */
+	guint                   attnotid;       /* Att notifications id */
 	GSList			*chars;		/* Characteristics */
 };
 
@@ -56,6 +57,7 @@ struct characteristic {
 	uint8_t			ns;		/* Battery Namespace */
 	uint16_t		description;	/* Battery description */
 	uint8_t			level;		/* Battery level */
+	gboolean		canNotify;	/* Char can notify flag */
 };
 
 struct descriptor {
@@ -86,6 +88,14 @@ static void char_free(gpointer user_data)
 	g_free(c);
 }
 
+static gint cmp_char_val_handle(gconstpointer a, gconstpointer b)
+{
+	const struct characteristic *ch = a;
+	const uint16_t *handle = b;
+
+	return ch->attr.value_handle - *handle;
+}
+
 static void battery_free(gpointer user_data)
 {
 	struct battery *batt = user_data;
@@ -96,8 +106,14 @@ static void battery_free(gpointer user_data)
 	if (batt->attioid > 0)
 		btd_device_remove_attio_callback(batt->dev, batt->attioid);
 
-	if (batt->attrib != NULL)
+	if (batt->attrib != NULL) {
+		if (batt->attnotid) {
+			g_attrib_unregister(batt->attrib, batt->attnotid);
+			batt->attnotid = 0;
+		}
+
 		g_attrib_unref(batt->attrib);
+	}
 
 	btd_device_unref(batt->dev);
 	g_free(batt->svc_range);
@@ -140,6 +156,18 @@ static void process_batteryservice_char(struct characteristic *ch)
 	}
 }
 
+static void batterylevel_enable_notify_cb(guint8 status, const guint8 *pdu,
+						guint16 len, gpointer user_data)
+{
+	struct characteristic *ch = (struct characteristic *)user_data;
+
+	if (status != 0) {
+		error("Could not enable batt level notification.");
+		ch->canNotify = FALSE;
+		process_batteryservice_char(ch);
+	}
+}
+
 static gint device_battery_cmp(gconstpointer a, gconstpointer b)
 {
 	const struct characteristic *ch = a;
@@ -176,6 +204,19 @@ static void batterylevel_refresh_cb(struct btd_battery *batt)
 		process_batteryservice_char(ch);
 }
 
+static void enable_battery_notification(struct characteristic *ch,
+								uint16_t handle)
+{
+	uint8_t atval[2];
+	uint16_t val;
+
+	val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
+
+	att_put_u16(val, atval);
+	gatt_write_char(ch->batt->attrib, handle, atval, 2,
+				batterylevel_enable_notify_cb, ch);
+}
+
 static void batterylevel_presentation_format_desc_cb(guint8 status,
 						const guint8 *pdu, guint16 len,
 						gpointer user_data)
@@ -211,6 +252,14 @@ static void process_batterylevel_desc(struct descriptor *desc)
 	char uuidstr[MAX_LEN_UUID_STR];
 	bt_uuid_t btuuid;
 
+	bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+
+	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0 && g_strcmp0(ch->attr.uuid,
+						BATTERY_LEVEL_UUID) == 0) {
+		enable_battery_notification(ch, desc->handle);
+		return;
+	}
+
 	bt_uuid16_create(&btuuid, GATT_CHARAC_FMT_UUID);
 
 	if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0) {
@@ -317,12 +366,54 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 	}
 }
 
+static void proc_batterylevel(struct characteristic *c, const uint8_t *pdu,
+						uint16_t len, gboolean final)
+{
+	if (!pdu) {
+		error("Battery level notification: Invalid pdu length");
+		return;
+	}
+
+	c->level = pdu[1];
+
+	btd_device_set_battery_opt(c->devbatt, BATTERY_OPT_LEVEL, c->level,
+							BATTERY_OPT_INVALID);
+}
+
+static void notif_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
+{
+	struct battery *batt = user_data;
+	struct characteristic *ch;
+	uint16_t handle;
+	GSList *l;
+
+	if (len < 3) {
+		error("notif_handler: Bad pdu received");
+		return;
+	}
+
+	handle = att_get_u16(&pdu[1]);
+	l = g_slist_find_custom(batt->chars, &handle, cmp_char_val_handle);
+	if (l == NULL) {
+		error("notif_handler: Unexpected handle 0x%04x", handle);
+		return;
+	}
+
+	ch = l->data;
+	if (g_strcmp0(ch->attr.uuid, BATTERY_LEVEL_UUID) == 0) {
+		proc_batterylevel(ch, pdu, len, FALSE);
+	}
+}
+
 static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 {
 	struct battery *batt = user_data;
 
 	batt->attrib = g_attrib_ref(attrib);
 
+	batt->attnotid = g_attrib_register(batt->attrib, ATT_OP_HANDLE_NOTIFY,
+						notif_handler, batt, NULL);
+
 	if (batt->chars == NULL) {
 		gatt_discover_char(batt->attrib, batt->svc_range->start,
 					batt->svc_range->end, NULL,
@@ -331,7 +422,8 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 		GSList *l;
 		for (l = batt->chars; l; l = l->next) {
 			struct characteristic *c = l->data;
-			process_batteryservice_char(c);
+			if (!c->canNotify)
+				process_batteryservice_char(c);
 		}
 	}
 }
@@ -340,6 +432,8 @@ static void attio_disconnected_cb(gpointer user_data)
 {
 	struct battery *batt = user_data;
 
+	g_attrib_unregister(batt->attrib, batt->attnotid);
+	batt->attnotid = 0;
 	g_attrib_unref(batt->attrib);
 	batt->attrib = NULL;
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 10/10] battery: Support persistent battery level
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (8 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 09/10] battery: Add support for notifications chen.ganir
@ 2012-09-20  8:27 ` chen.ganir
  2012-09-20 10:56 ` [PATCH v3 00/10] Implement Generic battery and LE Battery client Anderson Lizardo
  10 siblings, 0 replies; 17+ messages in thread
From: chen.ganir @ 2012-09-20  8:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: chen.ganir

From: Chen Ganir <chen.ganir@ti.com>

Store battery level when read, and use the level from storage
when connecting, to reduce GATT traffic.
---
 profiles/battery/battery.c |  107 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 106 insertions(+), 1 deletion(-)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index fce7724..f97ee9c 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -27,6 +27,8 @@
 #include <glib.h>
 #include <bluetooth/uuid.h>
 #include <stdbool.h>
+#include <sys/file.h>
+#include <stdlib.h>
 
 #include "adapter.h"
 #include "device.h"
@@ -37,6 +39,10 @@
 #include "gatt.h"
 #include "battery.h"
 #include "log.h"
+#include "storage.h"
+
+#define BATTERY_KEY_FORMAT	"%17s#%04X"
+#define BATTERY_LEVEL_FORMAT	"%03d"
 
 struct battery {
 	struct btd_device	*dev;		/* Device reference */
@@ -77,10 +83,103 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
 	return -1;
 }
 
+static inline int create_filename(char *buf, size_t size,
+				const bdaddr_t *bdaddr, const char *name)
+{
+	char addr[18];
+
+	ba2str(bdaddr, addr);
+
+	return create_name(buf, size, STORAGEDIR, addr, name);
+}
+
+static int store_battery_char(struct characteristic *chr)
+{
+	char filename[PATH_MAX + 1], addr[18], key[23];
+	bdaddr_t sba, dba;
+	char level[4];
+
+	adapter_get_address(device_get_adapter(chr->batt->dev), &sba);
+	device_get_address(chr->batt->dev, &dba, NULL);
+
+	create_filename(filename, PATH_MAX, &sba, "battery_gatt_client");
+
+	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+	ba2str(&dba, addr);
+
+	snprintf(key, sizeof(key), BATTERY_KEY_FORMAT, addr, chr->attr.handle);
+	snprintf(level, sizeof(level), BATTERY_LEVEL_FORMAT, chr->level);
+
+	return textfile_caseput(filename, key, level);
+}
+
+static char *read_battery_char(struct characteristic *chr)
+{
+	char filename[PATH_MAX + 1], addr[18], key[23];
+	char *str, *strnew;
+	bdaddr_t sba, dba;
+
+	adapter_get_address(device_get_adapter(chr->batt->dev), &sba);
+	device_get_address(chr->batt->dev, &dba, NULL);
+
+	create_filename(filename, PATH_MAX, &sba, "battery_gatt_client");
+
+	ba2str(&dba, addr);
+	snprintf(key, sizeof(key), BATTERY_KEY_FORMAT, addr, chr->attr.handle);
+
+	str = textfile_caseget(filename, key);
+	if (str == NULL)
+		return NULL;
+
+	strnew = g_strdup(str);
+	g_free(str);
+
+	return strnew;
+}
+
+static void del_battery_char(struct characteristic *chr)
+{
+	char filename[PATH_MAX + 1], addr[18], key[23];
+	bdaddr_t sba, dba;
+
+	adapter_get_address(device_get_adapter(chr->batt->dev), &sba);
+	device_get_address(chr->batt->dev, &dba, NULL);
+
+	create_filename(filename, PATH_MAX, &sba, "battery_gatt_client");
+
+	ba2str(&dba, addr);
+	snprintf(key, sizeof(key), BATTERY_KEY_FORMAT, addr, chr->attr.handle);
+
+	textfile_casedel(filename, key);
+}
+
+static gboolean read_battery_level_value(struct characteristic *chr)
+{
+	char *str;
+
+	if (!chr)
+		return FALSE;
+
+	str = read_battery_char(chr);
+	if (!str)
+		return FALSE;
+
+	chr->level = atoi(str);
+
+	btd_device_set_battery_opt(chr->devbatt, BATTERY_OPT_LEVEL, chr->level,
+						BATTERY_OPT_INVALID);
+
+	g_free(str);
+	return TRUE;
+}
+
 static void char_free(gpointer user_data)
 {
 	struct characteristic *c = user_data;
 
+	del_battery_char(c);
+
 	g_slist_free_full(c->desc, g_free);
 
 	btd_device_remove_battery(c->devbatt);
@@ -146,6 +245,8 @@ static void read_batterylevel_cb(guint8 status, const guint8 *pdu, guint16 len,
 	ch->level = value[0];
 	btd_device_set_battery_opt(ch->devbatt, BATTERY_OPT_LEVEL, ch->level,
 						BATTERY_OPT_INVALID);
+
+	store_battery_char(ch);
 }
 
 static void process_batteryservice_char(struct characteristic *ch)
@@ -309,6 +410,7 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
 	}
 
 	att_data_list_free(list);
+
 }
 
 static void configure_battery_cb(GSList *characteristics, guint8 status,
@@ -345,6 +447,9 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
 
 			ch->devbatt = btd_device_add_battery(ch->batt->dev);
 
+			if (!read_battery_level_value(ch))
+				process_batteryservice_char(ch);
+
 			btd_device_set_battery_opt(ch->devbatt,
 						   BATTERY_OPT_REFRESH_FUNC,
 						   batterylevel_refresh_cb,
@@ -422,7 +527,7 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 		GSList *l;
 		for (l = batt->chars; l; l = l->next) {
 			struct characteristic *c = l->data;
-			if (!c->canNotify)
+			if (!read_battery_level_value(c) && !c->canNotify)
 				process_batteryservice_char(c);
 		}
 	}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 06/10] battery: Get Battery ID
  2012-09-20  8:27 ` [PATCH v3 06/10] battery: Get Battery ID chen.ganir
@ 2012-09-20 10:46   ` Anderson Lizardo
  2012-09-20 11:03     ` Chen Ganir
  0 siblings, 1 reply; 17+ messages in thread
From: Anderson Lizardo @ 2012-09-20 10:46 UTC (permalink / raw)
  To: chen.ganir; +Cc: linux-bluetooth

Hi Chen,

On Thu, Sep 20, 2012 at 4:27 AM,  <chen.ganir@ti.com> wrote:
> @@ -150,31 +200,35 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
>
>         for (l = characteristics; l; l = l->next) {
>                 struct gatt_char *c = l->data;
> -               struct characteristic *ch;
> -               uint16_t start, end;
> -
> -               ch = g_new0(struct characteristic, 1);
> -               ch->attr.handle = c->handle;
> -               ch->attr.properties = c->properties;
> -               ch->attr.value_handle = c->value_handle;
> -               memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
> -               ch->batt = batt;
>
> -               batt->chars = g_slist_append(batt->chars, ch);
> -
> -               start = c->value_handle + 1;
> -
> -               if (l->next != NULL) {
> -                       struct gatt_char *c = l->next->data;
> -                       if (start == c->handle)
> +               if (g_strcmp0(c->uuid, BATTERY_LEVEL_UUID) == 0) {

Minor comment, but looks like it would be cleaner if you used:

if (g_strcmp0(c->uuid, BATTERY_LEVEL_UUID) != 0)
    continue;

and avoided all this shifting and one more level of indentation.

> +                       struct characteristic *ch;
> +                       uint16_t start, end;
> +
> +                       ch = g_new0(struct characteristic, 1);
> +                       ch->attr.handle = c->handle;
> +                       ch->attr.properties = c->properties;
> +                       ch->attr.value_handle = c->value_handle;
> +                       memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
> +                       ch->batt = batt;
> +
> +                       batt->chars = g_slist_append(batt->chars, ch);
> +
> +                       start = c->value_handle + 1;
> +
> +                       if (l->next != NULL) {
> +                               struct gatt_char *c = l->next->data;
> +                               if (start == c->handle)
> +                                       continue;
> +                               end = c->handle - 1;
> +                       } else if (c->value_handle != batt->svc_range->end)
> +                               end = batt->svc_range->end;
> +                       else
>                                 continue;
> -                       end = c->handle - 1;
> -               } else if (c->value_handle != batt->svc_range->end)
> -                       end = batt->svc_range->end;
> -               else
> -                       continue;
>
> -               gatt_find_info(batt->attrib, start, end, discover_desc_cb, ch);
> +                       gatt_find_info(batt->attrib, start, end,
> +                                                       discover_desc_cb, ch);
> +               }
>         }
>  }

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 09/10] battery: Add support for notifications
  2012-09-20  8:27 ` [PATCH v3 09/10] battery: Add support for notifications chen.ganir
@ 2012-09-20 10:54   ` Anderson Lizardo
  2012-09-20 11:00     ` Chen Ganir
  0 siblings, 1 reply; 17+ messages in thread
From: Anderson Lizardo @ 2012-09-20 10:54 UTC (permalink / raw)
  To: chen.ganir; +Cc: linux-bluetooth

Hi Chen,

On Thu, Sep 20, 2012 at 4:27 AM,  <chen.ganir@ti.com> wrote:
> @@ -140,6 +156,18 @@ static void process_batteryservice_char(struct characteristic *ch)
>         }
>  }
>
> +static void batterylevel_enable_notify_cb(guint8 status, const guint8 *pdu,
> +                                               guint16 len, gpointer user_data)
> +{
> +       struct characteristic *ch = (struct characteristic *)user_data;

Casting above seems unnecessary (gpointer is typedef to void*).

> +
> +       if (status != 0) {
> +               error("Could not enable batt level notification.");
> +               ch->canNotify = FALSE;

This camelCase is inconsistent with other struct fields on the same file.

> +               process_batteryservice_char(ch);
> +       }
> +}
> +
>  static gint device_battery_cmp(gconstpointer a, gconstpointer b)
>  {
>         const struct characteristic *ch = a;

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 00/10] Implement Generic battery and LE Battery client
  2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
                   ` (9 preceding siblings ...)
  2012-09-20  8:27 ` [PATCH v3 10/10] battery: Support persistent battery level chen.ganir
@ 2012-09-20 10:56 ` Anderson Lizardo
  2012-09-20 11:04   ` Chen Ganir
  10 siblings, 1 reply; 17+ messages in thread
From: Anderson Lizardo @ 2012-09-20 10:56 UTC (permalink / raw)
  To: chen.ganir; +Cc: linux-bluetooth

Hi Chen,

On Thu, Sep 20, 2012 at 4:27 AM,  <chen.ganir@ti.com> wrote:
> From: Chen Ganir <chen.ganir@ti.com>
>
> This patch set replaces previous patch sets which implemented the LE battery
> GATT Client. This patch set implements a generic device battery D-Bus interface
> that can be used to get remote device battery status using D-Bus. In addition,
> This patch set also implements the GATT Battery client, which uses the generic
> device battery to expose LE device battery status.
>
> see doc/battery-api.txt and doc/device-api.txt for more information.
>
> This is version 2 of the patch set, including multiple style and other comments
> reported on the ML. This version is rebased on the latest code.

Besides some minor style comments (found on this last round of
review), patch set looks good to me.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 09/10] battery: Add support for notifications
  2012-09-20 10:54   ` Anderson Lizardo
@ 2012-09-20 11:00     ` Chen Ganir
  0 siblings, 0 replies; 17+ messages in thread
From: Chen Ganir @ 2012-09-20 11:00 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth

Anderson,

On 09/20/2012 01:54 PM, Anderson Lizardo wrote:
> Hi Chen,
>
> On Thu, Sep 20, 2012 at 4:27 AM,  <chen.ganir@ti.com> wrote:
>> @@ -140,6 +156,18 @@ static void process_batteryservice_char(struct characteristic *ch)
>>          }
>>   }
>>
>> +static void batterylevel_enable_notify_cb(guint8 status, const guint8 *pdu,
>> +                                               guint16 len, gpointer user_data)
>> +{
>> +       struct characteristic *ch = (struct characteristic *)user_data;
>
> Casting above seems unnecessary (gpointer is typedef to void*).
>
I'll change that.

>> +
>> +       if (status != 0) {
>> +               error("Could not enable batt level notification.");
>> +               ch->canNotify = FALSE;
>
> This camelCase is inconsistent with other struct fields on the same file.
>
Will be changed.


>> +               process_batteryservice_char(ch);
>> +       }
>> +}
>> +
>>   static gint device_battery_cmp(gconstpointer a, gconstpointer b)
>>   {
>>          const struct characteristic *ch = a;
>
> Regards,
>

Thanks !

-- 
BR,
Chen Ganir


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 06/10] battery: Get Battery ID
  2012-09-20 10:46   ` Anderson Lizardo
@ 2012-09-20 11:03     ` Chen Ganir
  0 siblings, 0 replies; 17+ messages in thread
From: Chen Ganir @ 2012-09-20 11:03 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth

Anderson,

On 09/20/2012 01:46 PM, Anderson Lizardo wrote:
> Hi Chen,
>
> On Thu, Sep 20, 2012 at 4:27 AM,  <chen.ganir@ti.com> wrote:
>> @@ -150,31 +200,35 @@ static void configure_battery_cb(GSList *characteristics, guint8 status,
>>
>>          for (l = characteristics; l; l = l->next) {
>>                  struct gatt_char *c = l->data;
>> -               struct characteristic *ch;
>> -               uint16_t start, end;
>> -
>> -               ch = g_new0(struct characteristic, 1);
>> -               ch->attr.handle = c->handle;
>> -               ch->attr.properties = c->properties;
>> -               ch->attr.value_handle = c->value_handle;
>> -               memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
>> -               ch->batt = batt;
>>
>> -               batt->chars = g_slist_append(batt->chars, ch);
>> -
>> -               start = c->value_handle + 1;
>> -
>> -               if (l->next != NULL) {
>> -                       struct gatt_char *c = l->next->data;
>> -                       if (start == c->handle)
>> +               if (g_strcmp0(c->uuid, BATTERY_LEVEL_UUID) == 0) {
>
> Minor comment, but looks like it would be cleaner if you used:
>
> if (g_strcmp0(c->uuid, BATTERY_LEVEL_UUID) != 0)
>      continue;
>
> and avoided all this shifting and one more level of indentation.
>
I'll change that. It does make more sense.


>> +                       struct characteristic *ch;
>> +                       uint16_t start, end;
>> +
>> +                       ch = g_new0(struct characteristic, 1);
>> +                       ch->attr.handle = c->handle;
>> +                       ch->attr.properties = c->properties;
>> +                       ch->attr.value_handle = c->value_handle;
>> +                       memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
>> +                       ch->batt = batt;
>> +
>> +                       batt->chars = g_slist_append(batt->chars, ch);
>> +
>> +                       start = c->value_handle + 1;
>> +
>> +                       if (l->next != NULL) {
>> +                               struct gatt_char *c = l->next->data;
>> +                               if (start == c->handle)
>> +                                       continue;
>> +                               end = c->handle - 1;
>> +                       } else if (c->value_handle != batt->svc_range->end)
>> +                               end = batt->svc_range->end;
>> +                       else
>>                                  continue;
>> -                       end = c->handle - 1;
>> -               } else if (c->value_handle != batt->svc_range->end)
>> -                       end = batt->svc_range->end;
>> -               else
>> -                       continue;
>>
>> -               gatt_find_info(batt->attrib, start, end, discover_desc_cb, ch);
>> +                       gatt_find_info(batt->attrib, start, end,
>> +                                                       discover_desc_cb, ch);
>> +               }
>>          }
>>   }
>
> Regards,
>

Thanks,

-- 
BR,
Chen Ganir


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 00/10] Implement Generic battery and LE Battery client
  2012-09-20 10:56 ` [PATCH v3 00/10] Implement Generic battery and LE Battery client Anderson Lizardo
@ 2012-09-20 11:04   ` Chen Ganir
  0 siblings, 0 replies; 17+ messages in thread
From: Chen Ganir @ 2012-09-20 11:04 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth

Anderson,

On 09/20/2012 01:56 PM, Anderson Lizardo wrote:
> Hi Chen,
>
> On Thu, Sep 20, 2012 at 4:27 AM,  <chen.ganir@ti.com> wrote:
>> From: Chen Ganir <chen.ganir@ti.com>
>>
>> This patch set replaces previous patch sets which implemented the LE battery
>> GATT Client. This patch set implements a generic device battery D-Bus interface
>> that can be used to get remote device battery status using D-Bus. In addition,
>> This patch set also implements the GATT Battery client, which uses the generic
>> device battery to expose LE device battery status.
>>
>> see doc/battery-api.txt and doc/device-api.txt for more information.
>>
>> This is version 2 of the patch set, including multiple style and other comments
>> reported on the ML. This version is rebased on the latest code.
>
> Besides some minor style comments (found on this last round of
> review), patch set looks good to me.
>
> Regards,
>
Thanks for the review !

I'll wait and see if there are any more comments before i send the next 
patch set with fixes.


-- 
BR,
Chen Ganir


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-09-20 11:04 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-20  8:27 [PATCH v3 00/10] Implement Generic battery and LE Battery client chen.ganir
2012-09-20  8:27 ` [PATCH v3 01/10] battery: Add generic device battery documentation chen.ganir
2012-09-20  8:27 ` [PATCH v3 02/10] battery: Implement Generic device battery chen.ganir
2012-09-20  8:27 ` [PATCH v3 03/10] battery: Add GATT Battery Client Service skeleton chen.ganir
2012-09-20  8:27 ` [PATCH v3 04/10] battery: Add client connection logic chen.ganir
2012-09-20  8:27 ` [PATCH v3 05/10] battery: Discover Characteristic Descriptors chen.ganir
2012-09-20  8:27 ` [PATCH v3 06/10] battery: Get Battery ID chen.ganir
2012-09-20 10:46   ` Anderson Lizardo
2012-09-20 11:03     ` Chen Ganir
2012-09-20  8:27 ` [PATCH v3 07/10] battery: Add Battery to device chen.ganir
2012-09-20  8:27 ` [PATCH v3 08/10] battery: Read Battery level characteristic chen.ganir
2012-09-20  8:27 ` [PATCH v3 09/10] battery: Add support for notifications chen.ganir
2012-09-20 10:54   ` Anderson Lizardo
2012-09-20 11:00     ` Chen Ganir
2012-09-20  8:27 ` [PATCH v3 10/10] battery: Support persistent battery level chen.ganir
2012-09-20 10:56 ` [PATCH v3 00/10] Implement Generic battery and LE Battery client Anderson Lizardo
2012-09-20 11:04   ` Chen Ganir

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).