#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libudev.h>

#define OAU_VENDOR_ID	"1556"	/* CERN USB Vendor ID */
#define OAU_DEVICE_ID	"0443"	/* oau USB Device ID */

#define ID_VENDOR_ID	OAU_VENDOR_ID
#define ID_DEVICE_ID	OAU_DEVICE_ID

#define	MAX_OUA		16

struct oua_usb_dev {
	char	path[PATH_MAX];
	char	busnum[6];
	char	devnum[6];
	char	portnum[6];
	char	busport[16];
	char	devno[10];
	char	serial[256];
};

struct oua_devlist {
	struct oua_usb_dev	*devs;
	int			ndevs;
};

void oua_display_devlist(struct oua_devlist *ls)
{
	int i;
	for (i = 0; i < ls->ndevs; i++) {
		struct oua_usb_dev *entry = &ls->devs[i];

		printf("%d: busdev:%s:%s bus-port:%s devno:%s serial:%s devpath:%s\n",
			i, entry->busnum, entry->devnum,
			entry->busport, entry->devno, entry->serial, entry->path);
	}
}

static struct oua_usb_dev usb_dev[MAX_OUA];
static struct oua_devlist devlist = { usb_dev, -1, };

static struct oua_devlist *oua_enumerate(char *vendor_id, char *device_id)
{
    struct udev *udev = udev_new();
    struct udev_enumerate *enumerate = udev_enumerate_new(udev);
    struct udev_list_entry *devs, *ptr, *ptr2;
    int found_devs = 0;

    udev_enumerate_add_match_property(enumerate, "ID_VENDOR_ID", vendor_id);
    udev_enumerate_add_match_property(enumerate, "ID_MODEL_ID", device_id);
    udev_enumerate_scan_devices(enumerate);

    devs = udev_enumerate_get_list_entry(enumerate);
    udev_list_entry_foreach(ptr, devs) {
	if (found_devs >= MAX_OUA)
		goto out;
        const char *path = udev_list_entry_get_name(ptr);
        struct udev_device *dev = udev_device_new_from_syspath(udev, path);
	struct oua_usb_dev *entry = &usb_dev[found_devs];
	strcpy(entry->path, path);
	strcpy(entry->busnum, udev_device_get_sysattr_value(dev, "busnum"));
	strcpy(entry->devnum, udev_device_get_sysattr_value(dev, "devnum"));
	strcpy(entry->devno, udev_device_get_sysattr_value(dev, "dev"));
	strcpy(entry->serial, udev_device_get_sysattr_value(dev, "serial"));
	strcpy(entry->busport, rindex(entry->path, '/') + 1);

	found_devs++;
	udev_device_unref(dev);
    }
out:
    udev_enumerate_unref(enumerate);
    devlist.ndevs = found_devs;
    return &devlist;
}

int main(int argc, char *argv[])
{
	int i, devs;
	struct oua_devlist *list;

	list = oua_enumerate(ID_VENDOR_ID, ID_DEVICE_ID);
	oua_display_devlist(list);

	return 0;
}
