13aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* currently this file is included into ptp.c */ 23aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 33aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef HAVE_ICONV 43aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <iconv.h> 53aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 63aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 73aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevextern void 83aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_debug (PTPParams *params, const char *format, ...); 93aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint16_t 113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevhtod16p (PTPParams *params, uint16_t var) 123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var)); 143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevhtod32p (PTPParams *params, uint32_t var) 183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var)); 203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevhtod16ap (PTPParams *params, unsigned char *a, uint16_t val) 243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->byteorder==PTP_DL_LE) 263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htole16a(a,val); 273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htobe16a(a,val); 293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevhtod32ap (PTPParams *params, unsigned char *a, uint32_t val) 333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->byteorder==PTP_DL_LE) 353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htole32a(a,val); 363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htobe32a(a,val); 383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevhtod64ap (PTPParams *params, unsigned char *a, uint64_t val) 423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->byteorder==PTP_DL_LE) 443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htole64a(a,val); 453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htobe64a(a,val); 473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint16_t 503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevdtoh16p (PTPParams *params, uint16_t var) 513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var)); 533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevdtoh32p (PTPParams *params, uint32_t var) 573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var)); 593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint64_t 623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevdtoh64p (PTPParams *params, uint64_t var) 633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?le64toh(var):be64toh(var)); 653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint16_t 683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevdtoh16ap (PTPParams *params, const unsigned char *a) 693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a)); 713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevdtoh32ap (PTPParams *params, const unsigned char *a) 753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a)); 773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint64_t 803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevdtoh64ap (PTPParams *params, const unsigned char *a) 813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a)); 833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod8a(a,x) *(uint8_t*)(a) = x 863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod16a(a,x) htod16ap(params,a,x) 873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod32a(a,x) htod32ap(params,a,x) 883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod64a(a,x) htod64ap(params,a,x) 893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod16(x) htod16p(params,x) 903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod32(x) htod32p(params,x) 913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define htod64(x) htod64p(params,x) 923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh8a(x) (*(uint8_t*)(x)) 943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh16a(a) dtoh16ap(params,a) 953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh32a(a) dtoh32ap(params,a) 963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh64a(a) dtoh64ap(params,a) 973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh16(x) dtoh16p(params,x) 983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh32(x) dtoh32p(params,x) 993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define dtoh64(x) dtoh64p(params,x) 1003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline char* 1033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len) 1043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 1053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t length; 1063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t string[PTP_MAXSTRLEN+1]; 1073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* allow for UTF-8: max of 3 bytes per UCS-2 char, plus final null */ 1083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char loclstr[PTP_MAXSTRLEN*3+1]; 1093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size_t nconv, srclen, destlen; 1103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *src, *dest; 1113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev length = dtoh8a(&data[offset]); /* PTP_MAXSTRLEN == 255, 8 bit len */ 1133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *len = length; 1143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (length == 0) /* nothing to do? */ 1153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return(NULL); 1163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* copy to string[] to ensure correct alignment for iconv(3) */ 1183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy(string, &data[offset+1], length * sizeof(string[0])); 1193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev string[length] = 0x0000U; /* be paranoid! add a terminator. */ 1203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev loclstr[0] = '\0'; 1213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* convert from camera UCS-2 to our locale */ 1233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev src = (char *)string; 1243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev srclen = length * sizeof(string[0]); 1253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dest = loclstr; 1263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev destlen = sizeof(loclstr)-1; 1273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev nconv = (size_t)-1; 1283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef HAVE_ICONV 1293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev nconv = iconv(params->cd_ucs2_to_locale, &src, &srclen, 1303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &dest, &destlen); 1313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 1323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (nconv == (size_t) -1) { /* do it the hard way */ 1333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 1343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* try the old way, in case iconv is broken */ 1353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<length;i++) { 1363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (dtoh16a(&data[offset+1+2*i])>127) 1373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev loclstr[i] = '?'; 1383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 1393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev loclstr[i] = dtoh16a(&data[offset+1+2*i]); 1403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 1413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dest = loclstr+length; 1423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 1433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *dest = '\0'; 1443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev loclstr[sizeof(loclstr)-1] = '\0'; /* be safe? */ 1453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return(strdup(loclstr)); 1463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 1473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline int 1493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevucs2strlen(uint16_t const * const unicstr) 1503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 1513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int length; 1523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Unicode strings are terminated with 2 * 0x00 */ 1543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for(length = 0; unicstr[length] != 0x0000U; length ++); 1553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return length; 1563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 1573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 1603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len) 1613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 1623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int packedlen; 1633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t ucs2str[PTP_MAXSTRLEN+1]; 1643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *ucs2strp = (char *) ucs2str; 1653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size_t convlen = strlen(string); 1663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */ 1683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(ucs2strp, 0, sizeof(ucs2str)); /* XXX: necessary? */ 1693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#ifdef HAVE_ICONV 1703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 1713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size_t nconv; 1723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */ 1733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *stringp = string; 1743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, 1763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &ucs2strp, &convmax); 1773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (nconv == (size_t) -1) 1783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ucs2str[0] = 0x0000U; 1793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 1803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 1813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev { 1823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 1833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<convlen;i++) { 1843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ucs2str[i] = string[i]; 1853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 1863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ucs2str[convlen] = 0; 1873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 1883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 1893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 1903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * XXX: isn't packedlen just ( (uint16_t *)ucs2strp - ucs2str )? 1913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * why do we need ucs2strlen()? 1923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 1933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev packedlen = ucs2strlen(ucs2str); 1943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (packedlen > PTP_MAXSTRLEN-1) { 1953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *len=0; 1963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 1973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 1983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* number of characters including terminating 0 (PTP standard confirmed) */ 2003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(&data[offset],packedlen+1); 2013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy(&data[offset+1], &ucs2str[0], packedlen * sizeof(ucs2str[0])); 2023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&data[offset+packedlen*2+1], 0x0000); /* terminate 0 */ 2033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* The returned length is in number of characters */ 2053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *len = (uint8_t) packedlen+1; 2063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline unsigned char * 2093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size) 2103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t packed[PTP_MAXSTRLEN*2+3], len; 2123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size_t plen; 2133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *retcopy = NULL; 2143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (string == NULL) 2163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_pack_string(params, "", (unsigned char*) packed, 0, &len); 2173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 2183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_pack_string(params, string, (unsigned char*) packed, 0, &len); 2193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* returned length is in characters, then one byte for string length */ 2213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev plen = len*2 + 1; 2223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev retcopy = malloc(plen); 2243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!retcopy) { 2253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *packed_size = 0; 2263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return NULL; 2273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy(retcopy, packed, plen); 2293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *packed_size = plen; 2303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return (retcopy); 2313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 2343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array) 2353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t n, i=0; 2373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev n=dtoh32a(&data[offset]); 2393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *array = malloc (n*sizeof(uint32_t)); 2403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (n>i) { 2413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]); 2423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev i++; 2433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return n; 2453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 2483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ) 2493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i=0; 2513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *data = malloc ((arraylen+1)*sizeof(uint32_t)); 2533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&(*data)[0],arraylen); 2543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<arraylen;i++) 2553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]); 2563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return (arraylen+1)*sizeof(uint32_t); 2573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 2603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array) 2613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t n, i=0; 2633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev n=dtoh32a(&data[offset]); 2653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *array = malloc (n*sizeof(uint16_t)); 2663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (n>i) { 2673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]); 2683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev i++; 2693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 2703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return n; 2713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 2723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* DeviceInfo pack/unpack */ 2743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_di_StandardVersion 0 2763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_di_VendorExtensionID 2 2773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_di_VendorExtensionVersion 6 2783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_di_VendorExtensionDesc 8 2793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_di_FunctionalMode 8 2803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_di_OperationsSupported 10 2813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 2833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen) 2843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 2853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t len; 2863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned int totallen; 2873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!data) return; 2893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (datalen < 12) return; 2903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]); 2913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->VendorExtensionID = 2923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dtoh32a(&data[PTP_di_VendorExtensionID]); 2933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->VendorExtensionVersion = 2943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dtoh16a(&data[PTP_di_VendorExtensionVersion]); 2953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->VendorExtensionDesc = 2963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_unpack_string(params, data, 2973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_VendorExtensionDesc, &len); 2983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen=len*2+1; 2993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->FunctionalMode = 3003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dtoh16a(&data[PTP_di_FunctionalMode+totallen]); 3013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data, 3023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &di->OperationsSupported); 3043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 3053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data, 3063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &di->EventsSupported); 3083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 3093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->DevicePropertiesSupported_len = 3103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_unpack_uint16_t_array(params, data, 3113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &di->DevicePropertiesSupported); 3133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t); 3143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data, 3153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &di->CaptureFormats); 3173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 3183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data, 3193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &di->ImageFormats); 3213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 3223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->Manufacturer = ptp_unpack_string(params, data, 3233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &len); 3253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen+=len*2+1; 3263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->Model = ptp_unpack_string(params, data, 3273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &len); 3293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen+=len*2+1; 3303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->DeviceVersion = ptp_unpack_string(params, data, 3313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &len); 3333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen+=len*2+1; 3343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->SerialNumber = ptp_unpack_string(params, data, 3353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_di_OperationsSupported+totallen, 3363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &len); 3373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void 3403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_free_DI (PTPDeviceInfo *di) { 3413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->SerialNumber) free (di->SerialNumber); 3423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->DeviceVersion) free (di->DeviceVersion); 3433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->Model) free (di->Model); 3443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->Manufacturer) free (di->Manufacturer); 3453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->ImageFormats) free (di->ImageFormats); 3463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->CaptureFormats) free (di->CaptureFormats); 3473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->VendorExtensionDesc) free (di->VendorExtensionDesc); 3483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->OperationsSupported) free (di->OperationsSupported); 3493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->EventsSupported) free (di->EventsSupported); 3503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (di->DevicePropertiesSupported) free (di->DevicePropertiesSupported); 3513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* EOS Device Info unpack */ 3543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 3553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_EOS_DI (PTPParams *params, unsigned char* data, PTPCanonEOSDeviceInfo *di, unsigned int datalen) 3563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 3573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int totallen = 4; 3583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (datalen < 8) return; 3593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* uint32_t struct len - ignore */ 3613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->EventsSupported_len = ptp_unpack_uint32_t_array(params, data, 3623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen, &di->EventsSupported); 3633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!di->EventsSupported) return; 3643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen += di->EventsSupported_len*sizeof(uint32_t)+4; 3653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (totallen >= datalen) return; 3663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->DevicePropertiesSupported_len = ptp_unpack_uint32_t_array(params, data, 3683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen, &di->DevicePropertiesSupported); 3693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!di->DevicePropertiesSupported) return; 3703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen += di->DevicePropertiesSupported_len*sizeof(uint32_t)+4; 3713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (totallen >= datalen) return; 3723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev di->unk_len = ptp_unpack_uint32_t_array(params, data, 3743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen, &di->unk); 3753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!di->unk) return; 3763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totallen += di->unk_len*sizeof(uint32_t)+4; 3773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 3783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* ObjectHandles array pack/unpack */ 3813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oh 0 3833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 3853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len) 3863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 3873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (len) { 3883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler); 3893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 3903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oh->n = 0; 3913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oh->Handler = NULL; 3923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 3933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 3943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* StoreIDs array pack/unpack */ 3963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_sids 0 3983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 4003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len) 4013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 4023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids, 4033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &sids->Storage); 4043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 4053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* StorageInfo pack/unpack */ 4073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_StorageType 0 4093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_FilesystemType 2 4103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_AccessCapability 4 4113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_MaxCapability 6 4123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_FreeSpaceInBytes 14 4133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_FreeSpaceInImages 22 4143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_si_StorageDescription 26 4153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 4173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len) 4183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 4193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t storagedescriptionlen; 4203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->StorageType=dtoh16a(&data[PTP_si_StorageType]); 4223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]); 4233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]); 4243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]); 4253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]); 4263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]); 4273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->StorageDescription=ptp_unpack_string(params, data, 4283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_si_StorageDescription, &storagedescriptionlen); 4293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev si->VolumeLabel=ptp_unpack_string(params, data, 4303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_si_StorageDescription+storagedescriptionlen*2+1, 4313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev &storagedescriptionlen); 4323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 4333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* ObjectInfo pack/unpack */ 4353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_StorageID 0 4373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ObjectFormat 4 4383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ProtectionStatus 6 4393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ObjectCompressedSize 8 4403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ThumbFormat 12 4413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ThumbCompressedSize 14 4423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ThumbPixWidth 18 4433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ThumbPixHeight 22 4443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ImagePixWidth 26 4453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ImagePixHeight 30 4463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ImageBitDepth 34 4473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_ParentObject 38 4483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_AssociationType 42 4493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_AssociationDesc 44 4503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_SequenceNumber 48 4513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_filenamelen 52 4523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_Filename 53 4533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* the max length assuming zero length dates. We have need 3 */ 4553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* bytes for these. */ 4563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_oi_MaxLen PTP_oi_Filename+(PTP_MAXSTRLEN+1)*2+3 4573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 4593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr) 4603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 4613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char* oidata; 4623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t filenamelen; 4633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t capturedatelen=0; 4643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* let's allocate some memory first; correct assuming zero length dates */ 4653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oidata=malloc(PTP_oi_MaxLen); 4663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* the caller should free it after use! */ 4673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#if 0 4683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *capture_date="20020101T010101"; /* XXX Fake date */ 4693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 4703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset (oidata, 0, PTP_oi_MaxLen); 4713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_StorageID],oi->StorageID); 4723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat); 4733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus); 4743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize); 4753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat); 4763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize); 4773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth); 4783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight); 4793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth); 4803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight); 4813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth); 4823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject); 4833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType); 4843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc); 4853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber); 4863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen); 4883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 4893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev filenamelen=(uint8_t)strlen(oi->Filename); 4903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1); 4913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) { 4923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev req->data[PTP_oi_Filename+i*2]=oi->Filename[i]; 4933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 4943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 4953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 4963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *XXX Fake date. 4973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * for example Kodak sets Capture date on the basis of EXIF data. 4983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Spec says that this field is from perspective of Initiator. 4993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 5003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#if 0 /* seems now we don't need any data packed in OI dataset... for now ;)*/ 5013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev capturedatelen=strlen(capture_date); 5023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(&data[PTP_oi_Filename+(filenamelen+1)*2], 5033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev capturedatelen+1); 5043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 5053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data[PTP_oi_Filename+(i+filenamelen+1)*2+1]=capture_date[i]; 5063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 5073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(&data[PTP_oi_Filename+(filenamelen+capturedatelen+2)*2+1], 5083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev capturedatelen+1); 5093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<capturedatelen && i< PTP_MAXSTRLEN; i++) { 5103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data[PTP_oi_Filename+(i+filenamelen+capturedatelen+2)*2+2]= 5113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev capture_date[i]; 5123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 5133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 5143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* XXX this function should return dataset length */ 5153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *oidataptr=oidata; 5173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3); 5183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 5193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic time_t 5213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_PTPTIME (const char *str) { 5223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char ptpdate[40]; 5233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char tmp[5]; 5243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int ptpdatelen; 5253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev struct tm tm; 5263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!str) 5283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 5293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptpdatelen = strlen(str); 5303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptpdatelen >= sizeof (ptpdate)) { 5313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*ptp_debug (params ,"datelen is larger then size of buffer", ptpdatelen, (int)sizeof(ptpdate));*/ 5323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 5333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 5343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strcpy (ptpdate, str); 5353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ptpdatelen<15) { 5363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*ptp_debug (params ,"datelen is less than 15 (%d)", ptpdatelen);*/ 5373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 5383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 5393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(&tm,0,sizeof(tm)); 5413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy (tmp, ptpdate, 4); 5423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[4] = 0; 5433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_year=atoi (tmp) - 1900; 5443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy (tmp, ptpdate + 4, 2); 5453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[2] = 0; 5463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_mon = atoi (tmp) - 1; 5473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy (tmp, ptpdate + 6, 2); 5483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[2] = 0; 5493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_mday = atoi (tmp); 5503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy (tmp, ptpdate + 9, 2); 5513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[2] = 0; 5523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_hour = atoi (tmp); 5533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy (tmp, ptpdate + 11, 2); 5543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[2] = 0; 5553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_min = atoi (tmp); 5563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev strncpy (tmp, ptpdate + 13, 2); 5573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tmp[2] = 0; 5583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_sec = atoi (tmp); 5593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev tm.tm_isdst = -1; 5613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return mktime (&tm); 5633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 5643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 5663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_OI (PTPParams *params, unsigned char* data, PTPObjectInfo *oi, unsigned int len) 5673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 5683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t filenamelen; 5693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t capturedatelen; 5703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev char *capture_date; 5713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->StorageID=dtoh32a(&data[PTP_oi_StorageID]); 5733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]); 5743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]); 5753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]); 5763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]); 5773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]); 5783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]); 5793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ThumbPixHeight=dtoh32a(&data[PTP_oi_ThumbPixHeight]); 5803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ImagePixWidth=dtoh32a(&data[PTP_oi_ImagePixWidth]); 5813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ImagePixHeight=dtoh32a(&data[PTP_oi_ImagePixHeight]); 5823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ImageBitDepth=dtoh32a(&data[PTP_oi_ImageBitDepth]); 5833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ParentObject=dtoh32a(&data[PTP_oi_ParentObject]); 5843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]); 5853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]); 5863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]); 5873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen); 5883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev capture_date = ptp_unpack_string(params, data, 5903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_oi_filenamelen+filenamelen*2+1, &capturedatelen); 5913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* subset of ISO 8601, without '.s' tenths of second and 5923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * time zone 5933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 5943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->CaptureDate = ptp_unpack_PTPTIME(capture_date); 5953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(capture_date); 5963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 5973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* now the modification date ... */ 5983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev capture_date = ptp_unpack_string(params, data, 5993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP_oi_filenamelen+filenamelen*2 6003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev +capturedatelen*2+2,&capturedatelen); 6013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ModificationDate = ptp_unpack_PTPTIME(capture_date); 6023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(capture_date); 6033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 6043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* Custom Type Value Assignement (without Length) macro frequently used below */ 6063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define CTVAL(target,func) { \ 6073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (total - *offset < sizeof(target)) \ 6083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; \ 6093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev target = func(&data[*offset]); \ 6103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *offset += sizeof(target); \ 6113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 6123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define RARR(val,member,func) { \ 6143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int n,j; \ 6153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (total - *offset < sizeof(uint32_t)) \ 6163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; \ 6173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev n = dtoh32a (&data[*offset]); \ 6183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *offset += sizeof(uint32_t); \ 6193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev \ 6203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev val->a.count = n; \ 6213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev val->a.v = malloc(sizeof(val->a.v[0])*n); \ 6223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!val->a.v) return 0; \ 6233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<n;j++) \ 6243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(val->a.v[j].member, func); \ 6253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 6263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline int 6283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_DPV ( 6293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params, unsigned char* data, int *offset, int total, 6303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPPropertyValue* value, uint16_t datatype 6313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev) { 6323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (datatype) { 6333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT8: 6343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->i8,dtoh8a); 6353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 6373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->u8,dtoh8a); 6383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: 6403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->i16,dtoh16a); 6413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 6433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->u16,dtoh16a); 6443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT32: 6463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->i32,dtoh32a); 6473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 6493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->u32,dtoh32a); 6503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT64: 6523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->i64,dtoh64a); 6533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT64: 6553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev CTVAL(value->u64,dtoh64a); 6563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT128: 6593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *offset += 16; 6603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*fprintf(stderr,"unhandled unpack of uint128n");*/ 6613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT128: 6633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *offset += 16; 6643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*fprintf(stderr,"unhandled unpack of int128n");*/ 6653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 6693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT8: 6703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,i8,dtoh8a); 6713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT8: 6733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,u8,dtoh8a); 6743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT16: 6763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,u16,dtoh16a); 6773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT16: 6793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,i16,dtoh16a); 6803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT32: 6823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,u32,dtoh32a); 6833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT32: 6853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,i32,dtoh32a); 6863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT64: 6883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,u64,dtoh64a); 6893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT64: 6913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev RARR(value,i64,dtoh64a); 6923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 6933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* XXX: other int types are unimplemented */ 6943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* XXX: other int arrays are unimplemented also */ 6953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_STR: { 6963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t len; 6973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* XXX: max size */ 6983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev value->str = ptp_unpack_string(params,data,*offset,&len); 6993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *offset += len*2+1; 7003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!value->str) 7013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 7023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 7033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 7053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 7063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 7083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 7093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* Device Property pack/unpack */ 7113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_dpd_DevicePropertyCode 0 7133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_dpd_DataType 2 7143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_dpd_GetSet 4 7153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_dpd_FactoryDefaultValue 5 7163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline int 7183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_DPD (PTPParams *params, unsigned char* data, PTPDevicePropDesc *dpd, unsigned int dpdlen) 7193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 7203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int offset=0, ret; 7213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset (dpd, 0, sizeof(*dpd)); 7233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DevicePropertyCode=dtoh16a(&data[PTP_dpd_DevicePropertyCode]); 7243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType=dtoh16a(&data[PTP_dpd_DataType]); 7253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->GetSet=dtoh8a(&data[PTP_dpd_GetSet]); 7263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FormFlag=PTP_DPFF_None; 7273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset = PTP_dpd_FactoryDefaultValue; 7293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FactoryDefaultValue, dpd->DataType); 7303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 7313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((dpd->DataType == PTP_DTC_STR) && (offset == dpdlen)) 7323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 7333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->CurrentValue, dpd->DataType); 7343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 7353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* if offset==0 then Data Type format is not supported by this 7373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev code or the Data Type is a string (with two empty strings as 7383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev values). In both cases Form Flag should be set to 0x00 and FORM is 7393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev not present. */ 7403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (offset==PTP_dpd_FactoryDefaultValue) 7423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 7433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FormFlag=dtoh8a(&data[offset]); 7453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset+=sizeof(uint8_t); 7463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (dpd->FormFlag) { 7483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPFF_Range: 7493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MinimumValue, dpd->DataType); 7503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 7513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.MaximumValue, dpd->DataType); 7523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 7533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Range.StepSize, dpd->DataType); 7543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 7553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 7563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPFF_Enumeration: { 7573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 7583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define N dpd->FORM.Enum.NumberOfValues 7593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev N = dtoh16a(&data[offset]); 7603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset+=sizeof(uint16_t); 7613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FORM.Enum.SupportedValue = malloc(N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 7623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!dpd->FORM.Enum.SupportedValue) 7633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev goto outofmemory; 7643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset (dpd->FORM.Enum.SupportedValue,0 , N*sizeof(dpd->FORM.Enum.SupportedValue[0])); 7663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<N;i++) { 7673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, dpdlen, &dpd->FORM.Enum.SupportedValue[i], dpd->DataType); 7683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Slightly different handling here. The HP PhotoSmart 120 7703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * specifies an enumeration with N in wrong endian 7713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 01 instead of 01 00, so we count the enum just until the 7723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the end of the packet. 7733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 7743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) { 7753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!i) 7763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev goto outofmemory; 7773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FORM.Enum.NumberOfValues = i; 7783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 7793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 7833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#undef N 7843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 7853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevoutofmemory: 7863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_devicepropdesc(dpd); 7873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 7883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 7893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* (MTP) Object Property pack/unpack */ 7913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_opd_ObjectPropertyCode 0 7923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_opd_DataType 2 7933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_opd_GetSet 4 7943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_opd_FactoryDefaultValue 5 7953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 7963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline int 7973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_OPD (PTPParams *params, unsigned char* data, PTPObjectPropDesc *opd, unsigned int opdlen) 7983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 7993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int offset=0, ret; 8003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset (opd, 0, sizeof(*opd)); 8023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->ObjectPropertyCode=dtoh16a(&data[PTP_opd_ObjectPropertyCode]); 8033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->DataType=dtoh16a(&data[PTP_opd_DataType]); 8043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->GetSet=dtoh8a(&data[PTP_opd_GetSet]); 8053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset = PTP_opd_FactoryDefaultValue; 8073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType); 8083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 8093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->GroupCode=dtoh32a(&data[offset]); 8113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset+=sizeof(uint32_t); 8123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->FormFlag=dtoh8a(&data[offset]); 8143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset+=sizeof(uint8_t); 8153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (opd->FormFlag) { 8173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Range: 8183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType); 8193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 8203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType); 8213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 8223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType); 8233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) goto outofmemory; 8243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_OPFF_Enumeration: { 8263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 8273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define N opd->FORM.Enum.NumberOfValues 8283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev N = dtoh16a(&data[offset]); 8293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset+=sizeof(uint16_t); 8303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->FORM.Enum.SupportedValue = malloc(N*sizeof(opd->FORM.Enum.SupportedValue[0])); 8313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!opd->FORM.Enum.SupportedValue) 8323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev goto outofmemory; 8333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset (opd->FORM.Enum.SupportedValue,0 , N*sizeof(opd->FORM.Enum.SupportedValue[0])); 8353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<N;i++) { 8363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ret = ptp_unpack_DPV (params, data, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType); 8373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Slightly different handling here. The HP PhotoSmart 120 8393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * specifies an enumeration with N in wrong endian 8403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 00 01 instead of 01 00, so we count the enum just until the 8413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the end of the packet. 8423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 8433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ret) { 8443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!i) 8453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev goto outofmemory; 8463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opd->FORM.Enum.NumberOfValues = i; 8473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#undef N 8513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 8533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 1; 8543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevoutofmemory: 8553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_free_objectpropdesc(opd); 8563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 8573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 8583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 8613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_DPV (PTPParams *params, PTPPropertyValue* value, unsigned char** dpvptr, uint16_t datatype) 8623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 8633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char* dpv=NULL; 8643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t size=0; 8653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 8663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 8673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (datatype) { 8683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT8: 8693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(int8_t); 8703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 8713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(dpv,value->i8); 8723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 8743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint8_t); 8753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 8763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(dpv,value->u8); 8773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: 8793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(int16_t); 8803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 8813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(dpv,value->i16); 8823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 8843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint16_t); 8853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 8863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(dpv,value->u16); 8873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT32: 8893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(int32_t); 8903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 8913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->i32); 8923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 8943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t); 8953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 8963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->u32); 8973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 8983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT64: 8993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(int64_t); 9003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod64a(dpv,value->i64); 9023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT64: 9043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint64_t); 9053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod64a(dpv,value->u64); 9073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT8: 9093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(uint8_t); 9103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(&dpv[sizeof(uint32_t)+i*sizeof(uint8_t)],value->a.v[i].u8); 9143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT8: 9163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(int8_t); 9173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod8a(&dpv[sizeof(uint32_t)+i*sizeof(int8_t)],value->a.v[i].i8); 9213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT16: 9233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(uint16_t); 9243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&dpv[sizeof(uint32_t)+i*sizeof(uint16_t)],value->a.v[i].u16); 9283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT16: 9303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(int16_t); 9313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&dpv[sizeof(uint32_t)+i*sizeof(int16_t)],value->a.v[i].i16); 9353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT32: 9373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); 9383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&dpv[sizeof(uint32_t)+i*sizeof(uint32_t)],value->a.v[i].u32); 9423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT32: 9443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); 9453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&dpv[sizeof(uint32_t)+i*sizeof(int32_t)],value->a.v[i].i32); 9493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AUINT64: 9513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(uint64_t); 9523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod64a(&dpv[sizeof(uint32_t)+i*sizeof(uint64_t)],value->a.v[i].u64); 9563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_AINT64: 9583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev size=sizeof(uint32_t)+value->a.count*sizeof(int64_t); 9593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=malloc(size); 9603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(dpv,value->a.count); 9613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<value->a.count;i++) 9623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod64a(&dpv[sizeof(uint32_t)+i*sizeof(int64_t)],value->a.v[i].i64); 9633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* XXX: other int types are unimplemented */ 9653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_STR: { 9663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpv=ptp_get_packed_stringcopy(params, value->str, &size); 9673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 9683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 9693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 9703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *dpvptr=dpv; 9713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return size; 9723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 9733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 9743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define MAX_MTP_PROPS 127 9753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 9763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_OPL (PTPParams *params, MTPProperties *props, int nrofprops, unsigned char** opldataptr) 9773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 9783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char* opldata; 9793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *propitr; 9803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *packedprops[MAX_MTP_PROPS]; 9813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t packedpropslens[MAX_MTP_PROPS]; 9823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t packedobjecthandles[MAX_MTP_PROPS]; 9833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t packedpropsids[MAX_MTP_PROPS]; 9843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint16_t packedpropstypes[MAX_MTP_PROPS]; 9853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t totalsize = 0; 9863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t bufp = 0; 9873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t noitems = 0; 9883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t i; 9893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 9903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ 9913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propitr = props; 9923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (nrofprops-- && noitems < MAX_MTP_PROPS) { 9933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Object Handle */ 9943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev packedobjecthandles[noitems]=propitr->ObjectHandle; 9953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totalsize += sizeof(uint32_t); /* Object ID */ 9963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Metadata type */ 9973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev packedpropsids[noitems]=propitr->property; 9983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totalsize += sizeof(uint16_t); 9993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Data type */ 10003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev packedpropstypes[noitems]= propitr->datatype; 10013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totalsize += sizeof(uint16_t); 10023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Add each property to be sent. */ 10033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); 10043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev totalsize += packedpropslens[noitems]; 10053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev noitems ++; 10063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev propitr ++; 10073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Allocate memory for the packed property list */ 10103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev opldata = malloc(totalsize); 10113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&opldata[bufp],noitems); 10133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bufp += 4; 10143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Copy into a nice packed list */ 10163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < noitems; i++) { 10173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Object ID */ 10183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(&opldata[bufp],packedobjecthandles[i]); 10193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bufp += sizeof(uint32_t); 10203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&opldata[bufp],packedpropsids[i]); 10213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bufp += sizeof(uint16_t); 10223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(&opldata[bufp],packedpropstypes[i]); 10233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bufp += sizeof(uint16_t); 10243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* The copy the actual property */ 10253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); 10263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev bufp += packedpropslens[i]; 10273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev free(packedprops[i]); 10283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *opldataptr = opldata; 10303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return totalsize; 10313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 10323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic int 10343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev_compare_func(const void* x, const void *y) { 10353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const MTPProperties *px = x; 10363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const MTPProperties *py = y; 10373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return px->ObjectHandle - py->ObjectHandle; 10393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 10403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline int 10423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPProperties **pprops, unsigned int len) 10433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 10443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t prop_count = dtoh32a(data); 10453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev MTPProperties *props = NULL; 10463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int offset = 0, i; 10473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (prop_count == 0) { 10493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *pprops = NULL; 10503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 10513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params ,"Unpacking MTP OPL, size %d (prop_count %d)", len, prop_count); 10533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += sizeof(uint32_t); 10543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev len -= sizeof(uint32_t); 10553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev props = malloc(prop_count * sizeof(MTPProperties)); 10563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!props) return 0; 10573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i = 0; i < prop_count; i++) { 10583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (len <= 0) { 10593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params ,"short MTP Object Property List at property %d (of %d)", i, prop_count); 10603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params ,"device probably needs DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL", i); 10613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params ,"or even DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST", i); 10623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev qsort (props, i, sizeof(MTPProperties),_compare_func); 10633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *pprops = props; 10643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return i; 10653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev props[i].ObjectHandle = dtoh32a(data); 10673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += sizeof(uint32_t); 10683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev len -= sizeof(uint32_t); 10693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev props[i].property = dtoh16a(data); 10713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += sizeof(uint16_t); 10723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev len -= sizeof(uint16_t); 10733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev props[i].datatype = dtoh16a(data); 10753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += sizeof(uint16_t); 10763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev len -= sizeof(uint16_t); 10773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev offset = 0; 10793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_unpack_DPV(params, data, &offset, len, &props[i].propval, props[i].datatype); 10803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += offset; 10813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev len -= offset; 10823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 10833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev qsort (props, prop_count, sizeof(MTPProperties),_compare_func); 10843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *pprops = props; 10853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return prop_count; 10863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 10873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 10893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP USB Event container unpack 10903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev Copyright (c) 2003 Nikolai Kopanygin 10913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 10923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 10933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_Length 0 10943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_Type 4 10953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_Code 6 10963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_TransId 8 10973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_Param1 12 10983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_Param2 16 10993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ec_Param3 20 11003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 11023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_EC (PTPParams *params, unsigned char* data, PTPContainer *ec, unsigned int len) 11033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int length; 11053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int type; 11063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (data==NULL) 11083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 11093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(ec,0,sizeof(*ec)); 11103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev length=dtoh32a(&data[PTP_ec_Length]); 11113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev type = dtoh16a(&data[PTP_ec_Type]); 11123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Code=dtoh16a(&data[PTP_ec_Code]); 11143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Transaction_ID=dtoh32a(&data[PTP_ec_TransId]); 11153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (type!=PTP_USB_CONTAINER_EVENT) { 11173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "Unknown canon event type %d (code=%x,tid=%x), please report!",type,ec->Code,ec->Transaction_ID); 11183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 11193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (length>=(PTP_ec_Param1+4)) { 11213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Param1=dtoh32a(&data[PTP_ec_Param1]); 11223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Nparam=1; 11233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (length>=(PTP_ec_Param2+4)) { 11253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Param2=dtoh32a(&data[PTP_ec_Param2]); 11263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Nparam=2; 11273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (length>=(PTP_ec_Param3+4)) { 11293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Param3=dtoh32a(&data[PTP_ec_Param3]); 11303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ec->Nparam=3; 11313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 11353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP Canon Folder Entry unpack 11363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev Copyright (c) 2003 Nikolai Kopanygin 11373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 11383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_cfe_ObjectHandle 0 11393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_cfe_ObjectFormatCode 4 11403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_cfe_Flags 6 11413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_cfe_ObjectSize 7 11423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_cfe_Time 11 11433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_cfe_Filename 15 11443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 11463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe) 11473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 11493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (data==NULL) 11503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 11513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); 11523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); 11533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); 11543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); 11553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); 11563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0; i<PTP_CANON_FilenameBufferLen; i++) 11573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]); 11583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 11593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint16_t 11613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data ) 11623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 11633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 11643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev EOS ImageFormat entries (of at least the 5DMII and the 400D ) look like this: 11653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32: number of entries / generated files (1 or 2) 11663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32: size of this entry in bytes (most likely allways 0x10) 11673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32: image type (1 == JPG, 6 == RAW) 11683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32: image size (0 == Large, 1 == Medium, 2 == Small) 11693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW) 11703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev If number of entries is 2 the last uint32 repeat. 11713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev example: 11733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 0: 0x 1 11743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 1: 0x 10 11753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2: 0x 6 11763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 3: 0x 1 11773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4: 0x 4 11783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev The idea is to simply 'condense' these values to just one uint16 to be able to conveniontly 11803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev use the available enumeration facilities (look-up table). The image size and compression 11813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev values fully describe the image format. Hence we generate a uint16 with the four nibles set 11823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression. 11833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev The above example would result in the value 0x1400. 11843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 11853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev const unsigned char* d = *data; 11873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t n = dtoh32a( d ); 11883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t l, s1, c1, s2 = 0, c2 = 0; 11893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (n != 1 && n !=2) { 11913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n); 11923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 11933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 11943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 11953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev l = dtoh32a( d+=4 ); 11963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (l != 0x10) { 11973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 11983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 11993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev d+=4; /* skip type */ 12023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev s1 = dtoh32a( d+=4 ); 12033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev c1 = dtoh32a( d+=4 ); 12043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (n == 2) { 12063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev l = dtoh32a( d+=4 ); 12073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (l != 0x10) { 12083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l); 12093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 12103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev d+=4; /* skip type */ 12123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev s2 = dtoh32a( d+=4 ); 12133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev c2 = dtoh32a( d+=4 ); 12143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *data = (unsigned char*) d+4; 12173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0); 12193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 12223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value) 12233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 12243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t n = (value & 0xFF) ? 2 : 1; 12253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t s = 4 + 0x10 * n; 12263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if( !data ) 12283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return s; 12293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=0, n); 12313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, 0x10); 12323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1); 12333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, (value >> 12) & 0xF); 12343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, (value >> 8) & 0xF); 12353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (n==2) { 12373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, 0x10); 12383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1); 12393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, (value >> 4) & 0xF); 12403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(data+=4, (value >> 0) & 0xF); 12413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return s; 12443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 12453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 12473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP EOS Changes Entry unpack 12483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 12493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Size 0 12503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Type 4 12513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Prop_Subtype 8 /* only for properties */ 12533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Prop_Val_Data 0xc /* only for properties */ 12543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Prop_Desc_Type 0xc /* only for property descs */ 12553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Prop_Desc_Count 0x10 /* only for property descs */ 12563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_Prop_Desc_Data 0x14 /* only for property descs */ 12573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* for PTP_EC_CANON_EOS_RequestObjectTransfer */ 12593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OI_ObjectID 8 12603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OI_OFC 0x0c 12613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OI_Size 0x14 12623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OI_Name 0x1c 12633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* for PTP_EC_CANON_EOS_ObjectAddedEx */ 12653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OA_ObjectID 8 12663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OA_StorageID 0x0c 12673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OA_OFC 0x10 12683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OA_Size 0x1c 12693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OA_Parent 0x20 12703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_ece_OA_Name 0x28 12713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline int 12733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, PTPCanon_changes_entry **ce) 12743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 12753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i = 0, entries = 0; 12763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *curdata = data; 12773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (data==NULL) 12793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return 0; 12803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (curdata - data < datasize) { 12813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 12823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 12833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curdata += size; 12853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((size == 8) && (type == 0)) 12863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 12873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev entries++; 12883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 12893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *ce = malloc (sizeof(PTPCanon_changes_entry)*(entries+1)); 12903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!*ce) return 0; 12913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curdata = data; 12933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (curdata - data < datasize) { 12943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t size = dtoh32a(&curdata[PTP_ece_Size]); 12953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t type = dtoh32a(&curdata[PTP_ece_Type]); 12963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 12973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 12983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (type) { 12993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_EC_CANON_EOS_ObjectAddedEx: 13003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTINFO; 13013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OA_ObjectID]); 13023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.StorageID = dtoh32a(&curdata[PTP_ece_OA_StorageID]); 13033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.ParentObject = dtoh32a(&curdata[PTP_ece_OA_Parent]); 13043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OA_OFC]); 13053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.ObjectCompressedSize= dtoh32a(&curdata[PTP_ece_OA_Size]); 13063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OA_Name])); 13073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 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); 13083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_EC_CANON_EOS_RequestObjectTransfer: 13103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER; 13113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oid = dtoh32a(&curdata[PTP_ece_OI_ObjectID]); 13123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.StorageID = 0; /* use as marker */ 13133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.ObjectFormat = dtoh16a(&curdata[PTP_ece_OI_OFC]); 13143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.ParentObject = 0; /* check, but use as marker */ 13153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.ObjectCompressedSize = dtoh32a(&curdata[PTP_ece_OI_Size]); 13163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].u.object.oi.Filename = strdup(((char*)&curdata[PTP_ece_OI_Name])); 13173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: request object transfer oid %08lx, ofc %04x, size %d, filename %s", i, (*ce)[i].u.object.oid, (*ce)[i].u.object.oi.ObjectFormat, (*ce)[i].u.object.oi.ObjectCompressedSize, (*ce)[i].u.object.oi.Filename); 13193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_EC_CANON_EOS_AvailListChanged: { /* property desc */ 13213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 13223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propxtype = dtoh32a(&curdata[PTP_ece_Prop_Desc_Type]); 13233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t propxcnt = dtoh32a(&curdata[PTP_ece_Prop_Desc_Count]); 13243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *data = &curdata[PTP_ece_Prop_Desc_Data]; 13253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int j; 13263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPDevicePropDesc *dpd; 13273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: EOS prop %04x desc record, datasize %d, propxtype %d", i, proptype, size-PTP_ece_Prop_Desc_Data, propxtype); 13293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<params->nrofcanon_props;j++) 13303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->canon_props[j].proptype == proptype) 13313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j==params->nrofcanon_props) { 13333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: propdesc %x, default value not found.", i, proptype); 13343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd = ¶ms->canon_props[j].dpd; 13373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 1 - uint16 ? 13383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 3 - uint16 13393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * 7 - string? 13403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 13413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (propxtype != 3) { 13423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: propxtype is %x for %04x, unhandled.", i, propxtype, proptype); 13433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<size-PTP_ece_Prop_Desc_Data;j++) 13443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %d: %02x", j, data[j]); 13453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (! propxcnt) 13483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.", 13513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev i, propxtype, proptype, dpd->DataType, propxcnt); 13523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FormFlag = PTP_DPFF_Enumeration; 13533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FORM.Enum.NumberOfValues = propxcnt; 13543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt); 13553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (proptype) { 13573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormat: 13583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatCF: 13593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatSD: 13603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatExtHD: 13613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* special handling of ImageFormat properties */ 13623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<propxcnt;j++) { 13633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FORM.Enum.SupportedValue[j].u16 = 13643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dtoh16( ptp_unpack_EOS_ImageFormat( params, &data ) ); 13653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16); 13663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 13693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* 'normal' enumerated types */ 13703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (dpd->DataType) { 13713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define XX( TYPE, CONV )\ 13723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<propxcnt;j++) { \ 13733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(data); \ 13743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(data)); \ 13753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += 4; /* might only be for propxtype 3 */ \ 13763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } \ 13773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 13793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_INT16: XX( i16, dtoh16a ); 13803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: XX( u32, dtoh32a ); 13813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: XX( u16, dtoh16a ); 13823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: XX( u8, dtoh8a ); 13833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#undef XX 13843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 13853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params ,"event %d: data type 0x%04x of %x unhandled, raw values:", i, dpd->DataType, proptype, dtoh32a(data)); 13863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<(size-PTP_ece_Prop_Desc_Data)/4;j++, data+=4) /* 4 is good for propxtype 3 */ 13873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %3d: 0x%8x", j, dtoh32a(data)); 13883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 13923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 13933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_EC_CANON_EOS_PropValueChanged: 13943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (size >= 0xc) { /* property info */ 13953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int j; 13963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t proptype = dtoh32a(&curdata[PTP_ece_Prop_Subtype]); 13973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *data = &curdata[PTP_ece_Prop_Val_Data]; 13983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPDevicePropDesc *dpd; 13993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: EOS prop %04x info record, datasize is %d", i, proptype, size-PTP_ece_Prop_Val_Data); 14013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<params->nrofcanon_props;j++) 14023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (params->canon_props[j].proptype == proptype) 14033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 14043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j<params->nrofcanon_props) { 14053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ( (params->canon_props[j].size != size) || 14063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (memcmp(params->canon_props[j].data,data,size-PTP_ece_Prop_Val_Data))) { 14073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].data = realloc(params->canon_props[j].data,size-PTP_ece_Prop_Val_Data); 14083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy (params->canon_props[j].data,data,size-PTP_ece_Prop_Val_Data); 14093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } else { 14113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j) 14123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props = realloc(params->canon_props, sizeof(params->canon_props[0])*(j+1)); 14133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev else 14143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props = malloc(sizeof(params->canon_props[0])); 14153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].type = type; 14163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].proptype = proptype; 14173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].size = size; 14183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].data = malloc(size-PTP_ece_Prop_Val_Data); 14193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memcpy(params->canon_props[j].data, data, size-PTP_ece_Prop_Val_Data); 14203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset (¶ms->canon_props[j].dpd,0,sizeof(params->canon_props[j].dpd)); 14213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].dpd.GetSet = 1; 14223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->canon_props[j].dpd.FormFlag = PTP_DPFF_None; 14233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev params->nrofcanon_props = j+1; 14243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd = ¶ms->canon_props[j].dpd; 14263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* fix GetSet value */ 14283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (proptype) { 14293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define XX(x) case PTP_DPC_CANON_##x: 14303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_FocusMode) 14313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_BatteryPower) 14323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_BatterySelect) 14333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_ModelID) 14343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_PTPExtensionVersion) 14353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_DPOFVersion) 14363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_AvailableShots) 14373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_CurrentStorage) 14383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_CurrentFolder) 14393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_MyMenu) 14403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_MyMenuList) 14413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_HDDirectoryStructure) 14423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_BatteryInfo) 14433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_AdapterInfo) 14443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_LensStatus) 14453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_CardExtension) 14463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_TempStatus) 14473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_ShutterCounter) 14483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_SerialNumber) 14493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_DepthOfFieldPreview) 14503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_EVFRecordStatus) 14513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_LvAfSystem) 14523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_FocusInfoEx) 14533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_DepthOfField) 14543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_Brightness) 14553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_EFComp) 14563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_LensName) 14573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(EOS_LensID) 14583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#undef XX 14593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->GetSet = PTP_DPGS_Get; 14603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 14613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 14623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 14633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* set DataType */ 14643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (proptype) { 14653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CameraTime: 14663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFOutputDevice: 14673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_AvailableShots: 14683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CaptureDestination: 14693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_WhiteBalanceXA: 14703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_WhiteBalanceXB: 14713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_QuickReviewTime: 14723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CurrentStorage: 14733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CurrentFolder: 14743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ShutterCounter: 14753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ModelID: 14763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_LensID: 14773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_StroboFiring: 14783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_UINT32; 14793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 14803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_Aperture: 14813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ShutterSpeed: 14823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ISOSpeed: 14833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_FocusMode: 14843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_AutoExposureMode: 14853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ColorSpace: 14863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_BatteryPower: 14873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_PTPExtensionVersion: 14883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_DriveMode: 14893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_AEB: 14903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_UINT16; 14913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 14923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_PictureStyle: 14933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_WhiteBalance: 14943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_MeteringMode: 14953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ExpCompensation: /* actually int8 if you calculate */ 14963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_UINT8; 14973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 14983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_Owner: 14993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_Artist: 15003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_Copyright: 15013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_SerialNumber: 15023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_LensName: 15033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_STR; 15043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_WhiteBalanceAdjustA: 15063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_WhiteBalanceAdjustB: 15073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_INT16; 15083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* unknown props, listed from dump.... all 16 bit, but vals might be smaller */ 15103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_BatterySelect: 15113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case 0xd114: 15123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_DPOFVersion: 15133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_BracketMode: 15143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_UINT16; 15153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint16", i ,proptype, size-PTP_ece_Prop_Val_Data); 15163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 15173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %d: %02x", j, data[j]); 15183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc1: 15203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc2: 15213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc3: 15223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc4: 15233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc5: 15243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc6: 15253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc7: 15263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc8: 15273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc9: 15283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc10: 15293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFunc11: 15303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_UINT8; 15313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint8", i ,proptype, size-PTP_ece_Prop_Val_Data); 15323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 15333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %d: %02x", j, data[j]); 15343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* custom func entries look like this on the 400D: '5 0 0 0 ?' = 4 bytes size + 1 byte data */ 15353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev data += 4; 15363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* yet unknown 32bit props */ 15383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ColorTemperature: 15393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_WftStatus: 15403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_LensStatus: 15413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CardExtension: 15423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_TempStatus: 15433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_PhotoStudioMode: 15443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFMode: 15453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_DepthOfFieldPreview: 15463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFSharpness: 15473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFWBMode: 15483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFClickWBCoeffs: 15493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFColorTemp: 15503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_EVFRecordStatus: 15513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ExposureSimMode: 15523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_LvAfSystem: 15533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_MovSize: 15543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_DepthOfField: 15553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_LvViewTypeSelect: 15563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormat: 15573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatCF: 15583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatSD: 15593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatExtHD: 15603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_CustomFuncEx: 15613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev// dpd->DataType = PTP_DTC_UINT32; 15623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data); 15633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0) 15643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: Warning: datasize modulo sizeof(uint32) is not 0: ", i, (size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) ); 15653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<(size-PTP_ece_Prop_Val_Data)/sizeof(uint32_t);j++) 15663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %d: 0x%8x", j, ((uint32_t*)data)[j]); 15673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 15693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data); 15703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<size-PTP_ece_Prop_Val_Data;j++) 15713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %d: %02x", j, data[j]); 15723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 15743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (dpd->DataType) { 15753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT32: 15763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FactoryDefaultValue.u32 = dtoh32a(data); 15773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->CurrentValue.u32 = dtoh32a(data); 15783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params ,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u32); 15793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT16: 15813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FactoryDefaultValue.u16 = dtoh16a(data); 15823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->CurrentValue.u16 = dtoh16a(data); 15833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16); 15843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_UINT8: 15863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FactoryDefaultValue.u8 = dtoh8a(data); 15873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->CurrentValue.u8 = dtoh8a(data); 15883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 15893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 15903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DTC_STR: { 15913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#if 0 /* 5D MII and 400D aktually store plain ASCII in their string properties */ 15923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t len = 0; 15933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FactoryDefaultValue.str = ptp_unpack_string(params, data, 0, &len); 15943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->CurrentValue.str = ptp_unpack_string(params, data, 0, &len); 15953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#else 15963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FactoryDefaultValue.str = strdup( (char*)data ); 15973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->CurrentValue.str = strdup( (char*)data ); 15983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#endif 15993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params,"event %d: currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str); 16003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 16033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* debug is printed in switch above this one */ 16043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* ImageFormat special handling */ 16083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (proptype) { 16093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormat: 16103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatCF: 16113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatSD: 16123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case PTP_DPC_CANON_EOS_ImageFormatExtHD: 16133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->DataType = PTP_DTC_UINT16; 16143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &data ); 16153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16; 16163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8); 16173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev case 0: /* end marker */ 16233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (size == 8) /* no output */ 16243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: EOS event 0, but size %d", i, size); 16263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 16283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev switch (type) { 16293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define XX(x) case PTP_EC_CANON_EOS_##x: ptp_debug (params, "event %d: unhandled EOS event "#x" (size %d)", i, size);break; 16303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RequestGetEvent) 16313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(ObjectRemoved) 16323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RequestGetObjectInfoEx) 16333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(StorageStatusChanged) 16343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(StorageInfoChanged) 16353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(ObjectInfoChangedEx) 16363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(ObjectContentChanged) 16373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(CameraStatusChanged) 16383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(WillSoonShutdown) 16393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(ShutdownTimerUpdated) 16403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RequestCancelTransfer) 16413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RequestObjectTransferDT) 16423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RequestCancelTransferDT) 16433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(StoreAdded) 16443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(StoreRemoved) 16453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(BulbExposureTime) 16463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RecordingTime) 16473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(RequestObjectTransferTS) 16483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev XX(AfResult) 16493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#undef XX 16503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev default: 16513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, "event %d: unknown EOS event %04x", i, type); 16523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (size >= 0x8) { /* event info */ 16553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int j; 16563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=8;j<size;j++) 16573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_debug (params, " %d: %02x", j, curdata[j]); 16583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ce)[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; 16603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curdata += size; 16633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev i++; 16643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((size == 8) && (type == 0)) 16653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 16663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return entries; 16693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 16703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/* 16723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTP USB Event container unpack for Nikon events. 16733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev*/ 16743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_nikon_ec_Length 0 16753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_nikon_ec_Code 2 16763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_nikon_ec_Param1 4 16773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define PTP_nikon_ec_Size 6 16783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline void 16793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPContainer **ec, int *cnt) 16803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{ 16813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i; 16823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *ec = NULL; 16843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (data == NULL) 16853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 16863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (len < PTP_nikon_ec_Code) 16873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 16883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); 16893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ 16903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return; 16913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *ec = malloc(sizeof(PTPContainer)*(*cnt)); 16923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 16933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<*cnt;i++) { 16943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev memset(&(*ec)[i],0,sizeof(PTPContainer)); 16953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ec)[i].Code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); 16963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ec)[i].Param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); 16973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*ec)[i].Nparam = 1; 16983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 16993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 17003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint32_t 17033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { 17043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int i, len = 0; 17053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint8_t retlen; 17063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *curdata; 17073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev len = 2*(strlen(text->title)+1)+1+ 17093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2*(strlen(text->line[0])+1)+1+ 17103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2*(strlen(text->line[1])+1)+1+ 17113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2*(strlen(text->line[2])+1)+1+ 17123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2*(strlen(text->line[3])+1)+1+ 17133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 2*(strlen(text->line[4])+1)+1+ 17143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 4*2+2*4+2+4+2+5*4*2; 17153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *data = malloc(len); 17163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!*data) return 0; 17173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curdata = *data; 17193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,100);curdata+=2; 17203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,1);curdata+=2; 17213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,0);curdata+=2; 17223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,1000);curdata+=2; 17233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(curdata,0);curdata+=4; 17253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(curdata,0);curdata+=4; 17263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,6);curdata+=2; 17283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod32a(curdata,0);curdata+=4; 17293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 17313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,0x10);curdata+=2; 17323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<5;i++) { 17343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; 17353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,0x10);curdata+=2; 17363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,0x01);curdata+=2; 17373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,0x02);curdata+=2; 17383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev htod16a(curdata,0x06);curdata+=2; 17393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 17403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return len; 17413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 17423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_version 0x00 17443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_ofc 0x02 17453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_unk1 0x04 17463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_objectid 0x08 17473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_parentid 0x0c 17483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_previd 0x10 /* in same dir */ 17493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_nextid 0x14 /* in same dir */ 17503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_nextchild 0x18 /* down one dir */ 17513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_storageid 0x1c /* only in storage entry */ 17523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_name 0x20 17533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_flags 0x2c 17543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_size 0x30 17553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_unixtime 0x34 17563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_year 0x38 17573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_month 0x39 17583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_mday 0x3a 17593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_hour 0x3b 17603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_minute 0x3c 17613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_second 0x3d 17623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_unk2 0x3e 17633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_thumbsize 0x40 17643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_width 0x44 17653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ptp_canon_dir_height 0x48 17663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic inline uint16_t 17683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevptp_unpack_canon_directory ( 17693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPParams *params, 17703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *dir, 17713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t cnt, 17723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectHandles *handles, 17733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectInfo **oinfos, /* size(handles->n) */ 17743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t **flags /* size(handles->n) */ 17753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev) { 17763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned int i, j, nrofobs = 0, curob = 0; 17773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) 17793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<cnt;i++) 17803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ISOBJECT(dir+i*0x4c)) nrofobs++; 17813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handles->n = nrofobs; 17823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); 17833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!handles->Handler) return PTP_RC_GeneralError; 17843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); 17853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!*oinfos) return PTP_RC_GeneralError; 17863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *flags = calloc(sizeof((*flags)[0]),nrofobs); 17873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!*flags) return PTP_RC_GeneralError; 17883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Migrate data into objects ids, handles into 17903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the object handler array. 17913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 17923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curob = 0; 17933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<cnt;i++) { 17943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *cur = dir+i*0x4c; 17953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev PTPObjectInfo *oi = (*oinfos)+curob; 17963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 17973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ISOBJECT(cur)) 17983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 17993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); 18013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->StorageID = 0xffffffff; 18023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); 18033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); 18043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); 18053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); 18063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); 18073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); 18083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); 18093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); 18103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); 18113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev curob++; 18123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Walk over Storage ID entries and distribute the IDs to 18143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * the parent objects. */ 18153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<cnt;i++) { 18163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *cur = dir+i*0x4c; 18173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 18183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (ISOBJECT(cur)) 18203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 18213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 18223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j == handles->n) continue; 18233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); 18243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Walk over all objects and distribute the storage ids */ 18263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev while (1) { 18273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev int changed = 0; 18283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (i=0;i<cnt;i++) { 18293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev unsigned char *cur = dir+i*0x4c; 18303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); 18313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); 18323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); 18333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev uint32_t storageid; 18343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev 18353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!ISOBJECT(cur)) 18363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 18373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; 18383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j == handles->n) { 18393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ 18403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 18413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev storageid = (*oinfos)[j].StorageID; 18433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (storageid == 0xffffffff) continue; 18443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (nextoid != 0xffffffff) { 18453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; 18463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j == handles->n) { 18473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ 18483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 18493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((*oinfos)[j].StorageID == 0xffffffff) { 18513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*oinfos)[j].StorageID = storageid; 18523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev changed++; 18533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (nextchild != 0xffffffff) { 18563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; 18573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (j == handles->n) { 18583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ 18593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev continue; 18603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if ((*oinfos)[j].StorageID == 0xffffffff) { 18623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev (*oinfos)[j].StorageID = storageid; 18633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev changed++; 18643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev /* Check if we: 18683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * - changed no entry (nothing more to do) 18693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * - changed all of them at once (usually happens) 18703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * break if we do. 18713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */ 18723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev if (!changed || (changed==nrofobs-1)) 18733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev break; 18743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev } 18753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#undef ISOBJECT 18763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev return PTP_RC_OK; 18773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev} 1878