[PATCH] chan_usbradio fixes for newer kernels
Hello all, As mentioned in my previous post, I needed to make changes to chan_usbradio as well as Zaptel for Linux 3.1.0. The crux of the issue here was that the structure of /sys had changed. The first clue was when Asterisk started reporting that the USB device ".." had been assigned to a radio channel. The code previously looked up a path like: /sys/class/sound/dsp1/device On older kernels, this path would be a symlink to something like: ../../../devices/pci0000:00/0000:00:04.2/usb1/1-1/1-1:1.0 The second last component of this was extracted, resulting in 1-1. However, the above symlink now simply points to ../../card1, resulting in .. as I mentioned before. Now everything under /sys/class/sound is also a symlink and it is these that need to be queried instead. For dsp1, the new target is: ../../devices/pci0000:00/0000:00:04.2/usb1/1-1/1-1:1.0/sound/card1/dsp1 This is similar to before but the code that previously handled the path extraction was long winded. basename and dirname do the job for us much more efficiently. This new code will not work on older kernels. I was going to address that issue when it occurred to me that this whole process is very convoluted and over-complicated. Surely libusb can simply tell us the "devstr" value without having to iterate over all the sound cards and then go digging around in /sys? As it turns out, it can't, at least not in this version. The old "legacy" libusb API is being used here. The newer API includes a function called libusb_get_device_address but I'm not sure whether this returns the right information. The following discussion from August has led me to believe that the function we need may actually be introduced in the next version. http://libusb.6.n5.nabble.com/Find-specific-USB-device-based-on-udev-info-td... Despite this, I was still able to simplify the confusingly named usb_get_usbdev function. Instead of iterating over all the sound cards, looking for the one that matches the given devstr, we simply look up the device directly under /sys. For the 1-1 example: /sys/bus/usb/devices/1-1/1-1:1.0/sound This is a directory containing just one other directory, card1 in this case. We just look for a directory starting with "card" and take the number from the end. Job done. So to sum up, the attached patch works but only with newer kernels. I don't know exactly which kernel version introduced the change. It may have been as far back as 2.6.25. This could be fixed up to work with older kernels too but moving to the newer libusb and vastly simplifying this code is well worth considering. Of course, so is ditching Asterisk, but that's covered in my other post. ;) This code would look much the same under any system anyway. Regards, James
On Sun, 27 Nov 2011 06:46:56 +0000 James Le Cuirot <chewi@aura-online.co.uk> wrote:
As mentioned in my previous post, I needed to make changes to chan_usbradio as well as Zaptel for Linux 3.1.0. The crux of the issue here was that the structure of /sys had changed.
This patch only covers Asterisk so it was rooted to the asterisk directory. To apply it: cd /path/to/trunk/asterisk patch -p0 < /path/to/chan_usbradio-newer-kernels.patch Regards, James
Good timing. Thank you!! As luck would have it - I just lost the drive on one of my nodes. It's a newer piece of hardware and has always required a newer kernel. Just to report back - I applied this chan_usbradio patch against kernel 2.6.39 and it worked without a hitch (once I got my head out, anyhow)... Thanks again! I really appreciate this effort. As time goes on, I expect many others will be needing this support as well. FWIW - I used to work around this issue by enabling the depreciated SYSFS support (CONFIG_SYSFS_DEPRECATED); that option exists still in 2.6.39; but not sure if/when it will be dropped. But, it will be needed eventually. 73 - Jeremy, KD0EAV On 11/27/11 00:46, James Le Cuirot wrote:
Hello all,
As mentioned in my previous post, I needed to make changes to chan_usbradio as well as Zaptel for Linux 3.1.0. The crux of the issue here was that the structure of /sys had changed.
The first clue was when Asterisk started reporting that the USB device ".." had been assigned to a radio channel. The code previously looked up a path like:
/sys/class/sound/dsp1/device
On older kernels, this path would be a symlink to something like:
../../../devices/pci0000:00/0000:00:04.2/usb1/1-1/1-1:1.0
The second last component of this was extracted, resulting in 1-1. However, the above symlink now simply points to ../../card1, resulting in .. as I mentioned before. Now everything under /sys/class/sound is also a symlink and it is these that need to be queried instead. For dsp1, the new target is:
../../devices/pci0000:00/0000:00:04.2/usb1/1-1/1-1:1.0/sound/card1/dsp1
This is similar to before but the code that previously handled the path extraction was long winded. basename and dirname do the job for us much more efficiently.
This new code will not work on older kernels. I was going to address that issue when it occurred to me that this whole process is very convoluted and over-complicated. Surely libusb can simply tell us the "devstr" value without having to iterate over all the sound cards and then go digging around in /sys? As it turns out, it can't, at least not in this version. The old "legacy" libusb API is being used here. The newer API includes a function called libusb_get_device_address but I'm not sure whether this returns the right information. The following discussion from August has led me to believe that the function we need may actually be introduced in the next version.
http://libusb.6.n5.nabble.com/Find-specific-USB-device-based-on-udev-info-td...
Despite this, I was still able to simplify the confusingly named usb_get_usbdev function. Instead of iterating over all the sound cards, looking for the one that matches the given devstr, we simply look up the device directly under /sys. For the 1-1 example:
/sys/bus/usb/devices/1-1/1-1:1.0/sound
This is a directory containing just one other directory, card1 in this case. We just look for a directory starting with "card" and take the number from the end. Job done.
So to sum up, the attached patch works but only with newer kernels. I don't know exactly which kernel version introduced the change. It may have been as far back as 2.6.25. This could be fixed up to work with older kernels too but moving to the newer libusb and vastly simplifying this code is well worth considering. Of course, so is ditching Asterisk, but that's covered in my other post. ;) This code would look much the same under any system anyway.
Regards, James
_______________________________________________ App_rpt-users mailing list App_rpt-users@ohnosec.org http://ohnosec.org/cgi-bin/mailman/listinfo/app_rpt-users
participants (2)
-
"Jeremy R. Geeo [KDØEAV]" -
James Le Cuirot