summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Paulo Rechi Vita <jprvita@gmail.com>2014-01-06 18:04:23 -0300
committerJoão Paulo Rechi Vita <jprvita@gmail.com>2014-01-15 15:03:59 -0300
commit93a3efd7faeb20c2619bb73db8dfa96ca6c2c332 (patch)
treeaa6dfb1d1a237da0e9da674f2b747491db07b9f3
parent068cdc17e23cdc51632027fbfbc5f7555044293f (diff)
lib: Add support for GATT prepare write
-rw-r--r--lib/ble.c61
-rw-r--r--lib/ble.h54
2 files changed, 112 insertions, 3 deletions
diff --git a/lib/ble.c b/lib/ble.c
index cd76ee4..0d5ee12 100644
--- a/lib/ble.c
+++ b/lib/ble.c
@@ -45,6 +45,12 @@ struct ble_gatt_desc {
bt_uuid_t d;
};
+typedef enum {
+ BLE_GATT_ELEM_SERVICE,
+ BLE_GATT_ELEM_CHARACTERISTIC,
+ BLE_GATT_ELEM_DESCRIPTOR
+} gatt_elem_t;
+
/* Internal representation of a BLE device */
typedef struct ble_device ble_device_t;
struct ble_device {
@@ -58,6 +64,10 @@ struct ble_device {
ble_gatt_desc_t *descs;
uint8_t desc_count;
+ uint8_t write_prepared;
+ gatt_elem_t prep_write_type;
+ uint8_t prep_write_id;
+
ble_device_t *next;
};
@@ -628,6 +638,21 @@ static void write_descriptor_cb(int conn_id, int status,
data.cbs.desc_write_cb(conn_id, id, NULL, 0, 0, status);
}
+static void execute_write_cb(int conn_id, int status) {
+ ble_device_t *dev;
+
+ dev = find_device_by_conn_id(conn_id);
+ if (!dev || !dev->write_prepared)
+ return;
+
+ if (dev->prep_write_type == BLE_GATT_ELEM_CHARACTERISTIC &&
+ data.cbs.char_write_cb)
+ data.cbs.char_write_cb(conn_id, dev->prep_write_id, NULL, 0, 0, status);
+ else if (dev->prep_write_type == BLE_GATT_ELEM_DESCRIPTOR &&
+ data.cbs.desc_write_cb)
+ data.cbs.desc_write_cb(conn_id, dev->prep_write_id, NULL, 0, 0, status);
+}
+
static int ble_gatt_op(int operation, int conn_id, int id, int auth,
const char *value, int len) {
ble_device_t *dev;
@@ -672,9 +697,14 @@ static int ble_gatt_op(int operation, int conn_id, int id, int auth,
auth);
break;
+ case 4: /* Write characteristic with prepare write */
+ dev->write_prepared = 1;
+ dev->prep_write_type = BLE_GATT_ELEM_CHARACTERISTIC;
+ dev->prep_write_id = id;
+ /* pass-through */
+
case 2: /* Write characteristic with write command */
case 3: /* Write characteristic with write request */
- case 4: /* Write characteristic with prepare write */
if (dev->char_count <= 0 || id >= dev->char_count)
return -1;
@@ -686,9 +716,14 @@ static int ble_gatt_op(int operation, int conn_id, int id, int auth,
(char *) value);
break;
+ case 7: /* Write descriptor with prepare write */
+ dev->write_prepared = 1;
+ dev->prep_write_type = BLE_GATT_ELEM_DESCRIPTOR;
+ dev->prep_write_id = id;
+ /* pass-through */
+
case 5: /* Write descriptor with write command */
case 6: /* Write descriptor with write request */
- case 7: /* Write descriptor with prepare write */
if (dev->desc_count <= 0 || id >= dev->desc_count)
return -1;
@@ -699,6 +734,12 @@ static int ble_gatt_op(int operation, int conn_id, int id, int auth,
operation-4, len,
auth, (char *) value);
break;
+
+ case 8:
+ if (id == 0) /* Cancel prepared write */
+ dev->write_prepared = 0;
+ s = data.gattiface->client->execute_write(conn_id, id);
+ break;
}
if (s != BT_STATUS_SUCCESS)
@@ -735,6 +776,20 @@ int ble_gatt_write_req_desc(int conn_id, int desc_id, int auth,
return ble_gatt_op(6, conn_id, desc_id, auth, value, len);
}
+int ble_gatt_prep_write_char(int conn_id, int char_id, int auth,
+ const char *value, int len) {
+ return ble_gatt_op(4, conn_id, char_id, auth, value, len);
+}
+
+int ble_gatt_prep_write_desc(int conn_id, int desc_id, int auth,
+ const char *value, int len) {
+ return ble_gatt_op(7, conn_id, desc_id, auth, value, len);
+}
+
+int ble_gatt_execute_write(int conn_id, int execute) {
+ return ble_gatt_op(8, conn_id, execute, 0, NULL, 0);
+}
+
/* Called when the registration for notifications on a char finishes */
static void register_for_notification_cb(int conn_id, int registered,
int status,
@@ -838,7 +893,7 @@ static const btgatt_client_callbacks_t gattccbs = {
write_characteristic_cb,
read_descriptor_cb,
write_descriptor_cb,
- NULL, /* execute_write_cb */
+ execute_write_cb,
read_remote_rssi_cb
};
diff --git a/lib/ble.h b/lib/ble.h
index b2e1618..9e31687 100644
--- a/lib/ble.h
+++ b/lib/ble.h
@@ -472,6 +472,60 @@ int ble_gatt_write_req_desc(int conn_id, int desc_id, int auth,
const char *value, int len);
/**
+ * Prepare to write the value of a characteristic (with response) later, with
+ * @func ble_execute_write().
+ *
+ * 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 to be written.
+ * @param auth Whether or not link encryption should be requested before trying
+ * to write the descriptor: 1 request, 0 do not request.
+ * @param value Pointer to the value that should be written on the
+ * descriptor.
+ * @param len The length of the data pointed by the value parameter.
+ *
+ * @return 0 if descriptor write has been successfully requested.
+ * @return -1 if failed to request descriptor write.
+ */
+int ble_gatt_prep_write_char(int conn_id, int char_id, int auth,
+ const char *value, int len);
+
+/**
+ * Prepare to write the value of a descriptor (with response) later, with
+ * @func ble_execute_write().
+ *
+ * There should be an active connection with the device.
+ *
+ * @param conn_id The identifier of the connected remote device.
+ * @param desc_id The identifier of the descriptor to be written.
+ * @param auth Whether or not link encryption should be requested before trying
+ * to write the descriptor: 1 request, 0 do not request.
+ * @param value Pointer to the value that should be written on the
+ * descriptor.
+ * @param len The length of the data pointed by the value parameter.
+ *
+ * @return 0 if descriptor write has been successfully requested.
+ * @return -1 if failed to request descriptor write.
+ */
+int ble_gatt_prep_write_desc(int conn_id, int desc_id, int auth,
+ const char *value, int len);
+
+/**
+ * Execute or cancel a previously prepared write operation.
+ *
+ * There should be an active connection with the device.
+ *
+ * @param conn_id The identifier of the connected remote device.
+ * @param execute Whether the operation should be executed or cancelled:
+ * 1 request, 0 do not request.
+ *
+ * @return 0 if descriptor write has been successfully requested.
+ * @return -1 if failed to request descriptor write.
+ */
+int ble_gatt_execute_write(int conn_id, int execute);
+
+/**
* Register for notifications of changes in the value of a characteristic.
*
* There should be an active connection with the device.