ptp-pack.c revision d9ee8cd37f0704a501b62a185c3305d236c7c8df
1a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij/* ptp-pack.c 2a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * 3a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl> 4a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Copyright (C) 2003-2012 Marcus Meissner <marcus@jet.franken.de> 5a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Copyright (C) 2006-2008 Linus Walleij <triad@df.lth.se> 6a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Copyright (C) 2007 Tero Saarni <tero.saarni@gmail.com> 7a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Copyright (C) 2009 Axel Waggershauser <awagger@web.de> 8a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * 9a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * This library is free software; you can redistribute it and/or 10a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * modify it under the terms of the GNU Lesser General Public 11a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * License as published by the Free Software Foundation; either 12a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * version 2 of the License, or (at your option) any later version. 13a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * 14a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * This library is distributed in the hope that it will be useful, 15a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * but WITHOUT ANY WARRANTY; without even the implied warranty of 16a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Lesser General Public License for more details. 18a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * 19a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * You should have received a copy of the GNU Lesser General Public 20a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * License along with this library; if not, write to the 21a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Boston, MA 02111-1307, USA. 23a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij */ 24a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij 25b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* currently this file is included into ptp.c */ 26eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 276db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#ifdef HAVE_ICONV 28a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij#include <iconv.h> 296db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 30a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 31b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 32eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16p (PTPParams *params, uint16_t var) 33eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 34eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 35eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 36eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 37b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 38eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32p (PTPParams *params, uint32_t var) 39eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 40eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 41eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 42eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 43b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 44eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16ap (PTPParams *params, unsigned char *a, uint16_t val) 45eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 46eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 47b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole16a(a,val); 48e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 49eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe16a(a,val); 50eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 51eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 52b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 53eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32ap (PTPParams *params, unsigned char *a, uint32_t val) 54eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 55eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 56b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole32a(a,val); 57e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 58eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe32a(a,val); 59eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 60eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 61abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline void 62abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijhtod64ap (PTPParams *params, unsigned char *a, uint64_t val) 63abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 64abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij if (params->byteorder==PTP_DL_LE) 65abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htole64a(a,val); 66e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 67abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htobe64a(a,val); 68abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 69abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 70b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 71eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16p (PTPParams *params, uint16_t var) 72eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 73eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 74eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 75eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 76b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 77eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32p (PTPParams *params, uint32_t var) 78eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 79eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 80eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 81eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 82abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline uint64_t 83abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijdtoh64p (PTPParams *params, uint64_t var) 84abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 85abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var)); 86abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 87abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 88b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh16ap (PTPParams *params, const unsigned char *a) 90eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 91eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 92eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 93eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 94b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh32ap (PTPParams *params, const unsigned char *a) 96eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 97eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 98eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 99eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 100b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint64_t 1011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh64ap (PTPParams *params, const unsigned char *a) 102eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 103abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a)); 104eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 105eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 106b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod8a(a,x) *(uint8_t*)(a) = x 107b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16a(a,x) htod16ap(params,a,x) 108b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32a(a,x) htod32ap(params,a,x) 109abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64a(a,x) htod64ap(params,a,x) 110b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16(x) htod16p(params,x) 111b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32(x) htod32p(params,x) 112abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64(x) htod64p(params,x) 113b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 114b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh8a(x) (*(uint8_t*)(x)) 115b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16a(a) dtoh16ap(params,a) 116b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32a(a) dtoh32ap(params,a) 117b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh64a(a) dtoh64ap(params,a) 118b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16(x) dtoh16p(params,x) 119b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32(x) dtoh32p(params,x) 120abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define dtoh64(x) dtoh64p(params,x) 121b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 122b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 123b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline char* 124b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len) 125eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 126a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint8_t length; 127a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint16_t string[PTP_MAXSTRLEN+1]; 128a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ 129e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij char loclstr[PTP_MAXSTRLEN*3+1]; 130a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij size_t nconv, srclen, destlen; 131a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij char *src, *dest; 132a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 133a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ 134a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *len = length; 135a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (length == 0) /* nothing to do? */ 136a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(NULL); 137a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 138a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* copy to string[] to ensure correct alignment for iconv(3) */ 139a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(string, &data[offset+1], length * sizeof(string[0])); 140a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij string[length] = 0x0000U; /* be paranoid! add a terminator. */ 141a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[0] = '\0'; 142e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij 143a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* convert from camera UCS-2 to our locale */ 144a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij src = (char *)string; 145a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij srclen = length * sizeof(string[0]); 146a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr; 147a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij destlen = sizeof(loclstr)-1; 1486db174f4d18af574fab991309e11010aa0eb4543Linus Walleij nconv = (size_t)-1; 1496db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#ifdef HAVE_ICONV 150d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij if (params->cd_ucs2_to_locale != (iconv_t)-1) 151d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen); 1526db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 153a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (nconv == (size_t) -1) { /* do it the hard way */ 154a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij int i; 155a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* try the old way, in case iconv is broken */ 156a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij for (i=0;i<length;i++) { 157a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (dtoh16a(&data[offset+1+2*i])>127) 158a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = '?'; 159a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij else 160a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = dtoh16a(&data[offset+1+2*i]); 161eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 162a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr+length; 163eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 164a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *dest = '\0'; 165a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ 166a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(strdup(loclstr)); 167a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 168a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 169a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline int 170a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijucs2strlen(uint16_t const * const unicstr) 171a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 17296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int length = 0; 173a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 174a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Unicode strings are terminated with 2 * 0x00 */ 175a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for(length = 0; unicstr[length] != 0x0000U; length ++); 176a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return length; 177eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 178eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 179a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 180b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 181b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 182eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 18396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int packedlen = 0; 184a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t ucs2str[PTP_MAXSTRLEN+1]; 185a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *ucs2strp = (char *) ucs2str; 186a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = strlen(string); 187a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 188a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 189a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memset(ucs2strp, 0, sizeof(ucs2str)); /* XXX: necessary? */ 1906db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#ifdef HAVE_ICONV 191d000c371601fafcf75d2de2d1060ee11be2007d6Linus Walleij if (params->cd_locale_to_ucs2 != (iconv_t)-1) { 1926db174f4d18af574fab991309e11010aa0eb4543Linus Walleij size_t nconv; 1936db174f4d18af574fab991309e11010aa0eb4543Linus Walleij size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 1946db174f4d18af574fab991309e11010aa0eb4543Linus Walleij char *stringp = string; 1956db174f4d18af574fab991309e11010aa0eb4543Linus Walleij 1966db174f4d18af574fab991309e11010aa0eb4543Linus Walleij nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, 1976db174f4d18af574fab991309e11010aa0eb4543Linus Walleij &ucs2strp, &convmax); 1986db174f4d18af574fab991309e11010aa0eb4543Linus Walleij if (nconv == (size_t) -1) 1996db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[0] = 0x0000U; 200d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij } else 201d000c371601fafcf75d2de2d1060ee11be2007d6Linus Walleij#endif 2026db174f4d18af574fab991309e11010aa0eb4543Linus Walleij { 2036db174f4d18af574fab991309e11010aa0eb4543Linus Walleij int i; 2046db174f4d18af574fab991309e11010aa0eb4543Linus Walleij for (i=0;i<convlen;i++) { 2056db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[i] = string[i]; 2066db174f4d18af574fab991309e11010aa0eb4543Linus Walleij } 2076db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[convlen] = 0; 2086db174f4d18af574fab991309e11010aa0eb4543Linus Walleij } 209a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* 210a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 211a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * why do we need ucs2strlen()? 212a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij */ 213a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 214a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 215a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 216a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 217a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 218958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 2197f2343824550452974d78f5dbd94e64844355c33Linus Walleij /* number of characters including terminating 0 (PTP standard confirmed) */ 220a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 221a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 222a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 223958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 224958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* The returned length is in number of characters */ 225048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij *len = (uint8_t) packedlen+1; 226eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 227eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 228a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 229735f41692934a716158cf051d76e988febeca7eeLinus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 230a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 2318b42ca3d3baeb7c8f3e5eca88c613adb612e4ec0Richard Low uint8_t packed[PTP_MAXSTRLEN*2+3], len; 232a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 233a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 234d47b9218023a6b943a93faa743712ae072cba85cRichard Low 235d47b9218023a6b943a93faa743712ae072cba85cRichard Low if (string == NULL) 236d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, "", (unsigned char*) packed, 0, &len); 237d47b9218023a6b943a93faa743712ae072cba85cRichard Low else 238d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 239d47b9218023a6b943a93faa743712ae072cba85cRichard Low 240958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* returned length is in characters, then one byte for string length */ 241958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij plen = len*2 + 1; 242048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij 243a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 244735f41692934a716158cf051d76e988febeca7eeLinus Walleij if (!retcopy) { 245735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = 0; 246a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 247735f41692934a716158cf051d76e988febeca7eeLinus Walleij } 248a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 249735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = plen; 250a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 251a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 252a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 253b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 254b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 255eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 256eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 257eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 258eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 259eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 260eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 261eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 262eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 263eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 265eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 267b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 268f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 269f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 270f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 271f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 272f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 273f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 274f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 275f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 276f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 277f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 278f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 279f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 280b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 282eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 283eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 284eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 285eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 286eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij while (n>i) { 287eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 288eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij i++; 289eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 290eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 291eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 293eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 294eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 295eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 300eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 301eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 302b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 303b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 304eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 305eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 306eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 3077e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 308d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij if (!data) return; 309d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij if (datalen < 12) return; 3107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 311eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 312eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 313eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 314eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 315eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionDesc = 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_VendorExtensionDesc, &len); 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 319eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->FunctionalMode = 320eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 321eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 323eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 324eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 325eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 326eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 327eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 328eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 329eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 330eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 331eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 332eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 333eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 334eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 335eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 336eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 337eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 338eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 339eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 340eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 341eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 342eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 343eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 344eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 345eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 346eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 347eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 348eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 349eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 350eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 351eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 352eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 353eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 354eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 355eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 356eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 357eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 358a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 359e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleijstatic void inline 360a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleijptp_free_DI (PTPDeviceInfo *di) { 361a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->SerialNumber) free (di->SerialNumber); 362a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DeviceVersion) free (di->DeviceVersion); 363a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Model) free (di->Model); 364a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->Manufacturer) free (di->Manufacturer); 365a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->ImageFormats) free (di->ImageFormats); 366a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->CaptureFormats) free (di->CaptureFormats); 367a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->VendorExtensionDesc) free (di->VendorExtensionDesc); 368a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->OperationsSupported) free (di->OperationsSupported); 369a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->EventsSupported) free (di->EventsSupported); 370a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (di->DevicePropertiesSupported) free (di->DevicePropertiesSupported); 371a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij} 3727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij/* EOS Device Info unpack */ 3747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijstatic inline void 3757e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) 3767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij{ 3777e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int totallen = 4; 37896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 37996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij memset (di,0, sizeof(*di)); 3807e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (datalen < 8) return; 3817e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3827e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* uint32_t struct len - ignore */ 3837e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, 3847e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->EventsSupported); 3857e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->EventsSupported) return; 3867e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->EventsSupported_len*sizeof(uint32_t)+4; 3877e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (totallen >= datalen) return; 3887e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3897e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, 3907e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->DevicePropertiesSupported); 3917e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->DevicePropertiesSupported) return; 3927e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; 3937e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (totallen >= datalen) return; 3947e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 3957e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->unk_len = ptp_unpack_uint32_t_array(params, data, 3967e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen, &di->unk); 3977e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (!di->unk) return; 3987e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->unk_len*sizeof(uint32_t)+4; 3997e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 4007e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij} 4010d762ccc39331608119dd0267021b165e22de499Linus Walleij 4020d762ccc39331608119dd0267021b165e22de499Linus Walleijstatic inline void 4030d762ccc39331608119dd0267021b165e22de499Linus Walleijptp_free_EOS_DI (PTPCanonEOSDeviceInfo *di) 4040d762ccc39331608119dd0267021b165e22de499Linus Walleij{ 4050d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->EventsSupported); 4060d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->DevicePropertiesSupported); 4070d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->unk); 4080d762ccc39331608119dd0267021b165e22de499Linus Walleij} 409eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 410eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 411eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 413eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 414b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 415b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 416eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 417f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (len) { 418f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 419f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 420f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = 0; 421f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->Handler = NULL; 422f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 423eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 424eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 427eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 428eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 429b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 430b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 431eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 43296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij if (!data && !len) { 43396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij sids->n = 0; 43496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij sids->Storage = NULL; 43596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij return; 43696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij } 437eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 438eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &sids->Storage); 439eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 440eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 441eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 451b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 452b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 455eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 456eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 459eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 460eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 461eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 462eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 463eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription, &storagedescriptionlen); 464eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 465eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 466eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 467eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 468eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 469eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 470eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 471eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 472eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 473eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 474eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 475eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 476eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 477eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 478eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 479eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 480eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 481eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 482eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 487eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 488eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 489a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* the max length assuming zero length dates. We have need 3 */ 490a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* bytes for these. */ 491a679b1c4d273f210abb6befc5d9954a25427c329Richard Low#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 492a679b1c4d273f210abb6befc5d9954a25427c329Richard Low 493b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 494b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 495eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 496b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 499a679b1c4d273f210abb6befc5d9954a25427c329Richard Low /* let's allocate some memory first; correct assuming zero length dates */ 5000546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner oidata=malloc(PTP_oi_MaxLen + params->ocs64*4); 5010546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner *oidataptr=oidata; 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 503eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 504eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 5060546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner memset (oidata, 0, PTP_oi_MaxLen + params->ocs64*4); 507eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 508eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 509eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 510eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 5110546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (params->ocs64) 5120546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner oidata += 4; 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 514eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 515eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 516eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 517eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 518eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 520eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 521eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 522eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 523eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 524eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 525eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 526eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 527eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 528eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 529eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 530eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 531eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 532eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 533eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 534eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 535eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 536eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 537eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 538eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 539eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 540eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 541eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 542eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 543eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 544eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 545eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 546eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 547eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 548eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 549eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 550eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 551eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 552eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 5530546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3)+params->ocs64*4; 554eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 555eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 5563bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleijstatic time_t 5576db174f4d18af574fab991309e11010aa0eb4543Linus Walleijptp_unpack_PTPTIME (const char *str) { 5583bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char ptpdate[40]; 5593bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char tmp[5]; 560a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij size_t ptpdatelen; 5613bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij struct tm tm; 5623bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 5633bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (!str) 5643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5653bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptpdatelen = strlen(str); 5667e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen >= sizeof (ptpdate)) { 5676db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is larger then size of buffer", ptpdatelen, (int)sizeof(ptpdate));*/ 5683bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5697e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 5707e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen<15) { 5716db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is less than 15 (%d)", ptpdatelen);*/ 5723bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 5737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 574a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij strncpy (ptpdate, str, sizeof(ptpdate)); 575a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij ptpdate[sizeof(ptpdate) - 1] = '\0'; 5763bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 5773bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij memset(&tm,0,sizeof(tm)); 5783bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate, 4); 5793bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[4] = 0; 5803bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_year=atoi (tmp) - 1900; 5813bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 4, 2); 5823bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5833bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mon = atoi (tmp) - 1; 5843bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 6, 2); 5853bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5863bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mday = atoi (tmp); 5873bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 9, 2); 5883bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5893bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_hour = atoi (tmp); 5903bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 11, 2); 5913bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5923bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_min = atoi (tmp); 5933bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 13, 2); 5943bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 5953bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_sec = atoi (tmp); 596e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij tm.tm_isdst = -1; 5973bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return mktime (&tm); 5983bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij} 5993bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 600b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 601b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 602eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 603eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 604eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 605eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 606eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 607eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 608eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 609eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 610eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 6110546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 6120546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* Stupid Samsung Galaxy developers emit a 64bit objectcompressedsize */ 6130546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) { 6140546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner params->ocs64 = 1; 6150546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner data += 4; 6160546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner } 617eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 618eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 619eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 620eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 621eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 622eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 623eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 624eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 625eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 626eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 627eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 6280546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 629eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 630eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 631eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 632eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 633eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 634eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 635eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 6366db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); 637eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 638eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 6393bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij /* now the modification date ... */ 640eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 641eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 642eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij +capturedatelen*2+2,&capturedatelen); 6436db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); 644eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 645eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 646eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 647eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 648b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 649b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 650b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 651b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 652b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 653eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 654eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 655b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 656b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int n,j; \ 657b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 658b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 659b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 660b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 661b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 662b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 663b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 664b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 665b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 666b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 667b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 668eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 669b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 670b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 671b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPParams *params, unsigned char* data, int *offset, int total, 672b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 673b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 674eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 675b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 676b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 677b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 678b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 679b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 680b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 681b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 683b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 684b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 685b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 689b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 690b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 691b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 692b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 693abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 694abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->i64,dtoh64a); 695abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 696abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 697abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->u64,dtoh64a); 698abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 699abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 700037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT128: 701037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 702037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint128n");*/ 703037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 704037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT128: 705037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 706037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int128n");*/ 707037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 708037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 709037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 710037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 711b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 712b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 713b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 714b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 715b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 716b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 717b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 718b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 719b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 720b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 721b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 722b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 723b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 724b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 725b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 726b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 727b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 728b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 729abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 730abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,u64,dtoh64a); 731abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 732abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 733abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,i64,dtoh64a); 734abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 737b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 738b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 739b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 740b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij value->str = ptp_unpack_string(params,data,*offset,&len); 741b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 742b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 743deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 745eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 746037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij default: 747037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij return 0; 748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 749b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 750eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 751eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 752eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 753eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 754eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 755eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 756eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 757eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 759b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 760eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 762eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 764eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 765eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 766eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 767deddc3490b3084b802737017982285bfa58b382fLinus Walleij dpd->FormFlag=PTP_DPFF_None; 768b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 772deddc3490b3084b802737017982285bfa58b382fLinus Walleij if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) 773deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 775b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 776b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 777b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 782b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 784b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 787eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 788eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 789b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 790b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 791b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 792b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 793b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 794b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 795b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 796eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 797b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 798b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 799eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 800b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 801b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 802b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 803b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 804b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 805b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 806b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 810b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 812b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 815b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 816b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 817b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 820eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 822eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 823eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 824b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 825b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 826b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 827b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 828b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 829eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 830eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 831d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijstatic inline void 832d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijduplicate_PropertyValue (const PTPPropertyValue *src, PTPPropertyValue *dst, uint16_t type) { 833d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij if (type & PTP_DTC_ARRAY_MASK) { 834d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij int i; 835d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 836d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->a.count = src->a.count; 837d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->a.v = malloc (sizeof(src->a.v)*src->a.count); 838d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij for (i=0;i<src->a.count;i++) 839d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->a.v[i], &dst->a.v[i], type & ~PTP_DTC_ARRAY_MASK); 840d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij return; 841d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij } 842d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij switch (type & ~PTP_DTC_ARRAY_MASK) { 843d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT8: dst->i8 = src->i8; break; 844d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT8: dst->u8 = src->u8; break; 845d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT16: dst->i16 = src->i16; break; 846d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT16: dst->u16 = src->u16; break; 847d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT32: dst->i32 = src->i32; break; 848d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT32: dst->u32 = src->u32; break; 849d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT64: dst->u64 = src->u64; break; 850d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT64: dst->i64 = src->i64; break; 851d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij#if 0 852d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT128: dst->i128 = src->i128; break; 853d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT128: dst->u128 = src->u128; break; 854d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij#endif 855d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_STR: dst->str = strdup(src->str); break; 856d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij default: break; 857d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij } 858d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij return; 859d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij} 860d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 861d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijstatic inline void 862d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijduplicate_DevicePropDesc(const PTPDevicePropDesc *src, PTPDevicePropDesc *dst) { 863d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij int i; 864d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 865d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->DevicePropertyCode = src->DevicePropertyCode; 866d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->DataType = src->DataType; 867d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->GetSet = src->GetSet; 868d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 869d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FactoryDefaultValue, &dst->FactoryDefaultValue, dst->DataType); 870d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->CurrentValue, &dst->CurrentValue, dst->DataType); 871d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 872d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->FormFlag = src->FormFlag; 873d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij switch (src->FormFlag) { 874d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DPFF_Range: 875d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Range.MinimumValue, &dst->FORM.Range.MinimumValue, src->DataType); 876d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Range.MaximumValue, &dst->FORM.Range.MaximumValue, src->DataType); 877d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Range.StepSize, &dst->FORM.Range.StepSize, src->DataType); 878d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij break; 879d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DPFF_Enumeration: 880d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->FORM.Enum.NumberOfValues = src->FORM.Enum.NumberOfValues; 881d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->FORM.Enum.SupportedValue = malloc (sizeof(dst->FORM.Enum.SupportedValue[0])*src->FORM.Enum.NumberOfValues); 882d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij for (i = 0; i<src->FORM.Enum.NumberOfValues ; i++) 883d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Enum.SupportedValue[i], &dst->FORM.Enum.SupportedValue[i], src->DataType); 884d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij break; 885d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DPFF_None: 886d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij break; 887d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij } 888d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij} 889d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 892b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 894eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 896b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 897eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int offset=0, ret; 899b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 901b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 902b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 903b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 904b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 905b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 906b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 907b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 908b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 909b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 910b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 911b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 912b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 913b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 914b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 915b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 916b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 917b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 918b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 919b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 920b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 921b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 922b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 923b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 924b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 925b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 926b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 927b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 928b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 929b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 930b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 931b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 932b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 933b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 934b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 935b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 936b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 937b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 938b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 939b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 940b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 941b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 942b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 943b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 944b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 945b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 946b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 947b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 948b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 949b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 950b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 951eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 952b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 953b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 954b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 955b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 956eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 957eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 958eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 959b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 960b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 961eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 962b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 963eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 964b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 965eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 966eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 967b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 968b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 969b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 970b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 971b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 972b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 973b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 974b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 975b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 976b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 977b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 978b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 979b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 980b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 981b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 982b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 983b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 984b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 985b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 986b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 987b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 988b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 989b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 990b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 991b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 992b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 993b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 994b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 995b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 996b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 997abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 998abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(int64_t); 999abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1000abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->i64); 1001abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1002abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 1003abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint64_t); 1004abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1005abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->u64); 1006abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1007b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 1008b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 1009b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1010b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1011b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1012cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 1013b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1014b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 1015b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 1016b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1017b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1018b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1019cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 1020b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1021b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 1022b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 1023b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1024b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1025b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1026cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 1027b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1028b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 1029b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 1030b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1031b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1032b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1033cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 1034b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1035b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 1036b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 1037b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1038b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1039b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1040cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 1041b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1042b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 1043b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 1044b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1045b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1046b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1047cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 1048b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1049abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 1050abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 1051abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1052abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 1053abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 1054cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 1055abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1056abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 1057abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 1058abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1059abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 1060abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 1061cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 1062abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1063b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 1064b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 1065735f41692934a716158cf051d76e988febeca7eeLinus Walleij dpv=ptp_get_packed_stringcopy(params, value->str, &size); 1066eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 1067b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1068eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 1069eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 1070eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 107199310d4445697da39f22dff35457c75e35e97171Linus Walleij} 107299310d4445697da39f22dff35457c75e35e97171Linus Walleij 107399310d4445697da39f22dff35457c75e35e97171Linus Walleij#define MAX_MTP_PROPS 127 107499310d4445697da39f22dff35457c75e35e97171Linus Walleijstatic inline uint32_t 10751e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_pack_OPL (PTPParams *params, MTPProperties *props, int nrofprops, unsigned char** opldataptr) 107699310d4445697da39f22dff35457c75e35e97171Linus Walleij{ 107799310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char* opldata; 10781e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *propitr; 107999310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char *packedprops[MAX_MTP_PROPS]; 108099310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t packedpropslens[MAX_MTP_PROPS]; 108139b9374f23451201dece736db13f0f648584dc32Linus Walleij uint32_t packedobjecthandles[MAX_MTP_PROPS]; 108299310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropsids[MAX_MTP_PROPS]; 108399310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropstypes[MAX_MTP_PROPS]; 108499310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t totalsize = 0; 108599310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t bufp = 0; 108699310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t noitems = 0; 108799310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t i; 108899310d4445697da39f22dff35457c75e35e97171Linus Walleij 108999310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 10901e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr = props; 10911e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij while (nrofprops-- && noitems < MAX_MTP_PROPS) { 10926c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low /* Object Handle */ 109339b9374f23451201dece736db13f0f648584dc32Linus Walleij packedobjecthandles[noitems]=propitr->ObjectHandle; 109499310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint32_t); /* Object ID */ 109599310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Metadata type */ 109699310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropsids[noitems]=propitr->property; 109799310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 109899310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Data type */ 109999310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropstypes[noitems]= propitr->datatype; 110099310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 110199310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Add each property to be sent. */ 110299310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 110399310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += packedpropslens[noitems]; 110499310d4445697da39f22dff35457c75e35e97171Linus Walleij noitems ++; 11051e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr ++; 110699310d4445697da39f22dff35457c75e35e97171Linus Walleij } 110799310d4445697da39f22dff35457c75e35e97171Linus Walleij 110899310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Allocate memory for the packed property list */ 110999310d4445697da39f22dff35457c75e35e97171Linus Walleij opldata = malloc(totalsize); 111099310d4445697da39f22dff35457c75e35e97171Linus Walleij 111199310d4445697da39f22dff35457c75e35e97171Linus Walleij htod32a(&opldata[bufp],noitems); 111299310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += 4; 111399310d4445697da39f22dff35457c75e35e97171Linus Walleij 111499310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Copy into a nice packed list */ 111599310d4445697da39f22dff35457c75e35e97171Linus Walleij for (i = 0; i < noitems; i++) { 111699310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Object ID */ 11176c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low htod32a(&opldata[bufp],packedobjecthandles[i]); 111899310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint32_t); 111999310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropsids[i]); 112099310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 112199310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropstypes[i]); 112299310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 112399310d4445697da39f22dff35457c75e35e97171Linus Walleij /* The copy the actual property */ 112499310d4445697da39f22dff35457c75e35e97171Linus Walleij memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 112599310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += packedpropslens[i]; 112699310d4445697da39f22dff35457c75e35e97171Linus Walleij free(packedprops[i]); 112799310d4445697da39f22dff35457c75e35e97171Linus Walleij } 112899310d4445697da39f22dff35457c75e35e97171Linus Walleij *opldataptr = opldata; 112999310d4445697da39f22dff35457c75e35e97171Linus Walleij return totalsize; 1130eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1131eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 11321e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijstatic int 11331e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij_compare_func(const void* x, const void *y) { 11341e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *px = x; 11351e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *py = y; 11361e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 11371e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij return px->ObjectHandle - py->ObjectHandle; 11381e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij} 11391e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 11408d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowstatic inline int 11411e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) 11428d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low{ 1143277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij uint32_t prop_count = dtoh32a(data); 11441e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *props = NULL; 1145277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij int offset = 0, i; 1146277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1147277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij if (prop_count == 0) { 11481e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = NULL; 1149277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return 0; 1150277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 1151d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); 1152277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 11533bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij len -= sizeof(uint32_t); 11541e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props = malloc(prop_count * sizeof(MTPProperties)); 11551e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij if (!props) return 0; 1156277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij for (i = 0; i < prop_count; i++) { 11573bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (len <= 0) { 1158d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); 11593bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL", i); 11603bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i); 1161d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij qsort (props, i, sizeof(MTPProperties),_compare_func); 1162d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij *pprops = props; 11633bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return i; 11643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij } 11651e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].ObjectHandle = dtoh32a(data); 1166277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 1167277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint32_t); 1168277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 11691e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].property = dtoh16a(data); 1170277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1171277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1172277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 11731e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].datatype = dtoh16a(data); 1174277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1175277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1176277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1177277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij offset = 0; 11781e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype); 1179277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += offset; 1180277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= offset; 1181277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 11821e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij qsort (props, prop_count, sizeof(MTPProperties),_compare_func); 11831e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = props; 1184277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return prop_count; 11858d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low} 11868d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low 1187eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1188eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 1189eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1190eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1191eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1192eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 1193eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 1194eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 1195eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 1196eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 1197eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 1198eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 1199eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1200b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 12017e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len) 1202eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 12037e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int length; 12047e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int type; 12057e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 1206eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1207eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 12087e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(ec,0,sizeof(*ec)); 12097e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij length=dtoh32a(&data[PTP_ec_Length]); 12107e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij type = dtoh16a(&data[PTP_ec_Type]); 1211b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 12127e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Code=dtoh16a(&data[PTP_ec_Code]); 12137e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); 12147e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 12157e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (type!=PTP_USB_CONTAINER_EVENT) { 12167e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); 12177e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 12187e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 12197e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param1+4)) { 12207e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param1=dtoh32a(&data[PTP_ec_Param1]); 12217e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=1; 12227e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 12237e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param2+4)) { 12247e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param2=dtoh32a(&data[PTP_ec_Param2]); 12257e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=2; 12267e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 12277e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param3+4)) { 12287e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param3=dtoh32a(&data[PTP_ec_Param3]); 12297e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=3; 12307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1231eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1232eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1233eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1234eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 1235eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1236eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1237eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 1238eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 1239eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 1240eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 1241eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 1242eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 1243eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1244b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1245b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1246eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1247eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 1248eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1249eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1250eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1251eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1252eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1253b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1254eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1255eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1256b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1257b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 1258b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 125996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij/* 126096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij PTP Canon EOS Folder Entry unpack 126196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0: 00 00 08 a0 objectid 126296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij4: 01 00 02 00 storageid 126396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij8: 01 30 00 00 ofc 126496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij12: 01 00 126596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij14: 00 00 126696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij16: 11 00 00 00 126796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij20: 00 00 00 00 126896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij24: 00 00 00 80 126996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij28: 00 00 08 a0 127096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij32: 4d 49 53 43-00 00 00 00 00 00 00 00 name 127196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij00 00 00 00 127296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij84 bc 74 46 objectime 127396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 127496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 127596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij(normal PTP GetObjectInfo) 127696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus WalleijObjectInfo for 'IMG_0199.JPG': 127796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij Object ID: 0x92740c72 127896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij StorageID: 0x00020001 127996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ObjectFormat: 0x3801 128096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ProtectionStatus: 0x0000 128196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ObjectCompressedSize: 2217241 128296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbFormat: 0x3808 128396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbCompressedSize: 5122 128496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbPixWidth: 160 128596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbPixHeight: 120 128696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImagePixWidth: 4000 128796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImagePixHeight: 3000 128896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImageBitDepth: 24 128996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ParentObject: 0x92740000 129096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij AssociationType: 0x0000 129196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij AssociationDesc: 0x00000000 129296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij SequenceNumber: 0x00000000 129396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ModificationDate: 0x4d985ff0 129496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij CaptureDate: 0x4d985ff0 129596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 129696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0010 38 00 00 00 Size of this entry 129796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0014 72 0c 74 92 OID 129896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0018 01 00 02 00 StorageID 129996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij001c 01 38 00 00 OFC 130096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0020 00 00 00 00 00 00 00 00 ? 130196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0028 19 d5 21 00 Size 130296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij002c 00 00 74 92 ? 130396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0030 70 0c 74 92 OID 130496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0034 49 4d 47 5f-30 31 39 39 2e 4a 50 47 IMG_0199.JPG 130596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0040 00 00 00 00 130696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0044 10 7c 98 4d Time 130796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 130896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 130996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij*/ 131096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectHandle 0 131196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_StorageID 4 131296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectFormatCode 8 131396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Flags 12 131496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectSize 20 131596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Filename 32 131696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Time 48 131796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 131896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleijstatic inline void 131996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleijptp_unpack_Canon_EOS_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 132096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij{ 132196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int i; 132296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 132396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cefe_ObjectHandle]); 132496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cefe_ObjectFormatCode]); 132596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Flags=dtoh8a(&data[PTP_cefe_Flags]); 132696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cefe_ObjectSize]); 132796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cefe_Time]); 132896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 132996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Filename[i]=(char)data[PTP_cefe_Filename+i]; 133096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij} 133196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 133296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 13331a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint16_t 13341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data ) 13351a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 13361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 13370546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner EOS ImageFormat entries (of at least the 5DM2 and the 400D) look like this: 13381a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: number of entries / generated files (1 or 2) 13391a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: size of this entry in bytes (most likely allways 0x10) 13401a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image type (1 == JPG, 6 == RAW) 13410546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32: image size (0 == Large, 1 == Medium, 2 == Small, 0xe == S1, 0xf == S2, 0x10 == S3) 13421a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW) 13430546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner If the number of entries is 2 the last 4 uint32 repeat. 13441a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13451a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij example: 13461a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 0: 0x 1 13471a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1: 0x 10 13481a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 2: 0x 6 13491a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 3: 0x 1 13501a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 4: 0x 4 13511a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13520546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner The idea is to simply 'condense' these values to just one uint16 to be able to conveniently 13531a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij use the available enumeration facilities (look-up table). The image size and compression 13541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij values fully describe the image format. Hence we generate a uint16 with the four nibles set 13551a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression. 13561a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij The above example would result in the value 0x1400. 13570546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 13580546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner The EOS 5D Mark III (and possibly other high-end EOS as well) added the extra fancy S1, S2 13590546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner and S3 JPEG options. S1 replaces the old Small. -1 the S1/S2/S3 to prevent the 0x10 overflow. 13601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij */ 13611a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij const unsigned char* d = *data; 13631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = dtoh32a( d ); 13641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t l, s1, c1, s2 = 0, c2 = 0; 13651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n != 1 && n !=2) { 13671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n); 13681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 13691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13701a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 13721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 13731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 13741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 13751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13761a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 13781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s1 = dtoh32a( d+=4 ); 13791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c1 = dtoh32a( d+=4 ); 13801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n == 2) { 13821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 13831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 13841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 13851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 13861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 13881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s2 = dtoh32a( d+=4 ); 13891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c2 = dtoh32a( d+=4 ); 13901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 13911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij *data = (unsigned char*) d+4; 13931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 13940546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* deal with S1/S2/S3 JPEG sizes, see above. */ 13950546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if( s1 >= 0xe ) 13960546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner s1--; 13970546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if( s2 >= 0xe ) 13980546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner s2--; 13990546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0); 14011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 14021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint32_t 14041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value) 14051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 14061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = (value & 0xFF) ? 2 : 1; 14071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t s = 4 + 0x10 * n; 14081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if( !data ) 14101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 14111a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14120546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner#define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X) 14130546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14141a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=0, n); 14151a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 14161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1); 14170546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF)); 14181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 8) & 0xF); 14191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n==2) { 14211a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 14221a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1); 14230546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF)); 14241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 0) & 0xF); 14251a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 14261a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 14270546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner#undef PACK_5DM3_SMALL_JPEG_SIZE 14280546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14290546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return s; 14300546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner} 14310546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14320546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerstatic inline char* 14330546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerptp_unpack_EOS_CustomFuncEx (PTPParams* params, unsigned char** data ) 14340546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner{ 14350546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t s = dtoh32a( *data ); 14360546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t n = s/4, i; 1437a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij char* str = (char*)malloc( s ); /* n is size in uint32, average len(itoa(i)) < 4 -> alloc n chars */ 14380546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (!str) 14390546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return str; 14400546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner char* p = str; 14410546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14420546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner for (i=0; i < n; ++i) 14430546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner p += sprintf(p, "%x,", dtoh32a( *data + 4*i )); 14440546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14450546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return str; 14460546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner} 14470546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14480546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerstatic inline uint32_t 14490546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str) 14500546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner{ 14510546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t s = strtoul(str, NULL, 16); 14520546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t n = s/4, i, v; 14530546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14540546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (!data) 14550546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return s; 14560546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14570546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner for (i=0; i<n; i++) 14580546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner { 14590546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner v = strtoul(str, &str, 16); 1460a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij str++; /* skip the ',' delimiter */ 14610546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data + i*4, v); 14620546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner } 14630546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 14641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 14651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 14661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1467b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 1468f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTP EOS Changes Entry unpack 1469f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij*/ 1470f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Size 0 1471f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Type 4 1472f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1473f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Subtype 8 /* only for properties */ 1474f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 1475f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 1476f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 1477f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 1478f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1479d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_RequestObjectTransfer */ 1480d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_ObjectID 8 1481d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_OFC 0x0c 1482d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Size 0x14 1483d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Name 0x1c 1484d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij 1485d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_ObjectAddedEx */ 1486d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_ObjectID 8 1487d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_StorageID 0x0c 1488d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_OFC 0x10 1489d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Size 0x1c 1490d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Parent 0x20 1491d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Name 0x28 1492f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1493f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijstatic inline int 1494f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **ce) 1495f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij{ 1496f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int i = 0, entries = 0; 1497f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *curdata = data; 1498f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1499f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (data==NULL) 1500f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return 0; 1501f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1502f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1503f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1504f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1505f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1506f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ((size == 8) && (type == 0)) 1507f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1508f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij entries++; 1509f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 15109d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij *ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1)); 1511f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (!*ce) return 0; 1512f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1513f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata = data; 1514f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij while (curdata - data < datasize) { 1515f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1516f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1517f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1518d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1519d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.info = NULL; 1520f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (type) { 1521d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_EC_CANON_EOS_ObjectAddedEx: 1522f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1523d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OA_ObjectID]); 1524d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece_OA_StorageID]); 1525d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece_OA_Parent]); 1526d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OA_OFC]); 1527d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]); 1528d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OA_Name])); 1529d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: objectinfo added oid %08lx, parent %08lx, ofc %04x, size %d, filename %s", i, (*ce)[i].u.object.oid, (*ce)[i].u.object.oi.ParentObject, (*ce)[i].u.object.oi.ObjectFormat, (*ce)[i].u.object.oi.ObjectCompressedSize, (*ce)[i].u.object.oi.Filename); 1530d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1531d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_EC_CANON_EOS_RequestObjectTransfer: 1532d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER; 1533f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 1534d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.StorageID = 0; /* use as marker */ 1535f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 1536d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij (*ce)[i].u.object.oi.ParentObject = 0; /* check, but use as marker */ 1537f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 1538f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 15393bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 1540d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: request object transfer oid %08lx, ofc %04x, size %d, filename %s", i, (*ce)[i].u.object.oid, (*ce)[i].u.object.oi.ObjectFormat, (*ce)[i].u.object.oi.ObjectCompressedSize, (*ce)[i].u.object.oi.Filename); 1541f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 15427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_AvailListChanged: { /* property desc */ 1543f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1544f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 1545f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 1546e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Desc_Data]; 1547f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1548f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1549f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 15507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype); 1551f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1552f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1553f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1554f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j==params->nrofcanon_props) { 15553bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propdesc %x, default value not found.", i, proptype); 1556f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1557f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1558f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 15597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* 1 - uint16 ? 15607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 3 - uint16 15617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 7 - string? 15627e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij */ 1563f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (propxtype != 3) { 15643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propxtype is %x for %04x, unhandled.", i, propxtype, proptype); 15653bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++) 1566e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1567f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1568f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 15691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (! propxcnt) 15701a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 15711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.", 15731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij i, propxtype, proptype, dpd->DataType, propxcnt); 15741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 15751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.NumberOfValues = propxcnt; 15760d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->FORM.Enum.SupportedValue) free (dpd->FORM.Enum.SupportedValue); 15771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 15781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 15801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 15811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 15821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 15831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 15841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* special handling of ImageFormat properties */ 1585f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<propxcnt;j++) { 15861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue[j].u16 = 1587e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dtoh16( ptp_unpack_EOS_ImageFormat( params, &xdata ) ); 15881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16); 15891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 15901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 15911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 15921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 'normal' enumerated types */ 15931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (dpd->DataType) { 15941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX( TYPE, CONV )\ 15951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<propxcnt;j++) { \ 1596e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(xdata); \ 1597e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(xdata)); \ 1598e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; /* might only be for propxtype 3 */ \ 15991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } \ 16001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 16011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_INT16: XX( i16, dtoh16a ); 16031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT32: XX( u32, dtoh32a ); 16041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT16: XX( u16, dtoh16a ); 16051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT8: XX( u8, dtoh8a ); 16061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 16071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 1608e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params ,"event %d: data type 0x%04x of %x unhandled, raw values:", i, dpd->DataType, proptype, dtoh32a(xdata)); 1609e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, xdata+=4) /* 4 is good for propxtype 3 */ 1610e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %3d: 0x%8x", j, dtoh32a(xdata)); 16111a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 1612f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1613f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1614f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1615f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 16167e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_PropValueChanged: 1617f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (size >= 0xc) { /* property info */ 1618f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int j; 1619f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1620e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Val_Data]; 1621f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1622f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 16231a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: EOS prop %04x info record, datasize is %d", i, proptype, size-PTP_ece_Prop_Val_Data); 1624f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1625f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1626f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1627f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j<params->nrofcanon_props) { 1628f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ( (params->canon_props[j].size != size) || 1629e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij (memcmp(params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data))) { 1630f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 1631e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy (params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data); 1632f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1633f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 1634f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j) 1635f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 1636f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij else 1637f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = malloc(sizeof(params->canon_props[0])); 1638f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].type = type; 1639f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].proptype = proptype; 1640f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].size = size; 1641f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 1642e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy(params->canon_props[j].data, xdata, size-PTP_ece_Prop_Val_Data); 1643f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 1644f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.GetSet = 1; 1645f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 1646f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->nrofcanon_props = j+1; 1647f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1648f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 16491a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1650d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 1651d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.propid = proptype; 1652d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 16531a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* fix GetSet value */ 16541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 16551a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX(x) case PTP_DPC_CANON_##x: 16561a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusMode) 16571a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryPower) 16581a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatterySelect) 16591a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ModelID) 16601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_PTPExtensionVersion) 16611a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DPOFVersion) 16621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AvailableShots) 16631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentStorage) 16641a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentFolder) 16651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenu) 16661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenuList) 16671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_HDDirectoryStructure) 16681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryInfo) 16691a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AdapterInfo) 16701a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensStatus) 16711a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CardExtension) 16721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_TempStatus) 16731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ShutterCounter) 16741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_SerialNumber) 16751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfFieldPreview) 16761a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EVFRecordStatus) 16771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LvAfSystem) 16781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusInfoEx) 16791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfField) 16801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_Brightness) 16811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EFComp) 16821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensName) 16831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensID) 16841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 16851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->GetSet = PTP_DPGS_Get; 16861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 16871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 16881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* set DataType */ 1690f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (proptype) { 1691ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DPC_CANON_EOS_CameraTime: 1692d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_AvailableShots: 1693d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CaptureDestination: 1694d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXA: 1695d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXB: 1696d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentStorage: 1697d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentFolder: 1698d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ShutterCounter: 1699d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ModelID: 1700d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LensID: 1701d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_StroboFiring: 1702ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->DataType = PTP_DTC_UINT32; 1703ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 17040d762ccc39331608119dd0267021b165e22de499Linus Walleij /* enumeration for AEM is never provided, but is available to set */ 17050d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_AutoExposureMode: 17060d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT16; 17070d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 17080d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FORM.Enum.NumberOfValues = 0; 17090d762ccc39331608119dd0267021b165e22de499Linus Walleij break; 1710f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Aperture: 1711f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ShutterSpeed: 1712f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ISOSpeed: 17137e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_FocusMode: 17147e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorSpace: 17157e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_BatteryPower: 1716e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BatterySelect: 1717d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_PTPExtensionVersion: 17181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_DriveMode: 17191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_AEB: 1720e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BracketMode: 1721e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_QuickReviewTime: 17220d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFMode: 17230d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFOutputDevice: 1724a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij case PTP_DPC_CANON_EOS_AutoPowerOff: 1725f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT16; 1726f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1727f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_PictureStyle: 1728f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalance: 1729f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_MeteringMode: 17307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ExpCompensation: /* actually int8 if you calculate */ 1731f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT8; 1732f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1733f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Owner: 17341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Artist: 17351a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Copyright: 17361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_SerialNumber: 17371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_LensName: 1738f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_STR; 1739f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 17407e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA: 17417e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB: 17427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij dpd->DataType = PTP_DTC_INT16; 17437e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 17447e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* unknown props, listed from dump.... all 16 bit, but vals might be smaller */ 17457e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DPOFVersion: 17461a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT16; 17471a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data); 17481a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1749e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 17501a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 17517e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc1: 17527e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc2: 17537e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc3: 17547e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc4: 17557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc5: 17567e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc6: 17577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc7: 17587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc8: 17597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc9: 17607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc10: 17617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc11: 17621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT8; 17631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data); 17647e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1765e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 17661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* custom func entries look like this on the 400D: '5 0 0 0 ?' = 4 bytes size + 1 byte data */ 1767e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; 17687e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 17697e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* yet unknown 32bit props */ 17707e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorTemperature: 17717e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WftStatus: 17727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_LensStatus: 17737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CardExtension: 17747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_TempStatus: 17757e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_PhotoStudioMode: 17767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DepthOfFieldPreview: 17777e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFSharpness: 17787e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFWBMode: 17797e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFClickWBCoeffs: 17807e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFColorTemp: 1781d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_EVFRecordStatus: 1782d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ExposureSimMode: 1783d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvAfSystem: 1784d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_MovSize: 1785d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_DepthOfField: 1786d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvViewTypeSelect: 17870d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT32; 17887e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data); 17891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0) 17901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) ); 17911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++) 1792e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: 0x%8x", j, ((uint32_t*)xdata)[j]); 17937e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 1794d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij /* ImageFormat properties have to be ignored here, see special handling below */ 1795d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 1796d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 1797d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 1798d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 17990546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner case PTP_DPC_CANON_EOS_CustomFuncEx: 1800d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1801f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 18023bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data); 18033bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 1804e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1805f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1806f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1807f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (dpd->DataType) { 1808ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DTC_UINT32: 1809e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u32 = dtoh32a(xdata); 1810e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u32 = dtoh32a(xdata); 18113bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32); 1812ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 1813f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT16: 1814e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = dtoh16a(xdata); 1815e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u16 = dtoh16a(xdata); 18163bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 1817f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1818f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT8: 1819e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u8 = dtoh8a(xdata); 1820e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u8 = dtoh8a(xdata); 18213bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 1822f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1823f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_STR: { 18241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ 1825f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint8_t len = 0; 1826f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 1827f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 18281a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#else 18290d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str); 1830e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.str = strdup( (char*)xdata ); 18310d762ccc39331608119dd0267021b165e22de499Linus Walleij 18320d762ccc39331608119dd0267021b165e22de499Linus Walleij if (dpd->CurrentValue.str) free (dpd->CurrentValue.str); 1833e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.str = strdup( (char*)xdata ); 18341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#endif 18357e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 1836f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1837f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1838f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1839f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /* debug is printed in switch above this one */ 1840f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1841f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 18421a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 18430546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* ImageFormat and customFuncEx special handling (WARNING: dont move this in front of the dpd->DataType switch!) */ 1844d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij switch (proptype) { 1845d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 1846d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 1847d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 1848d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 1849d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->DataType = PTP_DTC_UINT16; 1850e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &xdata ); 1851d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16; 1852d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params,"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 1853d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 18540546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner case PTP_DPC_CANON_EOS_CustomFuncEx: 18550546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->DataType = PTP_DTC_STR; 18560546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str); 18570546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (dpd->CurrentValue.str) free (dpd->CurrentValue.str); 18580546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->FactoryDefaultValue.str = ptp_unpack_EOS_CustomFuncEx( params, &data ); 18590546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->CurrentValue.str = strdup( (char*)dpd->FactoryDefaultValue.str ); 18600546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner ptp_debug (params,"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 18610546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner break; 1862d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij } 1863d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 1864f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1865f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1866d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_EC_CANON_EOS_CameraStatusChanged: 1867d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d)", i, size); 1868d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS; 1869d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.status = dtoh32a(curdata+8); 18709e09ad0e32cbdac88637d4ee2cc02ca3b771ca40Linus Walleij params->eos_camerastatus = dtoh32a(curdata+8); 1871d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 18727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case 0: /* end marker */ 18737e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size == 8) /* no output */ 18747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 18757e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS event 0, but size %d", i, size); 18767e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 187796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij case PTP_EC_CANON_EOS_BulbExposureTime: 187896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 187996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij (*ce)[i].u.info = malloc(strlen("BulbExposureTime 123456789")); 188096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij sprintf ((*ce)[i].u.info, "BulbExposureTime %d", dtoh32a(curdata+8)); 188196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij break; 1882f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 1883d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij switch (type) { 1884d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij#define XX(x) case PTP_EC_CANON_EOS_##x: \ 1885d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size); \ 1886d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij (*ce)[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)")); \ 1887d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij sprintf ((*ce)[i].u.info, "unhandled EOS event "#x" (size %d)", size); \ 1888d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 1889d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetEvent) 1890d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectRemoved) 1891d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetObjectInfoEx) 1892d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageStatusChanged) 1893d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageInfoChanged) 1894d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectInfoChangedEx) 1895d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectContentChanged) 1896d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(WillSoonShutdown) 1897d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ShutdownTimerUpdated) 1898d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransfer) 1899d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferDT) 1900d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransferDT) 1901d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreAdded) 1902d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreRemoved) 1903d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(BulbExposureTime) 1904d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RecordingTime) 1905d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferTS) 1906d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(AfResult) 1907d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#undef XX 1908d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij default: 1909d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: unknown EOS event %04x", i, type); 1910d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1911d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij } 19127e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size >= 0x8) { /* event info */ 19137e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int j; 1914d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij for (j=8;j<size;j++) 1915d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, " %d: %02x", j, curdata[j]); 19167e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1917f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1918f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1919f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1920f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 1921f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij i++; 19229d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij if ((size == 8) && (type == 0)) 19239d22ce0e3214f38d30435fb9ec8ff2c8c6c4191eLinus Walleij break; 1924f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 19250d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!entries) { 19260d762ccc39331608119dd0267021b165e22de499Linus Walleij free (*ce); 19270d762ccc39331608119dd0267021b165e22de499Linus Walleij *ce = NULL; 19280d762ccc39331608119dd0267021b165e22de499Linus Walleij } 1929f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return entries; 1930f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij} 1931f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1932f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij/* 1933b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 1934b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 1935b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 1936b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 1937b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 1938b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 1939b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 19407e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, int *cnt) 1941b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 1942b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 1943b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1944b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 1945b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 1946b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1947b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 1948b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 1949b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 1950b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 1951b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 19520d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!*cnt) 19530d762ccc39331608119dd0267021b165e22de499Linus Walleij return; 19540d762ccc39331608119dd0267021b165e22de499Linus Walleij 19557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij *ec = malloc(sizeof(PTPContainer)*(*cnt)); 1956b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1957b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 19587e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(&(*ec)[i],0,sizeof(PTPContainer)); 19597e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 19607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 19617e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Nparam = 1; 1962b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1963eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1964eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1965eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1966b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1967b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 1968b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 1969b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 1970b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 1971b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1972b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 1973b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 1974b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 1975b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 1976b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 1977b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 1978b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 1979b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 1980b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 1981b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1982b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 1983b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 1984b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 1985b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 1986b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 1987b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1988b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1989b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1990b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1991b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 1992b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 1993b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1994b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1995b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 1996b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1997b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 1998b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 1999b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 2000b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 2001b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 2002b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 2003b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 2004b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 2005b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 20067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_version 0x00 20087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_ofc 0x02 20097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk1 0x04 20107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_objectid 0x08 20117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_parentid 0x0c 20127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_previd 0x10 /* in same dir */ 20137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextid 0x14 /* in same dir */ 20147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 20157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 20167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_name 0x20 20177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_flags 0x2c 20187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_size 0x30 20197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unixtime 0x34 20207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_year 0x38 20217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_month 0x39 20227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_mday 0x3a 20237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_hour 0x3b 20247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_minute 0x3c 20257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_second 0x3d 20267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk2 0x3e 20277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_thumbsize 0x40 20287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_width 0x44 20297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_height 0x48 20307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijstatic inline uint16_t 20327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijptp_unpack_canon_directory ( 20337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPParams *params, 20347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *dir, 20357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t cnt, 20367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectHandles *handles, 20377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo **oinfos, /* size(handles->n) */ 20387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t **flags /* size(handles->n) */ 20397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij) { 20407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned int i, j, nrofobs = 0, curob = 0; 20417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 20437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) 20447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(dir+i*0x4c)) nrofobs++; 20457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->n = nrofobs; 20467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); 20477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!handles->Handler) return PTP_RC_GeneralError; 20487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); 20497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*oinfos) return PTP_RC_GeneralError; 20507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij *flags = calloc(sizeof((*flags)[0]),nrofobs); 20517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*flags) return PTP_RC_GeneralError; 20527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Migrate data into objects ids, handles into 20547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the object handler array. 20557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 20567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob = 0; 20577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 20587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 20597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo *oi = (*oinfos)+curob; 20607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 20627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 20657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->StorageID = 0xffffffff; 20667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 20677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 20687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 20697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 20707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 20717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 20727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 20737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 20747347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 20757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob++; 20767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over Storage ID entries and distribute the IDs to 20787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the parent objects. */ 20797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 20807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 20817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 20827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(cur)) 20847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 20857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 20867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) continue; 20877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 20887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 20897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over all objects and distribute the storage ids */ 20907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij while (1) { 20917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij int changed = 0; 20927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 20937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 20947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 20957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 20967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 20977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t storageid; 20987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 20997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 21007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 21017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 21027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 21037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 21047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 21057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij storageid = (*oinfos)[j].StorageID; 21077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (storageid == 0xffffffff) continue; 21087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextoid != 0xffffffff) { 21097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 21107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 21117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 21127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 21137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 21157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 21167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 21177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextchild != 0xffffffff) { 21207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 21217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 21227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 21237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 21247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 21267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 21277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 21287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21297347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21317347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Check if we: 21327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed no entry (nothing more to do) 21337347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed all of them at once (usually happens) 21347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * break if we do. 21357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 21367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!changed || (changed==nrofobs-1)) 21377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij break; 21387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 21397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#undef ISOBJECT 21407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij return PTP_RC_OK; 21417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij} 2142