Identifying USB devices

15

6

I have five USB cameras, same brand, same model (Canyon CNR-FWC120H). They are used to monitor different scenes 24/7. I need to somehow identify which camera is which from the Linux (Debian) console or programmatically (any language).

I’ve tried looking at the output of lsusb -vvv, there is a field iSerial which should be different for each camera but unfortunately this manufacturer decided not to bother and all cameras have the same serial at that place: 200901010001

Is there any other way I could identify which camera is which independently of USB ports to which they are connected because unfortunately in my specific scenario I can not rely on the fact that the same camera will always be connected to the same port.

UPDATE After some discussion in the comments I realize this is mission impossible. So forget the last paragraph or if you do have some ingenious idea, please, you are welcome to present it. I’m now interested if I could identify which USB port the device is connected to; I use the built-in USB ports on the motherboard and additional PCI USB controller cards to accommodate the cameras with enough bandwidth. I would need to uniquely identify the port, and the port number/identification should not change if for example the machine reboots and for some reason the USB controllers get initialized in different order. Is that possible?

UPDATE 2 I see in my logs for one of the cameras the following info:

[Wed Apr 30 18:35:02 2014] uvcvideo: Found UVC 1.00 device FULL HD 1080P Webcam (0bda:58b0)
[Wed Apr 30 18:35:02 2014] input: FULL HD 1080P Webcam as /devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4

Using that, I’ve called this command:

udevadm info --query=all --path=/devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4

And got this:

P: /devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4
E: DEVPATH=/devices/pci0000:00/0000:00:01.0/0000:01:00.0/usb3/3-2/3-2:1.0/input/input4
E: EV=3
E: ID_BUS=usb
E: ID_INPUT=1
E: ID_INPUT_KEY=1
E: ID_MODEL=FULL_HD_1080P_Webcam
E: ID_MODEL_ENC=FULL\x20HD\x201080P\x20Webcam
E: ID_MODEL_ID=58b0
E: ID_PATH=pci-0000:01:00.0-usb-0:2:1.0
E: ID_PATH_TAG=pci-0000_01_00_0-usb-0_2_1_0
E: ID_REVISION=5801
E: ID_SERIAL=Generic_FULL_HD_1080P_Webcam_200901010001
E: ID_SERIAL_SHORT=200901010001
E: ID_TYPE=video
E: ID_USB_DRIVER=uvcvideo
E: ID_USB_INTERFACES=:0e0100:0e0200:010100:010200:
E: ID_USB_INTERFACE_NUM=00
E: ID_VENDOR=Generic
E: ID_VENDOR_ENC=Generic
E: ID_VENDOR_ID=0bda
E: KEY=100000 0 0 0
E: MODALIAS=input:b0003v0BDAp58B0e5801-e0,1,kD4,ramlsfw
E: NAME="FULL HD 1080P Webcam"
E: PHYS="usb-0000:01:00.0-2/button"
E: PRODUCT=3/bda/58b0/5801
E: PROP=0
E: SUBSYSTEM=input
E: UDEV_LOG=3
E: USEC_INITIALIZED=41090223

The things that differ between the cameras are DEVPATH, ID_PATH, ID_PATH_TAG, PHYS and (most interesting) USEC_INITIALIZED. Now the first four elements are probably related to the USB port, but the last one USEC_INITIALIZED looks like some sort of serial number. I can’t find any info about what it actually represents. Does anyone know anything about it? I thought that it is maybe the time in micro seconds when the camera initialized but the camera that initialized after this one has USEC_INITIALIZED=17919751, and then the one after that USEC_INITIALIZED=25609278 so it seems rather random. I’ll try to reboot the system and see, but I need to wait for a convenient time to do that.

And if anyone is wondering why I don’t just try reconnecting a camera and see if that remains the same. The answer is that I’m operating this PC remotely, and I’m investigating all this to prepare the system to be fully autonomous for any potential event in the future. Which for example might include disconnecting the cameras from USB ports.

Ivan Kovacevic

Posted 2014-04-30T15:16:46.020

Reputation: 457

Pls see my answer, I think I have found an adequate solution for you. – MariusMatutiae – 2016-03-04T10:40:10.793

Can it be non-programatic / non-software too? eg by marking the camera front glass with a marker (different colors)? If there are no differences in the hardware and/or serials then I doubt this will be possible without custom reprogramming, you could however connect the camera's via relays/hub's which ARE different? – Gizmo – 2014-04-30T15:18:00.090

