summaryrefslogtreecommitdiff
path: root/attrib
diff options
context:
space:
mode:
Diffstat (limited to 'attrib')
-rw-r--r--attrib/gatt.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/attrib/gatt.c b/attrib/gatt.c
index aafd3f77d..b8d766cd2 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -43,6 +43,7 @@ struct discover_primary {
GAttrib *attrib;
unsigned int id;
bt_uuid_t uuid;
+ uint16_t start;
GSList *primaries;
gatt_cb_t cb;
void *user_data;
@@ -255,8 +256,19 @@ static void primary_by_uuid_cb(guint8 status, const guint8 *ipdu,
if (range->end == 0xffff)
goto done;
+ /*
+ * If last handle is lower from previous start handle then it is smth
+ * wrong. Let's stop search, otherwise we might enter infinite loop.
+ */
+ if (range->end < dp->start) {
+ err = ATT_ECODE_UNLIKELY;
+ goto done;
+ }
+
+ dp->start = range->end + 1;
+
buf = g_attrib_get_buffer(dp->attrib, &buflen);
- oplen = encode_discover_primary(range->end + 1, 0xffff, &dp->uuid,
+ oplen = encode_discover_primary(dp->start, 0xffff, &dp->uuid,
buf, buflen);
if (oplen == 0)
@@ -325,12 +337,24 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
att_data_list_free(list);
err = 0;
+ /*
+ * If last handle is lower from previous start handle then it is smth
+ * wrong. Let's stop search, otherwise we might enter infinite loop.
+ */
+ if (end < dp->start) {
+ err = ATT_ECODE_UNLIKELY;
+ goto done;
+ }
+
+ dp->start = end + 1;
+
if (end != 0xffff) {
size_t buflen;
uint8_t *buf = g_attrib_get_buffer(dp->attrib, &buflen);
- guint16 oplen = encode_discover_primary(end + 1, 0xffff, NULL,
+ guint16 oplen = encode_discover_primary(dp->start, 0xffff, NULL,
buf, buflen);
+
g_attrib_send(dp->attrib, dp->id, buf, oplen, primary_all_cb,
discover_primary_ref(dp),
discover_primary_unref);
@@ -362,6 +386,7 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
dp->attrib = g_attrib_ref(attrib);
dp->cb = func;
dp->user_data = user_data;
+ dp->start = 0x0001;
if (uuid) {
dp->uuid = *uuid;