Пример #1
0
guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
						bt_uuid_t *uuid, gatt_cb_t func,
						gpointer user_data)
{
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(attrib, &buflen);
	struct discover_char *dc;
	bt_uuid_t type_uuid;
	guint16 plen;

	bt_uuid16_create(&type_uuid, GATT_CHARAC_UUID);

	plen = enc_read_by_type_req(start, end, &type_uuid, buf, buflen);
	if (plen == 0)
		return 0;

	dc = g_try_new0(struct discover_char, 1);
	if (dc == NULL)
		return 0;

	dc->attrib = g_attrib_ref(attrib);
	dc->cb = func;
	dc->user_data = user_data;
	dc->end = end;
	dc->uuid = g_memdup(uuid, sizeof(bt_uuid_t));

	return g_attrib_send(attrib, 0, buf, plen, char_discovered_cb,
								dc, NULL);
}
Пример #2
0
guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
					bt_uuid_t *uuid, GAttribResultFunc func,
					gpointer user_data)
{
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(attrib, &buflen);
	guint16 plen;

	plen = enc_read_by_type_req(start, end, uuid, buf, buflen);
	if (plen == 0)
		return 0;

	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
}
Пример #3
0
static guint find_included(struct included_discovery *isd, uint16_t start)
{
	bt_uuid_t uuid;
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(isd->attrib, &buflen);
	guint16 oplen;

	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
	oplen = enc_read_by_type_req(start, isd->end_handle, &uuid,
							buf, buflen);

	return g_attrib_send(isd->attrib, 0, buf, oplen, find_included_cb,
				isd_ref(isd), (GDestroyNotify) isd_unref);
}
Пример #4
0
static guint find_included(struct included_discovery *isd, uint16_t start)
{
	bt_uuid_t uuid;
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(isd->attrib, &buflen);
	guint16 oplen;

	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
	oplen = enc_read_by_type_req(start, isd->end_handle, &uuid,
							buf, buflen);

	/* If id != 0 it means we are in the middle of include search */
	if (isd->id)
		return g_attrib_send(isd->attrib, isd->id, buf, oplen,
				find_included_cb, isd_ref(isd),
				(GDestroyNotify) isd_unref);

	/* This is first call from the gattrib user */
	isd->id = g_attrib_send(isd->attrib, 0, buf, oplen, find_included_cb,
				isd_ref(isd), (GDestroyNotify) isd_unref);

	return isd->id;
}
Пример #5
0
static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
							gpointer user_data)
{
	struct discover_char *dc = user_data;
	struct att_data_list *list;
	unsigned int i, err = ATT_ECODE_ATTR_NOT_FOUND;
	uint16_t last = 0;

	if (status) {
		err = status;
		goto done;
	}

	list = dec_read_by_type_resp(ipdu, iplen);
	if (list == NULL) {
		err = ATT_ECODE_IO;
		goto done;
	}

	for (i = 0; i < list->num; i++) {
		uint8_t *value = list->data[i];
		struct gatt_char *chars;
		bt_uuid_t uuid;

		last = att_get_u16(value);

		if (list->len == 7) {
			bt_uuid_t uuid16 = att_get_uuid16(&value[5]);
			bt_uuid_to_uuid128(&uuid16, &uuid);
		} else
			uuid = att_get_uuid128(&value[5]);

		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid))
			continue;

		chars = g_try_new0(struct gatt_char, 1);
		if (!chars) {
			err = ATT_ECODE_INSUFF_RESOURCES;
			goto done;
		}

		chars->handle = last;
		chars->properties = value[2];
		chars->value_handle = att_get_u16(&value[3]);
		bt_uuid_to_string(&uuid, chars->uuid, sizeof(chars->uuid));
		dc->characteristics = g_slist_append(dc->characteristics,
									chars);
	}

	att_data_list_free(list);

	if (last != 0 && (last + 1 < dc->end)) {
		bt_uuid_t uuid;
		guint16 oplen;
		size_t buflen;
		uint8_t *buf;

		buf = g_attrib_get_buffer(dc->attrib, &buflen);

		bt_uuid16_create(&uuid, GATT_CHARAC_UUID);

		oplen = enc_read_by_type_req(last + 1, dc->end, &uuid, buf,
									buflen);

		if (oplen == 0)
			return;

		g_attrib_send(dc->attrib, 0, buf, oplen, char_discovered_cb,
								dc, NULL);

		return;
	}

done:
	err = (dc->characteristics ? 0 : err);

	dc->cb(dc->characteristics, err, dc->user_data);
	discover_char_free(dc);
}
Пример #6
0
static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
							gpointer user_data)
{
	struct discover_char *dc = user_data;
	struct att_data_list *list;
	unsigned int i, err = 0;
	uint16_t last = 0;
	uint8_t type;

	/* We have all the characteristic now, lets send it up */
	if (status == ATT_ECODE_ATTR_NOT_FOUND) {
		err = dc->characteristics ? 0 : status;
		goto done;
	}

	if (status) {
		err = status;
		goto done;
	}

	list = dec_read_by_type_resp(ipdu, iplen);
	if (list == NULL) {
		err = ATT_ECODE_IO;
		goto done;
	}

	if (list->len == 7)
		type = BT_UUID16;
	else
		type = BT_UUID128;

	for (i = 0; i < list->num; i++) {
		uint8_t *value = list->data[i];
		struct gatt_char *chars;
		bt_uuid_t uuid128;

		last = get_le16(value);

		get_uuid128(type, &value[5], &uuid128);

		if (dc->uuid && bt_uuid_cmp(dc->uuid, &uuid128))
			continue;

		chars = g_try_new0(struct gatt_char, 1);
		if (!chars) {
			att_data_list_free(list);
			err = ATT_ECODE_INSUFF_RESOURCES;
			goto done;
		}

		chars->handle = last;
		chars->properties = value[2];
		chars->value_handle = get_le16(&value[3]);
		bt_uuid_to_string(&uuid128, chars->uuid, sizeof(chars->uuid));
		dc->characteristics = g_slist_append(dc->characteristics,
									chars);
	}

	att_data_list_free(list);

	/*
	 * 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 (last < dc->start) {
		err = ATT_ECODE_UNLIKELY;
		goto done;
	}

	dc->start = last + 1;

	if (last != 0 && (dc->start < dc->end)) {
		bt_uuid_t uuid;
		guint16 oplen;
		size_t buflen;
		uint8_t *buf;

		buf = g_attrib_get_buffer(dc->attrib, &buflen);

		bt_uuid16_create(&uuid, GATT_CHARAC_UUID);

		oplen = enc_read_by_type_req(dc->start, dc->end, &uuid, buf,
									buflen);

		if (oplen == 0)
			return;

		g_attrib_send(dc->attrib, dc->id, buf, oplen,
				char_discovered_cb, discover_char_ref(dc),
				discover_char_unref);

		return;
	}

done:
	dc->cb(err, dc->characteristics, dc->user_data);
}