Unfortunately no for the marker idea, because I must not introduce anything to the picture itself. I was wondering if there is a possibility to overwrite the cameras serial number? Or any other camera setting/info... Does something like that exist? Writable, persistent memory? – Ivan Kovacevic – 2014-04-30T15:24:12.057

This is going to be really hard, especially when no unique information for the device's is provided, see this: http://stackoverflow.com/questions/14053764/how-to-identify-uniquely-an-usb-device . As for overwriting the memory, you could try to find a firmware flashing utility, identify the serial in the firmware and HEX-EDIT it to something you like? However I can't find any tools for it. If you can find a way to change the usb device descriptor then it would be easy from there on.

– Gizmo – 2014-04-30T15:27:29.780

You can try the HID Descriptor tool here - http://www.usb.org/developers/hidpage/ - Ofcourse, only if your cam is HID

– Gizmo – 2014-04-30T15:34:05.833

damn, yup I guess this is impossible, there is also no firmware for this model so that idea is out too. I guess the only thing I could do is to enforce that each camera stays connected to the same port on the PC all the time... I will modify my question. – Ivan Kovacevic – 2014-04-30T15:35:16.397

That HID Descriptor tool is Windows only I believe. But anyhow I don't think I would have much luck with that as I've checked now that only two devices report they are HID devices on my system and these are not the cameras. – Ivan Kovacevic – 2014-04-30T15:46:06.013

Then I think your only chance is to use a USB hub which supports unique identification (one usb hub - one camera) – Gizmo – 2014-04-30T15:50:07.447

I would really wish to avoid that(buying new hardware). See my update to the question. – Ivan Kovacevic – 2014-04-30T15:55:30.330

As for your update, I don't know how it's on linux but on windows the usb port numbers always remain the same, maybe this and this could be of help.

– Gizmo – 2014-04-30T16:19:21.407

It gave me some "inspiration". I've added another update to my question. – Ivan Kovacevic – 2014-04-30T18:17:22.557

