Ejemplo n.º 1
0
guint gatt_discover_desc(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_desc *dd;
	guint16 plen;

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

	dd = g_try_new0(struct discover_desc, 1);
	if (dd == NULL)
		return 0;

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

	dd->id = g_attrib_send(attrib, 0, buf, plen, desc_discovered_cb,
				discover_desc_ref(dd), discover_desc_unref);

	return dd->id;
}
Ejemplo n.º 2
0
static void indicate_cb(
	const uint8_t *pdu,
	uint16_t len,
	gpointer user_data) {
	if (pdu[0] != ATT_OP_HANDLE_IND) {
		std::cout << "Invalid opecode for indicate. pdu[0]:" << std::hex << static_cast<unsigned int>(pdu[0]) << std::endl;
		return;
	}
	uint16_t handle = (pdu[2] << 8) | pdu[1];
	std::cout << (boost::format("Indicate from %04x length:%d") % handle % len) << std::endl;
	for (std::size_t index = 3, address = 0; index < len; ++index, ++address) {
		if (address % 16 == 0) {
			std::cout << std::endl;
			std::cout << (boost::format("%08x:") % address);
		}
		if (address % 8 == 0) {
			std::cout << ' ';
		}
		std::cout << (boost::format("%02x ") % static_cast<unsigned int>(pdu[index]));
	}
	std::cout << std::endl;

	size_t plen;
	user_data_t* ud = static_cast<user_data_t*>(user_data);
	uint8_t* opdu = g_attrib_get_buffer(ud->attrib, &plen);
	uint16_t olen = enc_confirmation(opdu, plen);
	if (olen > 0)
		g_attrib_send(ud->attrib, 0, opdu, olen, NULL, NULL, NULL);
}
Ejemplo n.º 3
0
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
	GAttrib *attrib = user_data;
	uint8_t *opdu;
	uint16_t handle, i, olen = 0;
	size_t plen;

	handle = att_get_u16(&pdu[1]);

	switch (pdu[0]) {
	case ATT_OP_HANDLE_NOTIFY:
		g_print("Notification handle = 0x%04x value: ", handle);
		break;
	case ATT_OP_HANDLE_IND:
		g_print("Indication   handle = 0x%04x value: ", handle);
		break;
	default:
		g_print("Invalid opcode\n");
		return;
	}

	for (i = 3; i < len; i++)
		g_print("%02x ", pdu[i]);

	g_print("\n");

	if (pdu[0] == ATT_OP_HANDLE_NOTIFY)
		return;

	opdu = g_attrib_get_buffer(attrib, &plen);
	olen = enc_confirmation(opdu, plen);

	if (olen > 0)
		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
}
Ejemplo n.º 4
0
static void cmd_gatts(int argcp, char **argvp)
{
    if (argcp == 2) {
        GAttribResultFunc cb_func = NULL;
        uint8_t *opdu = NULL;
        size_t olen = gatt_attr_data_from_string(argvp[1], &opdu);

        DBG("GATTS %p %d %zd", opdu, opt_mtu, olen);

        /* Check if it is a value gatt server request */
        if (opdu && (opt_mtu == 0 || olen <= opt_mtu) &&
            !(opdu[0] == BT_ATT_OP_MTU_REQ ||
              opdu[0] == BT_ATT_OP_FIND_INFO_REQ ||
              opdu[0] == BT_ATT_OP_FIND_BY_TYPE_VAL_REQ ||
              opdu[0] == BT_ATT_OP_READ_BY_TYPE_REQ ||
              opdu[0] == BT_ATT_OP_READ_REQ ||
              opdu[0] == BT_ATT_OP_READ_BLOB_REQ ||
              opdu[0] == BT_ATT_OP_READ_MULT_REQ ||
              opdu[0] == BT_ATT_OP_READ_BY_GRP_TYPE_REQ ||
              opdu[0] == BT_ATT_OP_WRITE_REQ ||
              opdu[0] == BT_ATT_OP_PREP_WRITE_REQ ||
              opdu[0] == BT_ATT_OP_EXEC_WRITE_REQ)) {
            if (opdu[0] == BT_ATT_OP_HANDLE_VAL_IND) {
                cb_func = on_indicate_complete;
            }
            g_attrib_send(attrib, 0, opdu, olen, cb_func, NULL, NULL);
        } else {
            resp_error(err_BAD_PARAM);;
        }
        g_free(opdu);
    } else {
        resp_error(err_BAD_PARAM);;
    }
}
Ejemplo n.º 5
0
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data) {
	gatt_connection_t *conn = user_data;
	uint8_t opdu[ATT_MAX_MTU];
	uint16_t handle, i, olen = 0;

	handle = att_get_u16(&pdu[1]);
	// printf("0x%02x\n", handle);

	switch (pdu[0]) {
	case ATT_OP_HANDLE_NOTIFY:
		if (conn->notification_handler) {
			conn->notification_handler(handle, &pdu[3], len, conn->notification_user_data);
		}
		break;
	case ATT_OP_HANDLE_IND:
		if (conn->indication_handler) {
			conn->indication_handler(handle, &pdu[3], len, conn->indication_user_data);
		}
		break;
	default:
		g_print("Invalid opcode\n");
		return;
	}

	if (pdu[0] == ATT_OP_HANDLE_NOTIFY)
		return;

	olen = enc_confirmation(opdu, sizeof(opdu));

	if (olen > 0)
		g_attrib_send(conn->attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
}
Ejemplo n.º 6
0
guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
							gpointer user_data)
{
	struct discover_primary *dp;
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(attrib, &buflen);
	GAttribResultFunc cb;
	guint16 plen;

	plen = encode_discover_primary(0x0001, 0xffff, uuid, buf, buflen);
	if (plen == 0)
		return 0;

	dp = g_try_new0(struct discover_primary, 1);
	if (dp == NULL)
		return 0;

	dp->attrib = g_attrib_ref(attrib);
	dp->cb = func;
	dp->user_data = user_data;

	if (uuid) {
		dp->uuid = *uuid;
		cb = primary_by_uuid_cb;
	} else
		cb = primary_all_cb;

	return g_attrib_send(attrib, 0, buf, plen, cb, dp, NULL);
}
Ejemplo n.º 7
0
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
	uint8_t *opdu;
        uint8_t evt;
	uint16_t handle, i, olen;
	size_t plen;

        evt = pdu[0];

        if ( evt != ATT_OP_HANDLE_NOTIFY && evt != ATT_OP_HANDLE_IND )
        {
          printf("#Invalid opcode %02X in event handler??\n", evt);
          return;
        }

        assert( len >= 3 );
	handle = att_get_u16(&pdu[1]);

        resp_begin( evt==ATT_OP_HANDLE_NOTIFY ? rsp_NOTIFY : rsp_IND );
        send_uint( tag_HANDLE, handle );
        send_data( pdu+3, len-3 );
        resp_end();

	if (evt == ATT_OP_HANDLE_NOTIFY)
		return;

	opdu = g_attrib_get_buffer(attrib, &plen);
	olen = enc_confirmation(opdu, plen);

	if (olen > 0)
		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
}
Ejemplo n.º 8
0
static void read_char_helper(guint8 status, const guint8 *rpdu,
					guint16 rlen, gpointer user_data)
{
	struct read_long_data *long_read = user_data;
	int buflen;
	uint8_t *buf = g_attrib_get_buffer(long_read->attrib, &buflen);
	guint16 plen;
	guint id;

	if (status != 0 || rlen < buflen)
		goto done;

	long_read->buffer = g_malloc(rlen);

	if (long_read->buffer == NULL)
		goto done;

	memcpy(long_read->buffer, rpdu, rlen);
	long_read->size = rlen;

	plen = enc_read_blob_req(long_read->handle, rlen - 1, buf, buflen);
	id = g_attrib_send(long_read->attrib, long_read->id,
			ATT_OP_READ_BLOB_REQ, buf, plen, read_blob_helper,
			long_read, read_long_destroy);

	if (id != 0) {
		g_atomic_int_inc(&long_read->ref);
		return;
	}

	status = ATT_ECODE_IO;

done:
	long_read->func(status, rpdu, rlen, long_read->user_data);
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
static void read_char_helper(guint8 status, const guint8 *rpdu,
					guint16 rlen, gpointer user_data)
{
	struct read_long_data *long_read = user_data;
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(long_read->attrib, &buflen);
	guint16 plen;
	guint id;

	if (status != 0 || rlen < buflen)
		goto done;

	long_read->buffer = g_malloc(rlen);
	if (long_read->buffer == NULL) {
		status = ATT_ECODE_INSUFF_RESOURCES;
		goto done;
	}

	memcpy(long_read->buffer, rpdu, rlen);
	long_read->size = rlen;

	plen = enc_read_blob_req(long_read->handle, rlen - 1, buf, buflen);

	id = g_attrib_send(long_read->attrib, long_read->id, buf, plen,
				read_blob_helper, long_read, read_long_destroy);
	if (id != 0) {
		__sync_fetch_and_add(&long_read->ref, 1);
		return;
	}

	status = ATT_ECODE_IO;

done:
	long_read->func(status, rpdu, rlen, long_read->user_data);
}
Ejemplo n.º 11
0
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
    uint8_t opdu[ATT_MAX_MTU];
    uint16_t handle, i, olen;

    handle = att_get_u16(&pdu[1]);

    printf("\r");
    switch (pdu[0]) {
    case ATT_OP_HANDLE_NOTIFY:
        printf("Notification handle = 0x%04x value: ", handle);
        break;
    case ATT_OP_HANDLE_IND:
        printf("Indication   handle = 0x%04x value: ", handle);
        break;
    default:
        printf("Invalid opcode\n");
        goto done;
    }

    for (i = 3; i < len; i++)
        printf("%02x ", pdu[i]);

    if (pdu[0] == ATT_OP_HANDLE_NOTIFY)
        goto done;

    olen = enc_confirmation(opdu, sizeof(opdu));

    if (olen > 0)
        g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);

