OLD | NEW |
1 /** | 1 /** |
2 * \file libmtp.c | 2 * \file libmtp.c |
3 * | 3 * |
4 * Copyright (C) 2005-2011 Linus Walleij <triad@df.lth.se> | 4 * Copyright (C) 2005-2011 Linus Walleij <triad@df.lth.se> |
5 * Copyright (C) 2005-2008 Richard A. Low <richard@wentnet.com> | 5 * Copyright (C) 2005-2008 Richard A. Low <richard@wentnet.com> |
6 * Copyright (C) 2007 Ted Bullock <tbullock@canada.com> | 6 * Copyright (C) 2007 Ted Bullock <tbullock@canada.com> |
7 * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com> | 7 * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com> |
8 * Copyright (C) 2008 Florent Mertens <flomertens@gmail.com> | 8 * Copyright (C) 2008 Florent Mertens <flomertens@gmail.com> |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "libmtp.h" | 38 #include "libmtp.h" |
39 #include "unicode.h" | 39 #include "unicode.h" |
40 #include "ptp.h" | 40 #include "ptp.h" |
41 #include "libusb-glue.h" | 41 #include "libusb-glue.h" |
42 #include "device-flags.h" | 42 #include "device-flags.h" |
43 #if 0 | 43 #if 0 |
44 #include "playlist-spl.h" | 44 #include "playlist-spl.h" |
45 #endif | 45 #endif |
46 #include "util.h" | 46 #include "util.h" |
47 | 47 |
| 48 #include "mtpz.h" |
| 49 |
48 #include <stdlib.h> | 50 #include <stdlib.h> |
49 #include <limits.h> | 51 #include <limits.h> |
50 #include <unistd.h> | 52 #include <unistd.h> |
51 #include <string.h> | 53 #include <string.h> |
52 #include <sys/types.h> | 54 #include <sys/types.h> |
53 #include <sys/stat.h> | 55 #include <sys/stat.h> |
54 #include <fcntl.h> | 56 #include <fcntl.h> |
55 #include <time.h> | 57 #include <time.h> |
56 #include <errno.h> | 58 #include <errno.h> |
57 #ifdef _MSC_VER // For MSVC++ | 59 #ifdef _MSC_VER // For MSVC++ |
58 #define USE_WINDOWS_IO_H | 60 #define USE_WINDOWS_IO_H |
59 #include <io.h> | 61 #include <io.h> |
60 #endif | 62 #endif |
61 | 63 |
62 | 64 |
63 /** | 65 /** |
64 * Global debug level | 66 * Global debug level |
65 * We use a flag system to enable a part of logs. | 67 * We use a flag system to enable a part of logs. |
66 * | 68 * |
67 * The LIBMTP_DEBUG environment variable sets the debug flags for any binary | 69 * The LIBMTP_DEBUG environment variable sets the debug flags for any binary |
68 * that uses libmtp and calls LIBMTP_Init. The value can be given in decimal | 70 * that uses libmtp and calls LIBMTP_Init. The value can be given in decimal |
69 * (must not start with "0" or it will be interpreted in octal), or in | 71 * (must not start with "0" or it will be interpreted in octal), or in |
70 * hexadecimal (must start with "0x"). | 72 * hexadecimal (must start with "0x"). |
71 * | 73 * |
72 * The value "-1" enables all debug flags. | 74 * The value "-1" enables all debug flags. |
73 * | 75 * |
74 * Some of the utilities in examples/ also take a command-line flag "-d" that | 76 * Some of the utilities in examples/ also take a command-line flag "-d" that |
75 * enables all debug flags, as if you had set LIBMTP_DEBUG=-1. | 77 * enables LIBMTP_DEBUG_PTP and LIBMTP_DEBUG_DATA (same as setting |
| 78 * LIBMTP_DEBUG=9). |
76 * | 79 * |
77 * Flags (combine by adding the hex values): | 80 * Flags (combine by adding the hex values): |
78 * 0x00 [0000 0000] : no debug (default) | 81 * 0x00 [0000 0000] : LIBMTP_DEBUG_NONE : no debug (default) |
79 * 0x01 [0000 0001] : PTP debug | 82 * 0x01 [0000 0001] : LIBMTP_DEBUG_PTP : PTP debug |
80 * 0x02 [0000 0010] : Playlist debug | 83 * 0x02 [0000 0010] : LIBMTP_DEBUG_PLST : Playlist debug |
81 * 0x04 [0000 0100] : USB debug | 84 * 0x04 [0000 0100] : LIBMTP_DEBUG_USB : USB debug |
82 * 0x08 [0000 1000] : USB data debug | 85 * 0x08 [0000 1000] : LIBMTP_DEBUG_DATA : USB data debug |
| 86 * |
| 87 * (Please keep this list in sync with libmtp.h.) |
83 */ | 88 */ |
84 int LIBMTP_debug = LIBMTP_DEBUG_NONE; | 89 int LIBMTP_debug = LIBMTP_DEBUG_NONE; |
85 | 90 |
86 | 91 |
87 /* | 92 /* |
88 * This is a mapping between libmtp internal MTP filetypes and | 93 * This is a mapping between libmtp internal MTP filetypes and |
89 * the libgphoto2/PTP equivalent defines. We need this because | 94 * the libgphoto2/PTP equivalent defines. We need this because |
90 * otherwise the libmtp.h device has to be dependent on ptp.h | 95 * otherwise the libmtp.h device has to be dependent on ptp.h |
91 * to be installed too, and we don't want that. | 96 * to be installed too, and we don't want that. |
92 */ | 97 */ |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 LIBMTP_debug = level; | 750 LIBMTP_debug = level; |
746 } | 751 } |
747 | 752 |
748 | 753 |
749 /** | 754 /** |
750 * Initialize the library. You are only supposed to call this | 755 * Initialize the library. You are only supposed to call this |
751 * one, before using the library for the first time in a program. | 756 * one, before using the library for the first time in a program. |
752 * Never re-initialize libmtp! | 757 * Never re-initialize libmtp! |
753 * | 758 * |
754 * The only thing this does at the moment is to initialise the | 759 * The only thing this does at the moment is to initialise the |
755 * filetype mapping table. | 760 * filetype mapping table, as well as load MTPZ data if necessary. |
756 */ | 761 */ |
757 void LIBMTP_Init(void) | 762 void LIBMTP_Init(void) |
758 { | 763 { |
759 const char *env_debug = getenv("LIBMTP_DEBUG"); | 764 const char *env_debug = getenv("LIBMTP_DEBUG"); |
760 if (env_debug) { | 765 if (env_debug) { |
761 const long debug_flags = strtol(env_debug, NULL, 0); | 766 const long debug_flags = strtol(env_debug, NULL, 0); |
762 if (debug_flags != LONG_MIN && debug_flags != LONG_MAX && | 767 if (debug_flags != LONG_MIN && debug_flags != LONG_MAX && |
763 INT_MIN <= debug_flags && debug_flags <= INT_MAX) { | 768 INT_MIN <= debug_flags && debug_flags <= INT_MAX) { |
764 LIBMTP_Set_Debug(debug_flags); | 769 LIBMTP_Set_Debug(debug_flags); |
765 } else { | 770 } else { |
766 fprintf(stderr, "LIBMTP_Init: error setting debug flags from environment " | 771 fprintf(stderr, "LIBMTP_Init: error setting debug flags from environment " |
767 "value \"%s\"\n", env_debug); | 772 "value \"%s\"\n", env_debug); |
768 } | 773 } |
769 } | 774 } |
770 | 775 |
771 init_filemap(); | 776 init_filemap(); |
772 init_propertymap(); | 777 init_propertymap(); |
| 778 |
| 779 if (mtpz_loaddata() == -1) |
| 780 use_mtpz = 0; |
| 781 else |
| 782 use_mtpz = 1; |
| 783 |
773 return; | 784 return; |
774 } | 785 } |
775 | 786 |
776 | 787 |
777 /** | 788 /** |
778 * This helper function returns a textual description for a libmtp | 789 * This helper function returns a textual description for a libmtp |
779 * file type to be used in dialog boxes etc. | 790 * file type to be used in dialog boxes etc. |
780 * @param intype the libmtp internal filetype to get a description for. | 791 * @param intype the libmtp internal filetype to get a description for. |
781 * @return a string representing the filetype, this must <b>NOT</b> | 792 * @return a string representing the filetype, this must <b>NOT</b> |
782 * be free():ed by the caller! | 793 * be free():ed by the caller! |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 return mtp_device; | 2091 return mtp_device; |
2081 } | 2092 } |
2082 | 2093 |
2083 LIBMTP_mtpdevice_t *LIBMTP_Open_Raw_Device(LIBMTP_raw_device_t *rawdevice) | 2094 LIBMTP_mtpdevice_t *LIBMTP_Open_Raw_Device(LIBMTP_raw_device_t *rawdevice) |
2084 { | 2095 { |
2085 LIBMTP_mtpdevice_t *mtp_device = LIBMTP_Open_Raw_Device_Uncached(rawdevice); | 2096 LIBMTP_mtpdevice_t *mtp_device = LIBMTP_Open_Raw_Device_Uncached(rawdevice); |
2086 | 2097 |
2087 if (mtp_device == NULL) | 2098 if (mtp_device == NULL) |
2088 return NULL; | 2099 return NULL; |
2089 | 2100 |
| 2101 /* Check for MTPZ devices. */ |
| 2102 if (use_mtpz) { |
| 2103 LIBMTP_device_extension_t *tmpext = mtp_device->extensions; |
| 2104 |
| 2105 while (tmpext != NULL) { |
| 2106 if (!strcmp(tmpext->name, "microsoft.com/MTPZ")) { |
| 2107 LIBMTP_INFO("MTPZ device detected. Authenticating...\n"); |
| 2108 if (PTP_RC_OK == ptp_mtpz_handshake(mtp_device->params)) { |
| 2109 LIBMTP_INFO ("(MTPZ) Successfully authenticated with device.\n"); |
| 2110 } else { |
| 2111 LIBMTP_INFO ("(MTPZ) Failure - could not authenticate with device.\n")
; |
| 2112 } |
| 2113 break; |
| 2114 } |
| 2115 tmpext = tmpext->next; |
| 2116 } |
| 2117 } |
| 2118 |
2090 // Set up this device as cached | 2119 // Set up this device as cached |
2091 mtp_device->cached = 1; | 2120 mtp_device->cached = 1; |
2092 /* | 2121 /* |
2093 * Then get the handles and try to locate the default folders. | 2122 * Then get the handles and try to locate the default folders. |
2094 * This has the desired side effect of caching all handles from | 2123 * This has the desired side effect of caching all handles from |
2095 * the device which speeds up later operations. | 2124 * the device which speeds up later operations. |
2096 */ | 2125 */ |
2097 flush_handles(mtp_device); | 2126 flush_handles(mtp_device); |
2098 return mtp_device; | 2127 return mtp_device; |
2099 } | 2128 } |
2100 | 2129 |
2101 /** | 2130 /** |
2102 * To read events sent by the device, repeatedly call this function from a secon
dary | 2131 * To read events sent by the device, repeatedly call this function from a secon
dary |
2103 * thread until the return value is < 0. | 2132 * thread until the return value is < 0. |
2104 * | 2133 * |
2105 * @param device a pointer to the MTP device to poll for events. | 2134 * @param device a pointer to the MTP device to poll for events. |
2106 * @param event contains a pointer to be filled in with the event retrieved if t
he call | 2135 * @param event contains a pointer to be filled in with the event retrieved if t
he call |
2107 * is successful. | 2136 * is successful. |
| 2137 * @param out1 contains the param1 value from the raw event. |
2108 * @return 0 on success, any other value means the polling loop shall be | 2138 * @return 0 on success, any other value means the polling loop shall be |
2109 * terminated immediately for this session. | 2139 * terminated immediately for this session. |
2110 */ | 2140 */ |
2111 int LIBMTP_Read_Event(LIBMTP_mtpdevice_t *device, LIBMTP_event_t *event) | 2141 int LIBMTP_Read_Event(LIBMTP_mtpdevice_t *device, LIBMTP_event_t *event, uint32_
t *out1) |
2112 { | 2142 { |
2113 /* | 2143 /* |
2114 * FIXME: Potential race-condition here, if client deallocs device | 2144 * FIXME: Potential race-condition here, if client deallocs device |
2115 * while we're *not* waiting for input. As we'll be waiting for | 2145 * while we're *not* waiting for input. As we'll be waiting for |
2116 * input most of the time, it's unlikely but still worth considering | 2146 * input most of the time, it's unlikely but still worth considering |
2117 * for improvement. Also we cannot affect the state of the cache etc | 2147 * for improvement. Also we cannot affect the state of the cache etc |
2118 * unless we know we are the sole user on the device. A spinlock or | 2148 * unless we know we are the sole user on the device. A spinlock or |
2119 * mutex in the LIBMTP_mtpdevice_t is needed for this to work. | 2149 * mutex in the LIBMTP_mtpdevice_t is needed for this to work. |
2120 */ | 2150 */ |
2121 PTPParams *params = (PTPParams *) device->params; | 2151 PTPParams *params = (PTPParams *) device->params; |
(...skipping 30 matching lines...) Expand all Loading... |
2152 break; | 2182 break; |
2153 case PTP_EC_ObjectAdded: | 2183 case PTP_EC_ObjectAdded: |
2154 LIBMTP_INFO("Received event PTP_EC_ObjectAdded in session %u\n", session_i
d); | 2184 LIBMTP_INFO("Received event PTP_EC_ObjectAdded in session %u\n", session_i
d); |
2155 break; | 2185 break; |
2156 case PTP_EC_ObjectRemoved: | 2186 case PTP_EC_ObjectRemoved: |
2157 LIBMTP_INFO("Received event PTP_EC_ObjectRemoved in session %u\n", session
_id); | 2187 LIBMTP_INFO("Received event PTP_EC_ObjectRemoved in session %u\n", session
_id); |
2158 break; | 2188 break; |
2159 case PTP_EC_StoreAdded: | 2189 case PTP_EC_StoreAdded: |
2160 LIBMTP_INFO("Received event PTP_EC_StoreAdded in session %u\n", session_id
); | 2190 LIBMTP_INFO("Received event PTP_EC_StoreAdded in session %u\n", session_id
); |
2161 /* TODO: rescan storages */ | 2191 /* TODO: rescan storages */ |
| 2192 *event = LIBMTP_EVENT_STORE_ADDED; |
| 2193 *out1 = param1; |
2162 break; | 2194 break; |
2163 case PTP_EC_StoreRemoved: | 2195 case PTP_EC_StoreRemoved: |
2164 LIBMTP_INFO("Received event PTP_EC_StoreRemoved in session %u\n", session_
id); | 2196 LIBMTP_INFO("Received event PTP_EC_StoreRemoved in session %u\n", session_
id); |
2165 /* TODO: rescan storages */ | 2197 /* TODO: rescan storages */ |
2166 break; | 2198 break; |
2167 case PTP_EC_DevicePropChanged: | 2199 case PTP_EC_DevicePropChanged: |
2168 LIBMTP_INFO("Received event PTP_EC_DevicePropChanged in session %u\n", ses
sion_id); | 2200 LIBMTP_INFO("Received event PTP_EC_DevicePropChanged in session %u\n", ses
sion_id); |
2169 /* TODO: update device properties */ | 2201 /* TODO: update device properties */ |
2170 break; | 2202 break; |
2171 case PTP_EC_ObjectInfoChanged: | 2203 case PTP_EC_ObjectInfoChanged: |
(...skipping 6608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8780 sampledata->width = get_u32_from_object(device, id, PTP_OPC_RepresentativeSamp
leWidth, 0); | 8812 sampledata->width = get_u32_from_object(device, id, PTP_OPC_RepresentativeSamp
leWidth, 0); |
8781 sampledata->height = get_u32_from_object(device, id, PTP_OPC_RepresentativeSam
pleHeight, 0); | 8813 sampledata->height = get_u32_from_object(device, id, PTP_OPC_RepresentativeSam
pleHeight, 0); |
8782 sampledata->duration = get_u32_from_object(device, id, PTP_OPC_RepresentativeS
ampleDuration, 0); | 8814 sampledata->duration = get_u32_from_object(device, id, PTP_OPC_RepresentativeS
ampleDuration, 0); |
8783 sampledata->filetype = map_ptp_type_to_libmtp_type( | 8815 sampledata->filetype = map_ptp_type_to_libmtp_type( |
8784 get_u16_from_object(device, id, PTP_OPC_RepresentativeSampleFormat, LIBM
TP_FILETYPE_UNKNOWN)); | 8816 get_u16_from_object(device, id, PTP_OPC_RepresentativeSampleFormat, LIBM
TP_FILETYPE_UNKNOWN)); |
8785 | 8817 |
8786 return 0; | 8818 return 0; |
8787 } | 8819 } |
8788 | 8820 |
8789 /** | 8821 /** |
| 8822 * Retrieve the thumbnail for a file. |
| 8823 * @param device a pointer to the device to get the thumbnail from. |
| 8824 * @param id the object ID of the file to retrieve the thumbnail for. |
| 8825 * @return 0 on success, any other value means failure. |
| 8826 */ |
| 8827 int LIBMTP_Get_Thumbnail(LIBMTP_mtpdevice_t *device, uint32_t const id, |
| 8828 unsigned char **data, unsigned int *size) |
| 8829 { |
| 8830 PTPParams *params = (PTPParams *) device->params; |
| 8831 uint16_t ret; |
| 8832 |
| 8833 ret = ptp_getthumb(params, id, data, size); |
| 8834 if (ret == PTP_RC_OK) |
| 8835 return 0; |
| 8836 return -1; |
| 8837 } |
| 8838 |
| 8839 /** |
8790 * This routine updates an album based on the metadata | 8840 * This routine updates an album based on the metadata |
8791 * supplied. If the <code>tracks</code> field of the metadata | 8841 * supplied. If the <code>tracks</code> field of the metadata |
8792 * contains a track listing, these tracks will be added to the | 8842 * contains a track listing, these tracks will be added to the |
8793 * album in place of those already present, i.e. the | 8843 * album in place of those already present, i.e. the |
8794 * previous track listing will be deleted. | 8844 * previous track listing will be deleted. |
8795 * @param device a pointer to the device to create the new album on. | 8845 * @param device a pointer to the device to create the new album on. |
8796 * @param metadata the metadata for the album to be updated. | 8846 * @param metadata the metadata for the album to be updated. |
8797 * notice that the field <code>album_id</code> | 8847 * notice that the field <code>album_id</code> |
8798 * must contain the apropriate album ID. | 8848 * must contain the apropriate album ID. |
8799 * @return 0 on success, any other value means failure. | 8849 * @return 0 on success, any other value means failure. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8844 * @param device the device which may have a cache to which the object should be
updated. | 8894 * @param device the device which may have a cache to which the object should be
updated. |
8845 * @param object_id the object to update. | 8895 * @param object_id the object to update. |
8846 */ | 8896 */ |
8847 static void update_metadata_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id
) | 8897 static void update_metadata_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id
) |
8848 { | 8898 { |
8849 PTPParams *params = (PTPParams *)device->params; | 8899 PTPParams *params = (PTPParams *)device->params; |
8850 | 8900 |
8851 ptp_remove_object_from_cache(params, object_id); | 8901 ptp_remove_object_from_cache(params, object_id); |
8852 add_object_to_cache(device, object_id); | 8902 add_object_to_cache(device, object_id); |
8853 } | 8903 } |
OLD | NEW |