Example #1
0
static void
hid_dump_descriptor(report_desc_t r)
{
	struct hid_data	*d = NULL;
	struct hid_item	 h;

	for (d = hid_start_parse(r, ~0, -1); hid_get_item(d, &h); ) {
		switch (h.kind) {
		case hid_collection:
			fprintf(stdout,
"Collection page=%s usage=%s\n", hid_usage_page(HID_PAGE(h.usage)),
				 hid_usage_in_page(h.usage));
			break;

		case hid_endcollection:
			fprintf(stdout, "End collection\n");
			break;

		case hid_input:
			hid_dump_item("Input  ", &h);
			break;

		case hid_output:
			hid_dump_item("Output ", &h);
			break;

		case hid_feature:
			hid_dump_item("Feature", &h);
			break;
		}
	}

	hid_end_parse(d);
}
Example #2
0
static void
dumpitem(const char *label, struct hid_item *h)
{
	if ((h->flags & HIO_CONST) && !verbose)
		return;
	printf("%s rid=%d size=%d count=%d page=%s usage=%s%s%s", label,
	       h->report_ID, h->report_size, h->report_count,
	       hid_usage_page(HID_PAGE(h->usage)),
	       hid_usage_in_page(h->usage),
	       h->flags & HIO_CONST ? " Const" : "",
	       h->flags & HIO_VARIABLE ? "" : " Array");
	printf(", logical range %d..%d",
	       h->logical_minimum, h->logical_maximum);
	if (h->physical_minimum != h->physical_maximum)
		printf(", physical range %d..%d",
		       h->physical_minimum, h->physical_maximum);
	if (h->unit)
		printf(", unit=0x%02x exp=%d", h->unit, h->unit_exponent);
	printf("\n");
}
Example #3
0
static void
dumpitems(report_desc_t r)
{
	struct hid_data *d;
	struct hid_item h;
	int size;

	for (d = hid_start_parse(r, ~0, -1); hid_get_item(d, &h); ) {
		switch (h.kind) {
		case hid_collection:
			printf("Collection type=%s page=%s usage=%s\n",
			       hid_collection_type(h.collection),
			       hid_usage_page(HID_PAGE(h.usage)),
			       hid_usage_in_page(h.usage));
			break;
		case hid_endcollection:
			printf("End collection\n");
			break;
		case hid_input:
			dumpitem("Input  ", &h);
			break;
		case hid_output:
			dumpitem("Output ", &h);
			break;
		case hid_feature:
			dumpitem("Feature", &h);
			break;
		}
	}
	hid_end_parse(d);
	size = hid_report_size(r, hid_input, -1);
	printf("Total   input size %d bytes\n", size);

	size = hid_report_size(r, hid_output, -1);
	printf("Total  output size %d bytes\n", size);

	size = hid_report_size(r, hid_feature, -1);
	printf("Total feature size %d bytes\n", size);
}
Example #4
0
static void
hid_dump_item(char const *label, struct hid_item *h)
{
	if ((h->flags & HIO_CONST) && !verbose)
		return;

	fprintf(stdout,
"%s id=%u size=%u count=%u page=%s usage=%s%s%s%s%s%s%s%s%s%s",
		label, (uint8_t) h->report_ID, h->report_size, h->report_count,
		hid_usage_page(HID_PAGE(h->usage)),
		hid_usage_in_page(h->usage),
		h->flags & HIO_CONST ? " Const" : "",
		h->flags & HIO_VARIABLE ? " Variable" : "",
		h->flags & HIO_RELATIVE ? " Relative" : "",
		h->flags & HIO_WRAP ? " Wrap" : "",
		h->flags & HIO_NONLINEAR ? " NonLinear" : "",
		h->flags & HIO_NOPREF ? " NoPref" : "",
		h->flags & HIO_NULLSTATE ? " NullState" : "",
		h->flags & HIO_VOLATILE ? " Volatile" : "",
		h->flags & HIO_BUFBYTES ? " BufBytes" : "");

	fprintf(stdout,
", logical range %d..%d",
		h->logical_minimum, h->logical_maximum);

	if (h->physical_minimum != h->physical_maximum)
		fprintf(stdout,
", physical range %d..%d",
			h->physical_minimum, h->physical_maximum);

	if (h->unit)
		fprintf(stdout,
", unit=0x%02x exp=%d", h->unit, h->unit_exponent);

	fprintf(stdout, "\n");
}
Example #5
0
struct command *
parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore)
{
	FILE *f;
	char *p;
	int line;
	char buf[SIZE], name[SIZE], value[SIZE], debounce[SIZE], action[SIZE];
	char usbuf[SIZE], coll[SIZE], *tmp;
	struct command *cmd, *cmds;
	struct hid_data *d;
	struct hid_item h;
	int inst, cinst, u, lo, hi, range, t;

	f = fopen(conf, "r");
	if (f == NULL)
		err(1, "%s", conf);

	cmds = NULL;
	for (line = 1; ; line++) {
		if (fgets(buf, sizeof buf, f) == NULL)
			break;
		if (buf[0] == '#' || buf[0] == '\n')
			continue;
		p = strchr(buf, '\n');
		while (p && isspace(peek(f))) {
			if (fgets(p, sizeof buf - strlen(buf), f) == NULL)
				break;
			p = strchr(buf, '\n');
		}
		if (p)
			*p = 0;
		if (sscanf(buf, "%s %s %s %[^\n]",
			   name, value, debounce, action) != 4) {
			if (isdemon) {
				syslog(LOG_WARNING, "config file `%s', line %d"
				       ", syntax error: %s", conf, line, buf);
				freecommands(cmds);
				return (NULL);
			} else {
				errx(1, "config file `%s', line %d,"
				     ", syntax error: %s", conf, line, buf);
			}
		}
		tmp = strchr(name, '#');
		if (tmp != NULL) {
			*tmp = 0;
			inst = atoi(tmp + 1);
		} else
			inst = 0;

		cmd = malloc(sizeof *cmd);
		if (cmd == NULL)
			err(1, "malloc failed");
		cmd->next = cmds;
		cmds = cmd;
		cmd->line = line;

		if (strcmp(value, "*") == 0) {
			cmd->anyvalue = 1;
		} else {
			cmd->anyvalue = 0;
			if (sscanf(value, "%d", &cmd->value) != 1) {
				if (isdemon) {
					syslog(LOG_WARNING,
					       "config file `%s', line %d, "
					       "bad value: %s (should be * or a number)\n",
					       conf, line, value);
					freecommands(cmds);
					return (NULL);
				} else {
					errx(1, "config file `%s', line %d, "
					     "bad value: %s (should be * or a number)\n",
					     conf, line, value);
				}
			}
		}

		if (sscanf(debounce, "%d", &cmd->debounce) != 1) {
			if (isdemon) {
				syslog(LOG_WARNING,
				       "config file `%s', line %d, "
				       "bad value: %s (should be a number >= 0)\n",
				       conf, line, debounce);
				freecommands(cmds);
				return (NULL);
			} else {
				errx(1, "config file `%s', line %d, "
				     "bad value: %s (should be a number >= 0)\n",
				     conf, line, debounce);
			}
		}

		coll[0] = 0;
		cinst = 0;
		for (d = hid_start_parse(repd, 1 << hid_input, reportid);
		     hid_get_item(d, &h); ) {
			if (verbose > 2)
				printf("kind=%d usage=%x\n", h.kind, h.usage);
			if (h.flags & HIO_CONST)
				continue;
			switch (h.kind) {
			case hid_input:
				if (h.usage_minimum != 0 ||
				    h.usage_maximum != 0) {
					lo = h.usage_minimum;
					hi = h.usage_maximum;
					range = 1;
				} else {
					lo = h.usage;
					hi = h.usage;
					range = 0;
				}
				for (u = lo; u <= hi; u++) {
					if (coll[0]) {
						snprintf(usbuf, sizeof usbuf,
						  "%s.%s:%s", coll+1,
						  hid_usage_page(HID_PAGE(u)),
						  hid_usage_in_page(u));
					} else {
						snprintf(usbuf, sizeof usbuf,
						  "%s:%s",
						  hid_usage_page(HID_PAGE(u)),
						  hid_usage_in_page(u));
					}
					if (verbose > 2)
						printf("usage %s\n", usbuf);
					t = strlen(usbuf) - strlen(name);
					if (t > 0) {
						if (strcmp(usbuf + t, name))
							continue;
						if (usbuf[t - 1] != '.')
							continue;
					} else if (strcmp(usbuf, name))
						continue;
					if (inst == cinst++)
						goto foundhid;
				}
				break;
			case hid_collection:
				snprintf(coll + strlen(coll),
				    sizeof coll - strlen(coll),  ".%s:%s",
				    hid_usage_page(HID_PAGE(h.usage)), 
				    hid_usage_in_page(h.usage));
				break;
			case hid_endcollection:
				if (coll[0])
					*strrchr(coll, '.') = 0;
				break;
			default:
				break;
			}
		}
		if (ignore) {
			if (verbose)
				warnx("ignore item '%s'", name);
			continue;
		}
		if (isdemon) {
			syslog(LOG_WARNING, "config file `%s', line %d, HID "
			       "item not found: `%s'\n", conf, line, name);
			freecommands(cmds);
			return (NULL);
		} else {
			errx(1, "config file `%s', line %d, HID item "
			     "not found: `%s'\n", conf, line, name);
		}

	foundhid:
		hid_end_parse(d);
		cmd->lastseen = -1;
		cmd->lastused = -1;
		cmd->item = h;
		cmd->name = strdup(name);
		cmd->action = strdup(action);
		if (range) {
			if (cmd->value == 1)
				cmd->value = u - lo;
			else
				cmd->value = -1;
		}

		if (verbose)
			printf("PARSE:%d %s, %d, '%s'\n", cmd->line, name,
			       cmd->value, cmd->action);
	}
	fclose(f);
	return (cmds);
}
Example #6
0
static void
parceargs(report_desc_t r, int all, int nnames, char **names)
{
	struct hid_data *d;
	struct hid_item h;
	char colls[1000];
	char hname[1000], *tmp1, *tmp2;
	struct variable *var, **pnext;
	int i, instance, cp, t;

	pnext = &vars;
	if (all) {
		if (wflag)
			errx(1, "Must not specify -w to read variables");
		cp = 0;
		for (d = hid_start_parse(r,
		    1<<hid_input | 1<<hid_output | 1<<hid_feature, -1);
		    hid_get_item(d, &h); ) {
			if (h.kind == hid_collection) {
				cp += sprintf(&colls[cp], "%s%s:%s",
				    cp != 0 ? "." : "",
				    hid_usage_page(HID_PAGE(h.usage)),
				    hid_usage_in_page(h.usage));
			} else if (h.kind == hid_endcollection) {
				tmp1 = strrchr(colls, '.');
				if (tmp1 != NULL) {
					cp -= strlen(tmp1);
					tmp1[0] = 0;
				} else {
					cp = 0;
					colls[0] = 0;
				}
			}
			if ((h.kind != hid_input && h.kind != hid_output &&
			    h.kind != hid_feature) || (h.flags & HIO_CONST))
				continue;
			var = malloc(sizeof(*var));
			memset(var, 0, sizeof(*var));
			asprintf(&var->name, "%s%s%s:%s",
			    colls, colls[0] != 0 ? "." : "",
			    hid_usage_page(HID_PAGE(h.usage)),
			    hid_usage_in_page(h.usage));
			var->h = h;
			*pnext = var;
			pnext = &var->next;
		}
		hid_end_parse(d);
		return;
	}
	for (i = 0; i < nnames; i++) {
		var = malloc(sizeof(*var));
		memset(var, 0, sizeof(*var));
		tmp1 = tmp2 = strdup(names[i]);
		strsep(&tmp2, "=");
		var->name = strsep(&tmp1, "#");
		if (tmp1 != NULL)
			var->instance = atoi(tmp1);
		if (tmp2 != NULL) {
			if (!wflag)
				errx(1, "Must specify -w to write variables");
			var->val = atoi(tmp2);
		} else
			if (wflag)
				errx(1, "Must not specify -w to read variables");
		*pnext = var;
		pnext = &var->next;

		instance = 0;
		cp = 0;
		for (d = hid_start_parse(r,
		    1<<hid_input | 1<<hid_output | 1<<hid_feature, -1);
		    hid_get_item(d, &h); ) {
			if (h.kind == hid_collection) {
				cp += sprintf(&colls[cp], "%s%s:%s",
				    cp != 0 ? "." : "",
				    hid_usage_page(HID_PAGE(h.usage)),
				    hid_usage_in_page(h.usage));
			} else if (h.kind == hid_endcollection) {
				tmp1 = strrchr(colls, '.');
				if (tmp1 != NULL) {
					cp -= strlen(tmp1);
					tmp1[0] = 0;
				} else {
					cp = 0;
					colls[0] = 0;
				}
			}
			if ((h.kind != hid_input && h.kind != hid_output &&
			    h.kind != hid_feature) || (h.flags & HIO_CONST))
				continue;
			snprintf(hname, sizeof(hname), "%s%s%s:%s",
			    colls, colls[0] != 0 ? "." : "",
			    hid_usage_page(HID_PAGE(h.usage)),
			    hid_usage_in_page(h.usage));
			t = strlen(hname) - strlen(var->name);
			if (t > 0) {
				if (strcmp(hname + t, var->name) != 0)
					continue;
				if (hname[t - 1] != '.')
					continue;
			} else if (strcmp(hname, var->name) != 0)
				continue;
			if (var->instance != instance++)
				continue;
			var->h = h;
			break;
		}
		hid_end_parse(d);
		if (var->h.usage == 0)
			errx(1, "Unknown item '%s'", var->name);
	}
}
Example #7
0
int
main (int argc, char **argv)
{
    char *device_file;
    int fd = -1;
    int report_id;
    report_desc_t report_desc;
    struct hid_data *data;
    hid_item_t item;
    boolean is_keyboard = FALSE;
    boolean is_keypad = FALSE;
    boolean is_mouse = FALSE;
    boolean is_joystick = FALSE;

    if (! hfp_init(argc, argv))
        goto end;

    device_file = getenv("HAL_PROP_HIDDEV_DEVICE");
    if (! device_file)
        goto end;

    fd = open(device_file, O_RDONLY);
    if (fd < 0)
        goto end;

    /* give a meaningful process title for ps(1) */
    setproctitle("%s", device_file);

#ifdef HAVE_LIBUSB20
    report_id = hid_get_report_id(fd);
    if (report_id == -1)
#else
    if (ioctl(fd, USB_GET_REPORT_ID, &report_id) < 0)
#endif
        goto end;

    hid_init(NULL);

    report_desc = hid_get_report_desc(fd);
    if (! report_desc)
        goto end;

    for (data = hid_start_parse(report_desc, ~0, report_id); hid_get_item(data, &item);)
        if (item.kind == hid_collection)
        {
            if (item.collection == HID_COLLECTION_APPLICATION)
            {
                const char *page;
                char *full_page;
                int i;

                page = hid_usage_page(HID_PAGE(item.usage));

                full_page = hfp_strdup_printf("%s Page", page);
                for (i = 0; full_page[i] != 0; i++)
                    if (full_page[i] == '_')
                        full_page[i] = ' ';

                libhal_device_property_strlist_append(hfp_ctx, hfp_udi, "hiddev.application_pages", full_page, &hfp_error);
                hfp_free(full_page);
            }

            switch (item.usage)
            {
            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE):
                is_mouse = TRUE;
                break;

            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_JOYSTICK):
            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_GAME_PAD):
                is_joystick = TRUE;
                break;

            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD):
                is_keyboard = TRUE;
                break;

            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYPAD):
                is_keypad = TRUE;
                break;
            }
        }
    hid_end_parse(data);

    hid_dispose_report_desc(report_desc);

    if (is_keyboard || is_mouse || is_joystick || is_keypad)
    {
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input", &hfp_error);
        libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input", &hfp_error);
        libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", device_file, &hfp_error);
    }
    if (is_keyboard)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keyboard", &hfp_error);
    if (is_keypad)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keypad", &hfp_error);
    if (is_keyboard || is_keypad)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keys", &hfp_error);
    if (is_mouse)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.mouse", &hfp_error);
    if (is_joystick)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.joystick", &hfp_error);

