aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Ganir <chen.ganir@ti.com>2012-03-20 12:13:31 +0200
committerJoão Paulo Rechi Vita <jprvita@openbossa.org>2012-06-21 18:00:18 -0300
commitc7dfb49e00f3f6a6fb649e7aa3df26f779008759 (patch)
tree354f844d9389f8041d1b55ba900de6179a93a4d1
parent93729c82b026e410b7e2b2e839d7b9b11f731266 (diff)
downloadbluez-c7dfb49e00f3f6a6fb649e7aa3df26f779008759.tar.gz
bluez-c7dfb49e00f3f6a6fb649e7aa3df26f779008759.tar.xz
bluez-c7dfb49e00f3f6a6fb649e7aa3df26f779008759.zip
battery: Get Battery ID
Read the battery level format characteristic descriptor to get the unique namespace and description values.
-rw-r--r--batterystate/batterystate.c115
1 files changed, 87 insertions, 28 deletions
diff --git a/batterystate/batterystate.c b/batterystate/batterystate.c
index 4384a465..678e1230 100644
--- a/batterystate/batterystate.c
+++ b/batterystate/batterystate.c
@@ -37,6 +37,8 @@
#include "batterystate.h"
#include "log.h"
+#define BATTERY_LEVEL_UUID "00002a19-0000-1000-8000-00805f9b34fb"
+
struct battery {
struct btd_device *dev; /* Device reference */
GAttrib *attrib; /* GATT connection */
@@ -48,15 +50,18 @@ struct battery {
static GSList *servers = NULL;
struct characteristic {
- struct gatt_char attr; /* Characteristic */
- struct battery *batt; /* Parent Battery Service */
- GSList *desc; /* Descriptors */
+ struct gatt_char attr; /* Characteristic */
+ struct battery *batt; /* Parent Battery Service */
+ GSList *desc; /* Descriptors */
+ uint8_t ns; /* Battery Namespace */
+ uint16_t description; /* Battery description */
+ uint8_t level; /* Battery last known level */
};
struct descriptor {
- struct characteristic *ch; /* Parent Characteristic */
- uint16_t handle; /* Descriptor Handle */
- bt_uuid_t uuid; /* UUID */
+ struct characteristic *ch; /* Parent Characteristic */
+ uint16_t handle; /* Descriptor Handle */
+ bt_uuid_t uuid; /* UUID */
};
static void char_free(gpointer user_data)
@@ -96,6 +101,55 @@ static void batterystate_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];
+ ssize_t 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\n");
+ 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)
{
@@ -129,6 +183,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);
@@ -149,31 +204,35 @@ static void configure_batterystate_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);
+ }
}
}