Beispiel #1
0
static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct hog_device *hogdev = user_data;
	uint8_t value[HOG_REPORT_MAP_MAX_SIZE];
	struct uhid_event ev;
	uint16_t vendor_src, vendor, product, version;
	ssize_t vlen;
	int i;

	if (status != 0) {
		error("Report Map read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("ATT protocol error");
		return;
	}

	DBG("Report MAP:");
	for (i = 0; i < vlen; i++) {
		switch (value[i]) {
		case 0x85:
		case 0x86:
		case 0x87:
			hogdev->prepend_id = TRUE;
		}

		if (i % 2 == 0) {
			if (i + 1 == vlen)
				DBG("\t %02x", value[i]);
			else
				DBG("\t %02x %02x", value[i], value[i + 1]);
		}
	}

	vendor_src = btd_device_get_vendor_src(hogdev->device);
	vendor = btd_device_get_vendor(hogdev->device);
	product = btd_device_get_product(hogdev->device);
	version = btd_device_get_version(hogdev->device);
	DBG("DIS information: vendor_src=0x%X, vendor=0x%X, product=0x%X, "
			"version=0x%X",	vendor_src, vendor, product, version);

	/* create uHID device */
	memset(&ev, 0, sizeof(ev));
	ev.type = UHID_CREATE;
	strcpy((char *) ev.u.create.name, "bluez-hog-device");
	ev.u.create.vendor = vendor;
	ev.u.create.product = product;
	ev.u.create.version = version;
	ev.u.create.country = hogdev->bcountrycode;
	ev.u.create.bus = BUS_BLUETOOTH;
	ev.u.create.rd_data = value;
	ev.u.create.rd_size = vlen;

	if (write(hogdev->uhid_fd, &ev, sizeof(ev)) < 0)
		error("Failed to create uHID device: %s", strerror(errno));
}
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen, gpointer user_data)
{
  uint8_t value[plen];
  ssize_t vlen;
  int i;
  GString *s;

  if (status != 0) {
    printf("Characteristic value/descriptor read failed: %s\n", att_ecode2str(status));
    goto label;
  }

  vlen = dec_read_resp(pdu, plen, value, sizeof(value));
  if (vlen < 0) {
    printf("Protocol error\n");
    goto label;
  }

  s = g_string_new("Characteristic value/descriptor: ");
  for (i = 0; i < vlen; i++) {
    g_string_append_printf(s, "%02x ", value[i]);
  }

  printf("%s\n", s->str);
  g_string_free(s, TRUE);

label:
  g_main_loop_quit(event_loop);
  return;
}
Beispiel #3
0
static void resolve_included_uuid_cb(uint8_t status, const uint8_t *pdu,
					uint16_t len, gpointer user_data)
{
	struct included_uuid_query *query = user_data;
	struct included_discovery *isd = query->isd;
	struct gatt_included *incl = query->included;
	unsigned int err = status;
	bt_uuid_t uuid;
	size_t buflen;
	uint8_t *buf;

	if (err)
		goto done;

	buf = g_attrib_get_buffer(isd->attrib, &buflen);
	if (dec_read_resp(pdu, len, buf, buflen) != 16) {
		err = ATT_ECODE_IO;
		goto done;
	}

	uuid = att_get_uuid128(buf);
	bt_uuid_to_string(&uuid, incl->uuid, sizeof(incl->uuid));
	isd->includes = g_slist_append(isd->includes, incl);

done:
	if (err)
		g_free(incl);

	if (isd->err == 0)
		isd->err = err;

	isd_unref(isd);

	g_free(query);
}
static void read_feature_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct csc *csc = user_data;
	uint8_t value[2];
	ssize_t vlen;

	if (status) {
		error("CSC Feature read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error");
		return;
	}

	if (vlen != sizeof(value)) {
		error("Invalid value length for CSC Feature");
		return;
	}

	csc->feature = get_le16(value);

	if ((csc->feature & MULTI_SENSOR_LOC_SUPPORT)
						&& (csc->locations == NULL))
		read_supported_locations(csc);
}
Beispiel #5
0
static void read_sensor_location_cb(guint8 status, const guint8 *pdu,
						guint16 len, gpointer user_data)
{
	struct heartrate *hr = user_data;
	uint8_t value;
	ssize_t vlen;

	if (status != 0) {
		error("Body Sensor Location read failed: %s",
							att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, &value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error");
		return;
	}

	if (vlen != sizeof(value)) {
		error("Invalid length for Body Sensor Location");
		return;
	}

	hr->has_location = TRUE;
	hr->location = value;
}
Beispiel #6
0
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
                         gpointer user_data)
{
    uint8_t value[ATT_MAX_MTU];
    int i, vlen;

    if (status != 0) {
        printf("Characteristic value/descriptor read failed: %s\n",
               att_ecode2str(status));
        goto done;
    }

    if (!dec_read_resp(pdu, plen, value, &vlen)) {
        printf("Protocol error\n");
        goto done;
    }

    printf("\nCharacteristic value/descriptor: ");
    for (i = 0; i < vlen; i++)
        printf("%02x ", value[i]);

done:
    printf("\n%s", get_prompt());
    fflush(stdout);
}
static void read_location_cb(guint8 status, const guint8 *pdu,
						guint16 len, gpointer user_data)
{
	struct csc *csc = user_data;
	uint8_t value;
	ssize_t vlen;

	if (status) {
		error("Sensor Location read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, &value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error");
		return;
	}

	if (vlen != sizeof(value)) {
		error("Invalid value length for Sensor Location");
		return;
	}

	csc->has_location = TRUE;
	csc->location = value;

	g_dbus_emit_property_changed(btd_get_dbus_connection(),
					device_get_path(csc->dev),
					CYCLINGSPEED_INTERFACE, "Location");
}
Beispiel #8
0
static void proto_mode_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct hog_device *hogdev = user_data;
	uint8_t value;
	ssize_t vlen;

	if (status != 0) {
		error("Protocol Mode characteristic read failed: %s",
							att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, &value, sizeof(value));
	if (vlen < 0) {
		error("ATT protocol error");
		return;
	}

	if (value == HOG_PROTO_MODE_BOOT) {
		uint8_t nval = HOG_PROTO_MODE_REPORT;

		DBG("HoG device 0x%04X is operating in Boot Procotol Mode",
								hogdev->id);

		gatt_write_cmd(hogdev->attrib, hogdev->proto_mode_handle, &nval,
						sizeof(nval), NULL, NULL);
	} else if (value == HOG_PROTO_MODE_REPORT)
		DBG("HoG device 0x%04X is operating in Report Protocol Mode",
								hogdev->id);
}
Beispiel #9
0
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[ATT_MAX_MTU];
	ssize_t vlen;
	int i;

	if (status != 0) {
		g_printerr("Characteristic value/descriptor read failed: %s\n",
							att_ecode2str(status));
		goto done;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		g_printerr("Protocol error\n");
		goto done;
	}
	g_print("Characteristic value/descriptor: ");
	for (i = 0; i < vlen; i++)
		g_print("%02x ", value[i]);
	g_print("\n");