The USEC_INITIALIZED, is, probably - the timestamp at which the device has been initialized, sorry for destroying your hopes XD [unsigned int - second initialized], can you tell us by how much the numbers differ and if they change on reboot? (just to be sure, maybe I'm wrong) – Gizmo – 2014-04-30T18:30:14.627

It probably is the timestamp :-/ But it's a weird timestamp :). I've again modified the question. I've added USEC values from three different cameras, all initialized one after another(according to dmesg output) – Ivan Kovacevic – 2014-04-30T18:37:44.767

maybe it's the best to contact the manufacturer and ask for a firmware file + flash utility or some other utilities? If the camera's have some IO pins in them maybe you could connectto it and telnet to the camera to change the ID – Gizmo – 2014-04-30T19:03:26.657

To contact the manufacturer might be an option although I wouldn't put much hopes into that. They do have firmware updates for some other gadgets but not for this camera. So I suppose there is a reason for that and somehow I doubt they would be willing to provide one so I can hack it :). But hey I might try it... Regarding your second idea I did already disassemble these cameras but I did not spot any IO pins :-/ so it's probably over USB. – Ivan Kovacevic – 2014-04-30T19:20:42.230

What about toggling the power for the usb ports of each camera via sysfs? It's easy enough if you have an older kernel. – micke – 2014-04-30T22:19:22.217

I have the latest Debian stable(wheezy). Kernel: Linux 3.2.0-4-amd64 x86_64. What is you idea? You mean so I can check USEC_INITIALIZED? – Ivan Kovacevic – 2014-04-30T23:23:40.640

Answers

2

Are the cameras in a fixed position? Are the scenes more or less constant? If so, you could use image recognition to identify the cameras by what they are seeing instead.

There are some decent python tools to do this, this answer has some good info on the topic: https://stackoverflow.com/questions/1927660/compare-two-images-the-python-linux-way

walli

Posted 2014-04-30T15:16:46.020

Reputation: 109

I had this solution in mind, however I hoped for something simpler. And I would have a problem because few cameras are actually overlooking a busy port, ships moving, sea surface is not constant because of the waves, etc. – Ivan Kovacevic – 2014-07-30T02:18:15.273

2

As you discovered, the problem can't be solved, if you can't get a unique identification from the device itself. The closest thing to a solution is to depend upon the physical connection of the unit. (This won't change on reboot. Only if you physically change the position of the connector)

Programmatically you can use sysfs to get the information the kernel has, about the device. Sysfs is a file-system-like representation of devices as the kernel sees them. (Its not real files on the disk)

With it, you can: - identify the device type with product and vendor ID - read the serial number of the device, if it has one. - read the physical connection number on the USB hub

You could start by finding your type of devices in /sys/class. In this example I use an USB→LPT port. But the principle is the same.

$ ls -l /sys/class/usbmisc
lp1 -> ../../devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5:1.0/usbmisc/lp1
lp2 -> ../../devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.6/4-1.6:1.0/usbmisc/lp2

Grap the device name from the uevent file:

cat /sys/class/usbmisc/lp1/uevent
MAJOR=180
MINOR=1
DEVNAME=__usb/lp1__

add /dev so you get the device name to open: /dev/usb/lp1

Use the real path: $ cd -P /sys/class/usbmisc/lp1

Step back 3 branches:

$ cd ../../../
/sys/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5

This directory contains a lot of the information on the device:

idProduct and idVendor can be used to uniquely identify the device type.

If there is a serial file and it contains a unique serial number, you are done.

Otherwise your option is to use the physical connection as identification, which is this directory name “4-1.5” It is unique for the physical connection, and will as you already mentioned change if you plug the device into another port.

Simon Rigét

Posted 2014-04-30T15:16:46.020

Reputation: 121

I guess this is the best solution, or compromise in my case... Fixate the cameras to the same dedicated USB port. I say compromise because in my case I also had the requirement to identify the cameras if for example after a hardware maintenance the cameras would be connected to different ports by the person doing the maintenance. – Ivan Kovacevic – 2016-03-04T15:57:12.417

I agree. This is far from perfect. I wish it was common for vendors, to add a f... simple serialnumber to the device, as the protocol specifies. I hope you find a better solution! – Simon Rigét – 2016-03-05T20:43:08.427

1

Simply unplug the camera's, plug 1 in and do a lsusb. Identify the camera and note down which USB port is used. Maybe put a little label on the cam. Then repeat for the other camera's and you'll get there. Nothing is mission impossible ;)

Jakke

Posted 2014-04-30T15:16:46.020

Reputation: 910

I admit I did not explain completely clear the purpose of my configuration. It is a PC on a remote location used for recording long duration(months) time-lapses. I wished for a solution which could automatically identify cameras without my intervention. Now after any power outage I actually have to log in and manually reconfigure the camera numbers. – Ivan Kovacevic – 2014-07-30T02:14:21.367

This makes sense. Just plug one camera in at a time and note which physical port it's attached to. Looks like you could even turn the individual ports on and off if you can't differentiate within your software, so only one would appear at a time. See http://askubuntu.com/questions/342061/power-on-off-usb-port-in-ubuntu-12-10

– Ryan Griggs – 2014-05-28T02:33:03.363

0

It is possible to identify all cameras. The command

 $ sudo lsusb -v -d 046d:082d | grep -i serial
   iSerial                 1 05C6D16F

returns the Serial number of my camera (a Logitech HD Pro Webcam, used as an example with the correct Vendor:Product codes obtained from a previous use of lsusb). Please notice that it is absolutely necessary to perform this operation as a privileged user: an unprivileged user does not get access to all info available thru the command.

The serial number is often, but not always, unique. If it is not unique (just compare the output of the above commands for two devices with the same Vendor:Product codes), you can set them so that they are distinct. There are guides all over Google for doing that, I will merely point to a couple of them, for the sake of thoroughness: here and here.

Now the command

$ sudo udevadm info --query=all /dev/video1 | grep 'VENDOR_ID\|MODEL_ID\|SERIAL_SHORT'
  E: ID_MODEL_ID=082d
  E: ID_SERIAL_SHORT=05C6D16F
  E: ID_VENDOR_ID=046d

returns the appropriate codes for this particular camera. Trial and error with all /dev/videoX devices allows pigeon-holing all of them.

MariusMatutiae

Posted 2014-04-30T15:16:46.020

Reputation: 41 321

It seems to me as if you maybe did not read my initial question post to the end. I've already mentioned in my post about using udevadm... The problem is that all the cameras have the same serial number so you can't tell them apart from that info. You mentioned "you can set them so that they are distinct" is there a way to "set"/change the serial number? – Ivan Kovacevic – 2016-03-04T15:49:57.100

-1

I've heard of someone delaying power on in sequence to devices during a boot up, which would allow you to identify them based on the order they turn on. It would require some addition hardware that could control power to individual usb ports in order.

You could hack a USB hub that has individual power switches for each port, hook that to an arduino and trigger which order they are turned on.

zimmer62

Posted 2014-04-30T15:16:46.020

Reputation: 1 343