From 9e35ea333376215ea831bea027493b553b2e982c Mon Sep 17 00:00:00 2001 From: Hans Ulrich Niedermann Date: Mon, 18 Dec 2006 16:43:41 +0000 Subject: rename check_ptp_camera to check-ptp-camera (now all utilities use hyphens) git-svn-id: https://svn.code.sf.net/p/gphoto/code/branches/libgphoto2-2_3/libgphoto2@9670 67ed7778-7388-44ab-90cf-0a291f65f57c --- NEWS | 3 +- libgphoto2_port/usb/check-mtp-device.c | 151 +++++++++++++++++++++++++++++++++ packaging/generic/Makefile.am | 3 +- packaging/generic/check-ptp-camera | 20 +++++ packaging/generic/check_ptp_camera | 20 ----- packaging/generic/print-camera-list.c | 32 +++++-- 6 files changed, 198 insertions(+), 31 deletions(-) create mode 100644 libgphoto2_port/usb/check-mtp-device.c create mode 100644 packaging/generic/check-ptp-camera delete mode 100644 packaging/generic/check_ptp_camera diff --git a/NEWS b/NEWS index 1397477a2..00e337e3b 100644 --- a/NEWS +++ b/NEWS @@ -10,8 +10,7 @@ Package / System integration: * Fix libgphoto2 symbol list: Removed gpi_gphoto_port_type_map * Add new permission setup script doing class based matching for PTP class cameras not listed explicitly by USB IDs. - - This script is used by the generated UDEV rules. + This script (check-ptp-camera) is used by the generated UDEV rules. Example usage: print-camera-list udev-rules mode 660 group plugdev \ diff --git a/libgphoto2_port/usb/check-mtp-device.c b/libgphoto2_port/usb/check-mtp-device.c new file mode 100644 index 000000000..c411edffe --- /dev/null +++ b/libgphoto2_port/usb/check-mtp-device.c @@ -0,0 +1,151 @@ +/* check-mtp-device.c udev hookup + * + * Copyright © 2006 Marcus Meissner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * UDEV snippet: + * ACTION=="add", SUBSYSTEM=="usb", PROGRAM="/usr/sbin/check_ptp_camera", ... stuff ... + * you can also move it to /lib/udev/ and call without path. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * the USB event we trigger on: +UDEV [1166213739.401000] add@/class/usb_device/usbdev1.6 +UDEV_LOG=3 +ACTION=add +DEVPATH=/class/usb_device/usbdev1.6 +SUBSYSTEM=usb_device +SEQNUM=1634 +PHYSDEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-3 +PHYSDEVBUS=usb +PHYSDEVDRIVER=usb +MAJOR=189 +MINOR=5 +UDEVD_EVENT=1 +DEVNAME=/dev/bus/usb/001/006 +*/ + +/* This function reads the Microsoft OS Descriptor and looks inside to + * find if it is a MTP device. This is the similar to the way that + * Windows Media Player 10 uses. + * It is documented to some degree on various internet pages. + */ +int +main(int argc, char **arvg) +{ + char buf[1000], cmd, *s; + int ret; + usb_dev_handle *devh; + struct usb_device *dev; + struct usb_bus *bus; + char *devpath; + unsigned int xbus, xdev; + + devpath = getenv("DEVPATH"); + if (!devpath) { + fprintf(stderr,"DEVPATH not set\n"); + goto errout2; + } + + s = strstr(devpath,"usbdev"); + if (!s) goto errout2; + s+=strlen("usbdev"); + + if (2!=sscanf(s,"%d.%d",&xbus,&xdev)) { + fprintf (stderr,"Failed to parse %s, xbus %d, xdev %d\n", devpath, xbus, xdev); + goto errout2; + } + usb_init(); + usb_find_busses (); + usb_find_devices (); + + for (bus = usb_busses; bus; bus = bus->next) { + int busno = strtol(bus->dirname,NULL,10); + if (busno != xbus) continue; + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->devnum != xdev) continue; + goto found; + } + } + fprintf(stderr,"Device not found.\n"); + goto errout2; + +found: + fprintf (stderr,"dev is %s\n", dev->filename); + /* All of them are "vendor specific" device class, or interface defined. */ + if ((dev->descriptor.bDeviceClass!=0xff) && (dev->descriptor.bDeviceClass!=0)) { + fprintf(stderr,"Non MTP deviceclass?\n"); + goto errout2; + } + + devh = usb_open (dev); + /* get string descriptor at 0xEE */ + ret = usb_get_descriptor (devh, 0x03, 0xee, buf, sizeof(buf)); + /*if (ret > 0) gp_log_data("get_MS_OSD",buf, ret);*/ + if (ret < 10) goto errout; + if (!((buf[2] == 'M') && (buf[4]=='S') && (buf[6]=='F') && (buf[8]=='T'))) { + fprintf(stderr,"MS OS Descriptor request failed.\n"); + goto errout; + } + cmd = buf[16]; + ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, cmd, 0, 4, buf, sizeof(buf), 1000); + if (ret == -1) { + fprintf (stderr, "mtp matcher: control message says %d\n", ret); + goto errout; + } + if (buf[0] != 0x28) { + fprintf (stderr, "mtp matcher: ret is %d, buf[0] is %x\n", ret, buf[0]); + goto errout; + } + /*if (ret > 0) gp_log_data("get_MS_ExtDesc",buf, ret);*/ + if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) { + fprintf (stderr, "mtp matcher: buf at 0x12 is %02x%02x%02x\n", buf[0x12], buf[0x13], buf[0x14]); + goto errout; + } + ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, cmd, 0, 5, buf, sizeof(buf), 1000); + if (ret == -1) goto errout; + if (buf[0] != 0x28) { + fprintf (stderr, "mtp matcher: ret is %d, buf[0] is %x\n", ret, buf[0]); + goto errout; + } + /*if (ret > 0) gp_log_data("get_MS_ExtProp",buf, ret);*/ + if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) { + fprintf (stderr, "mtp matcher: buf at 0x12 is %02x%02x%02x\n", buf[0x12], buf[0x13], buf[0x14]); + goto errout; + } + usb_close (devh); + fprintf(stderr,"MTP Device found!\n"); + return 0; +errout: + usb_close (devh); +errout2: + fprintf(stderr,"MTP Device not found!\n"); + return 1; +} diff --git a/packaging/generic/Makefile.am b/packaging/generic/Makefile.am index 3ebabca6d..004404dca 100644 --- a/packaging/generic/Makefile.am +++ b/packaging/generic/Makefile.am @@ -1,5 +1,6 @@ utils_PROGRAMS = print-camera-list -EXTRA_DIST = check_ptp_camera +sbin_PROGRAMS = check-ptp-camera +EXTRA_DIST = check-ptp-camera print_camera_list_SOURCE = print-camera-list.c print_camera_list_LDADD = \ diff --git a/packaging/generic/check-ptp-camera b/packaging/generic/check-ptp-camera new file mode 100644 index 000000000..f309ed851 --- /dev/null +++ b/packaging/generic/check-ptp-camera @@ -0,0 +1,20 @@ +#!/bin/sh + +# check if any interface of this device is a PTP camera interface (06) +INTERFACE="${1:-06/01/01}" + +BASENAME=${PHYSDEVPATH##*/} +for d in /sys/${PHYSDEVPATH}/${BASENAME}:*; do + [[ -d ${d} ]] || continue + INTERFACEID="$(< ${d}/bInterfaceClass)" + INTERFACEID="${INTERFACEID}/$(< ${d}/bInterfaceSubClass)" + INTERFACEID="${INTERFACEID}/$(< ${d}/bInterfaceProtocol)" + + #echo ${d}: ${INTERFACEID} + if [[ ${INTERFACE} == ${INTERFACEID} ]]; then + # Found interface + exit 0 + fi +done + +exit 1 diff --git a/packaging/generic/check_ptp_camera b/packaging/generic/check_ptp_camera deleted file mode 100644 index f309ed851..000000000 --- a/packaging/generic/check_ptp_camera +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -# check if any interface of this device is a PTP camera interface (06) -INTERFACE="${1:-06/01/01}" - -BASENAME=${PHYSDEVPATH##*/} -for d in /sys/${PHYSDEVPATH}/${BASENAME}:*; do - [[ -d ${d} ]] || continue - INTERFACEID="$(< ${d}/bInterfaceClass)" - INTERFACEID="${INTERFACEID}/$(< ${d}/bInterfaceSubClass)" - INTERFACEID="${INTERFACEID}/$(< ${d}/bInterfaceProtocol)" - - #echo ${d}: ${INTERFACEID} - if [[ ${INTERFACE} == ${INTERFACEID} ]]; then - # Found interface - exit 0 - fi -done - -exit 1 diff --git a/packaging/generic/print-camera-list.c b/packaging/generic/print-camera-list.c index 2ac262806..b22d345dc 100644 --- a/packaging/generic/print-camera-list.c +++ b/packaging/generic/print-camera-list.c @@ -360,9 +360,14 @@ udev_camera_func (const func_params_t *params, if (flags & GP_USB_HOTPLUG_MATCH_INT_CLASS) { if ((flags & (GP_USB_HOTPLUG_MATCH_INT_CLASS|GP_USB_HOTPLUG_MATCH_INT_SUBCLASS|GP_USB_HOTPLUG_MATCH_INT_PROTOCOL)) == (GP_USB_HOTPLUG_MATCH_INT_CLASS|GP_USB_HOTPLUG_MATCH_INT_SUBCLASS|GP_USB_HOTPLUG_MATCH_INT_PROTOCOL)) - printf("PROGRAM=\"check_ptp_camera %02d/%02d/%02d\", ", class, subclass, proto); - else - fprintf(stderr,"unhandled interface match flags %x\n", flags); + printf("PROGRAM=\"check-ptp-camera %02d/%02d/%02d\", ", class, subclass, proto); + } else { + if (class == 666) { + printf("# not working yet: PROGRAM=\"check-mtp-device\", "); + } else { + fprintf(stderr,"unhandled interface match flags %x\n", flags); + } + } } else { printf ("SYSFS{idVendor}==\"%04x\", SYSFS{idProduct}==\"%04x\", ", a->usb_vendor, a->usb_product); @@ -467,9 +472,13 @@ udev_098_camera_func (const func_params_t *params, if (flags & GP_USB_HOTPLUG_MATCH_INT_CLASS) { if ((flags & (GP_USB_HOTPLUG_MATCH_INT_CLASS|GP_USB_HOTPLUG_MATCH_INT_SUBCLASS|GP_USB_HOTPLUG_MATCH_INT_PROTOCOL)) == (GP_USB_HOTPLUG_MATCH_INT_CLASS|GP_USB_HOTPLUG_MATCH_INT_SUBCLASS|GP_USB_HOTPLUG_MATCH_INT_PROTOCOL)) - printf("PROGRAM=\"check_ptp_camera %02d/%02d/%02d\", ", class, subclass, proto); - else - fprintf(stderr,"unhandled interface match flags %x\n", flags); + printf("PROGRAM=\"check-ptp-camera %02d/%02d/%02d\", ", class, subclass, proto); + } else { + if (class == 666) + printf("# not working yet: PROGRAM=\"check-mtp-device\", "); + else + fprintf(stderr,"unhandled interface match flags %x\n", flags); + } } else { printf ("ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", ", a->usb_vendor, a->usb_product); @@ -1030,7 +1039,10 @@ static const output_format_t formats[] = { }, {name: "udev-rules", descr: "udev < 0.98 rules file", - help: "Put it into /etc/udev/rules.d/90-libgphoto2.rules, set file mode, owner, group\n or add script to run. This rule files also uses the\n check_ptp_camera script included in libgphoto2 source. Either put it to\n /lib/udev/check_ptp_camera or adjust the path in the generated rules file.", + help: "Put it into /etc/udev/rules.d/90-libgphoto2.rules, set file mode, owner, group\n" + " or add script to run. This rule files also uses the\n" + " check-ptp-camera script included in libgphoto2 source. Either put it to\n" + " /lib/udev/check-ptp-camera or adjust the path in the generated rules file.", paramdescr: "( | [mode |owner |group ]* ) ", begin_func: udev_begin_func, camera_func: udev_camera_func, @@ -1038,7 +1050,11 @@ static const output_format_t formats[] = { }, {name: "udev-rules-0.98", descr: "udev >= 0.98 rules file", - help: "Put it into /etc/udev/rules.d/90-libgphoto2.rules, set file mode, owner, group\n or add script to run, for udev >= 0.98. This rule files also uses the\n check_ptp_camera script included in libgphoto2 source. Either put it to\n /lib/udev/check_ptp_camera or adjust the path in the generated rules file.", + help: + "Put it into /etc/udev/rules.d/90-libgphoto2.rules, set file mode, owner, group\n" + " or add script to run, for udev >= 0.98. This rule files also uses the\n" + " check-ptp-camera script included in libgphoto2 source. Either put it to\n" + " /lib/udev/check-ptp-camera or adjust the path in the generated rules file.", paramdescr: "( | [mode |owner |group ]* ) ", begin_func: udev_098_begin_func, camera_func: udev_098_camera_func, -- cgit v1.2.1