1a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij/* ptp-pack.c 2a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * 3a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl> 4aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner * Copyright (C) 2003-2016 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 219783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 229783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij * Boston, MA 02110-1301 USA 23a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij */ 24a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij 25b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* currently this file is included into ptp.c */ 26eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 279783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#ifdef HAVE_LIMITS_H 289783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#include <limits.h> 299783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#endif 309783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#ifndef UINT_MAX 319783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij# define UINT_MAX 0xFFFFFFFF 329783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#endif 333d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 34a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij#include <iconv.h> 356db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 36a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 37b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 38eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16p (PTPParams *params, uint16_t var) 39eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 40eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 41eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 42eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 43b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 44eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32p (PTPParams *params, uint32_t var) 45eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 46eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 47eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 48eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 49b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 50eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod16ap (PTPParams *params, unsigned char *a, uint16_t val) 51eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 52eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 53b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole16a(a,val); 54e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 55eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe16a(a,val); 56eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 57eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 58b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 59eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijhtod32ap (PTPParams *params, unsigned char *a, uint32_t val) 60eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 61eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (params->byteorder==PTP_DL_LE) 62b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htole32a(a,val); 63e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 64eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htobe32a(a,val); 65eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 66eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 67abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline void 68abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijhtod64ap (PTPParams *params, unsigned char *a, uint64_t val) 69abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 70abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij if (params->byteorder==PTP_DL_LE) 71abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htole64a(a,val); 72e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij else 73abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htobe64a(a,val); 74abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 75abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 76b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 77eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh16p (PTPParams *params, uint16_t var) 78eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 79eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 80eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 81eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 82b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 83eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleijdtoh32p (PTPParams *params, uint32_t var) 84eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 85eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 86eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 87eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 88abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijstatic inline uint64_t 89abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleijdtoh64p (PTPParams *params, uint64_t var) 90abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij{ 91abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var)); 92abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij} 93abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 94b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint16_t 951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh16ap (PTPParams *params, const unsigned char *a) 96eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 97eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 98eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 99eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 100b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh32ap (PTPParams *params, const unsigned char *a) 102eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 103eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 104eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 105eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 106b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint64_t 1071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijdtoh64ap (PTPParams *params, const unsigned char *a) 108eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 109abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a)); 110eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 111eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 112b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod8a(a,x) *(uint8_t*)(a) = x 113b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16a(a,x) htod16ap(params,a,x) 114b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32a(a,x) htod32ap(params,a,x) 115abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64a(a,x) htod64ap(params,a,x) 116b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod16(x) htod16p(params,x) 117b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define htod32(x) htod32p(params,x) 118abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define htod64(x) htod64p(params,x) 119b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 120b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh8a(x) (*(uint8_t*)(x)) 121b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16a(a) dtoh16ap(params,a) 122b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32a(a) dtoh32ap(params,a) 123b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh64a(a) dtoh64ap(params,a) 124b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh16(x) dtoh16p(params,x) 125b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define dtoh32(x) dtoh32p(params,x) 126abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij#define dtoh64(x) dtoh64p(params,x) 127b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 128b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 129b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline char* 130aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissnerptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t total, uint8_t *len) 131eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 132a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint8_t length; 133a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij uint16_t string[PTP_MAXSTRLEN+1]; 134a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ 135e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij char loclstr[PTP_MAXSTRLEN*3+1]; 136a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij size_t nconv, srclen, destlen; 137a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij char *src, *dest; 138a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 139aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (offset + 1 >= total) 140aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return NULL; 141aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 142a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ 143a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *len = length; 144a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (length == 0) /* nothing to do? */ 145aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return NULL; 146aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 147aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (offset + 1 + length*sizeof(string[0]) > total) 148aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return NULL; 149a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 150a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* copy to string[] to ensure correct alignment for iconv(3) */ 151a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(string, &data[offset+1], length * sizeof(string[0])); 152a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij string[length] = 0x0000U; /* be paranoid! add a terminator. */ 153a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[0] = '\0'; 154e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij 155a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* convert from camera UCS-2 to our locale */ 156a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij src = (char *)string; 157a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij srclen = length * sizeof(string[0]); 158a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr; 159a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij destlen = sizeof(loclstr)-1; 1606db174f4d18af574fab991309e11010aa0eb4543Linus Walleij nconv = (size_t)-1; 1613d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 162d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij if (params->cd_ucs2_to_locale != (iconv_t)-1) 163d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen); 1646db174f4d18af574fab991309e11010aa0eb4543Linus Walleij#endif 165a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (nconv == (size_t) -1) { /* do it the hard way */ 166a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij int i; 167a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* try the old way, in case iconv is broken */ 168a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij for (i=0;i<length;i++) { 169a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij if (dtoh16a(&data[offset+1+2*i])>127) 170a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = '?'; 171a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij else 172a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[i] = dtoh16a(&data[offset+1+2*i]); 173eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 174a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij dest = loclstr+length; 175eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 176a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij *dest = '\0'; 177a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ 178a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij return(strdup(loclstr)); 179a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 180a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 181a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline int 182a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijucs2strlen(uint16_t const * const unicstr) 183a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 18496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int length = 0; 185a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 186a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Unicode strings are terminated with 2 * 0x00 */ 187a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij for(length = 0; unicstr[length] != 0x0000U; length ++); 188a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return length; 189eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 190eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 191a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 192b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 193b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 194eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 19596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int packedlen = 0; 196a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij uint16_t ucs2str[PTP_MAXSTRLEN+1]; 197a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij char *ucs2strp = (char *) ucs2str; 198a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t convlen = strlen(string); 199a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 200a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 201a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memset(ucs2strp, 0, sizeof(ucs2str)); /* XXX: necessary? */ 2023d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 203d000c371601fafcf75d2de2d1060ee11be2007d6Linus Walleij if (params->cd_locale_to_ucs2 != (iconv_t)-1) { 2046db174f4d18af574fab991309e11010aa0eb4543Linus Walleij size_t nconv; 2056db174f4d18af574fab991309e11010aa0eb4543Linus Walleij size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 2066db174f4d18af574fab991309e11010aa0eb4543Linus Walleij char *stringp = string; 2076db174f4d18af574fab991309e11010aa0eb4543Linus Walleij 2086db174f4d18af574fab991309e11010aa0eb4543Linus Walleij nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, 2096db174f4d18af574fab991309e11010aa0eb4543Linus Walleij &ucs2strp, &convmax); 2106db174f4d18af574fab991309e11010aa0eb4543Linus Walleij if (nconv == (size_t) -1) 2116db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[0] = 0x0000U; 212d6f25baf36fba05e3d8b2fa6d3cd4c026e2e6d33Linus Walleij } else 213d000c371601fafcf75d2de2d1060ee11be2007d6Linus Walleij#endif 2146db174f4d18af574fab991309e11010aa0eb4543Linus Walleij { 2152ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int i; 2162ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij 2176db174f4d18af574fab991309e11010aa0eb4543Linus Walleij for (i=0;i<convlen;i++) { 2186db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[i] = string[i]; 2196db174f4d18af574fab991309e11010aa0eb4543Linus Walleij } 2206db174f4d18af574fab991309e11010aa0eb4543Linus Walleij ucs2str[convlen] = 0; 2216db174f4d18af574fab991309e11010aa0eb4543Linus Walleij } 222a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij /* 223a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 224a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij * why do we need ucs2strlen()? 225a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij */ 226a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij packedlen = ucs2strlen(ucs2str); 227a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij if (packedlen > PTP_MAXSTRLEN-1) { 228a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij *len=0; 229a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return; 230a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij } 231958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 2327f2343824550452974d78f5dbd94e64844355c33Linus Walleij /* number of characters including terminating 0 (PTP standard confirmed) */ 233a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij htod8a(&data[offset],packedlen+1); 234a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 235a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 236958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij 237958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* The returned length is in number of characters */ 238048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij *len = (uint8_t) packedlen+1; 239eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 240eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 241a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleijstatic inline unsigned char * 242735f41692934a716158cf051d76e988febeca7eeLinus Walleijptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 243a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij{ 2448b42ca3d3baeb7c8f3e5eca88c613adb612e4ec0Richard Low uint8_t packed[PTP_MAXSTRLEN*2+3], len; 245a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij size_t plen; 246a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij unsigned char *retcopy = NULL; 247d47b9218023a6b943a93faa743712ae072cba85cRichard Low 248d47b9218023a6b943a93faa743712ae072cba85cRichard Low if (string == NULL) 249d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, "", (unsigned char*) packed, 0, &len); 250d47b9218023a6b943a93faa743712ae072cba85cRichard Low else 251d47b9218023a6b943a93faa743712ae072cba85cRichard Low ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 252d47b9218023a6b943a93faa743712ae072cba85cRichard Low 253958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij /* returned length is in characters, then one byte for string length */ 254958441f8ed3e704cf07c9f600730f90a80a0d424Linus Walleij plen = len*2 + 1; 255048d938dc4889b74b258a786d5f53142b059fc32Linus Walleij 256a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij retcopy = malloc(plen); 257735f41692934a716158cf051d76e988febeca7eeLinus Walleij if (!retcopy) { 258735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = 0; 259a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return NULL; 260735f41692934a716158cf051d76e988febeca7eeLinus Walleij } 261a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij memcpy(retcopy, packed, plen); 262735f41692934a716158cf051d76e988febeca7eeLinus Walleij *packed_size = plen; 263a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij return (retcopy); 264a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij} 265a823a70e892d5eb1f4528679429cb3d9539abbe4Linus Walleij 266b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 2673d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissnerptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint32_t **array) 268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 269eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 270eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 271aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!data) 272aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 273aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 2743d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (offset >= datalen) 2753d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return 0; 2763d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 2773d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (offset + sizeof(uint32_t) > datalen) 2783d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return 0; 2793d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 2809783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij *array = NULL; 281eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 2829783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (n >= UINT_MAX/sizeof(uint32_t)) 2839783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 0; 2849783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!n) 2859783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 0; 2863d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 2873d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (offset + sizeof(uint32_t)*(n+1) > datalen) { 2883d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params ,"array runs over datalen bufferend (%d vs %d)", offset + sizeof(uint32_t)*(n+1) , datalen); 2893d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return 0; 2903d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 2913d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 292eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint32_t)); 293aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!*array) 294aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 2959783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij for (i=0;i<n;i++) 296eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 297eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 298eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 299eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 300b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 301f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 302f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij{ 303f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij uint32_t i=0; 304f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 305f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij *data = malloc ((arraylen+1)*sizeof(uint32_t)); 306aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!*data) 307aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 308f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[0],arraylen); 309f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij for (i=0;i<arraylen;i++) 310f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 311f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij return (arraylen+1)*sizeof(uint32_t); 312f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij} 313f67bca9bde733f456ad341c0d852147124ab388aLinus Walleij 314f67bca9bde733f456ad341c0d852147124ab388aLinus Walleijstatic inline uint32_t 3153d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissnerptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint16_t **array) 316eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 317eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t n, i=0; 318eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 319aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!data) 320aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 3219783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij *array = NULL; 322eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij n=dtoh32a(&data[offset]); 3239783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (n >= UINT_MAX/sizeof(uint16_t)) 3249783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 0; 3259783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!n) 3269783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 0; 3273d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (offset + sizeof(uint32_t) > datalen) 3283d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return 0; 3293d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (offset + sizeof(uint32_t)+sizeof(uint16_t)*n > datalen) { 3303d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params ,"array runs over datalen bufferend (%d vs %d)", offset + sizeof(uint32_t)+n*sizeof(uint16_t) , datalen); 3313d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return 0; 3323d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 333eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *array = malloc (n*sizeof(uint16_t)); 334aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!*array) 335aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 3369783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij for (i=0;i<n;i++) 337eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 338eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return n; 339eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 340eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 341eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* DeviceInfo pack/unpack */ 342eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 343eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_StandardVersion 0 344eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionID 2 345eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionVersion 6 346eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_VendorExtensionDesc 8 347eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_FunctionalMode 8 348eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_di_OperationsSupported 10 349eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 350aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissnerstatic inline int 351b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 352eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 353eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t len; 354eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij unsigned int totallen; 3557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 356aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!data) return 0; 357aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen < 12) return 0; 358aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner memset (di, 0, sizeof(*di)); 3597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 360eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionID = 361eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh32a(&data[PTP_di_VendorExtensionID]); 362eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->VendorExtensionVersion = 363eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_VendorExtensionVersion]); 364aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner di->VendorExtensionDesc = 365eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_string(params, data, 366aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner PTP_di_VendorExtensionDesc, 367aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner datalen, 368aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner &len); 369eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=len*2+1; 370aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen) return 0; 371aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner di->FunctionalMode = 372eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 373eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 374eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 3753d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner datalen, 376eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->OperationsSupported); 377eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 378aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 379eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 380eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 3813d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner datalen, 382eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->EventsSupported); 383eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 384aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 385eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DevicePropertiesSupported_len = 386eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_unpack_uint16_t_array(params, data, 387eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 3883d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner datalen, 389eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->DevicePropertiesSupported); 390eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 391aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 392eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 393eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 3943d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner datalen, 395eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->CaptureFormats); 396eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 397aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 398eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 4003d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner datalen, 401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &di->ImageFormats); 402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 403aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 404eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Manufacturer = ptp_unpack_string(params, data, 405eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 406aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner datalen, 407eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 408eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 409aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner /* be more relaxed ... as these are optional its ok if they are not here */ 410aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 1; 411eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->Model = ptp_unpack_string(params, data, 412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 413aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner datalen, 414eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 415eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 416aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner /* be more relaxed ... as these are optional its ok if they are not here */ 417aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 1; 418eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->DeviceVersion = ptp_unpack_string(params, data, 419eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 420aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner datalen, 421eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 422eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij totallen+=len*2+1; 423aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner /* be more relaxed ... as these are optional its ok if they are not here */ 424aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen <= totallen+PTP_di_OperationsSupported) return 1; 425eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij di->SerialNumber = ptp_unpack_string(params, data, 426eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_di_OperationsSupported+totallen, 427aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner datalen, 428eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &len); 429aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 1; 430eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 431a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij 4322ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleijinline static void 433a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleijptp_free_DI (PTPDeviceInfo *di) { 4343d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->SerialNumber); 4353d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->DeviceVersion); 4363d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->Model); 4373d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->Manufacturer); 4383d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->ImageFormats); 4393d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->CaptureFormats); 4403d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->VendorExtensionDesc); 4413d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->OperationsSupported); 4423d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->EventsSupported); 4433d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (di->DevicePropertiesSupported); 444aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner memset(di, 0, sizeof(*di)); 445a8a19cc8f7d6913e13f3e87709c687baddf2e596Linus Walleij} 4467e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 4477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij/* EOS Device Info unpack */ 448aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissnerstatic inline int 4497e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) 4507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij{ 4512ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int totallen = 4; 45296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 45396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij memset (di,0, sizeof(*di)); 454aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (datalen < 8) return 0; 4557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 4567e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* uint32_t struct len - ignore */ 4577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, 4583d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner totallen, datalen, &di->EventsSupported); 459aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!di->EventsSupported) return 0; 4607e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->EventsSupported_len*sizeof(uint32_t)+4; 461aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (totallen >= datalen) return 0; 4627e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 4637e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, 4643d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner totallen, datalen, &di->DevicePropertiesSupported); 465aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!di->DevicePropertiesSupported) return 0; 4667e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; 467aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (totallen >= datalen) return 0; 4687e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 4697e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij di->unk_len = ptp_unpack_uint32_t_array(params, data, 4703d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner totallen, datalen, &di->unk); 471aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!di->unk) return 0; 4727e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij totallen += di->unk_len*sizeof(uint32_t)+4; 473aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 1; 4747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij} 4750d762ccc39331608119dd0267021b165e22de499Linus Walleij 4760d762ccc39331608119dd0267021b165e22de499Linus Walleijstatic inline void 4770d762ccc39331608119dd0267021b165e22de499Linus Walleijptp_free_EOS_DI (PTPCanonEOSDeviceInfo *di) 4780d762ccc39331608119dd0267021b165e22de499Linus Walleij{ 4790d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->EventsSupported); 4800d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->DevicePropertiesSupported); 4810d762ccc39331608119dd0267021b165e22de499Linus Walleij free (di->unk); 4820d762ccc39331608119dd0267021b165e22de499Linus Walleij} 483eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 484eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectHandles array pack/unpack */ 485eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 486eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oh 0 487eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 488b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 489b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 490eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 491f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (len) { 4923d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, len, &oh->Handler); 493f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 494f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->n = 0; 495f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij oh->Handler = NULL; 496f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 497eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 498eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 499eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StoreIDs array pack/unpack */ 500eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 501eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_sids 0 502eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 503b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 504b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 505eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 506aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner sids->n = 0; 507aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner sids->Storage = NULL; 508aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 509aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!data || !len) 51096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij return; 511aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 5123d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, len, &sids->Storage); 513eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 514eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 515eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* StorageInfo pack/unpack */ 516eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 517eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageType 0 518eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FilesystemType 2 519eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_AccessCapability 4 520eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_MaxCapability 6 521eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInBytes 14 522eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_FreeSpaceInImages 22 523eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_si_StorageDescription 26 524eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 525aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissnerstatic inline int 526b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 527eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 528eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t storagedescriptionlen; 529eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 530aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (len < 26) return 0; 531eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 532eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 533eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 534eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 535eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 536eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 5373d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 5383d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner /* FIXME: check more lengths here */ 539eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->StorageDescription=ptp_unpack_string(params, data, 540aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner PTP_si_StorageDescription, 541aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner len, 542aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner &storagedescriptionlen); 543eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij si->VolumeLabel=ptp_unpack_string(params, data, 544eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_si_StorageDescription+storagedescriptionlen*2+1, 545aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner len, 546eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij &storagedescriptionlen); 547aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 1; 548eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 549eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 550eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* ObjectInfo pack/unpack */ 551eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 552eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_StorageID 0 553eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectFormat 4 554eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ProtectionStatus 6 555eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ObjectCompressedSize 8 556eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbFormat 12 557eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbCompressedSize 14 558eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixWidth 18 559eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ThumbPixHeight 22 560eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixWidth 26 561eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImagePixHeight 30 562eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ImageBitDepth 34 563eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_ParentObject 38 564eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationType 42 565eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_AssociationDesc 44 566eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_SequenceNumber 48 567eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_filenamelen 52 568eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_oi_Filename 53 569eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 570a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* the max length assuming zero length dates. We have need 3 */ 571a032327c7485548c42f8162f87469dc0e0dd2126Linus Walleij/* bytes for these. */ 572a679b1c4d273f210abb6befc5d9954a25427c329Richard Low#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 573a679b1c4d273f210abb6befc5d9954a25427c329Richard Low 574b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 575b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 576eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 577b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* oidata; 578eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 579eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen=0; 580a679b1c4d273f210abb6befc5d9954a25427c329Richard Low /* let's allocate some memory first; correct assuming zero length dates */ 5810546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner oidata=malloc(PTP_oi_MaxLen + params->ocs64*4); 5820546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner *oidataptr=oidata; 583eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* the caller should free it after use! */ 584eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 585eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date="20020101T010101"; /* XXX Fake date */ 586eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 5870546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner memset (oidata, 0, PTP_oi_MaxLen + params->ocs64*4); 588eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 589eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 590eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 591eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 5920546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (params->ocs64) 5930546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner oidata += 4; 594eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 595eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 596eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 597eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 598eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 599eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 600eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 601eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 602eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 603eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 604eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 605eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 606eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 607eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 608eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij filenamelen=(uint8_t)strlen(oi->Filename); 609eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 610eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 611eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 612eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 613eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 614eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* 615eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *XXX Fake date. 616eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * for example Kodak sets Capture date on the basis of EXIF data. 617eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * Spec says that this field is from perspective of Initiator. 618eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 619eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 620eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen=strlen(capture_date); 621eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 622eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 623eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 624eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 625eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 626eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 627eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capturedatelen+1); 628eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 629eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 630eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date[i]; 631eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 632eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#endif 633eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* XXX this function should return dataset length */ 6340546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3)+params->ocs64*4; 635eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 636eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 6373bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleijstatic time_t 6386db174f4d18af574fab991309e11010aa0eb4543Linus Walleijptp_unpack_PTPTIME (const char *str) { 6393bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char ptpdate[40]; 6403bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij char tmp[5]; 641a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij size_t ptpdatelen; 6423bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij struct tm tm; 6433bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 6443bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (!str) 6453bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 6463bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptpdatelen = strlen(str); 6477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen >= sizeof (ptpdate)) { 6486db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is larger then size of buffer", ptpdatelen, (int)sizeof(ptpdate));*/ 6493bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 6507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 6517e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (ptpdatelen<15) { 6526db174f4d18af574fab991309e11010aa0eb4543Linus Walleij /*ptp_debug (params ,"datelen is less than 15 (%d)", ptpdatelen);*/ 6533bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return 0; 6547e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 655a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij strncpy (ptpdate, str, sizeof(ptpdate)); 656a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij ptpdate[sizeof(ptpdate) - 1] = '\0'; 6573bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 6583bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij memset(&tm,0,sizeof(tm)); 6593bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate, 4); 6603bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[4] = 0; 6613bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_year=atoi (tmp) - 1900; 6623bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 4, 2); 6633bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 6643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mon = atoi (tmp) - 1; 6653bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 6, 2); 6663bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 6673bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_mday = atoi (tmp); 6683bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 9, 2); 6693bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 6703bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_hour = atoi (tmp); 6713bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 11, 2); 6723bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 6733bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_min = atoi (tmp); 6743bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij strncpy (tmp, ptpdate + 13, 2); 6753bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tmp[2] = 0; 6763bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij tm.tm_sec = atoi (tmp); 677e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij tm.tm_isdst = -1; 6783bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return mktime (&tm); 6793bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij} 6803bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij 681b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 683eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 684eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t filenamelen; 685eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint8_t capturedatelen; 686eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij char *capture_date; 687eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 6883d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (len < PTP_oi_SequenceNumber) 6893d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return; 6903d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 6913d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner oi->Filename = oi->Keywords = NULL; 6923d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 6933d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner /* FIXME: also handle length with all the strings at the end */ 694eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 695eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 696eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 697eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 6980546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 6990546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* Stupid Samsung Galaxy developers emit a 64bit objectcompressedsize */ 7000546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) { 7010546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner params->ocs64 = 1; 7020546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner data += 4; 7030546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner } 704eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 705eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 706eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 707eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 708eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 709eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 710eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 711eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 712eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 713eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 714eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 7150546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 716aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, len, &filenamelen); 717eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 718eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 719aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner PTP_oi_filenamelen+filenamelen*2+1, len, &capturedatelen); 720eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij /* subset of ISO 8601, without '.s' tenths of second and 721eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij * time zone 722eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij */ 7236db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); 724eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 725eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 7263bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij /* now the modification date ... */ 727eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij capture_date = ptp_unpack_string(params, data, 728eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP_oi_filenamelen+filenamelen*2 729aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner +capturedatelen*2+2, len, &capturedatelen); 7306db174f4d18af574fab991309e11010aa0eb4543Linus Walleij oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); 731eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij free(capture_date); 732eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 733eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 734eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Custom Type Value Assignement (without Length) macro frequently used below */ 735b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define CTVAL(target,func) { \ 736b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(target)) \ 737b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 738b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij target = func(&data[*offset]); \ 739b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(target); \ 740eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 741eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 742b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define RARR(val,member,func) { \ 7439783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij unsigned int n,j; \ 744b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (total - *offset < sizeof(uint32_t)) \ 745b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; \ 746b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij n = dtoh32a (&data[*offset]); \ 747b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += sizeof(uint32_t); \ 748b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij \ 7499783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (n >= UINT_MAX/sizeof(val->a.v[0])) \ 7509783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 0; \ 751aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (n > (total - (*offset))/sizeof(val->a.v[0]))\ 752aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; \ 753b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.count = n; \ 754b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij val->a.v = malloc(sizeof(val->a.v[0])*n); \ 755b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!val->a.v) return 0; \ 756b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (j=0;j<n;j++) \ 757b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(val->a.v[j].member, func); \ 758b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 759eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 7602ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleijstatic inline unsigned int 761b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPV ( 7623d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner PTPParams *params, unsigned char* data, unsigned int *offset, unsigned int total, 763b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTPPropertyValue* value, uint16_t datatype 764b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij) { 765aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (*offset >= total) /* we are at the end or over the end of the buffer */ 766aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 767aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 768eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 769b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 770b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i8,dtoh8a); 771b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 772b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 773b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u8,dtoh8a); 774b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 775b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 776b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i16,dtoh16a); 777b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 778b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 779b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u16,dtoh16a); 780b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 781b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 782b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->i32,dtoh32a); 783b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 784b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij CTVAL(value->u32,dtoh32a); 786b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 787abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 788abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->i64,dtoh64a); 789abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 790abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 791abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij CTVAL(value->u64,dtoh64a); 792abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 793abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij 794037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_UINT128: 795037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 796037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of uint128n");*/ 797037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 798037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij case PTP_DTC_INT128: 799037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij *offset += 16; 800037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij /*fprintf(stderr,"unhandled unpack of int128n");*/ 801037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij break; 802037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 803037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 804037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij 805b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 806b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i8,dtoh8a); 807b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 808b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 809b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u8,dtoh8a); 810b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 811b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 812b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u16,dtoh16a); 813b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 814b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 815b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i16,dtoh16a); 816b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 817b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 818b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,u32,dtoh32a); 819b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 820b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 821b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij RARR(value,i32,dtoh32a); 822b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 823abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 824abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,u64,dtoh64a); 825abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 826abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 827abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij RARR(value,i64,dtoh64a); 828abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 829b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 830b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int arrays are unimplemented also */ 831b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 832b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t len; 833b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: max size */ 834aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 835aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (*offset >= total+1) 836aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 837aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 838aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner value->str = ptp_unpack_string(params,data,*offset,total,&len); 839b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *offset += len*2+1; 840b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!value->str) 841deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 842b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 843eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 844037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij default: 845037a12589156bbcdb5e772b6bab49dee79107f9fLinus Walleij return 0; 846b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 847b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 848eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 849eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 850eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* Device Property pack/unpack */ 851eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DevicePropertyCode 0 852eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_DataType 2 853eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_GetSet 4 854eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_dpd_FactoryDefaultValue 5 855eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 856b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 857b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 858eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 8599783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij unsigned int offset = 0, ret; 860eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 861b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd, 0, sizeof(*dpd)); 862aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (dpdlen <= 5) 863aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 864eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 865eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 866eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 867deddc3490b3084b802737017982285bfa58b382fLinus Walleij dpd->FormFlag=PTP_DPFF_None; 868b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 869b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_dpd_FactoryDefaultValue; 870b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 871b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 872deddc3490b3084b802737017982285bfa58b382fLinus Walleij if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) 873deddc3490b3084b802737017982285bfa58b382fLinus Walleij return 1; 874b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 875b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 876b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 877b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* if offset==0 then Data Type format is not supported by this 878b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij code or the Data Type is a string (with two empty strings as 879b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 880b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij not present. */ 881b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 882b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (offset==PTP_dpd_FactoryDefaultValue) 883b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 884b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 885b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FormFlag=dtoh8a(&data[offset]); 886b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 887eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 888eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (dpd->FormFlag) { 889b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Range: 890b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 891b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 892b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 893b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 894b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 895b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 896eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 897b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DPFF_Enumeration: { 898b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i; 899eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 900b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 901b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 902b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 903b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 904b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 905b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 906b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 907b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 908b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 909b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 910b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 911b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 912b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 913b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 914b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 915b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 916b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 917b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 918b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 919b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 920eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 921b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 922eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 923eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 924b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 925b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 926b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 927b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_devicepropdesc(dpd); 928b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 929eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 930eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 9319783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij/* Device Property pack/unpack */ 9329783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#define PTP_dpd_Sony_DevicePropertyCode 0 9339783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#define PTP_dpd_Sony_DataType 2 9349783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#define PTP_dpd_Sony_GetSet 4 9359783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#define PTP_dpd_Sony_Unknown 5 9369783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#define PTP_dpd_Sony_FactoryDefaultValue 6 9379783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9389783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleijstatic inline int 9399783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleijptp_unpack_Sony_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen, unsigned int *poffset) 9409783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij{ 9419783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij unsigned int ret; 9423d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#if 0 9433d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner unsigned int unk1, unk2; 9443d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#endif 9459783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9469783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij memset (dpd, 0, sizeof(*dpd)); 9479783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_Sony_DevicePropertyCode]); 9489783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->DataType=dtoh16a(&data[PTP_dpd_Sony_DataType]); 9499783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9509783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#if 0 9513d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner /* get set ? */ 9523d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner unk1 = dtoh8a(&data[PTP_dpd_Sony_GetSet]); 9533d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner unk2 = dtoh8a(&data[PTP_dpd_Sony_Unknown]); 9543d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params, "prop 0x%04x, datatype 0x%04x, unk1 %d unk2 %d", dpd->DevicePropertyCode, dpd->DataType, unk1, unk2); 9559783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#endif 9569783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->GetSet=1; 9579783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9589783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->FormFlag=PTP_DPFF_None; 9599783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9609783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij *poffset = PTP_dpd_Sony_FactoryDefaultValue; 9619783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 9629783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ret) goto outofmemory; 9639783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if ((dpd->DataType == PTP_DTC_STR) && (*poffset == dpdlen)) 9649783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 1; 9659783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->CurrentValue, dpd->DataType); 9669783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ret) goto outofmemory; 9679783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9689783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* if offset==0 then Data Type format is not supported by this 9699783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij code or the Data Type is a string (with two empty strings as 9709783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij values). In both cases Form Flag should be set to 0x00 and FORM is 9719783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij not present. */ 9729783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9739783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (*poffset==PTP_dpd_Sony_FactoryDefaultValue) 9749783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 1; 9759783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9769783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->FormFlag=dtoh8a(&data[*poffset]); 9779783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij *poffset+=sizeof(uint8_t); 9789783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9799783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij switch (dpd->FormFlag) { 9809783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij case PTP_DPFF_Range: 9819783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 9829783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ret) goto outofmemory; 9839783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 9849783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ret) goto outofmemory; 9859783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 9869783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ret) goto outofmemory; 9879783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij break; 9889783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij case PTP_DPFF_Enumeration: { 9899783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij int i; 9909783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#define N dpd->FORM.Enum.NumberOfValues 9919783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij N = dtoh16a(&data[*poffset]); 9929783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij *poffset+=sizeof(uint16_t); 9939783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 9949783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!dpd->FORM.Enum.SupportedValue) 9959783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij goto outofmemory; 9969783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 9979783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 9989783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij for (i=0;i<N;i++) { 9999783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 10009783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 10019783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 10029783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij * specifies an enumeration with N in wrong endian 10039783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 10049783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij * the end of the packet. 10059783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij */ 10069783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ret) { 10079783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!i) 10089783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij goto outofmemory; 10099783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->FORM.Enum.NumberOfValues = i; 10109783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij break; 10119783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 10129783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 10139783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 10149783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 10159783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij#undef N 10169783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 1; 10179783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleijoutofmemory: 10189783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ptp_free_devicepropdesc(dpd); 10199783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return 0; 10209783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij} 10219783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 1022d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijstatic inline void 1023d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijduplicate_PropertyValue (const PTPPropertyValue *src, PTPPropertyValue *dst, uint16_t type) { 10249783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (type == PTP_DTC_STR) { 10259783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (src->str) 10269783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dst->str = strdup(src->str); 10279783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij else 10289783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dst->str = NULL; 10299783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return; 10309783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 10319783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 1032d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij if (type & PTP_DTC_ARRAY_MASK) { 10332ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int i; 1034d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 1035d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->a.count = src->a.count; 10369783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dst->a.v = malloc (sizeof(src->a.v[0])*src->a.count); 1037d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij for (i=0;i<src->a.count;i++) 1038d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->a.v[i], &dst->a.v[i], type & ~PTP_DTC_ARRAY_MASK); 1039d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij return; 1040d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij } 1041d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij switch (type & ~PTP_DTC_ARRAY_MASK) { 1042d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT8: dst->i8 = src->i8; break; 1043d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT8: dst->u8 = src->u8; break; 1044d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT16: dst->i16 = src->i16; break; 1045d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT16: dst->u16 = src->u16; break; 1046d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT32: dst->i32 = src->i32; break; 1047d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT32: dst->u32 = src->u32; break; 1048d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT64: dst->u64 = src->u64; break; 1049d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT64: dst->i64 = src->i64; break; 1050d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij#if 0 1051d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_INT128: dst->i128 = src->i128; break; 1052d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DTC_UINT128: dst->u128 = src->u128; break; 1053d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij#endif 1054d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij default: break; 1055d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij } 1056d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij return; 1057d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij} 1058d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 1059d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijstatic inline void 1060d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleijduplicate_DevicePropDesc(const PTPDevicePropDesc *src, PTPDevicePropDesc *dst) { 1061d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij int i; 1062d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 1063d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->DevicePropertyCode = src->DevicePropertyCode; 1064d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->DataType = src->DataType; 1065d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->GetSet = src->GetSet; 1066d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 10679783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij duplicate_PropertyValue (&src->FactoryDefaultValue, &dst->FactoryDefaultValue, src->DataType); 10689783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij duplicate_PropertyValue (&src->CurrentValue, &dst->CurrentValue, src->DataType); 1069d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 1070d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->FormFlag = src->FormFlag; 1071d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij switch (src->FormFlag) { 1072d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DPFF_Range: 1073d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Range.MinimumValue, &dst->FORM.Range.MinimumValue, src->DataType); 1074d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Range.MaximumValue, &dst->FORM.Range.MaximumValue, src->DataType); 1075d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Range.StepSize, &dst->FORM.Range.StepSize, src->DataType); 1076d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij break; 1077d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DPFF_Enumeration: 1078d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->FORM.Enum.NumberOfValues = src->FORM.Enum.NumberOfValues; 1079d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij dst->FORM.Enum.SupportedValue = malloc (sizeof(dst->FORM.Enum.SupportedValue[0])*src->FORM.Enum.NumberOfValues); 1080d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij for (i = 0; i<src->FORM.Enum.NumberOfValues ; i++) 1081d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij duplicate_PropertyValue (&src->FORM.Enum.SupportedValue[i], &dst->FORM.Enum.SupportedValue[i], src->DataType); 1082d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij break; 1083d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij case PTP_DPFF_None: 1084d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij break; 1085d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij } 1086d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij} 1087d9ee8cd37f0704a501b62a185c3305d236c7c8dfLinus Walleij 1088b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_ObjectPropertyCode 0 1089b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_DataType 2 1090b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_GetSet 4 1091b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_opd_FactoryDefaultValue 5 1092eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1093b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline int 1094b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 1095eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 10962ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int offset=0, ret; 1097b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1098b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd, 0, sizeof(*opd)); 1099b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 1100b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 1101b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 1102b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1103b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset = PTP_opd_FactoryDefaultValue; 1104b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 1105b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 1106b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1107b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->GroupCode=dtoh32a(&data[offset]); 1108b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint32_t); 1109b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1110b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FormFlag=dtoh8a(&data[offset]); 1111b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint8_t); 1112b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1113b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij switch (opd->FormFlag) { 1114b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Range: 1115b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 1116b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 1117b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 1118b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 1119b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 1120b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) goto outofmemory; 1121b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1122b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_OPFF_Enumeration: { 11232ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int i; 1124b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define N opd->FORM.Enum.NumberOfValues 1125b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij N = dtoh16a(&data[offset]); 1126b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij offset+=sizeof(uint16_t); 1127b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 1128b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!opd->FORM.Enum.SupportedValue) 1129b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 1130b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1131b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 1132b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<N;i++) { 1133b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 1134b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 1135b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* Slightly different handling here. The HP PhotoSmart 120 1136b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * specifies an enumeration with N in wrong endian 1137b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * 00 01 instead of 01 00, so we count the enum just until the 1138b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij * the end of the packet. 1139b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij */ 1140b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!ret) { 1141b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!i) 1142b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij goto outofmemory; 1143b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij opd->FORM.Enum.NumberOfValues = i; 1144b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1145b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1146b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1147b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#undef N 1148b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1149eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 1150b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 1; 1151b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijoutofmemory: 1152b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_free_objectpropdesc(opd); 1153b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return 0; 1154eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1155eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1156eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1157b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 1158b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 1159eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1160b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char* dpv=NULL; 1161eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij uint32_t size=0; 11622ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int i; 1163eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1164eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij switch (datatype) { 1165b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT8: 1166b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int8_t); 1167b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1168b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->i8); 1169b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1170b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT8: 1171b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint8_t); 1172b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1173b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod8a(dpv,value->u8); 1174b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1175b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT16: 1176b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int16_t); 1177b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1178b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->i16); 1179b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1180b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT16: 1181b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint16_t); 1182b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1183b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(dpv,value->u16); 1184b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1185b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_INT32: 1186b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(int32_t); 1187b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1188b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->i32); 1189b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1190b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_UINT32: 1191b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t); 1192b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1193b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->u32); 1194b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1195abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_INT64: 1196abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(int64_t); 1197abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1198abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->i64); 1199abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1200abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_UINT64: 1201abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint64_t); 1202abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1203abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod64a(dpv,value->u64); 1204abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1205b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT8: 1206b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 1207b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1208b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1209b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1210cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 1211b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1212b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT8: 1213b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 1214b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1215b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1216b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1217cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 1218b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1219b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT16: 1220b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 1221b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1222b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1223b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1224cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 1225b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1226b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT16: 1227b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 1228b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1229b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1230b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1231cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 1232b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1233b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AUINT32: 1234b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 1235b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1236b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1237b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1238cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 1239b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1240b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_AINT32: 1241b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 1242b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij dpv=malloc(size); 1243b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(dpv,value->a.count); 1244b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<value->a.count;i++) 1245cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 1246b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij break; 1247abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AUINT64: 1248abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 1249abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1250abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 1251abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 1252cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 1253abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1254abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij case PTP_DTC_AINT64: 1255abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 1256abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij dpv=malloc(size); 1257abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij htod32a(dpv,value->a.count); 1258abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij for (i=0;i<value->a.count;i++) 1259cc2659036a503fce161cb77d9b0af17a52d7437bRichard Low htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 1260abf5475a00d858a282595b7fe8c8ec8c5d629569Linus Walleij break; 1261b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij /* XXX: other int types are unimplemented */ 1262b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij case PTP_DTC_STR: { 1263735f41692934a716158cf051d76e988febeca7eeLinus Walleij dpv=ptp_get_packed_stringcopy(params, value->str, &size); 1264eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij break; 1265b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 1266eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij } 1267eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij *dpvptr=dpv; 1268eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return size; 126999310d4445697da39f22dff35457c75e35e97171Linus Walleij} 127099310d4445697da39f22dff35457c75e35e97171Linus Walleij 127199310d4445697da39f22dff35457c75e35e97171Linus Walleij#define MAX_MTP_PROPS 127 127299310d4445697da39f22dff35457c75e35e97171Linus Walleijstatic inline uint32_t 12731e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_pack_OPL (PTPParams *params, MTPProperties *props, int nrofprops, unsigned char** opldataptr) 127499310d4445697da39f22dff35457c75e35e97171Linus Walleij{ 127599310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char* opldata; 12761e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *propitr; 127799310d4445697da39f22dff35457c75e35e97171Linus Walleij unsigned char *packedprops[MAX_MTP_PROPS]; 127899310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t packedpropslens[MAX_MTP_PROPS]; 127939b9374f23451201dece736db13f0f648584dc32Linus Walleij uint32_t packedobjecthandles[MAX_MTP_PROPS]; 128099310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropsids[MAX_MTP_PROPS]; 128199310d4445697da39f22dff35457c75e35e97171Linus Walleij uint16_t packedpropstypes[MAX_MTP_PROPS]; 128299310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t totalsize = 0; 128399310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t bufp = 0; 128499310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t noitems = 0; 128599310d4445697da39f22dff35457c75e35e97171Linus Walleij uint32_t i; 128699310d4445697da39f22dff35457c75e35e97171Linus Walleij 128799310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 12881e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr = props; 12891e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij while (nrofprops-- && noitems < MAX_MTP_PROPS) { 12906c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low /* Object Handle */ 129139b9374f23451201dece736db13f0f648584dc32Linus Walleij packedobjecthandles[noitems]=propitr->ObjectHandle; 129299310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint32_t); /* Object ID */ 129399310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Metadata type */ 129499310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropsids[noitems]=propitr->property; 129599310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 129699310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Data type */ 129799310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropstypes[noitems]= propitr->datatype; 129899310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += sizeof(uint16_t); 129999310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Add each property to be sent. */ 130099310d4445697da39f22dff35457c75e35e97171Linus Walleij packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 130199310d4445697da39f22dff35457c75e35e97171Linus Walleij totalsize += packedpropslens[noitems]; 130299310d4445697da39f22dff35457c75e35e97171Linus Walleij noitems ++; 13031e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij propitr ++; 130499310d4445697da39f22dff35457c75e35e97171Linus Walleij } 130599310d4445697da39f22dff35457c75e35e97171Linus Walleij 130699310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Allocate memory for the packed property list */ 130799310d4445697da39f22dff35457c75e35e97171Linus Walleij opldata = malloc(totalsize); 130899310d4445697da39f22dff35457c75e35e97171Linus Walleij 130999310d4445697da39f22dff35457c75e35e97171Linus Walleij htod32a(&opldata[bufp],noitems); 131099310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += 4; 131199310d4445697da39f22dff35457c75e35e97171Linus Walleij 131299310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Copy into a nice packed list */ 131399310d4445697da39f22dff35457c75e35e97171Linus Walleij for (i = 0; i < noitems; i++) { 131499310d4445697da39f22dff35457c75e35e97171Linus Walleij /* Object ID */ 13156c0a6ce803cf79802b1c48339adf0964db30ec83Richard Low htod32a(&opldata[bufp],packedobjecthandles[i]); 131699310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint32_t); 131799310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropsids[i]); 131899310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 131999310d4445697da39f22dff35457c75e35e97171Linus Walleij htod16a(&opldata[bufp],packedpropstypes[i]); 132099310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += sizeof(uint16_t); 132199310d4445697da39f22dff35457c75e35e97171Linus Walleij /* The copy the actual property */ 132299310d4445697da39f22dff35457c75e35e97171Linus Walleij memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 132399310d4445697da39f22dff35457c75e35e97171Linus Walleij bufp += packedpropslens[i]; 132499310d4445697da39f22dff35457c75e35e97171Linus Walleij free(packedprops[i]); 132599310d4445697da39f22dff35457c75e35e97171Linus Walleij } 132699310d4445697da39f22dff35457c75e35e97171Linus Walleij *opldataptr = opldata; 132799310d4445697da39f22dff35457c75e35e97171Linus Walleij return totalsize; 1328eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1329eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 13301e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijstatic int 13311e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij_compare_func(const void* x, const void *y) { 13321e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *px = x; 13331e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij const MTPProperties *py = y; 13341e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 13351e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij return px->ObjectHandle - py->ObjectHandle; 13361e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij} 13371e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij 13388d82d2f4b0794e41ec26289045867eebb3496b8cRichard Lowstatic inline int 13391e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleijptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) 13408d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low{ 1341277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij uint32_t prop_count = dtoh32a(data); 13421e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij MTPProperties *props = NULL; 13432ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int offset = 0, i; 1344277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1345aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner *pprops = NULL; 1346aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (prop_count == 0) 1347aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return 0; 1348aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (prop_count >= INT_MAX/sizeof(MTPProperties)) { 1349aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params ,"prop_count %d is too large", prop_count); 1350277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return 0; 1351277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 1352d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); 1353277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 13543bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij len -= sizeof(uint32_t); 13551e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props = malloc(prop_count * sizeof(MTPProperties)); 13561e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij if (!props) return 0; 1357277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij for (i = 0; i < prop_count; i++) { 13583bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij if (len <= 0) { 1359d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); 1360aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL"); 13613bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i); 1362d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij qsort (props, i, sizeof(MTPProperties),_compare_func); 1363d49955b02710fd4bb1eda73b8bd6abb3f17f7c15Linus Walleij *pprops = props; 13643bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij return i; 13653bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij } 13661e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].ObjectHandle = dtoh32a(data); 1367277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint32_t); 1368277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint32_t); 1369277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 13701e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].property = dtoh16a(data); 1371277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1372277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1373277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 13741e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij props[i].datatype = dtoh16a(data); 1375277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += sizeof(uint16_t); 1376277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= sizeof(uint16_t); 1377277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij 1378277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij offset = 0; 1379aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (!ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype)) { 1380aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params ,"unpacking DPV of property %d encountered insufficient buffer. attack?", i); 1381aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner qsort (props, i, sizeof(MTPProperties),_compare_func); 1382aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner *pprops = props; 1383aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return i; 1384aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1385277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij data += offset; 1386277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij len -= offset; 1387277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij } 13881e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij qsort (props, prop_count, sizeof(MTPProperties),_compare_func); 13891e9a033f4d2d485a34954eab0858d368c0b30fceLinus Walleij *pprops = props; 1390277cd539ff4c4fdf591d92c1d0cd9c2e26eaaee0Linus Walleij return prop_count; 13918d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low} 13928d82d2f4b0794e41ec26289045867eebb3496b8cRichard Low 1393eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1394eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP USB Event container unpack 1395eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1396eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1397eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1398eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Length 0 1399eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Type 4 1400eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Code 6 1401eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_TransId 8 1402eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param1 12 1403eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param2 16 1404eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_ec_Param3 20 1405eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1406b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 14077e75653e64021908ca66b155eeb950d8304c87d8Linus Walleijptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len) 1408eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 14099783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij unsigned int length; 14107e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij int type; 14117e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 1412eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1413eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 14147e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(ec,0,sizeof(*ec)); 14159783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 14167e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij length=dtoh32a(&data[PTP_ec_Length]); 14179783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (length > len) { 14189783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ptp_debug (params, "length %d in container, but data only %d bytes?!", length, len); 14199783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return; 14209783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 14217e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij type = dtoh16a(&data[PTP_ec_Type]); 1422b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 14237e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Code=dtoh16a(&data[PTP_ec_Code]); 14247e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); 14257e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij 14267e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (type!=PTP_USB_CONTAINER_EVENT) { 14277e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); 14287e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij return; 14297e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 14307e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param1+4)) { 14317e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param1=dtoh32a(&data[PTP_ec_Param1]); 14327e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=1; 14337e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 14347e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param2+4)) { 14357e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param2=dtoh32a(&data[PTP_ec_Param2]); 14367e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=2; 14377e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 14387e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (length>=(PTP_ec_Param3+4)) { 14397e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Param3=dtoh32a(&data[PTP_ec_Param3]); 14407e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ec->Nparam=3; 14417e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 1442eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 1443eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1444eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij/* 1445eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij PTP Canon Folder Entry unpack 1446eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij Copyright (c) 2003 Nikolai Kopanygin 1447eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij*/ 1448eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectHandle 0 1449eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectFormatCode 4 1450eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Flags 6 1451eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_ObjectSize 7 1452eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Time 11 1453eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij#define PTP_cfe_Filename 15 1454eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 1455b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 1456b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1457eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij{ 1458eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij int i; 1459eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij if (data==NULL) 1460eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij return; 1461eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1462eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1463eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1464b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1465eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1466eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1467b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1468b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 1469b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 147096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij/* 147196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij PTP Canon EOS Folder Entry unpack 147296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0: 00 00 08 a0 objectid 147396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij4: 01 00 02 00 storageid 147496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij8: 01 30 00 00 ofc 147596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij12: 01 00 147696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij14: 00 00 147796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij16: 11 00 00 00 147896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij20: 00 00 00 00 147996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij24: 00 00 00 80 148096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij28: 00 00 08 a0 148196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij32: 4d 49 53 43-00 00 00 00 00 00 00 00 name 148296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij00 00 00 00 148396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij84 bc 74 46 objectime 148496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 148596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 148696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij(normal PTP GetObjectInfo) 148796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus WalleijObjectInfo for 'IMG_0199.JPG': 148896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij Object ID: 0x92740c72 148996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij StorageID: 0x00020001 149096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ObjectFormat: 0x3801 149196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ProtectionStatus: 0x0000 149296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ObjectCompressedSize: 2217241 149396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbFormat: 0x3808 149496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbCompressedSize: 5122 149596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbPixWidth: 160 149696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ThumbPixHeight: 120 149796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImagePixWidth: 4000 149896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImagePixHeight: 3000 149996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ImageBitDepth: 24 150096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ParentObject: 0x92740000 150196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij AssociationType: 0x0000 150296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij AssociationDesc: 0x00000000 150396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij SequenceNumber: 0x00000000 150496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij ModificationDate: 0x4d985ff0 150596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij CaptureDate: 0x4d985ff0 150696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 150796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0010 38 00 00 00 Size of this entry 150896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0014 72 0c 74 92 OID 150996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0018 01 00 02 00 StorageID 151096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij001c 01 38 00 00 OFC 15113d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner0020 00 00 00 00 ?? 15123d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner0024 21 00 00 00 flags (4 bytes? 1 byte?) 151396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0028 19 d5 21 00 Size 151496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij002c 00 00 74 92 ? 151596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0030 70 0c 74 92 OID 151696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0034 49 4d 47 5f-30 31 39 39 2e 4a 50 47 IMG_0199.JPG 151796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0040 00 00 00 00 151896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij0044 10 7c 98 4d Time 151996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 152096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 152196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij*/ 152296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectHandle 0 152396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_StorageID 4 152496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectFormatCode 8 15253d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#define PTP_cefe_Flags 16 152696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_ObjectSize 20 152796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Filename 32 152896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij#define PTP_cefe_Time 48 152996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 153096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleijstatic inline void 153196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleijptp_unpack_Canon_EOS_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 153296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij{ 153396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij int i; 153496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 153596aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectHandle=dtoh32a(&data[PTP_cefe_ObjectHandle]); 153696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectFormatCode=dtoh16a(&data[PTP_cefe_ObjectFormatCode]); 153796aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Flags=dtoh8a(&data[PTP_cefe_Flags]); 153896aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cefe_ObjectSize]); 153996aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Time=(time_t)dtoh32a(&data[PTP_cefe_Time]); 154096aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 154196aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij fe->Filename[i]=(char)data[PTP_cefe_Filename+i]; 154296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij} 154396aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 154496aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij 15451a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint16_t 15461a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data ) 15471a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 15481a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 15490546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner EOS ImageFormat entries (of at least the 5DM2 and the 400D) look like this: 15501a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: number of entries / generated files (1 or 2) 15511a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: size of this entry in bytes (most likely allways 0x10) 15521a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image type (1 == JPG, 6 == RAW) 15530546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32: image size (0 == Large, 1 == Medium, 2 == Small, 0xe == S1, 0xf == S2, 0x10 == S3) 15541a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW) 15550546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner If the number of entries is 2 the last 4 uint32 repeat. 15561a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15571a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij example: 15581a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 0: 0x 1 15591a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1: 0x 10 15601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 2: 0x 6 15611a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 3: 0x 1 15621a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 4: 0x 4 15631a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15640546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner The idea is to simply 'condense' these values to just one uint16 to be able to conveniently 15651a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij use the available enumeration facilities (look-up table). The image size and compression 15661a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij values fully describe the image format. Hence we generate a uint16 with the four nibles set 15671a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression. 15681a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij The above example would result in the value 0x1400. 15690546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 15700546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner The EOS 5D Mark III (and possibly other high-end EOS as well) added the extra fancy S1, S2 15710546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner and S3 JPEG options. S1 replaces the old Small. -1 the S1/S2/S3 to prevent the 0x10 overflow. 15721a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij */ 15731a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15741a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij const unsigned char* d = *data; 15751a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = dtoh32a( d ); 15761a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t l, s1, c1, s2 = 0, c2 = 0; 15771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n != 1 && n !=2) { 15791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n); 15801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 15811a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 15821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 15841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 15851a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 15861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 15871a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 15881a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 15901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s1 = dtoh32a( d+=4 ); 15911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c1 = dtoh32a( d+=4 ); 15921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 15931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n == 2) { 15941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij l = dtoh32a( d+=4 ); 15951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (l != 0x10) { 15961a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 15971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return 0; 15981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 15991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij d+=4; /* skip type */ 16001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij s2 = dtoh32a( d+=4 ); 16011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij c2 = dtoh32a( d+=4 ); 16021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 16031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij *data = (unsigned char*) d+4; 16051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16060546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* deal with S1/S2/S3 JPEG sizes, see above. */ 16070546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if( s1 >= 0xe ) 16080546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner s1--; 16090546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if( s2 >= 0xe ) 16100546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner s2--; 16110546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 16121a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0); 16131a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 16141a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16151a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijstatic inline uint32_t 16161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleijptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value) 16171a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij{ 16181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t n = (value & 0xFF) ? 2 : 1; 16191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij uint32_t s = 4 + 0x10 * n; 16201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16211a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if( !data ) 16221a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 16231a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16240546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner#define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X) 16250546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 16261a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=0, n); 16271a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 16281a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1); 16290546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF)); 16301a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 8) & 0xF); 16311a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16321a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (n==2) { 16331a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, 0x10); 16341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1); 16350546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF)); 16361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij htod32a(data+=4, (value >> 0) & 0xF); 16371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 16381a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 16390546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner#undef PACK_5DM3_SMALL_JPEG_SIZE 16400546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 16410546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return s; 16420546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner} 16430546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 16443d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner/* 00: 32 bit size 16453d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 04: 16 bit subsize 16463d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 08: 16 bit version (?) 16473d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 0c: 16 bit focus_points_in_struct 16483d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 10: 16 bit focus_points_in_use 16493d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 14: variable arrays: 16503d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit sizex, 16 bit sizey 16513d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit othersizex, 16 bit othersizey 16523d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit array height[focus_points_in_struct] 16533d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit array width[focus_points_in_struct] 16543d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit array offsetheight[focus_points_in_struct] middle is 0 16553d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit array offsetwidth[focus_points_in_struct] middle is ? 16563d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * bitfield of selected focus points, starting with 0 [size focus_points_in_struct in bits] 16573d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * unknown stuff , likely which are active 16583d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16 bit 0xffff 16593d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * 16603d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner * size=NxN,size2=NxN,points={NxNxNxN,NxNxNxN,...},selected={0,1,2} 16613d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner */ 16623d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissnerstatic inline char* 1663aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissnerptp_unpack_EOS_FocusInfoEx (PTPParams* params, unsigned char** data, uint32_t datasize ) 16643d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner{ 16653d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t size = dtoh32a( *data ); 16663d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t halfsize = dtoh16a( (*data) + 4); 16673d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t version = dtoh16a( (*data) + 6); 16683d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t focus_points_in_struct = dtoh16a( (*data) + 8); 16693d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t focus_points_in_use = dtoh16a( (*data) + 10); 16703d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t sizeX = dtoh16a( (*data) + 12); 16713d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t sizeY = dtoh16a( (*data) + 14); 16723d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t size2X = dtoh16a( (*data) + 16); 16733d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t size2Y = dtoh16a( (*data) + 18); 16743d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t i; 16753d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner uint32_t maxlen; 16763d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner char *str, *p; 16773d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 1678aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((size >= datasize) || (size < 20)) 1679aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("bad size 1"); 1680aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner /* every focuspoint gets 4 (16 bit number possible "-" sign and a x) and a ,*/ 16813d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner /* inital things around lets say 100 chars at most. 1682aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner * FIXME: check selected when we decode it 1683aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner */ 1684aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < focus_points_in_struct*8) { 1685aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_error(params, "focus_points_in_struct %d is too large vs size %d", focus_points_in_struct, size); 1686aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("bad size 2"); 1687aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1688aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (focus_points_in_use > focus_points_in_struct) { 1689aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_error(params, "focus_points_in_use %d is larger than focus_points_in_struct %d", focus_points_in_use, focus_points_in_struct); 1690aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("bad size 3"); 1691aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1692aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 1693aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner maxlen = focus_points_in_use*32 + 100 + (size - focus_points_in_struct*8)*2; 16943d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (halfsize != size-4) { 16953d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_error(params, "halfsize %d is not expected %d", halfsize, size-4); 1696aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("bad size 4"); 16973d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 16983d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (20 + focus_points_in_struct*8 + (focus_points_in_struct+7)/8 > size) { 16993d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_error(params, "size %d is too large for fp in struct %d", focus_points_in_struct*8 + 20 + (focus_points_in_struct+7)/8, size); 1700aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("bad size 5"); 17013d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 17023d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#if 0 17033d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug(params,"d1d3 content:"); 17043d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner for (i=0;i<size;i+=2) 17053d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug(params,"%d: %02x %02x", i, (*data)[i], (*data)[i+1]); 17063d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner#endif 1707aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug(params,"d1d3 version %d", version); 1708aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug(params,"d1d3 size %d", size); 17093d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug(params,"d1d3 focus points in struct %d, in use %d", focus_points_in_struct, focus_points_in_use); 17103d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17113d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner str = (char*)malloc( maxlen ); 17123d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (!str) 17133d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return NULL; 17143d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p = str; 17153d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17163d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p += sprintf(p,"eosversion=%d,size=%dx%d,size2=%dx%d,points={", version, sizeX, sizeY, size2X, size2Y); 17173d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner for (i=0;i<focus_points_in_use;i++) { 17183d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner int16_t x = dtoh16a((*data) + focus_points_in_struct*4 + 20 + 2*i); 17193d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner int16_t y = dtoh16a((*data) + focus_points_in_struct*6 + 20 + 2*i); 17203d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner int16_t w = dtoh16a((*data) + focus_points_in_struct*2 + 20 + 2*i); 17213d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner int16_t h = dtoh16a((*data) + focus_points_in_struct*0 + 20 + 2*i); 17223d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17233d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p += sprintf(p,"{%d,%d,%d,%d}",x,y,w,h); 17243d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17253d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (i<focus_points_in_use-1) 17263d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p += sprintf(p,","); 17273d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 17283d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p += sprintf(p,"},select={"); 17293d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner for (i=0;i<focus_points_in_use;i++) { 1730aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((1<<(i%8)) & ((*data)[focus_points_in_struct*8+20+i/8])) 17313d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p+=sprintf(p,"%d,", i); 17323d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 17333d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17343d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p += sprintf(p,"},unknown={"); 17353d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner for (i=focus_points_in_struct*8+(focus_points_in_struct+7)/8+20;i<size;i++) { 1736aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((p-str) > maxlen - 4) 1737aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 17383d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p+=sprintf(p,"%02x", (*data)[i]); 17393d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner } 17403d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner p += sprintf(p,"}"); 17413d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return str; 17423d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner} 17433d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17443d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 17450546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerstatic inline char* 17460546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerptp_unpack_EOS_CustomFuncEx (PTPParams* params, unsigned char** data ) 17470546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner{ 17480546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t s = dtoh32a( *data ); 17490546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t n = s/4, i; 1750aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner char *str, *p; 1751aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 1752aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (s > 1024) { 1753aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "customfuncex data is larger than 1k / %d... unexpected?", s); 1754aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("bad length"); 1755aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1756aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner str = (char*)malloc( s*2+s/4+1 ); /* n is size in uint32, maximum %x len is 8 chars and \0*/ 17570546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (!str) 1758aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner return strdup("malloc failed"); 17590546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 1760aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner p = str; 17610546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner for (i=0; i < n; ++i) 17620546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner p += sprintf(p, "%x,", dtoh32a( *data + 4*i )); 17630546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return str; 17640546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner} 17650546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 17660546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerstatic inline uint32_t 17670546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissnerptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str) 17680546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner{ 17690546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t s = strtoul(str, NULL, 16); 17700546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner uint32_t n = s/4, i, v; 17710546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 17720546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner if (!data) 17730546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner return s; 17740546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 17750546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner for (i=0; i<n; i++) 17760546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner { 17770546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner v = strtoul(str, &str, 16); 1778a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij str++; /* skip the ',' delimiter */ 17790546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner htod32a(data + i*4, v); 17800546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner } 17810546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner 17821a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij return s; 17831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij} 17841a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 1785b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij/* 1786f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTP EOS Changes Entry unpack 1787f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij*/ 1788f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Size 0 1789f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Type 4 1790f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1791f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Subtype 8 /* only for properties */ 1792f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 1793f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 1794f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 1795f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij#define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 1796f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1797d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_RequestObjectTransfer */ 1798d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_ObjectID 8 1799d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_OFC 0x0c 1800d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Size 0x14 1801d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OI_Name 0x1c 1802d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij 1803d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij/* for PTP_EC_CANON_EOS_ObjectAddedEx */ 1804d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_ObjectID 8 1805d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_StorageID 0x0c 1806d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_OFC 0x10 1807d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Size 0x1c 1808d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Parent 0x20 1809d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#define PTP_ece_OA_Name 0x28 1810f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1811aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_ObjectID 8 /* OK */ 1812aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_StorageID 0x0c /* OK */ 1813aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_OFC 0x10 /* OK */ 1814aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_Size 0x1c /* OK, might be 64 bit now? */ 1815aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_Parent 0x24 1816aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_2ndOID 0x28 1817aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece2_OA_Name 0x2c /* OK */ 1818aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 1819aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner/* for PTP_EC_CANON_EOS_ObjectAddedNew */ 1820aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece_OAN_OFC 0x0c 1821aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner#define PTP_ece_OAN_Size 0x14 1822aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 18233d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissnerstatic PTPDevicePropDesc* 18243d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner_lookup_or_allocate_canon_prop(PTPParams *params, uint16_t proptype) 18253d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner{ 18263d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner unsigned int j; 18273d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 18283d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner for (j=0;j<params->nrofcanon_props;j++) 18293d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (params->canon_props[j].proptype == proptype) 18303d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner break; 18313d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (j<params->nrofcanon_props) 18323d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return ¶ms->canon_props[j].dpd; 18333d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 18343d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner if (j) 18353d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 18363d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner else 18373d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props = malloc(sizeof(params->canon_props[0])); 18383d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props[j].proptype = proptype; 18393d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props[j].size = 0; 18403d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props[j].data = NULL; 18413d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 18423d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props[j].dpd.GetSet = 1; 18433d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 18443d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner params->nrofcanon_props = j+1; 18453d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner return ¶ms->canon_props[j].dpd; 18463d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner} 18473d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 18483d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner 1849f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleijstatic inline int 18509783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleijptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **pce) 1851f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij{ 1852f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij int i = 0, entries = 0; 1853f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij unsigned char *curdata = data; 18549783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij PTPCanon_changes_entry *ce; 1855f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1856f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (data==NULL) 1857f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij return 0; 1858aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner while (curdata - data + 8 < datasize) { 1859f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1860f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1861f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1862aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size > datasize) { 1863aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is larger than datasize %d", size, datasize); 1864aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1865aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1866aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < 8) { 1867aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than 8.", size); 1868aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1869aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1870f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ((size == 8) && (type == 0)) 1871f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1872aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((curdata - data) + size >= datasize) { 1873aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "canon eos event decoder ran over supplied data, skipping entries"); 1874aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1875aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 18769783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (type == PTP_EC_CANON_EOS_OLCInfoChanged) { 18779783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij unsigned int j; 18789783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 1879aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner entries++; 1880aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size >= 12+2) { 1881aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner for (j=0;j<31;j++) 1882aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (dtoh16a(curdata+12) & (1<<j)) 1883aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner entries++; 1884aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 18859783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 18869783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata += size; 1887f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij entries++; 1888f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 18899783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1)); 18909783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!ce) return 0; 1891f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1892f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata = data; 1893aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner while (curdata - data + 8 < datasize) { 1894f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1895f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1896f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1897aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size > datasize) { 1898aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is larger than datasize %d", size, datasize); 1899aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1900aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1901aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < 8) { 1902aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than 8", size); 1903aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1904aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1905aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 1906aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((size == 8) && (type == 0)) 1907aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1908aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 1909aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((curdata - data) + size >= datasize) { 1910aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "canon eos event decoder ran over supplied data, skipping entries"); 1911aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1912aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1913aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 19149783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 19159783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = NULL; 1916f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (type) { 1917aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner case PTP_EC_CANON_EOS_ObjectAddedEx: 1918aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < PTP_ece_OA_Name+1) { 1919aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_OA_Name+1); 1920aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1921aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 19229783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 19239783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OA_ObjectID]); 1924aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece_OA_StorageID]); 19259783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece_OA_Parent]); 19269783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OA_OFC]); 19279783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]); 1928aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OA_Name])); 1929aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 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); 1930aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1931aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner case PTP_EC_CANON_EOS_ObjectAddedUnknown: /* FIXME: review if the data used is correct */ 1932aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < PTP_ece2_OA_Name+1) { 1933aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than %d", size, PTP_ece2_OA_Name+1); 1934aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1935aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1936aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1937aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oid = dtoh32a(&curdata[PTP_ece2_OA_ObjectID]); 1938aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece2_OA_StorageID]); 1939aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece2_OA_Parent]); 1940aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece2_OA_OFC]); 1941aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece2_OA_Size]); /* FIXME: might be 64bit now */ 1942aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece2_OA_Name])); 19439783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus 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); 1944d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 1945aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner case PTP_EC_CANON_EOS_RequestObjectTransfer: 1946aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner case PTP_EC_CANON_EOS_RequestObjectTransferNew: /* FIXME: confirm */ 1947aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < PTP_ece_OI_Name+1) { 1948aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_OI_Name+1); 1949aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1950aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 19519783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER; 19529783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 1953aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.StorageID = 0; /* use as marker */ 19549783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 19559783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oi.ParentObject = 0; /* check, but use as marker */ 19569783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 1957aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 19589783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 19599783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ptp_debug (params, "event %d: request object transfer oid %08lx, ofc %04x, size %d, filename %p", i, ce[i].u.object.oid, ce[i].u.object.oi.ObjectFormat, ce[i].u.object.oi.ObjectCompressedSize, ce[i].u.object.oi.Filename); 1960f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1961aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner case PTP_EC_CANON_EOS_AvailListChanged: { /* property desc */ 1962f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1963f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 1964f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 1965e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Desc_Data]; 19662ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int j; 1967f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 1968f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 1969aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < PTP_ece_Prop_Desc_Data) { 1970aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_Prop_Desc_Data); 1971aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 1972aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 1973aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner 19747e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype); 1975f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 1976f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 1977f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1978f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j==params->nrofcanon_props) { 19793bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: propdesc %x, default value not found.", i, proptype); 1980f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1981f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 1982f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 19837e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* 1 - uint16 ? 19847e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 3 - uint16 19857e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij * 7 - string? 19867e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij */ 1987f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (propxtype != 3) { 1988aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "event %d: propxtype is %x for %04x, unhandled, size %d", i, propxtype, proptype, size); 19893bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++) 1990e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 1991f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 1992f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 19931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if (! propxcnt) 19941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 19959783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (propxcnt >= 2<<16) /* buggy or exploit */ 19969783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij break; 19971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 19981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.", 19991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij i, propxtype, proptype, dpd->DataType, propxcnt); 20001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 20011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.NumberOfValues = propxcnt; 20023d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->FORM.Enum.SupportedValue); 20031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 20041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 20051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 20061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 20071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 20081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 20091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 20101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* special handling of ImageFormat properties */ 2011f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<propxcnt;j++) { 20121a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->FORM.Enum.SupportedValue[j].u16 = 20139783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ptp_unpack_EOS_ImageFormat( params, &xdata ); 20141a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16); 20151a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 20161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 20171a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 20181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* 'normal' enumerated types */ 20191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (dpd->DataType) { 20201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX( TYPE, CONV )\ 2021aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (sizeof(dpd->FORM.Enum.SupportedValue[j].TYPE)*propxcnt + PTP_ece_Prop_Desc_Data > size) { \ 2022aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d does not match needed %d", sizeof(dpd->FORM.Enum.SupportedValue[j].TYPE)*propxcnt + PTP_ece_Prop_Desc_Data, size); \ 2023aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; \ 2024aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } \ 2025aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner for (j=0;j<propxcnt;j++) { \ 2026aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(xdata); \ 2027e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(xdata)); \ 2028e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; /* might only be for propxtype 3 */ \ 20291a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } \ 20301a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 20311a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 20321a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_INT16: XX( i16, dtoh16a ); 20331a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT32: XX( u32, dtoh32a ); 20341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT16: XX( u16, dtoh16a ); 20351a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DTC_UINT8: XX( u8, dtoh8a ); 20361a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 20371a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij default: 2038aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner free (dpd->FORM.Enum.SupportedValue); 2039aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner dpd->FORM.Enum.SupportedValue = NULL; 2040aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner dpd->FORM.Enum.NumberOfValues = 0; 2041aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params ,"event %d: data type 0x%04x of %x unhandled, size %d, raw values:", i, dpd->DataType, proptype, dtoh32a(xdata), size); 2042e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, xdata+=4) /* 4 is good for propxtype 3 */ 2043e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %3d: 0x%8x", j, dtoh32a(xdata)); 20441a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 2045f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2046f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2047f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2048f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 20497e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_EC_CANON_EOS_PropValueChanged: 2050f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (size >= 0xc) { /* property info */ 20512ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int j; 2052f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 2053e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij unsigned char *xdata = &curdata[PTP_ece_Prop_Val_Data]; 2054f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij PTPDevicePropDesc *dpd; 2055f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 2056aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < PTP_ece_Prop_Val_Data) { 2057aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_Prop_Val_Data); 2058aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 2059aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 20601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: EOS prop %04x info record, datasize is %d", i, proptype, size-PTP_ece_Prop_Val_Data); 2061f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij for (j=0;j<params->nrofcanon_props;j++) 2062f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (params->canon_props[j].proptype == proptype) 2063f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2064f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j<params->nrofcanon_props) { 2065f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if ( (params->canon_props[j].size != size) || 2066e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij (memcmp(params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data))) { 2067f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 2068aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner params->canon_props[j].size = size; 2069e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy (params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data); 2070f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2071f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } else { 2072f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij if (j) 2073f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 2074f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij else 2075f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props = malloc(sizeof(params->canon_props[0])); 2076f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].proptype = proptype; 2077f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].size = size; 2078f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 2079e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij memcpy(params->canon_props[j].data, xdata, size-PTP_ece_Prop_Val_Data); 2080f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 2081f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.GetSet = 1; 2082f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 2083f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij params->nrofcanon_props = j+1; 2084f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2085f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd = ¶ms->canon_props[j].dpd; 20861a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 20879783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 20889783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.propid = proptype; 2089d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 20901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* fix GetSet value */ 20911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij switch (proptype) { 20921a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#define XX(x) case PTP_DPC_CANON_##x: 20931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusMode) 20941a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryPower) 20951a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatterySelect) 20961a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ModelID) 20971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_PTPExtensionVersion) 20981a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DPOFVersion) 20991a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AvailableShots) 21001a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentStorage) 21011a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CurrentFolder) 21021a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenu) 21031a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_MyMenuList) 21041a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_HDDirectoryStructure) 21051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_BatteryInfo) 21061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_AdapterInfo) 21071a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensStatus) 21081a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_CardExtension) 21091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_TempStatus) 21101a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_ShutterCounter) 21111a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_SerialNumber) 21121a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfFieldPreview) 21131a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EVFRecordStatus) 21141a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LvAfSystem) 21151a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_FocusInfoEx) 21161a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_DepthOfField) 21171a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_Brightness) 21181a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_EFComp) 21191a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensName) 21201a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij XX(EOS_LensID) 21211a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#undef XX 21221a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->GetSet = PTP_DPGS_Get; 21231a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 21241a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij } 21251a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 21261a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* set DataType */ 2127f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (proptype) { 2128ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DPC_CANON_EOS_CameraTime: 21299783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij case PTP_DPC_CANON_EOS_UTCTime: 21309783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij case PTP_DPC_CANON_EOS_Summertime: /* basical the DST flag */ 2131d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_AvailableShots: 2132d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CaptureDestination: 2133d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXA: 2134d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceXB: 2135d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentStorage: 2136d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_CurrentFolder: 2137d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ShutterCounter: 2138d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ModelID: 2139d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LensID: 2140d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_StroboFiring: 21413d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DPC_CANON_EOS_AFSelectFocusArea: 21423d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DPC_CANON_EOS_ContinousAFMode: 2143aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner case PTP_DPC_CANON_EOS_MirrorUpSetting: 2144ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij dpd->DataType = PTP_DTC_UINT32; 2145ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 21460d762ccc39331608119dd0267021b165e22de499Linus Walleij /* enumeration for AEM is never provided, but is available to set */ 21470d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_AutoExposureMode: 21480d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT16; 21490d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FormFlag = PTP_DPFF_Enumeration; 21500d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->FORM.Enum.NumberOfValues = 0; 21510d762ccc39331608119dd0267021b165e22de499Linus Walleij break; 2152f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Aperture: 2153f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ShutterSpeed: 2154f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_ISOSpeed: 21557e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_FocusMode: 21567e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorSpace: 21577e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_BatteryPower: 2158e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BatterySelect: 2159d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_PTPExtensionVersion: 21601a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_DriveMode: 21611a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_AEB: 2162e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_BracketMode: 2163e29ca68e54b8dd04e54499d6b5fa8668770a20cfLinus Walleij case PTP_DPC_CANON_EOS_QuickReviewTime: 21640d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFMode: 21650d762ccc39331608119dd0267021b165e22de499Linus Walleij case PTP_DPC_CANON_EOS_EVFOutputDevice: 2166a381e8a353dfd64d25169cfb950b4dc7d4a3032aLinus Walleij case PTP_DPC_CANON_EOS_AutoPowerOff: 21673d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DPC_CANON_EOS_EVFRecordStatus: 2168f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT16; 2169f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2170f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_PictureStyle: 2171f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalance: 2172f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_MeteringMode: 21733d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DPC_CANON_EOS_ExpCompensation: 2174f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_UINT8; 2175f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2176f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DPC_CANON_EOS_Owner: 21771a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Artist: 21781a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_Copyright: 21791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_SerialNumber: 21801a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij case PTP_DPC_CANON_EOS_LensName: 2181f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->DataType = PTP_DTC_STR; 2182f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 21837e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA: 21847e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB: 21857e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij dpd->DataType = PTP_DTC_INT16; 21867e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 21877e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* unknown props, listed from dump.... all 16 bit, but vals might be smaller */ 21887e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DPOFVersion: 21891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT16; 21901a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data); 21911a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 2192e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 21931a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij break; 21947e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc1: 21957e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc2: 21967e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc3: 21977e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc4: 21987e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc5: 21997e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc6: 22007e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc7: 22017e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc8: 22027e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc9: 22037e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc10: 22047e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CustomFunc11: 22051a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij dpd->DataType = PTP_DTC_UINT8; 22061a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data); 22077e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 2208e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 22091a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij /* custom func entries look like this on the 400D: '5 0 0 0 ?' = 4 bytes size + 1 byte data */ 2210e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij xdata += 4; 22117e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 22127e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij /* yet unknown 32bit props */ 22137e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_ColorTemperature: 22147e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_WftStatus: 22157e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_LensStatus: 22167e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_CardExtension: 22177e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_TempStatus: 22187e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_PhotoStudioMode: 22197e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_DepthOfFieldPreview: 22207e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFSharpness: 22217e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFWBMode: 22227e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFClickWBCoeffs: 22237e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case PTP_DPC_CANON_EOS_EVFColorTemp: 2224d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_ExposureSimMode: 2225d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvAfSystem: 2226d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_MovSize: 2227d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_DepthOfField: 2228d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij case PTP_DPC_CANON_EOS_LvViewTypeSelect: 22292ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij case PTP_DPC_CANON_EOS_AloMode: 22309783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij case PTP_DPC_CANON_EOS_Brightness: 22310d762ccc39331608119dd0267021b165e22de499Linus Walleij dpd->DataType = PTP_DTC_UINT32; 22327e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data); 22331a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0) 22341a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) ); 22351a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++) 22363d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params, " %d: 0x%8x", j, dtoh32a(xdata+j*4)); 22377e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 2238d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij /* ImageFormat properties have to be ignored here, see special handling below */ 2239d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 2240d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 2241d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 2242d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 22430546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner case PTP_DPC_CANON_EOS_CustomFuncEx: 22443d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DPC_CANON_EOS_FocusInfoEx: 2245d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 2246f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 22473bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data); 22483bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 2249e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij ptp_debug (params, " %d: %02x", j, xdata[j]); 2250f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2251f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2252f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij switch (dpd->DataType) { 2253ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij case PTP_DTC_UINT32: 2254e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u32 = dtoh32a(xdata); 2255e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u32 = dtoh32a(xdata); 22563bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32); 2257ac052c1ac330b94932d2b4f774e0053e78e91216Linus Walleij break; 22582ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij case PTP_DTC_INT16: 22592ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij dpd->FactoryDefaultValue.i16 = dtoh16a(xdata); 22602ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij dpd->CurrentValue.i16 = dtoh16a(xdata); 22612ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %d", i, proptype, dpd->CurrentValue.i16); 22622ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij break; 2263f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT16: 2264e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = dtoh16a(xdata); 2265e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u16 = dtoh16a(xdata); 22663bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 2267f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2268f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_UINT8: 2269e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u8 = dtoh8a(xdata); 2270e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.u8 = dtoh8a(xdata); 22713bc0d7f58d56fad55449927a658951ca80a3258cLinus Walleij ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 2272f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 22733d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DTC_INT8: 22743d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd->FactoryDefaultValue.i8 = dtoh8a(xdata); 22753d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd->CurrentValue.i8 = dtoh8a(xdata); 22763d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.i8); 22773d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner break; 2278f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij case PTP_DTC_STR: { 22791a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ 2280f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij uint8_t len = 0; 2281f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 2282f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 22831a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#else 22843d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->FactoryDefaultValue.str); 2285e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.str = strdup( (char*)xdata ); 22860d762ccc39331608119dd0267021b165e22de499Linus Walleij 22873d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->CurrentValue.str); 2288e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->CurrentValue.str = strdup( (char*)xdata ); 22891a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij#endif 22907e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 2291f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2292f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2293f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 2294f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij /* debug is printed in switch above this one */ 2295f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2296f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 22971a0c3012b1cec61f54393ec3975c53141f698c8dLinus Walleij 22980546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner /* ImageFormat and customFuncEx special handling (WARNING: dont move this in front of the dpd->DataType switch!) */ 2299d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij switch (proptype) { 2300d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormat: 2301d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatCF: 2302d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatSD: 2303d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_DPC_CANON_EOS_ImageFormatExtHD: 2304d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->DataType = PTP_DTC_UINT16; 2305e206af608ab20ea4de89739d792ba2738377ccf8Linus Walleij dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &xdata ); 2306d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16; 2307d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params,"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 2308d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 23090546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner case PTP_DPC_CANON_EOS_CustomFuncEx: 23100546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->DataType = PTP_DTC_STR; 23113d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->FactoryDefaultValue.str); 23123d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->CurrentValue.str); 23133d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd->FactoryDefaultValue.str = ptp_unpack_EOS_CustomFuncEx( params, &xdata ); 23140546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner dpd->CurrentValue.str = strdup( (char*)dpd->FactoryDefaultValue.str ); 23150546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner ptp_debug (params,"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 23160546a76acd169daf35572ece1f58c9b3bc7f0f56Marcus Meissner break; 23173d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_DPC_CANON_EOS_FocusInfoEx: 23183d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd->DataType = PTP_DTC_STR; 23193d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->FactoryDefaultValue.str); 23203d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner free (dpd->CurrentValue.str); 2321aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner dpd->FactoryDefaultValue.str = ptp_unpack_EOS_FocusInfoEx( params, &xdata, size ); 23223d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd->CurrentValue.str = strdup( (char*)dpd->FactoryDefaultValue.str ); 23233d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params,"event %d: decoded focus info, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 23243d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner break; 2325d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij } 2326d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij 2327f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2328f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 23299783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* one more information record handed to us */ 23309783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij case PTP_EC_CANON_EOS_OLCInfoChanged: { 23319783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij uint32_t len, curoff; 23329783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij uint16_t mask,proptype; 23339783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij PTPDevicePropDesc *dpd; 23349783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 23359783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* unclear what OLC stands for */ 23369783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ptp_debug (params, "event %d: EOS event OLCInfoChanged (size %d)", i, size); 23379783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (size >= 0x8) { /* event info */ 23383d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner unsigned int k; 23393d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner for (k=8;k<size;k++) 23403d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ptp_debug (params, " %d: %02x", k-8, curdata[k]); 23419783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 23429783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij len = dtoh32a(curdata+8); 2343aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if ((len != size-8) && (len != size-4)) { 23449783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2345aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.info = strdup("OLC size unexpected"); 2346aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "event %d: OLC unexpected size %d for blob len %d (not -4 nor -8)", i, size, len); 23479783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij break; 23489783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 23499783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij mask = dtoh16a(curdata+8+4); 2350aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (size < 14) { 2351aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2352aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.info = strdup("OLC size too small"); 2353aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "event %d: OLC unexpected size %d", i, size); 2354aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner break; 2355aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 23569783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff = 8+4+4; 23579783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & CANON_EOS_OLC_BUTTON) { 23589783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 23599783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("Button 1234567")); 23609783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info, "Button %d", dtoh16a(curdata+curoff)); 23619783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 23629783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 2; 23639783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 23649783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 23659783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & CANON_EOS_OLC_SHUTTERSPEED) { 23669783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* 6 bytes: 01 01 98 10 00 60 */ 23679783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* this seesm to be the shutter speed record */ 23689783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij proptype = PTP_DPC_CANON_EOS_ShutterSpeed; 23693d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd = _lookup_or_allocate_canon_prop(params, proptype); 23709783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->CurrentValue.u16 = curdata[curoff+5]; /* just use last byte */ 23719783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 23729783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 23739783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.propid = proptype; 23749783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 6; 23759783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 23769783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 23779783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & CANON_EOS_OLC_APERTURE) { 23789783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* 5 bytes: 01 01 5b 30 30 */ 23799783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* this seesm to be the aperture record */ 23809783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij proptype = PTP_DPC_CANON_EOS_Aperture; 23813d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd = _lookup_or_allocate_canon_prop(params, proptype); 23829783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->CurrentValue.u16 = curdata[curoff+4]; /* just use last byte */ 23839783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 23849783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 23859783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.propid = proptype; 23869783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 5; 23879783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 23889783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 23899783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & CANON_EOS_OLC_ISO) { 23909783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* 5 bytes: 01 01 00 78 */ 23919783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* this seesm to be the aperture record */ 23929783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij proptype = PTP_DPC_CANON_EOS_ISOSpeed; 23933d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner dpd = _lookup_or_allocate_canon_prop(params, proptype); 23949783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij dpd->CurrentValue.u16 = curdata[curoff+3]; /* just use last byte */ 23959783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij 23969783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 23979783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.propid = proptype; 23989783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 4; 23999783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24009783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24019783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0010) { 24029783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0010: 4 bytes, 04 00 00 00 observed */ 24039783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 24049783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event 0x0010 content 01234567")+1); 24059783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info,"OLCInfo event 0x0010 content %02x%02x%02x%02x", 24069783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24079783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24089783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 24099783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3] 24109783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 24119783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 4; 24129783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24139783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24149783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0020) { 24159783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0020: 6 bytes, 00 00 00 00 00 00 observed */ 24169783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 24179783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event 0x0020 content 0123456789ab")+1); 24189783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info,"OLCInfo event 0x0020 content %02x%02x%02x%02x%02x%02x", 24199783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24209783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24219783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 24229783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3], 24239783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+4], 24249783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+5] 24259783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 24269783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 6; 24279783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24289783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24299783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0040) { 24303d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner int value = (signed char)curdata[curoff+2]; 24319783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0040: 7 bytes, 01 01 00 00 00 00 00 observed */ 24323d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner /* exposure indicator */ 24339783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 24343d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].u.info = malloc(strlen("OLCInfo exposure indicator 012345678901234567890123456789abcd")+1); 24353d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner sprintf(ce[i].u.info,"OLCInfo exposure indicator %d,%d,%d.%d (%02x%02x%02x%02x)", 24369783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24379783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24383d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner value/10,abs(value)%10, 24399783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3], 24409783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+4], 24419783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+5], 24429783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+6] 24439783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 24449783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 7; 24459783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24469783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24479783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0080) { 24489783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0080: 4 bytes, 00 00 00 00 observed */ 24499783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 24509783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event 0x0080 content 01234567")+1); 24519783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info,"OLCInfo event 0x0080 content %02x%02x%02x%02x", 24529783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24539783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24549783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 24559783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3] 24569783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 24579783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 4; 24589783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24599783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24609783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0100) { 24619783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0100: 6 bytes, 00 00 00 00 00 00 (before focus) and 00 00 00 00 01 00 (on focus) observed */ 24623d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO; 24633d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].u.info = malloc(strlen("0123456789ab")+1); 24643d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x", 24659783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24669783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24679783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 24689783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3], 24699783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+4], 24709783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+5] 24719783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 24729783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 6; 24739783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24749783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24759783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0200) { 24769783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0200: 7 bytes, 00 00 00 00 00 00 00 observed */ 24773d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK; 24783d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].u.info = malloc(strlen("0123456789abcd0123456789abcdef")+1); 24793d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x%02x", 24809783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24819783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24829783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 24839783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3], 24849783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+4], 24859783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+5], 24869783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+6] 24879783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 24889783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 7; 24899783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 24909783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 24919783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0400) { 24929783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0400: 7 bytes, 00 00 00 00 00 00 00 observed */ 24939783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 24949783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event 0x0400 content 0123456789abcd")+1); 24959783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info,"OLCInfo event 0x0400 content %02x%02x%02x%02x%02x%02x%02x", 24969783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 24979783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 24989783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 24999783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3], 25009783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+4], 25019783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+5], 25029783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+6] 25039783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 25049783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 7; 25059783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 25069783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 25079783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x0800) { 25089783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x0800: 8 bytes, 00 00 00 00 00 00 00 00 and 19 01 00 00 00 00 00 00 and others observed */ 25099783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* might be mask of focus points selected */ 25109783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 25119783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event 0x0800 content 0123456789abcdef")+1); 25129783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info,"OLCInfo event 0x0800 content %02x%02x%02x%02x%02x%02x%02x%02x", 25139783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff], 25149783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+1], 25159783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+2], 25169783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+3], 25179783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+4], 25189783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+5], 25199783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+6], 25209783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff+7] 25219783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 25229783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 8; 25239783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 25249783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 25259783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (mask & 0x1000) { 25269783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* mask 0x1000: 1 byte, 00 observed */ 25279783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 25289783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event 0x1000 content 01")+1); 25299783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info,"OLCInfo event 0x1000 content %02x", 25309783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curdata[curoff] 25319783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ); 25329783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij curoff += 1; 25339783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 25349783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 25359783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij /* handle more masks */ 25369783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 25379783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("OLCInfo event mask 0123456789")+1); 25389783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf(ce[i].u.info, "OLCInfo event mask=%x", mask); 25399783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij break; 25409783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij } 2541d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij case PTP_EC_CANON_EOS_CameraStatusChanged: 25429783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS; 25439783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.status = dtoh32a(curdata+8); 25449783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d) = %d", i, size, dtoh32a(curdata+8)); 25459e09ad0e32cbdac88637d4ee2cc02ca3b771ca40Linus Walleij params->eos_camerastatus = dtoh32a(curdata+8); 2546d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 25477e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij case 0: /* end marker */ 25487e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size == 8) /* no output */ 25497e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 25507e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij ptp_debug (params, "event %d: EOS event 0, but size %d", i, size); 25517e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij break; 255296aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij case PTP_EC_CANON_EOS_BulbExposureTime: 25539783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2554aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ce[i].u.info = malloc(strlen("BulbExposureTime 123456789012345678")); 25559783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf (ce[i].u.info, "BulbExposureTime %d", dtoh32a(curdata+8)); 255696aa0e34e92d98a5cf7900afbe20395f74ed3a20Linus Walleij break; 25573d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner case PTP_EC_CANON_EOS_ObjectRemoved: 25583d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTREMOVED; 25593d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner ce[i].u.object.oid = dtoh32a(curdata+8); 25603d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner break; 2561f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij default: 2562d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij switch (type) { 2563d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij#define XX(x) case PTP_EC_CANON_EOS_##x: \ 2564d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size); \ 25659783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)")); \ 25669783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij sprintf (ce[i].u.info, "unhandled EOS event "#x" (size %d)", size); \ 2567d7072c3fa6182eed4767c97d371b15860bc386afLinus Walleij break; 2568d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetEvent) 2569d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestGetObjectInfoEx) 2570d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageStatusChanged) 2571d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StorageInfoChanged) 2572d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectInfoChangedEx) 2573d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ObjectContentChanged) 2574d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(WillSoonShutdown) 2575d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(ShutdownTimerUpdated) 2576d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransfer) 2577d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferDT) 2578d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestCancelTransferDT) 2579d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreAdded) 2580d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(StoreRemoved) 2581d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(BulbExposureTime) 2582d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RecordingTime) 2583d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(RequestObjectTransferTS) 2584d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij XX(AfResult) 2585d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij#undef XX 2586d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij default: 2587d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, "event %d: unknown EOS event %04x", i, type); 2588d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij break; 2589d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij } 25907e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij if (size >= 0x8) { /* event info */ 25912ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int j; 2592aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner /*ptp_debug (params, "data=%p, curdata=%p, datsize=%d, size=%d", data, curdata, datasize, size);*/ 2593d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij for (j=8;j<size;j++) 2594d4637506d9551957a152cab2cfb80fdfed029424Linus Walleij ptp_debug (params, " %d: %02x", j, curdata[j]); 25957e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij } 25969783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2597f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij break; 2598f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 2599f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij curdata += size; 26009783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij i++; 2601aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (i >= entries) { 2602aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner ptp_debug (params, "BAD: i %d, entries %d", i, entries); 2603aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 2604f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij } 26059783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij if (!i) { 26069783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij free (ce); 26079783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij ce = NULL; 26080d762ccc39331608119dd0267021b165e22de499Linus Walleij } 26099783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij *pce = ce; 26109783ce3e1a9c2a1780be0c8a0648ba6b6ae1342aLinus Walleij return i; 2611f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij} 2612f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij 2613f0bf437f4de75d31a9493c06d03e4db8ded84be4Linus Walleij/* 2614b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij PTP USB Event container unpack for Nikon events. 2615b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij*/ 2616b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Length 0 2617b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Code 2 2618b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Param1 4 2619b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij#define PTP_nikon_ec_Size 6 2620b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline void 26212ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleijptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, unsigned int *cnt) 2622b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij{ 26232ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int i; 2624b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2625b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *ec = NULL; 2626b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (data == NULL) 2627b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 2628b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (len < PTP_nikon_ec_Code) 2629b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 2630b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 2631aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) { /* broken cnt? */ 2632aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner *cnt = 0; 2633b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return; 2634aa7d91a789873a9d86969028e57f888a1241c085Marcus Meissner } 26350d762ccc39331608119dd0267021b165e22de499Linus Walleij if (!*cnt) 26360d762ccc39331608119dd0267021b165e22de499Linus Walleij return; 26370d762ccc39331608119dd0267021b165e22de499Linus Walleij 26387e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij *ec = malloc(sizeof(PTPContainer)*(*cnt)); 2639b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2640b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<*cnt;i++) { 26417e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij memset(&(*ec)[i],0,sizeof(PTPContainer)); 26427e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 26437e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 26447e75653e64021908ca66b155eeb950d8304c87d8Linus Walleij (*ec)[i].Nparam = 1; 2645b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 2646eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij} 2647eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 2648eb8c6fe031f5ba155cabcbfabcc235acffbc2fbLinus Walleij 2649b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijstatic inline uint32_t 2650b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleijptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 2651b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij int i, len = 0; 2652b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij uint8_t retlen; 2653b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij unsigned char *curdata; 2654b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2655b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij len = 2*(strlen(text->title)+1)+1+ 2656b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[0])+1)+1+ 2657b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[1])+1)+1+ 2658b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[2])+1)+1+ 2659b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[3])+1)+1+ 2660b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2*(strlen(text->line[4])+1)+1+ 2661b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 4*2+2*4+2+4+2+5*4*2; 2662b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij *data = malloc(len); 2663b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij if (!*data) return 0; 2664b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2665b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij curdata = *data; 2666b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,100);curdata+=2; 2667b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1);curdata+=2; 2668b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0);curdata+=2; 2669b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,1000);curdata+=2; 2670b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2671b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 2672b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 2673b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2674b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,6);curdata+=2; 2675b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod32a(curdata,0);curdata+=4; 2676b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2677b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 2678b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 2679b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij 2680b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij for (i=0;i<5;i++) { 2681b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 2682b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x10);curdata+=2; 2683b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x01);curdata+=2; 2684b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x02);curdata+=2; 2685b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij htod16a(curdata,0x06);curdata+=2; 2686b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij } 2687b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij return len; 2688b02a066363ab3c9b4f8f48b227c9b7b71cf7705eLinus Walleij} 26897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 26907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_version 0x00 26917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_ofc 0x02 26927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk1 0x04 26937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_objectid 0x08 26947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_parentid 0x0c 26957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_previd 0x10 /* in same dir */ 26967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextid 0x14 /* in same dir */ 26977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 26987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 26997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_name 0x20 27007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_flags 0x2c 27017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_size 0x30 27027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unixtime 0x34 27037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_year 0x38 27047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_month 0x39 27057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_mday 0x3a 27067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_hour 0x3b 27077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_minute 0x3c 27087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_second 0x3d 27097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_unk2 0x3e 27107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_thumbsize 0x40 27117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_width 0x44 27127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ptp_canon_dir_height 0x48 27137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijstatic inline uint16_t 27157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleijptp_unpack_canon_directory ( 27167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPParams *params, 27177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *dir, 27187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t cnt, 27197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectHandles *handles, 27207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo **oinfos, /* size(handles->n) */ 27217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t **flags /* size(handles->n) */ 27227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij) { 27237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned int i, j, nrofobs = 0, curob = 0; 27247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27257347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 27267347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) 27277347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(dir+i*0x4c)) nrofobs++; 27287347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->n = nrofobs; 27293d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner handles->Handler = calloc(nrofobs,sizeof(handles->Handler[0])); 27307347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!handles->Handler) return PTP_RC_GeneralError; 27313d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner *oinfos = calloc(nrofobs,sizeof((*oinfos)[0])); 27327347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*oinfos) return PTP_RC_GeneralError; 27333d692dcb45c73f58e0c0bd86f5a19b001fd8ebf1Marcus Meissner *flags = calloc(nrofobs,sizeof((*flags)[0])); 27347347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!*flags) return PTP_RC_GeneralError; 27357347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27367347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Migrate data into objects ids, handles into 27377347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the object handler array. 27387347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 27397347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob = 0; 27407347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 27417347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 27427347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij PTPObjectInfo *oi = (*oinfos)+curob; 27437347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27447347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 27457347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 27467347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27477347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 27487347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->StorageID = 0xffffffff; 27497347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 27507347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 27517347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 27527347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 27537347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 27547347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 27557347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 27567347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 27577347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 27587347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij curob++; 27597347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 27607347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over Storage ID entries and distribute the IDs to 27617347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * the parent objects. */ 27627347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 27637347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 27647347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 27657347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27667347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (ISOBJECT(cur)) 27677347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 27687347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 27697347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) continue; 27707347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 27717347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 27727347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Walk over all objects and distribute the storage ids */ 27737347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij while (1) { 27742ad5b720731014737c5ab8781362e7b3faa713ecLinus Walleij unsigned int changed = 0; 27757347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (i=0;i<cnt;i++) { 27767347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij unsigned char *cur = dir+i*0x4c; 27777347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 27787347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 27797347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 27807347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij uint32_t storageid; 27817347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij 27827347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!ISOBJECT(cur)) 27837347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 27847347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 27857347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 27867347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 27877347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 27887347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 27897347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij storageid = (*oinfos)[j].StorageID; 27907347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (storageid == 0xffffffff) continue; 27917347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextoid != 0xffffffff) { 27927347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 27937347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 27947347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 27957347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 27967347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 27977347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 27987347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 27997347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 28007347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28017347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28027347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (nextchild != 0xffffffff) { 28037347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 28047347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (j == handles->n) { 28057347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 28067347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij continue; 28077347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28087347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if ((*oinfos)[j].StorageID == 0xffffffff) { 28097347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij (*oinfos)[j].StorageID = storageid; 28107347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij changed++; 28117347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28127347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28137347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28147347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij /* Check if we: 28157347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed no entry (nothing more to do) 28167347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * - changed all of them at once (usually happens) 28177347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij * break if we do. 28187347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij */ 28197347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij if (!changed || (changed==nrofobs-1)) 28207347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij break; 28217347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij } 28227347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij#undef ISOBJECT 28237347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij return PTP_RC_OK; 28247347d0f315ffcce2c934555e35014af8bbc2cb1cLinus Walleij} 2825