Пример #1
0
static void extract_hid_record(sdp_record_t *rec, struct hidp_connadd_req *req)
{
	sdp_data_t *pdlist, *pdlist2;
	uint8_t attr_val;

	pdlist = sdp_data_get(rec, 0x0101);
	pdlist2 = sdp_data_get(rec, 0x0102);
	if (pdlist) {
		if (pdlist2) {
			if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) {
				strncpy(req->name, pdlist2->val.str, 127);
				strcat(req->name, " ");
			}
			strncat(req->name, pdlist->val.str, 127 - strlen(req->name));
		} else
			strncpy(req->name, pdlist->val.str, 127);
	} else {
		pdlist2 = sdp_data_get(rec, 0x0100);
		if (pdlist2)
			strncpy(req->name, pdlist2->val.str, 127);
	}

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_PARSER_VERSION);
	req->parser = pdlist ? pdlist->val.uint16 : 0x0100;

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS);
	req->subclass = pdlist ? pdlist->val.uint8 : 0;

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE);
	req->country = pdlist ? pdlist->val.uint8 : 0;

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_VIRTUAL_CABLE);
	attr_val = pdlist ? pdlist->val.uint8 : 0;
	if (attr_val)
		req->flags |= (1 << HIDP_VIRTUAL_CABLE_UNPLUG);

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE);
	attr_val = pdlist ? pdlist->val.uint8 : 0;
	if (attr_val)
		req->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);

	pdlist = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
	if (pdlist) {
		pdlist = pdlist->val.dataseq;
		pdlist = pdlist->val.dataseq;
		pdlist = pdlist->next;

		req->rd_data = g_try_malloc0(pdlist->unitSize);
		if (req->rd_data) {
			memcpy(req->rd_data, (unsigned char *) pdlist->val.str,
								pdlist->unitSize);
			req->rd_size = pdlist->unitSize;
			epox_endian_quirk(req->rd_data, req->rd_size);
		}
	}
}
Пример #2
0
/* See HID profile specification v1.0, "7.11.6 HIDDescriptorList" for details
 * on the attribute format. */
static int extract_hid_desc_data(sdp_record_t *rec,
                                 struct hidp_connadd_req *req)
{
    sdp_data_t *d;

    d = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST);
    if (!d)
        goto invalid_desc;

    if (!SDP_IS_SEQ(d->dtd))
        goto invalid_desc;

    /* First HIDDescriptor */
    d = d->val.dataseq;
    if (!SDP_IS_SEQ(d->dtd))
        goto invalid_desc;

    /* ClassDescriptorType */
    d = d->val.dataseq;
    if (d->dtd != SDP_UINT8)
        goto invalid_desc;

    /* ClassDescriptorData */
    d = d->next;
    if (!d || !SDP_IS_TEXT_STR(d->dtd))
        goto invalid_desc;

    req->rd_data = g_try_malloc0(d->unitSize);
    if (req->rd_data) {
        memcpy(req->rd_data, d->val.str, d->unitSize);
        req->rd_size = d->unitSize;
        epox_endian_quirk(req->rd_data, req->rd_size);
    }

    return 0;

invalid_desc:
    error("Missing or invalid HIDDescriptorList SDP attribute");
    return -EINVAL;
}