aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Ganir <chen.ganir@ti.com>2012-03-14 15:36:14 +0200
committerJoão Paulo Rechi Vita <jprvita@openbossa.org>2012-06-21 18:00:18 -0300
commit632ebaf63d962b207c5103a198759013828ee0f9 (patch)
tree3d2b94e9e659285ad7bb66686cb64fcd1a71d1ff
parent02e88080046a875510761a23f6d2be8e5db80b29 (diff)
downloadbluez-632ebaf63d962b207c5103a198759013828ee0f9.tar.gz
bluez-632ebaf63d962b207c5103a198759013828ee0f9.tar.xz
bluez-632ebaf63d962b207c5103a198759013828ee0f9.zip
battery: Add connection logic
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.
-rw-r--r--batterystate/batterystate.c76
-rw-r--r--batterystate/batterystate.h3
-rw-r--r--batterystate/manager.c22
3 files changed, 97 insertions, 4 deletions
diff --git a/batterystate/batterystate.c b/batterystate/batterystate.c
index 6db593ef..79b4005c 100644
--- a/batterystate/batterystate.c
+++ b/batterystate/batterystate.c
@@ -29,17 +29,29 @@
#include "adapter.h"
#include "device.h"
+#include "gattrib.h"
+#include "attio.h"
#include "att.h"
#include "gattrib.h"
#include "gatt.h"
#include "batterystate.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 = NULL;
+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;
@@ -55,20 +67,82 @@ static void batterystate_free(gpointer user_data)
{
struct battery *batt = user_data;
+ if (batt->attioid > 0)
+ btd_device_remove_attio_callback(batt->dev, batt->attioid);
+
+ if (batt->attrib != NULL)
+ g_attrib_unref(batt->attrib);
+
+ if (batt->chars != NULL)
+ g_slist_free_full(batt->chars, g_free);
+
btd_device_unref(batt->dev);
g_free(batt);
}
+static void configure_batterystate_cb(GSList *characteristics, guint8 status,
+ gpointer user_data)
+{
+ struct battery *batt = user_data;
+ GSList *l;
+
+ if (status != 0) {
+ error("Discover batterystate 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);
+
+ gatt_discover_char(batt->attrib, batt->svc_range->start,
+ batt->svc_range->end, NULL,
+ configure_batterystate_cb, batt);
+
+}
+
+static void attio_disconnected_cb(gpointer user_data)
+{
+ struct battery *batt = user_data;
-int batterystate_register(struct btd_device *device)
+ g_attrib_unref(batt->attrib);
+ batt->attrib = NULL;
+}
+
+int batterystate_register(struct btd_device *device, struct gatt_primary *prim)
{
struct battery *batt;
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;
}
diff --git a/batterystate/batterystate.h b/batterystate/batterystate.h
index 9aedae7a..2d30028a 100644
--- a/batterystate/batterystate.h
+++ b/batterystate/batterystate.h
@@ -19,6 +19,5 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
-
-int batterystate_register(struct btd_device *device);
+int batterystate_register(struct btd_device *device, struct gatt_primary *prim);
void batterystate_unregister(struct btd_device *device);
diff --git a/batterystate/manager.c b/batterystate/manager.c
index 6718acfa..62076ac9 100644
--- a/batterystate/manager.c
+++ b/batterystate/manager.c
@@ -34,9 +34,29 @@
#define BATTERY_SERVICE_UUID "0000180f-0000-1000-8000-00805f9b34fb"
+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);
+}
+
static int batterystate_driver_probe(struct btd_device *device, GSList *uuids)
{
- return batterystate_register(device);
+ 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);
+ if (l == NULL)
+ return -EINVAL;
+
+ prim = l->data;
+
+ return batterystate_register(device, prim);
}
static void batterystate_driver_remove(struct btd_device *device)