summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Paulo Rechi Vita <jprvita@gmail.com>2013-12-17 10:46:40 -0300
committerJoão Paulo Rechi Vita <jprvita@gmail.com>2014-01-15 15:03:52 -0300
commita020d584edce7ce1228bb026cde4eff39e2dded1 (patch)
treed4f0f7f9ace3d840fdf0e274b28a037720864d31
parentc71d0336e7c1e07e94507bd20a4bb0a50145ba9e (diff)
lib: Create API for GATT descriptor discovery
-rw-r--r--lib/ble.c93
-rw-r--r--lib/ble.h16
2 files changed, 108 insertions, 1 deletions
diff --git a/lib/ble.c b/lib/ble.c
index e24faad..a9e50ad 100644
--- a/lib/ble.c
+++ b/lib/ble.c
@@ -38,6 +38,13 @@ struct ble_gatt_char {
btgatt_char_id_t c;
};
+/* Internal representation of a GATT descriptor */
+typedef struct ble_gatt_desc ble_gatt_desc_t;
+struct ble_gatt_desc {
+ ble_gatt_char_t c;
+ bt_uuid_t d;
+};
+
/* Internal representation of a BLE device */
typedef struct ble_device ble_device_t;
struct ble_device {
@@ -48,6 +55,8 @@ struct ble_device {
uint8_t srvc_count;
ble_gatt_char_t *chars;
uint8_t char_count;
+ ble_gatt_desc_t *descs;
+ uint8_t desc_count;
ble_device_t *next;
};
@@ -438,6 +447,87 @@ int ble_gatt_discover_characteristics(int conn_id, int service_id) {
return 0;
}
+static int find_descriptor(ble_device_t *dev, btgatt_srvc_id_t *srvc_id,
+ btgatt_char_id_t *char_id, bt_uuid_t *descr_id) {
+ int id;
+
+ for (id = 0; id < dev->desc_count; id++)
+ if (!memcmp(&dev->descs[id].d, descr_id, sizeof(bt_uuid_t)) &&
+ !memcmp(&dev->descs[id].c.c, char_id, sizeof(btgatt_char_id_t)) &&
+ !memcmp(&dev->descs[id].c.s, srvc_id, sizeof(btgatt_srvc_id_t)))
+ return id;
+
+ return -1;
+}
+
+/* Called for each descriptor discovery result */
+static void descriptor_discovery_cb(int conn_id, int status,
+ btgatt_srvc_id_t *srvc_id,
+ btgatt_char_id_t *char_id,
+ bt_uuid_t *descr_id) {
+ ble_device_t *dev;
+ int id;
+ bt_status_t s;
+
+ if (status != 0) {
+ if (data.cbs.desc_finished_cb)
+ data.cbs.desc_finished_cb(conn_id, status);
+ return;
+ }
+
+ dev = find_device_by_conn_id(conn_id);
+ if (!dev)
+ return;
+
+ id = find_descriptor(dev, srvc_id, char_id, descr_id);
+ if (id < 0) {
+ id = dev->desc_count++;
+ dev->descs = realloc(dev->descs,
+ dev->desc_count * sizeof(ble_gatt_desc_t));
+ memcpy(&dev->descs[id].c.s, srvc_id, sizeof(btgatt_srvc_id_t));
+ memcpy(&dev->descs[id].c.c, char_id, sizeof(btgatt_char_id_t));
+ memcpy(&dev->descs[id].d, descr_id, sizeof(bt_uuid_t));
+ }
+
+ if (data.cbs.desc_found_cb)
+ data.cbs.desc_found_cb(conn_id, id, descr_id->uu, 0);
+
+ /* Get next descriptor */
+ s = data.gattiface->client->get_descriptor(conn_id, srvc_id, char_id,
+ descr_id);
+ if (s != BT_STATUS_SUCCESS)
+ if (data.cbs.desc_finished_cb)
+ data.cbs.desc_finished_cb(conn_id, status);
+}
+
+int ble_gatt_discover_descriptors(int conn_id, int char_id) {
+ ble_device_t *dev;
+ bt_status_t s;
+
+ if (conn_id <= 0)
+ return -1;
+
+ if (!data.gattiface)
+ return -1;
+
+ dev = find_device_by_conn_id(conn_id);
+ if (!dev)
+ return -1;
+
+ if (dev->char_count <= 0)
+ return -1;
+
+ if (char_id < 0 || char_id >= dev->char_count)
+ return -1;
+
+ s = data.gattiface->client->get_descriptor(conn_id, &dev->chars[char_id].s,
+ &dev->chars[char_id].c, NULL);
+ if (s != BT_STATUS_SUCCESS)
+ return -s;
+
+ return 0;
+}
+
/* Called when the client registration is finished */
static void register_client_cb(int status, int client_if, bt_uuid_t *app_uuid) {
if (status == BT_STATUS_SUCCESS) {
@@ -457,7 +547,7 @@ static const btgatt_client_callbacks_t gattccbs = {
service_discovery_complete_cb,
service_discovery_result_cb,
characteristic_discovery_cb,
- NULL, /* get_descriptor_cb */
+ descriptor_discovery_cb,
NULL, /* get_included_service_cb */
NULL, /* register_for_notification_cb */
NULL, /* notify_cb */
@@ -582,6 +672,7 @@ static void remove_all_devices() {
free(dev->srvcs);
free(dev->chars);
+ free(dev->descs);
free(dev);
dev = next;
diff --git a/lib/ble.h b/lib/ble.h
index 551b1fc..5c5c3a9 100644
--- a/lib/ble.h
+++ b/lib/ble.h
@@ -143,6 +143,8 @@ typedef struct ble_cbs {
ble_gatt_finished_cb_t srvc_finished_cb;
ble_gatt_found_cb_t char_found_cb;
ble_gatt_finished_cb_t char_finished_cb;
+ ble_gatt_found_cb_t desc_found_cb;
+ ble_gatt_finished_cb_t desc_finished_cb;
} ble_cbs_t;
/**
@@ -275,4 +277,18 @@ int ble_gatt_discover_services(int conn_id, const uint8_t *uuid);
* @return -1 if failed to request characteristic discovery.
*/
int ble_gatt_discover_characteristics(int conn_id, int service_id);
+
+/**
+ * Discover descriptors of a characteristic of a BLE device.
+ *
+ * There should be an active connection with the device.
+ *
+ * @param conn_id The identifier of the connected remote device.
+ * @param char_id The identifier of the characteristic in which the descriptor
+ * discovery will be run.
+ *
+ * @return 0 if descriptor discovery has been successfully requested.
+ * @return -1 if failed to request descriptor discovery.
+ */
+int ble_gatt_discover_descriptors(int conn_id, int char_id);
#endif