Logo Search packages:      
Sourcecode: libgphoto2 version File versions

check-mtp-device.c

/* check-mtp-device.c udev hookup
 *
 * Copyright  2006  Marcus Meissner  <marcus@jet.franken.de>
 *
 * 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 <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/param.h>
#include <string.h>

#include <usb.h>

/*
 * 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,"%u.%u",&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) {
                  char *s = strchr(dev->filename,'/');
                  int devno;

                  if (!s) s = dev->filename;
                  devno = strtol(s,NULL,10);
                  if (devno != 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;
}

Generated by  Doxygen 1.6.0   Back to index