done:
    printf("\r%s", get_prompt());
    fflush(stdout);
}
Ejemplo n.º 12
0
guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func,
							gpointer user_data)
{
	uint8_t *buf;
	size_t buflen;
	guint16 plen;
	guint id;
	struct read_long_data *long_read;

	long_read = g_try_new0(struct read_long_data, 1);

	if (long_read == NULL)
		return 0;

	long_read->attrib = attrib;
	long_read->func = func;
	long_read->user_data = user_data;
	long_read->handle = handle;

	buf = g_attrib_get_buffer(attrib, &buflen);
	plen = enc_read_req(handle, buf, buflen);
	id = g_attrib_send(attrib, 0, buf, plen, read_char_helper,
						long_read, read_long_destroy);
	if (id == 0)
		g_free(long_read);
	else {
		__sync_fetch_and_add(&long_read->ref, 1);
		long_read->id = id;
	}

	return id;
}
static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
{
	uint8_t opdu[ATT_MAX_MTU];
	uint16_t handle, i, olen;

	handle = att_get_u16(&pdu[1]);

	printf("\n");
	switch (pdu[0]) {
	case ATT_OP_HANDLE_NOTIFY:
		printf("Notification handle = 0x%04x value: ", handle);
		break;
	case ATT_OP_HANDLE_IND:
		printf("Indication   handle = 0x%04x value: ", handle);
		break;
	default:
		printf("Invalid opcode\n");
		return;
	}

	for (i = 3; i < len; i++)
		printf("%02x ", pdu[i]);

	printf("\n");
	rl_forced_update_display();

	if (pdu[0] == ATT_OP_HANDLE_NOTIFY)
		return;

	olen = enc_confirmation(opdu, sizeof(opdu));

	if (olen > 0)
		g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
}
Ejemplo n.º 14
0
static void primary_by_uuid_cb(guint8 status, const guint8 *ipdu,
					guint16 iplen, gpointer user_data)