end:
    return 0;
}
Example #8
0
void
dumpdata(int f, report_desc_t rd, int loop)
{
	struct hid_data *d;
	struct hid_item h, *hids, *n;
	int r, dlen;
	u_char *dbuf;
	u_int32_t colls[100];
	int sp = 0;
	char namebuf[10000], *namep;

	hids = 0;
	for (d = hid_start_parse(rd, 1<<hid_input, -1);
	     hid_get_item(d, &h); ) {
		if (h.kind == hid_collection)
			colls[++sp] = h.usage;
		else if (h.kind == hid_endcollection)
			--sp;
		if (h.kind != hid_input || (h.flags & HIO_CONST))
			continue;
		h.next = hids;
		h.collection = colls[sp];
		hids = malloc(sizeof *hids);
		*hids = h;
	}
	hid_end_parse(d);
	rev(&hids);
	dlen = hid_report_size(rd, hid_input, -1);
	dbuf = malloc(dlen);
	if (!loop)
		if (hid_set_immed(f, 1) < 0) {
			if (errno == EOPNOTSUPP)
				warnx("device does not support immediate mode, only changes reported.");
			else
				err(1, "USB_SET_IMMED");
		}
	do {
		r = read(f, dbuf, dlen);
		if (r < 1) {
			err(1, "read error");
		}
		for (n = hids; n; n = n->next) {
			if (n->report_ID != 0 && dbuf[0] != n->report_ID)
				continue;
			namep = namebuf;
			namep += sprintf(namep, "%s:%s.",
					 hid_usage_page(HID_PAGE(n->collection)),
					 hid_usage_in_page(n->collection));
			namep += sprintf(namep, "%s:%s",
					 hid_usage_page(HID_PAGE(n->usage)),
					 hid_usage_in_page(n->usage));
			if (all || gotname(namebuf)) {
				if (!noname)
					printf("%s=", namebuf);
				prdata(dbuf, n);
				printf("\n");
			}
		}
		if (loop)
			printf("\n");
	} while (loop);
	free(dbuf);
}