• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * \file libusb-glue.c
3  * Low-level USB interface glue towards libusb.
4  *
5  * Copyright (C) 2005-2007 Richard A. Low <richard@wentnet.com>
6  * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
7  * Copyright (C) 2006-2007 Marcus Meissner
8  * Copyright (C) 2007 Ted Bullock
9  * Copyright (C) 2008 Chris Bagwell <chris@cnpbagwell.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  *
26  * Created by Richard Low on 24/12/2005. (as mtp-utils.c)
27  * Modified by Linus Walleij 2006-03-06
28  *  (Notice that Anglo-Saxons use little-endian dates and Swedes
29  *   use big-endian dates.)
30  *
31  */
32 #include "config.h"
33 #include "libmtp.h"
34 #include "libusb-glue.h"
35 #include "device-flags.h"
36 #include "util.h"
37 #include "ptp.h"
38 
39 #include <errno.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <usb.h>
44 
45 #include "ptp-pack.c"
46 
47 /* Aha, older libusb does not have USB_CLASS_PTP */
48 #ifndef USB_CLASS_PTP
49 #define USB_CLASS_PTP 6
50 #endif
51 
52 /* libusb dosn't have misc class defined */
53 #ifndef USB_CLASS_MISC
54 #define USB_CLASS_MISC 0xEF
55 #endif
56 
57 #define APPLE_VID 0x05ac
58 
59 /* To enable debug prints for USB stuff, switch on this */
60 //#define ENABLE_USB_BULK_DEBUG
61 
62 /* Default USB timeout length.  This can be overridden as needed
63  * but should start with a reasonable value so most common
64  * requests can be completed.  The original value of 4000 was
65  * not long enough for large file transfer.  Also, players can
66  * spend a bit of time collecting data.  Higher values also
67  * make connecting/disconnecting more reliable.
68  */
69 #define USB_TIMEOUT_DEFAULT     10000
70 
71 /* USB control message data phase direction */
72 #ifndef USB_DP_HTD
73 #define USB_DP_HTD		(0x00 << 7)	/* host to device */
74 #endif
75 #ifndef USB_DP_DTH
76 #define USB_DP_DTH		(0x01 << 7)	/* device to host */
77 #endif
78 
79 /* USB Feature selector HALT */
80 #ifndef USB_FEATURE_HALT
81 #define USB_FEATURE_HALT	0x00
82 #endif
83 
84 /* Internal data types */
85 struct mtpdevice_list_struct {
86   struct usb_device *libusb_device;
87   PTPParams *params;
88   PTP_USB *ptp_usb;
89   uint32_t bus_location;
90   struct mtpdevice_list_struct *next;
91 };
92 typedef struct mtpdevice_list_struct mtpdevice_list_t;
93 
94 static const LIBMTP_device_entry_t mtp_device_table[] = {
95 /* We include an .h file which is shared between us and libgphoto2 */
96 #include "music-players.h"
97 };
98 static const int mtp_device_table_size = sizeof(mtp_device_table) / sizeof(LIBMTP_device_entry_t);
99 
100 // Local functions
101 static struct usb_bus* init_usb();
102 static void close_usb(PTP_USB* ptp_usb);
103 static void find_interface_and_endpoints(struct usb_device *dev,
104 					 uint8_t *interface,
105 					 int* inep,
106 					 int* inep_maxpacket,
107 					 int* outep,
108 					 int* outep_maxpacket,
109 					 int* intep);
110 static void clear_stall(PTP_USB* ptp_usb);
111 static int init_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, struct usb_device* dev);
112 static short ptp_write_func (unsigned long,PTPDataHandler*,void *data,unsigned long*);
113 static short ptp_read_func (unsigned long,PTPDataHandler*,void *data,unsigned long*,int);
114 static int usb_clear_stall_feature(PTP_USB* ptp_usb, int ep);
115 static int usb_get_endpoint_status(PTP_USB* ptp_usb, int ep, uint16_t* status);
116 
117 /**
118  * Get a list of the supported USB devices.
119  *
120  * The developers depend on users of this library to constantly
121  * add in to the list of supported devices. What we need is the
122  * device name, USB Vendor ID (VID) and USB Product ID (PID).
123  * put this into a bug ticket at the project homepage, please.
124  * The VID/PID is used to let e.g. udev lift the device to
125  * console userspace access when it's plugged in.
126  *
127  * @param devices a pointer to a pointer that will hold a device
128  *        list after the call to this function, if it was
129  *        successful.
130  * @param numdevs a pointer to an integer that will hold the number
131  *        of devices in the device list if the call was successful.
132  * @return 0 if the list was successfull retrieved, any other
133  *        value means failure.
134  */
LIBMTP_Get_Supported_Devices_List(LIBMTP_device_entry_t ** const devices,int * const numdevs)135 int LIBMTP_Get_Supported_Devices_List(LIBMTP_device_entry_t ** const devices, int * const numdevs)
136 {
137   *devices = (LIBMTP_device_entry_t *) &mtp_device_table;
138   *numdevs = mtp_device_table_size;
139   return 0;
140 }
141 
142 
init_usb()143 static struct usb_bus* init_usb()
144 {
145   usb_init();
146   usb_find_busses();
147   usb_find_devices();
148   return (usb_get_busses());
149 }
150 
151 /**
152  * Small recursive function to append a new usb_device to the linked list of
153  * USB MTP devices
154  * @param devlist dynamic linked list of pointers to usb devices with MTP
155  *        properties, to be extended with new device.
156  * @param newdevice the new device to add.
157  * @param bus_location bus for this device.
158  * @return an extended array or NULL on failure.
159  */
append_to_mtpdevice_list(mtpdevice_list_t * devlist,struct usb_device * newdevice,uint32_t bus_location)160 static mtpdevice_list_t *append_to_mtpdevice_list(mtpdevice_list_t *devlist,
161 						  struct usb_device *newdevice,
162 						  uint32_t bus_location)
163 {
164   mtpdevice_list_t *new_list_entry;
165 
166   new_list_entry = (mtpdevice_list_t *) malloc(sizeof(mtpdevice_list_t));
167   if (new_list_entry == NULL) {
168     return NULL;
169   }
170   // Fill in USB device, if we *HAVE* to make a copy of the device do it here.
171   new_list_entry->libusb_device = newdevice;
172   new_list_entry->bus_location = bus_location;
173   new_list_entry->next = NULL;
174 
175   if (devlist == NULL) {
176     return new_list_entry;
177   } else {
178     mtpdevice_list_t *tmp = devlist;
179     while (tmp->next != NULL) {
180       tmp = tmp->next;
181     }
182     tmp->next = new_list_entry;
183   }
184   return devlist;
185 }
186 
187 /**
188  * Small recursive function to free dynamic memory allocated to the linked list
189  * of USB MTP devices
190  * @param devlist dynamic linked list of pointers to usb devices with MTP
191  * properties.
192  * @return nothing
193  */
free_mtpdevice_list(mtpdevice_list_t * devlist)194 static void free_mtpdevice_list(mtpdevice_list_t *devlist)
195 {
196   mtpdevice_list_t *tmplist = devlist;
197 
198   if (devlist == NULL)
199     return;
200   while (tmplist != NULL) {
201     mtpdevice_list_t *tmp = tmplist;
202     tmplist = tmplist->next;
203     // Do not free() the fields (ptp_usb, params)! These are used elsewhere.
204     free(tmp);
205   }
206   return;
207 }
208 
209 /* Comment out this define to enable the original, more aggressive probing. */
210 #define MILD_MTP_PROBING
211 
212 #ifdef MILD_MTP_PROBING
213 /**
214  * This checks if a device has an interface with MTP description.
215  *
216  * @param dev a device struct from libusb.
217  * @param dumpfile set to non-NULL to make the descriptors dump out
218  *        to this file in human-readable hex so we can scruitinze them.
219  * @return 1 if the device is MTP compliant, 0 if not.
220  */
probe_device_descriptor(struct usb_device * dev,FILE * dumpfile)221 static int probe_device_descriptor(struct usb_device *dev, FILE *dumpfile)
222 {
223   usb_dev_handle *devh;
224   unsigned char buf[1024];
225   int i;
226   int ret;
227 
228   /*
229    * Don't examine devices that are not likely to
230    * contain any MTP interface, update this the day
231    * you find some weird combination...
232    */
233   if (!(dev->descriptor.bDeviceClass == USB_CLASS_PER_INTERFACE ||
234 	    dev->descriptor.bDeviceClass == USB_CLASS_PTP ||
235 	    dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC) ||
236       /* Apple devices sometimes freeze when probed by libusb */
237       dev->descriptor.idVendor == APPLE_VID) {
238     return 0;
239   }
240 
241   /* Attempt to open Device on this port */
242   devh = usb_open(dev);
243   if (devh == NULL) {
244     /* Could not open this device */
245     return 0;
246   }
247 
248   /*
249    * This sometimes crashes on the j for loop below
250    * I think it is because config is NULL yet
251    * dev->descriptor.bNumConfigurations > 0
252    * this check should stop this
253    */
254   if (dev->config) {
255     /*
256      * Loop over the interfaces, and check for string "MTP"
257      * in the descriptions.
258      */
259 
260     for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
261       uint8_t j;
262 
263       for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
264         int k;
265         for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) {
266 	  /* Current interface descriptor */
267 	  struct usb_interface_descriptor *intf =
268 	    &dev->config[i].interface[j].altsetting[k];
269 
270           buf[0] = '\0';
271           ret = usb_get_string_simple(devh,
272 				      dev->config[i].interface[j].altsetting[k].iInterface,
273 				      (char *) buf,
274 				      1024);
275 
276 	  if (ret < 3)
277 	    continue;
278           if (strcmp((char *) buf, "MTP") == 0) {
279 	    if (dumpfile != NULL) {
280               fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k);
281 	      fprintf(dumpfile, "   Interface description contains the string \"MTP\"\n");
282 	      fprintf(dumpfile, "   Device recognized as MTP, no further probing.\n");
283 	    }
284             usb_close(devh);
285             return 1;
286           }
287        }
288       }
289     }
290   }
291 
292   usb_close(devh);
293   return 0;
294 }
295 
296 #else /* MILD_MTP_PROBING */
297 /**
298  * This checks if a device has an MTP descriptor. The descriptor was
299  * elaborated about in gPhoto bug 1482084, and some official documentation
300  * with no strings attached was published by Microsoft at
301  * http://www.microsoft.com/whdc/system/bus/USB/USBFAQ_intermed.mspx#E3HAC
302  *
303  * @param dev a device struct from libusb.
304  * @param dumpfile set to non-NULL to make the descriptors dump out
305  *        to this file in human-readable hex so we can scruitinze them.
306  * @return 1 if the device is MTP compliant, 0 if not.
307  */
probe_device_descriptor(struct usb_device * dev,FILE * dumpfile)308 static int probe_device_descriptor(struct usb_device *dev, FILE *dumpfile)
309 {
310   usb_dev_handle *devh;
311   unsigned char buf[1024], cmd;
312   int i;
313   int ret;
314 
315   /* Don't examine hubs (no point in that) */
316   if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) {
317     return 0;
318   }
319 
320   /* Attempt to open Device on this port */
321   devh = usb_open(dev);
322   if (devh == NULL) {
323     /* Could not open this device */
324     return 0;
325   }
326 
327   /*
328    * This sometimes crashes on the j for loop below
329    * I think it is because config is NULL yet
330    * dev->descriptor.bNumConfigurations > 0
331    * this check should stop this
332    */
333   if (dev->config) {
334     /*
335      * Loop over the device configurations and interfaces. Nokia MTP-capable
336      * handsets (possibly others) typically have the string "MTP" in their
337      * MTP interface descriptions, that's how they can be detected, before
338      * we try the more esoteric "OS descriptors" (below).
339      */
340     for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
341       uint8_t j;
342 
343       for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
344         int k;
345         for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) {
346 	  /* Current interface descriptor */
347 	  struct usb_interface_descriptor *intf =
348 	    &dev->config[i].interface[j].altsetting[k];
349 
350 
351           buf[0] = '\0';
352           ret = usb_get_string_simple(devh,
353 				      dev->config[i].interface[j].altsetting[k].iInterface,
354 				      (char *) buf,
355 				      1024);
356 	  if (ret < 3)
357 	    continue;
358           if (strcmp((char *) buf, "MTP") == 0) {
359 	    if (dumpfile != NULL) {
360               fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k);
361 	      fprintf(dumpfile, "   Interface description contains the string \"MTP\"\n");
362 	      fprintf(dumpfile, "   Device recognized as MTP, no further probing.\n");
363 	    }
364             usb_close(devh);
365             return 1;
366           }
367   #ifdef LIBUSB_HAS_GET_DRIVER_NP
368 	  {
369 	    /*
370 	     * Specifically avoid probing anything else than USB mass storage devices
371 	     * and non-associated drivers in Linux.
372 	     */
373 	    char devname[0x10];
374 
375 	    devname[0] = '\0';
376 	    ret = usb_get_driver_np(devh,
377 				    dev->config[i].interface[j].altsetting[k].iInterface,
378 				    devname,
379 				    sizeof(devname));
380 	    if (devname[0] != '\0' && strcmp(devname, "usb-storage")) {
381 	      printf("avoid probing device using kernel interface \"%s\"\n", devname);
382 	      return 0;
383 	    }
384 	  }
385   #endif
386         }
387       }
388     }
389   } else {
390     if (dev->descriptor.bNumConfigurations)
391       printf("dev->config is NULL in probe_device_descriptor yet dev->descriptor.bNumConfigurations > 0\n");
392   }
393 
394   /* Read the special descriptor */
395   ret = usb_get_descriptor(devh, 0x03, 0xee, buf, sizeof(buf));
396 
397   // Dump it, if requested
398   if (dumpfile != NULL && ret > 0) {
399     fprintf(dumpfile, "Microsoft device descriptor 0xee:\n");
400     data_dump_ascii(dumpfile, buf, ret, 16);
401   }
402 
403   /* Check if descriptor length is at least 10 bytes */
404   if (ret < 10) {
405     usb_close(devh);
406     return 0;
407   }
408 
409   /* Check if this device has a Microsoft Descriptor */
410   if (!((buf[2] == 'M') && (buf[4] == 'S') &&
411 	(buf[6] == 'F') && (buf[8] == 'T'))) {
412     usb_close(devh);
413     return 0;
414   }
415 
416   /* Check if device responds to control message 1 or if there is an error */
417   cmd = buf[16];
418   ret = usb_control_msg (devh,
419 			 USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR,
420 			 cmd,
421 			 0,
422 			 4,
423 			 (char *) buf,
424 			 sizeof(buf),
425                          USB_TIMEOUT_DEFAULT);
426 
427   // Dump it, if requested
428   if (dumpfile != NULL && ret > 0) {
429     fprintf(dumpfile, "Microsoft device response to control message 1, CMD 0x%02x:\n", cmd);
430     data_dump_ascii(dumpfile, buf, ret, 16);
431   }
432 
433   /* If this is true, the device either isn't MTP or there was an error */
434   if (ret <= 0x15) {
435     /* TODO: If there was an error, flag it and let the user know somehow */
436     /* if(ret == -1) {} */
437     usb_close(devh);
438     return 0;
439   }
440 
441   /* Check if device is MTP or if it is something like a USB Mass Storage
442      device with Janus DRM support */
443   if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
444     usb_close(devh);
445     return 0;
446   }
447 
448   /* After this point we are probably dealing with an MTP device */
449 
450   /* Check if device responds to control message 2 or if there is an error*/
451   ret = usb_control_msg (devh,
452 			 USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR,
453 			 cmd,
454 			 0,
455 			 5,
456 			 (char *) buf,
457 			 sizeof(buf),
458                          USB_TIMEOUT_DEFAULT);
459 
460   // Dump it, if requested
461   if (dumpfile != NULL && ret > 0) {
462     fprintf(dumpfile, "Microsoft device response to control message 2, CMD 0x%02x:\n", cmd);
463     data_dump_ascii(dumpfile, buf, ret, 16);
464   }
465 
466   /* If this is true, the device errored against control message 2 */
467   if (ret == -1) {
468     /* TODO: Implement callback function to let managing program know there
469        was a problem, along with description of the problem */
470     fprintf(stderr, "Potential MTP Device with VendorID:%04x and "
471 	    "ProductID:%04x encountered an error responding to "
472 	    "control message 2.\n"
473 	    "Problems may arrise but continuing\n",
474 	    dev->descriptor.idVendor, dev->descriptor.idProduct);
475   } else if (ret <= 0x15) {
476     /* TODO: Implement callback function to let managing program know there
477        was a problem, along with description of the problem */
478     fprintf(stderr, "Potential MTP Device with VendorID:%04x and "
479 	    "ProductID:%04x responded to control message 2 with a "
480 	    "response that was too short. Problems may arrise but "
481 	    "continuing\n",
482 	    dev->descriptor.idVendor, dev->descriptor.idProduct);
483   } else if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
484     /* TODO: Implement callback function to let managing program know there
485        was a problem, along with description of the problem */
486     fprintf(stderr, "Potential MTP Device with VendorID:%04x and "
487 	    "ProductID:%04x encountered an error responding to "
488 	    "control message 2\n"
489 	    "Problems may arrise but continuing\n",
490 	    dev->descriptor.idVendor, dev->descriptor.idProduct);
491   }
492 
493   /* Close the USB device handle */
494   usb_close(devh);
495   return 1;
496 }
497 #endif /* MILD_MTP_PROBING */
498 
499 /**
500  * This function scans through the connected usb devices on a machine and
501  * if they match known Vendor and Product identifiers appends them to the
502  * dynamic array mtp_device_list. Be sure to call
503  * <code>free_mtpdevice_list(mtp_device_list)</code> when you are done
504  * with it, assuming it is not NULL.
505  * @param mtp_device_list dynamic array of pointers to usb devices with MTP
506  *        properties (if this list is not empty, new entries will be appended
507  *        to the list).
508  * @return LIBMTP_ERROR_NONE implies that devices have been found, scan the list
509  *        appropriately. LIBMTP_ERROR_NO_DEVICE_ATTACHED implies that no
510  *        devices have been found.
511  */
get_mtp_usb_device_list(mtpdevice_list_t ** mtp_device_list)512 static LIBMTP_error_number_t get_mtp_usb_device_list(mtpdevice_list_t ** mtp_device_list)
513 {
514   struct usb_bus *bus = init_usb();
515   for (; bus != NULL; bus = bus->next) {
516     struct usb_device *dev = bus->devices;
517     for (; dev != NULL; dev = dev->next) {
518       if (dev->descriptor.bDeviceClass != USB_CLASS_HUB) {
519 	int i;
520         int found = 0;
521 
522 	// First check if we know about the device already.
523 	// Devices well known to us will not have their descriptors
524 	// probed, it caused problems with some devices.
525         for(i = 0; i < mtp_device_table_size; i++) {
526           if(dev->descriptor.idVendor == mtp_device_table[i].vendor_id &&
527             dev->descriptor.idProduct == mtp_device_table[i].product_id) {
528             /* Append this usb device to the MTP device list */
529             *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list,
530 							dev,
531 							bus->location);
532             found = 1;
533             break;
534           }
535         }
536 	// If we didn't know it, try probing the "OS Descriptor".
537         if (!found) {
538           if (probe_device_descriptor(dev, NULL)) {
539             /* Append this usb device to the MTP USB Device List */
540             *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list,
541 							dev,
542 							bus->location);
543           }
544           /*
545 	   * By thomas_-_s: Also append devices that are no MTP but PTP devices
546 	   * if this is commented out.
547 	   */
548 	  /*
549 	  else {
550 	    // Check whether the device is no USB hub but a PTP.
551 	    if ( dev->config != NULL &&dev->config->interface->altsetting->bInterfaceClass == USB_CLASS_PTP && dev->descriptor.bDeviceClass != USB_CLASS_HUB ) {
552 	      *mtp_device_list = append_to_mtpdevice_list(*mtp_device_list, dev, bus->location);
553 	    }
554           }
555 	  */
556         }
557       }
558     }
559   }
560 
561   /* If nothing was found we end up here. */
562   if(*mtp_device_list == NULL) {
563     return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
564   }
565   return LIBMTP_ERROR_NONE;
566 }
567 
568 /**
569  * Detect the raw MTP device descriptors and return a list of
570  * of the devices found.
571  *
572  * @param devices a pointer to a variable that will hold
573  *        the list of raw devices found. This may be NULL
574  *        on return if the number of detected devices is zero.
575  *        The user shall simply <code>free()</code> this
576  *        variable when finished with the raw devices,
577  *        in order to release memory.
578  * @param numdevs a pointer to an integer that will hold
579  *        the number of devices in the list. This may
580  *        be 0.
581  * @return 0 if successful, any other value means failure.
582  */
LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t ** devices,int * numdevs)583 LIBMTP_error_number_t LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t ** devices,
584 			      int * numdevs)
585 {
586   mtpdevice_list_t *devlist = NULL;
587   mtpdevice_list_t *dev;
588   LIBMTP_error_number_t ret;
589   LIBMTP_raw_device_t *retdevs;
590   int devs = 0;
591   int i, j;
592 
593   ret = get_mtp_usb_device_list(&devlist);
594   if (ret == LIBMTP_ERROR_NO_DEVICE_ATTACHED) {
595     *devices = NULL;
596     *numdevs = 0;
597     return ret;
598   } else if (ret != LIBMTP_ERROR_NONE) {
599     fprintf(stderr, "LIBMTP PANIC: get_mtp_usb_device_list() "
600 	    "error code: %d on line %d\n", ret, __LINE__);
601     return ret;
602   }
603 
604   // Get list size
605   dev = devlist;
606   while (dev != NULL) {
607     devs++;
608     dev = dev->next;
609   }
610   if (devs == 0) {
611     *devices = NULL;
612     *numdevs = 0;
613     return LIBMTP_ERROR_NONE;
614   }
615   // Conjure a device list
616   retdevs = (LIBMTP_raw_device_t *) malloc(sizeof(LIBMTP_raw_device_t) * devs);
617   if (retdevs == NULL) {
618     // Out of memory
619     *devices = NULL;
620     *numdevs = 0;
621     return LIBMTP_ERROR_MEMORY_ALLOCATION;
622   }
623   dev = devlist;
624   i = 0;
625   while (dev != NULL) {
626     int device_known = 0;
627 
628     // Assign default device info
629     retdevs[i].device_entry.vendor = NULL;
630     retdevs[i].device_entry.vendor_id = dev->libusb_device->descriptor.idVendor;
631     retdevs[i].device_entry.product = NULL;
632     retdevs[i].device_entry.product_id = dev->libusb_device->descriptor.idProduct;
633     retdevs[i].device_entry.device_flags = 0x00000000U;
634     // See if we can locate some additional vendor info and device flags
635     for(j = 0; j < mtp_device_table_size; j++) {
636       if(dev->libusb_device->descriptor.idVendor == mtp_device_table[j].vendor_id &&
637 	 dev->libusb_device->descriptor.idProduct == mtp_device_table[j].product_id) {
638 	device_known = 1;
639 	retdevs[i].device_entry.vendor = mtp_device_table[j].vendor;
640 	retdevs[i].device_entry.product = mtp_device_table[j].product;
641 	retdevs[i].device_entry.device_flags = mtp_device_table[j].device_flags;
642 
643 #ifdef _AFT_BUILD
644     // Disable the following features for all devices.
645 	retdevs[i].device_entry.device_flags |= DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST|
646                                             DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST|
647                                             DEVICE_FLAG_BROKEN_SEND_OBJECT_PROPLIST;
648 #endif
649 
650 #ifdef ENABLE_USB_BULK_DEBUG
651 	// This device is known to the developers
652 	fprintf(stderr, "Device %d (VID=%04x and PID=%04x) is a %s %s.\n",
653 		i,
654 		dev->libusb_device->descriptor.idVendor,
655 		dev->libusb_device->descriptor.idProduct,
656 		mtp_device_table[j].vendor,
657 		mtp_device_table[j].product);
658 #endif
659 	break;
660       }
661     }
662     if (!device_known) {
663       // This device is unknown to the developers
664       fprintf(stderr, "Device %d (VID=%04x and PID=%04x) is UNKNOWN.\n",
665 	      i,
666 	      dev->libusb_device->descriptor.idVendor,
667 	      dev->libusb_device->descriptor.idProduct);
668       fprintf(stderr, "Please report this VID/PID and the device model to the "
669 	      "libmtp development team\n");
670       /*
671        * Trying to get iManufacturer or iProduct from the device at this
672        * point would require opening a device handle, that we don't want
673        * to do right now. (Takes time for no good enough reason.)
674        */
675     }
676     // Save the location on the bus
677     retdevs[i].bus_location = dev->bus_location;
678     retdevs[i].devnum = dev->libusb_device->devnum;
679     i++;
680     dev = dev->next;
681   }
682   *devices = retdevs;
683   *numdevs = i;
684   free_mtpdevice_list(devlist);
685   return LIBMTP_ERROR_NONE;
686 }
687 
688 /**
689  * This routine just dumps out low-level
690  * USB information about the current device.
691  * @param ptp_usb the USB device to get information from.
692  */
dump_usbinfo(PTP_USB * ptp_usb)693 void dump_usbinfo(PTP_USB *ptp_usb)
694 {
695   struct usb_device *dev;
696 
697 #ifdef LIBUSB_HAS_GET_DRIVER_NP
698   char devname[0x10];
699   int res;
700 
701   devname[0] = '\0';
702   res = usb_get_driver_np(ptp_usb->handle, (int) ptp_usb->interface, devname, sizeof(devname));
703   if (devname[0] != '\0') {
704     printf("   Using kernel interface \"%s\"\n", devname);
705   }
706 #endif
707   dev = usb_device(ptp_usb->handle);
708   printf("   bcdUSB: %d\n", dev->descriptor.bcdUSB);
709   printf("   bDeviceClass: %d\n", dev->descriptor.bDeviceClass);
710   printf("   bDeviceSubClass: %d\n", dev->descriptor.bDeviceSubClass);
711   printf("   bDeviceProtocol: %d\n", dev->descriptor.bDeviceProtocol);
712   printf("   idVendor: %04x\n", dev->descriptor.idVendor);
713   printf("   idProduct: %04x\n", dev->descriptor.idProduct);
714   printf("   IN endpoint maxpacket: %d bytes\n", ptp_usb->inep_maxpacket);
715   printf("   OUT endpoint maxpacket: %d bytes\n", ptp_usb->outep_maxpacket);
716   printf("   Raw device info:\n");
717   printf("      Bus location: %d\n", ptp_usb->rawdevice.bus_location);
718   printf("      Device number: %d\n", ptp_usb->rawdevice.devnum);
719   printf("      Device entry info:\n");
720   printf("         Vendor: %s\n", ptp_usb->rawdevice.device_entry.vendor);
721   printf("         Vendor id: 0x%04x\n", ptp_usb->rawdevice.device_entry.vendor_id);
722   printf("         Product: %s\n", ptp_usb->rawdevice.device_entry.product);
723   printf("         Vendor id: 0x%04x\n", ptp_usb->rawdevice.device_entry.product_id);
724   printf("         Device flags: 0x%08x\n", ptp_usb->rawdevice.device_entry.device_flags);
725   (void) probe_device_descriptor(dev, stdout);
726 }
727 
728 /**
729  * Retrieve the apropriate playlist extension for this
730  * device. Rather hacky at the moment. This is probably
731  * desired by the managing software, but when creating
732  * lists on the device itself you notice certain preferences.
733  * @param ptp_usb the USB device to get suggestion for.
734  * @return the suggested playlist extension.
735  */
get_playlist_extension(PTP_USB * ptp_usb)736 const char *get_playlist_extension(PTP_USB *ptp_usb)
737 {
738   struct usb_device *dev;
739   static char creative_pl_extension[] = ".zpl";
740   static char default_pl_extension[] = ".pla";
741 
742   dev = usb_device(ptp_usb->handle);
743   if (dev->descriptor.idVendor == 0x041e) {
744     return creative_pl_extension;
745   }
746   return default_pl_extension;
747 }
748 
749 static void
libusb_glue_debug(PTPParams * params,const char * format,...)750 libusb_glue_debug (PTPParams *params, const char *format, ...)
751 {
752         va_list args;
753 
754         va_start (args, format);
755         if (params->debug_func!=NULL)
756                 params->debug_func (params->data, format, args);
757         else
758 	{
759                 vfprintf (stderr, format, args);
760 		fprintf (stderr,"\n");
761 		fflush (stderr);
762 	}
763         va_end (args);
764 }
765 
766 static void
libusb_glue_error(PTPParams * params,const char * format,...)767 libusb_glue_error (PTPParams *params, const char *format, ...)
768 {
769         va_list args;
770 
771         va_start (args, format);
772         if (params->error_func!=NULL)
773                 params->error_func (params->data, format, args);
774         else
775 	{
776                 vfprintf (stderr, format, args);
777 		fprintf (stderr,"\n");
778 		fflush (stderr);
779 	}
780         va_end (args);
781 }
782 
783 
784 /*
785  * ptp_read_func() and ptp_write_func() are
786  * based on same functions usb.c in libgphoto2.
787  * Much reading packet logs and having fun with trials and errors
788  * reveals that WMP / Windows is probably using an algorithm like this
789  * for large transfers:
790  *
791  * 1. Send the command (0x0c bytes) if headers are split, else, send
792  *    command plus sizeof(endpoint) - 0x0c bytes.
793  * 2. Send first packet, max size to be sizeof(endpoint) but only when using
794  *    split headers. Else goto 3.
795  * 3. REPEAT send 0x10000 byte chunks UNTIL remaining bytes < 0x10000
796  *    We call 0x10000 CONTEXT_BLOCK_SIZE.
797  * 4. Send remaining bytes MOD sizeof(endpoint)
798  * 5. Send remaining bytes. If this happens to be exactly sizeof(endpoint)
799  *    then also send a zero-length package.
800  *
801  * Further there is some special quirks to handle zero reads from the
802  * device, since some devices can't do them at all due to shortcomings
803  * of the USB slave controller in the device.
804  */
805 #define CONTEXT_BLOCK_SIZE_1	0x3e00
806 #define CONTEXT_BLOCK_SIZE_2  0x200
807 #define CONTEXT_BLOCK_SIZE    CONTEXT_BLOCK_SIZE_1+CONTEXT_BLOCK_SIZE_2
808 static short
ptp_read_func(unsigned long size,PTPDataHandler * handler,void * data,unsigned long * readbytes,int readzero)809 ptp_read_func (
810 	unsigned long size, PTPDataHandler *handler,void *data,
811 	unsigned long *readbytes,
812 	int readzero
813 ) {
814   PTP_USB *ptp_usb = (PTP_USB *)data;
815   unsigned long toread = 0;
816   int result = 0;
817   unsigned long curread = 0;
818   unsigned long written;
819   unsigned char *bytes;
820   int expect_terminator_byte = 0;
821 
822   // This is the largest block we'll need to read in.
823   bytes = malloc(CONTEXT_BLOCK_SIZE);
824   while (curread < size) {
825 
826 #ifdef ENABLE_USB_BULK_DEBUG
827     printf("Remaining size to read: 0x%04lx bytes\n", size - curread);
828 #endif
829     // check equal to condition here
830     if (size - curread < CONTEXT_BLOCK_SIZE)
831     {
832       // this is the last packet
833       toread = size - curread;
834       // this is equivalent to zero read for these devices
835       if (readzero && FLAG_NO_ZERO_READS(ptp_usb) && toread % 64 == 0) {
836         toread += 1;
837         expect_terminator_byte = 1;
838       }
839     }
840     else if (curread == 0)
841       // we are first packet, but not last packet
842       toread = CONTEXT_BLOCK_SIZE_1;
843     else if (toread == CONTEXT_BLOCK_SIZE_1)
844       toread = CONTEXT_BLOCK_SIZE_2;
845     else if (toread == CONTEXT_BLOCK_SIZE_2)
846       toread = CONTEXT_BLOCK_SIZE_1;
847     else
848       printf("unexpected toread size 0x%04x, 0x%04x remaining bytes\n",
849 	     (unsigned int) toread, (unsigned int) (size-curread));
850 
851 #ifdef ENABLE_USB_BULK_DEBUG
852     printf("Reading in 0x%04lx bytes\n", toread);
853 #endif
854     result = USB_BULK_READ(ptp_usb->handle, ptp_usb->inep, (char*)bytes, toread, ptp_usb->timeout);
855 #ifdef ENABLE_USB_BULK_DEBUG
856     printf("Result of read: 0x%04x\n", result);
857 #endif
858 
859     if (result < 0) {
860       return PTP_ERROR_IO;
861     }
862 #ifdef ENABLE_USB_BULK_DEBUG
863     printf("<==USB IN\n");
864     if (result == 0)
865       printf("Zero Read\n");
866     else if (result < 0)
867       fprintf(stderr, "USB_BULK_READ result=%#x\n", result);
868     else
869       data_dump_ascii (stdout,bytes,result,16);
870 #endif
871 
872     // want to discard extra byte
873     if (expect_terminator_byte && result == toread)
874     {
875 #ifdef ENABLE_USB_BULK_DEBUG
876       printf("<==USB IN\nDiscarding extra byte\n");
877 #endif
878       result--;
879     }
880 
881     int putfunc_ret = handler->putfunc(NULL, handler->priv, result, bytes, &written);
882     if (putfunc_ret != PTP_RC_OK)
883       return putfunc_ret;
884 
885     ptp_usb->current_transfer_complete += result;
886     curread += result;
887 
888     // Increase counters, call callback
889     if (ptp_usb->callback_active) {
890       if (ptp_usb->current_transfer_complete >= ptp_usb->current_transfer_total) {
891 	// send last update and disable callback.
892 	ptp_usb->current_transfer_complete = ptp_usb->current_transfer_total;
893 	ptp_usb->callback_active = 0;
894       }
895       if (ptp_usb->current_transfer_callback != NULL) {
896 	int ret;
897 	ret = ptp_usb->current_transfer_callback(ptp_usb->current_transfer_complete,
898 						 ptp_usb->current_transfer_total,
899 						 ptp_usb->current_transfer_callback_data);
900 	if (ret != 0) {
901 	  return PTP_ERROR_CANCEL;
902 	}
903       }
904     }
905 
906     if (result < toread) /* short reads are common */
907       break;
908   }
909   if (readbytes) *readbytes = curread;
910   free (bytes);
911 
912   // there might be a zero packet waiting for us...
913   if (readzero &&
914       !FLAG_NO_ZERO_READS(ptp_usb) &&
915       curread % ptp_usb->outep_maxpacket == 0) {
916     char temp;
917     int zeroresult = 0;
918 
919 #ifdef ENABLE_USB_BULK_DEBUG
920     printf("<==USB IN\n");
921     printf("Zero Read\n");
922 #endif
923     zeroresult = USB_BULK_READ(ptp_usb->handle, ptp_usb->inep, &temp, 0, ptp_usb->timeout);
924     if (zeroresult != 0)
925       printf("LIBMTP panic: unable to read in zero packet, response 0x%04x", zeroresult);
926   }
927 
928   return PTP_RC_OK;
929 }
930 
931 static short
ptp_write_func(unsigned long size,PTPDataHandler * handler,void * data,unsigned long * written)932 ptp_write_func (
933         unsigned long   size,
934         PTPDataHandler  *handler,
935         void            *data,
936         unsigned long   *written
937 ) {
938   PTP_USB *ptp_usb = (PTP_USB *)data;
939   unsigned long towrite = 0;
940   int result = 0;
941   unsigned long curwrite = 0;
942   unsigned char *bytes;
943 
944   // This is the largest block we'll need to read in.
945   bytes = malloc(CONTEXT_BLOCK_SIZE);
946   if (!bytes) {
947     return PTP_ERROR_IO;
948   }
949   while (curwrite < size) {
950     unsigned long usbwritten = 0;
951     towrite = size-curwrite;
952     if (towrite > CONTEXT_BLOCK_SIZE) {
953       towrite = CONTEXT_BLOCK_SIZE;
954     } else {
955       // This magic makes packets the same size that WMP send them.
956       if (towrite > ptp_usb->outep_maxpacket && towrite % ptp_usb->outep_maxpacket != 0) {
957         towrite -= towrite % ptp_usb->outep_maxpacket;
958       }
959     }
960     int getfunc_ret = handler->getfunc(NULL, handler->priv,towrite,bytes,&towrite);
961     if (getfunc_ret != PTP_RC_OK)
962       return getfunc_ret;
963     while (usbwritten < towrite) {
964 	    result = USB_BULK_WRITE(ptp_usb->handle,ptp_usb->outep,((char*)bytes+usbwritten),towrite-usbwritten,ptp_usb->timeout);
965 #ifdef ENABLE_USB_BULK_DEBUG
966 	    printf("USB OUT==>\n");
967         if (result > 0) {
968             data_dump_ascii (stdout,bytes+usbwritten,result,16);
969         } else {
970             fprintf(stderr, "USB_BULK_WRITE: result=%#x\n", result);
971         }
972 #endif
973 	    if (result < 0) {
974 	      return PTP_ERROR_IO;
975 	    }
976 	    // check for result == 0 perhaps too.
977 	    // Increase counters
978 	    ptp_usb->current_transfer_complete += result;
979 	    curwrite += result;
980 	    usbwritten += result;
981     }
982     // call callback
983     if (ptp_usb->callback_active) {
984       if (ptp_usb->current_transfer_complete >= ptp_usb->current_transfer_total) {
985 	// send last update and disable callback.
986 	ptp_usb->current_transfer_complete = ptp_usb->current_transfer_total;
987 	ptp_usb->callback_active = 0;
988       }
989       if (ptp_usb->current_transfer_callback != NULL) {
990 	int ret;
991 	ret = ptp_usb->current_transfer_callback(ptp_usb->current_transfer_complete,
992 						 ptp_usb->current_transfer_total,
993 						 ptp_usb->current_transfer_callback_data);
994 	if (ret != 0) {
995 	  return PTP_ERROR_CANCEL;
996 	}
997       }
998     }
999     if (result < towrite) /* short writes happen */
1000       break;
1001   }
1002   free (bytes);
1003   if (written) {
1004     *written = curwrite;
1005   }
1006 
1007 
1008   // If this is the last transfer send a zero write if required
1009   if (ptp_usb->current_transfer_complete >= ptp_usb->current_transfer_total) {
1010     if ((towrite % ptp_usb->outep_maxpacket) == 0) {
1011 #ifdef ENABLE_USB_BULK_DEBUG
1012       printf("USB OUT==>\n");
1013       printf("Zero Write\n");
1014 #endif
1015       result=USB_BULK_WRITE(ptp_usb->handle,ptp_usb->outep,(char *)"x",0,ptp_usb->timeout);
1016     }
1017   }
1018 
1019   if (result < 0)
1020     return PTP_ERROR_IO;
1021   return PTP_RC_OK;
1022 }
1023 
1024 /* memory data get/put handler */
1025 typedef struct {
1026 	unsigned char	*data;
1027 	unsigned long	size, curoff;
1028 } PTPMemHandlerPrivate;
1029 
1030 static uint16_t
memory_getfunc(PTPParams * params,void * private,unsigned long wantlen,unsigned char * data,unsigned long * gotlen)1031 memory_getfunc(PTPParams* params, void* private,
1032 	       unsigned long wantlen, unsigned char *data,
1033 	       unsigned long *gotlen
1034 ) {
1035 	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
1036 	unsigned long tocopy = wantlen;
1037 
1038 	if (priv->curoff + tocopy > priv->size)
1039 		tocopy = priv->size - priv->curoff;
1040 	memcpy (data, priv->data + priv->curoff, tocopy);
1041 	priv->curoff += tocopy;
1042 	*gotlen = tocopy;
1043 	return PTP_RC_OK;
1044 }
1045 
1046 static uint16_t
memory_putfunc(PTPParams * params,void * private,unsigned long sendlen,unsigned char * data,unsigned long * putlen)1047 memory_putfunc(PTPParams* params, void* private,
1048 	       unsigned long sendlen, unsigned char *data,
1049 	       unsigned long *putlen
1050 ) {
1051 	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
1052 
1053 	if (priv->curoff + sendlen > priv->size) {
1054 		priv->data = realloc (priv->data, priv->curoff+sendlen);
1055 		priv->size = priv->curoff + sendlen;
1056 	}
1057 	memcpy (priv->data + priv->curoff, data, sendlen);
1058 	priv->curoff += sendlen;
1059 	*putlen = sendlen;
1060 	return PTP_RC_OK;
1061 }
1062 
1063 /* init private struct for receiving data. */
1064 static uint16_t
ptp_init_recv_memory_handler(PTPDataHandler * handler)1065 ptp_init_recv_memory_handler(PTPDataHandler *handler) {
1066 	PTPMemHandlerPrivate* priv;
1067 	priv = malloc (sizeof(PTPMemHandlerPrivate));
1068 	handler->priv = priv;
1069 	handler->getfunc = memory_getfunc;
1070 	handler->putfunc = memory_putfunc;
1071 	priv->data = NULL;
1072 	priv->size = 0;
1073 	priv->curoff = 0;
1074 	return PTP_RC_OK;
1075 }
1076 
1077 /* init private struct and put data in for sending data.
1078  * data is still owned by caller.
1079  */
1080 static uint16_t
ptp_init_send_memory_handler(PTPDataHandler * handler,unsigned char * data,unsigned long len)1081 ptp_init_send_memory_handler(PTPDataHandler *handler,
1082 	unsigned char *data, unsigned long len
1083 ) {
1084 	PTPMemHandlerPrivate* priv;
1085 	priv = malloc (sizeof(PTPMemHandlerPrivate));
1086 	if (!priv)
1087 		return PTP_RC_GeneralError;
1088 	handler->priv = priv;
1089 	handler->getfunc = memory_getfunc;
1090 	handler->putfunc = memory_putfunc;
1091 	priv->data = data;
1092 	priv->size = len;
1093 	priv->curoff = 0;
1094 	return PTP_RC_OK;
1095 }
1096 
1097 /* free private struct + data */
1098 static uint16_t
ptp_exit_send_memory_handler(PTPDataHandler * handler)1099 ptp_exit_send_memory_handler (PTPDataHandler *handler) {
1100 	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
1101 	/* data is owned by caller */
1102 	free (priv);
1103 	return PTP_RC_OK;
1104 }
1105 
1106 /* hand over our internal data to caller */
1107 static uint16_t
ptp_exit_recv_memory_handler(PTPDataHandler * handler,unsigned char ** data,unsigned long * size)1108 ptp_exit_recv_memory_handler (PTPDataHandler *handler,
1109 	unsigned char **data, unsigned long *size
1110 ) {
1111 	PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)handler->priv;
1112 	*data = priv->data;
1113 	*size = priv->size;
1114 	free (priv);
1115 	return PTP_RC_OK;
1116 }
1117 
1118 /* send / receive functions */
1119 
1120 uint16_t
ptp_usb_sendreq(PTPParams * params,PTPContainer * req)1121 ptp_usb_sendreq (PTPParams* params, PTPContainer* req)
1122 {
1123 	uint16_t ret;
1124 	PTPUSBBulkContainer usbreq;
1125 	PTPDataHandler	memhandler;
1126 	unsigned long written = 0;
1127 	unsigned long towrite;
1128 #ifdef ENABLE_USB_BULK_DEBUG
1129 	char txt[256];
1130 
1131 	(void) ptp_render_opcode (params, req->Code, sizeof(txt), txt);
1132 	printf("REQUEST: 0x%04x, %s\n", req->Code, txt);
1133 #endif
1134 	/* build appropriate USB container */
1135 	usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
1136 		(sizeof(uint32_t)*(5-req->Nparam)));
1137 	usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);
1138 	usbreq.code=htod16(req->Code);
1139 	usbreq.trans_id=htod32(req->Transaction_ID);
1140 	usbreq.payload.params.param1=htod32(req->Param1);
1141 	usbreq.payload.params.param2=htod32(req->Param2);
1142 	usbreq.payload.params.param3=htod32(req->Param3);
1143 	usbreq.payload.params.param4=htod32(req->Param4);
1144 	usbreq.payload.params.param5=htod32(req->Param5);
1145 	/* send it to responder */
1146 	towrite = PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam));
1147 	ptp_init_send_memory_handler (&memhandler, (unsigned char*)&usbreq, towrite);
1148 	ret=ptp_write_func(
1149 		towrite,
1150 		&memhandler,
1151 		params->data,
1152 		&written
1153 	);
1154 	ptp_exit_send_memory_handler (&memhandler);
1155 	if (ret!=PTP_RC_OK && ret!=PTP_ERROR_CANCEL) {
1156 		ret = PTP_ERROR_IO;
1157 	}
1158 	if (written != towrite && ret != PTP_ERROR_CANCEL && ret != PTP_ERROR_IO) {
1159 		libusb_glue_error (params,
1160 			"PTP: request code 0x%04x sending req wrote only %ld bytes instead of %d",
1161 			req->Code, written, towrite
1162 		);
1163 		ret = PTP_ERROR_IO;
1164 	}
1165 	return ret;
1166 }
1167 
1168 uint16_t
ptp_usb_senddata(PTPParams * params,PTPContainer * ptp,unsigned long size,PTPDataHandler * handler)1169 ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
1170 		  unsigned long size, PTPDataHandler *handler
1171 ) {
1172 	uint16_t ret;
1173 	int wlen, datawlen;
1174 	unsigned long written;
1175 	PTPUSBBulkContainer usbdata;
1176 	uint32_t bytes_left_to_transfer;
1177 	PTPDataHandler memhandler;
1178 
1179 #ifdef ENABLE_USB_BULK_DEBUG
1180 	printf("SEND DATA PHASE\n");
1181 #endif
1182 	/* build appropriate USB container */
1183 	usbdata.length	= htod32(PTP_USB_BULK_HDR_LEN+size);
1184 	usbdata.type	= htod16(PTP_USB_CONTAINER_DATA);
1185 	usbdata.code	= htod16(ptp->Code);
1186 	usbdata.trans_id= htod32(ptp->Transaction_ID);
1187 
1188 	((PTP_USB*)params->data)->current_transfer_complete = 0;
1189 	((PTP_USB*)params->data)->current_transfer_total = size+PTP_USB_BULK_HDR_LEN;
1190 
1191 	if (params->split_header_data) {
1192 		datawlen = 0;
1193 		wlen = PTP_USB_BULK_HDR_LEN;
1194 	} else {
1195 		unsigned long gotlen;
1196 		/* For all camera devices. */
1197 		datawlen = (size<PTP_USB_BULK_PAYLOAD_LEN_WRITE)?size:PTP_USB_BULK_PAYLOAD_LEN_WRITE;
1198 		wlen = PTP_USB_BULK_HDR_LEN + datawlen;
1199 
1200 		ret = handler->getfunc(params, handler->priv, datawlen, usbdata.payload.data, &gotlen);
1201 		if (ret != PTP_RC_OK)
1202 			return ret;
1203 		if (gotlen != datawlen)
1204 			return PTP_RC_GeneralError;
1205 	}
1206 	ptp_init_send_memory_handler (&memhandler, (unsigned char *)&usbdata, wlen);
1207 	/* send first part of data */
1208 	ret = ptp_write_func(wlen, &memhandler, params->data, &written);
1209 	ptp_exit_send_memory_handler (&memhandler);
1210 	if (ret!=PTP_RC_OK) {
1211 		return ret;
1212 	}
1213 	if (size <= datawlen) return ret;
1214 	/* if everything OK send the rest */
1215 	bytes_left_to_transfer = size-datawlen;
1216 	ret = PTP_RC_OK;
1217 	while(bytes_left_to_transfer > 0) {
1218 		ret = ptp_write_func (bytes_left_to_transfer, handler, params->data, &written);
1219 		if (ret != PTP_RC_OK)
1220 			break;
1221 		if (written == 0) {
1222 			ret = PTP_ERROR_IO;
1223 			break;
1224 		}
1225 		bytes_left_to_transfer -= written;
1226 	}
1227 	if (ret!=PTP_RC_OK && ret!=PTP_ERROR_CANCEL)
1228 		ret = PTP_ERROR_IO;
1229 	return ret;
1230 }
1231 
ptp_usb_getpacket(PTPParams * params,PTPUSBBulkContainer * packet,unsigned long * rlen)1232 static uint16_t ptp_usb_getpacket(PTPParams *params,
1233 		PTPUSBBulkContainer *packet, unsigned long *rlen)
1234 {
1235 	PTPDataHandler	memhandler;
1236 	uint16_t	ret;
1237 	unsigned char	*x = NULL;
1238 
1239 	/* read the header and potentially the first data */
1240 	if (params->response_packet_size > 0) {
1241 		/* If there is a buffered packet, just use it. */
1242 		memcpy(packet, params->response_packet, params->response_packet_size);
1243 		*rlen = params->response_packet_size;
1244 		free(params->response_packet);
1245 		params->response_packet = NULL;
1246 		params->response_packet_size = 0;
1247 		/* Here this signifies a "virtual read" */
1248 		return PTP_RC_OK;
1249 	}
1250 	ptp_init_recv_memory_handler (&memhandler);
1251 	ret = ptp_read_func(PTP_USB_BULK_HS_MAX_PACKET_LEN_READ, &memhandler, params->data, rlen, 0);
1252 	ptp_exit_recv_memory_handler (&memhandler, &x, rlen);
1253 	if (x) {
1254 		memcpy (packet, x, *rlen);
1255 		free (x);
1256 	}
1257 	return ret;
1258 }
1259 
1260 uint16_t
ptp_usb_getdata(PTPParams * params,PTPContainer * ptp,PTPDataHandler * handler)1261 ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
1262 {
1263 	uint16_t ret;
1264 	PTPUSBBulkContainer usbdata;
1265 	unsigned long	written;
1266 	PTP_USB *ptp_usb = (PTP_USB *) params->data;
1267 
1268 #ifdef ENABLE_USB_BULK_DEBUG
1269 	printf("GET DATA PHASE\n");
1270 #endif
1271 	memset(&usbdata,0,sizeof(usbdata));
1272 	do {
1273 		unsigned long len, rlen;
1274 
1275 		ret = ptp_usb_getpacket(params, &usbdata, &rlen);
1276 		if (ret!=PTP_RC_OK) {
1277 			ret = PTP_ERROR_IO;
1278 			break;
1279 		}
1280 		if (dtoh16(usbdata.type)!=PTP_USB_CONTAINER_DATA) {
1281 			ret = PTP_ERROR_DATA_EXPECTED;
1282 			break;
1283 		}
1284 		if (dtoh16(usbdata.code)!=ptp->Code) {
1285 			if (FLAG_IGNORE_HEADER_ERRORS(ptp_usb)) {
1286 				libusb_glue_debug (params, "ptp2/ptp_usb_getdata: detected a broken "
1287 					   "PTP header, code field insane, expect problems! (But continuing)");
1288 				// Repair the header, so it won't wreak more havoc, don't just ignore it.
1289 				// Typically these two fields will be broken.
1290 				usbdata.code	 = htod16(ptp->Code);
1291 				usbdata.trans_id = htod32(ptp->Transaction_ID);
1292 				ret = PTP_RC_OK;
1293 			} else {
1294 				ret = dtoh16(usbdata.code);
1295 				// This filters entirely insane garbage return codes, but still
1296 				// makes it possible to return error codes in the code field when
1297 				// getting data. It appears Windows ignores the contents of this
1298 				// field entirely.
1299 				if (ret < PTP_RC_Undefined || ret > PTP_RC_SpecificationOfDestinationUnsupported) {
1300 					libusb_glue_debug (params, "ptp2/ptp_usb_getdata: detected a broken "
1301 						   "PTP header, code field insane.");
1302 					ret = PTP_ERROR_IO;
1303 				}
1304 				break;
1305 			}
1306 		}
1307 		if (usbdata.length == 0xffffffffU) {
1308 			/* Copy first part of data to 'data' */
1309       int putfunc_ret =
1310 			handler->putfunc(
1311 				params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN, usbdata.payload.data,
1312 				&written
1313 			);
1314       if (putfunc_ret != PTP_RC_OK)
1315         return putfunc_ret;
1316 			/* stuff data directly to passed data handler */
1317 			while (1) {
1318 				unsigned long readdata;
1319 				uint16_t xret;
1320 
1321 				xret = ptp_read_func(
1322 					PTP_USB_BULK_HS_MAX_PACKET_LEN_READ,
1323 					handler,
1324 					params->data,
1325 					&readdata,
1326 					0
1327 				);
1328 				if (xret != PTP_RC_OK)
1329 					return xret;
1330 				if (readdata < PTP_USB_BULK_HS_MAX_PACKET_LEN_READ)
1331 					break;
1332 			}
1333 			return PTP_RC_OK;
1334 		}
1335 		if (rlen > dtoh32(usbdata.length)) {
1336 			/*
1337 			 * Buffer the surplus response packet if it is >=
1338 			 * PTP_USB_BULK_HDR_LEN
1339 			 * (i.e. it is probably an entire package)
1340 			 * else discard it as erroneous surplus data.
1341 			 * This will even work if more than 2 packets appear
1342 			 * in the same transaction, they will just be handled
1343 			 * iteratively.
1344 			 *
1345 			 * Marcus observed stray bytes on iRiver devices;
1346 			 * these are still discarded.
1347 			 */
1348 			unsigned int packlen = dtoh32(usbdata.length);
1349 			unsigned int surplen = rlen - packlen;
1350 
1351 			if (surplen >= PTP_USB_BULK_HDR_LEN) {
1352 				params->response_packet = malloc(surplen);
1353 				memcpy(params->response_packet,
1354 				       (uint8_t *) &usbdata + packlen, surplen);
1355 				params->response_packet_size = surplen;
1356 			/* Ignore reading one extra byte if device flags have been set */
1357 			} else if(!FLAG_NO_ZERO_READS(ptp_usb) &&
1358 				  (rlen - dtoh32(usbdata.length) == 1)) {
1359 			  libusb_glue_debug (params, "ptp2/ptp_usb_getdata: read %d bytes "
1360 				     "too much, expect problems!",
1361 				     rlen - dtoh32(usbdata.length));
1362 			}
1363 			rlen = packlen;
1364 		}
1365 
1366 		/* For most PTP devices rlen is 512 == sizeof(usbdata)
1367 		 * here. For MTP devices splitting header and data it might
1368 		 * be 12.
1369 		 */
1370 		/* Evaluate full data length. */
1371 		len=dtoh32(usbdata.length)-PTP_USB_BULK_HDR_LEN;
1372 
1373 		/* autodetect split header/data MTP devices */
1374 		if (dtoh32(usbdata.length) > 12 && (rlen==12))
1375 			params->split_header_data = 1;
1376 
1377 		/* Copy first part of data to 'data' */
1378     int putfunc_ret =
1379 		handler->putfunc(
1380 			params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN, usbdata.payload.data,
1381 			&written
1382 		);
1383     if (putfunc_ret != PTP_RC_OK)
1384       return putfunc_ret;
1385 
1386 		if (FLAG_NO_ZERO_READS(ptp_usb) &&
1387 		    len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) {
1388 #ifdef ENABLE_USB_BULK_DEBUG
1389 		  printf("Reading in extra terminating byte\n");
1390 #endif
1391 		  // need to read in extra byte and discard it
1392 		  int result = 0;
1393 		  char byte = 0;
1394                   result = USB_BULK_READ(ptp_usb->handle, ptp_usb->inep, &byte, 1, ptp_usb->timeout);
1395 
1396 		  if (result != 1)
1397 		    printf("Could not read in extra byte for PTP_USB_BULK_HS_MAX_PACKET_LEN_READ long file, return value 0x%04x\n", result);
1398 		} else if (len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ && params->split_header_data == 0) {
1399 		  int zeroresult = 0;
1400 		  char zerobyte = 0;
1401 
1402 #ifdef ENABLE_USB_BULK_DEBUG
1403 		  printf("Reading in zero packet after header\n");
1404 #endif
1405                   zeroresult = USB_BULK_READ(ptp_usb->handle, ptp_usb->inep, &zerobyte, 0, ptp_usb->timeout);
1406 
1407 		  if (zeroresult != 0)
1408 		    printf("LIBMTP panic: unable to read in zero packet, response 0x%04x", zeroresult);
1409 		}
1410 
1411 		/* Is that all of data? */
1412 		if (len+PTP_USB_BULK_HDR_LEN<=rlen) {
1413 		  break;
1414 		}
1415 
1416 		ret = ptp_read_func(len - (rlen - PTP_USB_BULK_HDR_LEN),
1417 				    handler,
1418 				    params->data, &rlen, 1);
1419 
1420 		if (ret!=PTP_RC_OK) {
1421 		  break;
1422 		}
1423 	} while (0);
1424 	return ret;
1425 }
1426 
1427 uint16_t
ptp_usb_getresp(PTPParams * params,PTPContainer * resp)1428 ptp_usb_getresp (PTPParams* params, PTPContainer* resp)
1429 {
1430 	uint16_t ret;
1431 	unsigned long rlen;
1432 	PTPUSBBulkContainer usbresp;
1433 	PTP_USB *ptp_usb = (PTP_USB *)(params->data);
1434 
1435 #ifdef ENABLE_USB_BULK_DEBUG
1436 	printf("RESPONSE: ");
1437 #endif
1438 	memset(&usbresp,0,sizeof(usbresp));
1439 	/* read response, it should never be longer than sizeof(usbresp) */
1440 	ret = ptp_usb_getpacket(params, &usbresp, &rlen);
1441 
1442 	// Fix for bevahiour reported by Scott Snyder on Samsung YP-U3. The player
1443 	// sends a packet containing just zeroes of length 2 (up to 4 has been seen too)
1444 	// after a NULL packet when it should send the response. This code ignores
1445 	// such illegal packets.
1446 	while (ret==PTP_RC_OK && rlen<PTP_USB_BULK_HDR_LEN && usbresp.length==0) {
1447 	  libusb_glue_debug (params, "ptp_usb_getresp: detected short response "
1448 		     "of %d bytes, expect problems! (re-reading "
1449 		     "response), rlen");
1450 	  ret = ptp_usb_getpacket(params, &usbresp, &rlen);
1451 	}
1452 
1453 	if (ret!=PTP_RC_OK) {
1454 		ret = PTP_ERROR_IO;
1455 	} else
1456 	if (dtoh16(usbresp.type)!=PTP_USB_CONTAINER_RESPONSE) {
1457 		ret = PTP_ERROR_RESP_EXPECTED;
1458 	} else
1459 	if (dtoh16(usbresp.code)!=resp->Code) {
1460 		ret = dtoh16(usbresp.code);
1461 	}
1462 #ifdef ENABLE_USB_BULK_DEBUG
1463 	printf("%04x\n", ret);
1464 #endif
1465 	if (ret!=PTP_RC_OK) {
1466 /*		libusb_glue_error (params,
1467 		"PTP: request code 0x%04x getting resp error 0x%04x",
1468 			resp->Code, ret);*/
1469 		return ret;
1470 	}
1471 	/* build an appropriate PTPContainer */
1472 	resp->Code=dtoh16(usbresp.code);
1473 	resp->SessionID=params->session_id;
1474 	resp->Transaction_ID=dtoh32(usbresp.trans_id);
1475 	if (FLAG_IGNORE_HEADER_ERRORS(ptp_usb)) {
1476 		if (resp->Transaction_ID != params->transaction_id-1) {
1477 			libusb_glue_debug (params, "ptp_usb_getresp: detected a broken "
1478 				   "PTP header, transaction ID insane, expect "
1479 				   "problems! (But continuing)");
1480 			// Repair the header, so it won't wreak more havoc.
1481 			resp->Transaction_ID = params->transaction_id-1;
1482 		}
1483 	}
1484 	resp->Param1=dtoh32(usbresp.payload.params.param1);
1485 	resp->Param2=dtoh32(usbresp.payload.params.param2);
1486 	resp->Param3=dtoh32(usbresp.payload.params.param3);
1487 	resp->Param4=dtoh32(usbresp.payload.params.param4);
1488 	resp->Param5=dtoh32(usbresp.payload.params.param5);
1489 	return ret;
1490 }
1491 
1492 /* Event handling functions */
1493 
1494 /* PTP Events wait for or check mode */
1495 #define PTP_EVENT_CHECK			0x0000	/* waits for */
1496 #define PTP_EVENT_CHECK_FAST		0x0001	/* checks */
1497 
1498 static inline uint16_t
ptp_usb_event(PTPParams * params,PTPContainer * event,int wait)1499 ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
1500 {
1501 	uint16_t ret;
1502 	int result;
1503 	unsigned long rlen;
1504 	PTPUSBEventContainer usbevent;
1505 	PTP_USB *ptp_usb = (PTP_USB *)(params->data);
1506 
1507 	memset(&usbevent,0,sizeof(usbevent));
1508 
1509 	if ((params==NULL) || (event==NULL))
1510 		return PTP_ERROR_BADPARAM;
1511 	ret = PTP_RC_OK;
1512 	switch(wait) {
1513 	case PTP_EVENT_CHECK:
1514                 result=USB_BULK_READ(ptp_usb->handle, ptp_usb->intep,(char *)&usbevent,sizeof(usbevent),ptp_usb->timeout);
1515 		if (result==0)
1516                         result = USB_BULK_READ(ptp_usb->handle, ptp_usb->intep,(char *) &usbevent, sizeof(usbevent), ptp_usb->timeout);
1517 		if (result < 0) ret = PTP_ERROR_IO;
1518 		break;
1519 	case PTP_EVENT_CHECK_FAST:
1520                 result=USB_BULK_READ(ptp_usb->handle, ptp_usb->intep,(char *)&usbevent,sizeof(usbevent),ptp_usb->timeout);
1521 		if (result==0)
1522                         result = USB_BULK_READ(ptp_usb->handle, ptp_usb->intep,(char *) &usbevent, sizeof(usbevent), ptp_usb->timeout);
1523 		if (result < 0) ret = PTP_ERROR_IO;
1524 		break;
1525 	default:
1526 		ret=PTP_ERROR_BADPARAM;
1527 		break;
1528 	}
1529 	if (ret!=PTP_RC_OK) {
1530 		libusb_glue_error (params,
1531 			"PTP: reading event an error 0x%04x occurred", ret);
1532 		return PTP_ERROR_IO;
1533 	}
1534 	rlen = result;
1535 	if (rlen < 8) {
1536 		libusb_glue_error (params,
1537 			"PTP: reading event an short read of %ld bytes occurred", rlen);
1538 		return PTP_ERROR_IO;
1539 	}
1540 	/* if we read anything over interrupt endpoint it must be an event */
1541 	/* build an appropriate PTPContainer */
1542 	event->Code=dtoh16(usbevent.code);
1543 	event->SessionID=params->session_id;
1544 	event->Transaction_ID=dtoh32(usbevent.trans_id);
1545 	event->Param1=dtoh32(usbevent.param1);
1546 	event->Param2=dtoh32(usbevent.param2);
1547 	event->Param3=dtoh32(usbevent.param3);
1548 	return ret;
1549 }
1550 
1551 uint16_t
ptp_usb_event_check(PTPParams * params,PTPContainer * event)1552 ptp_usb_event_check (PTPParams* params, PTPContainer* event) {
1553 
1554 	return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);
1555 }
1556 
1557 uint16_t
ptp_usb_event_wait(PTPParams * params,PTPContainer * event)1558 ptp_usb_event_wait (PTPParams* params, PTPContainer* event) {
1559 
1560 	return ptp_usb_event (params, event, PTP_EVENT_CHECK);
1561 }
1562 
1563 uint16_t
ptp_usb_control_cancel_request(PTPParams * params,uint32_t transactionid)1564 ptp_usb_control_cancel_request (PTPParams *params, uint32_t transactionid) {
1565 	PTP_USB *ptp_usb = (PTP_USB *)(params->data);
1566 	int ret;
1567 	unsigned char buffer[6];
1568 
1569 	htod16a(&buffer[0],PTP_EC_CancelTransaction);
1570 	htod32a(&buffer[2],transactionid);
1571 	ret = usb_control_msg(ptp_usb->handle,
1572 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1573                               0x64, 0x0000, 0x0000, (char *) buffer, sizeof(buffer), ptp_usb->timeout);
1574 	if (ret < sizeof(buffer))
1575 		return PTP_ERROR_IO;
1576 	return PTP_RC_OK;
1577 }
1578 
init_ptp_usb(PTPParams * params,PTP_USB * ptp_usb,struct usb_device * dev)1579 static int init_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, struct usb_device* dev)
1580 {
1581   usb_dev_handle *device_handle;
1582 
1583   params->sendreq_func=ptp_usb_sendreq;
1584   params->senddata_func=ptp_usb_senddata;
1585   params->getresp_func=ptp_usb_getresp;
1586   params->getdata_func=ptp_usb_getdata;
1587   params->cancelreq_func=ptp_usb_control_cancel_request;
1588   params->data=ptp_usb;
1589   params->transaction_id=0;
1590   /*
1591    * This is hardcoded here since we have no devices whatsoever that are BE.
1592    * Change this the day we run into our first BE device (if ever).
1593    */
1594   params->byteorder = PTP_DL_LE;
1595 
1596   ptp_usb->timeout = USB_TIMEOUT_DEFAULT;
1597 
1598   device_handle = usb_open(dev);
1599   if (!device_handle) {
1600     perror("usb_open()");
1601     return -1;
1602   }
1603 
1604   ptp_usb->handle = device_handle;
1605 #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
1606   /*
1607   * If this device is known to be wrongfully claimed by other kernel
1608   * drivers (such as mass storage), then try to unload it to make it
1609   * accessible from user space.
1610   */
1611   if (FLAG_UNLOAD_DRIVER(ptp_usb)) {
1612     if (usb_detach_kernel_driver_np(device_handle, (int) ptp_usb->interface)) {
1613 	  // Totally ignore this error!
1614 	  // perror("usb_detach_kernel_driver_np()");
1615     }
1616   }
1617 #endif
1618 #ifdef __WIN32__
1619   // Only needed on Windows, and cause problems on other platforms.
1620   if (usb_set_configuration(device_handle, dev->config->bConfigurationValue)) {
1621     perror("usb_set_configuration()");
1622     return -1;
1623   }
1624 #endif
1625   if (usb_claim_interface(device_handle, (int) ptp_usb->interface)) {
1626     perror("usb_claim_interface()");
1627     return -1;
1628   }
1629 
1630   return 0;
1631 }
1632 
clear_stall(PTP_USB * ptp_usb)1633 static void clear_stall(PTP_USB* ptp_usb)
1634 {
1635   uint16_t status;
1636   int ret;
1637 
1638   /* check the inep status */
1639   status = 0;
1640   ret = usb_get_endpoint_status(ptp_usb,ptp_usb->inep,&status);
1641   if (ret<0) {
1642     perror ("inep: usb_get_endpoint_status()");
1643   } else if (status) {
1644     printf("Clearing stall on IN endpoint\n");
1645     ret = usb_clear_stall_feature(ptp_usb,ptp_usb->inep);
1646     if (ret<0) {
1647       perror ("usb_clear_stall_feature()");
1648     }
1649   }
1650 
1651   /* check the outep status */
1652   status=0;
1653   ret = usb_get_endpoint_status(ptp_usb,ptp_usb->outep,&status);
1654   if (ret<0) {
1655     perror("outep: usb_get_endpoint_status()");
1656   } else if (status) {
1657     printf("Clearing stall on OUT endpoint\n");
1658     ret = usb_clear_stall_feature(ptp_usb,ptp_usb->outep);
1659     if (ret<0) {
1660       perror("usb_clear_stall_feature()");
1661     }
1662   }
1663 
1664   /* TODO: do we need this for INTERRUPT (ptp_usb->intep) too? */
1665 }
1666 
clear_halt(PTP_USB * ptp_usb)1667 static void clear_halt(PTP_USB* ptp_usb)
1668 {
1669   int ret;
1670 
1671   ret = usb_clear_halt(ptp_usb->handle,ptp_usb->inep);
1672   if (ret<0) {
1673     perror("usb_clear_halt() on IN endpoint");
1674   }
1675   ret = usb_clear_halt(ptp_usb->handle,ptp_usb->outep);
1676   if (ret<0) {
1677     perror("usb_clear_halt() on OUT endpoint");
1678   }
1679   ret = usb_clear_halt(ptp_usb->handle,ptp_usb->intep);
1680   if (ret<0) {
1681     perror("usb_clear_halt() on INTERRUPT endpoint");
1682   }
1683 }
1684 
close_usb(PTP_USB * ptp_usb)1685 static void close_usb(PTP_USB* ptp_usb)
1686 {
1687   // Commented out since it was confusing some
1688   // devices to do these things.
1689   if (!FLAG_NO_RELEASE_INTERFACE(ptp_usb)) {
1690 
1691     /*
1692      * Clear any stalled endpoints
1693      * On misbehaving devices designed for Windows/Mac, quote from:
1694      * http://www2.one-eyed-alien.net/~mdharm/linux-usb/target_offenses.txt
1695      * Device does Bad Things(tm) when it gets a GET_STATUS after CLEAR_HALT
1696      * (...) Windows, when clearing a stall, only sends the CLEAR_HALT command,
1697      * and presumes that the stall has cleared.  Some devices actually choke
1698      * if the CLEAR_HALT is followed by a GET_STATUS (used to determine if the
1699      * STALL is persistant or not).
1700      */
1701     clear_stall(ptp_usb);
1702     // Clear halts on any endpoints
1703     clear_halt(ptp_usb);
1704     // Added to clear some stuff on the OUT endpoint
1705     // TODO: is this good on the Mac too?
1706     // HINT: some devices may need that you comment these two out too.
1707     usb_resetep(ptp_usb->handle, ptp_usb->outep);
1708     usb_release_interface(ptp_usb->handle, (int) ptp_usb->interface);
1709   }
1710 
1711   usb_close(ptp_usb->handle);
1712 }
1713 
1714 /**
1715  * Self-explanatory?
1716  */
find_interface_and_endpoints(struct usb_device * dev,uint8_t * interface,int * inep,int * inep_maxpacket,int * outep,int * outep_maxpacket,int * intep)1717 static void find_interface_and_endpoints(struct usb_device *dev,
1718 					 uint8_t *interface,
1719 					 int* inep,
1720 					 int* inep_maxpacket,
1721 					 int* outep,
1722 					 int *outep_maxpacket,
1723 					 int* intep)
1724 {
1725   int i;
1726 
1727   // Loop over the device configurations
1728   for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
1729     uint8_t j;
1730 
1731     for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
1732       uint8_t k;
1733       uint8_t no_ep;
1734       struct usb_endpoint_descriptor *ep;
1735 
1736       if (dev->descriptor.bNumConfigurations > 1 || dev->config[i].bNumInterfaces > 1) {
1737 	// OK This device has more than one interface, so we have to find out
1738 	// which one to use!
1739 	// FIXME: Probe the interface.
1740 	// FIXME: Release modules attached to all other interfaces in Linux...?
1741       }
1742 
1743       *interface = dev->config[i].interface[j].altsetting->bInterfaceNumber;
1744       ep = dev->config[i].interface[j].altsetting->endpoint;
1745       no_ep = dev->config[i].interface[j].altsetting->bNumEndpoints;
1746 
1747       for (k = 0; k < no_ep; k++) {
1748 	if (ep[k].bmAttributes==USB_ENDPOINT_TYPE_BULK)	{
1749 	  if ((ep[k].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==
1750 	      USB_ENDPOINT_DIR_MASK)
1751 	    {
1752 	      *inep=ep[k].bEndpointAddress;
1753 	      *inep_maxpacket=ep[k].wMaxPacketSize;
1754 	    }
1755 	  if ((ep[k].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==0)
1756 	    {
1757 	      *outep=ep[k].bEndpointAddress;
1758 	      *outep_maxpacket=ep[k].wMaxPacketSize;
1759 	    }
1760 	} else if (ep[k].bmAttributes==USB_ENDPOINT_TYPE_INTERRUPT){
1761 	  if ((ep[k].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==
1762 	      USB_ENDPOINT_DIR_MASK)
1763 	    {
1764 	      *intep=ep[k].bEndpointAddress;
1765 	    }
1766 	}
1767       }
1768       // We assigned the endpoints so return here.
1769       return;
1770     }
1771   }
1772 }
1773 
1774 /**
1775  * This function assigns params and usbinfo given a raw device
1776  * as input.
1777  * @param device the device to be assigned.
1778  * @param usbinfo a pointer to the new usbinfo.
1779  * @return an error code.
1780  */
configure_usb_device(LIBMTP_raw_device_t * device,PTPParams * params,void ** usbinfo)1781 LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
1782 					   PTPParams *params,
1783 					   void **usbinfo)
1784 {
1785   PTP_USB *ptp_usb;
1786   struct usb_device *libusb_device;
1787   uint16_t ret = 0;
1788   struct usb_bus *bus;
1789   int found = 0;
1790 
1791   /* See if we can find this raw device again... */
1792   bus = init_usb();
1793   for (; bus != NULL; bus = bus->next) {
1794     if (bus->location == device->bus_location) {
1795       struct usb_device *dev = bus->devices;
1796 
1797       for (; dev != NULL; dev = dev->next) {
1798 	if(dev->devnum == device->devnum &&
1799 	   dev->descriptor.idVendor == device->device_entry.vendor_id &&
1800 	   dev->descriptor.idProduct == device->device_entry.product_id ) {
1801 	  libusb_device = dev;
1802 	  found = 1;
1803 	  break;
1804 	}
1805       }
1806       if (found)
1807 	break;
1808     }
1809   }
1810   /* Device has gone since detecting raw devices! */
1811   if (!found) {
1812     return LIBMTP_ERROR_NO_DEVICE_ATTACHED;
1813   }
1814 
1815   /* Allocate structs */
1816   ptp_usb = (PTP_USB *) malloc(sizeof(PTP_USB));
1817   if (ptp_usb == NULL) {
1818     return LIBMTP_ERROR_MEMORY_ALLOCATION;
1819   }
1820   /* Start with a blank slate (includes setting device_flags to 0) */
1821   memset(ptp_usb, 0, sizeof(PTP_USB));
1822 
1823   /* Copy the raw device */
1824   memcpy(&ptp_usb->rawdevice, device, sizeof(LIBMTP_raw_device_t));
1825 
1826   /*
1827    * Some devices must have their "OS Descriptor" massaged in order
1828    * to work.
1829    */
1830   if (FLAG_ALWAYS_PROBE_DESCRIPTOR(ptp_usb)) {
1831     // Massage the device descriptor
1832     (void) probe_device_descriptor(libusb_device, NULL);
1833   }
1834 
1835 
1836   /* Assign endpoints to usbinfo... */
1837   find_interface_and_endpoints(libusb_device,
1838 		   &ptp_usb->interface,
1839 		   &ptp_usb->inep,
1840 		   &ptp_usb->inep_maxpacket,
1841 		   &ptp_usb->outep,
1842 		   &ptp_usb->outep_maxpacket,
1843 		   &ptp_usb->intep);
1844 
1845   /* Attempt to initialize this device */
1846   if (init_ptp_usb(params, ptp_usb, libusb_device) < 0) {
1847     fprintf(stderr, "LIBMTP PANIC: Unable to initialize device\n");
1848     return LIBMTP_ERROR_CONNECTING;
1849   }
1850 
1851   /*
1852    * This works in situations where previous bad applications
1853    * have not used LIBMTP_Release_Device on exit
1854    */
1855   if ((ret = ptp_opensession(params, 1)) == PTP_ERROR_IO) {
1856     fprintf(stderr, "PTP_ERROR_IO: Trying again after re-initializing USB interface\n");
1857     close_usb(ptp_usb);
1858 
1859     if(init_ptp_usb(params, ptp_usb, libusb_device) <0) {
1860       fprintf(stderr, "LIBMTP PANIC: Could not open session on device\n");
1861       return LIBMTP_ERROR_CONNECTING;
1862     }
1863 
1864     /* Device has been reset, try again */
1865     ret = ptp_opensession(params, 1);
1866   }
1867 
1868   /* Was the transaction id invalid? Try again */
1869   if (ret == PTP_RC_InvalidTransactionID) {
1870     fprintf(stderr, "LIBMTP WARNING: Transaction ID was invalid, increment and try again\n");
1871     params->transaction_id += 10;
1872     ret = ptp_opensession(params, 1);
1873   }
1874 
1875   if (ret != PTP_RC_SessionAlreadyOpened && ret != PTP_RC_OK) {
1876     fprintf(stderr, "LIBMTP PANIC: Could not open session! "
1877 	    "(Return code %d)\n  Try to reset the device.\n",
1878 	    ret);
1879     usb_release_interface(ptp_usb->handle,
1880 			  (int) ptp_usb->interface);
1881     return LIBMTP_ERROR_CONNECTING;
1882   }
1883 
1884   /* OK configured properly */
1885   *usbinfo = (void *) ptp_usb;
1886   return LIBMTP_ERROR_NONE;
1887 }
1888 
1889 
close_device(PTP_USB * ptp_usb,PTPParams * params)1890 void close_device (PTP_USB *ptp_usb, PTPParams *params)
1891 {
1892   if (ptp_closesession(params)!=PTP_RC_OK)
1893     fprintf(stderr,"ERROR: Could not close session!\n");
1894   close_usb(ptp_usb);
1895 }
1896 
set_usb_device_timeout(PTP_USB * ptp_usb,int timeout)1897 void set_usb_device_timeout(PTP_USB *ptp_usb, int timeout)
1898 {
1899     ptp_usb->timeout = timeout;
1900 }
1901 
get_usb_device_timeout(PTP_USB * ptp_usb,int * timeout)1902 void get_usb_device_timeout(PTP_USB *ptp_usb, int *timeout)
1903 {
1904     *timeout = ptp_usb->timeout;
1905 }
1906 
usb_clear_stall_feature(PTP_USB * ptp_usb,int ep)1907 static int usb_clear_stall_feature(PTP_USB* ptp_usb, int ep)
1908 {
1909 
1910   return (usb_control_msg(ptp_usb->handle,
1911 			  USB_RECIP_ENDPOINT, USB_REQ_CLEAR_FEATURE, USB_FEATURE_HALT,
1912                           ep, NULL, 0, ptp_usb->timeout));
1913 }
1914 
usb_get_endpoint_status(PTP_USB * ptp_usb,int ep,uint16_t * status)1915 static int usb_get_endpoint_status(PTP_USB* ptp_usb, int ep, uint16_t* status)
1916 {
1917   return (usb_control_msg(ptp_usb->handle,
1918 			  USB_DP_DTH|USB_RECIP_ENDPOINT, USB_REQ_GET_STATUS,
1919                           USB_FEATURE_HALT, ep, (char *)status, 2, ptp_usb->timeout));
1920 }
1921