{
	struct discover_primary *dp = user_data;
	GSList *ranges, *last;
	struct att_range *range;
	uint8_t *buf;
	guint16 oplen;
	int err = 0;
	size_t buflen;

	if (status) {
		err = status == ATT_ECODE_ATTR_NOT_FOUND ? 0 : status;
		goto done;
	}

	ranges = dec_find_by_type_resp(ipdu, iplen);
	if (ranges == NULL)
		goto done;

	dp->primaries = g_slist_concat(dp->primaries, ranges);

	last = g_slist_last(ranges);
	range = last->data;

	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(dp->start, 0xffff, &dp->uuid,
								buf, buflen);

	if (oplen == 0)
		goto done;

	g_attrib_send(dp->attrib, dp->id, buf, oplen, primary_by_uuid_cb,
			discover_primary_ref(dp), discover_primary_unref);
	return;

done:
	dp->cb(err, dp->primaries, dp->user_data);
}
Ejemplo n.º 15
0
guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
				GDestroyNotify notify, gpointer user_data)
{
	uint8_t *buf;
	size_t buflen;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);
	plen = enc_write_cmd(handle, value, vlen, buf, buflen);
	return g_attrib_send(attrib, 0, buf, plen, NULL, user_data, notify);
}
Ejemplo n.º 16
0
guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func,
							gpointer user_data)
{
	uint8_t *buf;
	size_t buflen;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);
	plen = enc_mtu_req(mtu, buf, buflen);
	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
}
Ejemplo n.º 17
0
guint gatt_read_char(GAttrib *attrib, uint16_t handle, uint16_t offset,
				GAttribResultFunc func, gpointer user_data)
{
	uint8_t *buf;
	int buflen;
	guint16 plen;
	guint id;
	struct read_long_data *long_read;

	long_read = g_try_new0(struct read_long_data, 1);

	if (long_read == NULL)
		return 0;

	long_read->attrib = attrib;
	long_read->func = func;
	long_read->user_data = user_data;
	long_read->handle = handle;

	buf = g_attrib_get_buffer(attrib, &buflen);
	if (offset > 0) {
		plen = enc_read_blob_req(long_read->handle, offset, buf,
									buflen);
		id = g_attrib_send(attrib, 0, ATT_OP_READ_BLOB_REQ, buf, plen,
				read_blob_helper, long_read, read_long_destroy);
	} else {
		plen = enc_read_req(handle, buf, buflen);
		id = g_attrib_send(attrib, 0, ATT_OP_READ_REQ, buf, plen,
				read_char_helper, long_read, read_long_destroy);
	}

	if (id == 0)
		g_free(long_read);
	else {
		g_atomic_int_inc(&long_read->ref);
		long_read->id = id;
	}

	return id;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
				GAttribResultFunc func, gpointer user_data)
{
	uint8_t *buf;
	size_t buflen;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);
	plen = enc_find_info_req(start, end, buf, buflen);
	if (plen == 0)
		return 0;

	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
}
Ejemplo n.º 20
0
static guint execute_write(GAttrib *attrib, uint8_t flags,
				GAttribResultFunc func, gpointer user_data)
{
	uint8_t *buf;
	size_t buflen;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);
	plen = enc_exec_write_req(flags, buf, buflen);
	if (plen == 0)
		return 0;

	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
}
Ejemplo n.º 21
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);
}
Ejemplo n.º 22
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);
}
Ejemplo n.º 23
0
static guint resolve_included_uuid(struct included_discovery *isd,
					struct gatt_included *incl)
{
	struct included_uuid_query *query;
	size_t buflen;
	uint8_t *buf = g_attrib_get_buffer(isd->attrib, &buflen);
	guint16 oplen = enc_read_req(incl->range.start, buf, buflen);