done:
	if (opt_listen == FALSE)
		g_main_loop_quit(event_loop);
}
Beispiel #10
0
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[plen];
	ssize_t vlen;
	int i;
	GString *s;

	if (status != 0) {
		error("Characteristic value/descriptor read failed: %s\n",
							att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error\n");
		return;
	}
	//rl_printf("%d\n",vlen);
	//rl_printf("%d\n",value[0]);
	//s = g_string_new("Characteristic value/descriptor: ");
	for (i = 0; i < vlen; i++)
		{
			//data[i] = value[i];
			//g_string_append_printf(s, "%02x ", value[i]);
		}
	//pocessing_data(data);
	//rl_printf("%s\n", s->str);
	//g_string_free(s, TRUE);
}
Beispiel #11
0
static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct characteristic *ch = user_data;
	uint8_t value[ATT_MAX_MTU];
	int vlen;

	if (status != 0) {
		error("Error reading PNP_ID value: %s", att_ecode2str(status));
		return;
	}

	if (!dec_read_resp(pdu, len, value, &vlen)) {
		error("Error reading PNP_ID: Protocol error");
		return;
	}

	if (vlen < 7) {
		error("Error reading PNP_ID: Invalid pdu length received");
		return;
	}

	device_set_pnpid(ch->d->dev, value[0], att_get_u16(&value[1]),
				att_get_u16(&value[3]), att_get_u16(&value[5]));
}
Beispiel #12
0
static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct characteristic *ch = user_data;
	uint8_t value[PNP_ID_SIZE];
	ssize_t vlen;

	if (status != 0) {
		error("Error reading PNP_ID value: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, value, sizeof(value));
	if (vlen < 0) {
		error("Error reading PNP_ID: Protocol error");
		return;
	}

	if (vlen < 7) {
		error("Error reading PNP_ID: Invalid pdu length received");
		return;
	}

	btd_device_set_pnpid(ch->d->dev, value[0], get_le16(&value[1]),
				get_le16(&value[3]), get_le16(&value[5]));
}
Beispiel #13
0
static void info_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct hog_device *hogdev = user_data;
	uint8_t value[HID_INFO_SIZE];
	ssize_t vlen;

	if (status != 0) {
		error("HID Information read failed: %s",
						att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen != 4) {
		error("ATT protocol error");
		return;
	}

	hogdev->bcdhid = get_le16(&value[0]);
	hogdev->bcountrycode = value[2];
	hogdev->flags = value[3];

	DBG("bcdHID: 0x%04X bCountryCode: 0x%02X Flags: 0x%02X",
			hogdev->bcdhid, hogdev->bcountrycode, hogdev->flags);
}
Beispiel #14
0
static void char_read_single_cb(guint8 status, const guint8 *pdu, guint16 plen,
                            gpointer user_data)
{
    uint8_t value[plen];
    ssize_t vlen;

    if (status != 0) {
        resp_error_comm(status);
        return;
    }

    if ((pdu != NULL) && (plen >= 1)) {
        if (pdu[0] == ATT_OP_READ_RESP)
            vlen = dec_read_resp(pdu, plen, value, sizeof(value));
        else
            vlen = dec_read_blob_resp(pdu, plen, value, sizeof(value));
    } else {
        vlen = -EINVAL;
    }
    if (vlen < 0) {
        resp_error(err_PROTO_ERR);
        return;
    }

    resp_begin(rsp_READ);
    send_data(value, vlen);
    resp_end();
}
Beispiel #15
0
void read_by_hnd_cb(guint8 status, const guint8 *pdu, guint16 plen,
                    gpointer user_data)
{
    uint8_t   data[plen];
    ssize_t   vlen;
    cb_ctx_t *cb_ctx = user_data;

    printf_dbg("[CB] IN read_by_hnd_cb\n");
    if (status) {
        cb_ctx->cb_ret_val = BL_REQUEST_FAIL_ERROR;
        sprintf(cb_ctx->cb_ret_msg, "Read by handle callback: Failure: %s\n",
                att_ecode2str(status));
        goto error;
    }

    if (data == NULL) {
        cb_ctx->cb_ret_val = BL_MALLOC_ERROR;
        strcpy(cb_ctx->cb_ret_msg, "Read by handle callback: Malloc error\n");
        goto error;
    }

    vlen = dec_read_resp(pdu, plen, data, sizeof(data));
    if (vlen < 0) {
        cb_ctx->cb_ret_val = BL_PROTOCOL_ERROR;
        strcpy(cb_ctx->cb_ret_msg,
               "Read by handle callback: Protocol error\n");
        goto error;
    }

    cb_ctx->cb_ret_pointer = bl_value_new(NULL, 0, vlen, data);
    if (cb_ctx->cb_ret_pointer == NULL) {
        cb_ctx->cb_ret_val = BL_MALLOC_ERROR;
        strcpy(cb_ctx->cb_ret_msg, "Read by handle callback: Malloc error\n");
    }

    cb_ctx->cb_ret_val = BL_NO_ERROR;
    goto exit;

error:
    if (cb_ctx->cb_ret_pointer)
        free(cb_ctx->cb_ret_pointer);
exit:
    g_mutex_unlock(&cb_ctx->pending_cb_mtx);
    printf_dbg("[CB] OUT read_by_hnd_cb\n");
}
Beispiel #16
0
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	if (status != 0) {
		error("Characteristic value/descriptor read failed: %s\n",
							att_ecode2str(status));
		return;
	}

	uint8_t value[plen];
	ssize_t vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("Protocol error\n");
		return;
	}

        handle_vehicle_msg_response(value, vlen);
}
Beispiel #17
0
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[plen];
	ssize_t vlen;

	if (status != 0) {
		resp_error(err_COMM_ERR); // Todo: status
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		resp_error(err_COMM_ERR);
		return;
	}

	resp_begin(rsp_READ);
        send_data(value, vlen);
        resp_end();
}
Beispiel #18
0
static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct gatt_request *req = user_data;
	struct bt_dis *dis = req->user_data;
	uint8_t value[PNP_ID_SIZE];
	ssize_t vlen;

	destroy_gatt_req(req);

	if (status != 0) {
		error("Error reading PNP_ID value: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, len, value, sizeof(value));
	if (vlen < 0) {
		error("Error reading PNP_ID: Protocol error");
		return;
	}

	if (vlen < 7) {
		error("Error reading PNP_ID: Invalid pdu length received");
		return;
	}

	dis->source = value[0];
	dis->vendor = get_le16(&value[1]);
	dis->product = get_le16(&value[3]);
	dis->version = get_le16(&value[5]);

	DBG("source: 0x%02X vendor: 0x%04X product: 0x%04X version: 0x%04X",
			dis->source, dis->vendor, dis->product, dis->version);

	if (dis->notify)
		dis->notify(dis->source, dis->vendor, dis->product,
						dis->version, dis->notify_data);
}
Beispiel #19
0
static void tx_power_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[ATT_MAX_MTU];
	int vlen;

	if (status != 0) {
		DBG("Tx Power Level read failed: %s", att_ecode2str(status));
		return;
	}

	if (!dec_read_resp(pdu, plen, value, &vlen)) {
		DBG("Protocol error");
		return;
	}

	if (vlen != 1) {
		DBG("Invalid length for TX Power value: %d", vlen);
		return;
	}

	DBG("Tx Power Level: %02x", (int8_t) value[0]);
}
Beispiel #20
0
//callback function for when we receive a ble message
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[plen];
	ssize_t vlen;

	if (status != 0) {
		printf("Characteristic value/descriptor read failed: %s\n",
							att_ecode2str(status));
		ble_disconnect();
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		printf("Protocol error\n");
		ble_disconnect();
		return;
	}

	ble_read_val = value;
	ble_read_len = vlen;
	ble_read = 1;
}
Beispiel #21
0
static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[ATT_MAX_MTU];
	int i, vlen;

	if (status != 0) {
		printf("Characteristic value/descriptor read failed: %s\n",
							att_ecode2str(status));
		return;
	}

	if (!dec_read_resp(pdu, plen, value, &vlen)) {
		printf("Protocol error\n");
		return;
	}

	printf("\nCharacteristic value/descriptor: ");
	for (i = 0; i < vlen; i++)
		printf("%02x ", value[i]);
	printf("\n");

	rl_forced_update_display();
}
Beispiel #22
0
static void tx_power_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	uint8_t value[TX_POWER_SIZE];
	ssize_t vlen;

	if (status != 0) {
		DBG("Tx Power Level read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		DBG("Protocol error");
		return;
	}

	if (vlen != 1) {
		DBG("Invalid length for TX Power value: %zd", vlen);
		return;
	}

	DBG("Tx Power Level: %02x", (int8_t) value[0]);
}
Beispiel #23
0
static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct hog_device *hogdev = user_data;
	struct btd_adapter *adapter = device_get_adapter(hogdev->device);
	uint8_t value[HOG_REPORT_MAP_MAX_SIZE];
	struct uhid_event ev;
	uint16_t vendor_src, vendor, product, version;
	ssize_t vlen;
	char itemstr[20]; /* 5x3 (data) + 4 (continuation) + 1 (null) */
	int i, err;

	if (status != 0) {
		error("Report Map read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("ATT protocol error");
		return;
	}

	DBG("Report MAP:");
	for (i = 0; i < vlen;) {
		ssize_t ilen = 0;
		bool long_item = false;

		if (get_descriptor_item_info(&value[i], vlen - i, &ilen,
								&long_item)) {
			/* Report ID is short item with prefix 100001xx */
			if (!long_item && (value[i] & 0xfc) == 0x84)
				hogdev->has_report_id = TRUE;

			DBG("\t%s", item2string(itemstr, &value[i], ilen));

			i += ilen;
		} else {
			error("Report Map parsing failed at %d", i);

			/* Just print remaining items at once and break */
			DBG("\t%s", item2string(itemstr, &value[i], vlen - i));
			break;
		}
	}

	vendor_src = btd_device_get_vendor_src(hogdev->device);
	vendor = btd_device_get_vendor(hogdev->device);
	product = btd_device_get_product(hogdev->device);
	version = btd_device_get_version(hogdev->device);
	DBG("DIS information: vendor_src=0x%X, vendor=0x%X, product=0x%X, "
			"version=0x%X",	vendor_src, vendor, product, version);

	/* create uHID device */
	memset(&ev, 0, sizeof(ev));
	ev.type = UHID_CREATE;
	if (device_name_known(hogdev->device))
		device_get_name(hogdev->device, (char *) ev.u.create.name,
						sizeof(ev.u.create.name));
	else
		strcpy((char *) ev.u.create.name, "bluez-hog-device");
	ba2str(btd_adapter_get_address(adapter), (char *) ev.u.create.phys);
	ba2str(device_get_address(hogdev->device), (char *) ev.u.create.uniq);
	ev.u.create.vendor = vendor;
	ev.u.create.product = product;
	ev.u.create.version = version;
	ev.u.create.country = hogdev->bcountrycode;
	ev.u.create.bus = BUS_BLUETOOTH;
	ev.u.create.rd_data = value;
	ev.u.create.rd_size = vlen;

	err = bt_uhid_send(hogdev->uhid, &ev);
	if (err < 0) {
		error("bt_uhid_send: %s", strerror(-err));
		return;
	}

	bt_uhid_register(hogdev->uhid, UHID_OUTPUT, forward_report, hogdev);
	bt_uhid_register(hogdev->uhid, UHID_SET_REPORT, set_report, hogdev);
	bt_uhid_register(hogdev->uhid, UHID_GET_REPORT, get_report, hogdev);
}
Beispiel #24
0
static void report_map_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
							gpointer user_data)
{
	struct bt_hog *hog = user_data;
	uint8_t value[HOG_REPORT_MAP_MAX_SIZE];
	struct uhid_event ev;
	ssize_t vlen;
	char itemstr[20]; /* 5x3 (data) + 4 (continuation) + 1 (null) */
	int i, err;
	GError *gerr = NULL;

	if (status != 0) {
		error("Report Map read failed: %s", att_ecode2str(status));
		return;
	}

	vlen = dec_read_resp(pdu, plen, value, sizeof(value));
	if (vlen < 0) {
		error("ATT protocol error");
		return;
	}

	DBG("Report MAP:");
	for (i = 0; i < vlen;) {
		ssize_t ilen = 0;
		bool long_item = false;

		if (get_descriptor_item_info(&value[i], vlen - i, &ilen,
								&long_item)) {
			/* Report ID is short item with prefix 100001xx */
			if (!long_item && (value[i] & 0xfc) == 0x84)
				hog->has_report_id = TRUE;

			DBG("\t%s", item2string(itemstr, &value[i], ilen));

			i += ilen;
		} else {
			error("Report Map parsing failed at %d", i);

			/* Just print remaining items at once and break */
			DBG("\t%s", item2string(itemstr, &value[i], vlen - i));
			break;
		}
	}

	/* create uHID device */
	memset(&ev, 0, sizeof(ev));
	ev.type = UHID_CREATE;

	bt_io_get(g_attrib_get_channel(hog->attrib), &gerr,
			BT_IO_OPT_SOURCE, ev.u.create.phys,
			BT_IO_OPT_DEST, ev.u.create.uniq,
			BT_IO_OPT_INVALID);
	if (gerr) {
		error("Failed to connection details: %s", gerr->message);
		g_error_free(gerr);
		return;
	}

	strcpy((char *) ev.u.create.name, hog->name);
	ev.u.create.vendor = hog->vendor;
	ev.u.create.product = hog->product;
	ev.u.create.version = hog->version;
	ev.u.create.country = hog->bcountrycode;
	ev.u.create.bus = BUS_BLUETOOTH;
	ev.u.create.rd_data = value;
	ev.u.create.rd_size = vlen;

	err = bt_uhid_send(hog->uhid, &ev);
	if (err < 0) {
		error("bt_uhid_send: %s", strerror(-err));
		return;
	}

	bt_uhid_register(hog->uhid, UHID_OUTPUT, forward_report, hog);
	bt_uhid_register(hog->uhid, UHID_FEATURE, forward_report, hog);
}