1 /* ptp-pack.c 2 * 3 * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi (at) ipartners.pl> 4 * Copyright (C) 2003-2016 Marcus Meissner <marcus (at) jet.franken.de> 5 * Copyright (C) 2006-2008 Linus Walleij <triad (at) df.lth.se> 6 * Copyright (C) 2007 Tero Saarni <tero.saarni (at) gmail.com> 7 * Copyright (C) 2009 Axel Waggershauser <awagger (at) web.de> 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the 21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301 USA 23 */ 24 25 /* currently this file is included into ptp.c */ 26 27 #ifdef HAVE_LIMITS_H 28 #include <limits.h> 29 #endif 30 #ifndef UINT_MAX 31 # define UINT_MAX 0xFFFFFFFF 32 #endif 33 #if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 34 #include <iconv.h> 35 #endif 36 37 static inline uint16_t 38 htod16p (PTPParams *params, uint16_t var) 39 { 40 return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 41 } 42 43 static inline uint32_t 44 htod32p (PTPParams *params, uint32_t var) 45 { 46 return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 47 } 48 49 static inline void 50 htod16ap (PTPParams *params, unsigned char *a, uint16_t val) 51 { 52 if (params->byteorder==PTP_DL_LE) 53 htole16a(a,val); 54 else 55 htobe16a(a,val); 56 } 57 58 static inline void 59 htod32ap (PTPParams *params, unsigned char *a, uint32_t val) 60 { 61 if (params->byteorder==PTP_DL_LE) 62 htole32a(a,val); 63 else 64 htobe32a(a,val); 65 } 66 67 static inline void 68 htod64ap (PTPParams *params, unsigned char *a, uint64_t val) 69 { 70 if (params->byteorder==PTP_DL_LE) 71 htole64a(a,val); 72 else 73 htobe64a(a,val); 74 } 75 76 static inline uint16_t 77 dtoh16p (PTPParams *params, uint16_t var) 78 { 79 return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 80 } 81 82 static inline uint32_t 83 dtoh32p (PTPParams *params, uint32_t var) 84 { 85 return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 86 } 87 88 static inline uint64_t 89 dtoh64p (PTPParams *params, uint64_t var) 90 { 91 return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var)); 92 } 93 94 static inline uint16_t 95 dtoh16ap (PTPParams *params, const unsigned char *a) 96 { 97 return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 98 } 99 100 static inline uint32_t 101 dtoh32ap (PTPParams *params, const unsigned char *a) 102 { 103 return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 104 } 105 106 static inline uint64_t 107 dtoh64ap (PTPParams *params, const unsigned char *a) 108 { 109 return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a)); 110 } 111 112 #define htod8a(a,x) *(uint8_t*)(a) = x 113 #define htod16a(a,x) htod16ap(params,a,x) 114 #define htod32a(a,x) htod32ap(params,a,x) 115 #define htod64a(a,x) htod64ap(params,a,x) 116 #define htod16(x) htod16p(params,x) 117 #define htod32(x) htod32p(params,x) 118 #define htod64(x) htod64p(params,x) 119 120 #define dtoh8a(x) (*(uint8_t*)(x)) 121 #define dtoh16a(a) dtoh16ap(params,a) 122 #define dtoh32a(a) dtoh32ap(params,a) 123 #define dtoh64a(a) dtoh64ap(params,a) 124 #define dtoh16(x) dtoh16p(params,x) 125 #define dtoh32(x) dtoh32p(params,x) 126 #define dtoh64(x) dtoh64p(params,x) 127 128 129 static inline char* 130 ptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t total, uint8_t *len) 131 { 132 uint8_t length; 133 uint16_t string[PTP_MAXSTRLEN+1]; 134 /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ 135 char loclstr[PTP_MAXSTRLEN*3+1]; 136 size_t nconv, srclen, destlen; 137 char *src, *dest; 138 139 if (offset + 1 >= total) 140 return NULL; 141 142 length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ 143 *len = length; 144 if (length == 0) /* nothing to do? */ 145 return NULL; 146 147 if (offset + 1 + length*sizeof(string[0]) > total) 148 return NULL; 149 150 /* copy to string[] to ensure correct alignment for iconv(3) */ 151 memcpy(string, &data[offset+1], length * sizeof(string[0])); 152 string[length] = 0x0000U; /* be paranoid! add a terminator. */ 153 loclstr[0] = '\0'; 154 155 /* convert from camera UCS-2 to our locale */ 156 src = (char *)string; 157 srclen = length * sizeof(string[0]); 158 dest = loclstr; 159 destlen = sizeof(loclstr)-1; 160 nconv = (size_t)-1; 161 #if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 162 if (params->cd_ucs2_to_locale != (iconv_t)-1) 163 nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, &dest, &destlen); 164 #endif 165 if (nconv == (size_t) -1) { /* do it the hard way */ 166 int i; 167 /* try the old way, in case iconv is broken */ 168 for (i=0;i<length;i++) { 169 if (dtoh16a(&data[offset+1+2*i])>127) 170 loclstr[i] = '?'; 171 else 172 loclstr[i] = dtoh16a(&data[offset+1+2*i]); 173 } 174 dest = loclstr+length; 175 } 176 *dest = '\0'; 177 loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ 178 return(strdup(loclstr)); 179 } 180 181 static inline int 182 ucs2strlen(uint16_t const * const unicstr) 183 { 184 int length = 0; 185 186 /* Unicode strings are terminated with 2 * 0x00 */ 187 for(length = 0; unicstr[length] != 0x0000U; length ++); 188 return length; 189 } 190 191 192 static inline void 193 ptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 194 { 195 int packedlen = 0; 196 uint16_t ucs2str[PTP_MAXSTRLEN+1]; 197 char *ucs2strp = (char *) ucs2str; 198 size_t convlen = strlen(string); 199 200 /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 201 memset(ucs2strp, 0, sizeof(ucs2str)); /* XXX: necessary? */ 202 #if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H) 203 if (params->cd_locale_to_ucs2 != (iconv_t)-1) { 204 size_t nconv; 205 size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 206 char *stringp = string; 207 208 nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, 209 &ucs2strp, &convmax); 210 if (nconv == (size_t) -1) 211 ucs2str[0] = 0x0000U; 212 } else 213 #endif 214 { 215 unsigned int i; 216 217 for (i=0;i<convlen;i++) { 218 ucs2str[i] = string[i]; 219 } 220 ucs2str[convlen] = 0; 221 } 222 /* 223 * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 224 * why do we need ucs2strlen()? 225 */ 226 packedlen = ucs2strlen(ucs2str); 227 if (packedlen > PTP_MAXSTRLEN-1) { 228 *len=0; 229 return; 230 } 231 232 /* number of characters including terminating 0 (PTP standard confirmed) */ 233 htod8a(&data[offset],packedlen+1); 234 memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 235 htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 236 237 /* The returned length is in number of characters */ 238 *len = (uint8_t) packedlen+1; 239 } 240 241 static inline unsigned char * 242 ptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 243 { 244 uint8_t packed[PTP_MAXSTRLEN*2+3], len; 245 size_t plen; 246 unsigned char *retcopy = NULL; 247 248 if (string == NULL) 249 ptp_pack_string(params, "", (unsigned char*) packed, 0, &len); 250 else 251 ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 252 253 /* returned length is in characters, then one byte for string length */ 254 plen = len*2 + 1; 255 256 retcopy = malloc(plen); 257 if (!retcopy) { 258 *packed_size = 0; 259 return NULL; 260 } 261 memcpy(retcopy, packed, plen); 262 *packed_size = plen; 263 return (retcopy); 264 } 265 266 static inline uint32_t 267 ptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint32_t **array) 268 { 269 uint32_t n, i=0; 270 271 if (!data) 272 return 0; 273 274 if (offset >= datalen) 275 return 0; 276 277 if (offset + sizeof(uint32_t) > datalen) 278 return 0; 279 280 *array = NULL; 281 n=dtoh32a(&data[offset]); 282 if (n >= UINT_MAX/sizeof(uint32_t)) 283 return 0; 284 if (!n) 285 return 0; 286 287 if (offset + sizeof(uint32_t)*(n+1) > datalen) { 288 ptp_debug (params ,"array runs over datalen bufferend (%d vs %d)", offset + sizeof(uint32_t)*(n+1) , datalen); 289 return 0; 290 } 291 292 *array = malloc (n*sizeof(uint32_t)); 293 if (!*array) 294 return 0; 295 for (i=0;i<n;i++) 296 (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 297 return n; 298 } 299 300 static inline uint32_t 301 ptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 302 { 303 uint32_t i=0; 304 305 *data = malloc ((arraylen+1)*sizeof(uint32_t)); 306 if (!*data) 307 return 0; 308 htod32a(&(*data)[0],arraylen); 309 for (i=0;i<arraylen;i++) 310 htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 311 return (arraylen+1)*sizeof(uint32_t); 312 } 313 314 static inline uint32_t 315 ptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, unsigned int offset, unsigned int datalen, uint16_t **array) 316 { 317 uint32_t n, i=0; 318 319 if (!data) 320 return 0; 321 *array = NULL; 322 n=dtoh32a(&data[offset]); 323 if (n >= UINT_MAX/sizeof(uint16_t)) 324 return 0; 325 if (!n) 326 return 0; 327 if (offset + sizeof(uint32_t) > datalen) 328 return 0; 329 if (offset + sizeof(uint32_t)+sizeof(uint16_t)*n > datalen) { 330 ptp_debug (params ,"array runs over datalen bufferend (%d vs %d)", offset + sizeof(uint32_t)+n*sizeof(uint16_t) , datalen); 331 return 0; 332 } 333 *array = malloc (n*sizeof(uint16_t)); 334 if (!*array) 335 return 0; 336 for (i=0;i<n;i++) 337 (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 338 return n; 339 } 340 341 /* DeviceInfo pack/unpack */ 342 343 #define PTP_di_StandardVersion 0 344 #define PTP_di_VendorExtensionID 2 345 #define PTP_di_VendorExtensionVersion 6 346 #define PTP_di_VendorExtensionDesc 8 347 #define PTP_di_FunctionalMode 8 348 #define PTP_di_OperationsSupported 10 349 350 static inline int 351 ptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 352 { 353 uint8_t len; 354 unsigned int totallen; 355 356 if (!data) return 0; 357 if (datalen < 12) return 0; 358 memset (di, 0, sizeof(*di)); 359 di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 360 di->VendorExtensionID = 361 dtoh32a(&data[PTP_di_VendorExtensionID]); 362 di->VendorExtensionVersion = 363 dtoh16a(&data[PTP_di_VendorExtensionVersion]); 364 di->VendorExtensionDesc = 365 ptp_unpack_string(params, data, 366 PTP_di_VendorExtensionDesc, 367 datalen, 368 &len); 369 totallen=len*2+1; 370 if (datalen <= totallen) return 0; 371 di->FunctionalMode = 372 dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 373 di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 374 PTP_di_OperationsSupported+totallen, 375 datalen, 376 &di->OperationsSupported); 377 totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 378 if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 379 di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 380 PTP_di_OperationsSupported+totallen, 381 datalen, 382 &di->EventsSupported); 383 totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 384 if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 385 di->DevicePropertiesSupported_len = 386 ptp_unpack_uint16_t_array(params, data, 387 PTP_di_OperationsSupported+totallen, 388 datalen, 389 &di->DevicePropertiesSupported); 390 totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 391 if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 392 di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 393 PTP_di_OperationsSupported+totallen, 394 datalen, 395 &di->CaptureFormats); 396 totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 397 if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 398 di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 399 PTP_di_OperationsSupported+totallen, 400 datalen, 401 &di->ImageFormats); 402 totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 403 if (datalen <= totallen+PTP_di_OperationsSupported) return 0; 404 di->Manufacturer = ptp_unpack_string(params, data, 405 PTP_di_OperationsSupported+totallen, 406 datalen, 407 &len); 408 totallen+=len*2+1; 409 /* be more relaxed ... as these are optional its ok if they are not here */ 410 if (datalen <= totallen+PTP_di_OperationsSupported) return 1; 411 di->Model = ptp_unpack_string(params, data, 412 PTP_di_OperationsSupported+totallen, 413 datalen, 414 &len); 415 totallen+=len*2+1; 416 /* be more relaxed ... as these are optional its ok if they are not here */ 417 if (datalen <= totallen+PTP_di_OperationsSupported) return 1; 418 di->DeviceVersion = ptp_unpack_string(params, data, 419 PTP_di_OperationsSupported+totallen, 420 datalen, 421 &len); 422 totallen+=len*2+1; 423 /* be more relaxed ... as these are optional its ok if they are not here */ 424 if (datalen <= totallen+PTP_di_OperationsSupported) return 1; 425 di->SerialNumber = ptp_unpack_string(params, data, 426 PTP_di_OperationsSupported+totallen, 427 datalen, 428 &len); 429 return 1; 430 } 431 432 inline static void 433 ptp_free_DI (PTPDeviceInfo *di) { 434 free (di->SerialNumber); 435 free (di->DeviceVersion); 436 free (di->Model); 437 free (di->Manufacturer); 438 free (di->ImageFormats); 439 free (di->CaptureFormats); 440 free (di->VendorExtensionDesc); 441 free (di->OperationsSupported); 442 free (di->EventsSupported); 443 free (di->DevicePropertiesSupported); 444 memset(di, 0, sizeof(*di)); 445 } 446 447 /* EOS Device Info unpack */ 448 static inline int 449 ptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) 450 { 451 unsigned int totallen = 4; 452 453 memset (di,0, sizeof(*di)); 454 if (datalen < 8) return 0; 455 456 /* uint32_t struct len - ignore */ 457 di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, 458 totallen, datalen, &di->EventsSupported); 459 if (!di->EventsSupported) return 0; 460 totallen += di->EventsSupported_len*sizeof(uint32_t)+4; 461 if (totallen >= datalen) return 0; 462 463 di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, 464 totallen, datalen, &di->DevicePropertiesSupported); 465 if (!di->DevicePropertiesSupported) return 0; 466 totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; 467 if (totallen >= datalen) return 0; 468 469 di->unk_len = ptp_unpack_uint32_t_array(params, data, 470 totallen, datalen, &di->unk); 471 if (!di->unk) return 0; 472 totallen += di->unk_len*sizeof(uint32_t)+4; 473 return 1; 474 } 475 476 static inline void 477 ptp_free_EOS_DI (PTPCanonEOSDeviceInfo *di) 478 { 479 free (di->EventsSupported); 480 free (di->DevicePropertiesSupported); 481 free (di->unk); 482 } 483 484 /* ObjectHandles array pack/unpack */ 485 486 #define PTP_oh 0 487 488 static inline void 489 ptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 490 { 491 if (len) { 492 oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, len, &oh->Handler); 493 } else { 494 oh->n = 0; 495 oh->Handler = NULL; 496 } 497 } 498 499 /* StoreIDs array pack/unpack */ 500 501 #define PTP_sids 0 502 503 static inline void 504 ptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 505 { 506 sids->n = 0; 507 sids->Storage = NULL; 508 509 if (!data || !len) 510 return; 511 512 sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, len, &sids->Storage); 513 } 514 515 /* StorageInfo pack/unpack */ 516 517 #define PTP_si_StorageType 0 518 #define PTP_si_FilesystemType 2 519 #define PTP_si_AccessCapability 4 520 #define PTP_si_MaxCapability 6 521 #define PTP_si_FreeSpaceInBytes 14 522 #define PTP_si_FreeSpaceInImages 22 523 #define PTP_si_StorageDescription 26 524 525 static inline int 526 ptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 527 { 528 uint8_t storagedescriptionlen; 529 530 if (len < 26) return 0; 531 si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 532 si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 533 si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 534 si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 535 si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 536 si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 537 538 /* FIXME: check more lengths here */ 539 si->StorageDescription=ptp_unpack_string(params, data, 540 PTP_si_StorageDescription, 541 len, 542 &storagedescriptionlen); 543 si->VolumeLabel=ptp_unpack_string(params, data, 544 PTP_si_StorageDescription+storagedescriptionlen*2+1, 545 len, 546 &storagedescriptionlen); 547 return 1; 548 } 549 550 /* ObjectInfo pack/unpack */ 551 552 #define PTP_oi_StorageID 0 553 #define PTP_oi_ObjectFormat 4 554 #define PTP_oi_ProtectionStatus 6 555 #define PTP_oi_ObjectCompressedSize 8 556 #define PTP_oi_ThumbFormat 12 557 #define PTP_oi_ThumbCompressedSize 14 558 #define PTP_oi_ThumbPixWidth 18 559 #define PTP_oi_ThumbPixHeight 22 560 #define PTP_oi_ImagePixWidth 26 561 #define PTP_oi_ImagePixHeight 30 562 #define PTP_oi_ImageBitDepth 34 563 #define PTP_oi_ParentObject 38 564 #define PTP_oi_AssociationType 42 565 #define PTP_oi_AssociationDesc 44 566 #define PTP_oi_SequenceNumber 48 567 #define PTP_oi_filenamelen 52 568 #define PTP_oi_Filename 53 569 570 /* the max length assuming zero length dates. We have need 3 */ 571 /* bytes for these. */ 572 #define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 573 574 static inline uint32_t 575 ptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 576 { 577 unsigned char* oidata; 578 uint8_t filenamelen; 579 uint8_t capturedatelen=0; 580 /* let's allocate some memory first; correct assuming zero length dates */ 581 oidata=malloc(PTP_oi_MaxLen + params->ocs64*4); 582 *oidataptr=oidata; 583 /* the caller should free it after use! */ 584 #if 0 585 char *capture_date="20020101T010101"; /* XXX Fake date */ 586 #endif 587 memset (oidata, 0, PTP_oi_MaxLen + params->ocs64*4); 588 htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 589 htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 590 htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 591 htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 592 if (params->ocs64) 593 oidata += 4; 594 htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 595 htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 596 htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 597 htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 598 htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 599 htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 600 htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 601 htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 602 htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 603 htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 604 htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 605 606 ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 607 /* 608 filenamelen=(uint8_t)strlen(oi->Filename); 609 htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 610 for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 611 req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 612 } 613 */ 614 /* 615 *XXX Fake date. 616 * for example Kodak sets Capture date on the basis of EXIF data. 617 * Spec says that this field is from perspective of Initiator. 618 */ 619 #if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 620 capturedatelen=strlen(capture_date); 621 htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 622 capturedatelen+1); 623 for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 624 data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 625 } 626 htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 627 capturedatelen+1); 628 for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 629 data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 630 capture_date[i]; 631 } 632 #endif 633 /* XXX this function should return dataset length */ 634 return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3)+params->ocs64*4; 635 } 636 637 static time_t 638 ptp_unpack_PTPTIME (const char *str) { 639 char ptpdate[40]; 640 char tmp[5]; 641 size_t ptpdatelen; 642 struct tm tm; 643 644 if (!str) 645 return 0; 646 ptpdatelen = strlen(str); 647 if (ptpdatelen >= sizeof (ptpdate)) { 648 /*ptp_debug (params ,"datelen is larger then size of buffer", ptpdatelen, (int)sizeof(ptpdate));*/ 649 return 0; 650 } 651 if (ptpdatelen<15) { 652 /*ptp_debug (params ,"datelen is less than 15 (%d)", ptpdatelen);*/ 653 return 0; 654 } 655 strncpy (ptpdate, str, sizeof(ptpdate)); 656 ptpdate[sizeof(ptpdate) - 1] = '\0'; 657 658 memset(&tm,0,sizeof(tm)); 659 strncpy (tmp, ptpdate, 4); 660 tmp[4] = 0; 661 tm.tm_year=atoi (tmp) - 1900; 662 strncpy (tmp, ptpdate + 4, 2); 663 tmp[2] = 0; 664 tm.tm_mon = atoi (tmp) - 1; 665 strncpy (tmp, ptpdate + 6, 2); 666 tmp[2] = 0; 667 tm.tm_mday = atoi (tmp); 668 strncpy (tmp, ptpdate + 9, 2); 669 tmp[2] = 0; 670 tm.tm_hour = atoi (tmp); 671 strncpy (tmp, ptpdate + 11, 2); 672 tmp[2] = 0; 673 tm.tm_min = atoi (tmp); 674 strncpy (tmp, ptpdate + 13, 2); 675 tmp[2] = 0; 676 tm.tm_sec = atoi (tmp); 677 tm.tm_isdst = -1; 678 return mktime (&tm); 679 } 680 681 static inline void 682 ptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 683 { 684 uint8_t filenamelen; 685 uint8_t capturedatelen; 686 char *capture_date; 687 688 if (len < PTP_oi_SequenceNumber) 689 return; 690 691 oi->Filename = oi->Keywords = NULL; 692 693 /* FIXME: also handle length with all the strings at the end */ 694 oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 695 oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 696 oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 697 oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 698 699 /* Stupid Samsung Galaxy developers emit a 64bit objectcompressedsize */ 700 if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) { 701 params->ocs64 = 1; 702 data += 4; 703 } 704 oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 705 oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 706 oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 707 oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 708 oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 709 oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 710 oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 711 oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 712 oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 713 oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 714 oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 715 716 oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, len, &filenamelen); 717 718 capture_date = ptp_unpack_string(params, data, 719 PTP_oi_filenamelen+filenamelen*2+1, len, &capturedatelen); 720 /* subset of ISO 8601, without '.s' tenths of second and 721 * time zone 722 */ 723 oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); 724 free(capture_date); 725 726 /* now the modification date ... */ 727 capture_date = ptp_unpack_string(params, data, 728 PTP_oi_filenamelen+filenamelen*2 729 +capturedatelen*2+2, len, &capturedatelen); 730 oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); 731 free(capture_date); 732 } 733 734 /* Custom Type Value Assignement (without Length) macro frequently used below */ 735 #define CTVAL(target,func) { \ 736 if (total - *offset < sizeof(target)) \ 737 return 0; \ 738 target = func(&data[*offset]); \ 739 *offset += sizeof(target); \ 740 } 741 742 #define RARR(val,member,func) { \ 743 unsigned int n,j; \ 744 if (total - *offset < sizeof(uint32_t)) \ 745 return 0; \ 746 n = dtoh32a (&data[*offset]); \ 747 *offset += sizeof(uint32_t); \ 748 \ 749 if (n >= UINT_MAX/sizeof(val->a.v[0])) \ 750 return 0; \ 751 if (n > (total - (*offset))/sizeof(val->a.v[0]))\ 752 return 0; \ 753 val->a.count = n; \ 754 val->a.v = malloc(sizeof(val->a.v[0])*n); \ 755 if (!val->a.v) return 0; \ 756 for (j=0;j<n;j++) \ 757 CTVAL(val->a.v[j].member, func); \ 758 } 759 760 static inline unsigned int 761 ptp_unpack_DPV ( 762 PTPParams *params, unsigned char* data, unsigned int *offset, unsigned int total, 763 PTPPropertyValue* value, uint16_t datatype 764 ) { 765 if (*offset >= total) /* we are at the end or over the end of the buffer */ 766 return 0; 767 768 switch (datatype) { 769 case PTP_DTC_INT8: 770 CTVAL(value->i8,dtoh8a); 771 break; 772 case PTP_DTC_UINT8: 773 CTVAL(value->u8,dtoh8a); 774 break; 775 case PTP_DTC_INT16: 776 CTVAL(value->i16,dtoh16a); 777 break; 778 case PTP_DTC_UINT16: 779 CTVAL(value->u16,dtoh16a); 780 break; 781 case PTP_DTC_INT32: 782 CTVAL(value->i32,dtoh32a); 783 break; 784 case PTP_DTC_UINT32: 785 CTVAL(value->u32,dtoh32a); 786 break; 787 case PTP_DTC_INT64: 788 CTVAL(value->i64,dtoh64a); 789 break; 790 case PTP_DTC_UINT64: 791 CTVAL(value->u64,dtoh64a); 792 break; 793 794 case PTP_DTC_UINT128: 795 *offset += 16; 796 /*fprintf(stderr,"unhandled unpack of uint128n");*/ 797 break; 798 case PTP_DTC_INT128: 799 *offset += 16; 800 /*fprintf(stderr,"unhandled unpack of int128n");*/ 801 break; 802 803 804 805 case PTP_DTC_AINT8: 806 RARR(value,i8,dtoh8a); 807 break; 808 case PTP_DTC_AUINT8: 809 RARR(value,u8,dtoh8a); 810 break; 811 case PTP_DTC_AUINT16: 812 RARR(value,u16,dtoh16a); 813 break; 814 case PTP_DTC_AINT16: 815 RARR(value,i16,dtoh16a); 816 break; 817 case PTP_DTC_AUINT32: 818 RARR(value,u32,dtoh32a); 819 break; 820 case PTP_DTC_AINT32: 821 RARR(value,i32,dtoh32a); 822 break; 823 case PTP_DTC_AUINT64: 824 RARR(value,u64,dtoh64a); 825 break; 826 case PTP_DTC_AINT64: 827 RARR(value,i64,dtoh64a); 828 break; 829 /* XXX: other int types are unimplemented */ 830 /* XXX: other int arrays are unimplemented also */ 831 case PTP_DTC_STR: { 832 uint8_t len; 833 /* XXX: max size */ 834 835 if (*offset >= total+1) 836 return 0; 837 838 value->str = ptp_unpack_string(params,data,*offset,total,&len); 839 *offset += len*2+1; 840 if (!value->str) 841 return 1; 842 break; 843 } 844 default: 845 return 0; 846 } 847 return 1; 848 } 849 850 /* Device Property pack/unpack */ 851 #define PTP_dpd_DevicePropertyCode 0 852 #define PTP_dpd_DataType 2 853 #define PTP_dpd_GetSet 4 854 #define PTP_dpd_FactoryDefaultValue 5 855 856 static inline int 857 ptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 858 { 859 unsigned int offset = 0, ret; 860 861 memset (dpd, 0, sizeof(*dpd)); 862 if (dpdlen <= 5) 863 return 0; 864 dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 865 dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 866 dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 867 dpd->FormFlag=PTP_DPFF_None; 868 869 offset = PTP_dpd_FactoryDefaultValue; 870 ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 871 if (!ret) goto outofmemory; 872 if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) 873 return 1; 874 ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 875 if (!ret) goto outofmemory; 876 877 /* if offset==0 then Data Type format is not supported by this 878 code or the Data Type is a string (with two empty strings as 879 values). In both cases Form Flag should be set to 0x00 and FORM is 880 not present. */ 881 882 if (offset==PTP_dpd_FactoryDefaultValue) 883 return 1; 884 885 dpd->FormFlag=dtoh8a(&data[offset]); 886 offset+=sizeof(uint8_t); 887 888 switch (dpd->FormFlag) { 889 case PTP_DPFF_Range: 890 ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 891 if (!ret) goto outofmemory; 892 ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 893 if (!ret) goto outofmemory; 894 ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 895 if (!ret) goto outofmemory; 896 break; 897 case PTP_DPFF_Enumeration: { 898 int i; 899 #define N dpd->FORM.Enum.NumberOfValues 900 N = dtoh16a(&data[offset]); 901 offset+=sizeof(uint16_t); 902 dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 903 if (!dpd->FORM.Enum.SupportedValue) 904 goto outofmemory; 905 906 memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 907 for (i=0;i<N;i++) { 908 ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 909 910 /* Slightly different handling here. The HP PhotoSmart 120 911 * specifies an enumeration with N in wrong endian 912 * 00 01 instead of 01 00, so we count the enum just until the 913 * the end of the packet. 914 */ 915 if (!ret) { 916 if (!i) 917 goto outofmemory; 918 dpd->FORM.Enum.NumberOfValues = i; 919 break; 920 } 921 } 922 } 923 } 924 #undef N 925 return 1; 926 outofmemory: 927 ptp_free_devicepropdesc(dpd); 928 return 0; 929 } 930 931 /* Device Property pack/unpack */ 932 #define PTP_dpd_Sony_DevicePropertyCode 0 933 #define PTP_dpd_Sony_DataType 2 934 #define PTP_dpd_Sony_GetSet 4 935 #define PTP_dpd_Sony_Unknown 5 936 #define PTP_dpd_Sony_FactoryDefaultValue 6 937 938 static inline int 939 ptp_unpack_Sony_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen, unsigned int *poffset) 940 { 941 unsigned int ret; 942 #if 0 943 unsigned int unk1, unk2; 944 #endif 945 946 memset (dpd, 0, sizeof(*dpd)); 947 dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_Sony_DevicePropertyCode]); 948 dpd->DataType=dtoh16a(&data[PTP_dpd_Sony_DataType]); 949 950 #if 0 951 /* get set ? */ 952 unk1 = dtoh8a(&data[PTP_dpd_Sony_GetSet]); 953 unk2 = dtoh8a(&data[PTP_dpd_Sony_Unknown]); 954 ptp_debug (params, "prop 0x%04x, datatype 0x%04x, unk1 %d unk2 %d", dpd->DevicePropertyCode, dpd->DataType, unk1, unk2); 955 #endif 956 dpd->GetSet=1; 957 958 dpd->FormFlag=PTP_DPFF_None; 959 960 *poffset = PTP_dpd_Sony_FactoryDefaultValue; 961 ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 962 if (!ret) goto outofmemory; 963 if ((dpd->DataType == PTP_DTC_STR) && (*poffset == dpdlen)) 964 return 1; 965 ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->CurrentValue, dpd->DataType); 966 if (!ret) goto outofmemory; 967 968 /* if offset==0 then Data Type format is not supported by this 969 code or the Data Type is a string (with two empty strings as 970 values). In both cases Form Flag should be set to 0x00 and FORM is 971 not present. */ 972 973 if (*poffset==PTP_dpd_Sony_FactoryDefaultValue) 974 return 1; 975 976 dpd->FormFlag=dtoh8a(&data[*poffset]); 977 *poffset+=sizeof(uint8_t); 978 979 switch (dpd->FormFlag) { 980 case PTP_DPFF_Range: 981 ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 982 if (!ret) goto outofmemory; 983 ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 984 if (!ret) goto outofmemory; 985 ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 986 if (!ret) goto outofmemory; 987 break; 988 case PTP_DPFF_Enumeration: { 989 int i; 990 #define N dpd->FORM.Enum.NumberOfValues 991 N = dtoh16a(&data[*poffset]); 992 *poffset+=sizeof(uint16_t); 993 dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 994 if (!dpd->FORM.Enum.SupportedValue) 995 goto outofmemory; 996 997 memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 998 for (i=0;i<N;i++) { 999 ret = ptp_unpack_DPV (params, data, poffset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 1000 1001 /* Slightly different handling here. The HP PhotoSmart 120 1002 * specifies an enumeration with N in wrong endian 1003 * 00 01 instead of 01 00, so we count the enum just until the 1004 * the end of the packet. 1005 */ 1006 if (!ret) { 1007 if (!i) 1008 goto outofmemory; 1009 dpd->FORM.Enum.NumberOfValues = i; 1010 break; 1011 } 1012 } 1013 } 1014 } 1015 #undef N 1016 return 1; 1017 outofmemory: 1018 ptp_free_devicepropdesc(dpd); 1019 return 0; 1020 } 1021 1022 static inline void 1023 duplicate_PropertyValue (const PTPPropertyValue *src, PTPPropertyValue *dst, uint16_t type) { 1024 if (type == PTP_DTC_STR) { 1025 if (src->str) 1026 dst->str = strdup(src->str); 1027 else 1028 dst->str = NULL; 1029 return; 1030 } 1031 1032 if (type & PTP_DTC_ARRAY_MASK) { 1033 unsigned int i; 1034 1035 dst->a.count = src->a.count; 1036 dst->a.v = malloc (sizeof(src->a.v[0])*src->a.count); 1037 for (i=0;i<src->a.count;i++) 1038 duplicate_PropertyValue (&src->a.v[i], &dst->a.v[i], type & ~PTP_DTC_ARRAY_MASK); 1039 return; 1040 } 1041 switch (type & ~PTP_DTC_ARRAY_MASK) { 1042 case PTP_DTC_INT8: dst->i8 = src->i8; break; 1043 case PTP_DTC_UINT8: dst->u8 = src->u8; break; 1044 case PTP_DTC_INT16: dst->i16 = src->i16; break; 1045 case PTP_DTC_UINT16: dst->u16 = src->u16; break; 1046 case PTP_DTC_INT32: dst->i32 = src->i32; break; 1047 case PTP_DTC_UINT32: dst->u32 = src->u32; break; 1048 case PTP_DTC_UINT64: dst->u64 = src->u64; break; 1049 case PTP_DTC_INT64: dst->i64 = src->i64; break; 1050 #if 0 1051 case PTP_DTC_INT128: dst->i128 = src->i128; break; 1052 case PTP_DTC_UINT128: dst->u128 = src->u128; break; 1053 #endif 1054 default: break; 1055 } 1056 return; 1057 } 1058 1059 static inline void 1060 duplicate_DevicePropDesc(const PTPDevicePropDesc *src, PTPDevicePropDesc *dst) { 1061 int i; 1062 1063 dst->DevicePropertyCode = src->DevicePropertyCode; 1064 dst->DataType = src->DataType; 1065 dst->GetSet = src->GetSet; 1066 1067 duplicate_PropertyValue (&src->FactoryDefaultValue, &dst->FactoryDefaultValue, src->DataType); 1068 duplicate_PropertyValue (&src->CurrentValue, &dst->CurrentValue, src->DataType); 1069 1070 dst->FormFlag = src->FormFlag; 1071 switch (src->FormFlag) { 1072 case PTP_DPFF_Range: 1073 duplicate_PropertyValue (&src->FORM.Range.MinimumValue, &dst->FORM.Range.MinimumValue, src->DataType); 1074 duplicate_PropertyValue (&src->FORM.Range.MaximumValue, &dst->FORM.Range.MaximumValue, src->DataType); 1075 duplicate_PropertyValue (&src->FORM.Range.StepSize, &dst->FORM.Range.StepSize, src->DataType); 1076 break; 1077 case PTP_DPFF_Enumeration: 1078 dst->FORM.Enum.NumberOfValues = src->FORM.Enum.NumberOfValues; 1079 dst->FORM.Enum.SupportedValue = malloc (sizeof(dst->FORM.Enum.SupportedValue[0])*src->FORM.Enum.NumberOfValues); 1080 for (i = 0; i<src->FORM.Enum.NumberOfValues ; i++) 1081 duplicate_PropertyValue (&src->FORM.Enum.SupportedValue[i], &dst->FORM.Enum.SupportedValue[i], src->DataType); 1082 break; 1083 case PTP_DPFF_None: 1084 break; 1085 } 1086 } 1087 1088 #define PTP_opd_ObjectPropertyCode 0 1089 #define PTP_opd_DataType 2 1090 #define PTP_opd_GetSet 4 1091 #define PTP_opd_FactoryDefaultValue 5 1092 1093 static inline int 1094 ptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 1095 { 1096 unsigned int offset=0, ret; 1097 1098 memset (opd, 0, sizeof(*opd)); 1099 opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 1100 opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 1101 opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 1102 1103 offset = PTP_opd_FactoryDefaultValue; 1104 ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 1105 if (!ret) goto outofmemory; 1106 1107 opd->GroupCode=dtoh32a(&data[offset]); 1108 offset+=sizeof(uint32_t); 1109 1110 opd->FormFlag=dtoh8a(&data[offset]); 1111 offset+=sizeof(uint8_t); 1112 1113 switch (opd->FormFlag) { 1114 case PTP_OPFF_Range: 1115 ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 1116 if (!ret) goto outofmemory; 1117 ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 1118 if (!ret) goto outofmemory; 1119 ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 1120 if (!ret) goto outofmemory; 1121 break; 1122 case PTP_OPFF_Enumeration: { 1123 unsigned int i; 1124 #define N opd->FORM.Enum.NumberOfValues 1125 N = dtoh16a(&data[offset]); 1126 offset+=sizeof(uint16_t); 1127 opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 1128 if (!opd->FORM.Enum.SupportedValue) 1129 goto outofmemory; 1130 1131 memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 1132 for (i=0;i<N;i++) { 1133 ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 1134 1135 /* Slightly different handling here. The HP PhotoSmart 120 1136 * specifies an enumeration with N in wrong endian 1137 * 00 01 instead of 01 00, so we count the enum just until the 1138 * the end of the packet. 1139 */ 1140 if (!ret) { 1141 if (!i) 1142 goto outofmemory; 1143 opd->FORM.Enum.NumberOfValues = i; 1144 break; 1145 } 1146 } 1147 #undef N 1148 } 1149 } 1150 return 1; 1151 outofmemory: 1152 ptp_free_objectpropdesc(opd); 1153 return 0; 1154 } 1155 1156 1157 static inline uint32_t 1158 ptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 1159 { 1160 unsigned char* dpv=NULL; 1161 uint32_t size=0; 1162 unsigned int i; 1163 1164 switch (datatype) { 1165 case PTP_DTC_INT8: 1166 size=sizeof(int8_t); 1167 dpv=malloc(size); 1168 htod8a(dpv,value->i8); 1169 break; 1170 case PTP_DTC_UINT8: 1171 size=sizeof(uint8_t); 1172 dpv=malloc(size); 1173 htod8a(dpv,value->u8); 1174 break; 1175 case PTP_DTC_INT16: 1176 size=sizeof(int16_t); 1177 dpv=malloc(size); 1178 htod16a(dpv,value->i16); 1179 break; 1180 case PTP_DTC_UINT16: 1181 size=sizeof(uint16_t); 1182 dpv=malloc(size); 1183 htod16a(dpv,value->u16); 1184 break; 1185 case PTP_DTC_INT32: 1186 size=sizeof(int32_t); 1187 dpv=malloc(size); 1188 htod32a(dpv,value->i32); 1189 break; 1190 case PTP_DTC_UINT32: 1191 size=sizeof(uint32_t); 1192 dpv=malloc(size); 1193 htod32a(dpv,value->u32); 1194 break; 1195 case PTP_DTC_INT64: 1196 size=sizeof(int64_t); 1197 dpv=malloc(size); 1198 htod64a(dpv,value->i64); 1199 break; 1200 case PTP_DTC_UINT64: 1201 size=sizeof(uint64_t); 1202 dpv=malloc(size); 1203 htod64a(dpv,value->u64); 1204 break; 1205 case PTP_DTC_AUINT8: 1206 size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 1207 dpv=malloc(size); 1208 htod32a(dpv,value->a.count); 1209 for (i=0;i<value->a.count;i++) 1210 htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 1211 break; 1212 case PTP_DTC_AINT8: 1213 size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 1214 dpv=malloc(size); 1215 htod32a(dpv,value->a.count); 1216 for (i=0;i<value->a.count;i++) 1217 htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 1218 break; 1219 case PTP_DTC_AUINT16: 1220 size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 1221 dpv=malloc(size); 1222 htod32a(dpv,value->a.count); 1223 for (i=0;i<value->a.count;i++) 1224 htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 1225 break; 1226 case PTP_DTC_AINT16: 1227 size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 1228 dpv=malloc(size); 1229 htod32a(dpv,value->a.count); 1230 for (i=0;i<value->a.count;i++) 1231 htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 1232 break; 1233 case PTP_DTC_AUINT32: 1234 size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 1235 dpv=malloc(size); 1236 htod32a(dpv,value->a.count); 1237 for (i=0;i<value->a.count;i++) 1238 htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 1239 break; 1240 case PTP_DTC_AINT32: 1241 size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 1242 dpv=malloc(size); 1243 htod32a(dpv,value->a.count); 1244 for (i=0;i<value->a.count;i++) 1245 htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 1246 break; 1247 case PTP_DTC_AUINT64: 1248 size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 1249 dpv=malloc(size); 1250 htod32a(dpv,value->a.count); 1251 for (i=0;i<value->a.count;i++) 1252 htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 1253 break; 1254 case PTP_DTC_AINT64: 1255 size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 1256 dpv=malloc(size); 1257 htod32a(dpv,value->a.count); 1258 for (i=0;i<value->a.count;i++) 1259 htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 1260 break; 1261 /* XXX: other int types are unimplemented */ 1262 case PTP_DTC_STR: { 1263 dpv=ptp_get_packed_stringcopy(params, value->str, &size); 1264 break; 1265 } 1266 } 1267 *dpvptr=dpv; 1268 return size; 1269 } 1270 1271 #define MAX_MTP_PROPS 127 1272 static inline uint32_t 1273 ptp_pack_OPL (PTPParams *params, MTPProperties *props, int nrofprops, unsigned char** opldataptr) 1274 { 1275 unsigned char* opldata; 1276 MTPProperties *propitr; 1277 unsigned char *packedprops[MAX_MTP_PROPS]; 1278 uint32_t packedpropslens[MAX_MTP_PROPS]; 1279 uint32_t packedobjecthandles[MAX_MTP_PROPS]; 1280 uint16_t packedpropsids[MAX_MTP_PROPS]; 1281 uint16_t packedpropstypes[MAX_MTP_PROPS]; 1282 uint32_t totalsize = 0; 1283 uint32_t bufp = 0; 1284 uint32_t noitems = 0; 1285 uint32_t i; 1286 1287 totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 1288 propitr = props; 1289 while (nrofprops-- && noitems < MAX_MTP_PROPS) { 1290 /* Object Handle */ 1291 packedobjecthandles[noitems]=propitr->ObjectHandle; 1292 totalsize += sizeof(uint32_t); /* Object ID */ 1293 /* Metadata type */ 1294 packedpropsids[noitems]=propitr->property; 1295 totalsize += sizeof(uint16_t); 1296 /* Data type */ 1297 packedpropstypes[noitems]= propitr->datatype; 1298 totalsize += sizeof(uint16_t); 1299 /* Add each property to be sent. */ 1300 packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 1301 totalsize += packedpropslens[noitems]; 1302 noitems ++; 1303 propitr ++; 1304 } 1305 1306 /* Allocate memory for the packed property list */ 1307 opldata = malloc(totalsize); 1308 1309 htod32a(&opldata[bufp],noitems); 1310 bufp += 4; 1311 1312 /* Copy into a nice packed list */ 1313 for (i = 0; i < noitems; i++) { 1314 /* Object ID */ 1315 htod32a(&opldata[bufp],packedobjecthandles[i]); 1316 bufp += sizeof(uint32_t); 1317 htod16a(&opldata[bufp],packedpropsids[i]); 1318 bufp += sizeof(uint16_t); 1319 htod16a(&opldata[bufp],packedpropstypes[i]); 1320 bufp += sizeof(uint16_t); 1321 /* The copy the actual property */ 1322 memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 1323 bufp += packedpropslens[i]; 1324 free(packedprops[i]); 1325 } 1326 *opldataptr = opldata; 1327 return totalsize; 1328 } 1329 1330 static int 1331 _compare_func(const void* x, const void *y) { 1332 const MTPProperties *px = x; 1333 const MTPProperties *py = y; 1334 1335 return px->ObjectHandle - py->ObjectHandle; 1336 } 1337 1338 static inline int 1339 ptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) 1340 { 1341 uint32_t prop_count = dtoh32a(data); 1342 MTPProperties *props = NULL; 1343 unsigned int offset = 0, i; 1344 1345 *pprops = NULL; 1346 if (prop_count == 0) 1347 return 0; 1348 if (prop_count >= INT_MAX/sizeof(MTPProperties)) { 1349 ptp_debug (params ,"prop_count %d is too large", prop_count); 1350 return 0; 1351 } 1352 ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); 1353 data += sizeof(uint32_t); 1354 len -= sizeof(uint32_t); 1355 props = malloc(prop_count * sizeof(MTPProperties)); 1356 if (!props) return 0; 1357 for (i = 0; i < prop_count; i++) { 1358 if (len <= 0) { 1359 ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); 1360 ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL"); 1361 ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i); 1362 qsort (props, i, sizeof(MTPProperties),_compare_func); 1363 *pprops = props; 1364 return i; 1365 } 1366 props[i].ObjectHandle = dtoh32a(data); 1367 data += sizeof(uint32_t); 1368 len -= sizeof(uint32_t); 1369 1370 props[i].property = dtoh16a(data); 1371 data += sizeof(uint16_t); 1372 len -= sizeof(uint16_t); 1373 1374 props[i].datatype = dtoh16a(data); 1375 data += sizeof(uint16_t); 1376 len -= sizeof(uint16_t); 1377 1378 offset = 0; 1379 if (!ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype)) { 1380 ptp_debug (params ,"unpacking DPV of property %d encountered insufficient buffer. attack?", i); 1381 qsort (props, i, sizeof(MTPProperties),_compare_func); 1382 *pprops = props; 1383 return i; 1384 } 1385 data += offset; 1386 len -= offset; 1387 } 1388 qsort (props, prop_count, sizeof(MTPProperties),_compare_func); 1389 *pprops = props; 1390 return prop_count; 1391 } 1392 1393 /* 1394 PTP USB Event container unpack 1395 Copyright (c) 2003 Nikolai Kopanygin 1396 */ 1397 1398 #define PTP_ec_Length 0 1399 #define PTP_ec_Type 4 1400 #define PTP_ec_Code 6 1401 #define PTP_ec_TransId 8 1402 #define PTP_ec_Param1 12 1403 #define PTP_ec_Param2 16 1404 #define PTP_ec_Param3 20 1405 1406 static inline void 1407 ptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len) 1408 { 1409 unsigned int length; 1410 int type; 1411 1412 if (data==NULL) 1413 return; 1414 memset(ec,0,sizeof(*ec)); 1415 1416 length=dtoh32a(&data[PTP_ec_Length]); 1417 if (length > len) { 1418 ptp_debug (params, "length %d in container, but data only %d bytes?!", length, len); 1419 return; 1420 } 1421 type = dtoh16a(&data[PTP_ec_Type]); 1422 1423 ec->Code=dtoh16a(&data[PTP_ec_Code]); 1424 ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); 1425 1426 if (type!=PTP_USB_CONTAINER_EVENT) { 1427 ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); 1428 return; 1429 } 1430 if (length>=(PTP_ec_Param1+4)) { 1431 ec->Param1=dtoh32a(&data[PTP_ec_Param1]); 1432 ec->Nparam=1; 1433 } 1434 if (length>=(PTP_ec_Param2+4)) { 1435 ec->Param2=dtoh32a(&data[PTP_ec_Param2]); 1436 ec->Nparam=2; 1437 } 1438 if (length>=(PTP_ec_Param3+4)) { 1439 ec->Param3=dtoh32a(&data[PTP_ec_Param3]); 1440 ec->Nparam=3; 1441 } 1442 } 1443 1444 /* 1445 PTP Canon Folder Entry unpack 1446 Copyright (c) 2003 Nikolai Kopanygin 1447 */ 1448 #define PTP_cfe_ObjectHandle 0 1449 #define PTP_cfe_ObjectFormatCode 4 1450 #define PTP_cfe_Flags 6 1451 #define PTP_cfe_ObjectSize 7 1452 #define PTP_cfe_Time 11 1453 #define PTP_cfe_Filename 15 1454 1455 static inline void 1456 ptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1457 { 1458 int i; 1459 if (data==NULL) 1460 return; 1461 fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 1462 fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 1463 fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 1464 fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 1465 fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 1466 for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1467 fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 1468 } 1469 1470 /* 1471 PTP Canon EOS Folder Entry unpack 1472 0: 00 00 08 a0 objectid 1473 4: 01 00 02 00 storageid 1474 8: 01 30 00 00 ofc 1475 12: 01 00 1476 14: 00 00 1477 16: 11 00 00 00 1478 20: 00 00 00 00 1479 24: 00 00 00 80 1480 28: 00 00 08 a0 1481 32: 4d 49 53 43-00 00 00 00 00 00 00 00 name 1482 00 00 00 00 1483 84 bc 74 46 objectime 1484 1485 1486 (normal PTP GetObjectInfo) 1487 ObjectInfo for 'IMG_0199.JPG': 1488 Object ID: 0x92740c72 1489 StorageID: 0x00020001 1490 ObjectFormat: 0x3801 1491 ProtectionStatus: 0x0000 1492 ObjectCompressedSize: 2217241 1493 ThumbFormat: 0x3808 1494 ThumbCompressedSize: 5122 1495 ThumbPixWidth: 160 1496 ThumbPixHeight: 120 1497 ImagePixWidth: 4000 1498 ImagePixHeight: 3000 1499 ImageBitDepth: 24 1500 ParentObject: 0x92740000 1501 AssociationType: 0x0000 1502 AssociationDesc: 0x00000000 1503 SequenceNumber: 0x00000000 1504 ModificationDate: 0x4d985ff0 1505 CaptureDate: 0x4d985ff0 1506 1507 0010 38 00 00 00 Size of this entry 1508 0014 72 0c 74 92 OID 1509 0018 01 00 02 00 StorageID 1510 001c 01 38 00 00 OFC 1511 0020 00 00 00 00 ?? 1512 0024 21 00 00 00 flags (4 bytes? 1 byte?) 1513 0028 19 d5 21 00 Size 1514 002c 00 00 74 92 ? 1515 0030 70 0c 74 92 OID 1516 0034 49 4d 47 5f-30 31 39 39 2e 4a 50 47 IMG_0199.JPG 1517 0040 00 00 00 00 1518 0044 10 7c 98 4d Time 1519 1520 1521 */ 1522 #define PTP_cefe_ObjectHandle 0 1523 #define PTP_cefe_StorageID 4 1524 #define PTP_cefe_ObjectFormatCode 8 1525 #define PTP_cefe_Flags 16 1526 #define PTP_cefe_ObjectSize 20 1527 #define PTP_cefe_Filename 32 1528 #define PTP_cefe_Time 48 1529 1530 static inline void 1531 ptp_unpack_Canon_EOS_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 1532 { 1533 int i; 1534 1535 fe->ObjectHandle=dtoh32a(&data[PTP_cefe_ObjectHandle]); 1536 fe->ObjectFormatCode=dtoh16a(&data[PTP_cefe_ObjectFormatCode]); 1537 fe->Flags=dtoh8a(&data[PTP_cefe_Flags]); 1538 fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cefe_ObjectSize]); 1539 fe->Time=(time_t)dtoh32a(&data[PTP_cefe_Time]); 1540 for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 1541 fe->Filename[i]=(char)data[PTP_cefe_Filename+i]; 1542 } 1543 1544 1545 static inline uint16_t 1546 ptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data ) 1547 { 1548 /* 1549 EOS ImageFormat entries (of at least the 5DM2 and the 400D) look like this: 1550 uint32: number of entries / generated files (1 or 2) 1551 uint32: size of this entry in bytes (most likely allways 0x10) 1552 uint32: image type (1 == JPG, 6 == RAW) 1553 uint32: image size (0 == Large, 1 == Medium, 2 == Small, 0xe == S1, 0xf == S2, 0x10 == S3) 1554 uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW) 1555 If the number of entries is 2 the last 4 uint32 repeat. 1556 1557 example: 1558 0: 0x 1 1559 1: 0x 10 1560 2: 0x 6 1561 3: 0x 1 1562 4: 0x 4 1563 1564 The idea is to simply 'condense' these values to just one uint16 to be able to conveniently 1565 use the available enumeration facilities (look-up table). The image size and compression 1566 values fully describe the image format. Hence we generate a uint16 with the four nibles set 1567 as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression. 1568 The above example would result in the value 0x1400. 1569 1570 The EOS 5D Mark III (and possibly other high-end EOS as well) added the extra fancy S1, S2 1571 and S3 JPEG options. S1 replaces the old Small. -1 the S1/S2/S3 to prevent the 0x10 overflow. 1572 */ 1573 1574 const unsigned char* d = *data; 1575 uint32_t n = dtoh32a( d ); 1576 uint32_t l, s1, c1, s2 = 0, c2 = 0; 1577 1578 if (n != 1 && n !=2) { 1579 ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n); 1580 return 0; 1581 } 1582 1583 l = dtoh32a( d+=4 ); 1584 if (l != 0x10) { 1585 ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 1586 return 0; 1587 } 1588 1589 d+=4; /* skip type */ 1590 s1 = dtoh32a( d+=4 ); 1591 c1 = dtoh32a( d+=4 ); 1592 1593 if (n == 2) { 1594 l = dtoh32a( d+=4 ); 1595 if (l != 0x10) { 1596 ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 1597 return 0; 1598 } 1599 d+=4; /* skip type */ 1600 s2 = dtoh32a( d+=4 ); 1601 c2 = dtoh32a( d+=4 ); 1602 } 1603 1604 *data = (unsigned char*) d+4; 1605 1606 /* deal with S1/S2/S3 JPEG sizes, see above. */ 1607 if( s1 >= 0xe ) 1608 s1--; 1609 if( s2 >= 0xe ) 1610 s2--; 1611 1612 return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0); 1613 } 1614 1615 static inline uint32_t 1616 ptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value) 1617 { 1618 uint32_t n = (value & 0xFF) ? 2 : 1; 1619 uint32_t s = 4 + 0x10 * n; 1620 1621 if( !data ) 1622 return s; 1623 1624 #define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X) 1625 1626 htod32a(data+=0, n); 1627 htod32a(data+=4, 0x10); 1628 htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1); 1629 htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF)); 1630 htod32a(data+=4, (value >> 8) & 0xF); 1631 1632 if (n==2) { 1633 htod32a(data+=4, 0x10); 1634 htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1); 1635 htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF)); 1636 htod32a(data+=4, (value >> 0) & 0xF); 1637 } 1638 1639 #undef PACK_5DM3_SMALL_JPEG_SIZE 1640 1641 return s; 1642 } 1643 1644 /* 00: 32 bit size 1645 * 04: 16 bit subsize 1646 * 08: 16 bit version (?) 1647 * 0c: 16 bit focus_points_in_struct 1648 * 10: 16 bit focus_points_in_use 1649 * 14: variable arrays: 1650 * 16 bit sizex, 16 bit sizey 1651 * 16 bit othersizex, 16 bit othersizey 1652 * 16 bit array height[focus_points_in_struct] 1653 * 16 bit array width[focus_points_in_struct] 1654 * 16 bit array offsetheight[focus_points_in_struct] middle is 0 1655 * 16 bit array offsetwidth[focus_points_in_struct] middle is ? 1656 * bitfield of selected focus points, starting with 0 [size focus_points_in_struct in bits] 1657 * unknown stuff , likely which are active 1658 * 16 bit 0xffff 1659 * 1660 * size=NxN,size2=NxN,points={NxNxNxN,NxNxNxN,...},selected={0,1,2} 1661 */ 1662 static inline char* 1663 ptp_unpack_EOS_FocusInfoEx (PTPParams* params, unsigned char** data, uint32_t datasize ) 1664 { 1665 uint32_t size = dtoh32a( *data ); 1666 uint32_t halfsize = dtoh16a( (*data) + 4); 1667 uint32_t version = dtoh16a( (*data) + 6); 1668 uint32_t focus_points_in_struct = dtoh16a( (*data) + 8); 1669 uint32_t focus_points_in_use = dtoh16a( (*data) + 10); 1670 uint32_t sizeX = dtoh16a( (*data) + 12); 1671 uint32_t sizeY = dtoh16a( (*data) + 14); 1672 uint32_t size2X = dtoh16a( (*data) + 16); 1673 uint32_t size2Y = dtoh16a( (*data) + 18); 1674 uint32_t i; 1675 uint32_t maxlen; 1676 char *str, *p; 1677 1678 if ((size >= datasize) || (size < 20)) 1679 return strdup("bad size 1"); 1680 /* every focuspoint gets 4 (16 bit number possible "-" sign and a x) and a ,*/ 1681 /* inital things around lets say 100 chars at most. 1682 * FIXME: check selected when we decode it 1683 */ 1684 if (size < focus_points_in_struct*8) { 1685 ptp_error(params, "focus_points_in_struct %d is too large vs size %d", focus_points_in_struct, size); 1686 return strdup("bad size 2"); 1687 } 1688 if (focus_points_in_use > focus_points_in_struct) { 1689 ptp_error(params, "focus_points_in_use %d is larger than focus_points_in_struct %d", focus_points_in_use, focus_points_in_struct); 1690 return strdup("bad size 3"); 1691 } 1692 1693 maxlen = focus_points_in_use*32 + 100 + (size - focus_points_in_struct*8)*2; 1694 if (halfsize != size-4) { 1695 ptp_error(params, "halfsize %d is not expected %d", halfsize, size-4); 1696 return strdup("bad size 4"); 1697 } 1698 if (20 + focus_points_in_struct*8 + (focus_points_in_struct+7)/8 > size) { 1699 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); 1700 return strdup("bad size 5"); 1701 } 1702 #if 0 1703 ptp_debug(params,"d1d3 content:"); 1704 for (i=0;i<size;i+=2) 1705 ptp_debug(params,"%d: %02x %02x", i, (*data)[i], (*data)[i+1]); 1706 #endif 1707 ptp_debug(params,"d1d3 version %d", version); 1708 ptp_debug(params,"d1d3 size %d", size); 1709 ptp_debug(params,"d1d3 focus points in struct %d, in use %d", focus_points_in_struct, focus_points_in_use); 1710 1711 str = (char*)malloc( maxlen ); 1712 if (!str) 1713 return NULL; 1714 p = str; 1715 1716 p += sprintf(p,"eosversion=%d,size=%dx%d,size2=%dx%d,points={", version, sizeX, sizeY, size2X, size2Y); 1717 for (i=0;i<focus_points_in_use;i++) { 1718 int16_t x = dtoh16a((*data) + focus_points_in_struct*4 + 20 + 2*i); 1719 int16_t y = dtoh16a((*data) + focus_points_in_struct*6 + 20 + 2*i); 1720 int16_t w = dtoh16a((*data) + focus_points_in_struct*2 + 20 + 2*i); 1721 int16_t h = dtoh16a((*data) + focus_points_in_struct*0 + 20 + 2*i); 1722 1723 p += sprintf(p,"{%d,%d,%d,%d}",x,y,w,h); 1724 1725 if (i<focus_points_in_use-1) 1726 p += sprintf(p,","); 1727 } 1728 p += sprintf(p,"},select={"); 1729 for (i=0;i<focus_points_in_use;i++) { 1730 if ((1<<(i%8)) & ((*data)[focus_points_in_struct*8+20+i/8])) 1731 p+=sprintf(p,"%d,", i); 1732 } 1733 1734 p += sprintf(p,"},unknown={"); 1735 for (i=focus_points_in_struct*8+(focus_points_in_struct+7)/8+20;i<size;i++) { 1736 if ((p-str) > maxlen - 4) 1737 break; 1738 p+=sprintf(p,"%02x", (*data)[i]); 1739 } 1740 p += sprintf(p,"}"); 1741 return str; 1742 } 1743 1744 1745 static inline char* 1746 ptp_unpack_EOS_CustomFuncEx (PTPParams* params, unsigned char** data ) 1747 { 1748 uint32_t s = dtoh32a( *data ); 1749 uint32_t n = s/4, i; 1750 char *str, *p; 1751 1752 if (s > 1024) { 1753 ptp_debug (params, "customfuncex data is larger than 1k / %d... unexpected?", s); 1754 return strdup("bad length"); 1755 } 1756 str = (char*)malloc( s*2+s/4+1 ); /* n is size in uint32, maximum %x len is 8 chars and \0*/ 1757 if (!str) 1758 return strdup("malloc failed"); 1759 1760 p = str; 1761 for (i=0; i < n; ++i) 1762 p += sprintf(p, "%x,", dtoh32a( *data + 4*i )); 1763 return str; 1764 } 1765 1766 static inline uint32_t 1767 ptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str) 1768 { 1769 uint32_t s = strtoul(str, NULL, 16); 1770 uint32_t n = s/4, i, v; 1771 1772 if (!data) 1773 return s; 1774 1775 for (i=0; i<n; i++) 1776 { 1777 v = strtoul(str, &str, 16); 1778 str++; /* skip the ',' delimiter */ 1779 htod32a(data + i*4, v); 1780 } 1781 1782 return s; 1783 } 1784 1785 /* 1786 PTP EOS Changes Entry unpack 1787 */ 1788 #define PTP_ece_Size 0 1789 #define PTP_ece_Type 4 1790 1791 #define PTP_ece_Prop_Subtype 8 /* only for properties */ 1792 #define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 1793 #define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 1794 #define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 1795 #define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 1796 1797 /* for PTP_EC_CANON_EOS_RequestObjectTransfer */ 1798 #define PTP_ece_OI_ObjectID 8 1799 #define PTP_ece_OI_OFC 0x0c 1800 #define PTP_ece_OI_Size 0x14 1801 #define PTP_ece_OI_Name 0x1c 1802 1803 /* for PTP_EC_CANON_EOS_ObjectAddedEx */ 1804 #define PTP_ece_OA_ObjectID 8 1805 #define PTP_ece_OA_StorageID 0x0c 1806 #define PTP_ece_OA_OFC 0x10 1807 #define PTP_ece_OA_Size 0x1c 1808 #define PTP_ece_OA_Parent 0x20 1809 #define PTP_ece_OA_Name 0x28 1810 1811 #define PTP_ece2_OA_ObjectID 8 /* OK */ 1812 #define PTP_ece2_OA_StorageID 0x0c /* OK */ 1813 #define PTP_ece2_OA_OFC 0x10 /* OK */ 1814 #define PTP_ece2_OA_Size 0x1c /* OK, might be 64 bit now? */ 1815 #define PTP_ece2_OA_Parent 0x24 1816 #define PTP_ece2_OA_2ndOID 0x28 1817 #define PTP_ece2_OA_Name 0x2c /* OK */ 1818 1819 /* for PTP_EC_CANON_EOS_ObjectAddedNew */ 1820 #define PTP_ece_OAN_OFC 0x0c 1821 #define PTP_ece_OAN_Size 0x14 1822 1823 static PTPDevicePropDesc* 1824 _lookup_or_allocate_canon_prop(PTPParams *params, uint16_t proptype) 1825 { 1826 unsigned int j; 1827 1828 for (j=0;j<params->nrofcanon_props;j++) 1829 if (params->canon_props[j].proptype == proptype) 1830 break; 1831 if (j<params->nrofcanon_props) 1832 return ¶ms->canon_props[j].dpd; 1833 1834 if (j) 1835 params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 1836 else 1837 params->canon_props = malloc(sizeof(params->canon_props[0])); 1838 params->canon_props[j].proptype = proptype; 1839 params->canon_props[j].size = 0; 1840 params->canon_props[j].data = NULL; 1841 memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 1842 params->canon_props[j].dpd.GetSet = 1; 1843 params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 1844 params->nrofcanon_props = j+1; 1845 return ¶ms->canon_props[j].dpd; 1846 } 1847 1848 1849 static inline int 1850 ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **pce) 1851 { 1852 int i = 0, entries = 0; 1853 unsigned char *curdata = data; 1854 PTPCanon_changes_entry *ce; 1855 1856 if (data==NULL) 1857 return 0; 1858 while (curdata - data + 8 < datasize) { 1859 uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1860 uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1861 1862 if (size > datasize) { 1863 ptp_debug (params, "size %d is larger than datasize %d", size, datasize); 1864 break; 1865 } 1866 if (size < 8) { 1867 ptp_debug (params, "size %d is smaller than 8.", size); 1868 break; 1869 } 1870 if ((size == 8) && (type == 0)) 1871 break; 1872 if ((curdata - data) + size >= datasize) { 1873 ptp_debug (params, "canon eos event decoder ran over supplied data, skipping entries"); 1874 break; 1875 } 1876 if (type == PTP_EC_CANON_EOS_OLCInfoChanged) { 1877 unsigned int j; 1878 1879 entries++; 1880 if (size >= 12+2) { 1881 for (j=0;j<31;j++) 1882 if (dtoh16a(curdata+12) & (1<<j)) 1883 entries++; 1884 } 1885 } 1886 curdata += size; 1887 entries++; 1888 } 1889 ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1)); 1890 if (!ce) return 0; 1891 1892 curdata = data; 1893 while (curdata - data + 8 < datasize) { 1894 uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 1895 uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 1896 1897 if (size > datasize) { 1898 ptp_debug (params, "size %d is larger than datasize %d", size, datasize); 1899 break; 1900 } 1901 if (size < 8) { 1902 ptp_debug (params, "size %d is smaller than 8", size); 1903 break; 1904 } 1905 1906 if ((size == 8) && (type == 0)) 1907 break; 1908 1909 if ((curdata - data) + size >= datasize) { 1910 ptp_debug (params, "canon eos event decoder ran over supplied data, skipping entries"); 1911 break; 1912 } 1913 1914 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 1915 ce[i].u.info = NULL; 1916 switch (type) { 1917 case PTP_EC_CANON_EOS_ObjectAddedEx: 1918 if (size < PTP_ece_OA_Name+1) { 1919 ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_OA_Name+1); 1920 break; 1921 } 1922 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1923 ce[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OA_ObjectID]); 1924 ce[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece_OA_StorageID]); 1925 ce[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece_OA_Parent]); 1926 ce[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OA_OFC]); 1927 ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]); 1928 ce[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OA_Name])); 1929 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); 1930 break; 1931 case PTP_EC_CANON_EOS_ObjectAddedUnknown: /* FIXME: review if the data used is correct */ 1932 if (size < PTP_ece2_OA_Name+1) { 1933 ptp_debug (params, "size %d is smaller than %d", size, PTP_ece2_OA_Name+1); 1934 break; 1935 } 1936 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 1937 ce[i].u.object.oid = dtoh32a(&curdata[PTP_ece2_OA_ObjectID]); 1938 ce[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece2_OA_StorageID]); 1939 ce[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece2_OA_Parent]); 1940 ce[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece2_OA_OFC]); 1941 ce[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece2_OA_Size]); /* FIXME: might be 64bit now */ 1942 ce[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece2_OA_Name])); 1943 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); 1944 break; 1945 case PTP_EC_CANON_EOS_RequestObjectTransfer: 1946 case PTP_EC_CANON_EOS_RequestObjectTransferNew: /* FIXME: confirm */ 1947 if (size < PTP_ece_OI_Name+1) { 1948 ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_OI_Name+1); 1949 break; 1950 } 1951 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER; 1952 ce[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 1953 ce[i].u.object.oi.StorageID = 0; /* use as marker */ 1954 ce[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 1955 ce[i].u.object.oi.ParentObject = 0; /* check, but use as marker */ 1956 ce[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 1957 ce[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 1958 1959 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); 1960 break; 1961 case PTP_EC_CANON_EOS_AvailListChanged: { /* property desc */ 1962 uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 1963 uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 1964 uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 1965 unsigned char *xdata = &curdata[PTP_ece_Prop_Desc_Data]; 1966 unsigned int j; 1967 PTPDevicePropDesc *dpd; 1968 1969 if (size < PTP_ece_Prop_Desc_Data) { 1970 ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_Prop_Desc_Data); 1971 break; 1972 } 1973 1974 ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype); 1975 for (j=0;j<params->nrofcanon_props;j++) 1976 if (params->canon_props[j].proptype == proptype) 1977 break; 1978 if (j==params->nrofcanon_props) { 1979 ptp_debug (params, "event %d: propdesc %x, default value not found.", i, proptype); 1980 break; 1981 } 1982 dpd = ¶ms->canon_props[j].dpd; 1983 /* 1 - uint16 ? 1984 * 3 - uint16 1985 * 7 - string? 1986 */ 1987 if (propxtype != 3) { 1988 ptp_debug (params, "event %d: propxtype is %x for %04x, unhandled, size %d", i, propxtype, proptype, size); 1989 for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++) 1990 ptp_debug (params, " %d: %02x", j, xdata[j]); 1991 break; 1992 } 1993 if (! propxcnt) 1994 break; 1995 if (propxcnt >= 2<<16) /* buggy or exploit */ 1996 break; 1997 1998 ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.", 1999 i, propxtype, proptype, dpd->DataType, propxcnt); 2000 dpd->FormFlag = PTP_DPFF_Enumeration; 2001 dpd->FORM.Enum.NumberOfValues = propxcnt; 2002 free (dpd->FORM.Enum.SupportedValue); 2003 dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 2004 2005 switch (proptype) { 2006 case PTP_DPC_CANON_EOS_ImageFormat: 2007 case PTP_DPC_CANON_EOS_ImageFormatCF: 2008 case PTP_DPC_CANON_EOS_ImageFormatSD: 2009 case PTP_DPC_CANON_EOS_ImageFormatExtHD: 2010 /* special handling of ImageFormat properties */ 2011 for (j=0;j<propxcnt;j++) { 2012 dpd->FORM.Enum.SupportedValue[j].u16 = 2013 ptp_unpack_EOS_ImageFormat( params, &xdata ); 2014 ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16); 2015 } 2016 break; 2017 default: 2018 /* 'normal' enumerated types */ 2019 switch (dpd->DataType) { 2020 #define XX( TYPE, CONV )\ 2021 if (sizeof(dpd->FORM.Enum.SupportedValue[j].TYPE)*propxcnt + PTP_ece_Prop_Desc_Data > size) { \ 2022 ptp_debug (params, "size %d does not match needed %d", sizeof(dpd->FORM.Enum.SupportedValue[j].TYPE)*propxcnt + PTP_ece_Prop_Desc_Data, size); \ 2023 break; \ 2024 } \ 2025 for (j=0;j<propxcnt;j++) { \ 2026 dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(xdata); \ 2027 ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(xdata)); \ 2028 xdata += 4; /* might only be for propxtype 3 */ \ 2029 } \ 2030 break; 2031 2032 case PTP_DTC_INT16: XX( i16, dtoh16a ); 2033 case PTP_DTC_UINT32: XX( u32, dtoh32a ); 2034 case PTP_DTC_UINT16: XX( u16, dtoh16a ); 2035 case PTP_DTC_UINT8: XX( u8, dtoh8a ); 2036 #undef XX 2037 default: 2038 free (dpd->FORM.Enum.SupportedValue); 2039 dpd->FORM.Enum.SupportedValue = NULL; 2040 dpd->FORM.Enum.NumberOfValues = 0; 2041 ptp_debug (params ,"event %d: data type 0x%04x of %x unhandled, size %d, raw values:", i, dpd->DataType, proptype, dtoh32a(xdata), size); 2042 for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, xdata+=4) /* 4 is good for propxtype 3 */ 2043 ptp_debug (params, " %3d: 0x%8x", j, dtoh32a(xdata)); 2044 break; 2045 } 2046 } 2047 break; 2048 } 2049 case PTP_EC_CANON_EOS_PropValueChanged: 2050 if (size >= 0xc) { /* property info */ 2051 unsigned int j; 2052 uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 2053 unsigned char *xdata = &curdata[PTP_ece_Prop_Val_Data]; 2054 PTPDevicePropDesc *dpd; 2055 2056 if (size < PTP_ece_Prop_Val_Data) { 2057 ptp_debug (params, "size %d is smaller than %d", size, PTP_ece_Prop_Val_Data); 2058 break; 2059 } 2060 ptp_debug (params, "event %d: EOS prop %04x info record, datasize is %d", i, proptype, size-PTP_ece_Prop_Val_Data); 2061 for (j=0;j<params->nrofcanon_props;j++) 2062 if (params->canon_props[j].proptype == proptype) 2063 break; 2064 if (j<params->nrofcanon_props) { 2065 if ( (params->canon_props[j].size != size) || 2066 (memcmp(params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data))) { 2067 params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 2068 params->canon_props[j].size = size; 2069 memcpy (params->canon_props[j].data,xdata,size-PTP_ece_Prop_Val_Data); 2070 } 2071 } else { 2072 if (j) 2073 params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 2074 else 2075 params->canon_props = malloc(sizeof(params->canon_props[0])); 2076 params->canon_props[j].proptype = proptype; 2077 params->canon_props[j].size = size; 2078 params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 2079 memcpy(params->canon_props[j].data, xdata, size-PTP_ece_Prop_Val_Data); 2080 memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 2081 params->canon_props[j].dpd.GetSet = 1; 2082 params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 2083 params->nrofcanon_props = j+1; 2084 } 2085 dpd = ¶ms->canon_props[j].dpd; 2086 2087 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 2088 ce[i].u.propid = proptype; 2089 2090 /* fix GetSet value */ 2091 switch (proptype) { 2092 #define XX(x) case PTP_DPC_CANON_##x: 2093 XX(EOS_FocusMode) 2094 XX(EOS_BatteryPower) 2095 XX(EOS_BatterySelect) 2096 XX(EOS_ModelID) 2097 XX(EOS_PTPExtensionVersion) 2098 XX(EOS_DPOFVersion) 2099 XX(EOS_AvailableShots) 2100 XX(EOS_CurrentStorage) 2101 XX(EOS_CurrentFolder) 2102 XX(EOS_MyMenu) 2103 XX(EOS_MyMenuList) 2104 XX(EOS_HDDirectoryStructure) 2105 XX(EOS_BatteryInfo) 2106 XX(EOS_AdapterInfo) 2107 XX(EOS_LensStatus) 2108 XX(EOS_CardExtension) 2109 XX(EOS_TempStatus) 2110 XX(EOS_ShutterCounter) 2111 XX(EOS_SerialNumber) 2112 XX(EOS_DepthOfFieldPreview) 2113 XX(EOS_EVFRecordStatus) 2114 XX(EOS_LvAfSystem) 2115 XX(EOS_FocusInfoEx) 2116 XX(EOS_DepthOfField) 2117 XX(EOS_Brightness) 2118 XX(EOS_EFComp) 2119 XX(EOS_LensName) 2120 XX(EOS_LensID) 2121 #undef XX 2122 dpd->GetSet = PTP_DPGS_Get; 2123 break; 2124 } 2125 2126 /* set DataType */ 2127 switch (proptype) { 2128 case PTP_DPC_CANON_EOS_CameraTime: 2129 case PTP_DPC_CANON_EOS_UTCTime: 2130 case PTP_DPC_CANON_EOS_Summertime: /* basical the DST flag */ 2131 case PTP_DPC_CANON_EOS_AvailableShots: 2132 case PTP_DPC_CANON_EOS_CaptureDestination: 2133 case PTP_DPC_CANON_EOS_WhiteBalanceXA: 2134 case PTP_DPC_CANON_EOS_WhiteBalanceXB: 2135 case PTP_DPC_CANON_EOS_CurrentStorage: 2136 case PTP_DPC_CANON_EOS_CurrentFolder: 2137 case PTP_DPC_CANON_EOS_ShutterCounter: 2138 case PTP_DPC_CANON_EOS_ModelID: 2139 case PTP_DPC_CANON_EOS_LensID: 2140 case PTP_DPC_CANON_EOS_StroboFiring: 2141 case PTP_DPC_CANON_EOS_AFSelectFocusArea: 2142 case PTP_DPC_CANON_EOS_ContinousAFMode: 2143 case PTP_DPC_CANON_EOS_MirrorUpSetting: 2144 dpd->DataType = PTP_DTC_UINT32; 2145 break; 2146 /* enumeration for AEM is never provided, but is available to set */ 2147 case PTP_DPC_CANON_EOS_AutoExposureMode: 2148 dpd->DataType = PTP_DTC_UINT16; 2149 dpd->FormFlag = PTP_DPFF_Enumeration; 2150 dpd->FORM.Enum.NumberOfValues = 0; 2151 break; 2152 case PTP_DPC_CANON_EOS_Aperture: 2153 case PTP_DPC_CANON_EOS_ShutterSpeed: 2154 case PTP_DPC_CANON_EOS_ISOSpeed: 2155 case PTP_DPC_CANON_EOS_FocusMode: 2156 case PTP_DPC_CANON_EOS_ColorSpace: 2157 case PTP_DPC_CANON_EOS_BatteryPower: 2158 case PTP_DPC_CANON_EOS_BatterySelect: 2159 case PTP_DPC_CANON_EOS_PTPExtensionVersion: 2160 case PTP_DPC_CANON_EOS_DriveMode: 2161 case PTP_DPC_CANON_EOS_AEB: 2162 case PTP_DPC_CANON_EOS_BracketMode: 2163 case PTP_DPC_CANON_EOS_QuickReviewTime: 2164 case PTP_DPC_CANON_EOS_EVFMode: 2165 case PTP_DPC_CANON_EOS_EVFOutputDevice: 2166 case PTP_DPC_CANON_EOS_AutoPowerOff: 2167 case PTP_DPC_CANON_EOS_EVFRecordStatus: 2168 dpd->DataType = PTP_DTC_UINT16; 2169 break; 2170 case PTP_DPC_CANON_EOS_PictureStyle: 2171 case PTP_DPC_CANON_EOS_WhiteBalance: 2172 case PTP_DPC_CANON_EOS_MeteringMode: 2173 case PTP_DPC_CANON_EOS_ExpCompensation: 2174 dpd->DataType = PTP_DTC_UINT8; 2175 break; 2176 case PTP_DPC_CANON_EOS_Owner: 2177 case PTP_DPC_CANON_EOS_Artist: 2178 case PTP_DPC_CANON_EOS_Copyright: 2179 case PTP_DPC_CANON_EOS_SerialNumber: 2180 case PTP_DPC_CANON_EOS_LensName: 2181 dpd->DataType = PTP_DTC_STR; 2182 break; 2183 case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA: 2184 case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB: 2185 dpd->DataType = PTP_DTC_INT16; 2186 break; 2187 /* unknown props, listed from dump.... all 16 bit, but vals might be smaller */ 2188 case PTP_DPC_CANON_EOS_DPOFVersion: 2189 dpd->DataType = PTP_DTC_UINT16; 2190 ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data); 2191 for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 2192 ptp_debug (params, " %d: %02x", j, xdata[j]); 2193 break; 2194 case PTP_DPC_CANON_EOS_CustomFunc1: 2195 case PTP_DPC_CANON_EOS_CustomFunc2: 2196 case PTP_DPC_CANON_EOS_CustomFunc3: 2197 case PTP_DPC_CANON_EOS_CustomFunc4: 2198 case PTP_DPC_CANON_EOS_CustomFunc5: 2199 case PTP_DPC_CANON_EOS_CustomFunc6: 2200 case PTP_DPC_CANON_EOS_CustomFunc7: 2201 case PTP_DPC_CANON_EOS_CustomFunc8: 2202 case PTP_DPC_CANON_EOS_CustomFunc9: 2203 case PTP_DPC_CANON_EOS_CustomFunc10: 2204 case PTP_DPC_CANON_EOS_CustomFunc11: 2205 dpd->DataType = PTP_DTC_UINT8; 2206 ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data); 2207 for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 2208 ptp_debug (params, " %d: %02x", j, xdata[j]); 2209 /* custom func entries look like this on the 400D: '5 0 0 0 ?' = 4 bytes size + 1 byte data */ 2210 xdata += 4; 2211 break; 2212 /* yet unknown 32bit props */ 2213 case PTP_DPC_CANON_EOS_ColorTemperature: 2214 case PTP_DPC_CANON_EOS_WftStatus: 2215 case PTP_DPC_CANON_EOS_LensStatus: 2216 case PTP_DPC_CANON_EOS_CardExtension: 2217 case PTP_DPC_CANON_EOS_TempStatus: 2218 case PTP_DPC_CANON_EOS_PhotoStudioMode: 2219 case PTP_DPC_CANON_EOS_DepthOfFieldPreview: 2220 case PTP_DPC_CANON_EOS_EVFSharpness: 2221 case PTP_DPC_CANON_EOS_EVFWBMode: 2222 case PTP_DPC_CANON_EOS_EVFClickWBCoeffs: 2223 case PTP_DPC_CANON_EOS_EVFColorTemp: 2224 case PTP_DPC_CANON_EOS_ExposureSimMode: 2225 case PTP_DPC_CANON_EOS_LvAfSystem: 2226 case PTP_DPC_CANON_EOS_MovSize: 2227 case PTP_DPC_CANON_EOS_DepthOfField: 2228 case PTP_DPC_CANON_EOS_LvViewTypeSelect: 2229 case PTP_DPC_CANON_EOS_AloMode: 2230 case PTP_DPC_CANON_EOS_Brightness: 2231 dpd->DataType = PTP_DTC_UINT32; 2232 ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data); 2233 if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0) 2234 ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) ); 2235 for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++) 2236 ptp_debug (params, " %d: 0x%8x", j, dtoh32a(xdata+j*4)); 2237 break; 2238 /* ImageFormat properties have to be ignored here, see special handling below */ 2239 case PTP_DPC_CANON_EOS_ImageFormat: 2240 case PTP_DPC_CANON_EOS_ImageFormatCF: 2241 case PTP_DPC_CANON_EOS_ImageFormatSD: 2242 case PTP_DPC_CANON_EOS_ImageFormatExtHD: 2243 case PTP_DPC_CANON_EOS_CustomFuncEx: 2244 case PTP_DPC_CANON_EOS_FocusInfoEx: 2245 break; 2246 default: 2247 ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data); 2248 for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 2249 ptp_debug (params, " %d: %02x", j, xdata[j]); 2250 break; 2251 } 2252 switch (dpd->DataType) { 2253 case PTP_DTC_UINT32: 2254 dpd->FactoryDefaultValue.u32 = dtoh32a(xdata); 2255 dpd->CurrentValue.u32 = dtoh32a(xdata); 2256 ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32); 2257 break; 2258 case PTP_DTC_INT16: 2259 dpd->FactoryDefaultValue.i16 = dtoh16a(xdata); 2260 dpd->CurrentValue.i16 = dtoh16a(xdata); 2261 ptp_debug (params,"event %d: currentvalue of %x is %d", i, proptype, dpd->CurrentValue.i16); 2262 break; 2263 case PTP_DTC_UINT16: 2264 dpd->FactoryDefaultValue.u16 = dtoh16a(xdata); 2265 dpd->CurrentValue.u16 = dtoh16a(xdata); 2266 ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 2267 break; 2268 case PTP_DTC_UINT8: 2269 dpd->FactoryDefaultValue.u8 = dtoh8a(xdata); 2270 dpd->CurrentValue.u8 = dtoh8a(xdata); 2271 ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 2272 break; 2273 case PTP_DTC_INT8: 2274 dpd->FactoryDefaultValue.i8 = dtoh8a(xdata); 2275 dpd->CurrentValue.i8 = dtoh8a(xdata); 2276 ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.i8); 2277 break; 2278 case PTP_DTC_STR: { 2279 #if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ 2280 uint8_t len = 0; 2281 dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 2282 dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 2283 #else 2284 free (dpd->FactoryDefaultValue.str); 2285 dpd->FactoryDefaultValue.str = strdup( (char*)xdata ); 2286 2287 free (dpd->CurrentValue.str); 2288 dpd->CurrentValue.str = strdup( (char*)xdata ); 2289 #endif 2290 ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 2291 break; 2292 } 2293 default: 2294 /* debug is printed in switch above this one */ 2295 break; 2296 } 2297 2298 /* ImageFormat and customFuncEx special handling (WARNING: dont move this in front of the dpd->DataType switch!) */ 2299 switch (proptype) { 2300 case PTP_DPC_CANON_EOS_ImageFormat: 2301 case PTP_DPC_CANON_EOS_ImageFormatCF: 2302 case PTP_DPC_CANON_EOS_ImageFormatSD: 2303 case PTP_DPC_CANON_EOS_ImageFormatExtHD: 2304 dpd->DataType = PTP_DTC_UINT16; 2305 dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &xdata ); 2306 dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16; 2307 ptp_debug (params,"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 2308 break; 2309 case PTP_DPC_CANON_EOS_CustomFuncEx: 2310 dpd->DataType = PTP_DTC_STR; 2311 free (dpd->FactoryDefaultValue.str); 2312 free (dpd->CurrentValue.str); 2313 dpd->FactoryDefaultValue.str = ptp_unpack_EOS_CustomFuncEx( params, &xdata ); 2314 dpd->CurrentValue.str = strdup( (char*)dpd->FactoryDefaultValue.str ); 2315 ptp_debug (params,"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 2316 break; 2317 case PTP_DPC_CANON_EOS_FocusInfoEx: 2318 dpd->DataType = PTP_DTC_STR; 2319 free (dpd->FactoryDefaultValue.str); 2320 free (dpd->CurrentValue.str); 2321 dpd->FactoryDefaultValue.str = ptp_unpack_EOS_FocusInfoEx( params, &xdata, size ); 2322 dpd->CurrentValue.str = strdup( (char*)dpd->FactoryDefaultValue.str ); 2323 ptp_debug (params,"event %d: decoded focus info, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 2324 break; 2325 } 2326 2327 break; 2328 } 2329 /* one more information record handed to us */ 2330 case PTP_EC_CANON_EOS_OLCInfoChanged: { 2331 uint32_t len, curoff; 2332 uint16_t mask,proptype; 2333 PTPDevicePropDesc *dpd; 2334 2335 /* unclear what OLC stands for */ 2336 ptp_debug (params, "event %d: EOS event OLCInfoChanged (size %d)", i, size); 2337 if (size >= 0x8) { /* event info */ 2338 unsigned int k; 2339 for (k=8;k<size;k++) 2340 ptp_debug (params, " %d: %02x", k-8, curdata[k]); 2341 } 2342 len = dtoh32a(curdata+8); 2343 if ((len != size-8) && (len != size-4)) { 2344 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2345 ce[i].u.info = strdup("OLC size unexpected"); 2346 ptp_debug (params, "event %d: OLC unexpected size %d for blob len %d (not -4 nor -8)", i, size, len); 2347 break; 2348 } 2349 mask = dtoh16a(curdata+8+4); 2350 if (size < 14) { 2351 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2352 ce[i].u.info = strdup("OLC size too small"); 2353 ptp_debug (params, "event %d: OLC unexpected size %d", i, size); 2354 break; 2355 } 2356 curoff = 8+4+4; 2357 if (mask & CANON_EOS_OLC_BUTTON) { 2358 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2359 ce[i].u.info = malloc(strlen("Button 1234567")); 2360 sprintf(ce[i].u.info, "Button %d", dtoh16a(curdata+curoff)); 2361 i++; 2362 curoff += 2; 2363 } 2364 2365 if (mask & CANON_EOS_OLC_SHUTTERSPEED) { 2366 /* 6 bytes: 01 01 98 10 00 60 */ 2367 /* this seesm to be the shutter speed record */ 2368 proptype = PTP_DPC_CANON_EOS_ShutterSpeed; 2369 dpd = _lookup_or_allocate_canon_prop(params, proptype); 2370 dpd->CurrentValue.u16 = curdata[curoff+5]; /* just use last byte */ 2371 2372 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 2373 ce[i].u.propid = proptype; 2374 curoff += 6; 2375 i++; 2376 } 2377 if (mask & CANON_EOS_OLC_APERTURE) { 2378 /* 5 bytes: 01 01 5b 30 30 */ 2379 /* this seesm to be the aperture record */ 2380 proptype = PTP_DPC_CANON_EOS_Aperture; 2381 dpd = _lookup_or_allocate_canon_prop(params, proptype); 2382 dpd->CurrentValue.u16 = curdata[curoff+4]; /* just use last byte */ 2383 2384 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 2385 ce[i].u.propid = proptype; 2386 curoff += 5; 2387 i++; 2388 } 2389 if (mask & CANON_EOS_OLC_ISO) { 2390 /* 5 bytes: 01 01 00 78 */ 2391 /* this seesm to be the aperture record */ 2392 proptype = PTP_DPC_CANON_EOS_ISOSpeed; 2393 dpd = _lookup_or_allocate_canon_prop(params, proptype); 2394 dpd->CurrentValue.u16 = curdata[curoff+3]; /* just use last byte */ 2395 2396 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_PROPERTY; 2397 ce[i].u.propid = proptype; 2398 curoff += 4; 2399 i++; 2400 } 2401 if (mask & 0x0010) { 2402 /* mask 0x0010: 4 bytes, 04 00 00 00 observed */ 2403 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2404 ce[i].u.info = malloc(strlen("OLCInfo event 0x0010 content 01234567")+1); 2405 sprintf(ce[i].u.info,"OLCInfo event 0x0010 content %02x%02x%02x%02x", 2406 curdata[curoff], 2407 curdata[curoff+1], 2408 curdata[curoff+2], 2409 curdata[curoff+3] 2410 ); 2411 curoff += 4; 2412 i++; 2413 } 2414 if (mask & 0x0020) { 2415 /* mask 0x0020: 6 bytes, 00 00 00 00 00 00 observed */ 2416 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2417 ce[i].u.info = malloc(strlen("OLCInfo event 0x0020 content 0123456789ab")+1); 2418 sprintf(ce[i].u.info,"OLCInfo event 0x0020 content %02x%02x%02x%02x%02x%02x", 2419 curdata[curoff], 2420 curdata[curoff+1], 2421 curdata[curoff+2], 2422 curdata[curoff+3], 2423 curdata[curoff+4], 2424 curdata[curoff+5] 2425 ); 2426 curoff += 6; 2427 i++; 2428 } 2429 if (mask & 0x0040) { 2430 int value = (signed char)curdata[curoff+2]; 2431 /* mask 0x0040: 7 bytes, 01 01 00 00 00 00 00 observed */ 2432 /* exposure indicator */ 2433 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2434 ce[i].u.info = malloc(strlen("OLCInfo exposure indicator 012345678901234567890123456789abcd")+1); 2435 sprintf(ce[i].u.info,"OLCInfo exposure indicator %d,%d,%d.%d (%02x%02x%02x%02x)", 2436 curdata[curoff], 2437 curdata[curoff+1], 2438 value/10,abs(value)%10, 2439 curdata[curoff+3], 2440 curdata[curoff+4], 2441 curdata[curoff+5], 2442 curdata[curoff+6] 2443 ); 2444 curoff += 7; 2445 i++; 2446 } 2447 if (mask & 0x0080) { 2448 /* mask 0x0080: 4 bytes, 00 00 00 00 observed */ 2449 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2450 ce[i].u.info = malloc(strlen("OLCInfo event 0x0080 content 01234567")+1); 2451 sprintf(ce[i].u.info,"OLCInfo event 0x0080 content %02x%02x%02x%02x", 2452 curdata[curoff], 2453 curdata[curoff+1], 2454 curdata[curoff+2], 2455 curdata[curoff+3] 2456 ); 2457 curoff += 4; 2458 i++; 2459 } 2460 if (mask & 0x0100) { 2461 /* mask 0x0100: 6 bytes, 00 00 00 00 00 00 (before focus) and 00 00 00 00 01 00 (on focus) observed */ 2462 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO; 2463 ce[i].u.info = malloc(strlen("0123456789ab")+1); 2464 sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x", 2465 curdata[curoff], 2466 curdata[curoff+1], 2467 curdata[curoff+2], 2468 curdata[curoff+3], 2469 curdata[curoff+4], 2470 curdata[curoff+5] 2471 ); 2472 curoff += 6; 2473 i++; 2474 } 2475 if (mask & 0x0200) { 2476 /* mask 0x0200: 7 bytes, 00 00 00 00 00 00 00 observed */ 2477 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK; 2478 ce[i].u.info = malloc(strlen("0123456789abcd0123456789abcdef")+1); 2479 sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x%02x", 2480 curdata[curoff], 2481 curdata[curoff+1], 2482 curdata[curoff+2], 2483 curdata[curoff+3], 2484 curdata[curoff+4], 2485 curdata[curoff+5], 2486 curdata[curoff+6] 2487 ); 2488 curoff += 7; 2489 i++; 2490 } 2491 if (mask & 0x0400) { 2492 /* mask 0x0400: 7 bytes, 00 00 00 00 00 00 00 observed */ 2493 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2494 ce[i].u.info = malloc(strlen("OLCInfo event 0x0400 content 0123456789abcd")+1); 2495 sprintf(ce[i].u.info,"OLCInfo event 0x0400 content %02x%02x%02x%02x%02x%02x%02x", 2496 curdata[curoff], 2497 curdata[curoff+1], 2498 curdata[curoff+2], 2499 curdata[curoff+3], 2500 curdata[curoff+4], 2501 curdata[curoff+5], 2502 curdata[curoff+6] 2503 ); 2504 curoff += 7; 2505 i++; 2506 } 2507 if (mask & 0x0800) { 2508 /* mask 0x0800: 8 bytes, 00 00 00 00 00 00 00 00 and 19 01 00 00 00 00 00 00 and others observed */ 2509 /* might be mask of focus points selected */ 2510 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2511 ce[i].u.info = malloc(strlen("OLCInfo event 0x0800 content 0123456789abcdef")+1); 2512 sprintf(ce[i].u.info,"OLCInfo event 0x0800 content %02x%02x%02x%02x%02x%02x%02x%02x", 2513 curdata[curoff], 2514 curdata[curoff+1], 2515 curdata[curoff+2], 2516 curdata[curoff+3], 2517 curdata[curoff+4], 2518 curdata[curoff+5], 2519 curdata[curoff+6], 2520 curdata[curoff+7] 2521 ); 2522 curoff += 8; 2523 i++; 2524 } 2525 if (mask & 0x1000) { 2526 /* mask 0x1000: 1 byte, 00 observed */ 2527 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2528 ce[i].u.info = malloc(strlen("OLCInfo event 0x1000 content 01")+1); 2529 sprintf(ce[i].u.info,"OLCInfo event 0x1000 content %02x", 2530 curdata[curoff] 2531 ); 2532 curoff += 1; 2533 i++; 2534 } 2535 /* handle more masks */ 2536 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2537 ce[i].u.info = malloc(strlen("OLCInfo event mask 0123456789")+1); 2538 sprintf(ce[i].u.info, "OLCInfo event mask=%x", mask); 2539 break; 2540 } 2541 case PTP_EC_CANON_EOS_CameraStatusChanged: 2542 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS; 2543 ce[i].u.status = dtoh32a(curdata+8); 2544 ptp_debug (params, "event %d: EOS event CameraStatusChanged (size %d) = %d", i, size, dtoh32a(curdata+8)); 2545 params->eos_camerastatus = dtoh32a(curdata+8); 2546 break; 2547 case 0: /* end marker */ 2548 if (size == 8) /* no output */ 2549 break; 2550 ptp_debug (params, "event %d: EOS event 0, but size %d", i, size); 2551 break; 2552 case PTP_EC_CANON_EOS_BulbExposureTime: 2553 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2554 ce[i].u.info = malloc(strlen("BulbExposureTime 123456789012345678")); 2555 sprintf (ce[i].u.info, "BulbExposureTime %d", dtoh32a(curdata+8)); 2556 break; 2557 case PTP_EC_CANON_EOS_ObjectRemoved: 2558 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTREMOVED; 2559 ce[i].u.object.oid = dtoh32a(curdata+8); 2560 break; 2561 default: 2562 switch (type) { 2563 #define XX(x) case PTP_EC_CANON_EOS_##x: \ 2564 ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size); \ 2565 ce[i].u.info = malloc(strlen("unhandled EOS event "#x" (size 123456789)")); \ 2566 sprintf (ce[i].u.info, "unhandled EOS event "#x" (size %d)", size); \ 2567 break; 2568 XX(RequestGetEvent) 2569 XX(RequestGetObjectInfoEx) 2570 XX(StorageStatusChanged) 2571 XX(StorageInfoChanged) 2572 XX(ObjectInfoChangedEx) 2573 XX(ObjectContentChanged) 2574 XX(WillSoonShutdown) 2575 XX(ShutdownTimerUpdated) 2576 XX(RequestCancelTransfer) 2577 XX(RequestObjectTransferDT) 2578 XX(RequestCancelTransferDT) 2579 XX(StoreAdded) 2580 XX(StoreRemoved) 2581 XX(BulbExposureTime) 2582 XX(RecordingTime) 2583 XX(RequestObjectTransferTS) 2584 XX(AfResult) 2585 #undef XX 2586 default: 2587 ptp_debug (params, "event %d: unknown EOS event %04x", i, type); 2588 break; 2589 } 2590 if (size >= 0x8) { /* event info */ 2591 unsigned int j; 2592 /*ptp_debug (params, "data=%p, curdata=%p, datsize=%d, size=%d", data, curdata, datasize, size);*/ 2593 for (j=8;j<size;j++) 2594 ptp_debug (params, " %d: %02x", j, curdata[j]); 2595 } 2596 ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 2597 break; 2598 } 2599 curdata += size; 2600 i++; 2601 if (i >= entries) { 2602 ptp_debug (params, "BAD: i %d, entries %d", i, entries); 2603 } 2604 } 2605 if (!i) { 2606 free (ce); 2607 ce = NULL; 2608 } 2609 *pce = ce; 2610 return i; 2611 } 2612 2613 /* 2614 PTP USB Event container unpack for Nikon events. 2615 */ 2616 #define PTP_nikon_ec_Length 0 2617 #define PTP_nikon_ec_Code 2 2618 #define PTP_nikon_ec_Param1 4 2619 #define PTP_nikon_ec_Size 6 2620 static inline void 2621 ptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, unsigned int *cnt) 2622 { 2623 unsigned int i; 2624 2625 *ec = NULL; 2626 if (data == NULL) 2627 return; 2628 if (len < PTP_nikon_ec_Code) 2629 return; 2630 *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 2631 if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) { /* broken cnt? */ 2632 *cnt = 0; 2633 return; 2634 } 2635 if (!*cnt) 2636 return; 2637 2638 *ec = malloc(sizeof(PTPContainer)*(*cnt)); 2639 2640 for (i=0;i<*cnt;i++) { 2641 memset(&(*ec)[i],0,sizeof(PTPContainer)); 2642 (*ec)[i].Code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 2643 (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 2644 (*ec)[i].Nparam = 1; 2645 } 2646 } 2647 2648 2649 static inline uint32_t 2650 ptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 2651 int i, len = 0; 2652 uint8_t retlen; 2653 unsigned char *curdata; 2654 2655 len = 2*(strlen(text->title)+1)+1+ 2656 2*(strlen(text->line[0])+1)+1+ 2657 2*(strlen(text->line[1])+1)+1+ 2658 2*(strlen(text->line[2])+1)+1+ 2659 2*(strlen(text->line[3])+1)+1+ 2660 2*(strlen(text->line[4])+1)+1+ 2661 4*2+2*4+2+4+2+5*4*2; 2662 *data = malloc(len); 2663 if (!*data) return 0; 2664 2665 curdata = *data; 2666 htod16a(curdata,100);curdata+=2; 2667 htod16a(curdata,1);curdata+=2; 2668 htod16a(curdata,0);curdata+=2; 2669 htod16a(curdata,1000);curdata+=2; 2670 2671 htod32a(curdata,0);curdata+=4; 2672 htod32a(curdata,0);curdata+=4; 2673 2674 htod16a(curdata,6);curdata+=2; 2675 htod32a(curdata,0);curdata+=4; 2676 2677 ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 2678 htod16a(curdata,0x10);curdata+=2; 2679 2680 for (i=0;i<5;i++) { 2681 ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 2682 htod16a(curdata,0x10);curdata+=2; 2683 htod16a(curdata,0x01);curdata+=2; 2684 htod16a(curdata,0x02);curdata+=2; 2685 htod16a(curdata,0x06);curdata+=2; 2686 } 2687 return len; 2688 } 2689 2690 #define ptp_canon_dir_version 0x00 2691 #define ptp_canon_dir_ofc 0x02 2692 #define ptp_canon_dir_unk1 0x04 2693 #define ptp_canon_dir_objectid 0x08 2694 #define ptp_canon_dir_parentid 0x0c 2695 #define ptp_canon_dir_previd 0x10 /* in same dir */ 2696 #define ptp_canon_dir_nextid 0x14 /* in same dir */ 2697 #define ptp_canon_dir_nextchild 0x18 /* down one dir */ 2698 #define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 2699 #define ptp_canon_dir_name 0x20 2700 #define ptp_canon_dir_flags 0x2c 2701 #define ptp_canon_dir_size 0x30 2702 #define ptp_canon_dir_unixtime 0x34 2703 #define ptp_canon_dir_year 0x38 2704 #define ptp_canon_dir_month 0x39 2705 #define ptp_canon_dir_mday 0x3a 2706 #define ptp_canon_dir_hour 0x3b 2707 #define ptp_canon_dir_minute 0x3c 2708 #define ptp_canon_dir_second 0x3d 2709 #define ptp_canon_dir_unk2 0x3e 2710 #define ptp_canon_dir_thumbsize 0x40 2711 #define ptp_canon_dir_width 0x44 2712 #define ptp_canon_dir_height 0x48 2713 2714 static inline uint16_t 2715 ptp_unpack_canon_directory ( 2716 PTPParams *params, 2717 unsigned char *dir, 2718 uint32_t cnt, 2719 PTPObjectHandles *handles, 2720 PTPObjectInfo **oinfos, /* size(handles->n) */ 2721 uint32_t **flags /* size(handles->n) */ 2722 ) { 2723 unsigned int i, j, nrofobs = 0, curob = 0; 2724 2725 #define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 2726 for (i=0;i<cnt;i++) 2727 if (ISOBJECT(dir+i*0x4c)) nrofobs++; 2728 handles->n = nrofobs; 2729 handles->Handler = calloc(nrofobs,sizeof(handles->Handler[0])); 2730 if (!handles->Handler) return PTP_RC_GeneralError; 2731 *oinfos = calloc(nrofobs,sizeof((*oinfos)[0])); 2732 if (!*oinfos) return PTP_RC_GeneralError; 2733 *flags = calloc(nrofobs,sizeof((*flags)[0])); 2734 if (!*flags) return PTP_RC_GeneralError; 2735 2736 /* Migrate data into objects ids, handles into 2737 * the object handler array. 2738 */ 2739 curob = 0; 2740 for (i=0;i<cnt;i++) { 2741 unsigned char *cur = dir+i*0x4c; 2742 PTPObjectInfo *oi = (*oinfos)+curob; 2743 2744 if (!ISOBJECT(cur)) 2745 continue; 2746 2747 handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 2748 oi->StorageID = 0xffffffff; 2749 oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 2750 oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 2751 oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 2752 oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 2753 oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 2754 oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 2755 oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 2756 oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 2757 (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 2758 curob++; 2759 } 2760 /* Walk over Storage ID entries and distribute the IDs to 2761 * the parent objects. */ 2762 for (i=0;i<cnt;i++) { 2763 unsigned char *cur = dir+i*0x4c; 2764 uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 2765 2766 if (ISOBJECT(cur)) 2767 continue; 2768 for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 2769 if (j == handles->n) continue; 2770 (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 2771 } 2772 /* Walk over all objects and distribute the storage ids */ 2773 while (1) { 2774 unsigned int changed = 0; 2775 for (i=0;i<cnt;i++) { 2776 unsigned char *cur = dir+i*0x4c; 2777 uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 2778 uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 2779 uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 2780 uint32_t storageid; 2781 2782 if (!ISOBJECT(cur)) 2783 continue; 2784 for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 2785 if (j == handles->n) { 2786 /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 2787 continue; 2788 } 2789 storageid = (*oinfos)[j].StorageID; 2790 if (storageid == 0xffffffff) continue; 2791 if (nextoid != 0xffffffff) { 2792 for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 2793 if (j == handles->n) { 2794 /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 2795 continue; 2796 } 2797 if ((*oinfos)[j].StorageID == 0xffffffff) { 2798 (*oinfos)[j].StorageID = storageid; 2799 changed++; 2800 } 2801 } 2802 if (nextchild != 0xffffffff) { 2803 for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 2804 if (j == handles->n) { 2805 /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 2806 continue; 2807 } 2808 if ((*oinfos)[j].StorageID == 0xffffffff) { 2809 (*oinfos)[j].StorageID = storageid; 2810 changed++; 2811 } 2812 } 2813 } 2814 /* Check if we: 2815 * - changed no entry (nothing more to do) 2816 * - changed all of them at once (usually happens) 2817 * break if we do. 2818 */ 2819 if (!changed || (changed==nrofobs-1)) 2820 break; 2821 } 2822 #undef ISOBJECT 2823 return PTP_RC_OK; 2824 } 2825