	query = g_new0(struct included_uuid_query, 1);
	query->isd = isd_ref(isd);
	query->included = incl;

	return g_attrib_send(isd->attrib, 0, buf, oplen,
				resolve_included_uuid_cb, query, NULL);
}
Ejemplo n.º 24
0
guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
				GAttribResultFunc func, gpointer user_data)
{
	uint8_t *buf;
	int buflen;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);
	plen = enc_find_info_req(start, end, buf, buflen);
	if (plen == 0)
		return 0;

	return g_attrib_send(attrib, 0, ATT_OP_FIND_INFO_REQ, buf, plen, func,
							user_data, NULL);
}
Ejemplo n.º 25
0
guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
			int vlen, GAttribResultFunc func, gpointer user_data)
{
	uint8_t *buf;
	int buflen;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);
	if (func)
		plen = enc_write_req(handle, value, vlen, buf, buflen);
	else
		plen = enc_write_cmd(handle, value, vlen, buf, buflen);

	return g_attrib_send(attrib, 0, buf[0], buf, plen, func,
							user_data, NULL);
}
Ejemplo n.º 26
0
static void read_blob_helper(guint8 status, const guint8 *rpdu, guint16 rlen,
							gpointer user_data)
{
	struct read_long_data *long_read = user_data;
	uint8_t *buf;
	int buflen;
	guint8 *tmp;
	guint16 plen;
	guint id;

	if (status != 0 || rlen == 1) {
		status = 0;
		goto done;
	}

	tmp = g_try_realloc(long_read->buffer, long_read->size + rlen - 1);

	if (tmp == NULL) {
		status = ATT_ECODE_INSUFF_RESOURCES;
		goto done;
	}

	memcpy(&tmp[long_read->size], &rpdu[1], rlen - 1);
	long_read->buffer = tmp;
	long_read->size += rlen - 1;

	buf = g_attrib_get_buffer(long_read->attrib, &buflen);
	if (rlen < buflen)
		goto done;

	plen = enc_read_blob_req(long_read->handle, long_read->size - 1,
								buf, buflen);
	id = g_attrib_send(long_read->attrib, long_read->id,
				ATT_OP_READ_BLOB_REQ, buf, plen,
				read_blob_helper, long_read, read_long_destroy);

	if (id != 0) {
		g_atomic_int_inc(&long_read->ref);
		return;
	}

	status = ATT_ECODE_IO;

done:
	long_read->func(status, long_read->buffer, long_read->size,
							long_read->user_data);
}
Ejemplo n.º 27
0
guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
					const uint8_t *value, size_t vlen,
					GAttribResultFunc func,
					gpointer user_data)
{
	uint8_t *buf;
	guint16 plen;
	size_t buflen;

	buf = g_attrib_get_buffer(attrib, &buflen);

	plen = enc_prep_write_req(handle, 0, value, vlen, buf, buflen);
	if (!plen)
		return 0;

	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
}
Ejemplo n.º 28
0
static void events_handler(const uint8_t *pdu, uint16_t len,
							gpointer user_data)
{
	struct gatt_service *gatt = user_data;
	struct characteristic *chr;
	GSList *l;
	uint8_t opdu[ATT_MAX_MTU];
	guint handle;
	uint16_t olen;

	if (len < 3) {
		DBG("Malformed notification/indication packet (opcode 0x%02x)",
									pdu[0]);
		return;
	}

	handle = att_get_u16(&pdu[1]);

	l = g_slist_find_custom(gatt->chars, GUINT_TO_POINTER(handle),
						characteristic_handle_cmp);

	if (!l)
		return;

	chr = l->data;

	if (chr == NULL) {
		DBG("Attribute handle 0x%02x not found", handle);
		return;
	}

	switch (pdu[0]) {
	case ATT_OP_HANDLE_IND:
		olen = enc_confirmation(opdu, sizeof(opdu));
		g_attrib_send(gatt->attrib, 0, opdu[0], opdu, olen,
						NULL, NULL, NULL);

	case ATT_OP_HANDLE_NOTIFY:
		if (characteristic_set_value(chr, &pdu[3], len - 3) < 0)
			DBG("Can't change Characteristic 0x%02x", handle);

		g_slist_foreach(gatt->watchers, update_watchers_valuechange, chr);
		break;
	}
}
Ejemplo n.º 29
0
static guint prepare_write(struct write_long_data *long_write)
{
	GAttrib *attrib = long_write->attrib;
	uint16_t handle = long_write->handle;
	uint16_t offset = long_write->offset;
	uint8_t *buf, *value = long_write->value + offset;
	size_t buflen, vlen = long_write->vlen - offset;
	guint16 plen;

	buf = g_attrib_get_buffer(attrib, &buflen);

	plen = enc_prep_write_req(handle, offset, value, vlen, buf, buflen);
	if (plen == 0)
		return 0;

	return g_attrib_send(attrib, 0, buf, plen, prepare_write_cb, long_write,
									NULL);
}
Ejemplo n.º 30
0
static guint prepare_write(GAttrib *attrib, uint16_t handle, uint16_t offset,
			uint8_t *value, size_t vlen, GAttribResultFunc func,
			gpointer user_data)
{
	guint16 plen;
	size_t buflen;
	uint8_t *buf;

	buf = g_attrib_get_buffer(attrib, &buflen);

	plen = enc_prep_write_req(handle, offset, &value[offset], vlen - offset,
								buf, buflen);
	if (plen == 0)
		return 0;

	return g_attrib_send(attrib, 0, buf, plen, prepare_write_cb,
							user_data, NULL);
}