13aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 23aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * \file libmtp.c 33aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 43aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2005-2009 Linus Walleij <triad@df.lth.se> 53aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2005-2008 Richard A. Low <richard@wentnet.com> 63aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2007 Ted Bullock <tbullock@canada.com> 73aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com> 83aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2008 Florent Mertens <flomertens@gmail.com> 93aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This library is free software; you can redistribute it and/or 113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * modify it under the terms of the GNU Lesser General Public 123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * License as published by the Free Software Foundation; either 133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * version 2 of the License, or (at your option) any later version. 143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This library is distributed in the hope that it will be useful, 163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * but WITHOUT ANY WARRANTY; without even the implied warranty of 173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Lesser General Public License for more details. 193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * You should have received a copy of the GNU Lesser General Public 213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * License along with this library; if not, write to the 223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Boston, MA 02111-1307, USA. 243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This file provides an interface "glue" to the underlying 263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * PTP implementation from libgphoto2. It uses some local 273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * code to convert from/to UTF-8 (stored in unicode.c/.h) 283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and some small utility functions, mainly for debugging 293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (stored in util.c/.h). 303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The three PTP files (ptp.c, ptp.h and ptp-pack.c) are 323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * plain copied from the libhphoto2 codebase. 333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The files libusb-glue.c/.h are just what they say: an 353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * interface to libusb for the actual, physical USB traffic. 363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "config.h" 383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "libmtp.h" 393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "unicode.h" 403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "ptp.h" 413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "libusb-glue.h" 423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "device-flags.h" 433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "playlist-spl.h" 443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <stdlib.h> 463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <unistd.h> 473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <string.h> 483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <sys/types.h> 493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <sys/stat.h> 503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <fcntl.h> 513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <time.h> 523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <errno.h> 533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef _MSC_VER // For MSVC++ 543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define USE_WINDOWS_IO_H 553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <io.h> 563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* To enable PTP level debug prints (all ptp_debug(...)), switch on this */ 593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev//#define ENABLE_PTP_DEBUG 603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This is a mapping between libmtp internal MTP filetypes and 633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the libgphoto2/PTP equivalent defines. We need this because 643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * otherwise the libmtp.h device has to be dependent on ptp.h 653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to be installed too, and we don't want that. 663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev//typedef struct filemap_struct filemap_t; 683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevtypedef struct filemap_struct { 693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *description; /**< Text description for the file type */ 703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filetype_t id; /**< LIBMTP internal type for the file type */ 713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ptp_id; /**< PTP ID for the filetype */ 723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev struct filemap_struct *next; 733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} filemap_t; 743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This is a mapping between libmtp internal MTP properties and 773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the libgphoto2/PTP equivalent defines. We need this because 783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * otherwise the libmtp.h device has to be dependent on ptp.h 793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to be installed too, and we don't want that. 803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevtypedef struct propertymap_struct { 823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *description; /**< Text description for the property */ 833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t id; /**< LIBMTP internal type for the property */ 843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ptp_id; /**< PTP ID for the property */ 853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev struct propertymap_struct *next; 863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} propertymap_t; 873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev// Global variables 893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev// This holds the global filetype mapping table 903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic filemap_t *filemap = NULL; 913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev// This holds the global property mapping table 923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic propertymap_t *propertymap = NULL; 933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int load_cache_on_demand = 0; 953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Forward declarations of local (static) functions. 973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int register_filetype(char const * const description, LIBMTP_filetype_t const id, 993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const ptp_id); 1003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void init_filemap(); 1013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int register_property(char const * const description, LIBMTP_property_t const id, 1023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const ptp_id); 1033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void init_propertymap(); 1043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void add_error_to_errorstack(LIBMTP_mtpdevice_t *device, 1053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_number_t errornumber, 1063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const error_text); 1073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void add_ptp_error_to_errorstack(LIBMTP_mtpdevice_t *device, 1083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ptp_error, 1093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const error_text); 1103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void flush_handles(LIBMTP_mtpdevice_t *device); 1113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void get_handles_recursively(LIBMTP_mtpdevice_t *device, 1123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params, 1133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t storageid, 1143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t parent); 1153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void free_storage_list(LIBMTP_mtpdevice_t *device); 1163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int sort_storage_by(LIBMTP_mtpdevice_t *device, int const sortby); 1173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint32_t get_writeable_storageid(LIBMTP_mtpdevice_t *device, uint64_t fitsize); 1183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int get_storage_freespace(LIBMTP_mtpdevice_t *device, 1193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage, 1203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint64_t *freespace); 1213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int check_if_file_fits(LIBMTP_mtpdevice_t *device, 1223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage, 1233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint64_t const filesize); 1243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t map_libmtp_type_to_ptp_type(LIBMTP_filetype_t intype); 1253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_filetype_t map_ptp_type_to_libmtp_type(uint16_t intype); 1263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t map_libmtp_property_to_ptp_property(LIBMTP_property_t inproperty); 1273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_property_t map_ptp_property_to_libmtp_property(uint16_t intype); 1283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int get_device_unicode_property(LIBMTP_mtpdevice_t *device, 1293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char **unicstring, uint16_t property); 1303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t adjust_u16(uint16_t val, PTPObjectPropDesc *opd); 1313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint32_t adjust_u32(uint32_t val, PTPObjectPropDesc *opd); 1323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic char *get_iso8601_stamp(void); 1333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic char *get_string_from_object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id); 1353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint64_t get_u64_from_object(LIBMTP_mtpdevice_t *device,uint32_t const object_id, 1363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint64_t const value_default); 1373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint32_t get_u32_from_object(LIBMTP_mtpdevice_t *device,uint32_t const object_id, 1383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint32_t const value_default); 1393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t get_u16_from_object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint16_t const value_default); 1413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint8_t get_u8_from_object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint8_t const value_default); 1433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_string(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, char const * const string); 1453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_u32(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint32_t const value); 1473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_u16(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint16_t const value); 1493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_u8(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 1503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint8_t const value); 1513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void get_track_metadata(LIBMTP_mtpdevice_t *device, uint16_t objectformat, 1523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *track); 1533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_folder_t *get_subfolders_for_folder(LIBMTP_folder_t *list, uint32_t parent); 1543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int create_new_abstract_list(LIBMTP_mtpdevice_t *device, 1553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const name, 1563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const artist, 1573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const composer, 1583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const genre, 1593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const parenthandle, 1603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const storageid, 1613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const objectformat, 1623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const suffix, 1633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t * const newid, 1643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const * const tracks, 1653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const no_tracks); 1663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int update_abstract_list(LIBMTP_mtpdevice_t *device, 1673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const name, 1683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const artist, 1693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const composer, 1703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const genre, 1713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const objecthandle, 1723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const objectformat, 1733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const * const tracks, 1743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const no_tracks); 1753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int send_file_object_info(LIBMTP_mtpdevice_t *device, LIBMTP_file_t *filedata); 1763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void add_object_to_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id); 1773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void update_metadata_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id); 1783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_filename(LIBMTP_mtpdevice_t *device, 1793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t object_id, 1803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ptp_type, 1813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const char **newname); 1823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 1843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * These are to wrap the get/put handlers to convert from the MTP types to PTP types 1853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in a reliable way 1863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 1873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevtypedef struct _MTPDataHandler { 1883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataGetFunc getfunc; 1893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataPutFunc putfunc; 1903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void *priv; 1913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} MTPDataHandler; 1923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t get_func_wrapper(PTPParams* params, void* priv, unsigned long wantlen, unsigned char *data, unsigned long *gotlen); 1943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t put_func_wrapper(PTPParams* params, void* priv, unsigned long sendlen, unsigned char *data, unsigned long *putlen); 1953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 1973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Checks if a filename ends with ".ogg". Used in various 1983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * situations when the device has no idea that it support 1993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * OGG but still does. 2003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 2013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param name string to be checked. 2023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if this does not end with ogg, any other 2033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * value means it does. 2043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 2053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int has_ogg_extension(char *name) { 2063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *ptype; 2073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (name == NULL) 2093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 2103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptype = strrchr(name,'.'); 2113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptype == NULL) 2123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 2133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!strcasecmp (ptype, ".ogg")) 2143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 2153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 2163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 2193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Checks if a filename ends with ".flac". Used in various 2203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * situations when the device has no idea that it support 2213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * FLAC but still does. 2223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 2233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param name string to be checked. 2243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if this does not end with flac, any other 2253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * value means it does. 2263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 2273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int has_flac_extension(char *name) { 2283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *ptype; 2293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (name == NULL) 2313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 2323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptype = strrchr(name,'.'); 2333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptype == NULL) 2343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 2353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!strcasecmp (ptype, ".flac")) 2363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 2373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 2383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 2433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Create a new file mapping entry 2443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated filemapping entry. 2453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 2463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic filemap_t *new_filemap_entry() 2473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap_t *filemap; 2493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap = (filemap_t *)malloc(sizeof(filemap_t)); 2513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if( filemap != NULL ) { 2533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap->description = NULL; 2543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap->id = LIBMTP_FILETYPE_UNKNOWN; 2553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap->ptp_id = PTP_OFC_Undefined; 2563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap->next = NULL; 2573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return filemap; 2603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 2633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Register an MTP or PTP filetype for data retrieval 2643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 2653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param description Text description of filetype 2663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id libmtp internal filetype id 2673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param ptp_id PTP filetype id 2683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 for success any other value means error. 2693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 2703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int register_filetype(char const * const description, LIBMTP_filetype_t const id, 2713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const ptp_id) 2723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap_t *new = NULL, *current; 2743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Has this LIBMTP filetype been registered before ? 2763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = filemap; 2773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 2783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->id == id) { 2793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 2803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 2823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Create the entry 2853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current == NULL) { 2863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new = new_filemap_entry(); 2873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(new == NULL) { 2883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 2893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->id = id; 2923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(description != NULL) { 2933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->description = strdup(description); 2943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->ptp_id = ptp_id; 2963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add the entry to the list 2983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(filemap == NULL) { 2993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap = new; 3003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 3013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = filemap; 3023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current->next != NULL ) current=current->next; 3033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->next = new; 3043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update the existing entry 3063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 3073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (current->description != NULL) { 3083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(current->description); 3093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->description = NULL; 3113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(description != NULL) { 3123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->description = strdup(description); 3133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->ptp_id = ptp_id; 3153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 3183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void init_filemap() 3213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 3223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Folder", LIBMTP_FILETYPE_FOLDER, PTP_OFC_Association); 3233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("MediaCard", LIBMTP_FILETYPE_MEDIACARD, PTP_OFC_MTP_MediaCard); 3243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("RIFF WAVE file", LIBMTP_FILETYPE_WAV, PTP_OFC_WAV); 3253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("ISO MPEG-1 Audio Layer 3", LIBMTP_FILETYPE_MP3, PTP_OFC_MP3); 3263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("ISO MPEG-1 Audio Layer 2", LIBMTP_FILETYPE_MP2, PTP_OFC_MTP_MP2); 3273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Microsoft Windows Media Audio", LIBMTP_FILETYPE_WMA, PTP_OFC_MTP_WMA); 3283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Ogg container format", LIBMTP_FILETYPE_OGG, PTP_OFC_MTP_OGG); 3293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Free Lossless Audio Codec (FLAC)", LIBMTP_FILETYPE_FLAC, PTP_OFC_MTP_FLAC); 3303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Advanced Audio Coding (AAC)/MPEG-2 Part 7/MPEG-4 Part 3", LIBMTP_FILETYPE_AAC, PTP_OFC_MTP_AAC); 3313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("MPEG-4 Part 14 Container Format (Audio Emphasis)", LIBMTP_FILETYPE_M4A, PTP_OFC_MTP_M4A); 3323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("MPEG-4 Part 14 Container Format (Audio+Video Emphasis)", LIBMTP_FILETYPE_MP4, PTP_OFC_MTP_MP4); 3333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Audible.com Audio Codec", LIBMTP_FILETYPE_AUDIBLE, PTP_OFC_MTP_AudibleCodec); 3343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Undefined audio file", LIBMTP_FILETYPE_UNDEF_AUDIO, PTP_OFC_MTP_UndefinedAudio); 3353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Microsoft Windows Media Video", LIBMTP_FILETYPE_WMV, PTP_OFC_MTP_WMV); 3363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Audio Video Interleave", LIBMTP_FILETYPE_AVI, PTP_OFC_AVI); 3373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("MPEG video stream", LIBMTP_FILETYPE_MPEG, PTP_OFC_MPEG); 3383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Microsoft Advanced Systems Format", LIBMTP_FILETYPE_ASF, PTP_OFC_ASF); 3393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Apple Quicktime container format", LIBMTP_FILETYPE_QT, PTP_OFC_QT); 3403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Undefined video file", LIBMTP_FILETYPE_UNDEF_VIDEO, PTP_OFC_MTP_UndefinedVideo); 3413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("JPEG file", LIBMTP_FILETYPE_JPEG, PTP_OFC_EXIF_JPEG); 3423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("JP2 file", LIBMTP_FILETYPE_JP2, PTP_OFC_JP2); 3433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("JPX file", LIBMTP_FILETYPE_JPX, PTP_OFC_JPX); 3443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("JFIF file", LIBMTP_FILETYPE_JFIF, PTP_OFC_JFIF); 3453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("TIFF bitmap file", LIBMTP_FILETYPE_TIFF, PTP_OFC_TIFF); 3463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("BMP bitmap file", LIBMTP_FILETYPE_BMP, PTP_OFC_BMP); 3473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("GIF bitmap file", LIBMTP_FILETYPE_GIF, PTP_OFC_GIF); 3483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("PICT bitmap file", LIBMTP_FILETYPE_PICT, PTP_OFC_PICT); 3493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Portable Network Graphics", LIBMTP_FILETYPE_PNG, PTP_OFC_PNG); 3503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Microsoft Windows Image Format", LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT, PTP_OFC_MTP_WindowsImageFormat); 3513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("VCalendar version 1", LIBMTP_FILETYPE_VCALENDAR1, PTP_OFC_MTP_vCalendar1); 3523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("VCalendar version 2", LIBMTP_FILETYPE_VCALENDAR2, PTP_OFC_MTP_vCalendar2); 3533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("VCard version 2", LIBMTP_FILETYPE_VCARD2, PTP_OFC_MTP_vCard2); 3543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("VCard version 3", LIBMTP_FILETYPE_VCARD3, PTP_OFC_MTP_vCard3); 3553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Undefined Windows executable file", LIBMTP_FILETYPE_WINEXEC, PTP_OFC_MTP_UndefinedWindowsExecutable); 3563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Text file", LIBMTP_FILETYPE_TEXT, PTP_OFC_Text); 3573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("HTML file", LIBMTP_FILETYPE_HTML, PTP_OFC_HTML); 3583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("XML file", LIBMTP_FILETYPE_XML, PTP_OFC_MTP_XMLDocument); 3593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("DOC file", LIBMTP_FILETYPE_DOC, PTP_OFC_MTP_MSWordDocument); 3603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("XLS file", LIBMTP_FILETYPE_XLS, PTP_OFC_MTP_MSExcelSpreadsheetXLS); 3613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("PPT file", LIBMTP_FILETYPE_PPT, PTP_OFC_MTP_MSPowerpointPresentationPPT); 3623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("MHT file", LIBMTP_FILETYPE_MHT, PTP_OFC_MTP_MHTCompiledHTMLDocument); 3633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Firmware file", LIBMTP_FILETYPE_FIRMWARE, PTP_OFC_MTP_Firmware); 3643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Abstract Album file", LIBMTP_FILETYPE_ALBUM, PTP_OFC_MTP_AbstractAudioAlbum); 3653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Abstract Playlist file", LIBMTP_FILETYPE_PLAYLIST, PTP_OFC_MTP_AbstractAudioVideoPlaylist); 3663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_filetype("Undefined filetype", LIBMTP_FILETYPE_UNKNOWN, PTP_OFC_Undefined); 3673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 3703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Returns the PTP filetype that maps to a certain libmtp internal file type. 3713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param intype the MTP library interface type 3723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the PTP (libgphoto2) interface type 3733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 3743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t map_libmtp_type_to_ptp_type(LIBMTP_filetype_t intype) 3753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 3763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap_t *current; 3773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = filemap; 3793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 3813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->id == intype) { 3823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return current->ptp_id; 3833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 3853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // printf("map_libmtp_type_to_ptp_type: unknown filetype.\n"); 3873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_OFC_Undefined; 3883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 3923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Returns the MTP internal interface type that maps to a certain ptp 3933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * interface type. 3943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param intype the PTP (libgphoto2) interface type 3953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the MTP library interface type 3963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 3973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_filetype_t map_ptp_type_to_libmtp_type(uint16_t intype) 3983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 3993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap_t *current; 4003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = filemap; 4023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 4043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->ptp_id == intype) { 4053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return current->id; 4063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 4083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // printf("map_ptp_type_to_libmtp_type: unknown filetype.\n"); 4103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_FILETYPE_UNKNOWN; 4113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 4123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 4143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Create a new property mapping entry 4153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated propertymapping entry. 4163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 4173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic propertymap_t *new_propertymap_entry() 4183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 4193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap_t *propertymap; 4203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap = (propertymap_t *)malloc(sizeof(propertymap_t)); 4223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if( propertymap != NULL ) { 4243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap->description = NULL; 4253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap->id = LIBMTP_PROPERTY_UNKNOWN; 4263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap->ptp_id = 0; 4273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap->next = NULL; 4283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return propertymap; 4313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 4323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 4343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Register an MTP or PTP property for data retrieval 4353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 4363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param description Text description of property 4373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id libmtp internal property id 4383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param ptp_id PTP property id 4393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 for success any other value means error. 4403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 4413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int register_property(char const * const description, LIBMTP_property_t const id, 4423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const ptp_id) 4433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 4443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap_t *new = NULL, *current; 4453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Has this LIBMTP propety been registered before ? 4473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = propertymap; 4483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 4493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->id == id) { 4503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 4513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 4533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Create the entry 4563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current == NULL) { 4573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new = new_propertymap_entry(); 4583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(new == NULL) { 4593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 4603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->id = id; 4633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(description != NULL) { 4643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->description = strdup(description); 4653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->ptp_id = ptp_id; 4673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add the entry to the list 4693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(propertymap == NULL) { 4703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap = new; 4713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 4723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = propertymap; 4733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current->next != NULL ) current=current->next; 4743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->next = new; 4753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update the existing entry 4773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 4783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (current->description != NULL) { 4793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(current->description); 4803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->description = NULL; 4823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(description != NULL) { 4833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->description = strdup(description); 4843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current->ptp_id = ptp_id; 4863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 4893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 4903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void init_propertymap() 4923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 4933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Storage ID", LIBMTP_PROPERTY_StorageID, PTP_OPC_StorageID); 4943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Object Format", LIBMTP_PROPERTY_ObjectFormat, PTP_OPC_ObjectFormat); 4953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Protection Status", LIBMTP_PROPERTY_ProtectionStatus, PTP_OPC_ProtectionStatus); 4963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Object Size", LIBMTP_PROPERTY_ObjectSize, PTP_OPC_ObjectSize); 4973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Association Type", LIBMTP_PROPERTY_AssociationType, PTP_OPC_AssociationType); 4983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Association Desc", LIBMTP_PROPERTY_AssociationDesc, PTP_OPC_AssociationDesc); 4993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Object File Name", LIBMTP_PROPERTY_ObjectFileName, PTP_OPC_ObjectFileName); 5003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Date Created", LIBMTP_PROPERTY_DateCreated, PTP_OPC_DateCreated); 5013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Date Modified", LIBMTP_PROPERTY_DateModified, PTP_OPC_DateModified); 5023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Keywords", LIBMTP_PROPERTY_Keywords, PTP_OPC_Keywords); 5033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Parent Object", LIBMTP_PROPERTY_ParentObject, PTP_OPC_ParentObject); 5043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Allowed Folder Contents", LIBMTP_PROPERTY_AllowedFolderContents, PTP_OPC_AllowedFolderContents); 5053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Hidden", LIBMTP_PROPERTY_Hidden, PTP_OPC_Hidden); 5063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("System Object", LIBMTP_PROPERTY_SystemObject, PTP_OPC_SystemObject); 5073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Persistant Unique Object Identifier", LIBMTP_PROPERTY_PersistantUniqueObjectIdentifier, PTP_OPC_PersistantUniqueObjectIdentifier); 5083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Sync ID", LIBMTP_PROPERTY_SyncID, PTP_OPC_SyncID); 5093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Property Bag", LIBMTP_PROPERTY_PropertyBag, PTP_OPC_PropertyBag); 5103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Name", LIBMTP_PROPERTY_Name, PTP_OPC_Name); 5113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Created By", LIBMTP_PROPERTY_CreatedBy, PTP_OPC_CreatedBy); 5123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Artist", LIBMTP_PROPERTY_Artist, PTP_OPC_Artist); 5133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Date Authored", LIBMTP_PROPERTY_DateAuthored, PTP_OPC_DateAuthored); 5143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Description", LIBMTP_PROPERTY_Description, PTP_OPC_Description); 5153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("URL Reference", LIBMTP_PROPERTY_URLReference, PTP_OPC_URLReference); 5163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Language Locale", LIBMTP_PROPERTY_LanguageLocale, PTP_OPC_LanguageLocale); 5173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Copyright Information", LIBMTP_PROPERTY_CopyrightInformation, PTP_OPC_CopyrightInformation); 5183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Source", LIBMTP_PROPERTY_Source, PTP_OPC_Source); 5193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Origin Location", LIBMTP_PROPERTY_OriginLocation, PTP_OPC_OriginLocation); 5203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Date Added", LIBMTP_PROPERTY_DateAdded, PTP_OPC_DateAdded); 5213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Non Consumable", LIBMTP_PROPERTY_NonConsumable, PTP_OPC_NonConsumable); 5223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Corrupt Or Unplayable", LIBMTP_PROPERTY_CorruptOrUnplayable, PTP_OPC_CorruptOrUnplayable); 5233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Producer Serial Number", LIBMTP_PROPERTY_ProducerSerialNumber, PTP_OPC_ProducerSerialNumber); 5243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Representative Sample Format", LIBMTP_PROPERTY_RepresentativeSampleFormat, PTP_OPC_RepresentativeSampleFormat); 5253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Representative Sample Sise", LIBMTP_PROPERTY_RepresentativeSampleSize, PTP_OPC_RepresentativeSampleSize); 5263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Representative Sample Height", LIBMTP_PROPERTY_RepresentativeSampleHeight, PTP_OPC_RepresentativeSampleHeight); 5273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Representative Sample Width", LIBMTP_PROPERTY_RepresentativeSampleWidth, PTP_OPC_RepresentativeSampleWidth); 5283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Representative Sample Duration", LIBMTP_PROPERTY_RepresentativeSampleDuration, PTP_OPC_RepresentativeSampleDuration); 5293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Representative Sample Data", LIBMTP_PROPERTY_RepresentativeSampleData, PTP_OPC_RepresentativeSampleData); 5303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Width", LIBMTP_PROPERTY_Width, PTP_OPC_Width); 5313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Height", LIBMTP_PROPERTY_Height, PTP_OPC_Height); 5323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Duration", LIBMTP_PROPERTY_Duration, PTP_OPC_Duration); 5333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Rating", LIBMTP_PROPERTY_Rating, PTP_OPC_Rating); 5343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Track", LIBMTP_PROPERTY_Track, PTP_OPC_Track); 5353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Genre", LIBMTP_PROPERTY_Genre, PTP_OPC_Genre); 5363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Credits", LIBMTP_PROPERTY_Credits, PTP_OPC_Credits); 5373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Lyrics", LIBMTP_PROPERTY_Lyrics, PTP_OPC_Lyrics); 5383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Subscription Content ID", LIBMTP_PROPERTY_SubscriptionContentID, PTP_OPC_SubscriptionContentID); 5393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Produced By", LIBMTP_PROPERTY_ProducedBy, PTP_OPC_ProducedBy); 5403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Use Count", LIBMTP_PROPERTY_UseCount, PTP_OPC_UseCount); 5413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Skip Count", LIBMTP_PROPERTY_SkipCount, PTP_OPC_SkipCount); 5423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Last Accessed", LIBMTP_PROPERTY_LastAccessed, PTP_OPC_LastAccessed); 5433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Parental Rating", LIBMTP_PROPERTY_ParentalRating, PTP_OPC_ParentalRating); 5443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Meta Genre", LIBMTP_PROPERTY_MetaGenre, PTP_OPC_MetaGenre); 5453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Composer", LIBMTP_PROPERTY_Composer, PTP_OPC_Composer); 5463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Effective Rating", LIBMTP_PROPERTY_EffectiveRating, PTP_OPC_EffectiveRating); 5473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Subtitle", LIBMTP_PROPERTY_Subtitle, PTP_OPC_Subtitle); 5483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Original Release Date", LIBMTP_PROPERTY_OriginalReleaseDate, PTP_OPC_OriginalReleaseDate); 5493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Album Name", LIBMTP_PROPERTY_AlbumName, PTP_OPC_AlbumName); 5503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Album Artist", LIBMTP_PROPERTY_AlbumArtist, PTP_OPC_AlbumArtist); 5513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Mood", LIBMTP_PROPERTY_Mood, PTP_OPC_Mood); 5523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("DRM Status", LIBMTP_PROPERTY_DRMStatus, PTP_OPC_DRMStatus); 5533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Sub Description", LIBMTP_PROPERTY_SubDescription, PTP_OPC_SubDescription); 5543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Is Cropped", LIBMTP_PROPERTY_IsCropped, PTP_OPC_IsCropped); 5553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Is Color Corrected", LIBMTP_PROPERTY_IsColorCorrected, PTP_OPC_IsColorCorrected); 5563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Image Bit Depth", LIBMTP_PROPERTY_ImageBitDepth, PTP_OPC_ImageBitDepth); 5573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("f Number", LIBMTP_PROPERTY_Fnumber, PTP_OPC_Fnumber); 5583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Exposure Time", LIBMTP_PROPERTY_ExposureTime, PTP_OPC_ExposureTime); 5593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Exposure Index", LIBMTP_PROPERTY_ExposureIndex, PTP_OPC_ExposureIndex); 5603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Display Name", LIBMTP_PROPERTY_DisplayName, PTP_OPC_DisplayName); 5613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Body Text", LIBMTP_PROPERTY_BodyText, PTP_OPC_BodyText); 5623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Subject", LIBMTP_PROPERTY_Subject, PTP_OPC_Subject); 5633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Priority", LIBMTP_PROPERTY_Priority, PTP_OPC_Priority); 5643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Given Name", LIBMTP_PROPERTY_GivenName, PTP_OPC_GivenName); 5653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Middle Names", LIBMTP_PROPERTY_MiddleNames, PTP_OPC_MiddleNames); 5663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Family Name", LIBMTP_PROPERTY_FamilyName, PTP_OPC_FamilyName); 5673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Prefix", LIBMTP_PROPERTY_Prefix, PTP_OPC_Prefix); 5683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Suffix", LIBMTP_PROPERTY_Suffix, PTP_OPC_Suffix); 5693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phonetic Given Name", LIBMTP_PROPERTY_PhoneticGivenName, PTP_OPC_PhoneticGivenName); 5703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phonetic Family Name", LIBMTP_PROPERTY_PhoneticFamilyName, PTP_OPC_PhoneticFamilyName); 5713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Email: Primary", LIBMTP_PROPERTY_EmailPrimary, PTP_OPC_EmailPrimary); 5723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Email: Personal 1", LIBMTP_PROPERTY_EmailPersonal1, PTP_OPC_EmailPersonal1); 5733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Email: Personal 2", LIBMTP_PROPERTY_EmailPersonal2, PTP_OPC_EmailPersonal2); 5743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Email: Business 1", LIBMTP_PROPERTY_EmailBusiness1, PTP_OPC_EmailBusiness1); 5753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Email: Business 2", LIBMTP_PROPERTY_EmailBusiness2, PTP_OPC_EmailBusiness2); 5763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Email: Others", LIBMTP_PROPERTY_EmailOthers, PTP_OPC_EmailOthers); 5773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Primary", LIBMTP_PROPERTY_PhoneNumberPrimary, PTP_OPC_PhoneNumberPrimary); 5783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Personal", LIBMTP_PROPERTY_PhoneNumberPersonal, PTP_OPC_PhoneNumberPersonal); 5793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Personal 2", LIBMTP_PROPERTY_PhoneNumberPersonal2, PTP_OPC_PhoneNumberPersonal2); 5803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Business", LIBMTP_PROPERTY_PhoneNumberBusiness, PTP_OPC_PhoneNumberBusiness); 5813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Business 2", LIBMTP_PROPERTY_PhoneNumberBusiness2, PTP_OPC_PhoneNumberBusiness2); 5823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Mobile", LIBMTP_PROPERTY_PhoneNumberMobile, PTP_OPC_PhoneNumberMobile); 5833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Mobile 2", LIBMTP_PROPERTY_PhoneNumberMobile2, PTP_OPC_PhoneNumberMobile2); 5843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Fax Number: Primary", LIBMTP_PROPERTY_FaxNumberPrimary, PTP_OPC_FaxNumberPrimary); 5853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Fax Number: Personal", LIBMTP_PROPERTY_FaxNumberPersonal, PTP_OPC_FaxNumberPersonal); 5863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Fax Number: Business", LIBMTP_PROPERTY_FaxNumberBusiness, PTP_OPC_FaxNumberBusiness); 5873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Pager Number", LIBMTP_PROPERTY_PagerNumber, PTP_OPC_PagerNumber); 5883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phone Number: Others", LIBMTP_PROPERTY_PhoneNumberOthers, PTP_OPC_PhoneNumberOthers); 5893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Primary Web Address", LIBMTP_PROPERTY_PrimaryWebAddress, PTP_OPC_PrimaryWebAddress); 5903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Personal Web Address", LIBMTP_PROPERTY_PersonalWebAddress, PTP_OPC_PersonalWebAddress); 5913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Business Web Address", LIBMTP_PROPERTY_BusinessWebAddress, PTP_OPC_BusinessWebAddress); 5923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Instant Messenger Address 1", LIBMTP_PROPERTY_InstantMessengerAddress, PTP_OPC_InstantMessengerAddress); 5933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Instant Messenger Address 2", LIBMTP_PROPERTY_InstantMessengerAddress2, PTP_OPC_InstantMessengerAddress2); 5943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Instant Messenger Address 3", LIBMTP_PROPERTY_InstantMessengerAddress3, PTP_OPC_InstantMessengerAddress3); 5953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: Full", LIBMTP_PROPERTY_PostalAddressPersonalFull, PTP_OPC_PostalAddressPersonalFull); 5963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: Line 1", LIBMTP_PROPERTY_PostalAddressPersonalFullLine1, PTP_OPC_PostalAddressPersonalFullLine1); 5973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: Line 2", LIBMTP_PROPERTY_PostalAddressPersonalFullLine2, PTP_OPC_PostalAddressPersonalFullLine2); 5983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: City", LIBMTP_PROPERTY_PostalAddressPersonalFullCity, PTP_OPC_PostalAddressPersonalFullCity); 5993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: Region", LIBMTP_PROPERTY_PostalAddressPersonalFullRegion, PTP_OPC_PostalAddressPersonalFullRegion); 6003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: Postal Code", LIBMTP_PROPERTY_PostalAddressPersonalFullPostalCode, PTP_OPC_PostalAddressPersonalFullPostalCode); 6013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Personal: Country", LIBMTP_PROPERTY_PostalAddressPersonalFullCountry, PTP_OPC_PostalAddressPersonalFullCountry); 6023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: Full", LIBMTP_PROPERTY_PostalAddressBusinessFull, PTP_OPC_PostalAddressBusinessFull); 6033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: Line 1", LIBMTP_PROPERTY_PostalAddressBusinessLine1, PTP_OPC_PostalAddressBusinessLine1); 6043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: Line 2", LIBMTP_PROPERTY_PostalAddressBusinessLine2, PTP_OPC_PostalAddressBusinessLine2); 6053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: City", LIBMTP_PROPERTY_PostalAddressBusinessCity, PTP_OPC_PostalAddressBusinessCity); 6063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: Region", LIBMTP_PROPERTY_PostalAddressBusinessRegion, PTP_OPC_PostalAddressBusinessRegion); 6073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: Postal Code", LIBMTP_PROPERTY_PostalAddressBusinessPostalCode, PTP_OPC_PostalAddressBusinessPostalCode); 6083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Business: Country", LIBMTP_PROPERTY_PostalAddressBusinessCountry, PTP_OPC_PostalAddressBusinessCountry); 6093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: Full", LIBMTP_PROPERTY_PostalAddressOtherFull, PTP_OPC_PostalAddressOtherFull); 6103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: Line 1", LIBMTP_PROPERTY_PostalAddressOtherLine1, PTP_OPC_PostalAddressOtherLine1); 6113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: Line 2", LIBMTP_PROPERTY_PostalAddressOtherLine2, PTP_OPC_PostalAddressOtherLine2); 6123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: City", LIBMTP_PROPERTY_PostalAddressOtherCity, PTP_OPC_PostalAddressOtherCity); 6133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: Region", LIBMTP_PROPERTY_PostalAddressOtherRegion, PTP_OPC_PostalAddressOtherRegion); 6143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: Postal Code", LIBMTP_PROPERTY_PostalAddressOtherPostalCode, PTP_OPC_PostalAddressOtherPostalCode); 6153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Postal Address: Other: Counrtry", LIBMTP_PROPERTY_PostalAddressOtherCountry, PTP_OPC_PostalAddressOtherCountry); 6163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Organization Name", LIBMTP_PROPERTY_OrganizationName, PTP_OPC_OrganizationName); 6173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Phonetic Organization Name", LIBMTP_PROPERTY_PhoneticOrganizationName, PTP_OPC_PhoneticOrganizationName); 6183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Role", LIBMTP_PROPERTY_Role, PTP_OPC_Role); 6193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Birthdate", LIBMTP_PROPERTY_Birthdate, PTP_OPC_Birthdate); 6203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Message To", LIBMTP_PROPERTY_MessageTo, PTP_OPC_MessageTo); 6213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Message CC", LIBMTP_PROPERTY_MessageCC, PTP_OPC_MessageCC); 6223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Message BCC", LIBMTP_PROPERTY_MessageBCC, PTP_OPC_MessageBCC); 6233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Message Read", LIBMTP_PROPERTY_MessageRead, PTP_OPC_MessageRead); 6243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Message Received Time", LIBMTP_PROPERTY_MessageReceivedTime, PTP_OPC_MessageReceivedTime); 6253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Message Sender", LIBMTP_PROPERTY_MessageSender, PTP_OPC_MessageSender); 6263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Activity Begin Time", LIBMTP_PROPERTY_ActivityBeginTime, PTP_OPC_ActivityBeginTime); 6273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Activity End Time", LIBMTP_PROPERTY_ActivityEndTime, PTP_OPC_ActivityEndTime); 6283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Activity Location", LIBMTP_PROPERTY_ActivityLocation, PTP_OPC_ActivityLocation); 6293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Activity Required Attendees", LIBMTP_PROPERTY_ActivityRequiredAttendees, PTP_OPC_ActivityRequiredAttendees); 6303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Optional Attendees", LIBMTP_PROPERTY_ActivityOptionalAttendees, PTP_OPC_ActivityOptionalAttendees); 6313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Activity Resources", LIBMTP_PROPERTY_ActivityResources, PTP_OPC_ActivityResources); 6323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Activity Accepted", LIBMTP_PROPERTY_ActivityAccepted, PTP_OPC_ActivityAccepted); 6333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Owner", LIBMTP_PROPERTY_Owner, PTP_OPC_Owner); 6343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Editor", LIBMTP_PROPERTY_Editor, PTP_OPC_Editor); 6353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Webmaster", LIBMTP_PROPERTY_Webmaster, PTP_OPC_Webmaster); 6363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("URL Source", LIBMTP_PROPERTY_URLSource, PTP_OPC_URLSource); 6373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("URL Destination", LIBMTP_PROPERTY_URLDestination, PTP_OPC_URLDestination); 6383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Time Bookmark", LIBMTP_PROPERTY_TimeBookmark, PTP_OPC_TimeBookmark); 6393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Object Bookmark", LIBMTP_PROPERTY_ObjectBookmark, PTP_OPC_ObjectBookmark); 6403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Byte Bookmark", LIBMTP_PROPERTY_ByteBookmark, PTP_OPC_ByteBookmark); 6413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Last Build Date", LIBMTP_PROPERTY_LastBuildDate, PTP_OPC_LastBuildDate); 6423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Time To Live", LIBMTP_PROPERTY_TimetoLive, PTP_OPC_TimetoLive); 6433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Media GUID", LIBMTP_PROPERTY_MediaGUID, PTP_OPC_MediaGUID); 6443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Total Bit Rate", LIBMTP_PROPERTY_TotalBitRate, PTP_OPC_TotalBitRate); 6453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Bit Rate Type", LIBMTP_PROPERTY_BitRateType, PTP_OPC_BitRateType); 6463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Sample Rate", LIBMTP_PROPERTY_SampleRate, PTP_OPC_SampleRate); 6473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Number Of Channels", LIBMTP_PROPERTY_NumberOfChannels, PTP_OPC_NumberOfChannels); 6483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Audio Bit Depth", LIBMTP_PROPERTY_AudioBitDepth, PTP_OPC_AudioBitDepth); 6493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Scan Depth", LIBMTP_PROPERTY_ScanDepth, PTP_OPC_ScanDepth); 6503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Audio WAVE Codec", LIBMTP_PROPERTY_AudioWAVECodec, PTP_OPC_AudioWAVECodec); 6513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Audio Bit Rate", LIBMTP_PROPERTY_AudioBitRate, PTP_OPC_AudioBitRate); 6523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Video Four CC Codec", LIBMTP_PROPERTY_VideoFourCCCodec, PTP_OPC_VideoFourCCCodec); 6533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Video Bit Rate", LIBMTP_PROPERTY_VideoBitRate, PTP_OPC_VideoBitRate); 6543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Frames Per Thousand Seconds", LIBMTP_PROPERTY_FramesPerThousandSeconds, PTP_OPC_FramesPerThousandSeconds); 6553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Key Frame Distance", LIBMTP_PROPERTY_KeyFrameDistance, PTP_OPC_KeyFrameDistance); 6563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Buffer Size", LIBMTP_PROPERTY_BufferSize, PTP_OPC_BufferSize); 6573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Encoding Quality", LIBMTP_PROPERTY_EncodingQuality, PTP_OPC_EncodingQuality); 6583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Encoding Profile", LIBMTP_PROPERTY_EncodingProfile, PTP_OPC_EncodingProfile); 6593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Buy flag", LIBMTP_PROPERTY_BuyFlag, PTP_OPC_BuyFlag); 6603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev register_property("Unknown property", LIBMTP_PROPERTY_UNKNOWN, 0); 6613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 6623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 6643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Returns the PTP property that maps to a certain libmtp internal property type. 6653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param inproperty the MTP library interface property 6663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the PTP (libgphoto2) property type 6673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 6683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t map_libmtp_property_to_ptp_property(LIBMTP_property_t inproperty) 6693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 6703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap_t *current; 6713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = propertymap; 6733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 6753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->id == inproperty) { 6763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return current->ptp_id; 6773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 6783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 6793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 6803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 6813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 6823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 6853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Returns the MTP internal interface property that maps to a certain ptp 6863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * interface property. 6873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param inproperty the PTP (libgphoto2) interface property 6883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the MTP library interface property 6893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 6903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_property_t map_ptp_property_to_libmtp_property(uint16_t inproperty) 6913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 6923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap_t *current; 6933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = propertymap; 6953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 6973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->ptp_id == inproperty) { 6983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return current->id; 6993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 7013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // printf("map_ptp_type_to_libmtp_type: unknown filetype.\n"); 7033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_PROPERTY_UNKNOWN; 7043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 7053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 7083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Initialize the library. You are only supposed to call this 7093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * one, before using the library for the first time in a program. 7103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Never re-initialize libmtp! 7113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 7123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The only thing this does at the moment is to initialise the 7133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * filetype mapping table. 7143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 7153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Init(void) 7163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 7173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev init_filemap(); 7183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev init_propertymap(); 7193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 7203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 7213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 7243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This helper function returns a textual description for a libmtp 7253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * file type to be used in dialog boxes etc. 7263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param intype the libmtp internal filetype to get a description for. 7273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a string representing the filetype, this must <b>NOT</b> 7283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * be free():ed by the caller! 7293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 7303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar const * LIBMTP_Get_Filetype_Description(LIBMTP_filetype_t intype) 7313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 7323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filemap_t *current; 7333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = filemap; 7353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 7373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->id == intype) { 7383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return current->description; 7393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 7413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return "Unknown filetype"; 7443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 7453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 7473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This helper function returns a textual description for a libmtp 7483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * property to be used in dialog boxes etc. 7493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param inproperty the libmtp internal property to get a description for. 7503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a string representing the filetype, this must <b>NOT</b> 7513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * be free():ed by the caller! 7523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 7533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar const * LIBMTP_Get_Property_Description(LIBMTP_property_t inproperty) 7543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 7553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propertymap_t *current; 7563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = propertymap; 7583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (current != NULL) { 7603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current->id == inproperty) { 7613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return current->description; 7623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current = current->next; 7643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return "Unknown property"; 7673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 7683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 7703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function will do its best to fit a 16bit 7713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * value into a PTP object property if the property 7723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * is limited in range or step sizes. 7733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 7743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t adjust_u16(uint16_t val, PTPObjectPropDesc *opd) 7753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 7763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd->FormFlag) { 7773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPFF_Range: 7783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val < opd->FORM.Range.MinimumValue.u16) { 7793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return opd->FORM.Range.MinimumValue.u16; 7803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val > opd->FORM.Range.MaximumValue.u16) { 7823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return opd->FORM.Range.MaximumValue.u16; 7833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Round down to last step. 7853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val % opd->FORM.Range.StepSize.u16 != 0) { 7863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val - (val % opd->FORM.Range.StepSize.u16); 7873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val; 7893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 7903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPFF_Enumeration: 7913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 7923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 7933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t bestfit = opd->FORM.Enum.SupportedValue[0].u16; 7943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0; i<opd->FORM.Enum.NumberOfValues; i++) { 7963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val == opd->FORM.Enum.SupportedValue[i].u16) { 7973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val; 7983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Rough guess of best fit 8003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd->FORM.Enum.SupportedValue[i].u16 < val) { 8013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bestfit = opd->FORM.Enum.SupportedValue[i].u16; 8023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just some default that'll work. 8053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return bestfit; 8063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 8083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Will accept any value 8093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val; 8123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 8133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 8153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function will do its best to fit a 32bit 8163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * value into a PTP object property if the property 8173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * is limited in range or step sizes. 8183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 8193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint32_t adjust_u32(uint32_t val, PTPObjectPropDesc *opd) 8203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 8213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd->FormFlag) { 8223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPFF_Range: 8233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val < opd->FORM.Range.MinimumValue.u32) { 8243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return opd->FORM.Range.MinimumValue.u32; 8253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val > opd->FORM.Range.MaximumValue.u32) { 8273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return opd->FORM.Range.MaximumValue.u32; 8283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Round down to last step. 8303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val % opd->FORM.Range.StepSize.u32 != 0) { 8313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val - (val % opd->FORM.Range.StepSize.u32); 8323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val; 8343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPFF_Enumeration: 8363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 8373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 8383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t bestfit = opd->FORM.Enum.SupportedValue[0].u32; 8393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0; i<opd->FORM.Enum.NumberOfValues; i++) { 8413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (val == opd->FORM.Enum.SupportedValue[i].u32) { 8423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val; 8433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Rough guess of best fit 8453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd->FORM.Enum.SupportedValue[i].u32 < val) { 8463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bestfit = opd->FORM.Enum.SupportedValue[i].u32; 8473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just some default that'll work. 8503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return bestfit; 8513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 8533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Will accept any value 8543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return val; 8573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 8583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 8603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function returns a newly created ISO 8601 timestamp with the 8613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * current time in as high precision as possible. It even adds 8623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the time zone if it can. 8633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 8643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic char *get_iso8601_stamp(void) 8653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 8663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev time_t curtime; 8673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev struct tm *loctime; 8683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char tmp[64]; 8693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curtime = time(NULL); 8713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev loctime = localtime(&curtime); 8723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strftime (tmp, sizeof(tmp), "%Y%m%dT%H%M%S.0%z", loctime); 8733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return strdup(tmp); 8743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 8753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 8773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Gets the allowed values (range or enum) for a property 8783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device 8793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param property the property to query 8803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filetype the filetype of the object you want to set values for 8813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param allowed_vals pointer to a LIBMTP_allowed_values_t struct to 8823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * receive the allowed values. Call LIBMTP_destroy_allowed_values_t 8833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on this on successful completion. 8843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 8853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 8863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Allowed_Property_Values(LIBMTP_mtpdevice_t *device, LIBMTP_property_t const property, 8873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filetype_t const filetype, LIBMTP_allowed_values_t *allowed_vals) 8883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 8893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 8903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret = 0; 8913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(device->params, map_libmtp_property_to_ptp_property(property), map_libmtp_type_to_ptp_type(filetype), &opd); 8933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 8943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Allowed_Property_Values(): could not get property description."); 8953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 8963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd.FormFlag == PTP_OPFF_Enumeration) { 8993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i = 0; 9003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 9013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->is_range = 0; 9023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->num_entries = opd.FORM.Enum.NumberOfValues; 9033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 9043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.DataType) 9053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 9063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT8: 9073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i8vals = malloc(sizeof(int8_t) * opd.FORM.Enum.NumberOfValues); 9083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT8; 9093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 9113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u8vals = malloc(sizeof(uint8_t) * opd.FORM.Enum.NumberOfValues); 9123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT8; 9133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: 9153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i16vals = malloc(sizeof(int16_t) * opd.FORM.Enum.NumberOfValues); 9163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT16; 9173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 9193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u16vals = malloc(sizeof(uint16_t) * opd.FORM.Enum.NumberOfValues); 9203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT16; 9213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT32: 9233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i32vals = malloc(sizeof(int32_t) * opd.FORM.Enum.NumberOfValues); 9243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT32; 9253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 9273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u32vals = malloc(sizeof(uint32_t) * opd.FORM.Enum.NumberOfValues); 9283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT32; 9293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT64: 9313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i64vals = malloc(sizeof(int64_t) * opd.FORM.Enum.NumberOfValues); 9323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT64; 9333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT64: 9353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u64vals = malloc(sizeof(uint64_t) * opd.FORM.Enum.NumberOfValues); 9363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT64; 9373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 9393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 9403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < opd.FORM.Enum.NumberOfValues; i++) { 9413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.DataType) 9423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 9433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT8: 9443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i8vals[i] = opd.FORM.Enum.SupportedValue[i].i8; 9453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 9473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u8vals[i] = opd.FORM.Enum.SupportedValue[i].u8; 9483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: 9503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i16vals[i] = opd.FORM.Enum.SupportedValue[i].i16; 9513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 9533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u16vals[i] = opd.FORM.Enum.SupportedValue[i].u16; 9543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT32: 9563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i32vals[i] = opd.FORM.Enum.SupportedValue[i].i32; 9573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 9593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u32vals[i] = opd.FORM.Enum.SupportedValue[i].u32; 9603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT64: 9623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i64vals[i] = opd.FORM.Enum.SupportedValue[i].i64; 9633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT64: 9653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u64vals[i] = opd.FORM.Enum.SupportedValue[i].u64; 9663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 9683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 9693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 9703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 9713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.FormFlag == PTP_OPFF_Range) { 9723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->is_range = 1; 9733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 9743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.DataType) 9753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 9763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT8: 9773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i8min = opd.FORM.Range.MinimumValue.i8; 9783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i8max = opd.FORM.Range.MaximumValue.i8; 9793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i8step = opd.FORM.Range.StepSize.i8; 9803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT8; 9813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 9833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u8min = opd.FORM.Range.MinimumValue.u8; 9843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u8max = opd.FORM.Range.MaximumValue.u8; 9853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u8step = opd.FORM.Range.StepSize.u8; 9863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT8; 9873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: 9893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i16min = opd.FORM.Range.MinimumValue.i16; 9903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i16max = opd.FORM.Range.MaximumValue.i16; 9913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i16step = opd.FORM.Range.StepSize.i16; 9923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT16; 9933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 9953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u16min = opd.FORM.Range.MinimumValue.u16; 9963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u16max = opd.FORM.Range.MaximumValue.u16; 9973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u16step = opd.FORM.Range.StepSize.u16; 9983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT16; 9993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT32: 10013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i32min = opd.FORM.Range.MinimumValue.i32; 10023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i32max = opd.FORM.Range.MaximumValue.i32; 10033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i32step = opd.FORM.Range.StepSize.i32; 10043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT32; 10053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 10073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u32min = opd.FORM.Range.MinimumValue.u32; 10083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u32max = opd.FORM.Range.MaximumValue.u32; 10093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u32step = opd.FORM.Range.StepSize.u32; 10103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT32; 10113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT64: 10133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i64min = opd.FORM.Range.MinimumValue.i64; 10143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i64max = opd.FORM.Range.MaximumValue.i64; 10153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->i64step = opd.FORM.Range.StepSize.i64; 10163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_INT64; 10173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT64: 10193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u64min = opd.FORM.Range.MinimumValue.u64; 10203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u64max = opd.FORM.Range.MaximumValue.u64; 10213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->u64step = opd.FORM.Range.StepSize.u64; 10223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev allowed_vals->datatype = LIBMTP_DATATYPE_UINT64; 10233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 10263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else 10273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 10283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 10293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 10313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Destroys a LIBMTP_allowed_values_t struct 10323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param allowed_vals the struct to destroy 10333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 10343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_allowed_values_t(LIBMTP_allowed_values_t *allowed_vals) 10353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 10363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!allowed_vals->is_range) 10373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 10383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (allowed_vals->datatype) 10393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 10403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_INT8: 10413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->i8vals) 10423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->i8vals); 10433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_UINT8: 10453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->u8vals) 10463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->u8vals); 10473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_INT16: 10493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->i16vals) 10503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->i16vals); 10513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_UINT16: 10533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->u16vals) 10543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->u16vals); 10553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_INT32: 10573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->i32vals) 10583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->i32vals); 10593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_UINT32: 10613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->u32vals) 10623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->u32vals); 10633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_INT64: 10653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->i64vals) 10663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->i64vals); 10673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_DATATYPE_UINT64: 10693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (allowed_vals->u64vals) 10703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(allowed_vals->u64vals); 10713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 10723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 10753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 10773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Determine if a property is supported for a given file type 10783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device 10793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param property the property to query 10803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filetype the filetype of the object you want to set values for 10813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if not supported, positive if supported, negative on error 10823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 10833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Is_Property_Supported(LIBMTP_mtpdevice_t *device, LIBMTP_property_t const property, 10843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filetype_t const filetype) 10853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 10863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 10873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 10883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret = 0; 10893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i = 0; 10903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int supported = 0; 10913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ptp_prop = map_libmtp_property_to_ptp_property(property); 10923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(device->params, map_libmtp_type_to_ptp_type(filetype), &propcnt, &props); 10943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 10953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Is_Property_Supported(): could not get properties supported."); 10963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 10973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < propcnt; i++) { 11003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (props[i] == ptp_prop) { 11013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev supported = 1; 11023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 11033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 11073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return supported; 11093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 11123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves a string from an object 11133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 11143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 11153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 11163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 11173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return valid string or NULL on failure. The returned string 11183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * must bee <code>free()</code>:ed by the caller after 11193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * use. 11203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_String_From_Object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 11223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id) 11233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_string_from_object(device, object_id, attribute_id); 11253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 11283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev* Retrieves an unsigned 64-bit integer from an object attribute 11293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 11303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 11313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 11323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 11333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 11343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the value 11353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevuint64_t LIBMTP_Get_u64_From_Object(LIBMTP_mtpdevice_t *device,uint32_t const object_id, 11373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint64_t const value_default) 11383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_u64_from_object(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value_default); 11403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 11433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves an unsigned 32-bit integer from an object attribute 11443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 11453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 11463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 11473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 11483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 11493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the value 11503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevuint32_t LIBMTP_Get_u32_From_Object(LIBMTP_mtpdevice_t *device,uint32_t const object_id, 11523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint32_t const value_default) 11533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_u32_from_object(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value_default); 11553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 11583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves an unsigned 16-bit integer from an object attribute 11593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 11603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 11613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 11623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 11633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 11643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a value 11653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevuint16_t LIBMTP_Get_u16_From_Object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 11673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint16_t const value_default) 11683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_u16_from_object(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value_default); 11703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 11733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves an unsigned 8-bit integer from an object attribute 11743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 11753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 11763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 11773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 11783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 11793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a value 11803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevuint8_t LIBMTP_Get_u8_From_Object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 11823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint8_t const value_default) 11833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_u8_from_object(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value_default); 11853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 11883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from a string 11893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 11903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 11913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 11923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 11933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param string string value to set 11943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 11953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Object_String(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 11973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, char const * const string) 11983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return set_object_string(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), string); 12003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 12043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from an unsigned 32-bit integer 12053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 12063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 12073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 12083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 12093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value 32-bit unsigned integer to set 12103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 12113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 12123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Object_u32(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 12133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint32_t const value) 12143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 12153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return set_object_u32(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value); 12163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 12193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from an unsigned 16-bit integer 12203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 12213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 12223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 12233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 12243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value 16-bit unsigned integer to set 12253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 12263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 12273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Object_u16(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 12283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint16_t const value) 12293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 12303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return set_object_u16(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value); 12313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 12343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from an unsigned 8-bit integer 12353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 12363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 12373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 12383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id MTP attribute ID 12393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value 8-bit unsigned integer to set 12403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 12413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 12423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Object_u8(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 12433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_property_t const attribute_id, uint8_t const value) 12443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 12453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return set_object_u8(device, object_id, map_libmtp_property_to_ptp_property(attribute_id), value); 12463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 12493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves a string from an object 12503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 12513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 12523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 12533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 12543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return valid string or NULL on failure. The returned string 12553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * must bee <code>free()</code>:ed by the caller after 12563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * use. 12573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 12583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic char *get_string_from_object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 12593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id) 12603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 12613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 12623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retstring = NULL; 12633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 12643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 12653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 12663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( device == NULL || object_id == 0) { 12683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 12693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_find_object_prop_in_cache(params, object_id, attribute_id); 12723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop) { 12733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 12743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return strdup(prop->propval.str); 12753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 12763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 12773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropvalue(params, object_id, attribute_id, &propval, PTP_DTC_STR); 12803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) { 12813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (propval.str != NULL) { 12823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retstring = (char *) strdup(propval.str); 12833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.str); 12843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 12863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_string_from_object(): could not get object string."); 12873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retstring; 12903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 12933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev* Retrieves an unsigned 64-bit integer from an object attribute 12943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 12953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 12963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 12973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 12983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 12993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the value 13003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 13013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint64_t get_u64_from_object(LIBMTP_mtpdevice_t *device,uint32_t const object_id, 13023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint64_t const value_default) 13033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 13043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 13053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint64_t retval = value_default; 13063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 13073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 13083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 13093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( device == NULL ) { 13113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return value_default; 13123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_find_object_prop_in_cache(params, object_id, attribute_id); 13153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop) 13163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return prop->propval.u64; 13173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropvalue(params, object_id, 13193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev attribute_id, 13203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 13213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_UINT64); 13223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) { 13233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retval = propval.u64; 13243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 13253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_u64_from_object(): could not get unsigned 64bit integer from object."); 13263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retval; 13293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 13303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 13323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves an unsigned 32-bit integer from an object attribute 13333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 13343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 13353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 13363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 13373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 13383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the value 13393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 13403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint32_t get_u32_from_object(LIBMTP_mtpdevice_t *device,uint32_t const object_id, 13413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint32_t const value_default) 13423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 13433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 13443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t retval = value_default; 13453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 13463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 13473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 13483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( device == NULL ) { 13503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return value_default; 13513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_find_object_prop_in_cache(params, object_id, attribute_id); 13543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop) 13553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return prop->propval.u32; 13563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropvalue(params, object_id, 13583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev attribute_id, 13593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 13603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_UINT32); 13613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) { 13623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retval = propval.u32; 13633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 13643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_u32_from_object(): could not get unsigned 32bit integer from object."); 13653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retval; 13673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 13683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 13703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves an unsigned 16-bit integer from an object attribute 13713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 13723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 13733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 13743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 13753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 13763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a value 13773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 13783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t get_u16_from_object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 13793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint16_t const value_default) 13803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 13813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 13823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t retval = value_default; 13833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 13843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 13853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 13863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( device == NULL ) { 13883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return value_default; 13893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This O(n) search should not be used so often, since code 13923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // using the cached properties don't usually call this function. 13933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_find_object_prop_in_cache(params, object_id, attribute_id); 13943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop) 13953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return prop->propval.u16; 13963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropvalue(params, object_id, 13983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev attribute_id, 13993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 14003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_UINT16); 14013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) { 14023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retval = propval.u16; 14033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 14043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_u16_from_object(): could not get unsigned 16bit integer from object."); 14053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retval; 14083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 14093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 14113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Retrieves an unsigned 8-bit integer from an object attribute 14123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 14133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 14143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 14153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 14163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value_default Default value to return on failure 14173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a value 14183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 14193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint8_t get_u8_from_object(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 14203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint8_t const value_default) 14213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 14223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 14233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t retval = value_default; 14243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 14253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 14263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 14273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( device == NULL ) { 14293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return value_default; 14303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This O(n) search should not be used so often, since code 14333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // using the cached properties don't usually call this function. 14343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_find_object_prop_in_cache(params, object_id, attribute_id); 14353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop) 14363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return prop->propval.u8; 14373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropvalue(params, object_id, 14393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev attribute_id, 14403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 14413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_UINT8); 14423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) { 14433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retval = propval.u8; 14443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 14453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_u8_from_object(): could not get unsigned 8bit integer from object."); 14463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retval; 14493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 14503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 14523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from a string 14533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 14543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 14553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 14563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 14573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param string string value to set 14583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 14593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 14603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_string(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 14613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, char const * const string) 14623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 14633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 14643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 14653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 14663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL || string == NULL) { 14683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 14693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_MTP_SetObjectPropValue)) { 14723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_string(): could not set object string: " 14733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "PTP_OC_MTP_SetObjectPropValue not supported."); 14743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 14753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.str = (char *) string; 14773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectpropvalue(params, object_id, attribute_id, &propval, PTP_DTC_STR); 14783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 14793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "set_object_string(): could not set object string."); 14803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 14813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 14843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 14853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 14883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from an unsigned 32-bit integer 14893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 14903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 14913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 14923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 14933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value 32-bit unsigned integer to set 14943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 14953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 14963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_u32(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 14973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint32_t const value) 14983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 14993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 15003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 15013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 15023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 15043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 15053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_MTP_SetObjectPropValue)) { 15083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_u32(): could not set unsigned 32bit integer property: " 15093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "PTP_OC_MTP_SetObjectPropValue not supported."); 15103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 15113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.u32 = value; 15143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectpropvalue(params, object_id, attribute_id, &propval, PTP_DTC_UINT32); 15153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 15163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "set_object_u32(): could not set unsigned 32bit integer property."); 15173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 15183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 15213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 15223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 15243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from an unsigned 16-bit integer 15253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 15263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 15273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 15283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 15293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value 16-bit unsigned integer to set 15303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 15313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 15323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_u16(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 15333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint16_t const value) 15343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 15353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 15363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 15373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 15383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 15403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 15413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_MTP_SetObjectPropValue)) { 15443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_u16(): could not set unsigned 16bit integer property: " 15453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "PTP_OC_MTP_SetObjectPropValue not supported."); 15463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 15473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.u16 = value; 15493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectpropvalue(params, object_id, attribute_id, &propval, PTP_DTC_UINT16); 15503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 15513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "set_object_u16(): could not set unsigned 16bit integer property."); 15523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 15533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 15563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 15573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 15593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets an object attribute from an unsigned 8-bit integer 15603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 15613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to an MTP device. 15623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id Object reference 15633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param attribute_id PTP attribute ID 15643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param value 8-bit unsigned integer to set 15653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure 15663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 15673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_u8(LIBMTP_mtpdevice_t *device, uint32_t const object_id, 15683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const attribute_id, uint8_t const value) 15693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 15703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 15713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 15723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 15733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 15753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 15763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_MTP_SetObjectPropValue)) { 15793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_u8(): could not set unsigned 8bit integer property: " 15803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "PTP_OC_MTP_SetObjectPropValue not supported."); 15813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 15823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.u8 = value; 15843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectpropvalue(params, object_id, attribute_id, &propval, PTP_DTC_UINT8); 15853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 15863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "set_object_u8(): could not set unsigned 8bit integer property."); 15873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 15883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 15913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 15923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 15933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 15943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Get the first (as in "first in the list of") connected MTP device. 15953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a device pointer. 15963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Connected_Devices() 15973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 15983aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_mtpdevice_t *LIBMTP_Get_First_Device(void) 15993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 16003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *first_device = NULL; 16013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_raw_device_t *devices; 16023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int numdevs; 16033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_number_t ret; 16043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = LIBMTP_Detect_Raw_Devices(&devices, &numdevs); 16063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != LIBMTP_ERROR_NONE) { 16073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 16083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (devices == NULL || numdevs == 0) { 16113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 16123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev first_device = LIBMTP_Open_Raw_Device(&devices[0]); 16153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(devices); 16163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return first_device; 16173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 16183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 16203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Overriding debug function. 16213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This way we can disable debug prints. 16223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 16233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void 16243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef __GNUC__ 16253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev__attribute__((__format__(printf,2,0))) 16263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 16273aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_ptp_debug(void *data, const char *format, va_list args) 16283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 16293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef ENABLE_PTP_DEBUG 16303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev vfprintf (stderr, format, args); 16313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fflush (stderr); 16323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 16333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 16343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 16363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Overriding error function. 16373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This way we can capture all error etc to our errorstack. 16383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 16393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void 16403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef __GNUC__ 16413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev__attribute__((__format__(printf,2,0))) 16423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 16433aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_ptp_error(void *data, const char *format, va_list args) 16443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 16453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // if (data == NULL) { 16463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev vfprintf (stderr, format, args); 16473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fflush (stderr); 16483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 16493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev FIXME: find out how we shall get the device here. 16503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 16513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = data; 16523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *device = ...; 16533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char buf[2048]; 16543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev vsnprintf (buf, sizeof (buf), format, args); 16563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, 16573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_ERROR_PTP_LAYER, 16583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev buf); 16593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 16613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 16623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 16643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function opens a device from a raw device. It is the 16653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * preferred way to access devices in the new interface where 16663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * several devices can come and go as the library is working 16673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on a certain device. 16683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param rawdevice the raw device to open a "real" device for. 16693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return an open device. 16703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 16713aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_mtpdevice_t *LIBMTP_Open_Raw_Device(LIBMTP_raw_device_t *rawdevice) 16723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 16733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *mtp_device; 16743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t bs = 0; 16753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *current_params; 16763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb; 16773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_number_t err; 16783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 16793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Allocate dynamic space for our device */ 16813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device = (LIBMTP_mtpdevice_t *) malloc(sizeof(LIBMTP_mtpdevice_t)); 16823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(mtp_device, 0, sizeof(LIBMTP_mtpdevice_t)); 16833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Check if there was a memory allocation error */ 16843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(mtp_device == NULL) { 16853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* There has been an memory allocation error. We are going to ignore this 16863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device and attempt to continue */ 16873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* TODO: This error statement could probably be a bit more robust */ 16893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: connect_usb_devices encountered a memory " 16903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "allocation error with device %d on bus %d, trying to continue", 16913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev rawdevice->devnum, rawdevice->bus_location); 16923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 16943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Create PTP params */ 16973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params = (PTPParams *) malloc(sizeof(PTPParams)); 16983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (current_params == NULL) { 16993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(mtp_device); 17003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 17013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(current_params, 0, sizeof(PTPParams)); 17033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->device_flags = rawdevice->device_entry.device_flags; 17043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->nrofobjects = 0; 17053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->objects = NULL; 17063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->response_packet_size = 0; 17073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->response_packet = NULL; 17083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* This will be a pointer to PTP_USB later */ 17093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->data = NULL; 17103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Set upp local debug and error functions */ 17113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->debug_func = LIBMTP_ptp_debug; 17123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->error_func = LIBMTP_ptp_error; 17133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* TODO: Will this always be little endian? */ 17143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->byteorder = PTP_DL_LE; 17153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->cd_locale_to_ucs2 = iconv_open("UCS-2LE", "UTF-8"); 17163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->cd_ucs2_to_locale = iconv_open("UTF-8", "UCS-2LE"); 17173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(current_params->cd_locale_to_ucs2 == (iconv_t) -1 || 17193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->cd_ucs2_to_locale == (iconv_t) -1) { 17203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Cannot open iconv() converters to/from UCS-2!\n" 17213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Too old stdlibc, glibc and libiconv?\n"); 17223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(current_params); 17233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(mtp_device); 17243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 17253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->params = current_params; 17273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Create usbinfo, this also opens the session */ 17303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev err = configure_usb_device(rawdevice, 17313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params, 17323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &mtp_device->usbinfo); 17333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (err != LIBMTP_ERROR_NONE) { 17343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(current_params); 17353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(mtp_device); 17363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 17373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb = (PTP_USB*) mtp_device->usbinfo; 17393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Set pointer back to params */ 17403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->params = current_params; 17413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Cache the device information for later use */ 17443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_getdeviceinfo(current_params, 17453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ¤t_params->deviceinfo) != PTP_RC_OK) { 17463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Unable to read device information on device " 17473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "%d on bus %d, trying to continue", 17483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev rawdevice->devnum, rawdevice->bus_location); 17493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Prevent memory leaks for this device */ 17513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(mtp_device->usbinfo); 17523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(mtp_device->params); 17533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params = NULL; 17543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(mtp_device); 17553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 17563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Determine if the object size supported is 32 or 64 bit wide */ 17593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<current_params->deviceinfo.ImageFormats_len;i++) { 17603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 17613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_mtp_getobjectpropdesc(current_params, 17633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OPC_ObjectSize, 17643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_params->deviceinfo.ImageFormats[i], 17653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &opd) != PTP_RC_OK) { 17663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("LIBMTP PANIC: " 17673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not inspect object property descriptions!\n"); 17683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 17693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd.DataType == PTP_DTC_UINT32) { 17703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (bs == 0) { 17713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bs = 32; 17723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (bs != 32) { 17733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("LIBMTP PANIC: " 17743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "different objects support different object sizes!\n"); 17753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bs = 0; 17763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 17773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.DataType == PTP_DTC_UINT64) { 17793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (bs == 0) { 17803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bs = 64; 17813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (bs != 64) { 17823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("LIBMTP PANIC: " 17833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "different objects support different object sizes!\n"); 17843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bs = 0; 17853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 17863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 17883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore if other size. 17893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("LIBMTP PANIC: " 17903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "awkward object size data type: %04x\n", opd.DataType); 17913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bs = 0; 17923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 17933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (bs == 0) { 17973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Could not detect object bitsize, assume 32 bits 17983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bs = 32; 17993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->object_bitsize = bs; 18013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* No Errors yet for this device */ 18033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->errorstack = NULL; 18043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Default Max Battery Level, we will adjust this if possible */ 18063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->maximum_battery_level = 100; 18073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Check if device supports reading maximum battery level */ 18093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(!FLAG_BROKEN_BATTERY_LEVEL(ptp_usb) && 18103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_property_issupported( current_params, PTP_DPC_BatteryLevel)) { 18113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPDevicePropDesc dpd; 18123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Try to read maximum battery level */ 18143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(ptp_getdevicepropdesc(current_params, 18153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DPC_BatteryLevel, 18163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &dpd) != PTP_RC_OK) { 18173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(mtp_device, 18183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_ERROR_CONNECTING, 18193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Unable to read Maximum Battery Level for this " 18203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "device even though the device supposedly " 18213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "supports this functionality"); 18223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* TODO: is this appropriate? */ 18253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* If max battery level is 0 then leave the default, otherwise assign */ 18263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (dpd.FORM.Range.MaximumValue.u8 != 0) { 18273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->maximum_battery_level = dpd.FORM.Range.MaximumValue.u8; 18283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_devicepropdesc(&dpd); 18313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Set all default folders to 0 (root directory) */ 18343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_music_folder = 0; 18353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_playlist_folder = 0; 18363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_picture_folder = 0; 18373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_video_folder = 0; 18383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_organizer_folder = 0; 18393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_zencast_folder = 0; 18403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_album_folder = 0; 18413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->default_text_folder = 0; 18423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Set initial storage information */ 18443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->storage = NULL; 18453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (LIBMTP_Get_Storage(mtp_device, LIBMTP_STORAGE_SORTBY_NOTSORTED) == -1) { 18463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(mtp_device, 18473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_ERROR_GENERAL, 18483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Get Storage information failed."); 18493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->storage = NULL; 18503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 18533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Then get the handles and try to locate the default folders. 18543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This has the desired side effect of caching all handles from 18553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device which speeds up later operations. 18563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 18573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(mtp_device); 18583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return mtp_device; 18603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 18613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 18633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Recursive function that adds MTP devices to a linked list 18643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param devices a list of raw devices to have real devices created for. 18653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a device pointer to a newly created mtpdevice (used in linked 18663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list creation). 18673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 18683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_mtpdevice_t * create_usb_mtp_devices(LIBMTP_raw_device_t *devices, int numdevs) 18693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 18703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t i; 18713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *mtp_device_list = NULL; 18723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *current_device = NULL; 18733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0; i < numdevs; i++) { 18753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *mtp_device; 18763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device = LIBMTP_Open_Raw_Device(&devices[i]); 18773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* On error, try next device */ 18793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (mtp_device == NULL) 18803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 18813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Add the device to the list */ 18833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device->next = NULL; 18843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (mtp_device_list == NULL) { 18853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_device_list = current_device = mtp_device; 18863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 18873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_device->next = mtp_device; 18883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev current_device = mtp_device; 18893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return mtp_device_list; 18923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 18933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 18953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Get the number of devices that are available in the listed device list 18963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device_list Pointer to a linked list of devices 18973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return Number of devices in the device list device_list 18983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Connected_Devices() 18993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 19003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevuint32_t LIBMTP_Number_Devices_In_List(LIBMTP_mtpdevice_t *device_list) 19013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 19023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t numdevices = 0; 19033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_mtpdevice_t *iter; 19043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(iter = device_list; iter != NULL; iter = iter->next) 19053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev numdevices++; 19063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return numdevices; 19083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 19093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 19113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Get the first connected MTP device node in the linked list of devices. 19123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Currently this only provides access to USB devices 19133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device_list A list of devices ready to be used by the caller. You 19143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * need to know how many there are. 19153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return Any error information gathered from device connections 19163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Number_Devices_In_List() 19173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 19183aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_error_number_t LIBMTP_Get_Connected_Devices(LIBMTP_mtpdevice_t **device_list) 19193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 19203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_raw_device_t *devices; 19213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int numdevs; 19223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_number_t ret; 19233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = LIBMTP_Detect_Raw_Devices(&devices, &numdevs); 19253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != LIBMTP_ERROR_NONE) { 19263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *device_list = NULL; 19273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 19283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 19293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Assign linked list of devices */ 19313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (devices == NULL || numdevs == 0) { 19323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *device_list = NULL; 19333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_ERROR_NO_DEVICE_ATTACHED; 19343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 19353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *device_list = create_usb_mtp_devices(devices, numdevs); 19373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(devices); 19383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* TODO: Add wifi device access here */ 19403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* We have found some devices but create failed */ 19423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (*device_list == NULL) 19433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_ERROR_CONNECTING; 19443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_ERROR_NONE; 19463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 19473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 19493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This closes and releases an allocated MTP device. 19503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to release. 19513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 19523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Release_Device_List(LIBMTP_mtpdevice_t *device) 19533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 19543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(device != NULL) 19553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 19563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(device->next != NULL) 19573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 19583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_Release_Device_List(device->next); 19593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 19603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_Release_Device(device); 19623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 19633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 19643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 19663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This closes and releases an allocated MTP device. 19673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to release. 19683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 19693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Release_Device(LIBMTP_mtpdevice_t *device) 19703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 19713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 19723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 19733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev close_device(ptp_usb, params); 19753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Clear error stack 19763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_Clear_Errorstack(device); 19773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Free iconv() converters... 19783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev iconv_close(params->cd_locale_to_ucs2); 19793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev iconv_close(params->cd_ucs2_to_locale); 19803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(ptp_usb); 19813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_params(params); 19823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free_storage_list(device); 19833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(device); 19843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 19853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 19873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This can be used by any libmtp-intrinsic code that 19883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * need to stack up an error on the stack. You are only 19893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supposed to add errors to the error stack using this 19903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * function, do not create and reference error entries 19913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * directly. 19923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 19933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void add_error_to_errorstack(LIBMTP_mtpdevice_t *device, 19943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_number_t errornumber, 19953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const error_text) 19963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 19973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_t *newerror; 19983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 19993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 20003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Trying to add error to a NULL device!\n"); 20013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 20023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newerror = (LIBMTP_error_t *) malloc(sizeof(LIBMTP_error_t)); 20043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newerror->errornumber = errornumber; 20053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newerror->error_text = strdup(error_text); 20063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newerror->next = NULL; 20073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->errorstack == NULL) { 20083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->errorstack = newerror; 20093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 20103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_t *tmp = device->errorstack; 20113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (tmp->next != NULL) { 20133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp = tmp->next; 20143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp->next = newerror; 20163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 20183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 20203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Adds an error from the PTP layer to the error stack. 20213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 20223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void add_ptp_error_to_errorstack(LIBMTP_mtpdevice_t *device, 20233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ptp_error, 20243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const error_text) 20253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 20263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 20273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Trying to add PTP error to a NULL device!\n"); 20283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 20293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 20303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char outstr[256]; 20313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev snprintf(outstr, sizeof(outstr), "PTP Layer error %04x: %s", ptp_error, error_text); 20323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev outstr[sizeof(outstr)-1] = '\0'; 20333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_PTP_LAYER, outstr); 20343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_PTP_LAYER, "(Look this up in ptp.h for an explanation.)"); 20353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 20373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 20393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This returns the error stack for a device in case you 20403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * need to either reference the error numbers (e.g. when 20413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * creating multilingual apps with multiple-language text 20423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * representations for each error number) or when you need 20433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to build a multi-line error text widget or something like 20443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * that. You need to call the <code>LIBMTP_Clear_Errorstack</code> 20453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to clear it when you're finished with it. 20463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to get the error 20473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * stack for. 20483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return the error stack or NULL if there are no errors 20493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on the stack. 20503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Clear_Errorstack() 20513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Dump_Errorstack() 20523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 20533aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_error_t *LIBMTP_Get_Errorstack(LIBMTP_mtpdevice_t *device) 20543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 20553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 20563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Trying to get the error stack of a NULL device!\n"); 20573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 20583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return device->errorstack; 20603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 20613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 20633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function clears the error stack of a device and frees 20643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * any memory used by it. Call this when you're finished with 20653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * using the errors. 20663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to clear the error 20673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * stack for. 20683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 20693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Clear_Errorstack(LIBMTP_mtpdevice_t *device) 20703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 20713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 20723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Trying to clear the error stack of a NULL device!\n"); 20733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 20743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_t *tmp = device->errorstack; 20753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (tmp != NULL) { 20773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_t *tmp2; 20783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (tmp->error_text != NULL) { 20803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(tmp->error_text); 20813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp2 = tmp; 20833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp = tmp->next; 20843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(tmp2); 20853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->errorstack = NULL; 20873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 20883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 20893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 20903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 20913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function dumps the error stack to <code>stderr</code>. 20923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (You still have to clear the stack though.) 20933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to dump the error 20943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * stack for. 20953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 20963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Dump_Errorstack(LIBMTP_mtpdevice_t *device) 20973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 20983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device == NULL) { 20993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "LIBMTP PANIC: Trying to dump the error stack of a NULL device!\n"); 21003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 21013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_error_t *tmp = device->errorstack; 21023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (tmp != NULL) { 21043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (tmp->error_text != NULL) { 21053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "Error %d: %s\n", tmp->errornumber, tmp->error_text); 21063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 21073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr, "Error %d: (unknown)\n", tmp->errornumber); 21083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp = tmp->next; 21103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 21133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Set_Device_Timeout(LIBMTP_mtpdevice_t *device, int milliseconds) 21153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 21163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 21173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_usb_device_timeout(ptp_usb, milliseconds); 21183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 21193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Get_Device_Timeout(LIBMTP_mtpdevice_t *device, int * milliseconds) 21213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 21223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 21233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_usb_device_timeout(ptp_usb, milliseconds); 21243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 21253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 21273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This command gets all handles and stuff by FAST directory retrieveal 21283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * which is available by getting all metadata for object 21293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>0xffffffff</code> which simply means "all metadata for all objects". 21303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This works on the vast majority of MTP devices (there ARE exceptions!) 21313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and is quite quick. Check the error stack to see if there were 21323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * problems getting the metadata. 21333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if all was OK, -1 on failure. 21343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 21353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int get_all_metadata_fast(LIBMTP_mtpdevice_t *device, 21363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t storage) 21373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 21383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 21393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int cnt = 0; 21403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i, j, nrofprops; 21413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t lasthandle = 0xffffffff; 21423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 21433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 21443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 21453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int oldtimeout; 21463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 21473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* The follow request causes the device to generate 21493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * a list of very file on the device and return it 21503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in a single response. 21513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 21523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Some slow devices as well as devices with very 21533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * large file systems can easily take longer then 21543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the standard timeout value before it is able 21553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to return a response. 21563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 21573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Temporarly set timeout to allow working with 21583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * widest range of devices. 21593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 21603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_usb_device_timeout(ptp_usb, &oldtimeout); 21613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_usb_device_timeout(ptp_usb, 60000); 21623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectproplist(params, 0xffffffff, &props, &nrofprops); 21643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_usb_device_timeout(ptp_usb, oldtimeout); 21653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 21663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_MTP_Specification_By_Group_Unsupported) { 21673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // What's the point in the device implementing this command if 21683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // you cannot use it to get all props for AT LEAST one object? 21693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Well, whatever... 21703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_all_metadata_fast(): " 21713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "cannot retrieve all metadata for an object on this device."); 21723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 21733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 21753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_all_metadata_fast(): " 21763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get proplist of all objects."); 21773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 21783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (props == NULL && nrofprops != 0) { 21803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 21813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "get_all_metadata_fast(): " 21823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "call to ptp_mtp_getobjectproplist() returned " 21833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "inconsistent results."); 21843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 21853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 21873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * We count the number of objects by counting the ObjectHandle 21883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * references, whenever it changes we get a new object, when it's 21893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the same, it is just different properties of the same object. 21903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 21913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = props; 21923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<nrofprops;i++) { 21933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (lasthandle != prop->ObjectHandle) { 21943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev cnt++; 21953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev lasthandle = prop->ObjectHandle; 21963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop++; 21983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 21993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev lasthandle = 0xffffffff; 22003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects = calloc (sizeof(PTPObject),cnt); 22013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = props; 22023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev i = -1; 22033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<nrofprops;j++) { 22043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (lasthandle != prop->ObjectHandle) { 22053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (i >= 0) { 22063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].flags |= PTPOBJECT_OBJECTINFO_LOADED; 22073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!params->objects[i].oi.Filename) { 22083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* I have one such file on my Creative (Marcus) */ 22093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.Filename = strdup("<null>"); 22103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev i++; 22133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev lasthandle = prop->ObjectHandle; 22143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oid = prop->ObjectHandle; 22153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (prop->property) { 22173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ParentObject: 22183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.ParentObject = prop->propval.u32; 22193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].flags |= PTPOBJECT_PARENTOBJECT_LOADED; 22203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 22213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectFormat: 22223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.ObjectFormat = prop->propval.u16; 22233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 22243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectSize: 22253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We loose precision here, up to 32 bits! However the commands that 22263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // retrieve metadata for files and tracks will make sure that the 22273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // PTP_OPC_ObjectSize is read in and duplicated again. 22283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 22293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.ObjectCompressedSize = (uint32_t) prop->propval.u64; 22303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 22313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.ObjectCompressedSize = prop->propval.u32; 22323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 22343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_StorageID: 22353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.StorageID = prop->propval.u32; 22363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].flags |= PTPOBJECT_STORAGEID_LOADED; 22373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 22383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectFileName: 22393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 22403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].oi.Filename = strdup(prop->propval.str); 22413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 22423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: { 22433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *newprops; 22443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 22453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Copy all of the other MTP oprierties into the per-object proplist */ 22463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->objects[i].nrofmtpprops) { 22473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newprops = realloc(params->objects[i].mtpprops,(params->objects[i].nrofmtpprops+1)*sizeof(MTPProperties)); 22483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 22493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newprops = calloc(sizeof(MTPProperties),1); 22503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!newprops) return 0; /* FIXME: error handling? */ 22523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].mtpprops = newprops; 22533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy(¶ms->objects[i].mtpprops[params->objects[i].nrofmtpprops],&props[j],sizeof(props[j])); 22543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].nrofmtpprops++; 22553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].flags |= PTPOBJECT_MTPPROPLIST_LOADED; 22563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 22573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop++; 22603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* mark last entry also */ 22623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects[i].flags |= PTPOBJECT_OBJECTINFO_LOADED; 22633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->nrofobjects = i+1; 22643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* The device might not give the list in linear ascending order */ 22653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_objects_sort (params); 22663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 22673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 22683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 22693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 22703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function will recurse through all the directories on the device, 22713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * starting at the root directory, gathering metadata as it moves along. 22723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * It works better on some devices that will only return data for a 22733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * certain directory and does not respect the option to get all metadata 22743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for all objects. 22753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 22763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void get_handles_recursively(LIBMTP_mtpdevice_t *device, 22773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params, 22783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t storageid, 22793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t parent) 22803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 22813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectHandles currentHandles; 22823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i = 0; 22833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret = ptp_getobjecthandles(params, 22843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageid, 22853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_GOH_ALL_FORMATS, 22863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev parent, 22873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ¤tHandles); 22883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 22893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 22903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_handles_recursively(): could not get object handles."); 22913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 22923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 22933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 22943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (currentHandles.Handler == NULL || currentHandles.n == 0) 22953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 22963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 22973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Now descend into any subdirectories found 22983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < currentHandles.n; i++) { 22993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 23003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want(params,currentHandles.Handler[i],PTPOBJECT_OBJECTINFO_LOADED, &ob); 23013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) { 23023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat == PTP_OFC_Association) 23033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_handles_recursively(device, params, storageid, currentHandles.Handler[i]); 23043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 23053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, 23063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_ERROR_CONNECTING, 23073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Found a bad handle, trying to ignore it."); 23083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(currentHandles.Handler); 23113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 23123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23143aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_file_t * obj2file(LIBMTP_mtpdevice_t *device, PTPObject *ob) 23153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 23163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 23173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 23183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *file; 23193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *xob; 23203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 23213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename == NULL) 23243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob->oi.Filename = strdup("<null>"); 23253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Keywords == NULL) 23273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob->oi.Keywords = strdup("<null>"); 23283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new file type 23303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file = LIBMTP_new_file_t(); 23313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->parent_id = ob->oi.ParentObject; 23333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->storage_id = ob->oi.StorageID; 23343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is some sort of unique ID so we can keep track of the track. 23363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->item_id = ob->oid; 23373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set the filetype 23393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = map_ptp_type_to_libmtp_type(ob->oi.ObjectFormat); 23403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set the modification date 23423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->modificationdate = ob->oi.ModificationDate; 23433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Original file-specific properties 23453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We only have 32-bit file size here; if we find it, we use the 23463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // PTP_OPC_ObjectSize property which has 64bit precision. 23473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = ob->oi.ObjectCompressedSize; 23483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename != NULL) { 23493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filename = strdup(ob->oi.Filename); 23503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 23533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * A special quirk for devices that doesn't quite 23543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * remember that some files marked as "unknown" type are 23553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * actually OGG or FLAC files. We look at the filename extension 23563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and see if it happens that this was atleast named "ogg" or "flac" 23573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and fall back on this heuristic approach in that case, 23583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for these bugged devices only. 23593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 23603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (file->filetype == LIBMTP_FILETYPE_UNKNOWN) { 23613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) || 23623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev FLAG_OGG_IS_UNKNOWN(ptp_usb)) && 23633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_ogg_extension(file->filename)) 23643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = LIBMTP_FILETYPE_OGG; 23663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_FLAC_IS_UNKNOWN(ptp_usb) && has_flac_extension(file->filename)) 23683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = LIBMTP_FILETYPE_FLAC; 23693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 23723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If we have a cached, large set of metadata, then use it! 23733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 23743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, ob->oid, PTPOBJECT_MTPPROPLIST_LOADED, &xob); 23753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->mtpprops) { 23763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = ob->mtpprops; 23773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 23783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<ob->nrofmtpprops;i++) { 23803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Pick ObjectSize here... 23813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->property == PTP_OPC_ObjectSize) { 23823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 23833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = prop->propval.u64; 23843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 23853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = prop->propval.u32; 23863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 23883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop++; 23903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 23913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 23923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 23933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 23943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 23953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be retrieved for this object format 23963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, ob->oi.ObjectFormat, &propcnt, &props); 23973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 23983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "obj2file(): call to ptp_mtp_getobjectpropssupported() failed."); 23993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Silently fall through. 24003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 24013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 24023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 24033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 24053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev TODO: (yavor) See what is a sensible thing to do for Folders 24063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat == PTP_OFC_Association) 24073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 24083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (props[i]) { 24093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectSize: 24103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 24113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = get_u64_from_object(device, file->item_id, PTP_OPC_ObjectSize, 0); 24123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 24133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = get_u32_from_object(device, file->item_id, PTP_OPC_ObjectSize, 0); 24143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 24163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 24173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 24183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 24213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return file; 24253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 24263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_file_t * get_files(LIBMTP_mtpdevice_t *device, 24303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params, 24313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t storageid, 24323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t parentId 24333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ) 24343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 24353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i = 0; 24363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *curfile = NULL; 24373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *retfiles = NULL; 24383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectHandles currentHandles; 24393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret = ptp_getobjecthandles(params, 24413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageid, 24423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_GOH_ALL_FORMATS, 24433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev parentId, 24443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ¤tHandles); 24453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 24473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_files(): could not get object handles."); 24483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 24493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (currentHandles.Handler == NULL || currentHandles.n == 0) 24523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 24533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < currentHandles.n; i++) { 24553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 24563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *file; 24573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want(params, currentHandles.Handler[i],PTPOBJECT_OBJECTINFO_LOADED, &ob); 24593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) 24603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 24613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file = obj2file(device, ob); 24633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (file == NULL) 24653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 24663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add track to a list that will be returned afterwards. 24683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (curfile == NULL) { 24693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curfile = file; 24703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retfiles = file; 24713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 24723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curfile->next = file; 24733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curfile = file; 24743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 24763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(currentHandles.Handler); 24783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Return a pointer to the original first file 24803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // in the big list. 24813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retfiles; 24823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 24833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 24853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function controls the usage of the internal object cache. 24863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The default configuration loads all object handles on initialization. 24873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * In order to handle large number of files turn on the on demand 24883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * loading by calling this function with parameter 1, and use 24893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_Get_Files_And_Folders() to load content when needed. 24903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 24913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param flag - 0 means turn off on demand loading. 24923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * - 1 means turn on on demand loading. 24933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 24943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Set_Load_Cache_On_Demand(int flag) 24953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 24963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev load_cache_on_demand = flag; 24973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 24983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 24993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 25003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves the content of a folder with id - parentId. 25013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The result contains both files and folders. 25023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * NOTE: the request will always perform I/O with the device. 25033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to report info from. 25043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @storageId the id for the storage. 25053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param parentId the parent folder id. 25063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 25073aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_file_t * LIBMTP_Get_Files_And_Folders(LIBMTP_mtpdevice_t *device, uint32_t storageId, uint32_t parentId) 25083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 25093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *retfiles = NULL; 25103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 25113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 25123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 25133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 25143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#if 0 25163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev //TODO: (yavor) Try to use get_all_metadata_fast for a parendId. 25173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList) 25183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev && !FLAG_BROKEN_MTPGETOBJPROPLIST(ptp_usb) 25193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev && !FLAG_BROKEN_MTPGETOBJPROPLIST_ALL(ptp_usb)) { 25203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Use the fast method. Ignore return value for now. 25213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = get_all_metadata_fast(device, PTP_GOH_ALL_STORAGE); 25223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 25243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retfiles = get_files(device, params, storageId, parentId); 25273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retfiles; 25293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 25303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 25323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function refresh the internal handle list whenever 25333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the items stored inside the device is altered. On operations 25343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * that do not add or remove objects, this is typically not 25353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * called. 25363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to flush handles for. 25373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 25383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void flush_handles(LIBMTP_mtpdevice_t *device) 25393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 25403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 25413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 25423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 25433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 25443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (load_cache_on_demand) { 25463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 25473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->objects != NULL) { 25503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<params->nrofobjects;i++) 25513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_object (¶ms->objects[i]); 25523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(params->objects); 25533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->objects = NULL; 25543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->nrofobjects = 0; 25553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjPropList) 25583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev && !FLAG_BROKEN_MTPGETOBJPROPLIST(ptp_usb) 25593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev && !FLAG_BROKEN_MTPGETOBJPROPLIST_ALL(ptp_usb)) { 25603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Use the fast method. Ignore return value for now. 25613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = get_all_metadata_fast(device, PTP_GOH_ALL_STORAGE); 25623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // If the previous failed or returned no objects, use classic 25653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // methods instead. 25663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 25673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles using just standard commands. 25683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage == NULL) { 25693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_handles_recursively(device, params, 25703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_GOH_ALL_STORAGE, 25713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_GOH_ROOT_PARENT); 25723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 25733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get handles for each storage in turn. 25743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage = device->storage; 25753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(storage != NULL) { 25763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_handles_recursively(device, params, 25773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->id, 25783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_GOH_ROOT_PARENT); 25793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 25803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 25853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Loop over the handles, fix up any NULL filenames or 25863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * keywords, then attempt to locate some default folders 25873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in the root directory of the primary storage. 25883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 25893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(i = 0; i < params->nrofobjects; i++) { 25903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob, *xob; 25913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 25923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob = ¶ms->objects[i]; 25933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want(params,params->objects[i].oid,PTPOBJECT_OBJECTINFO_LOADED, &xob); 25943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 25953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fprintf(stderr,"broken! %x not found\n", params->objects[i].oid); 25963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 25973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename == NULL) 25983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob->oi.Filename = strdup("<null>"); 25993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Keywords == NULL) 26003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob->oi.Keywords = strdup("<null>"); 26013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Ignore handles that point to non-folders */ 26033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(ob->oi.ObjectFormat != PTP_OFC_Association) 26043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 26053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Only look in the root folder */ 26063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ParentObject != 0x00000000U) 26073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 26083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Only look in the primary storage */ 26093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage != NULL && ob->oi.StorageID != device->storage->id) 26103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 26113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Is this the Music Folder */ 26143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!strcasecmp(ob->oi.Filename, "My Music") || 26153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Music")) { 26163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_music_folder = ob->oid; 26173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "My Playlists") || 26193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Playlists")) { 26203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_playlist_folder = ob->oid; 26213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "My Pictures") || 26233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Pictures")) { 26243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_picture_folder = ob->oid; 26253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "My Video") || 26273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Video")) { 26283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_video_folder = ob->oid; 26293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "My Organizer")) { 26313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_organizer_folder = ob->oid; 26323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "ZENcast") || 26343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Datacasts")) { 26353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_zencast_folder = ob->oid; 26363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "My Albums") || 26383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Albums")) { 26393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_album_folder = ob->oid; 26403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (!strcasecmp(ob->oi.Filename, "Text") || 26423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !strcasecmp(ob->oi.Filename, "Texts")) { 26433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->default_text_folder = ob->oid; 26443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 26473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 26493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function traverses a devices storage list freeing up the 26503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings and the structs. 26513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to free the storage 26523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list for. 26533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 26543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void free_storage_list(LIBMTP_mtpdevice_t *device) 26553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 26563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage; 26573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *tmp; 26583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = device->storage; 26603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(storage != NULL) { 26613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage->StorageDescription != NULL) { 26623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(storage->StorageDescription); 26633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage->VolumeIdentifier != NULL) { 26653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(storage->VolumeIdentifier); 26663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp = storage; 26683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 26693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(tmp); 26703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 26713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->storage = NULL; 26723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 26743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 26753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 26773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function traverses a devices storage list freeing up the 26783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings and the structs. 26793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to free the storage 26803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list for. 26813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 26823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int sort_storage_by(LIBMTP_mtpdevice_t *device,int const sortby) 26833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 26843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *oldhead, *ptr1, *ptr2, *newlist; 26853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage == NULL) 26873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 26883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (sortby == LIBMTP_STORAGE_SORTBY_NOTSORTED) 26893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 26903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oldhead = ptr1 = ptr2 = device->storage; 26923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist = NULL; 26943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(oldhead != NULL) { 26963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1 = ptr2 = oldhead; 26973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(ptr1 != NULL) { 26983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 26993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (sortby == LIBMTP_STORAGE_SORTBY_FREESPACE && ptr1->FreeSpaceInBytes > ptr2->FreeSpaceInBytes) 27003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr2 = ptr1; 27013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (sortby == LIBMTP_STORAGE_SORTBY_MAXSPACE && ptr1->FreeSpaceInBytes > ptr2->FreeSpaceInBytes) 27023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr2 = ptr1; 27033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1 = ptr1->next; 27053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Make our previous entries next point to our next 27083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(ptr2->prev != NULL) { 27093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1 = ptr2->prev; 27103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1->next = ptr2->next; 27113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 27123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oldhead = ptr2->next; 27133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(oldhead != NULL) 27143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oldhead->prev = NULL; 27153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Make our next entries previous point to our previous 27183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1 = ptr2->next; 27193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(ptr1 != NULL) { 27203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1->prev = ptr2->prev; 27213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 27223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1 = ptr2->prev; 27233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(ptr1 != NULL) 27243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr1->next = NULL; 27253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(newlist == NULL) { 27283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist = ptr2; 27293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist->prev = NULL; 27303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 27313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptr2->prev = newlist; 27323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist->next = ptr2; 27333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist = newlist->next; 27343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (newlist != NULL) { 27383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist->next = NULL; 27393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(newlist->prev != NULL) 27403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newlist = newlist->prev; 27413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->storage = newlist; 27423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 27453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 27463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 27483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function grabs the first writeable storageid from the 27493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * device storage list. 27503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to locate writeable 27513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * storage for. 27523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param fitsize a file of this file must fit on the device. 27533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 27543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint32_t get_writeable_storageid(LIBMTP_mtpdevice_t *device, uint64_t fitsize) 27553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 27563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage; 27573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t store = 0x00000000; //Should this be 0xffffffffu instead? 27583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int subcall_ret; 27593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 27603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // See if there is some storage we can fit this file on. 27613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = device->storage; 27623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage == NULL) { 27633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Sometimes the storage just cannot be detected. 27643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = 0x00000000U; 27653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 27663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(storage != NULL) { 27673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // These storages cannot be used. 27683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage->StorageType == PTP_ST_FixedROM || storage->StorageType == PTP_ST_RemovableROM) { 27693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 27703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 27713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Storage IDs with the lower 16 bits 0x0000 are not supposed 27733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // to be writeable. 27743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((storage->id & 0x0000FFFFU) == 0x00000000U) { 27753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 27763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 27773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Also check the access capability to avoid e.g. deletable only storages 27793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage->AccessCapability == PTP_AC_ReadOnly || storage->AccessCapability == PTP_AC_ReadOnly_with_Object_Deletion) { 27803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 27813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 27823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Then see if we can fit the file. 27843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev subcall_ret = check_if_file_fits(device, storage, fitsize); 27853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (subcall_ret != 0) { 27863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 27873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 27883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We found a storage that is writable and can fit the file! 27893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 27903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage == NULL) { 27933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_STORAGE_FULL, "LIBMTP_Send_File_From_File_Descriptor(): " 27943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "all device storage is full or corrupt."); 27953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 27963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = storage->id; 27983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 27993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return store; 28013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 28023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 28043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function grabs the freespace from a certain storage in 28053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * device storage list. 28063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to free the storage 28073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list for. 28083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param storageid the storage ID for the storage to flush and 28093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * get free space for. 28103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param freespace the free space on this storage will be returned 28113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in this variable. 28123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 28133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int get_storage_freespace(LIBMTP_mtpdevice_t *device, 28143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage, 28153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint64_t *freespace) 28163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 28173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 28183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Always query the device about this, since some models explicitly 28203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // needs that. We flush all data on queries storage here. 28213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params,PTP_OC_GetStorageInfo)) { 28223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPStorageInfo storageInfo; 28233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 28243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getstorageinfo(params, storage->id, &storageInfo); 28263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 28273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_first_storage_freespace(): could not get storage info."); 28283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 28293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage->StorageDescription != NULL) { 28313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(storage->StorageDescription); 28323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage->VolumeIdentifier != NULL) { 28343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(storage->VolumeIdentifier); 28353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->StorageType = storageInfo.StorageType; 28373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FilesystemType = storageInfo.FilesystemType; 28383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->AccessCapability = storageInfo.AccessCapability; 28393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->MaxCapacity = storageInfo.MaxCapability; 28403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FreeSpaceInBytes = storageInfo.FreeSpaceInBytes; 28413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FreeSpaceInObjects = storageInfo.FreeSpaceInImages; 28423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->StorageDescription = storageInfo.StorageDescription; 28433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->VolumeIdentifier = storageInfo.VolumeLabel; 28443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(storage->FreeSpaceInBytes == (uint64_t) -1) 28463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 28473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *freespace = storage->FreeSpaceInBytes; 28483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 28493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 28503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 28523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function dumps out a large chunk of textual information 28533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * provided from the PTP protocol and additionally some extra 28543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP-specific information where applicable. 28553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the MTP device to report info from. 28563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 28573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_Dump_Device_Info(LIBMTP_mtpdevice_t *device) 28583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 28593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 28603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 28613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 28623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage = device->storage; 28633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("USB low-level info:\n"); 28653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dump_usbinfo(ptp_usb); 28663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Print out some verbose information */ 28673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Device info:\n"); 28683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Manufacturer: %s\n", params->deviceinfo.Manufacturer); 28693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Model: %s\n", params->deviceinfo.Model); 28703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Device version: %s\n", params->deviceinfo.DeviceVersion); 28713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Serial number: %s\n", params->deviceinfo.SerialNumber); 28723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Vendor extension ID: 0x%08x\n", params->deviceinfo.VendorExtensionID); 28733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Vendor extension description: %s\n", params->deviceinfo.VendorExtensionDesc); 28743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Detected object size: %d bits\n", device->object_bitsize); 28753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Supported operations:\n"); 28763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<params->deviceinfo.OperationsSupported_len;i++) { 28773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char txt[256]; 28783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (void) ptp_render_opcode (params, params->deviceinfo.OperationsSupported[i], sizeof(txt), txt); 28803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" %04x: %s\n", params->deviceinfo.OperationsSupported[i], txt); 28813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Events supported:\n"); 28833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.EventsSupported_len == 0) { 28843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" None.\n"); 28853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 28863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<params->deviceinfo.EventsSupported_len;i++) { 28873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" 0x%04x\n", params->deviceinfo.EventsSupported[i]); 28883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 28903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Device Properties Supported:\n"); 28913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<params->deviceinfo.DevicePropertiesSupported_len;i++) { 28923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const *propdesc = ptp_get_property_description(params, params->deviceinfo.DevicePropertiesSupported[i]); 28933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 28943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (propdesc != NULL) { 28953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" 0x%04x: %s\n", params->deviceinfo.DevicePropertiesSupported[i], propdesc); 28963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 28973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t prop = params->deviceinfo.DevicePropertiesSupported[i]; 28983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" 0x%04x: Unknown property\n", prop); 28993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params,PTP_OC_MTP_GetObjectPropsSupported)) { 29033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Playable File (Object) Types and Object Properties Supported:\n"); 29043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<params->deviceinfo.ImageFormats_len;i++) { 29053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char txt[256]; 29063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 29073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 29083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 29093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int j; 29103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (void) ptp_render_ofc (params, params->deviceinfo.ImageFormats[i], sizeof(txt), txt); 29123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" %04x: %s\n", params->deviceinfo.ImageFormats[i], txt); 29133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported (params, params->deviceinfo.ImageFormats[i], &propcnt, &props); 29153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 29163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Dump_Device_Info(): error on query for object properties."); 29173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 29183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<propcnt;j++) { 29193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 29203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int k; 29213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" %04x: %s", props[j], LIBMTP_Get_Property_Description(map_ptp_property_to_libmtp_property(props[j]))); 29233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get a more verbose description 29243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, props[j], params->deviceinfo.ImageFormats[i], &opd); 29253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 29263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Dump_Device_Info(): " 29273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 29283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd.DataType == PTP_DTC_STR) { 29323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" STRING data type"); 29333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 29343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_DateTime: 29353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" DATETIME FORM"); 29363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_RegularExpression: 29383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" REGULAR EXPRESSION FORM"); 29393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_LongString: 29413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" LONG STRING FORM"); 29423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 29443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 29473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd.DataType & PTP_DTC_ARRAY_MASK) { 29483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" array of"); 29493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.DataType & (~PTP_DTC_ARRAY_MASK)) { 29523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UNDEF: 29543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UNDEFINED data type"); 29553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT8: 29583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" INT8 data type"); 29593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 29603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 29613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" range: MIN %d, MAX %d, STEP %d", 29623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MinimumValue.i8, 29633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MaximumValue.i8, 29643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.StepSize.i8); 29653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: 29673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration: "); 29683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 29693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("%d, ", opd.FORM.Enum.SupportedValue[k].i8); 29703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_ByteArray: 29733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" byte array: "); 29743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 29763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" ANY 8BIT VALUE form"); 29773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 29813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 29823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UINT8 data type"); 29833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 29843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 29853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" range: MIN %d, MAX %d, STEP %d", 29863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MinimumValue.u8, 29873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MaximumValue.u8, 29883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.StepSize.u8); 29893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: 29913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration: "); 29923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 29933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("%d, ", opd.FORM.Enum.SupportedValue[k].u8); 29943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 29953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_ByteArray: 29973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" byte array: "); 29983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 29993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 30003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" ANY 8BIT VALUE form"); 30013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 30053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: 30063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" INT16 data type"); 30073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 30083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 30093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" range: MIN %d, MAX %d, STEP %d", 30103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MinimumValue.i16, 30113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MaximumValue.i16, 30123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.StepSize.i16); 30133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: 30153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration: "); 30163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 30173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("%d, ", opd.FORM.Enum.SupportedValue[k].i16); 30183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 30213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" ANY 16BIT VALUE form"); 30223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 30263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 30273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UINT16 data type"); 30283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 30293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 30303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" range: MIN %d, MAX %d, STEP %d", 30313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MinimumValue.u16, 30323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MaximumValue.u16, 30333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.StepSize.u16); 30343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: 30363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration: "); 30373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 30383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("%d, ", opd.FORM.Enum.SupportedValue[k].u16); 30393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 30423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" ANY 16BIT VALUE form"); 30433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 30473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT32: 30483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" INT32 data type"); 30493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 30503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 30513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" range: MIN %d, MAX %d, STEP %d", 30523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MinimumValue.i32, 30533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MaximumValue.i32, 30543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.StepSize.i32); 30553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: 30573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration: "); 30583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 30593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("%d, ", opd.FORM.Enum.SupportedValue[k].i32); 30603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 30633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" ANY 32BIT VALUE form"); 30643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 30683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 30693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UINT32 data type"); 30703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd.FormFlag) { 30713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 30723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" range: MIN %d, MAX %d, STEP %d", 30733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MinimumValue.u32, 30743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.MaximumValue.u32, 30753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd.FORM.Range.StepSize.u32); 30763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 30773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: 30783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Special pretty-print for FOURCC codes 30793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.ImageFormats[i] == PTP_OPC_VideoFourCCCodec) { 30803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration of u32 casted FOURCC: "); 30813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 30823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd.FORM.Enum.SupportedValue[k].u32 == 0) { 30833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("ANY, "); 30843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 30853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char fourcc[6]; 30863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fourcc[0] = (opd.FORM.Enum.SupportedValue[k].u32 >> 24) & 0xFFU; 30873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fourcc[1] = (opd.FORM.Enum.SupportedValue[k].u32 >> 16) & 0xFFU; 30883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fourcc[2] = (opd.FORM.Enum.SupportedValue[k].u32 >> 8) & 0xFFU; 30893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fourcc[3] = opd.FORM.Enum.SupportedValue[k].u32 & 0xFFU; 30903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fourcc[4] = '\n'; 30913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fourcc[5] = '\0'; 30923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("\"%s\", ", fourcc); 30933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 30953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 30963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" enumeration: "); 30973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(k=0;k<opd.FORM.Enum.NumberOfValues;k++) { 30983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("%d, ", opd.FORM.Enum.SupportedValue[k].u32); 30993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 31033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" ANY 32BIT VALUE form"); 31043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 31083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT64: 31093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" INT64 data type"); 31103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 31123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT64: 31133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UINT64 data type"); 31143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 31163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT128: 31173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" INT128 data type"); 31183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 31203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT128: 31213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UINT128 data type"); 31223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 31243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 31253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" UNKNOWN data type"); 31263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (opd.GetSet) { 31303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" GET/SET"); 31313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 31323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" READ ONLY"); 31333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("\n"); 31353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 31363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 31383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 31423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(storage != NULL && ptp_operation_issupported(params,PTP_OC_GetStorageInfo)) { 31433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Storage Devices:\n"); 31443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(storage != NULL) { 31453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" StorageID: 0x%08x\n",storage->id); 31463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" StorageType: 0x%04x ",storage->StorageType); 31473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (storage->StorageType) { 31483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_ST_Undefined: 31493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("(undefined)\n"); 31503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_ST_FixedROM: 31523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("fixed ROM storage\n"); 31533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_ST_RemovableROM: 31553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("removable ROM storage\n"); 31563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_ST_FixedRAM: 31583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("fixed RAM storage\n"); 31593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_ST_RemovableRAM: 31613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("removable RAM storage\n"); 31623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 31643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("UNKNOWN storage\n"); 31653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" FilesystemType: 0x%04x ",storage->FilesystemType); 31683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch(storage->FilesystemType) { 31693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_FST_Undefined: 31703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("(undefined)\n"); 31713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_FST_GenericFlat: 31733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("generic flat filesystem\n"); 31743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_FST_GenericHierarchical: 31763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("generic hierarchical\n"); 31773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_FST_DCF: 31793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("DCF\n"); 31803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 31823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("UNKNONWN filesystem type\n"); 31833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 31853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" AccessCapability: 0x%04x ",storage->AccessCapability); 31863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch(storage->AccessCapability) { 31873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_AC_ReadWrite: 31883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("read/write\n"); 31893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_AC_ReadOnly: 31913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("read only\n"); 31923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_AC_ReadOnly_with_Object_Deletion: 31943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("read only + object deletion\n"); 31953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 31973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("UNKNOWN access capability\n"); 31983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 31993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" MaxCapacity: %llu\n", (long long unsigned int) storage->MaxCapacity); 32013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" FreeSpaceInBytes: %llu\n", (long long unsigned int) storage->FreeSpaceInBytes); 32023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" FreeSpaceInObjects: %llu\n", (long long unsigned int) storage->FreeSpaceInObjects); 32033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" StorageDescription: %s\n",storage->StorageDescription); 32043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" VolumeIdentifier: %s\n",storage->VolumeIdentifier); 32053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = storage->next; 32063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Special directories:\n"); 32103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default music folder: 0x%08x\n", device->default_music_folder); 32113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default playlist folder: 0x%08x\n", device->default_playlist_folder); 32123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default picture folder: 0x%08x\n", device->default_picture_folder); 32133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default video folder: 0x%08x\n", device->default_video_folder); 32143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default organizer folder: 0x%08x\n", device->default_organizer_folder); 32153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default zencast folder: 0x%08x\n", device->default_zencast_folder); 32163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default album folder: 0x%08x\n", device->default_album_folder); 32173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf(" Default text folder: 0x%08x\n", device->default_text_folder); 32183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 32193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 32213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This resets a device in case it supports the <code>PTP_OC_ResetDevice</code> 32223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation code (0x1010). 32233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to reset. 32243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 32253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 32263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Reset_Device(LIBMTP_mtpdevice_t *device) 32273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 32283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 32293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 32303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_ResetDevice)) { 32323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 32333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Reset_Device(): device does not support resetting."); 32343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 32353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_resetdevice(params); 32373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 32383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "Error resetting."); 32393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 32403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 32423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 32433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 32453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This retrieves the manufacturer name of an MTP device. 32463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the manufacturer name for. 32473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated UTF-8 string representing the manufacturer name. 32483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The string must be freed by the caller after use. If the call 32493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * was unsuccessful this will contain NULL. 32503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 32513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_Manufacturername(LIBMTP_mtpdevice_t *device) 32523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 32533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retmanuf = NULL; 32543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 32553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.Manufacturer != NULL) { 32573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retmanuf = strdup(params->deviceinfo.Manufacturer); 32583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retmanuf; 32603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 32613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 32633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This retrieves the model name (often equal to product name) 32643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * of an MTP device. 32653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the model name for. 32663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated UTF-8 string representing the model name. 32673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The string must be freed by the caller after use. If the call 32683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * was unsuccessful this will contain NULL. 32693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 32703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_Modelname(LIBMTP_mtpdevice_t *device) 32713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 32723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retmodel = NULL; 32733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 32743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.Model != NULL) { 32763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retmodel = strdup(params->deviceinfo.Model); 32773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retmodel; 32793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 32803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 32823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This retrieves the serial number of an MTP device. 32833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the serial number for. 32843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated UTF-8 string representing the serial number. 32853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The string must be freed by the caller after use. If the call 32863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * was unsuccessful this will contain NULL. 32873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 32883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_Serialnumber(LIBMTP_mtpdevice_t *device) 32893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 32903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retnumber = NULL; 32913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 32923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.SerialNumber != NULL) { 32943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retnumber = strdup(params->deviceinfo.SerialNumber); 32953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 32963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retnumber; 32973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 32983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 32993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 33003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This retrieves the device version (hardware and firmware version) of an 33013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP device. 33023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the device version for. 33033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated UTF-8 string representing the device version. 33043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The string must be freed by the caller after use. If the call 33053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * was unsuccessful this will contain NULL. 33063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 33073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_Deviceversion(LIBMTP_mtpdevice_t *device) 33083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 33093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retversion = NULL; 33103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 33113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.DeviceVersion != NULL) { 33133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retversion = strdup(params->deviceinfo.DeviceVersion); 33143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 33153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retversion; 33163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 33173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 33203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This retrieves the "friendly name" of an MTP device. Usually 33213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this is simply the name of the owner or something like 33223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * "John Doe's Digital Audio Player". This property should be supported 33233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * by all MTP devices. 33243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the friendly name for. 33253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated UTF-8 string representing the friendly name. 33263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The string must be freed by the caller after use. 33273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_Friendlyname() 33283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 33293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_Friendlyname(LIBMTP_mtpdevice_t *device) 33303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 33313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 33323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retstring = NULL; 33333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 33343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 33353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_property_issupported(params, PTP_DPC_MTP_DeviceFriendlyName)) { 33373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 33383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 33393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getdevicepropvalue(params, 33413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DPC_MTP_DeviceFriendlyName, 33423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 33433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_STR); 33443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 33453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "Error getting friendlyname."); 33463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 33473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 33483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (propval.str != NULL) { 33493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retstring = strdup(propval.str); 33503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.str); 33513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 33523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retstring; 33533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 33543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 33563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets the "friendly name" of an MTP device. 33573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to set the friendly name for. 33583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param friendlyname the new friendly name for the device. 33593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 33603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Friendlyname() 33613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 33623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Friendlyname(LIBMTP_mtpdevice_t *device, 33633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const friendlyname) 33643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 33653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 33663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 33673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 33683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_property_issupported(params, PTP_DPC_MTP_DeviceFriendlyName)) { 33703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 33713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 33723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.str = (char *) friendlyname; 33733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_setdevicepropvalue(params, 33743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DPC_MTP_DeviceFriendlyName, 33753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 33763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_STR); 33773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 33783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "Error setting friendlyname."); 33793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 33803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 33813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 33823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 33833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 33853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This retrieves the syncronization partner of an MTP device. This 33863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * property should be supported by all MTP devices. 33873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the sync partner for. 33883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a newly allocated UTF-8 string representing the synchronization 33893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * partner. The string must be freed by the caller after use. 33903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_Syncpartner() 33913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 33923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevchar *LIBMTP_Get_Syncpartner(LIBMTP_mtpdevice_t *device) 33933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 33943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 33953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *retstring = NULL; 33963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 33973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 33983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_property_issupported(params, PTP_DPC_MTP_SynchronizationPartner)) { 34003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 34013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getdevicepropvalue(params, 34043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DPC_MTP_SynchronizationPartner, 34053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 34063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_STR); 34073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 34083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "Error getting syncpartner."); 34093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 34103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (propval.str != NULL) { 34123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retstring = strdup(propval.str); 34133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.str); 34143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retstring; 34163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 34173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 34203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Sets the synchronization partner of an MTP device. Note that 34213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * we have no idea what the effect of setting this to "foobar" 34223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * may be. But the general idea seems to be to tell which program 34233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * shall synchronize with this device and tell others to leave 34243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * it alone. 34253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to set the sync partner for. 34263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param syncpartner the new synchronization partner for the device. 34273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 34283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Syncpartner() 34293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 34303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Syncpartner(LIBMTP_mtpdevice_t *device, 34313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const syncpartner) 34323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 34333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 34343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 34353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 34363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_property_issupported(params, PTP_DPC_MTP_SynchronizationPartner)) { 34383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 34393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.str = (char *) syncpartner; 34413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_setdevicepropvalue(params, 34423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DPC_MTP_SynchronizationPartner, 34433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 34443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_STR); 34453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 34463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "Error setting syncpartner."); 34473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 34483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 34503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 34513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 34533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Checks if the device can stora a file of this size or 34543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * if it's too big. 34553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device. 34563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filesize the size of the file to check whether it will fit. 34573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param storageid the ID of the storage to try to fit the file on. 34583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the file fits, any other value means failure. 34593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 34603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int check_if_file_fits(LIBMTP_mtpdevice_t *device, 34613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage, 34623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint64_t const filesize) { 34633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 34643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint64_t freebytes; 34653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 34663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // If we cannot check the storage, no big deal. 34683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_GetStorageInfo)) { 34693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 34703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = get_storage_freespace(device, storage, &freebytes); 34733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 34743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 34753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "check_if_file_fits(): error checking free storage."); 34763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 34773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 34783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // See if it fits. 34793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (filesize > freebytes) { 34803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 34813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 34833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 34843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 34853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 34873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 34883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves the current battery level on the device. 34893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the battery level for. 34903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param maximum_level a pointer to a variable that will hold the 34913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * maximum level of the battery if the call was successful. 34923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param current_level a pointer to a variable that will hold the 34933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * current level of the battery if the call was successful. 34943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * A value of 0 means that the device is on external power. 34953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the storage info was successfully retrieved, any other 34963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * means failure. A typical cause of failure is that 34973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device does not support the battery level property. 34983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 34993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Batterylevel(LIBMTP_mtpdevice_t *device, 35003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t * const maximum_level, 35013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t * const current_level) 35023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 35033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 35043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 35053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 35063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 35073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *maximum_level = 0; 35093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *current_level = 0; 35103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_BROKEN_BATTERY_LEVEL(ptp_usb) || 35123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !ptp_property_issupported(params, PTP_DPC_BatteryLevel)) { 35133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 35143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getdevicepropvalue(params, PTP_DPC_BatteryLevel, &propval, PTP_DTC_UINT8); 35173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 35183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Batterylevel(): could not get device property value."); 35193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 35203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *maximum_level = device->maximum_battery_level; 35233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *current_level = propval.u8; 35243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 35263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 35273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 35303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Formats device storage (if the device supports the operation). 35313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * WARNING: This WILL delete all data from the device. Make sure you've 35323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * got confirmation from the user BEFORE you call this function. 35333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 35343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device containing the storage to format. 35353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param storage the actual storage to format. 35363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 35373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 35383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Format_Storage(LIBMTP_mtpdevice_t *device, LIBMTP_devicestorage_t *storage) 35393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 35403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 35413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 35423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_FormatStore)) { 35443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 35453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Format_Storage(): device does not support formatting storage."); 35463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 35473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_formatstore(params, storage->id); 35493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 35503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Format_Storage(): failed to format storage."); 35513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 35523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 35543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 35553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 35573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Helper function to extract a unicode property off a device. 35583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This is the standard way of retrieveing unicode device 35593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * properties as described by the PTP spec. 35603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the property from. 35613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param unicstring a pointer to a pointer that will hold the 35623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * property after this call is completed. 35633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param property the property to retrieve. 35643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 35653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 35663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int get_device_unicode_property(LIBMTP_mtpdevice_t *device, 35673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char **unicstring, uint16_t property) 35683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 35693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 35703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 35713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *tmp; 35723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 35733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 35743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_property_issupported(params, property)) { 35763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 35773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Unicode strings are 16bit unsigned integer arrays. 35803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getdevicepropvalue(params, 35813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev property, 35823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval, 35833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_DTC_AUINT16); 35843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 35853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: add a note on WHICH property that we failed to get. 35863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *unicstring = NULL; 35873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_device_unicode_property(): failed to get unicode property."); 35883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 35893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 35913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Extract the actual array. 35923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // printf("Array of %d elements\n", propval.a.count); 35933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp = malloc((propval.a.count + 1)*sizeof(uint16_t)); 35943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < propval.a.count; i++) { 35953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[i] = propval.a.v[i].u16; 35963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // printf("%04x ", tmp[i]); 35973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 35983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[propval.a.count] = 0x0000U; 35993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.a.v); 36003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *unicstring = utf16_to_utf8(device, tmp); 36023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(tmp); 36043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 36063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 36073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 36093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function returns the secure time as an XML document string from 36103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device. 36113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the secure time for. 36123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param sectime the secure time string as an XML document or NULL if the call 36133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failed or the secure time property is not supported. This string 36143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * must be <code>free()</code>:ed by the caller after use. 36153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 36163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 36173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Secure_Time(LIBMTP_mtpdevice_t *device, char ** const sectime) 36183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 36193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_device_unicode_property(device, sectime, PTP_DPC_MTP_SecureTime); 36203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 36213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 36233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function returns the device (public key) certificate as an 36243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * XML document string from the device. 36253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the device certificate for. 36263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param devcert the device certificate as an XML string or NULL if the call 36273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failed or the device certificate property is not supported. This 36283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * string must be <code>free()</code>:ed by the caller after use. 36293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 36303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 36313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Device_Certificate(LIBMTP_mtpdevice_t *device, char ** const devcert) 36323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 36333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return get_device_unicode_property(device, devcert, PTP_DPC_MTP_DeviceCertificate); 36343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 36353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 36373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves a list of supported file types, i.e. the file 36383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * types that this device claims it supports, e.g. audio file types that 36393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device can play etc. This list is mitigated to 36403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * inlcude the file types that libmtp can handle, i.e. it will not list 36413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * filetypes that libmtp will handle internally like playlists and folders. 36423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the filetype capabilities for. 36433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filetypes a pointer to a pointer that will hold the list of 36443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supported filetypes if the call was successful. This list must 36453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * be <code>free()</code>:ed by the caller after use. 36463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param length a pointer to a variable that will hold the length of the 36473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list of supported filetypes if the call was successful. 36483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 36493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Filetype_Description() 36503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 36513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Supported_Filetypes(LIBMTP_mtpdevice_t *device, uint16_t ** const filetypes, 36523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t * const length) 36533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 36543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 36553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 36563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *localtypes; 36573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t localtypelen; 36583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 36593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is more memory than needed if there are unknown types, but what the heck. 36613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypes = (uint16_t *) malloc(params->deviceinfo.ImageFormats_len * sizeof(uint16_t)); 36623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypelen = 0; 36633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<params->deviceinfo.ImageFormats_len;i++) { 36653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t localtype = map_ptp_type_to_libmtp_type(params->deviceinfo.ImageFormats[i]); 36663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (localtype != LIBMTP_FILETYPE_UNKNOWN) { 36673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypes[localtypelen] = localtype; 36683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypelen++; 36693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 36703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 36713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // The forgotten Ogg support on YP-10 and others... 36723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_OGG_IS_UNKNOWN(ptp_usb)) { 36733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypes = (uint16_t *) realloc(localtypes, (params->deviceinfo.ImageFormats_len+1) * sizeof(uint16_t)); 36743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypes[localtypelen] = LIBMTP_FILETYPE_OGG; 36753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypelen++; 36763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 36773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // The forgotten FLAC support on Cowon iAudio S9 and others... 36783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_FLAC_IS_UNKNOWN(ptp_usb)) { 36793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypes = (uint16_t *) realloc(localtypes, (params->deviceinfo.ImageFormats_len+1) * sizeof(uint16_t)); 36803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypes[localtypelen] = LIBMTP_FILETYPE_FLAC; 36813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localtypelen++; 36823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 36833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *filetypes = localtypes; 36853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *length = localtypelen; 36863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 36883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 36893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 36903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 36913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function updates all the storage id's of a device and their 36923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * properties, then creates a linked list and puts the list head into 36933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device struct. It also optionally sorts this list. If you want 36943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to display storage information in your application you should call 36953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this function, then dereference the device struct 36963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (<code>device->storage</code>) to get out information on the storage. 36973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 36983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * You need to call this everytime you want to update the 36993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>device->storage</code> list, for example anytime you need 37003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to check available storage somewhere. 37013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 37023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <b>WARNING:</b> since this list is dynamically updated, do not 37033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * reference its fields in external applications by pointer! E.g 37043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * do not put a reference to any <code>char *</code> field. instead 37053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>strncpy()</code> it! 37063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 37073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the storage for. 37083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param sortby an integer that determines the sorting of the storage list. 37093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Valid sort methods are defined in libmtp.h with beginning with 37103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_STORAGE_SORTBY_. 0 or LIBMTP_STORAGE_SORTBY_NOTSORTED to not 37113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * sort. 37123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, 1 success but only with storage id's, storage 37133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * properities could not be retrieved and -1 means failure. 37143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 37153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Storage(LIBMTP_mtpdevice_t *device, int const sortby) 37163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 37173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i = 0; 37183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPStorageInfo storageInfo; 37193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 37203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPStorageIDs storageIDs; 37213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage = NULL; 37223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storageprev = NULL; 37233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage != NULL) 37253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free_storage_list(device); 37263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // if (!ptp_operation_issupported(params,PTP_OC_GetStorageIDs)) 37283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // return -1; 37293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_getstorageids (params, &storageIDs) != PTP_RC_OK) 37303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 37313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storageIDs.n < 1) 37323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 37333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ptp_operation_issupported(params,PTP_OC_GetStorageInfo)) { 37353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < storageIDs.n; i++) { 37363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = (LIBMTP_devicestorage_t *) malloc(sizeof(LIBMTP_devicestorage_t)); 37383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->prev = storageprev; 37393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storageprev != NULL) 37403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageprev->next = storage; 37413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage == NULL) 37423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->storage = storage; 37433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->id = storageIDs.Storage[i]; 37453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->StorageType = PTP_ST_Undefined; 37463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FilesystemType = PTP_FST_Undefined; 37473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->AccessCapability = PTP_AC_ReadWrite; 37483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->MaxCapacity = (uint64_t) -1; 37493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FreeSpaceInBytes = (uint64_t) -1; 37503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FreeSpaceInObjects = (uint64_t) -1; 37513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->StorageDescription = strdup("Unknown storage"); 37523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->VolumeIdentifier = strdup("Unknown volume"); 37533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->next = NULL; 37543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageprev = storage; 37563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 37573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(storageIDs.Storage); 37583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 37593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 37603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < storageIDs.n; i++) { 37613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 37623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getstorageinfo(params, storageIDs.Storage[i], &storageInfo); 37633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 37643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Storage(): Could not get storage info."); 37653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage != NULL) { 37663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free_storage_list(device); 37673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 37683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 37693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 37703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = (LIBMTP_devicestorage_t *) malloc(sizeof(LIBMTP_devicestorage_t)); 37723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->prev = storageprev; 37733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storageprev != NULL) 37743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageprev->next = storage; 37753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->storage == NULL) 37763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev device->storage = storage; 37773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->id = storageIDs.Storage[i]; 37793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->StorageType = storageInfo.StorageType; 37803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FilesystemType = storageInfo.FilesystemType; 37813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->AccessCapability = storageInfo.AccessCapability; 37823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->MaxCapacity = storageInfo.MaxCapability; 37833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FreeSpaceInBytes = storageInfo.FreeSpaceInBytes; 37843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->FreeSpaceInObjects = storageInfo.FreeSpaceInImages; 37853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->StorageDescription = storageInfo.StorageDescription; 37863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->VolumeIdentifier = storageInfo.VolumeLabel; 37873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->next = NULL; 37883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageprev = storage; 37903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 37913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage != NULL) 37933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage->next = NULL; 37943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 37953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sort_storage_by(device,sortby); 37963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(storageIDs.Storage); 37973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 37983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 37993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 38003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 38013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 38023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a new file metadata structure and allocates memory 38033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for it. Notice that if you add strings to this structure they 38043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will be freed by the corresponding <code>LIBMTP_destroy_file_t</code> 38053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation later, so be careful of using strdup() when assigning 38063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings, e.g.: 38073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <pre> 38093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_file_t *file = LIBMTP_new_file_t(); 38103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * file->filename = strdup(namestr); 38113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * .... 38123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_destroy_file_t(file); 38133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </pre> 38143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a pointer to the newly allocated metadata structure. 38163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_destroy_file_t() 38173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 38183aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_file_t *LIBMTP_new_file_t(void) 38193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 38203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *new = (LIBMTP_file_t *) malloc(sizeof(LIBMTP_file_t)); 38213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (new == NULL) { 38223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 38233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 38243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->filename = NULL; 38253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->item_id = 0; 38263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->parent_id = 0; 38273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->storage_id = 0; 38283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->filesize = 0; 38293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->modificationdate = 0; 38303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->filetype = LIBMTP_FILETYPE_UNKNOWN; 38313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->next = NULL; 38323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new; 38333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 38343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 38353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 38363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This destroys a file metadata structure and deallocates the memory 38373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * used by it, including any strings. Never use a file metadata 38383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * structure again after calling this function on it. 38393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param file the file metadata to destroy. 38403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_new_file_t() 38413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 38423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_file_t(LIBMTP_file_t *file) 38433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 38443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (file == NULL) { 38453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 38463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 38473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (file->filename != NULL) 38483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(file->filename); 38493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(file); 38503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 38513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 38523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 38533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 38543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev* THIS FUNCTION IS DEPRECATED. PLEASE UPDATE YOUR CODE IN ORDER 38553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * NOT TO USE IT. 38563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Filelisting_With_Callback() 38573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 38583aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_file_t *LIBMTP_Get_Filelisting(LIBMTP_mtpdevice_t *device) 38593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 38603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("WARNING: LIBMTP_Get_Filelisting() is deprecated.\n"); 38613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("WARNING: please update your code to use LIBMTP_Get_Filelisting_With_Callback()\n"); 38623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL); 38633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 38643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 38653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 38663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This returns a long list of all files available 38673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on the current MTP device. Folders will not be returned, but abstract 38683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * entities like playlists and albums will show up as "files". Typical usage: 38693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <pre> 38713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_file_t *filelist; 38723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * filelist = LIBMTP_Get_Filelisting_With_Callback(device, callback, data); 38743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * while (filelist != NULL) { 38753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_file_t *tmp; 38763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * // Do something on each element in the list here... 38783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * tmp = filelist; 38793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * filelist = filelist->next; 38803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_destroy_file_t(tmp); 38813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * } 38823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </pre> 38833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If you want to group your file listing by storage (per storage unit) or 38853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * arrange files into folders, you must dereference the <code>storage_id</code> 38863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and/or <code>parent_id</code> field of the returned <code>LIBMTP_file_t</code> 38873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * struct. To arrange by folders or files you typically have to create the proper 38883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * trees by calls to <code>LIBMTP_Get_Storage()</code> and/or 38893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>LIBMTP_Get_Folder_List()</code> first. 38903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 38913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the file listing for. 38923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a function to be called during the tracklisting retrieveal 38933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for displaying progress bars etc, or NULL if you don't want 38943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * any callbacks. 38953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 38963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 38973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 38983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 38993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a list of files that can be followed using the <code>next</code> 39003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * field of the <code>LIBMTP_file_t</code> data structure. 39013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Each of the metadata tags must be freed after use, and may 39023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contain only partial metadata information, i.e. one or several 39033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * fields may be NULL or 0. 39043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Filemetadata() 39053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 39063aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_file_t *LIBMTP_Get_Filelisting_With_Callback(LIBMTP_mtpdevice_t *device, 39073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 39083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 39093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 39103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i = 0; 39113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *retfiles = NULL; 39123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *curfile = NULL; 39133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 39143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 39153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 39163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 39183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 39193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 39203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < params->nrofobjects; i++) { 39233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *file; 39243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob, *xob; 39253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (callback != NULL) 39273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev callback(i, params->nrofobjects, data); 39283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob = ¶ms->objects[i]; 39303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat == PTP_OFC_Association) { 39323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // MTP use this object format for folders which means 39333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // these "files" will turn up on a folder listing instead. 39343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 39353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new file type 39383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file = LIBMTP_new_file_t(); 39393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->parent_id = ob->oi.ParentObject; 39413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->storage_id = ob->oi.StorageID; 39423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is some sort of unique ID so we can keep track of the track. 39443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->item_id = ob->oid; 39453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set the filetype 39473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = map_ptp_type_to_libmtp_type(ob->oi.ObjectFormat); 39483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set the modification date 39503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->modificationdate = ob->oi.ModificationDate; 39513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Original file-specific properties 39533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We only have 32-bit file size here; if we find it, we use the 39543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // PTP_OPC_ObjectSize property which has 64bit precision. 39553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = ob->oi.ObjectCompressedSize; 39563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename != NULL) { 39573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filename = strdup(ob->oi.Filename); 39583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 39613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * A special quirk for devices that doesn't quite 39623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * remember that some files marked as "unknown" type are 39633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * actually OGG or FLAC files. We look at the filename extension 39643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and see if it happens that this was atleast named "ogg" or "flac" 39653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and fall back on this heuristic approach in that case, 39663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for these bugged devices only. 39673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 39683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (file->filetype == LIBMTP_FILETYPE_UNKNOWN) { 39693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) || 39703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev FLAG_OGG_IS_UNKNOWN(ptp_usb)) && 39713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_ogg_extension(file->filename)) 39723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = LIBMTP_FILETYPE_OGG; 39733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_FLAC_IS_UNKNOWN(ptp_usb) && 39743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_flac_extension(file->filename)) 39753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = LIBMTP_FILETYPE_FLAC; 39763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 39793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If we have a cached, large set of metadata, then use it! 39803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 39813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, ob->oid, PTPOBJECT_MTPPROPLIST_LOADED, &xob); 39823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->mtpprops) { 39833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = ob->mtpprops; 39843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 39853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 39863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<ob->nrofmtpprops;i++) { 39873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Pick ObjectSize here... 39883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->property == PTP_OPC_ObjectSize) { 39893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 39903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = prop->propval.u64; 39913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 39923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = prop->propval.u32; 39933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 39953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop++; 39973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 39983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 39993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 40003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 40013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be retrieved for this object format 40033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, ob->oi.ObjectFormat, &propcnt, &props); 40043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 40053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Filelisting_With_Callback(): call to ptp_mtp_getobjectpropssupported() failed."); 40063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Silently fall through. 40073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 40083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 40093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 40103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (props[i]) { 40113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectSize: 40123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 40133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = get_u64_from_object(device, file->item_id, PTP_OPC_ObjectSize, 0); 40143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 40153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = get_u32_from_object(device, file->item_id, PTP_OPC_ObjectSize, 0); 40163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 40183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 40193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 40203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 40233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add track to a list that will be returned afterwards. 40273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (retfiles == NULL) { 40283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retfiles = file; 40293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curfile = file; 40303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 40313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curfile->next = file; 40323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curfile = file; 40333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Call listing callback 40363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // double progressPercent = (double)i*(double)100.0 / (double)params->handles.n; 40373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } // Handle counting loop 40393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retfiles; 40403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 40413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 40433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves the metadata for a single file off 40443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device. 40453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 40463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Do not call this function repeatedly! The file handles are linearly 40473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * searched O(n) and the call may involve (slow) USB traffic, so use 40483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>LIBMTP_Get_Filelisting()</code> and cache the file, preferably 40493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as an efficient data structure such as a hash list. 40503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 40513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Incidentally this function will return metadata for 40523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * a folder (association) as well, but this is not a proper use 40533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * of it, it is intended for file manipulation, not folder manipulation. 40543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 40553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the file metadata from. 40563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param fileid the object ID of the file that you want the metadata for. 40573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a metadata entry on success or NULL on failure. 40583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Filelisting() 40593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 40603aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_file_t *LIBMTP_Get_Filemetadata(LIBMTP_mtpdevice_t *device, uint32_t const fileid) 40613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 40623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i = 0; 40633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 40643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 40653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 40663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *file; 40673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 40693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 40703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 40713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, fileid, PTPOBJECT_OBJECTINFO_LOADED|PTPOBJECT_MTPPROPLIST_LOADED, &ob); 40743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) 40753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 40763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new file type 40783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file = LIBMTP_new_file_t(); 40793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->parent_id = ob->oi.ParentObject; 40813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->storage_id = ob->oi.StorageID; 40823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set the filetype 40843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filetype = map_ptp_type_to_libmtp_type(ob->oi.ObjectFormat); 40853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Original file-specific properties 40873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We only have 32-bit file size here; later we use the PTP_OPC_ObjectSize property 40893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = ob->oi.ObjectCompressedSize; 40903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename != NULL) { 40913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filename = strdup(ob->oi.Filename); 40923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 40933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is some sort of unique ID so we can keep track of the file. 40953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->item_id = fileid; 40963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 40973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 40983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If we have a cached, large set of metadata, then use it! 40993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 41003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->mtpprops) { 41013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = ob->mtpprops; 41023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 41033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<ob->nrofmtpprops;i++,prop++) { 41043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Pick ObjectSize here... 41053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->property == PTP_OPC_ObjectSize) { 41063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This may already be set, but this 64bit precision value 41073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // is better than the PTP 32bit value, so let it override. 41083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 41093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = prop->propval.u64; 41103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 41113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = prop->propval.u32; 41123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 41143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 41173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 41183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 41193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 41203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be retrieved for this object format 41213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, map_libmtp_type_to_ptp_type(file->filetype), &propcnt, &props); 41223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 41233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Filemetadata(): call to ptp_mtp_getobjectpropssupported() failed."); 41243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Silently fall through. 41253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 41263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 41273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (props[i]) { 41283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectSize: 41293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 41303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = get_u64_from_object(device, file->item_id, PTP_OPC_ObjectSize, 0); 41313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 41323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filesize = get_u32_from_object(device, file->item_id, PTP_OPC_ObjectSize, 0); 41333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 41353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 41363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 41373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 41403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 41433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return file; 41443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 41453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 41463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 41473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a new track metadata structure and allocates memory 41483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for it. Notice that if you add strings to this structure they 41493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will be freed by the corresponding <code>LIBMTP_destroy_track_t</code> 41503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation later, so be careful of using strdup() when assigning 41513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings, e.g.: 41523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 41533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <pre> 41543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_track_t *track = LIBMTP_new_track_t(); 41553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * track->title = strdup(titlestr); 41563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * .... 41573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_destroy_track_t(track); 41583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </pre> 41593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 41603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a pointer to the newly allocated metadata structure. 41613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_destroy_track_t() 41623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 41633aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_track_t *LIBMTP_new_track_t(void) 41643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 41653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *new = (LIBMTP_track_t *) malloc(sizeof(LIBMTP_track_t)); 41663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (new == NULL) { 41673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 41683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 41693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->item_id = 0; 41703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->parent_id = 0; 41713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->storage_id = 0; 41723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->title = NULL; 41733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->artist = NULL; 41743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->composer = NULL; 41753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->album = NULL; 41763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->genre = NULL; 41773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->date = NULL; 41783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->filename = NULL; 41793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->duration = 0; 41803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->tracknumber = 0; 41813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->filesize = 0; 41823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->filetype = LIBMTP_FILETYPE_UNKNOWN; 41833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->samplerate = 0; 41843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->nochannels = 0; 41853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->wavecodec = 0; 41863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->bitrate = 0; 41873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->bitratetype = 0; 41883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->rating = 0; 41893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->usecount = 0; 41903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->modificationdate = 0; 41913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->next = NULL; 41923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new; 41933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 41943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 41953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 41963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This destroys a track metadata structure and deallocates the memory 41973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * used by it, including any strings. Never use a track metadata 41983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * structure again after calling this function on it. 41993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param track the track metadata to destroy. 42003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_new_track_t() 42013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 42023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_track_t(LIBMTP_track_t *track) 42033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 42043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track == NULL) { 42053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 42063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 42073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->title != NULL) 42083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->title); 42093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->artist != NULL) 42103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->artist); 42113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->composer != NULL) 42123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->composer); 42133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->album != NULL) 42143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->album); 42153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->genre != NULL) 42163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->genre); 42173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->date != NULL) 42183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->date); 42193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->filename != NULL) 42203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->filename); 42213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track); 42223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 42233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 42243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 42253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 42263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function maps and copies a property onto the track metadata if applicable. 42273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 42283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void pick_property_to_track_metadata(LIBMTP_mtpdevice_t *device, MTPProperties *prop, LIBMTP_track_t *track) 42293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 42303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (prop->property) { 42313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 42323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 42333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->title = strdup(prop->propval.str); 42343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 42353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->title = NULL; 42363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 42383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 42393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->artist = strdup(prop->propval.str); 42403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 42413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->artist = NULL; 42423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 42443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 42453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->composer = strdup(prop->propval.str); 42463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 42473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->composer = NULL; 42483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Duration: 42503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->duration = prop->propval.u32; 42513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Track: 42533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->tracknumber = prop->propval.u16; 42543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 42563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 42573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->genre = strdup(prop->propval.str); 42583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 42593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->genre = NULL; 42603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumName: 42623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 42633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->album = strdup(prop->propval.str); 42643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 42653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->album = NULL; 42663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_OriginalReleaseDate: 42683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 42693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->date = strdup(prop->propval.str); 42703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 42713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->date = NULL; 42723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // These are, well not so important. 42743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_SampleRate: 42753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->samplerate = prop->propval.u32; 42763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_NumberOfChannels: 42783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->nochannels = prop->propval.u16; 42793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioWAVECodec: 42813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->wavecodec = prop->propval.u32; 42823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioBitRate: 42843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->bitrate = prop->propval.u32; 42853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_BitRateType: 42873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->bitratetype = prop->propval.u16; 42883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Rating: 42903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->rating = prop->propval.u16; 42913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_UseCount: 42933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->usecount = prop->propval.u32; 42943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 42953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectSize: 42963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 42973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filesize = prop->propval.u64; 42983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 42993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filesize = prop->propval.u32; 43003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 43013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 43033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 43053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 43063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 43073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 43083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves the track metadata for a track 43093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given by a unique ID. 43103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track metadata off. 43113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param trackid the unique ID of the track. 43123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param objectformat the object format of this track, so we know what it supports. 43133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param track a metadata set to fill in. 43143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 43153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void get_track_metadata(LIBMTP_mtpdevice_t *device, uint16_t objectformat, 43163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *track) 43173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 43183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 43193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 43203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 43213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 43223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 43233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 43243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 43253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If we have a cached, large set of metadata, then use it! 43263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 43273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want(params, track->item_id, PTPOBJECT_MTPPROPLIST_LOADED, &ob); 43283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->mtpprops) { 43293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ob->mtpprops; 43303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<ob->nrofmtpprops;i++,prop++) 43313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pick_property_to_track_metadata(device, prop, track); 43323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 43333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 43343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 43353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 43363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be retrieved for this object format 43373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, map_libmtp_type_to_ptp_type(track->filetype), &propcnt, &props); 43383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 43393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_track_metadata(): call to ptp_mtp_getobjectpropssupported() failed."); 43403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just bail out for now, nothing is ever set. 43413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 43423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 43433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 43443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (props[i]) { 43453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 43463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->title = get_string_from_object(device, track->item_id, PTP_OPC_Name); 43473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 43493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->artist = get_string_from_object(device, track->item_id, PTP_OPC_Artist); 43503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 43523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->composer = get_string_from_object(device, track->item_id, PTP_OPC_Composer); 43533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Duration: 43553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->duration = get_u32_from_object(device, track->item_id, PTP_OPC_Duration, 0); 43563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Track: 43583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->tracknumber = get_u16_from_object(device, track->item_id, PTP_OPC_Track, 0); 43593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 43613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->genre = get_string_from_object(device, track->item_id, PTP_OPC_Genre); 43623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumName: 43643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->album = get_string_from_object(device, track->item_id, PTP_OPC_AlbumName); 43653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_OriginalReleaseDate: 43673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->date = get_string_from_object(device, track->item_id, PTP_OPC_OriginalReleaseDate); 43683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // These are, well not so important. 43703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_SampleRate: 43713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->samplerate = get_u32_from_object(device, track->item_id, PTP_OPC_SampleRate, 0); 43723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_NumberOfChannels: 43743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->nochannels = get_u16_from_object(device, track->item_id, PTP_OPC_NumberOfChannels, 0); 43753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioWAVECodec: 43773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->wavecodec = get_u32_from_object(device, track->item_id, PTP_OPC_AudioWAVECodec, 0); 43783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioBitRate: 43803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->bitrate = get_u32_from_object(device, track->item_id, PTP_OPC_AudioBitRate, 0); 43813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_BitRateType: 43833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->bitratetype = get_u16_from_object(device, track->item_id, PTP_OPC_BitRateType, 0); 43843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Rating: 43863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->rating = get_u16_from_object(device, track->item_id, PTP_OPC_Rating, 0); 43873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_UseCount: 43893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->usecount = get_u32_from_object(device, track->item_id, PTP_OPC_UseCount, 0); 43903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectSize: 43923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->object_bitsize == 64) { 43933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filesize = get_u64_from_object(device, track->item_id, PTP_OPC_ObjectSize, 0); 43943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 43953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filesize = (uint64_t) get_u32_from_object(device, track->item_id, PTP_OPC_ObjectSize, 0); 43963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 43973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 43983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 43993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 44003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 44013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 44023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 44033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 44043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 44063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * THIS FUNCTION IS DEPRECATED. PLEASE UPDATE YOUR CODE IN ORDER 44073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * NOT TO USE IT. 44083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Tracklisting_With_Callback() 44093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 44103aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_track_t *LIBMTP_Get_Tracklisting(LIBMTP_mtpdevice_t *device) 44113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 44123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("WARNING: LIBMTP_Get_Tracklisting() is deprecated.\n"); 44133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("WARNING: please update your code to use LIBMTP_Get_Tracklisting_With_Callback()\n"); 44143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_Get_Tracklisting_With_Callback(device, NULL, NULL); 44153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 44163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 44183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This returns a long list of all tracks available on the current MTP device. 44193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Tracks include multimedia objects, both music tracks and video tracks. 44203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Typical usage: 44213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 44223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <pre> 44233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_track_t *tracklist; 44243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 44253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * tracklist = LIBMTP_Get_Tracklisting_With_Callback(device, callback, data); 44263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * while (tracklist != NULL) { 44273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_track_t *tmp; 44283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 44293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * // Do something on each element in the list here... 44303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * tmp = tracklist; 44313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * tracklist = tracklist->next; 44323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_destroy_track_t(tmp); 44333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * } 44343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </pre> 44353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 44363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If you want to group your track listing by storage (per storage unit) or 44373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * arrange tracks into folders, you must dereference the <code>storage_id</code> 44383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and/or <code>parent_id</code> field of the returned <code>LIBMTP_track_t</code> 44393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * struct. To arrange by folders or files you typically have to create the proper 44403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * trees by calls to <code>LIBMTP_Get_Storage()</code> and/or 44413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>LIBMTP_Get_Folder_List()</code> first. 44423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 44433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track listing for. 44443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a function to be called during the tracklisting retrieveal 44453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for displaying progress bars etc, or NULL if you don't want 44463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * any callbacks. 44473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 44483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 44493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 44503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 44513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a list of tracks that can be followed using the <code>next</code> 44523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * field of the <code>LIBMTP_track_t</code> data structure. 44533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Each of the metadata tags must be freed after use, and may 44543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contain only partial metadata information, i.e. one or several 44553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * fields may be NULL or 0. 44563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Trackmetadata() 44573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 44583aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_track_t *LIBMTP_Get_Tracklisting_With_Callback(LIBMTP_mtpdevice_t *device, 44593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 44603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 44613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 44623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i = 0; 44633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *retracks = NULL; 44643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *curtrack = NULL; 44653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 44663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 44673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 44693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 44703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 44713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 44723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < params->nrofobjects; i++) { 44743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *track; 44753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 44763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filetype_t mtptype; 44773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (callback != NULL) 44793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev callback(i, params->nrofobjects, data); 44803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob = ¶ms->objects[i]; 44823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtptype = map_ptp_type_to_libmtp_type(ob->oi.ObjectFormat); 44833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore stuff we don't know how to handle... 44853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: get this list as an intersection of the sets 44863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // supported by the device and the from the device and 44873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // all known track files? 44883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!LIBMTP_FILETYPE_IS_TRACK(mtptype) && 44893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This row lets through undefined files for examination since they may be forgotten OGG files. 44903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (ob->oi.ObjectFormat != PTP_OFC_Undefined || 44913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (!FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) && 44923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_OGG_IS_UNKNOWN(ptp_usb) && 44933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_FLAC_IS_UNKNOWN(ptp_usb))) 44943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ) { 44953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev //printf("Not a music track (name: %s format: %d), skipping...\n", oi->Filename, oi->ObjectFormat); 44963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 44973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 44983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 44993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new track type 45003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track = LIBMTP_new_track_t(); 45013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is some sort of unique ID so we can keep track of the track. 45033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->item_id = ob->oid; 45043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->parent_id = ob->oi.ParentObject; 45053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->storage_id = ob->oi.StorageID; 45063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->modificationdate = ob->oi.ModificationDate; 45073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filetype = mtptype; 45093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Original file-specific properties 45113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filesize = ob->oi.ObjectCompressedSize; 45123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename != NULL) { 45133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filename = strdup(ob->oi.Filename); 45143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 45153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_track_metadata(device, ob->oi.ObjectFormat, track); 45173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 45193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * A special quirk for iriver devices that doesn't quite 45203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * remember that some files marked as "unknown" type are 45213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * actually OGG or FLAC files. We look at the filename extension 45223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and see if it happens that this was atleast named "ogg" or "flac" 45233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and fall back on this heuristic approach in that case, 45243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for these bugged devices only. 45253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 45263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->filetype == LIBMTP_FILETYPE_UNKNOWN && 45273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filename != NULL) { 45283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) || 45293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev FLAG_OGG_IS_UNKNOWN(ptp_usb)) && 45303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_ogg_extension(track->filename)) 45313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filetype = LIBMTP_FILETYPE_OGG; 45323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (FLAG_FLAC_IS_UNKNOWN(ptp_usb) && 45333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_flac_extension(track->filename)) 45343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filetype = LIBMTP_FILETYPE_FLAC; 45353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else { 45363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This was not an OGG/FLAC file so discard it and continue 45373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_track_t(track); 45383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 45393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 45403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 45413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add track to a list that will be returned afterwards. 45433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (retracks == NULL) { 45443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retracks = track; 45453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curtrack = track; 45463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 45473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curtrack->next = track; 45483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curtrack = track; 45493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 45503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Call listing callback 45523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // double progressPercent = (double)i*(double)100.0 / (double)params->handles.n; 45533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } // Handle counting loop 45563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retracks; 45573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 45583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 45603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves the metadata for a single track off 45613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the device. 45623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 45633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Do not call this function repeatedly! The track handles are linearly 45643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * searched O(n) and the call may involve (slow) USB traffic, so use 45653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>LIBMTP_Get_Tracklisting()</code> and cache the tracks, preferably 45663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as an efficient data structure such as a hash list. 45673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 45683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track metadata from. 45693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param trackid the object ID of the track that you want the metadata for. 45703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a track metadata entry on success or NULL on failure. 45713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Tracklisting() 45723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 45733aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_track_t *LIBMTP_Get_Trackmetadata(LIBMTP_mtpdevice_t *device, uint32_t const trackid) 45743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 45753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 45763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 45773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 45783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *track; 45793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filetype_t mtptype; 45803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 45813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 45833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) 45843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 45853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, trackid, PTPOBJECT_OBJECTINFO_LOADED, &ob); 45873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) 45883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 45893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtptype = map_ptp_type_to_libmtp_type(ob->oi.ObjectFormat); 45913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 45923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore stuff we don't know how to handle... 45933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!LIBMTP_FILETYPE_IS_TRACK(mtptype) && 45943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 45953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This row lets through undefined files for examination 45963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * since they may be forgotten OGG or FLAC files. 45973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 45983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (ob->oi.ObjectFormat != PTP_OFC_Undefined || 45993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (!FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) && 46003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_OGG_IS_UNKNOWN(ptp_usb) && 46013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_FLAC_IS_UNKNOWN(ptp_usb))) 46023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ) { 46033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev //printf("Not a music track (name: %s format: %d), skipping...\n", oi->Filename, oi->ObjectFormat); 46043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 46053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 46063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new track type 46083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track = LIBMTP_new_track_t(); 46093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is some sort of unique ID so we can keep track of the track. 46113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->item_id = ob->oid; 46123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->parent_id = ob->oi.ParentObject; 46133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->storage_id = ob->oi.StorageID; 46143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->modificationdate = ob->oi.ModificationDate; 46153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filetype = mtptype; 46173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Original file-specific properties 46193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filesize = ob->oi.ObjectCompressedSize; 46203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.Filename != NULL) { 46213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filename = strdup(ob->oi.Filename); 46223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 46233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 46253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * A special quirk for devices that doesn't quite 46263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * remember that some files marked as "unknown" type are 46273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * actually OGG or FLAC files. We look at the filename extension 46283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and see if it happens that this was atleast named "ogg" 46293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and fall back on this heuristic approach in that case, 46303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for these bugged devices only. 46313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 46323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (track->filetype == LIBMTP_FILETYPE_UNKNOWN && 46333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filename != NULL) { 46343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((FLAG_IRIVER_OGG_ALZHEIMER(ptp_usb) || 46353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev FLAG_OGG_IS_UNKNOWN(ptp_usb)) && 46363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_ogg_extension(track->filename)) 46373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filetype = LIBMTP_FILETYPE_OGG; 46383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if (FLAG_FLAC_IS_UNKNOWN(ptp_usb) && 46393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev has_flac_extension(track->filename)) 46403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filetype = LIBMTP_FILETYPE_FLAC; 46413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else { 46423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This was not an OGG/FLAC file so discard it 46433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_track_t(track); 46443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 46453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 46463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 46473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_track_metadata(device, ob->oi.ObjectFormat, track); 46483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return track; 46493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 46503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 46523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This is a manual conversion from MTPDataGetFunc to PTPDataGetFunc 46533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to isolate the internal type. 46543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 46553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t get_func_wrapper(PTPParams* params, void* priv, unsigned long wantlen, unsigned char *data, unsigned long *gotlen) 46563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 46573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataHandler *handler = (MTPDataHandler *)priv; 46583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 46593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t local_gotlen = 0; 46603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = handler->getfunc(params, handler->priv, wantlen, data, &local_gotlen); 46613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *gotlen = local_gotlen; 46623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (ret) 46633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 46643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_HANDLER_RETURN_OK: 46653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_RC_OK; 46663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_HANDLER_RETURN_ERROR: 46673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_ERROR_IO; 46683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_HANDLER_RETURN_CANCEL: 46693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_ERROR_CANCEL; 46703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 46713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_ERROR_IO; 46723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 46733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 46743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 46763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This is a manual conversion from MTPDataPutFunc to PTPDataPutFunc 46773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to isolate the internal type. 46783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 46793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic uint16_t put_func_wrapper(PTPParams* params, void* priv, unsigned long sendlen, unsigned char *data, unsigned long *putlen) 46803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 46813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataHandler *handler = (MTPDataHandler *)priv; 46823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 46833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t local_putlen = 0; 46843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = handler->putfunc(params, handler->priv, sendlen, data, &local_putlen); 46853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *putlen = local_putlen; 46863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (ret) 46873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 46883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_HANDLER_RETURN_OK: 46893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_RC_OK; 46903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_HANDLER_RETURN_ERROR: 46913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_ERROR_IO; 46923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_HANDLER_RETURN_CANCEL: 46933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_ERROR_CANCEL; 46943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 46953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_ERROR_IO; 46963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 46973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 46983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 46993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 47003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This gets a file off the device to a local file identified 47013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * by a filename. 47023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track from. 47033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the file ID of the file to retrieve. 47043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param path a filename to use for the retrieved file. 47053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 47063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 47073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 47083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 47093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 47103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 47113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 47123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_File_To_File_Descriptor() 47133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 47143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_File_To_File(LIBMTP_mtpdevice_t *device, uint32_t const id, 47153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const path, LIBMTP_progressfunc_t const callback, 47163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 47173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 47183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int fd = -1; 4719bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev struct utimbuf mtime; 47203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 47213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 47223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Sanity check 47233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (path == NULL) { 47243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_File_To_File(): Bad arguments, path was NULL."); 47253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 47263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 47273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 47283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Open file 47293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef __WIN32__ 47303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef USE_WINDOWS_IO_H 47313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = _open(path, O_RDWR|O_CREAT|O_TRUNC|O_BINARY,_S_IREAD)) == -1 ) { 47323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 47333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = open(path, O_RDWR|O_CREAT|O_TRUNC|O_BINARY,S_IRWXU)) == -1 ) { 47343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 47353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 47363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = open(path, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP)) == -1) { 47373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 47383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_File_To_File(): Could not create file."); 47393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 47403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 47413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4742bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev ret = LIBMTP_Get_File_To_File_Descriptor(device, id, fd, callback, data, &mtime); 47433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 47443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Close file 47453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev close(fd); 47463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 47473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Delete partial file. 47483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == -1) { 47493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unlink(path); 4750bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev } else { 4751bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev utime(path, &mtime); 47523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 47533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 47543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 47553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 47563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 47573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This gets a file off the device to a file identified 47583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * by a file descriptor. 47593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 47603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function can potentially be used for streaming 47613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * files off the device for playback or broadcast for example, 47623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * by downloading the file into a stream sink e.g. a socket. 47633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 47643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the file from. 47653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the file ID of the file to retrieve. 47663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param fd a local file descriptor to write the file to. 47673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 47683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 47693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 47703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 47713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 4772bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev * @param mtime out parameter to return the timestamp for file on 4773bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev * the device. 47743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 4775bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev * failure. 47763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_File_To_File() 47773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 47783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_File_To_File_Descriptor(LIBMTP_mtpdevice_t *device, 47793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id, 47803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int const fd, 47813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 4782bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev void const * const data, 4783bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev struct utimbuf * mtime) 47843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 47853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 47863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 47873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 47883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 47893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 47903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, id, PTPOBJECT_OBJECTINFO_LOADED, &ob); 47913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 47923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_File_To_File_Descriptor(): Could not get object info."); 47933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 47943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 47953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat == PTP_OFC_Association) { 47963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_File_To_File_Descriptor(): Bad object format."); 47973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 47983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 47993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4800bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev if (mtime != NULL) { 4801bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev mtime->actime = ob->oi.CaptureDate; 4802bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev mtime->modtime = ob->oi.ModificationDate; 4803bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev } 4804bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev 48053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Callbacks 48063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 1; 48073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_total = ob->oi.ObjectCompressedSize+ 48083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB_BULK_HDR_LEN+sizeof(uint32_t); // Request length, one parameter 48093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_complete = 0; 48103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = callback; 48113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = data; 48123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getobject_tofd(params, id, fd); 48143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 0; 48163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = NULL; 48173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = NULL; 48183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_ERROR_CANCEL) { 48203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_CANCELLED, "LIBMTP_Get_File_From_File_Descriptor(): Cancelled transfer."); 48213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 48223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 48233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 48243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_File_To_File_Descriptor(): Could not get file from device."); 48253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 48263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 48273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 48293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 48303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 48323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This gets a file off the device and calls put_func 48333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * with chunks of data 48343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 48353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the file from. 48363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the file ID of the file to retrieve. 48373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param put_func the function to call when we have data. 48383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param priv the user-defined pointer that is passed to 48393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>put_func</code>. 48403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 48413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 48423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 48433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 48443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 48453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 48463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 48473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 48483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_File_To_Handler(LIBMTP_mtpdevice_t *device, 48493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id, 48503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataPutFunc put_func, 48513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void * priv, 48523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 48533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 48543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 48553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 48563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 48573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 48583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 48593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, id, PTPOBJECT_OBJECTINFO_LOADED, &ob); 48613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 48623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_File_To_File_Descriptor(): Could not get object info."); 48633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 48643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 48653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat == PTP_OFC_Association) { 48663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_File_To_File_Descriptor(): Bad object format."); 48673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 48683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 48693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Callbacks 48713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 1; 48723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_total = ob->oi.ObjectCompressedSize+ 48733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB_BULK_HDR_LEN+sizeof(uint32_t); // Request length, one parameter 48743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_complete = 0; 48753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = callback; 48763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = data; 48773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataHandler mtp_handler; 48793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_handler.getfunc = NULL; 48803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_handler.putfunc = put_func; 48813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_handler.priv = priv; 48823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPDataHandler handler; 48843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handler.getfunc = NULL; 48853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handler.putfunc = put_func_wrapper; 48863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handler.priv = &mtp_handler; 48873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_getobject_to_handler(params, id, &handler); 48893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 0; 48913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = NULL; 48923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = NULL; 48933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 48943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_ERROR_CANCEL) { 48953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_CANCELLED, "LIBMTP_Get_File_From_File_Descriptor(): Cancelled transfer."); 48963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 48973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 48983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 48993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_File_To_File_Descriptor(): Could not get file from device."); 49003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 49013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 49023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 49033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 49043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 49053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 49063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 49073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 49083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This gets a track off the device to a file identified 49093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * by a filename. This is actually just a wrapper for the 49103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * \c LIBMTP_Get_Track_To_File() function. 49113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track from. 49123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the track ID of the track to retrieve. 49133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param path a filename to use for the retrieved track. 49143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 49153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 49163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 49173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 49183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 49193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 49203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 49213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Track_To_File_Descriptor() 49223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 49233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Track_To_File(LIBMTP_mtpdevice_t *device, uint32_t const id, 49243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const path, LIBMTP_progressfunc_t const callback, 49253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 49263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 49273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is just a wrapper 49283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_Get_File_To_File(device, id, path, callback, data); 49293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 49303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 49313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 49323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This gets a track off the device to a file identified 49333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * by a file descriptor. This is actually just a wrapper for 49343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the \c LIBMTP_Get_File_To_File_Descriptor() function. 49353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track from. 49363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the track ID of the track to retrieve. 49373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param fd a file descriptor to write the track to. 49383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 49393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 49403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 49413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 49423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 4943bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev * @param mtime out parameter to return the timestamp for file on 4944bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev * the device. 49453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 49463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 49473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Track_To_File() 49483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 49493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Track_To_File_Descriptor(LIBMTP_mtpdevice_t *device, 49503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id, 49513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int const fd, 49523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 4953bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev void const * const data, 4954bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev struct utimbuf * mtime) 49553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 49563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is just a wrapper 4957bf992f9881b17ef13f0877b128001e4d001d7c56Yavor Goulishev return LIBMTP_Get_File_To_File_Descriptor(device, id, fd, callback, data, mtime); 49583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 49593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 49603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 49613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This gets a track off the device to a handler function. 49623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This is actually just a wrapper for 49633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the \c LIBMTP_Get_File_To_Handler() function. 49643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track from. 49653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the track ID of the track to retrieve. 49663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param put_func the function to call when we have data. 49673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param priv the user-defined pointer that is passed to 49683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>put_func</code>. 49693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 49703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 49713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 49723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 49733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 49743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 49753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 49763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 49773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Track_To_Handler(LIBMTP_mtpdevice_t *device, 49783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id, 49793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataPutFunc put_func, 49803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void * priv, 49813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 49823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 49833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 49843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This is just a wrapper 49853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return LIBMTP_Get_File_To_Handler(device, id, put_func, priv, callback, data); 49863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 49873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 49883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 49893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends a track from a local file to an 49903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP device. A filename and a set of metadata must be 49913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given as input. 49923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the track to. 49933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param path the filename of a local file which will be sent. 49943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata a track metadata set to be written along with the file. 49953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * After this call the field <code>metadata->item_id</code> 49963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will contain the new track ID. Other fields such 49973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as the <code>metadata->filename</code>, <code>metadata->parent_id</code> 49983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or <code>metadata->storage_id</code> may also change during this 49993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation due to device restrictions, so do not rely on the 50003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contents of this struct to be preserved in any way. 50013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 50023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->parent_id</code> should be set to the parent 50033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this track in. Since some 50043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * devices are a bit picky about where files 50053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * are placed, a default folder will be chosen if libmtp 50063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * has detected one for the current filetype and this 50073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parameter is set to 0. If this is 0 and no default folder 50083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * can be found, the file will be stored in the root folder. 50093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->storage_id</code> should be set to the 50103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 50113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this track in. Setting this to 0 will store 50123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the track on the primary storage. 50133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 50143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 50153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 50163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 50173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 50183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 50193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 50203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 50213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Track_From_File_Descriptor() 50223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_File_From_File() 50233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 50243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 50253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_Track_From_File(LIBMTP_mtpdevice_t *device, 50263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const path, LIBMTP_track_t * const metadata, 50273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 50283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 50293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 50303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int fd; 50313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 50323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 50333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Sanity check 50343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (path == NULL) { 50353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Send_Track_From_File(): Bad arguments, path was NULL."); 50363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 50373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 50383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 50393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Open file 50403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef __WIN32__ 50413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef USE_WINDOWS_IO_H 50423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = _open(path, O_RDONLY|O_BINARY) == -1) ) { 50433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 50443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = open(path, O_RDONLY|O_BINARY) == -1) ) { 50453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 50463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 50473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = open(path, O_RDONLY)) == -1) { 50483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 50493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("LIBMTP_Send_Track_From_File(): Could not open source file \"%s\"\n", path); 50503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 50513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 50523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 50533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = LIBMTP_Send_Track_From_File_Descriptor(device, fd, metadata, callback, data); 50543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 50553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Close file. 50563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef USE_WINDOWS_IO_H 50573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev _close(fd); 50583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 50593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev close(fd); 50603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 50613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 50623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 50633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 50643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 50653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 50663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends a track from a file descriptor to an 50673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP device. A filename and a set of metadata must be 50683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given as input. 50693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the track to. 50703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param fd the filedescriptor for a local file which will be sent. 50713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata a track metadata set to be written along with the file. 50723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * After this call the field <code>metadata->item_id</code> 50733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will contain the new track ID. Other fields such 50743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as the <code>metadata->filename</code>, <code>metadata->parent_id</code> 50753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or <code>metadata->storage_id</code> may also change during this 50763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation due to device restrictions, so do not rely on the 50773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contents of this struct to be preserved in any way. 50783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 50793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->parent_id</code> should be set to the parent 50803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this track in. Since some 50813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * devices are a bit picky about where files 50823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * are placed, a default folder will be chosen if libmtp 50833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * has detected one for the current filetype and this 50843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parameter is set to 0. If this is 0 and no default folder 50853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * can be found, the file will be stored in the root folder. 50863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->storage_id</code> should be set to the 50873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 50883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this track in. Setting this to 0 will store 50893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the track on the primary storage. 50903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 50913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 50923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 50933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 50943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 50953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 50963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 50973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 50983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Track_From_File() 50993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 51003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 51013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_Track_From_File_Descriptor(LIBMTP_mtpdevice_t *device, 51023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int const fd, LIBMTP_track_t * const metadata, 51033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 51043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 51053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 51063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int subcall_ret; 51073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t filedata; 51083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Sanity check, is this really a track? 51103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!LIBMTP_FILETYPE_IS_TRACK(metadata->filetype)) { 51113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 51123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Send_Track_From_File_Descriptor(): " 51133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "I don't think this is actually a track, strange filetype..."); 51143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 51153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Wrap around the file transfer function 51173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.item_id = metadata->item_id; 51183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.parent_id = metadata->parent_id; 51193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.storage_id = metadata->storage_id; 51203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.filename = metadata->filename; 51213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.filesize = metadata->filesize; 51223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.filetype = metadata->filetype; 51233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.next = NULL; 51243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev subcall_ret = LIBMTP_Send_File_From_File_Descriptor(device, 51263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fd, 51273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &filedata, 51283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev callback, 51293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data); 51303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (subcall_ret != 0) { 51323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 51333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Send_Track_From_File_Descriptor(): " 51343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "subcall to LIBMTP_Send_File_From_File_Descriptor failed."); 51353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We used to delete the file here, but don't... It might be OK after all. 51363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // (void) LIBMTP_Delete_Object(device, metadata->item_id); 51373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 51383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 51393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Pick up new item (and parent, storage) ID 51413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->item_id = filedata.item_id; 51423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->parent_id = filedata.parent_id; 51433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->storage_id = filedata.storage_id; 51443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set track metadata for the new fine track 51463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev subcall_ret = LIBMTP_Update_Track_Metadata(device, metadata); 51473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (subcall_ret != 0) { 51483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Subcall will add error to errorstack 51493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We used to delete the file here, but don't... It might be OK after all. 51503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // (void) LIBMTP_Delete_Object(device, metadata->item_id); 51513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 51523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 51533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // note we don't need to update the cache here because LIBMTP_Send_File_From_File_Descriptor 51553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // has added the object handle and LIBMTP_Update_Track_Metadata has added the metadata. 51563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 51583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 51593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 51603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 51613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends a track from a handler function to an 51623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP device. A filename and a set of metadata must be 51633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given as input. 51643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the track to. 51653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param get_func the function to call when we have data. 51663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param priv the user-defined pointer that is passed to 51673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>get_func</code>. 51683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata a track metadata set to be written along with the file. 51693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * After this call the field <code>metadata->item_id</code> 51703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will contain the new track ID. Other fields such 51713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as the <code>metadata->filename</code>, <code>metadata->parent_id</code> 51723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or <code>metadata->storage_id</code> may also change during this 51733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation due to device restrictions, so do not rely on the 51743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contents of this struct to be preserved in any way. 51753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 51763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->parent_id</code> should be set to the parent 51773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this track in. Since some 51783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * devices are a bit picky about where files 51793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * are placed, a default folder will be chosen if libmtp 51803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * has detected one for the current filetype and this 51813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parameter is set to 0. If this is 0 and no default folder 51823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * can be found, the file will be stored in the root folder. 51833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->storage_id</code> should be set to the 51843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 51853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this track in. Setting this to 0 will store 51863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the track on the primary storage. 51873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 51883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 51893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 51903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 51913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 51923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 51933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 51943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 51953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Track_From_File() 51963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 51973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 51983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_Track_From_Handler(LIBMTP_mtpdevice_t *device, 51993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataGetFunc get_func, void * priv, LIBMTP_track_t * const metadata, 52003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 52013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 52023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 52033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int subcall_ret; 52043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t filedata; 52053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Sanity check, is this really a track? 52073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!LIBMTP_FILETYPE_IS_TRACK(metadata->filetype)) { 52083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 52093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Send_Track_From_Handler(): " 52103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "I don't think this is actually a track, strange filetype..."); 52113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 52123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Wrap around the file transfer function 52143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.item_id = metadata->item_id; 52153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.parent_id = metadata->parent_id; 52163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.storage_id = metadata->storage_id; 52173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.filename = metadata->filename; 52183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.filesize = metadata->filesize; 52193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.filetype = metadata->filetype; 52203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata.next = NULL; 52213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev subcall_ret = LIBMTP_Send_File_From_Handler(device, 52233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_func, 52243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev priv, 52253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &filedata, 52263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev callback, 52273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data); 52283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (subcall_ret != 0) { 52303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 52313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Send_Track_From_Handler(): " 52323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "subcall to LIBMTP_Send_File_From_Handler failed."); 52333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We used to delete the file here, but don't... It might be OK after all. 52343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // (void) LIBMTP_Delete_Object(device, metadata->item_id); 52353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 52363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 52373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Pick up new item (and parent, storage) ID 52393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->item_id = filedata.item_id; 52403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->parent_id = filedata.parent_id; 52413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->storage_id = filedata.storage_id; 52423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Set track metadata for the new fine track 52443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev subcall_ret = LIBMTP_Update_Track_Metadata(device, metadata); 52453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (subcall_ret != 0) { 52463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Subcall will add error to errorstack 52473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We used to delete the file here, but don't... It might be OK after all. 52483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // (void) LIBMTP_Delete_Object(device, metadata->item_id); 52493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 52503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 52513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // note we don't need to update the cache here because LIBMTP_Send_File_From_File_Descriptor 52533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // has added the object handle and LIBMTP_Update_Track_Metadata has added the metadata. 52543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 52563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 52573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 52593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends a local file to an MTP device. 52603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * A filename and a set of metadata must be 52613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given as input. 52623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the track to. 52633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param path the filename of a local file which will be sent. 52643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filedata a file metadata set to be written along with the file. 52653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * After this call the field <code>filedata->item_id</code> 52663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will contain the new file ID. Other fields such 52673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as the <code>filedata->filename</code>, <code>filedata->parent_id</code> 52683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or <code>filedata->storage_id</code> may also change during this 52693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation due to device restrictions, so do not rely on the 52703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contents of this struct to be preserved in any way. 52713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 52723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>filedata->parent_id</code> should be set to the parent 52733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this file in. If this is 0, 52743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the file will be stored in the root folder. 52753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>filedata->storage_id</code> should be set to the 52763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 52773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this file in. Setting this to 0 will store 52783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the file on the primary storage. 52793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 52803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 52813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 52823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 52833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 52843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 52853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 52863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 52873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_File_From_File_Descriptor() 52883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 52893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 52903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_File_From_File(LIBMTP_mtpdevice_t *device, 52913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const path, LIBMTP_file_t * const filedata, 52923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 52933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 52943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 52953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int fd; 52963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 52973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 52983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Sanity check 52993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (path == NULL) { 53003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Send_File_From_File(): Bad arguments, path was NULL."); 53013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 53023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 53033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Open file 53053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef __WIN32__ 53063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef USE_WINDOWS_IO_H 53073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = _open(path, O_RDONLY|O_BINARY) == -1) ) { 53083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 53093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = open(path, O_RDONLY|O_BINARY) == -1) ) { 53103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 53113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 53123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (fd = open(path, O_RDONLY)) == -1) { 53133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 53143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Send_File_From_File(): Could not open source file."); 53153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 53163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 53173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = LIBMTP_Send_File_From_File_Descriptor(device, fd, filedata, callback, data); 53193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Close file. 53213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef USE_WINDOWS_IO_H 53223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev _close(fd); 53233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 53243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev close(fd); 53253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 53263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 53283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 53293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 53313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends a generic file from a file descriptor to an 53323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP device. A filename and a set of metadata must be 53333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given as input. 53343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 53353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This can potentially be used for sending in a stream of unknown 53363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * length. Send music files with 53373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>LIBMTP_Send_Track_From_File_Descriptor()</code> 53383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 53393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the file to. 53403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param fd the filedescriptor for a local file which will be sent. 53413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filedata a file metadata set to be written along with the file. 53423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * After this call the field <code>filedata->item_id</code> 53433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will contain the new file ID. Other fields such 53443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as the <code>filedata->filename</code>, <code>filedata->parent_id</code> 53453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or <code>filedata->storage_id</code> may also change during this 53463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation due to device restrictions, so do not rely on the 53473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contents of this struct to be preserved in any way. 53483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 53493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>filedata->parent_id</code> should be set to the parent 53503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this file in. If this is 0, 53513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the file will be stored in the root folder. 53523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>filedata->storage_id</code> should be set to the 53533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 53543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this file in. Setting this to 0 will store 53553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the file on the primary storage. 53563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 53573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 53583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 53593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 53603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 53613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 53623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 53633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 53643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_File_From_File() 53653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Track_From_File_Descriptor() 53663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 53673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 53683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_File_From_File_Descriptor(LIBMTP_mtpdevice_t *device, 53693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int const fd, LIBMTP_file_t * const filedata, 53703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, 53713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev void const * const data) 53723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 53733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 53743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 53753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 53763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *newfilemeta; 53773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (send_file_object_info(device, filedata)) 53793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 53803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // no need to output an error since send_file_object_info will already have done so 53813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 53823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 53833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Callbacks 53853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 1; 53863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // The callback will deactivate itself after this amount of data has been sent 53873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // One BULK header for the request, one for the data phase. No parameters to the request. 53883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_total = filedata->filesize+PTP_USB_BULK_HDR_LEN*2; 53893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_complete = 0; 53903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = callback; 53913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = data; 53923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobject_fromfd(params, fd, filedata->filesize); 53943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 0; 53963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = NULL; 53973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = NULL; 53983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 53993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_ERROR_CANCEL) { 54003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_CANCELLED, "LIBMTP_Send_File_From_File_Descriptor(): Cancelled transfer."); 54013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 54023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 54033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 54043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Send_File_From_File_Descriptor(): " 54053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Could not send object."); 54063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 54073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 54083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_object_to_cache(device, filedata->item_id); 54103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 54123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Get the device-assined parent_id from the cache. 54133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The operation that adds it to the cache will 54143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * look it up from the device, so we get the new 54153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parent_id from the cache. 54163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 54173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newfilemeta = LIBMTP_Get_Filemetadata(device, filedata->item_id); 54183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (newfilemeta != NULL) { 54193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->parent_id = newfilemeta->parent_id; 54203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->storage_id = newfilemeta->storage_id; 54213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_file_t(newfilemeta); 54223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 54233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 54243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Send_File_From_File_Descriptor(): " 54253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Could not retrieve updated metadata."); 54263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 54273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 54283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 54303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 54313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 54333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends a generic file from a handler function to an 54343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP device. A filename and a set of metadata must be 54353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given as input. 54363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 54373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This can potentially be used for sending in a stream of unknown 54383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * length. Send music files with 54393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>LIBMTP_Send_Track_From_Handler()</code> 54403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 54413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the file to. 54423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param get_func the function to call to get data to write 54433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param priv a user-defined pointer that is passed along to 54443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <code>get_func</code>. If not used, this is set to NULL. 54453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filedata a file metadata set to be written along with the file. 54463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * After this call the field <code>filedata->item_id</code> 54473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will contain the new file ID. Other fields such 54483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * as the <code>filedata->filename</code>, <code>filedata->parent_id</code> 54493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or <code>filedata->storage_id</code> may also change during this 54503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation due to device restrictions, so do not rely on the 54513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contents of this struct to be preserved in any way. 54523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 54533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>filedata->parent_id</code> should be set to the parent 54543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this file in. If this is 0, 54553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the file will be stored in the root folder. 54563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>filedata->storage_id</code> should be set to the 54573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 54583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this file in. Setting this to 0 will store 54593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the file on the primary storage. 54603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 54613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param callback a progress indicator function or NULL to ignore. 54623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param data a user-defined pointer that is passed along to 54633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the <code>progress</code> function in order to 54643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pass along some user defined data to the progress 54653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * updates. If not used, set this to NULL. 54663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 54673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 54683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_File_From_File() 54693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Track_From_File_Descriptor() 54703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 54713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 54723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_File_From_Handler(LIBMTP_mtpdevice_t *device, 54733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataGetFunc get_func, void * priv, LIBMTP_file_t * const filedata, 54743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_progressfunc_t const callback, void const * const data) 54753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 54763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 54773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 54783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 54793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *newfilemeta; 54803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (send_file_object_info(device, filedata)) 54823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 54833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // no need to output an error since send_file_object_info will already have done so 54843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 54853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 54863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Callbacks 54883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 1; 54893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // The callback will deactivate itself after this amount of data has been sent 54903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // One BULK header for the request, one for the data phase. No parameters to the request. 54913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_total = filedata->filesize+PTP_USB_BULK_HDR_LEN*2; 54923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_complete = 0; 54933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = callback; 54943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = data; 54953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 54963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPDataHandler mtp_handler; 54973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_handler.getfunc = get_func; 54983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_handler.putfunc = NULL; 54993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev mtp_handler.priv = priv; 55003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPDataHandler handler; 55023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handler.getfunc = get_func_wrapper; 55033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handler.putfunc = NULL; 55043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handler.priv = &mtp_handler; 55053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobject_from_handler(params, &handler, filedata->filesize); 55073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->callback_active = 0; 55093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback = NULL; 55103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_usb->current_transfer_callback_data = NULL; 55113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_ERROR_CANCEL) { 55133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_CANCELLED, "LIBMTP_Send_File_From_Handler(): Cancelled transfer."); 55143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 55153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 55163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 55173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Send_File_From_Handler(): " 55183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Could not send object."); 55193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 55203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 55213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_object_to_cache(device, filedata->item_id); 55233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 55253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Get the device-assined parent_id from the cache. 55263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The operation that adds it to the cache will 55273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * look it up from the device, so we get the new 55283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parent_id from the cache. 55293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 55303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newfilemeta = LIBMTP_Get_Filemetadata(device, filedata->item_id); 55313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (newfilemeta != NULL) { 55323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->parent_id = newfilemeta->parent_id; 55333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->storage_id = newfilemeta->storage_id; 55343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_file_t(newfilemeta); 55353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 55363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, 55373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "LIBMTP_Send_File_From_Handler(): " 55383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Could not retrieve updated metadata."); 55393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 55403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 55413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 55433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 55443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 55463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function sends the file object info, ready for sendobject 55473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to send the file to. 55483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filedata a file metadata set to be written along with the file. 55493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 if the transfer was successful, any other value means 55503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * failure. 55513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 55523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int send_file_object_info(LIBMTP_mtpdevice_t *device, LIBMTP_file_t *filedata) 55533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 55543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 55553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 55563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t store; 5557ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev 5558ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev#ifdef _AFT_BUILD 5559ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev int use_primary_storage = 0; 5560ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev#else 55613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int use_primary_storage = 1; 5562ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev#endif 5563ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev 55643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t of = map_libmtp_type_to_ptp_type(filedata->filetype); 55653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_devicestorage_t *storage; 55663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t localph = filedata->parent_id; 55673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 55683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 55693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (filedata->storage_id != 0) { 55713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = filedata->storage_id; 55723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 55733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = get_writeable_storageid(device, filedata->filesize); 55743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 55753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Detect if something non-primary is in use. 55763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storage = device->storage; 55773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage != NULL && store != storage->id) { 55783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev use_primary_storage = 0; 55793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 55803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 55823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If no destination folder was given, look up a default 55833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * folder if possible. Perhaps there is some way of retrieveing 55843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the default folder for different forms of content, what 55853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * do I know, we use a fixed list in lack of any better method. 55863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Some devices obviously need to have their files in certain 55873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * folders in order to find/display them at all (hello Creative), 55883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * so we have to have a method for this. We only do this if the 55893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * primary storage is in use. 55903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 55913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 55923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (localph == 0 && use_primary_storage) { 55933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (LIBMTP_FILETYPE_IS_AUDIO(filedata->filetype)) { 55943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_music_folder; 55953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (LIBMTP_FILETYPE_IS_VIDEO(filedata->filetype)) { 55963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_video_folder; 55973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (of == PTP_OFC_EXIF_JPEG || 55983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_JP2 || 55993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_JPX || 56003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_JFIF || 56013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_TIFF || 56023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_TIFF_IT || 56033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_BMP || 56043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_GIF || 56053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_PICT || 56063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_PNG || 56073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_MTP_WindowsImageFormat) { 56083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_picture_folder; 56093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (of == PTP_OFC_MTP_vCalendar1 || 56103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_MTP_vCalendar2 || 56113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_MTP_UndefinedContact || 56123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_MTP_vCard2 || 56133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_MTP_vCard3 || 56143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of == PTP_OFC_MTP_UndefinedCalendarItem) { 56153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_organizer_folder; 56163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (of == PTP_OFC_Text) { 56173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_text_folder; 56183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 56193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 56203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5621ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev // default parent handle 5622ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev if (localph == 0) { 5623ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev localph = 0xFFFFFFFFU; // Set to -1 5624ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev } 5625ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev 56263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Here we wire the type to unknown on bugged, but 56273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ogg or FLAC-supportive devices. 56283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_OGG_IS_UNKNOWN(ptp_usb) && of == PTP_OFC_MTP_OGG) { 56293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of = PTP_OFC_Undefined; 56303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 56313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_FLAC_IS_UNKNOWN(ptp_usb) && of == PTP_OFC_MTP_FLAC) { 56323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of = PTP_OFC_Undefined; 56333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 56343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 56353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params, PTP_OC_MTP_SendObjectPropList) && 56363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_BROKEN_SEND_OBJECT_PROPLIST(ptp_usb)) { 56373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 56383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MTP enhanched does it this way (from a sniff): 56393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * -> PTP_OC_MTP_SendObjectPropList (0x9808): 56403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 20 00 00 00 01 00 08 98 1B 00 00 00 01 00 01 00 56413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * FF FF FF FF 00 30 00 00 00 00 00 00 12 5E 00 00 56423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Length: 0x00000020 56433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Type: 0x0001 PTP_USB_CONTAINER_COMMAND 56443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Code: 0x9808 56453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Transaction ID: 0x0000001B 56463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param1: 0x00010001 <- store 56473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param2: 0xffffffff <- parent handle (-1 ?) 56483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param3: 0x00003000 <- file type PTP_OFC_Undefined - we don't know about PDF files 56493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param4: 0x00000000 <- file length MSB (-0x0c header len) 56503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param5: 0x00005e12 <- file length LSB (-0x0c header len) 56513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 56523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * -> PTP_OC_MTP_SendObjectPropList (0x9808): 56533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 46 00 00 00 02 00 08 98 1B 00 00 00 03 00 00 00 56543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 00 00 00 07 DC FF FF 0D 4B 00 53 00 30 00 36 - dc07 = file name 56553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 30 00 33 00 30 00 36 00 2E 00 70 00 64 00 66 56563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 00 00 00 00 00 00 03 DC 04 00 00 00 00 00 00 - dc03 = protection status 56573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 4F DC 02 00 01 - dc4f = non consumable 56583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Length: 0x00000046 56593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Type: 0x0002 PTP_USB_CONTAINER_DATA 56603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Code: 0x9808 56613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Transaction ID: 0x0000001B 56623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Metadata.... 56633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x00000003 <- Number of metadata items 56643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x00000000 <- Object handle, set to 0x00000000 since it is unknown! 56653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0xdc07 <- metadata type: file name 56663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0xffff <- metadata type: string 56673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x0d <- number of (uint16_t) characters 56683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 4b 53 30 36 30 33 30 36 2e 50 64 66 00 "KS060306.pdf", null terminated 56693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x00000000 <- Object handle, set to 0x00000000 since it is unknown! 56703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0xdc03 <- metadata type: protection status 56713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x0004 <- metadata type: uint16_t 56723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x0000 <- not protected 56733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x00000000 <- Object handle, set to 0x00000000 since it is unknown! 56743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0xdc4f <- non consumable 56753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x0002 <- metadata type: uint8_t 56763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0x01 <- non-consumable (this device cannot display PDF) 56773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 56783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <- Read 0x18 bytes back 56793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 18 00 00 00 03 00 01 20 1B 00 00 00 01 00 01 00 56803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 00 00 00 01 40 00 00 56813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Length: 0x000000018 56823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Type: 0x0003 PTP_USB_CONTAINER_RESPONSE 56833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Code: 0x2001 PTP_OK 56843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Transaction ID: 0x0000001B 56853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param1: 0x00010001 <- store 56863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param2: 0x00000000 <- parent handle 56873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Param3: 0x00004001 <- new file/object ID 56883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 56893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * -> PTP_OC_SendObject (0x100d) 56903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0C 00 00 00 01 00 0D 10 1C 00 00 00 56913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * -> ... all the bytes ... 56923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <- Read 0x0c bytes back 56933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 0C 00 00 00 03 00 01 20 1C 00 00 00 56943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * ... Then update metadata one-by one, actually (instead of sending it first!) ... 56953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 56963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 56973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int nrofprops = 0; 56983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = NULL; 56993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *properties = NULL; 57003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 57013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Must be 0x00000000U for new objects 57033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->item_id = 0x00000000U; 57043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, of, &propcnt, &properties); 57063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 57083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 57093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, properties[i], of, &opd); 57113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 57123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "send_file_object_info(): " 57133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 57143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.GetSet) { 57153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 57163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectFileName: 57173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 57183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = filedata->item_id; 57193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_ObjectFileName; 57203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 57213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (filedata->filename != NULL) { 57223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(filedata->filename); 57233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) { 57243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strip_7bit_from_utf8(prop->propval.str); 57253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 57283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ProtectionStatus: 57293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 57303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = filedata->item_id; 57313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_ProtectionStatus; 57323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT16; 57333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u16 = 0x0000U; /* Not protected */ 57343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 57353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_NonConsumable: 57363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 57373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = filedata->item_id; 57383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_NonConsumable; 57393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT8; 57403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u8 = 0x00; /* It is supported, then it is consumable */ 57413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 57423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 57433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 57443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = filedata->item_id; 57453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Name; 57463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 57473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (filedata->filename != NULL) 57483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(filedata->filename); 57493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 57503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 57513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Tag with current time if that is supported 57523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 57533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 57543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = filedata->item_id; 57553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_DateModified; 57563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 57573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = get_iso8601_stamp(); 57583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->modificationdate = time(NULL); 57593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 57613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 57643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 57663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_sendobjectproplist(params, &store, &localph, &filedata->item_id, 57683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev of, filedata->filesize, props, nrofprops); 57693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Free property list */ 57713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_destroy_object_prop_list(props, nrofprops); 57723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 57743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "send_file_object_info():" 57753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Could not send object property list."); 57763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_AccessDenied) { 57773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "ACCESS DENIED."); 57783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 57803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (ptp_operation_issupported(params,PTP_OC_SendObjectInfo)) { 57823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectInfo new_file; 57833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(&new_file, 0, sizeof(PTPObjectInfo)); 57853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 57863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_file.Filename = filedata->filename; 57873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) { 57883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strip_7bit_from_utf8(new_file.Filename); 57893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 57903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We lose precision here. 57913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_file.ObjectCompressedSize = (uint32_t) filedata->filesize; 57923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_file.ObjectFormat = of; 57933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_file.StorageID = store; 57943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_file.ParentObject = localph; 57953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_file.ModificationDate = time(NULL); 57963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Create the object 5797ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev 57983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobjectinfo(params, &store, &localph, &filedata->item_id, &new_file); 57993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 58013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "send_file_object_info(): " 58023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Could not send object info."); 58033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_AccessDenied) { 58043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "ACCESS DENIED."); 58053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 58063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 58073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 58083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // NOTE: the char* pointers inside new_file are not copies so don't 58093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // try to destroy this objectinfo! 58103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 58113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Now there IS an object with this parent handle. 58133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filedata->parent_id = localph; 58143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 58163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 58173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 58193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function updates the MTP track object metadata on a 58203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * single file identified by an object ID. 58213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to update the track 58223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * metadata on. 58233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata a track metadata set to be written to the file. 58243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * notice that the <code>track_id</code> field of the 58253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * metadata structure must be correct so that the 58263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * function can update the right file. If some properties 58273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * of this metadata are set to NULL (strings) or 0 58283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (numerical values) they will be discarded and the 58293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * track will not be tagged with these blank values. 58303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. If some 58313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or all of the properties fail to update we will still 58323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * return success. On some devices (notably iRiver T30) 58333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * properties that exist cannot be updated. 58343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 58353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Update_Track_Metadata(LIBMTP_mtpdevice_t *device, 58363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t const * const metadata) 58373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 58383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 58393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 58403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 58413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 58423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *properties = NULL; 58433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 58443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be set on this file format and apply accordingly 58463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // i.e only try to update this metadata for object tags that exist on the current player. 58473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, map_libmtp_type_to_ptp_type(metadata->filetype), &propcnt, &properties); 58483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 58493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just bail out for now, nothing is ever set. 58503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 58513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not retrieve supported object properties."); 58523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 58533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 58543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjPropList) && 58553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_BROKEN_SET_OBJECT_PROPLIST(ptp_usb)) { 58563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 58573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = NULL; 58583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int nrofprops = 0; 58593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 58613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 58623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 58633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, properties[i], map_libmtp_type_to_ptp_type(metadata->filetype), &opd); 58643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 58653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 58663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 58673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.GetSet) { 58683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 58693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 58703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->title == NULL) 58713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 58733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 58743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Name; 58753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 58763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(metadata->title); 58773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumName: 58793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->album == NULL) 58803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 58823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 58833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_AlbumName; 58843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 58853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(metadata->album); 58863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 58883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->artist == NULL) 58893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 58913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 58923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Artist; 58933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 58943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(metadata->artist); 58953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 58973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->composer == NULL) 58983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 58993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Composer; 59023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 59033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(metadata->composer); 59043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 59063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->genre == NULL) 59073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Genre; 59113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 59123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(metadata->genre); 59133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Duration: 59153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Duration; 59183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT32; 59193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u32 = adjust_u32(metadata->duration, &opd); 59203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Track: 59223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Track; 59253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT16; 59263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u16 = adjust_u16(metadata->tracknumber, &opd); 59273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_OriginalReleaseDate: 59293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->date == NULL) 59303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_OriginalReleaseDate; 59343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 59353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(metadata->date); 59363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_SampleRate: 59383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_SampleRate; 59413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT32; 59423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u32 = adjust_u32(metadata->samplerate, &opd); 59433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_NumberOfChannels: 59453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_NumberOfChannels; 59483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT16; 59493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u16 = adjust_u16(metadata->nochannels, &opd); 59503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioWAVECodec: 59523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_AudioWAVECodec; 59553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT32; 59563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u32 = adjust_u32(metadata->wavecodec, &opd); 59573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioBitRate: 59593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_AudioBitRate; 59623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT32; 59633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u32 = adjust_u32(metadata->bitrate, &opd); 59643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_BitRateType: 59663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_BitRateType; 59693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT16; 59703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u16 = adjust_u16(metadata->bitratetype, &opd); 59713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Rating: 59733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: shall this be set for rating 0? 59743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->rating == 0) 59753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Rating; 59793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT16; 59803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u16 = adjust_u16(metadata->rating, &opd); 59813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_UseCount: 59833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_UseCount; 59863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT32; 59873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u32 = adjust_u32(metadata->usecount, &opd); 59883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 59903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 59913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Tag with current time if that is supported 59923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 59933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = metadata->item_id; 59943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_DateModified; 59953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 59963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = get_iso8601_stamp(); 59973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 59983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 59993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 60003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 60043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 60063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // NOTE: File size is not updated, this should not change anyway. 60073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // neither will we change the filename. 60083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 60093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectproplist(params, props, nrofprops); 60103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 60113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_destroy_object_prop_list(props, nrofprops); 60123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 60133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 60143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: return error of which property we couldn't set 60153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set object property list."); 60173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 60183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 60193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 60213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (ptp_operation_issupported(params,PTP_OC_MTP_SetObjectPropValue)) { 60223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 60233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 60243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 60253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, properties[i], map_libmtp_type_to_ptp_type(metadata->filetype), &opd); 60263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 60273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 60293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.GetSet) { 60303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 60313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 60323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update title 60333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_Name, metadata->title); 60343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track title."); 60373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumName: 60403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update album 60413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_AlbumName, metadata->album); 60423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track album name."); 60453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 60483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update artist 60493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_Artist, metadata->artist); 60503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track artist name."); 60533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 60563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update composer 60573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_Composer, metadata->composer); 60583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track composer name."); 60613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 60643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update genre 60653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_Genre, metadata->genre); 60663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track genre name."); 60693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Duration: 60723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update duration 60733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->duration != 0) { 60743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u32(device, metadata->item_id, PTP_OPC_Duration, adjust_u32(metadata->duration, &opd)); 60753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track duration."); 60783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Track: 60823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update track number. 60833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->tracknumber != 0) { 60843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u16(device, metadata->item_id, PTP_OPC_Track, adjust_u16(metadata->tracknumber, &opd)); 60853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track tracknumber."); 60883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_OriginalReleaseDate: 60923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update creation datetime 60933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_OriginalReleaseDate, metadata->date); 60943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 60953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 60963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set track release date."); 60973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 60983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 60993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // These are, well not so important. 61003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_SampleRate: 61013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update sample rate 61023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->samplerate != 0) { 61033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u32(device, metadata->item_id, PTP_OPC_SampleRate, adjust_u32(metadata->samplerate, &opd)); 61043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set samplerate."); 61073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_NumberOfChannels: 61113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update number of channels 61123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->nochannels != 0) { 61133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u16(device, metadata->item_id, PTP_OPC_NumberOfChannels, adjust_u16(metadata->nochannels, &opd)); 61143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set number of channels."); 61173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioWAVECodec: 61213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update WAVE codec 61223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->wavecodec != 0) { 61233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u32(device, metadata->item_id, PTP_OPC_AudioWAVECodec, adjust_u32(metadata->wavecodec, &opd)); 61243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set WAVE codec."); 61273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AudioBitRate: 61313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update bitrate 61323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->bitrate != 0) { 61333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u32(device, metadata->item_id, PTP_OPC_AudioBitRate, adjust_u32(metadata->bitrate, &opd)); 61343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set bitrate."); 61373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_BitRateType: 61413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update bitrate type 61423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->bitratetype != 0) { 61433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u16(device, metadata->item_id, PTP_OPC_BitRateType, adjust_u16(metadata->bitratetype, &opd)); 61443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set bitratetype."); 61473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Rating: 61513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update user rating 61523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: shall this be set for rating 0? 61533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (metadata->rating != 0) { 61543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u16(device, metadata->item_id, PTP_OPC_Rating, adjust_u16(metadata->rating, &opd)); 61553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set user rating."); 61583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_UseCount: 61623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update use count, set even to zero if desired. 61633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_u32(device, metadata->item_id, PTP_OPC_UseCount, adjust_u32(metadata->usecount, &opd)); 61643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set use count."); 61673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 61703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 61713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update modification time if supported 61723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *tmpstamp = get_iso8601_stamp(); 61733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, metadata->item_id, PTP_OPC_DateModified, tmpstamp); 61743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 61753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set modification date."); 61773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(tmpstamp); 61793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 61823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // NOTE: File size is not updated, this should not change anyway. 61833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // neither will we change the filename. 61843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 61853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 61863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 61893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 61913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Update_Track_Metadata(): " 61923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Your device doesn't seem to support any known way of setting metadata."); 61933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 61943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 61953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 61963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 61973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // update cached object properties if metadata cache exists 61983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev update_metadata_cache(device, metadata->item_id); 61993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 62013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 62033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 62043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 62063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function deletes a single file, track, playlist, folder or 62073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * any other object off the MTP device, identified by the object ID. 62083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 62093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If you delete a folder, there is no guarantee that the device will 62103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * really delete all the files that were in that folder, rather it is 62113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * expected that they will not be deleted, and will turn up in object 62123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * listings with parent set to a non-existant object ID. The safe way 62133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to do this is to recursively delete all files (and folders) contained 62143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in the folder, then the folder itself. 62153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 62163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to delete the object from. 62173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id the object to delete. 62183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 62193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 62203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Delete_Object(LIBMTP_mtpdevice_t *device, 62213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t object_id) 62223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 62233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 62243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 62253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_deleteobject(params, object_id, 0); 62273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 62283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Delete_Object(): could not delete object."); 62293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 62303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 62313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 62333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 62343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 62363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Internal function to update an object filename property. 62373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 62383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int set_object_filename(LIBMTP_mtpdevice_t *device, 62393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t object_id, uint16_t ptp_type, 62403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const char **newname_ptr) 62413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 62423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 62433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 62443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 62453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 62463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *newname; 62473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // See if we can modify the filename on this kind of files. 62493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, PTP_OPC_ObjectFileName, ptp_type, &opd); 62503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 62513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): " 62523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 62533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 62543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 62553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!opd.GetSet) { 62573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 62583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): " 62593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev " property is not settable."); 62603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: we COULD actually upload/download the object here, if we feel 62613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // like wasting time for the user. 62623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 62633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 62643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev newname = strdup(*newname_ptr); 62663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) { 62683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strip_7bit_from_utf8(newname); 62693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 62703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjPropList) && 62723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_BROKEN_SET_OBJECT_PROPLIST(ptp_usb)) { 62733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 62743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = NULL; 62753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int nrofprops = 0; 62763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 62783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = object_id; 62793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_ObjectFileName; 62803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 62813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = newname; 62823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectproplist(params, props, nrofprops); 62843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_destroy_object_prop_list(props, nrofprops); 62863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 62873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 62883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): " 62893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev " could not set object property list."); 62903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 62913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 62923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 62933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (ptp_operation_issupported(params, PTP_OC_MTP_SetObjectPropValue)) { 62943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, object_id, PTP_OPC_ObjectFileName, newname); 62953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 62963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): " 62973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev " could not set object filename."); 62983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 62993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 63003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 63013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 63023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(newname); 63033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "set_object_filename(): " 63043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev " your device doesn't seem to support any known way of setting metadata."); 63053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 63063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 63073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 63083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 63103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // update cached object properties if metadata cache exists 63123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev update_metadata_cache(device, object_id); 63133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 63153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 63163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 63183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function renames a single file. 63193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This simply means that the PTP_OPC_ObjectFileName property 63203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * is updated, if this is supported by the device. 63213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 63223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device that contains the file. 63233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param file the file metadata of the file to rename. 63243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * On success, the filename member is updated. Be aware, that 63253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this name can be different than newname depending of device restrictions. 63263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param newname the new filename for this object. 63273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 63283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 63293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_File_Name(LIBMTP_mtpdevice_t *device, 63303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *file, const char *newname) 63313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 63323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 63333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_filename(device, file->item_id, 63353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev map_libmtp_type_to_ptp_type(file->filetype), 63363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &newname); 63373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 63393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 63403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 63413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(file->filename); 63433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file->filename = strdup(newname); 63443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 63453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 63463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 63483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function renames a single folder. 63493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This simply means that the PTP_OPC_ObjectFileName property 63503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * is updated, if this is supported by the device. 63513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 63523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device that contains the file. 63533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param folder the folder metadata of the folder to rename. 63543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * On success, the name member is updated. Be aware, that 63553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this name can be different than newname depending of device restrictions. 63563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param newname the new name for this object. 63573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 63583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 63593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Folder_Name(LIBMTP_mtpdevice_t *device, 63603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t *folder, const char* newname) 63613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 63623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 63633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_filename(device, folder->folder_id, 63653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_Association, 63663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &newname); 63673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 63693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 63703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 63713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(folder->name); 63733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->name = strdup(newname); 63743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 63753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 63763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 63783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function renames a single track. 63793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This simply means that the PTP_OPC_ObjectFileName property 63803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * is updated, if this is supported by the device. 63813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 63823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device that contains the file. 63833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param track the track metadata of the track to rename. 63843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * On success, the filename member is updated. Be aware, that 63853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this name can be different than newname depending of device restrictions. 63863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param newname the new filename for this object. 63873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 63883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 63893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Track_Name(LIBMTP_mtpdevice_t *device, 63903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_track_t *track, const char* newname) 63913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 63923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 63933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_filename(device, track->item_id, 63953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev map_libmtp_type_to_ptp_type(track->filetype), 63963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &newname); 63973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 63983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 63993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 64003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 64013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(track->filename); 64033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev track->filename = strdup(newname); 64043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 64053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 64063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 64083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function renames a single playlist object file holder. 64093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This simply means that the <code>PTP_OPC_ObjectFileName</code> 64103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * property is updated, if this is supported by the device. 64113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The playlist filename should nominally end with an extension 64123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * like ".pla". 64133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 64143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * NOTE: if you want to change the metadata the device display 64153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * about a playlist you must <i>not</i> use this function, 64163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * use <code>LIBMTP_Update_Playlist()</code> instead! 64173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 64183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device that contains the file. 64193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param playlist the playlist metadata of the playlist to rename. 64203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * On success, the name member is updated. Be aware, that 64213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this name can be different than newname depending of device restrictions. 64223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param newname the new name for this object. 64233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 64243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Update_Playlist() 64253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 64263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Playlist_Name(LIBMTP_mtpdevice_t *device, 64273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t *playlist, const char* newname) 64283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 64293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 64303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_filename(device, playlist->playlist_id, 64323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_MTP_AbstractAudioVideoPlaylist, 64333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &newname); 64343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 64363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 64373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 64383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(playlist->name); 64403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev playlist->name = strdup(newname); 64413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 64423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 64433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 64453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function renames a single album. 64463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This simply means that the <code>PTP_OPC_ObjectFileName</code> 64473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * property is updated, if this is supported by the device. 64483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * The album filename should nominally end with an extension 64493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * like ".alb". 64503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 64513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * NOTE: if you want to change the metadata the device display 64523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * about a playlist you must <i>not</i> use this function, 64533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * use <code>LIBMTP_Update_Album()</code> instead! 64543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 64553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device that contains the file. 64563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param album the album metadata of the album to rename. 64573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * On success, the name member is updated. Be aware, that 64583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * this name can be different than newname depending of device restrictions. 64593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param newname the new name for this object. 64603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 64613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Update_Album() 64623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 64633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Album_Name(LIBMTP_mtpdevice_t *device, 64643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *album, const char* newname) 64653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 64663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 64673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_filename(device, album->album_id, 64693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_MTP_AbstractAudioAlbum, 64703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &newname); 64713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 64733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 64743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 64753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album->name); 64773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev album->name = strdup(newname); 64783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 64793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 64803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 64823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * THIS FUNCTION IS DEPRECATED. PLEASE UPDATE YOUR CODE IN ORDER 64833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * NOT TO USE IT. 64843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 64853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_File_Name() 64863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_Track_Name() 64873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_Folder_Name() 64883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_Playlist_Name() 64893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Set_Album_Name() 64903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 64913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Set_Object_Filename(LIBMTP_mtpdevice_t *device, 64923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t object_id, char* newname) 64933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 64943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ret; 64953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_file_t *file; 64963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev file = LIBMTP_Get_Filemetadata(device, object_id); 64983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 64993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (file == NULL) { 65003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Set_Object_Filename(): " 65013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get file metadata for target object."); 65023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 65033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 65043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_filename(device, object_id, map_libmtp_type_to_ptp_type(file->filetype), (const char **) &newname); 65063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(file); 65083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 65103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 65113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 65133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Helper function. This indicates if a track exists on the device 65143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track from. 65153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id the track ID of the track to retrieve. 65163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return TRUE (!=0) if the track exists, FALSE (0) if not 65173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 65183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Track_Exists(LIBMTP_mtpdevice_t *device, 65193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id) 65203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 65213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 65223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 65233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 65243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, id, 0, &ob); 65263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_OK) 65273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 65283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 65293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 65303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 65323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a new folder structure and allocates memory 65333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for it. Notice that if you add strings to this structure they 65343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will be freed by the corresponding <code>LIBMTP_folder_track_t</code> 65353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation later, so be careful of using strdup() when assigning 65363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings, e.g.: 65373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 65383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a pointer to the newly allocated folder structure. 65393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_destroy_folder_t() 65403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 65413aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_folder_t *LIBMTP_new_folder_t(void) 65423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 65433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t *new = (LIBMTP_folder_t *) malloc(sizeof(LIBMTP_folder_t)); 65443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (new == NULL) { 65453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 65463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 65473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->folder_id = 0; 65483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->parent_id = 0; 65493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->storage_id = 0; 65503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->name = NULL; 65513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->sibling = NULL; 65523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->child = NULL; 65533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new; 65543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 65553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 65573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This recursively deletes the memory for a folder structure. 65583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This shall typically be called on a top-level folder list to 65593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * detsroy the entire folder tree. 65603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 65613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param folder folder structure to destroy 65623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_new_folder_t() 65633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 65643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_folder_t(LIBMTP_folder_t *folder) 65653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 65663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folder == NULL) { 65683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 65693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 65703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev //Destroy from the bottom up 65723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folder->child != NULL) { 65733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_folder_t(folder->child); 65743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 65753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folder->sibling != NULL) { 65773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_folder_t(folder->sibling); 65783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 65793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folder->name != NULL) { 65813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(folder->name); 65823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 65833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(folder); 65853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 65863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 65883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Helper function. Returns a folder structure for a 65893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * specified id. 65903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 65913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param folderlist list of folders to search 65923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @id id of folder to look for 65933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a folder or NULL if not found 65943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 65953aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_folder_t *LIBMTP_Find_Folder(LIBMTP_folder_t *folderlist, uint32_t id) 65963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 65973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t *ret = NULL; 65983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 65993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folderlist == NULL) { 66003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 66013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folderlist->folder_id == id) { 66043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return folderlist; 66053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folderlist->sibling) { 66083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = LIBMTP_Find_Folder(folderlist->sibling, id); 66093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(folderlist->child && ret == NULL) { 66123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = LIBMTP_Find_Folder(folderlist->child, id); 66133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ret; 66163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 66173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 66193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Function used to recursively get subfolders from params. 66203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 66213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic LIBMTP_folder_t *get_subfolders_for_folder(LIBMTP_folder_t *list, uint32_t parent) 66223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 66233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t *retfolders = NULL, *children, *iter, *curr; 66243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev iter = list->sibling; 66263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(iter != list) { 66273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (iter->parent_id != parent) { 66283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev iter = iter->sibling; 66293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 66303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* We know that iter is a child of 'parent', therefore we can safely 66333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * hold on to 'iter' locally since no one else will steal it 66343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * from the 'list' as we recurse. */ 66353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev children = get_subfolders_for_folder(list, iter->folder_id); 66363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr = iter; 66383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev iter = iter->sibling; 66393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Remove curr from the list. 66413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->child->sibling = curr->sibling; 66423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->sibling->child = curr->child; 66433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Attach the children to curr. 66453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->child = children; 66463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Put this folder into the list of siblings. 66483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->sibling = retfolders; 66493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retfolders = curr; 66503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retfolders; 66533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 66543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 66563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This returns a list of all folders available 66573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on the current MTP device. 66583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 66593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the folder listing for. 66603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a list of folders 66613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 66623aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_folder_t *LIBMTP_Get_Folder_List(LIBMTP_mtpdevice_t *device) 66633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 66643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 66653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t head, *rv; 66663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 66673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 66693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 66703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 66713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 66743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a temporary list of the folders, this is in a 66753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * reverse order and uses the Folder pointers that are already 66763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in the Folder structure. From this we can then build up the 66773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * folder hierarchy with only looking at this temporary list, 66783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and removing the folders from this temporary list as we go. 66793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This significantly reduces the number of operations that we 66803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * have to do in building the folder hierarchy. Also since the 66813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * temp list is in reverse order, when we prepend to the sibling 66823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list things are in the same order as they were originally 66833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * in the handle list. 66843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 66853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev head.sibling = &head; 66863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev head.child = &head; 66873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < params->nrofobjects; i++) { 66883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t *folder; 66893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 66903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 66913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob = ¶ms->objects[i]; 66923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat != PTP_OFC_Association) { 66933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 66943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 66953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 66963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Do we know how to handle these? They are part 66973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * of the MTP 1.0 specification paragraph 3.6.4. 66983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * For AssociationDesc 0x00000001U ptp_mtp_getobjectreferences() 66993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * should be called on these to get the contained objects, but 67003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * we basically don't care. Hopefully parent_id is maintained for all 67013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * children, because we rely on that instead. 67023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 67033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.AssociationDesc != 0x00000000U) { 67043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("MTP extended association type 0x%08x encountered\n", ob->oi.AssociationDesc); 67053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 67063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Create a folder struct... 67083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder = LIBMTP_new_folder_t(); 67093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (folder == NULL) { 67103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // malloc failure or so. 67113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 67123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 67133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->folder_id = ob->oid; 67143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->parent_id = ob->oi.ParentObject; 67153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->storage_id = ob->oi.StorageID; 67163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->name = (ob->oi.Filename) ? (char *)strdup(ob->oi.Filename) : NULL; 67173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // pretend sibling says next, and child says prev. 67193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->sibling = head.sibling; 67203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev folder->child = &head; 67213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev head.sibling->child = folder; 67223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev head.sibling = folder; 67233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 67243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // We begin at the root folder and get them all recursively 67263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev rv = get_subfolders_for_folder(&head, 0x00000000); 67273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // The temp list should be empty. Clean up any orphans just in case. 67293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while(head.sibling != &head) { 67303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_folder_t *curr = head.sibling; 67313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Orphan folder with ID: 0x%08x name: \"%s\" encountered.\n", 67333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->folder_id, 67343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->name); 67353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->sibling->child = curr->child; 67363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->child->sibling = curr->sibling; 67373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->child = NULL; 67383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curr->sibling = NULL; 67393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_destroy_folder_t(curr); 67403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 67413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return rv; 67433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 67443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 67463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This create a folder on the current MTP device. The PTP name 67473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for a folder is "association". The PTP/MTP devices does not 67483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * have an internal "folder" concept really, it contains a flat 67493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * list of all files and some file are "associations" that other 67503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * files and folders may refer to as its "parent". 67513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 67523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to create the folder on. 67533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param name the name of the new folder. Note this can be modified 67543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * if the device does not support all the characters in the 67553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * name. 67563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param parent_id id of parent folder to add the new folder to, 67573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or 0 to put it in the root directory. 67583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param storage_id id of the storage to add this new folder to. 67593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * notice that you cannot mismatch storage id and parent id: 67603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * they must both be on the same storage! Pass in 0 if you 67613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * want to create this folder on the default storage. 67623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return id to new folder or 0 if an error occured 67633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 67643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevuint32_t LIBMTP_Create_Folder(LIBMTP_mtpdevice_t *device, char *name, 67653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t parent_id, uint32_t storage_id) 67663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 67673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 67683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 67693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t parenthandle = 0; 67703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t store; 67713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectInfo new_folder; 67723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 67733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t new_id = 0; 67743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storage_id == 0) { 67763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // I'm just guessing that a folder may require 512 bytes 67773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = get_writeable_storageid(device, 512); 67783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 67793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = storage_id; 67803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 6781ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev 6782ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev if (parent_id == 0) { 6783ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev parent_id = 0xFFFFFFFFU; // Set to -1 6784ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev } 6785ad8fdfb856407f0c1f2c2b0305c8fa0a062736b1Yavor Goulishev 67863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev parenthandle = parent_id; 67873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 67883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(&new_folder, 0, sizeof(new_folder)); 67893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.Filename = name; 67903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) { 67913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strip_7bit_from_utf8(new_folder.Filename); 67923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 67933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.ObjectCompressedSize = 1; 67943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.ObjectFormat = PTP_OFC_Association; 67953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.ProtectionStatus = PTP_PS_NoProtection; 67963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.AssociationType = PTP_AT_GenericFolder; 67973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.ParentObject = parent_id; 67983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_folder.StorageID = store; 67993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Create the object 68013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // FIXME: use send list here if available. 68023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobjectinfo(params, &store, &parenthandle, &new_id, &new_folder); 68033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 68043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Create_Folder: Could not send object info."); 68053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_AccessDenied) { 68063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "ACCESS DENIED."); 68073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 68083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 68093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 68103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // NOTE: don't destroy the new_folder objectinfo, because it is statically referencing 68113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // several strings. 68123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_object_to_cache(device, new_id); 68143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new_id; 68163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 68173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 68193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a new playlist metadata structure and allocates memory 68203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for it. Notice that if you add strings to this structure they 68213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will be freed by the corresponding <code>LIBMTP_destroy_playlist_t</code> 68223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation later, so be careful of using strdup() when assigning 68233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings, e.g.: 68243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 68253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <pre> 68263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_playlist_t *pl = LIBMTP_new_playlist_t(); 68273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pl->name = strdup(str); 68283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * .... 68293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * LIBMTP_destroy_playlist_t(pl); 68303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </pre> 68313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 68323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a pointer to the newly allocated metadata structure. 68333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_destroy_playlist_t() 68343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 68353aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_playlist_t *LIBMTP_new_playlist_t(void) 68363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 68373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t *new = (LIBMTP_playlist_t *) malloc(sizeof(LIBMTP_playlist_t)); 68383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (new == NULL) { 68393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 68403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 68413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->playlist_id = 0; 68423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->parent_id = 0; 68433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->storage_id = 0; 68443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->name = NULL; 68453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->tracks = NULL; 68463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->no_tracks = 0; 68473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->next = NULL; 68483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new; 68493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 68503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 68523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This destroys a playlist metadata structure and deallocates the memory 68533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * used by it, including any strings. Never use a track metadata 68543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * structure again after calling this function on it. 68553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param playlist the playlist metadata to destroy. 68563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_new_playlist_t() 68573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 68583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_playlist_t(LIBMTP_playlist_t *playlist) 68593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 68603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (playlist == NULL) { 68613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 68623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 68633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (playlist->name != NULL) 68643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(playlist->name); 68653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (playlist->tracks != NULL) 68663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(playlist->tracks); 68673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(playlist); 68683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 68693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 68703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 68723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function returns a list of the playlists available on the 68733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * device. Typical usage: 68743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 68753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <pre> 68763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </pre> 68773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 68783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the playlist listing from. 68793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a playlist list on success, else NULL. If there are no playlists 68803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on the device, NULL will be returned as well. 68813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Playlist() 68823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 68833aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_playlist_t *LIBMTP_Get_Playlist_List(LIBMTP_mtpdevice_t *device) 68843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 68853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 68863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const int REQ_SPL = FLAG_PLAYLIST_SPL(ptp_usb); 68873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 68883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t *retlists = NULL; 68893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t *curlist = NULL; 68903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 68913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 68933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 68943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 68953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 68963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 68973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < params->nrofobjects; i++) { 68983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t *pl; 68993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 69003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 69013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob = ¶ms->objects[i]; 69033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore stuff that isn't playlists 69053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // For Samsung players we must look for the .spl extension explicitly since 69073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // playlists are not stored as playlist objects. 69083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( REQ_SPL && is_spl_playlist(&ob->oi) ) { 69093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new playlist type 69103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl = LIBMTP_new_playlist_t(); 69113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev spl_to_playlist_t(device, &ob->oi, ob->oid, pl); 69123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if ( ob->oi.ObjectFormat != PTP_OFC_MTP_AbstractAudioVideoPlaylist ) { 69143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 69153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else { 69173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new playlist type 69183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl = LIBMTP_new_playlist_t(); 69193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Try to look up proper name, else use the oi->Filename field. 69213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->name = get_string_from_object(device, ob->oid, PTP_OPC_Name); 69223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (pl->name == NULL) { 69233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->name = strdup(ob->oi.Filename); 69243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->playlist_id = ob->oid; 69263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->parent_id = ob->oi.ParentObject; 69273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->storage_id = ob->oi.StorageID; 69283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Then get the track listing for this playlist 69303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectreferences(params, pl->playlist_id, &pl->tracks, &pl->no_tracks); 69313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 69323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Playlist_List(): " 69333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get object references."); 69343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->tracks = NULL; 69353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->no_tracks = 0; 69363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add playlist to a list that will be returned afterwards. 69403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (retlists == NULL) { 69413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retlists = pl; 69423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curlist = pl; 69433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 69443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curlist->next = pl; 69453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curlist = pl; 69463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Call callback here if we decide to add that possibility... 69493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retlists; 69513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 69523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 69553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves an individual playlist from the device. 69563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the playlist from. 69573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param plid the unique ID of the playlist to retrieve. 69583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a valid playlist metadata post or NULL on failure. 69593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Playlist_List() 69603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 69613aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_playlist_t *LIBMTP_Get_Playlist(LIBMTP_mtpdevice_t *device, uint32_t const plid) 69623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 69633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 69643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const int REQ_SPL = FLAG_PLAYLIST_SPL(ptp_usb); 69653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 69663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 69673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t *pl; 69683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 69693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 69713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) { 69723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 69733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, plid, PTPOBJECT_OBJECTINFO_LOADED, &ob); 69763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) 69773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 69783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // For Samsung players we must look for the .spl extension explicitly since 69803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // playlists are not stored as playlist objects. 69813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( REQ_SPL && is_spl_playlist(&ob->oi) ) { 69823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new playlist type 69833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl = LIBMTP_new_playlist_t(); 69843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev spl_to_playlist_t(device, &ob->oi, ob->oid, pl); 69853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return pl; 69863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore stuff that isn't playlists 69893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else if ( ob->oi.ObjectFormat != PTP_OFC_MTP_AbstractAudioVideoPlaylist ) { 69903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 69913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 69923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new playlist type 69943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl = LIBMTP_new_playlist_t(); 69953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 69963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->name = get_string_from_object(device, ob->oid, PTP_OPC_Name); 69973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (pl->name == NULL) { 69983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->name = strdup(ob->oi.Filename); 69993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->playlist_id = ob->oid; 70013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->parent_id = ob->oi.ParentObject; 70023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->storage_id = ob->oi.StorageID; 70033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Then get the track listing for this playlist 70053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectreferences(params, pl->playlist_id, &pl->tracks, &pl->no_tracks); 70063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 70073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Playlist(): Could not get object references."); 70083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->tracks = NULL; 70093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pl->no_tracks = 0; 70103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return pl; 70133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 70143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 70163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function creates a new abstract list such as a playlist 70173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * or an album. 70183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 70193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to create the new abstract list 70203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on. 70213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param name the name of the new abstract list. 70223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param artist the artist of the new abstract list or NULL. 70233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param genre the genre of the new abstract list or NULL. 70243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param parenthandle the handle of the parent or 0 for no parent 70253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * i.e. the root folder. 70263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param objectformat the abstract list type to create. 70273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param suffix the ".foo" (4 characters) suffix to use for the virtual 70283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * "file" created by this operation. 70293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param newid a pointer to a variable that will hold the new object 70303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * ID if this call is successful. 70313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param tracks an array of tracks to associate with this list. 70323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param no_tracks the number of tracks in the list. 70333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 70343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 70353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int create_new_abstract_list(LIBMTP_mtpdevice_t *device, 70363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const name, 70373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const artist, 70383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const composer, 70393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const genre, 70403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const parenthandle, 70413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const storageid, 70423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const objectformat, 70433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const suffix, 70443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t * const newid, 70453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const * const tracks, 70463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const no_tracks) 70473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 70493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 70503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int supported = 0; 70513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 70523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *properties = NULL; 70533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 70543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t store; 70553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t localph = parenthandle; 70563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t nonconsumable = 0x00U; /* By default it is consumable */ 70573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 70583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 70593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char fname[256]; 70603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t data[2]; 70613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storageid == 0) { 70633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // I'm just guessing that an abstract list may require 512 bytes 70643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = get_writeable_storageid(device, 512); 70653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 70663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev store = storageid; 70673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Check if we can create an object of this type 70703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for ( i=0; i < params->deviceinfo.ImageFormats_len; i++ ) { 70713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->deviceinfo.ImageFormats[i] == objectformat) { 70723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev supported = 1; 70733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 70743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!supported) { 70773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): player does not support this abstract type."); 70783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev printf("Unsupported abstract list type: %04x\n", objectformat); 70793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 70803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // add the new suffix if it isn't there 70833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fname[0] = '\0'; 70843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (strlen(name) > strlen(suffix)) { 70853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const suff = &name[strlen(name)-strlen(suffix)]; 70863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!strcmp(suff, suffix)) { 70873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Home free. 70883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy(fname, name, sizeof(fname)); 70893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // If it didn't end with "<suffix>" then add that here. 70923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (fname[0] == '\0') { 70933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy(fname, name, sizeof(fname)-strlen(suffix)-1); 70943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strcat(fname, suffix); 70953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fname[sizeof(fname)-1] = '\0'; 70963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 70973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 70983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params, PTP_OC_MTP_SendObjectPropList) && 70993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_BROKEN_SEND_OBJECT_PROPLIST(ptp_usb)) { 71003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 71013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = NULL; 71023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int nrofprops = 0; 71033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 71043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *newid = 0x00000000U; 71053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 71063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, objectformat, &propcnt, &properties); 71073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 71083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 71093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 71103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 71113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, properties[i], objectformat, &opd); 71123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 71133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): " 71143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 71153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.GetSet) { 71163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 71173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ObjectFileName: 71183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_ObjectFileName; 71213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(fname); 71233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) { 71243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strip_7bit_from_utf8(prop->propval.str); 71253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_ProtectionStatus: 71283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_ProtectionStatus; 71313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT16; 71323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u16 = 0x0000U; /* Not protected */ 71333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_NonConsumable: 71353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_NonConsumable; 71383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_UINT8; 71393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.u8 = nonconsumable; 71403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 71423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (name != NULL) { 71433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Name; 71463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(name); 71483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumArtist: 71513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (artist != NULL) { 71523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_AlbumArtist; 71553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(artist); 71573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 71603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (artist != NULL) { 71613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Artist; 71643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(artist); 71663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 71693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (composer != NULL) { 71703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Composer; 71733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(composer); 71753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 71783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (genre != NULL) { 71793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Genre; 71823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(genre); 71843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 71873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Tag with current time if that is supported 71883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 71893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props,&nrofprops); 71903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = *newid; 71913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_DateModified; 71923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 71933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = get_iso8601_stamp(); 71943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 71963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 71983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 71993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 72013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_sendobjectproplist(params, &store, &localph, newid, 72033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev objectformat, 0, props, nrofprops); 72043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Free property list */ 72063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_destroy_object_prop_list(props, nrofprops); 72073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 72093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "create_new_abstract_list(): Could not send object property list."); 72103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_AccessDenied) { 72113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "ACCESS DENIED."); 72123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // now send the blank object 72173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobject(params, NULL, 0); 72183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 72193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "create_new_abstract_list(): Could not send blank object data."); 72203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (ptp_operation_issupported(params,PTP_OC_SendObjectInfo)) { 72243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectInfo new_object; 72253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_object.Filename = fname; 72273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (FLAG_ONLY_7BIT_FILENAMES(ptp_usb)) { 72283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strip_7bit_from_utf8(new_object.Filename); 72293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_object.ObjectCompressedSize = 1; 72313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new_object.ObjectFormat = objectformat; 72323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Create the object 72343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobjectinfo(params, &store, &localph, newid, &new_object); 72353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 72363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "create_new_abstract_list(): Could not send object info (the playlist itself)."); 72373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret == PTP_RC_AccessDenied) { 72383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "ACCESS DENIED."); 72393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // NOTE: don't destroy new_object objectinfo afterwards - the strings it contains are 72433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // not copies. 72443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 72453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * We have to send this one blank data byte. 72463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If we don't, the handle will not be created and thus there is no playlist. 72473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 72483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data[0] = '\0'; 72493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data[1] = '\0'; 72503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_sendobject(params, data, 1); 72513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 72523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "create_new_abstract_list(): Could not send blank object data."); 72533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // set the properties one by one 72573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, objectformat, &propcnt, &properties); 72583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 72603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 72613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 72623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, properties[i], objectformat, &opd); 72633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 72643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): " 72653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 72663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.GetSet) { 72673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 72683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 72693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (name != NULL) { 72703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, *newid, PTP_OPC_Name, name); 72713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 72723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity name."); 72733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 72773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumArtist: 72783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (artist != NULL) { 72793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, *newid, PTP_OPC_AlbumArtist, artist); 72803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 72813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity album artist."); 72823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 72863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 72873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (artist != NULL) { 72883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, *newid, PTP_OPC_Artist, artist); 72893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 72903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity artist."); 72913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 72923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 72943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 72953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 72963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (composer != NULL) { 72973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, *newid, PTP_OPC_Composer, composer); 72983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 72993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity composer."); 73003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 73013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 73043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 73053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (genre != NULL) { 73063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, *newid, PTP_OPC_Genre, genre); 73073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 73083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set entity genre."); 73093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 73103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 73133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 73143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 73153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, *newid, PTP_OPC_DateModified, get_iso8601_stamp()); 73163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 73173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "create_new_abstract_list(): could not set date modified."); 73183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 73193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 73223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 73253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 73273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (no_tracks > 0) { 73303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add tracks to the list as object references. 73313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectreferences (params, *newid, (uint32_t *) tracks, no_tracks); 73323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 73333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "create_new_abstract_list(): could not add tracks as object references."); 73343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 73353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_object_to_cache(device, *newid); 73393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 73413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 73423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 73443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This updates the metadata and track listing 73453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for an abstract list. 73463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device that the abstract list 73473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * resides on. 73483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param name the name of the abstract list. 73493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param artist the artist of the abstract list or NULL. 73503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param genre the genre of the abstract list or NULL. 73513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param objecthandle the object to be updated. 73523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param objectformat the abstract list type to update. 73533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param tracks an array of tracks to associate with this list. 73543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param no_tracks the number of tracks in the list. 73553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 73563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 73573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int update_abstract_list(LIBMTP_mtpdevice_t *device, 73583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const name, 73593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const artist, 73603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const composer, 73613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char const * const genre, 73623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const objecthandle, 73633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t const objectformat, 73643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const * const tracks, 73653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const no_tracks) 73663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 73673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 73683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 73693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 73703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *properties = NULL; 73713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 73723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 73733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be set 73753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // i.e only try to update this metadata for object tags that exist on the current player. 73763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, objectformat, &propcnt, &properties); 73773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 73783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just bail out for now, nothing is ever set. 73793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 73803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not retrieve supported object properties."); 73813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 73823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 73833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptp_operation_issupported(params,PTP_OC_MTP_SetObjPropList) && 73843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev !FLAG_BROKEN_SET_OBJECT_PROPLIST(ptp_usb)) { 73853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 73863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop = NULL; 73873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int nrofprops = 0; 73883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 73903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd; 73913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropdesc(params, properties[i], objectformat, &opd); 73933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 73943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 73953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not get property description."); 73963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (opd.GetSet) { 73973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 73983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 73993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 74003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = objecthandle; 74013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Name; 74023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 74033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (name != NULL) 74043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(name); 74053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumArtist: 74073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (artist != NULL) { 74083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 74093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = objecthandle; 74103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_AlbumArtist; 74113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 74123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(artist); 74133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 74163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (artist != NULL) { 74173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 74183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = objecthandle; 74193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Artist; 74203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 74213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(artist); 74223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 74253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (composer != NULL) { 74263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 74273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = objecthandle; 74283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Composer; 74293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 74303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(composer); 74313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 74343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (genre != NULL) { 74353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 74363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = objecthandle; 74373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_Genre; 74383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 74393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = strdup(genre); 74403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 74433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 74443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Tag with current time if that is supported 74453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ptp_get_new_object_prop_entry(&props, &nrofprops); 74463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->ObjectHandle = objecthandle; 74473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->property = PTP_OPC_DateModified; 74483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->datatype = PTP_DTC_STR; 74493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop->propval.str = get_iso8601_stamp(); 74503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 74533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd); 74573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 74593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // proplist could be NULL if we can't write any properties 74603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (props != NULL) { 74613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectproplist(params, props, nrofprops); 74623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 74633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_destroy_object_prop_list(props, nrofprops); 74643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 74653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 74663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: return error of which property we couldn't set 74673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 74683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set object property list."); 74693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 74703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 74713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 74743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (ptp_operation_issupported(params,PTP_OC_MTP_SetObjectPropValue)) { 74753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 74763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (properties[i]) { 74773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 74783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update title 74793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, objecthandle, PTP_OPC_Name, name); 74803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 74813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 74823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set title."); 74833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumArtist: 74863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update album artist 74873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, objecthandle, PTP_OPC_AlbumArtist, artist); 74883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 74893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 74903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set album artist name."); 74913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 74923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 74933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 74943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update artist 74953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, objecthandle, PTP_OPC_Artist, artist); 74963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 74973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 74983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set artist name."); 74993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 75013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update composer 75023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, objecthandle, PTP_OPC_Composer, composer); 75033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 75043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 75053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set composer name."); 75063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 75083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 75093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update genre 75103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, objecthandle, PTP_OPC_Genre, genre); 75113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 75123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 75133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set genre."); 75143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 75163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_DateModified: 75173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Update date modified 75183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_CANNOT_HANDLE_DATEMODIFIED(ptp_usb)) { 75193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *tmpdate = get_iso8601_stamp(); 75203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = set_object_string(device, objecthandle, PTP_OPC_DateModified, tmpdate); 75213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != 0) { 75223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 75233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "could not set modification date."); 75243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(tmpdate); 75263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 75283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 75293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 75323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "update_abstract_list(): " 75333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev "Your device doesn't seem to support any known way of setting metadata."); 75343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 75353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 75363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Then the object references... 75393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectreferences (params, objecthandle, (uint32_t *) tracks, no_tracks); 75403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 75413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "update_abstract_list(): could not add tracks as object references."); 75423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 75433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 75443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(properties); 75473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev update_metadata_cache(device, objecthandle); 75493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 75513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 75523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 75553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine creates a new playlist based on the metadata 75563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supplied. If the <code>tracks</code> field of the metadata 75573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contains a track listing, these tracks will be added to the 75583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * playlist. 75593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to create the new playlist on. 75603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata the metadata for the new playlist. If the function 75613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * exits with success, the <code>playlist_id</code> field of this 75623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * struct will contain the new playlist ID of the playlist. 75633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 75643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->parent_id</code> should be set to the parent 75653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this track in. Since some 75663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * devices are a bit picky about where files 75673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * are placed, a default folder will be chosen if libmtp 75683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * has detected one for the current filetype and this 75693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parameter is set to 0. If this is 0 and no default folder 75703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * can be found, the file will be stored in the root folder. 75713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->storage_id</code> should be set to the 75723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 75733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this track in. Setting this to 0 will store 75743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the track on the primary storage. 75753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 75763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 75773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Update_Playlist() 75783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 75793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 75803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Create_New_Playlist(LIBMTP_mtpdevice_t *device, 75813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t * const metadata) 75823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 75833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 75843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t localph = metadata->parent_id; 75853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Use a default folder if none given 75873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (localph == 0) { 75883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->default_playlist_folder != 0) 75893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_playlist_folder; 75903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 75913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_music_folder; 75923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->parent_id = localph; 75943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 75953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Samsung needs its own special type of playlists 75963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(FLAG_PLAYLIST_SPL(ptp_usb)) { 75973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return playlist_t_to_spl(device, metadata); 75983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 75993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 76003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just create a new abstract audio/video playlist... 76013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return create_new_abstract_list(device, 76023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->name, 76033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev NULL, 76043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev NULL, 76053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev NULL, 76063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph, 76073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->storage_id, 76083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_MTP_AbstractAudioVideoPlaylist, 76093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_playlist_extension(ptp_usb), 76103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &metadata->playlist_id, 76113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->tracks, 76123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->no_tracks); 76133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 76143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 76153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 76163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine updates a playlist based on the metadata 76173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supplied. If the <code>tracks</code> field of the metadata 76183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contains a track listing, these tracks will be added to the 76193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * playlist in place of those already present, i.e. the 76203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * previous track listing will be deleted. For Samsung devices the 76213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * playlist id (metadata->playlist_id) is likely to change. 76223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to create the new playlist on. 76233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata the metadata for the playlist to be updated. 76243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * notice that the field <code>playlist_id</code> 76253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * must contain the apropriate playlist ID. Playlist ID 76263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * be modified to a new playlist ID by the time the 76273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * function returns since edit-in-place is not always possible. 76283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 76293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Create_New_Playlist() 76303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 76313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 76323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Update_Playlist(LIBMTP_mtpdevice_t *device, 76333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_playlist_t * const metadata) 76343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 76353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 76363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Samsung needs its own special type of playlists 76373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 76383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if(FLAG_PLAYLIST_SPL(ptp_usb)) { 76393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return update_spl_playlist(device, metadata); 76403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 76413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 76423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return update_abstract_list(device, 76433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->name, 76443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev NULL, 76453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev NULL, 76463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev NULL, 76473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->playlist_id, 76483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_MTP_AbstractAudioVideoPlaylist, 76493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->tracks, 76503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->no_tracks); 76513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 76523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 76533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 76543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a new album metadata structure and allocates memory 76553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for it. Notice that if you add strings to this structure they 76563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will be freed by the corresponding <code>LIBMTP_destroy_album_t</code> 76573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation later, so be careful of using strdup() when assigning 76583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings. 76593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 76603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a pointer to the newly allocated metadata structure. 76613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_destroy_album_t() 76623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 76633aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_album_t *LIBMTP_new_album_t(void) 76643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 76653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *new = (LIBMTP_album_t *) malloc(sizeof(LIBMTP_album_t)); 76663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (new == NULL) { 76673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 76683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 76693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->album_id = 0; 76703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->parent_id = 0; 76713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->storage_id = 0; 76723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->name = NULL; 76733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->artist = NULL; 76743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->composer = NULL; 76753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->genre = NULL; 76763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->tracks = NULL; 76773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->no_tracks = 0; 76783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->next = NULL; 76793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new; 76803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 76813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 76823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 76833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This recursively deletes the memory for an album structure 76843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 76853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param album structure to destroy 76863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_new_album_t() 76873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 76883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_album_t(LIBMTP_album_t *album) 76893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 76903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (album == NULL) { 76913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 76923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 76933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (album->name != NULL) 76943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album->name); 76953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (album->artist != NULL) 76963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album->artist); 76973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (album->composer != NULL) 76983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album->composer); 76993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (album->genre != NULL) 77003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album->genre); 77013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (album->tracks != NULL) 77023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album->tracks); 77033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(album); 77043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 77053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 77063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 77073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 77083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function maps and copies a property onto the album metadata if applicable. 77093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 77103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void pick_property_to_album_metadata(LIBMTP_mtpdevice_t *device, 77113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop, LIBMTP_album_t *alb) 77123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 77133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (prop->property) { 77143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 77153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 77163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->name = strdup(prop->propval.str); 77173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 77183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->name = NULL; 77193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumArtist: 77213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) { 77223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // This should take precedence over plain "Artist" 77233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (alb->artist != NULL) 77243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(alb->artist); 77253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->artist = strdup(prop->propval.str); 77263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else 77273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->artist = NULL; 77283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 77303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) { 77313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Only use of AlbumArtist is not set 77323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (alb->artist == NULL) 77333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->artist = strdup(prop->propval.str); 77343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else 77353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->artist = NULL; 77363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 77383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 77393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->composer = strdup(prop->propval.str); 77403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 77413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->composer = NULL; 77423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 77443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop->propval.str != NULL) 77453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->genre = strdup(prop->propval.str); 77463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 77473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->genre = NULL; 77483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 77503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 77513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 77523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 77533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves the album metadata for an album 77543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * given by a unique ID. 77553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the track metadata off. 77563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param alb an album metadata metadata set to fill in. 77573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 77583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void get_album_metadata(LIBMTP_mtpdevice_t *device, 77593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *alb) 77603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 77613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 77623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 77633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 77643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *prop; 77653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 77663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 77673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 77683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * If we have a cached, large set of metadata, then use it! 77693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 77703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want(params, alb->album_id, PTPOBJECT_MTPPROPLIST_LOADED, &ob); 77713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->mtpprops) { 77723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev prop = ob->mtpprops; 77733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<ob->nrofmtpprops;i++,prop++) 77743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev pick_property_to_album_metadata(device, prop, alb); 77753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 77763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 77773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 77783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 77793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // First see which properties can be retrieved for albums 77803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, PTP_OFC_MTP_AbstractAudioAlbum, &propcnt, &props); 77813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 77823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "get_album_metadata(): call to ptp_mtp_getobjectpropssupported() failed."); 77833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just bail out for now, nothing is ever set. 77843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 77853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 77863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<propcnt;i++) { 77873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (props[i]) { 77883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Name: 77893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->name = get_string_from_object(device, ob->oid, PTP_OPC_Name); 77903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_AlbumArtist: 77923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (alb->artist != NULL) 77933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(alb->artist); 77943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->artist = get_string_from_object(device, ob->oid, PTP_OPC_AlbumArtist); 77953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 77963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Artist: 77973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (alb->artist == NULL) 77983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->artist = get_string_from_object(device, ob->oid, PTP_OPC_Artist); 77993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 78003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Composer: 78013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->composer = get_string_from_object(device, ob->oid, PTP_OPC_Composer); 78023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 78033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_Genre: 78043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->genre = get_string_from_object(device, ob->oid, PTP_OPC_Genre); 78053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 78063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 78073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 78083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 78113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 78143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 78163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function returns a list of the albums available on the 78173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * device. 78183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 78193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the album listing from. 78203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return an album list on success, else NULL. If there are no albums 78213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * on the device, NULL will be returned as well. 78223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Album() 78233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 78243aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_album_t *LIBMTP_Get_Album_List(LIBMTP_mtpdevice_t *device) 78253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 78263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 78273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *retalbums = NULL; 78283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *curalbum = NULL; 78293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 78303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 78323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) 78333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 78343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < params->nrofobjects; i++) { 78363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *alb; 78373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 78383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 78393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ob = ¶ms->objects[i]; 78413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore stuff that isn't an album 78433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( ob->oi.ObjectFormat != PTP_OFC_MTP_AbstractAudioAlbum ) 78443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 78453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new album type 78473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb = LIBMTP_new_album_t(); 78483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->album_id = ob->oid; 78493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->parent_id = ob->oi.ParentObject; 78503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->storage_id = ob->oi.StorageID; 78513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Fetch supported metadata 78533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_album_metadata(device, alb); 78543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Then get the track listing for this album 78563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectreferences(params, alb->album_id, &alb->tracks, &alb->no_tracks); 78573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 78583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Album_List(): Could not get object references."); 78593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->tracks = NULL; 78603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->no_tracks = 0; 78613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Add album to a list that will be returned afterwards. 78643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (retalbums == NULL) { 78653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retalbums = alb; 78663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curalbum = alb; 78673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 78683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curalbum->next = alb; 78693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curalbum = alb; 78703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 78733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return retalbums; 78743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 78753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 78773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This function retrieves an individual album from the device. 78783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to get the album from. 78793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param albid the unique ID of the album to retrieve. 78803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a valid album metadata or NULL on failure. 78813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Album_List() 78823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 78833aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_album_t *LIBMTP_Get_Album(LIBMTP_mtpdevice_t *device, uint32_t const albid) 78843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 78853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 78863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 78873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 78883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t *alb; 78893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get all the handles if we haven't already done that 78913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->nrofobjects == 0) 78923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev flush_handles(device); 78933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want(params, albid, PTPOBJECT_OBJECTINFO_LOADED, &ob); 78953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) 78963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 78973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 78983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Ignore stuff that isn't an album 78993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ob->oi.ObjectFormat != PTP_OFC_MTP_AbstractAudioAlbum) 79003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 79013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Allocate a new album type 79033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb = LIBMTP_new_album_t(); 79043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->album_id = ob->oid; 79053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->parent_id = ob->oi.ParentObject; 79063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->storage_id = ob->oi.StorageID; 79073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Fetch supported metadata 79093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_album_metadata(device, alb); 79103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Then get the track listing for this album 79123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectreferences(params, alb->album_id, &alb->tracks, &alb->no_tracks); 79133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 79143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Album: Could not get object references."); 79153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->tracks = NULL; 79163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev alb->no_tracks = 0; 79173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 79183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return alb; 79203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 79213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 79233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine creates a new album based on the metadata 79243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supplied. If the <code>tracks</code> field of the metadata 79253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contains a track listing, these tracks will be added to the 79263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * album. 79273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to create the new album on. 79283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata the metadata for the new album. If the function 79293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * exits with success, the <code>album_id</code> field of this 79303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * struct will contain the new ID of the album. 79313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <ul> 79323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->parent_id</code> should be set to the parent 79333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * (e.g. folder) to store this track in. Since some 79343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * devices are a bit picky about where files 79353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * are placed, a default folder will be chosen if libmtp 79363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * has detected one for the current filetype and this 79373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * parameter is set to 0. If this is 0 and no default folder 79383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * can be found, the file will be stored in the root folder. 79393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * <li><code>metadata->storage_id</code> should be set to the 79403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * desired storage (e.g. memory card or whatever your device 79413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * presents) to store this track in. Setting this to 0 will store 79423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the track on the primary storage. 79433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * </ul> 79443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 79453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Update_Album() 79463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 79473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 79483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Create_New_Album(LIBMTP_mtpdevice_t *device, 79493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t * const metadata) 79503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 79513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t localph = metadata->parent_id; 79523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Use a default folder if none given 79543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (localph == 0) { 79553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (device->default_album_folder != 0) 79563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_album_folder; 79573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 79583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph = device->default_music_folder; 79593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 79603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->parent_id = localph; 79613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Just create a new abstract album... 79633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return create_new_abstract_list(device, 79643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->name, 79653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->artist, 79663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->composer, 79673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->genre, 79683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev localph, 79693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->storage_id, 79703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_MTP_AbstractAudioAlbum, 79713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ".alb", 79723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &metadata->album_id, 79733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->tracks, 79743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->no_tracks); 79753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 79763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 79773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 79783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This creates a new sample data metadata structure and allocates memory 79793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for it. Notice that if you add strings to this structure they 79803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * will be freed by the corresponding <code>LIBMTP_destroy_sampledata_t</code> 79813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * operation later, so be careful of using strdup() when assigning 79823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * strings. 79833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 79843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return a pointer to the newly allocated metadata structure. 79853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_destroy_sampledata_t() 79863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 79873aa430dc5437a98734b36f996f9b17081a589143Yavor GoulishevLIBMTP_filesampledata_t *LIBMTP_new_filesampledata_t(void) 79883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 79893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filesampledata_t *new = (LIBMTP_filesampledata_t *) malloc(sizeof(LIBMTP_filesampledata_t)); 79903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (new == NULL) { 79913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 79923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 79933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->height=0; 79943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->width = 0; 79953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->data = NULL; 79963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->duration = 0; 79973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev new->size = 0; 79983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return new; 79993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 80003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 80013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 80023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This destroys a file sample metadata type. 80033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param sample the file sample metadata to be destroyed. 80043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 80053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid LIBMTP_destroy_filesampledata_t(LIBMTP_filesampledata_t * sample) 80063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 80073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (sample == NULL) { 80083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 80093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 80103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (sample->data != NULL) { 80113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(sample->data); 80123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 80133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(sample); 80143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 80153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 80163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 80173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine figures out whether a certain filetype supports 80183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * representative samples (small thumbnail images) or not. This 80193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * typically applies to JPEG files, MP3 files and Album abstract 80203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * playlists, but in theory any filetype could support representative 80213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * samples. 80223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device which is to be examined. 80233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param filetype the fileype to examine, and return the representative sample 80243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * properties for. 80253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param sample this will contain a new sample type with the fields 80263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * filled in with suitable default values. For example, the 80273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supported sample type will be set, the supported height and 80283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * width will be set to max values if it is an image sample, 80293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * and duration will also be given some suitable default value 80303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * which should not be exceeded on audio samples. If the 80313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * device does not support samples for this filetype, this 80323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * pointer will be NULL. If it is not NULL, the user must 80333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * destroy this struct with <code>LIBMTP_destroy_filesampledata_t()</code> 80343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * after use. 80353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 80363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Representative_Sample() 80373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Create_New_Album() 80383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 80393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Representative_Sample_Format(LIBMTP_mtpdevice_t *device, 80403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filetype_t const filetype, 80413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filesampledata_t ** sample) 80423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 80433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 80443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 80453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 80463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 80473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 80483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // TODO: Get rid of these when we can properly query the device. 80493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int support_data = 0; 80503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int support_format = 0; 80513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int support_height = 0; 80523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int support_width = 0; 80533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int support_duration = 0; 80543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int support_size = 0; 80553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 80563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd_height; 80573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd_width; 80583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd_format; 80593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd_duration; 80603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectPropDesc opd_size; 80613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 80623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Default to no type supported. 80633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *sample = NULL; 80643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 80653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, map_libmtp_type_to_ptp_type(filetype), &propcnt, &props); 80663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 80673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Representative_Sample_Format(): could not get object properties."); 80683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 80693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 80703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 80713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * TODO: when walking through these object properties, make calls to 80723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * a new function in ptp.h/ptp.c that can send the command 80733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * PTP_OC_MTP_GetObjectPropDesc to get max/min values of the properties 80743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supported. 80753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 80763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < propcnt; i++) { 80773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch(props[i]) { 80783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_RepresentativeSampleData: 80793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev support_data = 1; 80803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_RepresentativeSampleFormat: 80823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev support_format = 1; 80833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_RepresentativeSampleSize: 80853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev support_size = 1; 80863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_RepresentativeSampleHeight: 80883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev support_height = 1; 80893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_RepresentativeSampleWidth: 80913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev support_width = 1; 80923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPC_RepresentativeSampleDuration: 80943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev support_duration = 1; 80953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 80973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 80983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 80993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 81003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 81013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 81023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (support_data && support_format && support_height && support_width && !support_duration) { 81033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Something that supports height and width and not duration is likely to be JPEG 81043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filesampledata_t *retsam = LIBMTP_new_filesampledata_t(); 81053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 81063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Populate the sample format with the first supported format 81073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 81083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * TODO: figure out how to pass back more than one format if more are 81093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supported by the device. 81103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 81113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleFormat, map_libmtp_type_to_ptp_type(filetype), &opd_format); 81123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->filetype = map_ptp_type_to_libmtp_type(opd_format.FORM.Enum.SupportedValue[0].u16); 81133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_format); 81143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Populate the maximum image height */ 81153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleWidth, map_libmtp_type_to_ptp_type(filetype), &opd_width); 81163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->width = opd_width.FORM.Range.MaximumValue.u32; 81173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_width); 81183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Populate the maximum image width */ 81193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleHeight, map_libmtp_type_to_ptp_type(filetype), &opd_height); 81203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->height = opd_height.FORM.Range.MaximumValue.u32; 81213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_height); 81223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Populate the maximum size */ 81233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (support_size) { 81243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleSize, map_libmtp_type_to_ptp_type(filetype), &opd_size); 81253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->size = opd_size.FORM.Range.MaximumValue.u32; 81263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_size); 81273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 81283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *sample = retsam; 81293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else if (support_data && support_format && !support_height && !support_width && support_duration) { 81303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Another qualified guess 81313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filesampledata_t *retsam = LIBMTP_new_filesampledata_t(); 81323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 81333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Populate the sample format with the first supported format 81343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 81353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * TODO: figure out how to pass back more than one format if more are 81363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supported by the device. 81373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 81383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleFormat, map_libmtp_type_to_ptp_type(filetype), &opd_format); 81393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->filetype = map_ptp_type_to_libmtp_type(opd_format.FORM.Enum.SupportedValue[0].u16); 81403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_format); 81413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Populate the maximum duration */ 81423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleDuration, map_libmtp_type_to_ptp_type(filetype), &opd_duration); 81433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->duration = opd_duration.FORM.Range.MaximumValue.u32; 81443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_duration); 81453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Populate the maximum size */ 81463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (support_size) { 81473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_mtp_getobjectpropdesc (params, PTP_OPC_RepresentativeSampleSize, map_libmtp_type_to_ptp_type(filetype), &opd_size); 81483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retsam->size = opd_size.FORM.Range.MaximumValue.u32; 81493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(&opd_size); 81503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 81513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *sample = retsam; 81523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 81533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 81543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 81553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 81563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 81573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine sends representative sample data for an object. 81583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This uses the RepresentativeSampleData property of the album, 81593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * if the device supports it. The data should be of a format acceptable 81603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * to the player (for iRiver and Creative, this seems to be JPEG) and 81613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * must not be too large. (for a Creative, max seems to be about 20KB.) 81623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Check by calling LIBMTP_Get_Representative_Sample_Format() to get 81633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * maximum size, dimensions, etc.. 81643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device which the object is on. 81653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id unique id of the object to set artwork for. 81663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param pointer to LIBMTP_filesampledata_t struct containing data 81673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 81683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Representative_Sample() 81693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Representative_Sample_Format() 81703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Create_New_Album() 81713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 81723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Send_Representative_Sample(LIBMTP_mtpdevice_t *device, 81733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id, 81743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filesampledata_t *sampledata) 81753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 81763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 81773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 81783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_USB *ptp_usb = (PTP_USB*) device->usbinfo; 81793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 81803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 81813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 81823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 81833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 81843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int supported = 0; 81853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 81863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // get the file format for the object we're going to send representative data for 81873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, id, PTPOBJECT_OBJECTINFO_LOADED, &ob); 81883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 81893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Send_Representative_Sample(): could not get object info."); 81903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 81913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 81923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 81933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // check that we can send representative sample data for this object format 81943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, ob->oi.ObjectFormat, &propcnt, &props); 81953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 81963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Send_Representative_Sample(): could not get object properties."); 81973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 81983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 81993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < propcnt; i++) { 82013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (props[i] == PTP_OPC_RepresentativeSampleData) { 82023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev supported = 1; 82033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 82043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!supported) { 82073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 82083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Send_Representative_Sample(): object type doesn't support RepresentativeSampleData."); 82093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 82103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 82123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Go ahead and send the data 82143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.a.count = sampledata->size; 82153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.a.v = malloc(sizeof(PTPPropertyValue) * sampledata->size); 82163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < sampledata->size; i++) { 82173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propval.a.v[i].u8 = sampledata->data[i]; 82183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_setobjectpropvalue(params,id,PTP_OPC_RepresentativeSampleData, 82213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval,PTP_DTC_AUINT8); 82223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 82233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Send_Representative_Sample(): could not send sample data."); 82243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.a.v); 82253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 82263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.a.v); 82283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Set the height and width if the sample is an image, otherwise just 82303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * set the duration and size */ 82313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch(sampledata->filetype) { 82323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_JPEG: 82333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_JFIF: 82343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_TIFF: 82353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_BMP: 82363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_GIF: 82373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_PICT: 82383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case LIBMTP_FILETYPE_PNG: 82393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!FLAG_BROKEN_SET_SAMPLE_DIMENSIONS(ptp_usb)) { 82403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // For images, set the height and width 82413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_object_u32(device, id, PTP_OPC_RepresentativeSampleHeight, sampledata->height); 82423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_object_u32(device, id, PTP_OPC_RepresentativeSampleWidth, sampledata->width); 82433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 82453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 82463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // For anything not an image, set the duration and size 82473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_object_u32(device, id, PTP_OPC_RepresentativeSampleDuration, sampledata->duration); 82483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev set_object_u32(device, id, PTP_OPC_RepresentativeSampleSize, sampledata->size); 82493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 82503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 82533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 82543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 82563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine gets representative sample data for an object. 82573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This uses the RepresentativeSampleData property of the album, 82583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * if the device supports it. 82593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device which the object is on. 82603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param id unique id of the object to get data for. 82613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param pointer to LIBMTP_filesampledata_t struct to receive data 82623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 82633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Send_Representative_Sample() 82643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Get_Representative_Sample_Format() 82653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Create_New_Album() 82663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 82673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Get_Representative_Sample(LIBMTP_mtpdevice_t *device, 82683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t const id, 82693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_filesampledata_t *sampledata) 82703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 82713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 82723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *) device->params; 82733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue propval; 82743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObject *ob; 82753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 82763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t *props = NULL; 82773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propcnt = 0; 82783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int supported = 0; 82793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // get the file format for the object we're going to send representative data for 82813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_object_want (params, id, PTPOBJECT_OBJECTINFO_LOADED, &ob); 82823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 82833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_Representative_Sample(): could not get object info."); 82843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 82853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // check that we can store representative sample data for this object format 82883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropssupported(params, ob->oi.ObjectFormat, &propcnt, &props); 82893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 82903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Representative_Sample(): could not get object properties."); 82913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 82923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 82943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < propcnt; i++) { 82953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (props[i] == PTP_OPC_RepresentativeSampleData) { 82963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev supported = 1; 82973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 82983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 82993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 83003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!supported) { 83013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 83023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_error_to_errorstack(device, LIBMTP_ERROR_GENERAL, "LIBMTP_Get_Representative_Sample(): object type doesn't support RepresentativeSampleData."); 83033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 83043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 83053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(props); 83063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get the data 83083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_mtp_getobjectpropvalue(params,id,PTP_OPC_RepresentativeSampleData, 83093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &propval,PTP_DTC_AUINT8); 83103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 83113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "LIBMTP_Get_Representative_Sample(): could not get sample data."); 83123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return -1; 83133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 83143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Store it 83163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->size = propval.a.count; 83173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->data = malloc(sizeof(PTPPropertyValue) * propval.a.count); 83183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < propval.a.count; i++) { 83193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->data[i] = propval.a.v[i].u8; 83203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 83213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(propval.a.v); 83223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev // Get the other properties 83243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->width = get_u32_from_object(device, id, PTP_OPC_RepresentativeSampleWidth, 0); 83253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->height = get_u32_from_object(device, id, PTP_OPC_RepresentativeSampleHeight, 0); 83263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->duration = get_u32_from_object(device, id, PTP_OPC_RepresentativeSampleDuration, 0); 83273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sampledata->filetype = map_ptp_type_to_libmtp_type( 83283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev get_u16_from_object(device, id, PTP_OPC_RepresentativeSampleFormat, LIBMTP_FILETYPE_UNKNOWN)); 83293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 83313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 83323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 83343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This routine updates an album based on the metadata 83353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * supplied. If the <code>tracks</code> field of the metadata 83363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * contains a track listing, these tracks will be added to the 83373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * album in place of those already present, i.e. the 83383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * previous track listing will be deleted. 83393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device a pointer to the device to create the new album on. 83403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param metadata the metadata for the album to be updated. 83413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * notice that the field <code>album_id</code> 83423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * must contain the apropriate album ID. 83433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @return 0 on success, any other value means failure. 83443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Create_New_Album() 83453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @see LIBMTP_Delete_Object() 83463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 83473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint LIBMTP_Update_Album(LIBMTP_mtpdevice_t *device, 83483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev LIBMTP_album_t const * const metadata) 83493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 83503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return update_abstract_list(device, 83513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->name, 83523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->artist, 83533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->composer, 83543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->genre, 83553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->album_id, 83563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_OFC_MTP_AbstractAudioAlbum, 83573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->tracks, 83583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev metadata->no_tracks); 83593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 83603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 83623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Dummy function needed to interface to upstream 83633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * ptp.c/ptp.h files. 83643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 83653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevvoid ptp_nikon_getptpipguid (unsigned char* guid) { 83663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 83673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 83683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 83703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Add an object to cache. 83713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device the device which may have a cache to which the object should be added. 83723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id the object to add to the cache. 83733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 83743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void add_object_to_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id) 83753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 83763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *)device->params; 83773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ret; 83783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_add_object_to_cache(params, object_id); 83803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ret != PTP_RC_OK) { 83813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_ptp_error_to_errorstack(device, ret, "add_object_to_cache(): couldn't add object to cache"); 83823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 83833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 83843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/** 83873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Update cache after object has been modified 83883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param device the device which may have a cache to which the object should be updated. 83893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * @param object_id the object to update. 83903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 83913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void update_metadata_cache(LIBMTP_mtpdevice_t *device, uint32_t object_id) 83923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 83933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params = (PTPParams *)device->params; 83943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 83953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_remove_object_from_cache(params, object_id); 83963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev add_object_to_cache(device, object_id); 83973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 8398